This source file includes following definitions.
- cast_phw_vega10_power_state
- cast_const_phw_vega10_power_state
- vega10_set_default_registry_data
- vega10_set_features_platform_caps
- vega10_odn_initial_default_setting
- vega10_init_dpm_defaults
- vega10_get_socclk_for_voltage_evv
- vega10_get_evv_voltages
- vega10_patch_with_vdd_leakage
- vega10_patch_lookup_table_with_leakage
- vega10_patch_clock_voltage_limits_with_vddc_leakage
- vega10_patch_voltage_dependency_tables_with_lookup_table
- vega10_sort_lookup_table
- vega10_complete_dependency_tables
- vega10_set_private_data_based_on_pptable
- vega10_hwmgr_backend_fini
- vega10_hwmgr_backend_init
- vega10_init_sclk_threshold
- vega10_setup_dpm_led_config
- vega10_setup_asic_task
- vega10_trim_voltage_table
- vega10_get_mvdd_voltage_table
- vega10_get_vddci_voltage_table
- vega10_get_vdd_voltage_table
- vega10_trim_voltage_table_to_fit_state_table
- vega10_construct_voltage_tables
- vega10_init_dpm_state
- vega10_setup_default_single_dpm_table
- vega10_setup_default_pcie_table
- vega10_setup_default_dpm_tables
- vega10_populate_ulv_state
- vega10_populate_single_lclk_level
- vega10_populate_smc_link_levels
- vega10_populate_single_gfx_level
- vega10_populate_single_soc_level
- vega10_populate_all_graphic_levels
- vega10_populate_vddc_soc_levels
- vega10_populate_single_memory_level
- vega10_populate_all_memory_levels
- vega10_populate_single_display_type
- vega10_populate_all_display_clock_levels
- vega10_populate_single_eclock_level
- vega10_populate_smc_vce_levels
- vega10_populate_single_vclock_level
- vega10_populate_single_dclock_level
- vega10_populate_smc_uvd_levels
- vega10_populate_clock_stretcher_table
- vega10_populate_avfs_parameters
- vega10_acg_enable
- vega10_acg_disable
- vega10_populate_gpio_parameters
- vega10_avfs_enable
- vega10_update_avfs
- vega10_populate_and_upload_avfs_fuse_override
- vega10_check_dpm_table_updated
- vega10_init_smc_table
- vega10_enable_thermal_protection
- vega10_disable_thermal_protection
- vega10_enable_vrhot_feature
- vega10_enable_ulv
- vega10_disable_ulv
- vega10_enable_deep_sleep_master_switch
- vega10_disable_deep_sleep_master_switch
- vega10_stop_dpm
- vega10_start_dpm
- vega10_enable_disable_PCC_limit_feature
- vega10_enable_dpm_tasks
- vega10_get_power_state_size
- vega10_get_pp_table_entry_callback_func
- vega10_get_pp_table_entry
- vega10_patch_boot_state
- vega10_apply_state_adjust_rules
- vega10_find_dpm_states_clocks_in_dpm_table
- vega10_populate_and_upload_sclk_mclk_dpm_levels
- vega10_trim_single_dpm_states
- vega10_trim_single_dpm_states_with_mask
- vega10_trim_dpm_states
- vega10_find_lowest_dpm_level
- vega10_find_highest_dpm_level
- vega10_apply_dal_minimum_voltage_request
- vega10_get_soc_index_for_max_uclk
- vega10_upload_dpm_bootup_level
- vega10_upload_dpm_max_level
- vega10_generate_dpm_level_enable_mask
- vega10_enable_disable_vce_dpm
- vega10_update_sclk_threshold
- vega10_set_power_state_tasks
- vega10_dpm_get_sclk
- vega10_dpm_get_mclk
- vega10_get_gpu_power
- vega10_read_sensor
- vega10_notify_smc_display_change
- vega10_display_clock_voltage_request
- vega10_get_uclk_index
- vega10_notify_smc_display_config_after_ps_adjustment
- vega10_force_dpm_highest
- vega10_force_dpm_lowest
- vega10_unforce_dpm_levels
- vega10_get_profiling_clk_mask
- vega10_set_fan_control_mode
- vega10_force_clock_level
- vega10_dpm_force_dpm_level
- vega10_get_fan_control_mode
- vega10_get_dal_power_level
- vega10_get_sclks
- vega10_get_memclocks
- vega10_get_dcefclocks
- vega10_get_socclocks
- vega10_get_clock_by_type_with_latency
- vega10_get_clock_by_type_with_voltage
- vega10_set_watermarks_for_clocks_ranges
- vega10_get_ppfeature_status
- vega10_set_ppfeature_status
- vega10_print_clock_levels
- vega10_display_configuration_changed_task
- vega10_enable_disable_uvd_dpm
- vega10_power_gate_vce
- vega10_power_gate_uvd
- vega10_are_power_levels_equal
- vega10_check_states_equal
- vega10_check_smc_update_required_for_display_configuration
- vega10_disable_dpm_tasks
- vega10_power_off_asic
- vega10_get_sclk_od
- vega10_set_sclk_od
- vega10_get_mclk_od
- vega10_set_mclk_od
- vega10_notify_cac_buffer_info
- vega10_get_thermal_temperature_range
- vega10_get_power_profile_mode
- vega10_set_power_profile_mode
- vega10_check_clk_voltage_valid
- vega10_odn_update_power_state
- vega10_odn_update_soc_table
- vega10_odn_edit_dpm_table
- vega10_set_mp1_state
- vega10_get_performance_level
- vega10_hwmgr_init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include <linux/delay.h>
25 #include <linux/fb.h>
26 #include <linux/module.h>
27 #include <linux/pci.h>
28 #include <linux/slab.h>
29
30 #include "hwmgr.h"
31 #include "amd_powerplay.h"
32 #include "hardwaremanager.h"
33 #include "ppatomfwctrl.h"
34 #include "atomfirmware.h"
35 #include "cgs_common.h"
36 #include "vega10_powertune.h"
37 #include "smu9.h"
38 #include "smu9_driver_if.h"
39 #include "vega10_inc.h"
40 #include "soc15_common.h"
41 #include "pppcielanes.h"
42 #include "vega10_hwmgr.h"
43 #include "vega10_smumgr.h"
44 #include "vega10_processpptables.h"
45 #include "vega10_pptable.h"
46 #include "vega10_thermal.h"
47 #include "pp_debug.h"
48 #include "amd_pcie_helpers.h"
49 #include "ppinterrupt.h"
50 #include "pp_overdriver.h"
51 #include "pp_thermal.h"
52 #include "vega10_baco.h"
53
54 #include "smuio/smuio_9_0_offset.h"
55 #include "smuio/smuio_9_0_sh_mask.h"
56
57 #define HBM_MEMORY_CHANNEL_WIDTH 128
58
59 static const uint32_t channel_number[] = {1, 2, 0, 4, 0, 8, 0, 16, 2};
60
61 #define mmDF_CS_AON0_DramBaseAddress0 0x0044
62 #define mmDF_CS_AON0_DramBaseAddress0_BASE_IDX 0
63
64
65 #define DF_CS_AON0_DramBaseAddress0__AddrRngVal__SHIFT 0x0
66 #define DF_CS_AON0_DramBaseAddress0__LgcyMmioHoleEn__SHIFT 0x1
67 #define DF_CS_AON0_DramBaseAddress0__IntLvNumChan__SHIFT 0x4
68 #define DF_CS_AON0_DramBaseAddress0__IntLvAddrSel__SHIFT 0x8
69 #define DF_CS_AON0_DramBaseAddress0__DramBaseAddr__SHIFT 0xc
70 #define DF_CS_AON0_DramBaseAddress0__AddrRngVal_MASK 0x00000001L
71 #define DF_CS_AON0_DramBaseAddress0__LgcyMmioHoleEn_MASK 0x00000002L
72 #define DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK 0x000000F0L
73 #define DF_CS_AON0_DramBaseAddress0__IntLvAddrSel_MASK 0x00000700L
74 #define DF_CS_AON0_DramBaseAddress0__DramBaseAddr_MASK 0xFFFFF000L
75
76 typedef enum {
77 CLK_SMNCLK = 0,
78 CLK_SOCCLK,
79 CLK_MP0CLK,
80 CLK_MP1CLK,
81 CLK_LCLK,
82 CLK_DCEFCLK,
83 CLK_VCLK,
84 CLK_DCLK,
85 CLK_ECLK,
86 CLK_UCLK,
87 CLK_GFXCLK,
88 CLK_COUNT,
89 } CLOCK_ID_e;
90
91 static const ULONG PhwVega10_Magic = (ULONG)(PHM_VIslands_Magic);
92
93 struct vega10_power_state *cast_phw_vega10_power_state(
94 struct pp_hw_power_state *hw_ps)
95 {
96 PP_ASSERT_WITH_CODE((PhwVega10_Magic == hw_ps->magic),
97 "Invalid Powerstate Type!",
98 return NULL;);
99
100 return (struct vega10_power_state *)hw_ps;
101 }
102
103 const struct vega10_power_state *cast_const_phw_vega10_power_state(
104 const struct pp_hw_power_state *hw_ps)
105 {
106 PP_ASSERT_WITH_CODE((PhwVega10_Magic == hw_ps->magic),
107 "Invalid Powerstate Type!",
108 return NULL;);
109
110 return (const struct vega10_power_state *)hw_ps;
111 }
112
113 static void vega10_set_default_registry_data(struct pp_hwmgr *hwmgr)
114 {
115 struct vega10_hwmgr *data = hwmgr->backend;
116
117 data->registry_data.sclk_dpm_key_disabled =
118 hwmgr->feature_mask & PP_SCLK_DPM_MASK ? false : true;
119 data->registry_data.socclk_dpm_key_disabled =
120 hwmgr->feature_mask & PP_SOCCLK_DPM_MASK ? false : true;
121 data->registry_data.mclk_dpm_key_disabled =
122 hwmgr->feature_mask & PP_MCLK_DPM_MASK ? false : true;
123 data->registry_data.pcie_dpm_key_disabled =
124 hwmgr->feature_mask & PP_PCIE_DPM_MASK ? false : true;
125
126 data->registry_data.dcefclk_dpm_key_disabled =
127 hwmgr->feature_mask & PP_DCEFCLK_DPM_MASK ? false : true;
128
129 if (hwmgr->feature_mask & PP_POWER_CONTAINMENT_MASK) {
130 data->registry_data.power_containment_support = 1;
131 data->registry_data.enable_pkg_pwr_tracking_feature = 1;
132 data->registry_data.enable_tdc_limit_feature = 1;
133 }
134
135 data->registry_data.clock_stretcher_support =
136 hwmgr->feature_mask & PP_CLOCK_STRETCH_MASK ? true : false;
137
138 data->registry_data.ulv_support =
139 hwmgr->feature_mask & PP_ULV_MASK ? true : false;
140
141 data->registry_data.sclk_deep_sleep_support =
142 hwmgr->feature_mask & PP_SCLK_DEEP_SLEEP_MASK ? true : false;
143
144 data->registry_data.disable_water_mark = 0;
145
146 data->registry_data.fan_control_support = 1;
147 data->registry_data.thermal_support = 1;
148 data->registry_data.fw_ctf_enabled = 1;
149
150 data->registry_data.avfs_support =
151 hwmgr->feature_mask & PP_AVFS_MASK ? true : false;
152 data->registry_data.led_dpm_enabled = 1;
153
154 data->registry_data.vr0hot_enabled = 1;
155 data->registry_data.vr1hot_enabled = 1;
156 data->registry_data.regulator_hot_gpio_support = 1;
157
158 data->registry_data.didt_support = 1;
159 if (data->registry_data.didt_support) {
160 data->registry_data.didt_mode = 6;
161 data->registry_data.sq_ramping_support = 1;
162 data->registry_data.db_ramping_support = 0;
163 data->registry_data.td_ramping_support = 0;
164 data->registry_data.tcp_ramping_support = 0;
165 data->registry_data.dbr_ramping_support = 0;
166 data->registry_data.edc_didt_support = 1;
167 data->registry_data.gc_didt_support = 0;
168 data->registry_data.psm_didt_support = 0;
169 }
170
171 data->display_voltage_mode = PPVEGA10_VEGA10DISPLAYVOLTAGEMODE_DFLT;
172 data->dcef_clk_quad_eqn_a = PPREGKEY_VEGA10QUADRATICEQUATION_DFLT;
173 data->dcef_clk_quad_eqn_b = PPREGKEY_VEGA10QUADRATICEQUATION_DFLT;
174 data->dcef_clk_quad_eqn_c = PPREGKEY_VEGA10QUADRATICEQUATION_DFLT;
175 data->disp_clk_quad_eqn_a = PPREGKEY_VEGA10QUADRATICEQUATION_DFLT;
176 data->disp_clk_quad_eqn_b = PPREGKEY_VEGA10QUADRATICEQUATION_DFLT;
177 data->disp_clk_quad_eqn_c = PPREGKEY_VEGA10QUADRATICEQUATION_DFLT;
178 data->pixel_clk_quad_eqn_a = PPREGKEY_VEGA10QUADRATICEQUATION_DFLT;
179 data->pixel_clk_quad_eqn_b = PPREGKEY_VEGA10QUADRATICEQUATION_DFLT;
180 data->pixel_clk_quad_eqn_c = PPREGKEY_VEGA10QUADRATICEQUATION_DFLT;
181 data->phy_clk_quad_eqn_a = PPREGKEY_VEGA10QUADRATICEQUATION_DFLT;
182 data->phy_clk_quad_eqn_b = PPREGKEY_VEGA10QUADRATICEQUATION_DFLT;
183 data->phy_clk_quad_eqn_c = PPREGKEY_VEGA10QUADRATICEQUATION_DFLT;
184
185 data->gfxclk_average_alpha = PPVEGA10_VEGA10GFXCLKAVERAGEALPHA_DFLT;
186 data->socclk_average_alpha = PPVEGA10_VEGA10SOCCLKAVERAGEALPHA_DFLT;
187 data->uclk_average_alpha = PPVEGA10_VEGA10UCLKCLKAVERAGEALPHA_DFLT;
188 data->gfx_activity_average_alpha = PPVEGA10_VEGA10GFXACTIVITYAVERAGEALPHA_DFLT;
189 }
190
191 static int vega10_set_features_platform_caps(struct pp_hwmgr *hwmgr)
192 {
193 struct vega10_hwmgr *data = hwmgr->backend;
194 struct phm_ppt_v2_information *table_info =
195 (struct phm_ppt_v2_information *)hwmgr->pptable;
196 struct amdgpu_device *adev = hwmgr->adev;
197
198 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
199 PHM_PlatformCaps_SclkDeepSleep);
200
201 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
202 PHM_PlatformCaps_DynamicPatchPowerState);
203
204 if (data->vddci_control == VEGA10_VOLTAGE_CONTROL_NONE)
205 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
206 PHM_PlatformCaps_ControlVDDCI);
207
208 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
209 PHM_PlatformCaps_EnableSMU7ThermalManagement);
210
211 if (adev->pg_flags & AMD_PG_SUPPORT_UVD)
212 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
213 PHM_PlatformCaps_UVDPowerGating);
214
215 if (adev->pg_flags & AMD_PG_SUPPORT_VCE)
216 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
217 PHM_PlatformCaps_VCEPowerGating);
218
219 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
220 PHM_PlatformCaps_UnTabledHardwareInterface);
221
222 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
223 PHM_PlatformCaps_FanSpeedInTableIsRPM);
224
225 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
226 PHM_PlatformCaps_ODFuzzyFanControlSupport);
227
228 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
229 PHM_PlatformCaps_DynamicPowerManagement);
230
231 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
232 PHM_PlatformCaps_SMC);
233
234
235
236 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
237 PHM_PlatformCaps_PowerContainment);
238 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
239 PHM_PlatformCaps_DiDtSupport);
240 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
241 PHM_PlatformCaps_SQRamping);
242 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
243 PHM_PlatformCaps_DBRamping);
244 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
245 PHM_PlatformCaps_TDRamping);
246 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
247 PHM_PlatformCaps_TCPRamping);
248 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
249 PHM_PlatformCaps_DBRRamping);
250 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
251 PHM_PlatformCaps_DiDtEDCEnable);
252 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
253 PHM_PlatformCaps_GCEDC);
254 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
255 PHM_PlatformCaps_PSM);
256
257 if (data->registry_data.didt_support) {
258 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DiDtSupport);
259 if (data->registry_data.sq_ramping_support)
260 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SQRamping);
261 if (data->registry_data.db_ramping_support)
262 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DBRamping);
263 if (data->registry_data.td_ramping_support)
264 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TDRamping);
265 if (data->registry_data.tcp_ramping_support)
266 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TCPRamping);
267 if (data->registry_data.dbr_ramping_support)
268 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DBRRamping);
269 if (data->registry_data.edc_didt_support)
270 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DiDtEDCEnable);
271 if (data->registry_data.gc_didt_support)
272 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_GCEDC);
273 if (data->registry_data.psm_didt_support)
274 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PSM);
275 }
276
277 if (data->registry_data.power_containment_support)
278 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
279 PHM_PlatformCaps_PowerContainment);
280 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
281 PHM_PlatformCaps_CAC);
282
283 if (table_info->tdp_table->usClockStretchAmount &&
284 data->registry_data.clock_stretcher_support)
285 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
286 PHM_PlatformCaps_ClockStretcher);
287
288 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
289 PHM_PlatformCaps_RegulatorHot);
290 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
291 PHM_PlatformCaps_AutomaticDCTransition);
292
293 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
294 PHM_PlatformCaps_UVDDPM);
295 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
296 PHM_PlatformCaps_VCEDPM);
297
298 return 0;
299 }
300
301 static int vega10_odn_initial_default_setting(struct pp_hwmgr *hwmgr)
302 {
303 struct vega10_hwmgr *data = hwmgr->backend;
304 struct phm_ppt_v2_information *table_info =
305 (struct phm_ppt_v2_information *)(hwmgr->pptable);
306 struct vega10_odn_dpm_table *odn_table = &(data->odn_dpm_table);
307 struct vega10_odn_vddc_lookup_table *od_lookup_table;
308 struct phm_ppt_v1_voltage_lookup_table *vddc_lookup_table;
309 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table[3];
310 struct phm_ppt_v1_clock_voltage_dependency_table *od_table[3];
311 struct pp_atomfwctrl_avfs_parameters avfs_params = {0};
312 uint32_t i;
313 int result;
314
315 result = pp_atomfwctrl_get_avfs_information(hwmgr, &avfs_params);
316 if (!result) {
317 data->odn_dpm_table.max_vddc = avfs_params.ulMaxVddc;
318 data->odn_dpm_table.min_vddc = avfs_params.ulMinVddc;
319 }
320
321 od_lookup_table = &odn_table->vddc_lookup_table;
322 vddc_lookup_table = table_info->vddc_lookup_table;
323
324 for (i = 0; i < vddc_lookup_table->count; i++)
325 od_lookup_table->entries[i].us_vdd = vddc_lookup_table->entries[i].us_vdd;
326
327 od_lookup_table->count = vddc_lookup_table->count;
328
329 dep_table[0] = table_info->vdd_dep_on_sclk;
330 dep_table[1] = table_info->vdd_dep_on_mclk;
331 dep_table[2] = table_info->vdd_dep_on_socclk;
332 od_table[0] = (struct phm_ppt_v1_clock_voltage_dependency_table *)&odn_table->vdd_dep_on_sclk;
333 od_table[1] = (struct phm_ppt_v1_clock_voltage_dependency_table *)&odn_table->vdd_dep_on_mclk;
334 od_table[2] = (struct phm_ppt_v1_clock_voltage_dependency_table *)&odn_table->vdd_dep_on_socclk;
335
336 for (i = 0; i < 3; i++)
337 smu_get_voltage_dependency_table_ppt_v1(dep_table[i], od_table[i]);
338
339 if (odn_table->max_vddc == 0 || odn_table->max_vddc > 2000)
340 odn_table->max_vddc = dep_table[0]->entries[dep_table[0]->count - 1].vddc;
341 if (odn_table->min_vddc == 0 || odn_table->min_vddc > 2000)
342 odn_table->min_vddc = dep_table[0]->entries[0].vddc;
343
344 i = od_table[2]->count - 1;
345 od_table[2]->entries[i].clk = hwmgr->platform_descriptor.overdriveLimit.memoryClock > od_table[2]->entries[i].clk ?
346 hwmgr->platform_descriptor.overdriveLimit.memoryClock :
347 od_table[2]->entries[i].clk;
348 od_table[2]->entries[i].vddc = odn_table->max_vddc > od_table[2]->entries[i].vddc ?
349 odn_table->max_vddc :
350 od_table[2]->entries[i].vddc;
351
352 return 0;
353 }
354
355 static void vega10_init_dpm_defaults(struct pp_hwmgr *hwmgr)
356 {
357 struct vega10_hwmgr *data = hwmgr->backend;
358 int i;
359 uint32_t sub_vendor_id, hw_revision;
360 uint32_t top32, bottom32;
361 struct amdgpu_device *adev = hwmgr->adev;
362
363 vega10_initialize_power_tune_defaults(hwmgr);
364
365 for (i = 0; i < GNLD_FEATURES_MAX; i++) {
366 data->smu_features[i].smu_feature_id = 0xffff;
367 data->smu_features[i].smu_feature_bitmap = 1 << i;
368 data->smu_features[i].enabled = false;
369 data->smu_features[i].supported = false;
370 }
371
372 data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_id =
373 FEATURE_DPM_PREFETCHER_BIT;
374 data->smu_features[GNLD_DPM_GFXCLK].smu_feature_id =
375 FEATURE_DPM_GFXCLK_BIT;
376 data->smu_features[GNLD_DPM_UCLK].smu_feature_id =
377 FEATURE_DPM_UCLK_BIT;
378 data->smu_features[GNLD_DPM_SOCCLK].smu_feature_id =
379 FEATURE_DPM_SOCCLK_BIT;
380 data->smu_features[GNLD_DPM_UVD].smu_feature_id =
381 FEATURE_DPM_UVD_BIT;
382 data->smu_features[GNLD_DPM_VCE].smu_feature_id =
383 FEATURE_DPM_VCE_BIT;
384 data->smu_features[GNLD_DPM_MP0CLK].smu_feature_id =
385 FEATURE_DPM_MP0CLK_BIT;
386 data->smu_features[GNLD_DPM_LINK].smu_feature_id =
387 FEATURE_DPM_LINK_BIT;
388 data->smu_features[GNLD_DPM_DCEFCLK].smu_feature_id =
389 FEATURE_DPM_DCEFCLK_BIT;
390 data->smu_features[GNLD_ULV].smu_feature_id =
391 FEATURE_ULV_BIT;
392 data->smu_features[GNLD_AVFS].smu_feature_id =
393 FEATURE_AVFS_BIT;
394 data->smu_features[GNLD_DS_GFXCLK].smu_feature_id =
395 FEATURE_DS_GFXCLK_BIT;
396 data->smu_features[GNLD_DS_SOCCLK].smu_feature_id =
397 FEATURE_DS_SOCCLK_BIT;
398 data->smu_features[GNLD_DS_LCLK].smu_feature_id =
399 FEATURE_DS_LCLK_BIT;
400 data->smu_features[GNLD_PPT].smu_feature_id =
401 FEATURE_PPT_BIT;
402 data->smu_features[GNLD_TDC].smu_feature_id =
403 FEATURE_TDC_BIT;
404 data->smu_features[GNLD_THERMAL].smu_feature_id =
405 FEATURE_THERMAL_BIT;
406 data->smu_features[GNLD_GFX_PER_CU_CG].smu_feature_id =
407 FEATURE_GFX_PER_CU_CG_BIT;
408 data->smu_features[GNLD_RM].smu_feature_id =
409 FEATURE_RM_BIT;
410 data->smu_features[GNLD_DS_DCEFCLK].smu_feature_id =
411 FEATURE_DS_DCEFCLK_BIT;
412 data->smu_features[GNLD_ACDC].smu_feature_id =
413 FEATURE_ACDC_BIT;
414 data->smu_features[GNLD_VR0HOT].smu_feature_id =
415 FEATURE_VR0HOT_BIT;
416 data->smu_features[GNLD_VR1HOT].smu_feature_id =
417 FEATURE_VR1HOT_BIT;
418 data->smu_features[GNLD_FW_CTF].smu_feature_id =
419 FEATURE_FW_CTF_BIT;
420 data->smu_features[GNLD_LED_DISPLAY].smu_feature_id =
421 FEATURE_LED_DISPLAY_BIT;
422 data->smu_features[GNLD_FAN_CONTROL].smu_feature_id =
423 FEATURE_FAN_CONTROL_BIT;
424 data->smu_features[GNLD_ACG].smu_feature_id = FEATURE_ACG_BIT;
425 data->smu_features[GNLD_DIDT].smu_feature_id = FEATURE_GFX_EDC_BIT;
426 data->smu_features[GNLD_PCC_LIMIT].smu_feature_id = FEATURE_PCC_LIMIT_CONTROL_BIT;
427
428 if (!data->registry_data.prefetcher_dpm_key_disabled)
429 data->smu_features[GNLD_DPM_PREFETCHER].supported = true;
430
431 if (!data->registry_data.sclk_dpm_key_disabled)
432 data->smu_features[GNLD_DPM_GFXCLK].supported = true;
433
434 if (!data->registry_data.mclk_dpm_key_disabled)
435 data->smu_features[GNLD_DPM_UCLK].supported = true;
436
437 if (!data->registry_data.socclk_dpm_key_disabled)
438 data->smu_features[GNLD_DPM_SOCCLK].supported = true;
439
440 if (PP_CAP(PHM_PlatformCaps_UVDDPM))
441 data->smu_features[GNLD_DPM_UVD].supported = true;
442
443 if (PP_CAP(PHM_PlatformCaps_VCEDPM))
444 data->smu_features[GNLD_DPM_VCE].supported = true;
445
446 if (!data->registry_data.pcie_dpm_key_disabled)
447 data->smu_features[GNLD_DPM_LINK].supported = true;
448
449 if (!data->registry_data.dcefclk_dpm_key_disabled)
450 data->smu_features[GNLD_DPM_DCEFCLK].supported = true;
451
452 if (PP_CAP(PHM_PlatformCaps_SclkDeepSleep) &&
453 data->registry_data.sclk_deep_sleep_support) {
454 data->smu_features[GNLD_DS_GFXCLK].supported = true;
455 data->smu_features[GNLD_DS_SOCCLK].supported = true;
456 data->smu_features[GNLD_DS_LCLK].supported = true;
457 data->smu_features[GNLD_DS_DCEFCLK].supported = true;
458 }
459
460 if (data->registry_data.enable_pkg_pwr_tracking_feature)
461 data->smu_features[GNLD_PPT].supported = true;
462
463 if (data->registry_data.enable_tdc_limit_feature)
464 data->smu_features[GNLD_TDC].supported = true;
465
466 if (data->registry_data.thermal_support)
467 data->smu_features[GNLD_THERMAL].supported = true;
468
469 if (data->registry_data.fan_control_support)
470 data->smu_features[GNLD_FAN_CONTROL].supported = true;
471
472 if (data->registry_data.fw_ctf_enabled)
473 data->smu_features[GNLD_FW_CTF].supported = true;
474
475 if (data->registry_data.avfs_support)
476 data->smu_features[GNLD_AVFS].supported = true;
477
478 if (data->registry_data.led_dpm_enabled)
479 data->smu_features[GNLD_LED_DISPLAY].supported = true;
480
481 if (data->registry_data.vr1hot_enabled)
482 data->smu_features[GNLD_VR1HOT].supported = true;
483
484 if (data->registry_data.vr0hot_enabled)
485 data->smu_features[GNLD_VR0HOT].supported = true;
486
487 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetSmuVersion);
488 hwmgr->smu_version = smum_get_argument(hwmgr);
489
490 if ((hwmgr->smu_version & 0xff000000) == 0x5000000)
491 data->smu_features[GNLD_ACG].supported = true;
492 if (data->registry_data.didt_support)
493 data->smu_features[GNLD_DIDT].supported = true;
494
495 hw_revision = adev->pdev->revision;
496 sub_vendor_id = adev->pdev->subsystem_vendor;
497
498 if ((hwmgr->chip_id == 0x6862 ||
499 hwmgr->chip_id == 0x6861 ||
500 hwmgr->chip_id == 0x6868) &&
501 (hw_revision == 0) &&
502 (sub_vendor_id != 0x1002))
503 data->smu_features[GNLD_PCC_LIMIT].supported = true;
504
505
506 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32);
507 top32 = smum_get_argument(hwmgr);
508 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32);
509 bottom32 = smum_get_argument(hwmgr);
510
511 adev->unique_id = ((uint64_t)bottom32 << 32) | top32;
512 }
513
514 #ifdef PPLIB_VEGA10_EVV_SUPPORT
515 static int vega10_get_socclk_for_voltage_evv(struct pp_hwmgr *hwmgr,
516 phm_ppt_v1_voltage_lookup_table *lookup_table,
517 uint16_t virtual_voltage_id, int32_t *socclk)
518 {
519 uint8_t entry_id;
520 uint8_t voltage_id;
521 struct phm_ppt_v2_information *table_info =
522 (struct phm_ppt_v2_information *)(hwmgr->pptable);
523
524 PP_ASSERT_WITH_CODE(lookup_table->count != 0,
525 "Lookup table is empty",
526 return -EINVAL);
527
528
529 for (entry_id = 0; entry_id < table_info->vdd_dep_on_sclk->count; entry_id++) {
530 voltage_id = table_info->vdd_dep_on_socclk->entries[entry_id].vddInd;
531 if (lookup_table->entries[voltage_id].us_vdd == virtual_voltage_id)
532 break;
533 }
534
535 PP_ASSERT_WITH_CODE(entry_id < table_info->vdd_dep_on_socclk->count,
536 "Can't find requested voltage id in vdd_dep_on_socclk table!",
537 return -EINVAL);
538
539 *socclk = table_info->vdd_dep_on_socclk->entries[entry_id].clk;
540
541 return 0;
542 }
543
544 #define ATOM_VIRTUAL_VOLTAGE_ID0 0xff01
545
546
547
548
549
550
551 static int vega10_get_evv_voltages(struct pp_hwmgr *hwmgr)
552 {
553 struct vega10_hwmgr *data = hwmgr->backend;
554 uint16_t vv_id;
555 uint32_t vddc = 0;
556 uint16_t i, j;
557 uint32_t sclk = 0;
558 struct phm_ppt_v2_information *table_info =
559 (struct phm_ppt_v2_information *)hwmgr->pptable;
560 struct phm_ppt_v1_clock_voltage_dependency_table *socclk_table =
561 table_info->vdd_dep_on_socclk;
562 int result;
563
564 for (i = 0; i < VEGA10_MAX_LEAKAGE_COUNT; i++) {
565 vv_id = ATOM_VIRTUAL_VOLTAGE_ID0 + i;
566
567 if (!vega10_get_socclk_for_voltage_evv(hwmgr,
568 table_info->vddc_lookup_table, vv_id, &sclk)) {
569 if (PP_CAP(PHM_PlatformCaps_ClockStretcher)) {
570 for (j = 1; j < socclk_table->count; j++) {
571 if (socclk_table->entries[j].clk == sclk &&
572 socclk_table->entries[j].cks_enable == 0) {
573 sclk += 5000;
574 break;
575 }
576 }
577 }
578
579 PP_ASSERT_WITH_CODE(!atomctrl_get_voltage_evv_on_sclk_ai(hwmgr,
580 VOLTAGE_TYPE_VDDC, sclk, vv_id, &vddc),
581 "Error retrieving EVV voltage value!",
582 continue);
583
584
585
586 PP_ASSERT_WITH_CODE((vddc < 2000 && vddc != 0),
587 "Invalid VDDC value", result = -EINVAL;);
588
589
590 if (vddc != 0 && vddc != vv_id) {
591 data->vddc_leakage.actual_voltage[data->vddc_leakage.count] = (uint16_t)(vddc/100);
592 data->vddc_leakage.leakage_id[data->vddc_leakage.count] = vv_id;
593 data->vddc_leakage.count++;
594 }
595 }
596 }
597
598 return 0;
599 }
600
601
602
603
604
605
606
607
608 static void vega10_patch_with_vdd_leakage(struct pp_hwmgr *hwmgr,
609 uint16_t *voltage, struct vega10_leakage_voltage *leakage_table)
610 {
611 uint32_t index;
612
613
614 for (index = 0; index < leakage_table->count; index++) {
615
616
617 if (leakage_table->leakage_id[index] == *voltage) {
618 *voltage = leakage_table->actual_voltage[index];
619 break;
620 }
621 }
622
623 if (*voltage > ATOM_VIRTUAL_VOLTAGE_ID0)
624 pr_info("Voltage value looks like a Leakage ID but it's not patched\n");
625 }
626
627
628
629
630
631
632
633
634
635 static int vega10_patch_lookup_table_with_leakage(struct pp_hwmgr *hwmgr,
636 phm_ppt_v1_voltage_lookup_table *lookup_table,
637 struct vega10_leakage_voltage *leakage_table)
638 {
639 uint32_t i;
640
641 for (i = 0; i < lookup_table->count; i++)
642 vega10_patch_with_vdd_leakage(hwmgr,
643 &lookup_table->entries[i].us_vdd, leakage_table);
644
645 return 0;
646 }
647
648 static int vega10_patch_clock_voltage_limits_with_vddc_leakage(
649 struct pp_hwmgr *hwmgr, struct vega10_leakage_voltage *leakage_table,
650 uint16_t *vddc)
651 {
652 vega10_patch_with_vdd_leakage(hwmgr, (uint16_t *)vddc, leakage_table);
653
654 return 0;
655 }
656 #endif
657
658 static int vega10_patch_voltage_dependency_tables_with_lookup_table(
659 struct pp_hwmgr *hwmgr)
660 {
661 uint8_t entry_id, voltage_id;
662 unsigned i;
663 struct phm_ppt_v2_information *table_info =
664 (struct phm_ppt_v2_information *)(hwmgr->pptable);
665 struct phm_ppt_v1_mm_clock_voltage_dependency_table *mm_table =
666 table_info->mm_dep_table;
667 struct phm_ppt_v1_clock_voltage_dependency_table *mclk_table =
668 table_info->vdd_dep_on_mclk;
669
670 for (i = 0; i < 6; i++) {
671 struct phm_ppt_v1_clock_voltage_dependency_table *vdt;
672 switch (i) {
673 case 0: vdt = table_info->vdd_dep_on_socclk; break;
674 case 1: vdt = table_info->vdd_dep_on_sclk; break;
675 case 2: vdt = table_info->vdd_dep_on_dcefclk; break;
676 case 3: vdt = table_info->vdd_dep_on_pixclk; break;
677 case 4: vdt = table_info->vdd_dep_on_dispclk; break;
678 case 5: vdt = table_info->vdd_dep_on_phyclk; break;
679 }
680
681 for (entry_id = 0; entry_id < vdt->count; entry_id++) {
682 voltage_id = vdt->entries[entry_id].vddInd;
683 vdt->entries[entry_id].vddc =
684 table_info->vddc_lookup_table->entries[voltage_id].us_vdd;
685 }
686 }
687
688 for (entry_id = 0; entry_id < mm_table->count; ++entry_id) {
689 voltage_id = mm_table->entries[entry_id].vddcInd;
690 mm_table->entries[entry_id].vddc =
691 table_info->vddc_lookup_table->entries[voltage_id].us_vdd;
692 }
693
694 for (entry_id = 0; entry_id < mclk_table->count; ++entry_id) {
695 voltage_id = mclk_table->entries[entry_id].vddInd;
696 mclk_table->entries[entry_id].vddc =
697 table_info->vddc_lookup_table->entries[voltage_id].us_vdd;
698 voltage_id = mclk_table->entries[entry_id].vddciInd;
699 mclk_table->entries[entry_id].vddci =
700 table_info->vddci_lookup_table->entries[voltage_id].us_vdd;
701 voltage_id = mclk_table->entries[entry_id].mvddInd;
702 mclk_table->entries[entry_id].mvdd =
703 table_info->vddmem_lookup_table->entries[voltage_id].us_vdd;
704 }
705
706
707 return 0;
708
709 }
710
711 static int vega10_sort_lookup_table(struct pp_hwmgr *hwmgr,
712 struct phm_ppt_v1_voltage_lookup_table *lookup_table)
713 {
714 uint32_t table_size, i, j;
715 struct phm_ppt_v1_voltage_lookup_record tmp_voltage_lookup_record;
716
717 PP_ASSERT_WITH_CODE(lookup_table && lookup_table->count,
718 "Lookup table is empty", return -EINVAL);
719
720 table_size = lookup_table->count;
721
722
723 for (i = 0; i < table_size - 1; i++) {
724 for (j = i + 1; j > 0; j--) {
725 if (lookup_table->entries[j].us_vdd <
726 lookup_table->entries[j - 1].us_vdd) {
727 tmp_voltage_lookup_record = lookup_table->entries[j - 1];
728 lookup_table->entries[j - 1] = lookup_table->entries[j];
729 lookup_table->entries[j] = tmp_voltage_lookup_record;
730 }
731 }
732 }
733
734 return 0;
735 }
736
737 static int vega10_complete_dependency_tables(struct pp_hwmgr *hwmgr)
738 {
739 int result = 0;
740 int tmp_result;
741 struct phm_ppt_v2_information *table_info =
742 (struct phm_ppt_v2_information *)(hwmgr->pptable);
743 #ifdef PPLIB_VEGA10_EVV_SUPPORT
744 struct vega10_hwmgr *data = hwmgr->backend;
745
746 tmp_result = vega10_patch_lookup_table_with_leakage(hwmgr,
747 table_info->vddc_lookup_table, &(data->vddc_leakage));
748 if (tmp_result)
749 result = tmp_result;
750
751 tmp_result = vega10_patch_clock_voltage_limits_with_vddc_leakage(hwmgr,
752 &(data->vddc_leakage), &table_info->max_clock_voltage_on_dc.vddc);
753 if (tmp_result)
754 result = tmp_result;
755 #endif
756
757 tmp_result = vega10_patch_voltage_dependency_tables_with_lookup_table(hwmgr);
758 if (tmp_result)
759 result = tmp_result;
760
761 tmp_result = vega10_sort_lookup_table(hwmgr, table_info->vddc_lookup_table);
762 if (tmp_result)
763 result = tmp_result;
764
765 return result;
766 }
767
768 static int vega10_set_private_data_based_on_pptable(struct pp_hwmgr *hwmgr)
769 {
770 struct phm_ppt_v2_information *table_info =
771 (struct phm_ppt_v2_information *)(hwmgr->pptable);
772 struct phm_ppt_v1_clock_voltage_dependency_table *allowed_sclk_vdd_table =
773 table_info->vdd_dep_on_socclk;
774 struct phm_ppt_v1_clock_voltage_dependency_table *allowed_mclk_vdd_table =
775 table_info->vdd_dep_on_mclk;
776
777 PP_ASSERT_WITH_CODE(allowed_sclk_vdd_table,
778 "VDD dependency on SCLK table is missing. This table is mandatory", return -EINVAL);
779 PP_ASSERT_WITH_CODE(allowed_sclk_vdd_table->count >= 1,
780 "VDD dependency on SCLK table is empty. This table is mandatory", return -EINVAL);
781
782 PP_ASSERT_WITH_CODE(allowed_mclk_vdd_table,
783 "VDD dependency on MCLK table is missing. This table is mandatory", return -EINVAL);
784 PP_ASSERT_WITH_CODE(allowed_mclk_vdd_table->count >= 1,
785 "VDD dependency on MCLK table is empty. This table is mandatory", return -EINVAL);
786
787 table_info->max_clock_voltage_on_ac.sclk =
788 allowed_sclk_vdd_table->entries[allowed_sclk_vdd_table->count - 1].clk;
789 table_info->max_clock_voltage_on_ac.mclk =
790 allowed_mclk_vdd_table->entries[allowed_mclk_vdd_table->count - 1].clk;
791 table_info->max_clock_voltage_on_ac.vddc =
792 allowed_sclk_vdd_table->entries[allowed_sclk_vdd_table->count - 1].vddc;
793 table_info->max_clock_voltage_on_ac.vddci =
794 allowed_mclk_vdd_table->entries[allowed_mclk_vdd_table->count - 1].vddci;
795
796 hwmgr->dyn_state.max_clock_voltage_on_ac.sclk =
797 table_info->max_clock_voltage_on_ac.sclk;
798 hwmgr->dyn_state.max_clock_voltage_on_ac.mclk =
799 table_info->max_clock_voltage_on_ac.mclk;
800 hwmgr->dyn_state.max_clock_voltage_on_ac.vddc =
801 table_info->max_clock_voltage_on_ac.vddc;
802 hwmgr->dyn_state.max_clock_voltage_on_ac.vddci =
803 table_info->max_clock_voltage_on_ac.vddci;
804
805 return 0;
806 }
807
808 static int vega10_hwmgr_backend_fini(struct pp_hwmgr *hwmgr)
809 {
810 kfree(hwmgr->dyn_state.vddc_dep_on_dal_pwrl);
811 hwmgr->dyn_state.vddc_dep_on_dal_pwrl = NULL;
812
813 kfree(hwmgr->backend);
814 hwmgr->backend = NULL;
815
816 return 0;
817 }
818
819 static int vega10_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
820 {
821 int result = 0;
822 struct vega10_hwmgr *data;
823 uint32_t config_telemetry = 0;
824 struct pp_atomfwctrl_voltage_table vol_table;
825 struct amdgpu_device *adev = hwmgr->adev;
826
827 data = kzalloc(sizeof(struct vega10_hwmgr), GFP_KERNEL);
828 if (data == NULL)
829 return -ENOMEM;
830
831 hwmgr->backend = data;
832
833 hwmgr->workload_mask = 1 << hwmgr->workload_prority[PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT];
834 hwmgr->power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
835 hwmgr->default_power_profile_mode = PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT;
836
837 vega10_set_default_registry_data(hwmgr);
838 data->disable_dpm_mask = 0xff;
839
840
841 data->vddc_control = VEGA10_VOLTAGE_CONTROL_NONE;
842 data->mvdd_control = VEGA10_VOLTAGE_CONTROL_NONE;
843 data->vddci_control = VEGA10_VOLTAGE_CONTROL_NONE;
844
845
846 if (pp_atomfwctrl_is_voltage_controlled_by_gpio_v4(hwmgr,
847 VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2)) {
848 if (!pp_atomfwctrl_get_voltage_table_v4(hwmgr,
849 VOLTAGE_TYPE_VDDC, VOLTAGE_OBJ_SVID2,
850 &vol_table)) {
851 config_telemetry = ((vol_table.telemetry_slope << 8) & 0xff00) |
852 (vol_table.telemetry_offset & 0xff);
853 data->vddc_control = VEGA10_VOLTAGE_CONTROL_BY_SVID2;
854 }
855 } else {
856 kfree(hwmgr->backend);
857 hwmgr->backend = NULL;
858 PP_ASSERT_WITH_CODE(false,
859 "VDDCR_SOC is not SVID2!",
860 return -1);
861 }
862
863
864 if (pp_atomfwctrl_is_voltage_controlled_by_gpio_v4(hwmgr,
865 VOLTAGE_TYPE_MVDDC, VOLTAGE_OBJ_SVID2)) {
866 if (!pp_atomfwctrl_get_voltage_table_v4(hwmgr,
867 VOLTAGE_TYPE_MVDDC, VOLTAGE_OBJ_SVID2,
868 &vol_table)) {
869 config_telemetry |=
870 ((vol_table.telemetry_slope << 24) & 0xff000000) |
871 ((vol_table.telemetry_offset << 16) & 0xff0000);
872 data->mvdd_control = VEGA10_VOLTAGE_CONTROL_BY_SVID2;
873 }
874 }
875
876
877 if (PP_CAP(PHM_PlatformCaps_ControlVDDCI)) {
878 if (pp_atomfwctrl_is_voltage_controlled_by_gpio_v4(hwmgr,
879 VOLTAGE_TYPE_VDDCI, VOLTAGE_OBJ_GPIO_LUT))
880 data->vddci_control = VEGA10_VOLTAGE_CONTROL_BY_GPIO;
881 }
882
883 data->config_telemetry = config_telemetry;
884
885 vega10_set_features_platform_caps(hwmgr);
886
887 vega10_init_dpm_defaults(hwmgr);
888
889 #ifdef PPLIB_VEGA10_EVV_SUPPORT
890
891 PP_ASSERT_WITH_CODE(!vega10_get_evv_voltages(hwmgr),
892 "Get EVV Voltage Failed. Abort Driver loading!",
893 return -1);
894 #endif
895
896
897
898
899 vega10_complete_dependency_tables(hwmgr);
900
901
902 vega10_set_private_data_based_on_pptable(hwmgr);
903
904 data->is_tlu_enabled = false;
905
906 hwmgr->platform_descriptor.hardwareActivityPerformanceLevels =
907 VEGA10_MAX_HARDWARE_POWERLEVELS;
908 hwmgr->platform_descriptor.hardwarePerformanceLevels = 2;
909 hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50;
910
911 hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400;
912
913 hwmgr->platform_descriptor.clockStep.engineClock = 500;
914 hwmgr->platform_descriptor.clockStep.memoryClock = 500;
915
916 data->total_active_cus = adev->gfx.cu_info.number;
917
918 data->odn_fan_table.target_fan_speed =
919 hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanRPM;
920 data->odn_fan_table.target_temperature =
921 hwmgr->thermal_controller.
922 advanceFanControlParameters.ucTargetTemperature;
923 data->odn_fan_table.min_performance_clock =
924 hwmgr->thermal_controller.advanceFanControlParameters.
925 ulMinFanSCLKAcousticLimit;
926 data->odn_fan_table.min_fan_limit =
927 hwmgr->thermal_controller.
928 advanceFanControlParameters.usFanPWMMinLimit *
929 hwmgr->thermal_controller.fanInfo.ulMaxRPM / 100;
930
931 data->mem_channels = (RREG32_SOC15(DF, 0, mmDF_CS_AON0_DramBaseAddress0) &
932 DF_CS_AON0_DramBaseAddress0__IntLvNumChan_MASK) >>
933 DF_CS_AON0_DramBaseAddress0__IntLvNumChan__SHIFT;
934 PP_ASSERT_WITH_CODE(data->mem_channels < ARRAY_SIZE(channel_number),
935 "Mem Channel Index Exceeded maximum!",
936 return -EINVAL);
937
938 return result;
939 }
940
941 static int vega10_init_sclk_threshold(struct pp_hwmgr *hwmgr)
942 {
943 struct vega10_hwmgr *data = hwmgr->backend;
944
945 data->low_sclk_interrupt_threshold = 0;
946
947 return 0;
948 }
949
950 static int vega10_setup_dpm_led_config(struct pp_hwmgr *hwmgr)
951 {
952 struct vega10_hwmgr *data = hwmgr->backend;
953 PPTable_t *pp_table = &(data->smc_state_table.pp_table);
954
955 struct pp_atomfwctrl_voltage_table table;
956 uint8_t i, j;
957 uint32_t mask = 0;
958 uint32_t tmp;
959 int32_t ret = 0;
960
961 ret = pp_atomfwctrl_get_voltage_table_v4(hwmgr, VOLTAGE_TYPE_LEDDPM,
962 VOLTAGE_OBJ_GPIO_LUT, &table);
963
964 if (!ret) {
965 tmp = table.mask_low;
966 for (i = 0, j = 0; i < 32; i++) {
967 if (tmp & 1) {
968 mask |= (uint32_t)(i << (8 * j));
969 if (++j >= 3)
970 break;
971 }
972 tmp >>= 1;
973 }
974 }
975
976 pp_table->LedPin0 = (uint8_t)(mask & 0xff);
977 pp_table->LedPin1 = (uint8_t)((mask >> 8) & 0xff);
978 pp_table->LedPin2 = (uint8_t)((mask >> 16) & 0xff);
979 return 0;
980 }
981
982 static int vega10_setup_asic_task(struct pp_hwmgr *hwmgr)
983 {
984 PP_ASSERT_WITH_CODE(!vega10_init_sclk_threshold(hwmgr),
985 "Failed to init sclk threshold!",
986 return -EINVAL);
987
988 PP_ASSERT_WITH_CODE(!vega10_setup_dpm_led_config(hwmgr),
989 "Failed to set up led dpm config!",
990 return -EINVAL);
991
992 smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_NumOfDisplays, 0);
993
994 return 0;
995 }
996
997
998
999
1000
1001
1002
1003
1004
1005 static int vega10_trim_voltage_table(struct pp_hwmgr *hwmgr,
1006 struct pp_atomfwctrl_voltage_table *vol_table)
1007 {
1008 uint32_t i, j;
1009 uint16_t vvalue;
1010 bool found = false;
1011 struct pp_atomfwctrl_voltage_table *table;
1012
1013 PP_ASSERT_WITH_CODE(vol_table,
1014 "Voltage Table empty.", return -EINVAL);
1015 table = kzalloc(sizeof(struct pp_atomfwctrl_voltage_table),
1016 GFP_KERNEL);
1017
1018 if (!table)
1019 return -ENOMEM;
1020
1021 table->mask_low = vol_table->mask_low;
1022 table->phase_delay = vol_table->phase_delay;
1023
1024 for (i = 0; i < vol_table->count; i++) {
1025 vvalue = vol_table->entries[i].value;
1026 found = false;
1027
1028 for (j = 0; j < table->count; j++) {
1029 if (vvalue == table->entries[j].value) {
1030 found = true;
1031 break;
1032 }
1033 }
1034
1035 if (!found) {
1036 table->entries[table->count].value = vvalue;
1037 table->entries[table->count].smio_low =
1038 vol_table->entries[i].smio_low;
1039 table->count++;
1040 }
1041 }
1042
1043 memcpy(vol_table, table, sizeof(struct pp_atomfwctrl_voltage_table));
1044 kfree(table);
1045
1046 return 0;
1047 }
1048
1049 static int vega10_get_mvdd_voltage_table(struct pp_hwmgr *hwmgr,
1050 phm_ppt_v1_clock_voltage_dependency_table *dep_table,
1051 struct pp_atomfwctrl_voltage_table *vol_table)
1052 {
1053 int i;
1054
1055 PP_ASSERT_WITH_CODE(dep_table->count,
1056 "Voltage Dependency Table empty.",
1057 return -EINVAL);
1058
1059 vol_table->mask_low = 0;
1060 vol_table->phase_delay = 0;
1061 vol_table->count = dep_table->count;
1062
1063 for (i = 0; i < vol_table->count; i++) {
1064 vol_table->entries[i].value = dep_table->entries[i].mvdd;
1065 vol_table->entries[i].smio_low = 0;
1066 }
1067
1068 PP_ASSERT_WITH_CODE(!vega10_trim_voltage_table(hwmgr,
1069 vol_table),
1070 "Failed to trim MVDD Table!",
1071 return -1);
1072
1073 return 0;
1074 }
1075
1076 static int vega10_get_vddci_voltage_table(struct pp_hwmgr *hwmgr,
1077 phm_ppt_v1_clock_voltage_dependency_table *dep_table,
1078 struct pp_atomfwctrl_voltage_table *vol_table)
1079 {
1080 uint32_t i;
1081
1082 PP_ASSERT_WITH_CODE(dep_table->count,
1083 "Voltage Dependency Table empty.",
1084 return -EINVAL);
1085
1086 vol_table->mask_low = 0;
1087 vol_table->phase_delay = 0;
1088 vol_table->count = dep_table->count;
1089
1090 for (i = 0; i < dep_table->count; i++) {
1091 vol_table->entries[i].value = dep_table->entries[i].vddci;
1092 vol_table->entries[i].smio_low = 0;
1093 }
1094
1095 PP_ASSERT_WITH_CODE(!vega10_trim_voltage_table(hwmgr, vol_table),
1096 "Failed to trim VDDCI table.",
1097 return -1);
1098
1099 return 0;
1100 }
1101
1102 static int vega10_get_vdd_voltage_table(struct pp_hwmgr *hwmgr,
1103 phm_ppt_v1_clock_voltage_dependency_table *dep_table,
1104 struct pp_atomfwctrl_voltage_table *vol_table)
1105 {
1106 int i;
1107
1108 PP_ASSERT_WITH_CODE(dep_table->count,
1109 "Voltage Dependency Table empty.",
1110 return -EINVAL);
1111
1112 vol_table->mask_low = 0;
1113 vol_table->phase_delay = 0;
1114 vol_table->count = dep_table->count;
1115
1116 for (i = 0; i < vol_table->count; i++) {
1117 vol_table->entries[i].value = dep_table->entries[i].vddc;
1118 vol_table->entries[i].smio_low = 0;
1119 }
1120
1121 return 0;
1122 }
1123
1124
1125
1126
1127
1128
1129 static void vega10_trim_voltage_table_to_fit_state_table(
1130 struct pp_hwmgr *hwmgr,
1131 uint32_t max_vol_steps,
1132 struct pp_atomfwctrl_voltage_table *vol_table)
1133 {
1134 unsigned int i, diff;
1135
1136 if (vol_table->count <= max_vol_steps)
1137 return;
1138
1139 diff = vol_table->count - max_vol_steps;
1140
1141 for (i = 0; i < max_vol_steps; i++)
1142 vol_table->entries[i] = vol_table->entries[i + diff];
1143
1144 vol_table->count = max_vol_steps;
1145 }
1146
1147
1148
1149
1150
1151
1152
1153 static int vega10_construct_voltage_tables(struct pp_hwmgr *hwmgr)
1154 {
1155 struct vega10_hwmgr *data = hwmgr->backend;
1156 struct phm_ppt_v2_information *table_info =
1157 (struct phm_ppt_v2_information *)hwmgr->pptable;
1158 int result;
1159
1160 if (data->mvdd_control == VEGA10_VOLTAGE_CONTROL_BY_SVID2 ||
1161 data->mvdd_control == VEGA10_VOLTAGE_CONTROL_NONE) {
1162 result = vega10_get_mvdd_voltage_table(hwmgr,
1163 table_info->vdd_dep_on_mclk,
1164 &(data->mvdd_voltage_table));
1165 PP_ASSERT_WITH_CODE(!result,
1166 "Failed to retrieve MVDDC table!",
1167 return result);
1168 }
1169
1170 if (data->vddci_control == VEGA10_VOLTAGE_CONTROL_NONE) {
1171 result = vega10_get_vddci_voltage_table(hwmgr,
1172 table_info->vdd_dep_on_mclk,
1173 &(data->vddci_voltage_table));
1174 PP_ASSERT_WITH_CODE(!result,
1175 "Failed to retrieve VDDCI_MEM table!",
1176 return result);
1177 }
1178
1179 if (data->vddc_control == VEGA10_VOLTAGE_CONTROL_BY_SVID2 ||
1180 data->vddc_control == VEGA10_VOLTAGE_CONTROL_NONE) {
1181 result = vega10_get_vdd_voltage_table(hwmgr,
1182 table_info->vdd_dep_on_sclk,
1183 &(data->vddc_voltage_table));
1184 PP_ASSERT_WITH_CODE(!result,
1185 "Failed to retrieve VDDCR_SOC table!",
1186 return result);
1187 }
1188
1189 PP_ASSERT_WITH_CODE(data->vddc_voltage_table.count <= 16,
1190 "Too many voltage values for VDDC. Trimming to fit state table.",
1191 vega10_trim_voltage_table_to_fit_state_table(hwmgr,
1192 16, &(data->vddc_voltage_table)));
1193
1194 PP_ASSERT_WITH_CODE(data->vddci_voltage_table.count <= 16,
1195 "Too many voltage values for VDDCI. Trimming to fit state table.",
1196 vega10_trim_voltage_table_to_fit_state_table(hwmgr,
1197 16, &(data->vddci_voltage_table)));
1198
1199 PP_ASSERT_WITH_CODE(data->mvdd_voltage_table.count <= 16,
1200 "Too many voltage values for MVDD. Trimming to fit state table.",
1201 vega10_trim_voltage_table_to_fit_state_table(hwmgr,
1202 16, &(data->mvdd_voltage_table)));
1203
1204
1205 return 0;
1206 }
1207
1208
1209
1210
1211
1212
1213
1214
1215 static void vega10_init_dpm_state(struct vega10_dpm_state *dpm_state)
1216 {
1217 dpm_state->soft_min_level = 0xff;
1218 dpm_state->soft_max_level = 0xff;
1219 dpm_state->hard_min_level = 0xff;
1220 dpm_state->hard_max_level = 0xff;
1221 }
1222
1223 static void vega10_setup_default_single_dpm_table(struct pp_hwmgr *hwmgr,
1224 struct vega10_single_dpm_table *dpm_table,
1225 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table)
1226 {
1227 int i;
1228
1229 dpm_table->count = 0;
1230
1231 for (i = 0; i < dep_table->count; i++) {
1232 if (i == 0 || dpm_table->dpm_levels[dpm_table->count - 1].value <=
1233 dep_table->entries[i].clk) {
1234 dpm_table->dpm_levels[dpm_table->count].value =
1235 dep_table->entries[i].clk;
1236 dpm_table->dpm_levels[dpm_table->count].enabled = true;
1237 dpm_table->count++;
1238 }
1239 }
1240 }
1241 static int vega10_setup_default_pcie_table(struct pp_hwmgr *hwmgr)
1242 {
1243 struct vega10_hwmgr *data = hwmgr->backend;
1244 struct vega10_pcie_table *pcie_table = &(data->dpm_table.pcie_table);
1245 struct phm_ppt_v2_information *table_info =
1246 (struct phm_ppt_v2_information *)(hwmgr->pptable);
1247 struct phm_ppt_v1_pcie_table *bios_pcie_table =
1248 table_info->pcie_table;
1249 uint32_t i;
1250
1251 PP_ASSERT_WITH_CODE(bios_pcie_table->count,
1252 "Incorrect number of PCIE States from VBIOS!",
1253 return -1);
1254
1255 for (i = 0; i < NUM_LINK_LEVELS; i++) {
1256 if (data->registry_data.pcieSpeedOverride)
1257 pcie_table->pcie_gen[i] =
1258 data->registry_data.pcieSpeedOverride;
1259 else
1260 pcie_table->pcie_gen[i] =
1261 bios_pcie_table->entries[i].gen_speed;
1262
1263 if (data->registry_data.pcieLaneOverride)
1264 pcie_table->pcie_lane[i] = (uint8_t)encode_pcie_lane_width(
1265 data->registry_data.pcieLaneOverride);
1266 else
1267 pcie_table->pcie_lane[i] = (uint8_t)encode_pcie_lane_width(
1268 bios_pcie_table->entries[i].lane_width);
1269 if (data->registry_data.pcieClockOverride)
1270 pcie_table->lclk[i] =
1271 data->registry_data.pcieClockOverride;
1272 else
1273 pcie_table->lclk[i] =
1274 bios_pcie_table->entries[i].pcie_sclk;
1275 }
1276
1277 pcie_table->count = NUM_LINK_LEVELS;
1278
1279 return 0;
1280 }
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290 static int vega10_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
1291 {
1292 struct vega10_hwmgr *data = hwmgr->backend;
1293 struct phm_ppt_v2_information *table_info =
1294 (struct phm_ppt_v2_information *)(hwmgr->pptable);
1295 struct vega10_single_dpm_table *dpm_table;
1296 uint32_t i;
1297
1298 struct phm_ppt_v1_clock_voltage_dependency_table *dep_soc_table =
1299 table_info->vdd_dep_on_socclk;
1300 struct phm_ppt_v1_clock_voltage_dependency_table *dep_gfx_table =
1301 table_info->vdd_dep_on_sclk;
1302 struct phm_ppt_v1_clock_voltage_dependency_table *dep_mclk_table =
1303 table_info->vdd_dep_on_mclk;
1304 struct phm_ppt_v1_mm_clock_voltage_dependency_table *dep_mm_table =
1305 table_info->mm_dep_table;
1306 struct phm_ppt_v1_clock_voltage_dependency_table *dep_dcef_table =
1307 table_info->vdd_dep_on_dcefclk;
1308 struct phm_ppt_v1_clock_voltage_dependency_table *dep_pix_table =
1309 table_info->vdd_dep_on_pixclk;
1310 struct phm_ppt_v1_clock_voltage_dependency_table *dep_disp_table =
1311 table_info->vdd_dep_on_dispclk;
1312 struct phm_ppt_v1_clock_voltage_dependency_table *dep_phy_table =
1313 table_info->vdd_dep_on_phyclk;
1314
1315 PP_ASSERT_WITH_CODE(dep_soc_table,
1316 "SOCCLK dependency table is missing. This table is mandatory",
1317 return -EINVAL);
1318 PP_ASSERT_WITH_CODE(dep_soc_table->count >= 1,
1319 "SOCCLK dependency table is empty. This table is mandatory",
1320 return -EINVAL);
1321
1322 PP_ASSERT_WITH_CODE(dep_gfx_table,
1323 "GFXCLK dependency table is missing. This table is mandatory",
1324 return -EINVAL);
1325 PP_ASSERT_WITH_CODE(dep_gfx_table->count >= 1,
1326 "GFXCLK dependency table is empty. This table is mandatory",
1327 return -EINVAL);
1328
1329 PP_ASSERT_WITH_CODE(dep_mclk_table,
1330 "MCLK dependency table is missing. This table is mandatory",
1331 return -EINVAL);
1332 PP_ASSERT_WITH_CODE(dep_mclk_table->count >= 1,
1333 "MCLK dependency table has to have is missing. This table is mandatory",
1334 return -EINVAL);
1335
1336
1337 dpm_table = &(data->dpm_table.soc_table);
1338 vega10_setup_default_single_dpm_table(hwmgr,
1339 dpm_table,
1340 dep_soc_table);
1341
1342 vega10_init_dpm_state(&(dpm_table->dpm_state));
1343
1344 dpm_table = &(data->dpm_table.gfx_table);
1345 vega10_setup_default_single_dpm_table(hwmgr,
1346 dpm_table,
1347 dep_gfx_table);
1348 if (hwmgr->platform_descriptor.overdriveLimit.engineClock == 0)
1349 hwmgr->platform_descriptor.overdriveLimit.engineClock =
1350 dpm_table->dpm_levels[dpm_table->count-1].value;
1351 vega10_init_dpm_state(&(dpm_table->dpm_state));
1352
1353
1354 data->dpm_table.mem_table.count = 0;
1355 dpm_table = &(data->dpm_table.mem_table);
1356 vega10_setup_default_single_dpm_table(hwmgr,
1357 dpm_table,
1358 dep_mclk_table);
1359 if (hwmgr->platform_descriptor.overdriveLimit.memoryClock == 0)
1360 hwmgr->platform_descriptor.overdriveLimit.memoryClock =
1361 dpm_table->dpm_levels[dpm_table->count-1].value;
1362 vega10_init_dpm_state(&(dpm_table->dpm_state));
1363
1364 data->dpm_table.eclk_table.count = 0;
1365 dpm_table = &(data->dpm_table.eclk_table);
1366 for (i = 0; i < dep_mm_table->count; i++) {
1367 if (i == 0 || dpm_table->dpm_levels
1368 [dpm_table->count - 1].value <=
1369 dep_mm_table->entries[i].eclk) {
1370 dpm_table->dpm_levels[dpm_table->count].value =
1371 dep_mm_table->entries[i].eclk;
1372 dpm_table->dpm_levels[dpm_table->count].enabled =
1373 (i == 0) ? true : false;
1374 dpm_table->count++;
1375 }
1376 }
1377 vega10_init_dpm_state(&(dpm_table->dpm_state));
1378
1379 data->dpm_table.vclk_table.count = 0;
1380 data->dpm_table.dclk_table.count = 0;
1381 dpm_table = &(data->dpm_table.vclk_table);
1382 for (i = 0; i < dep_mm_table->count; i++) {
1383 if (i == 0 || dpm_table->dpm_levels
1384 [dpm_table->count - 1].value <=
1385 dep_mm_table->entries[i].vclk) {
1386 dpm_table->dpm_levels[dpm_table->count].value =
1387 dep_mm_table->entries[i].vclk;
1388 dpm_table->dpm_levels[dpm_table->count].enabled =
1389 (i == 0) ? true : false;
1390 dpm_table->count++;
1391 }
1392 }
1393 vega10_init_dpm_state(&(dpm_table->dpm_state));
1394
1395 dpm_table = &(data->dpm_table.dclk_table);
1396 for (i = 0; i < dep_mm_table->count; i++) {
1397 if (i == 0 || dpm_table->dpm_levels
1398 [dpm_table->count - 1].value <=
1399 dep_mm_table->entries[i].dclk) {
1400 dpm_table->dpm_levels[dpm_table->count].value =
1401 dep_mm_table->entries[i].dclk;
1402 dpm_table->dpm_levels[dpm_table->count].enabled =
1403 (i == 0) ? true : false;
1404 dpm_table->count++;
1405 }
1406 }
1407 vega10_init_dpm_state(&(dpm_table->dpm_state));
1408
1409
1410 dpm_table = &(data->dpm_table.dcef_table);
1411 vega10_setup_default_single_dpm_table(hwmgr,
1412 dpm_table,
1413 dep_dcef_table);
1414
1415 vega10_init_dpm_state(&(dpm_table->dpm_state));
1416
1417 dpm_table = &(data->dpm_table.pixel_table);
1418 vega10_setup_default_single_dpm_table(hwmgr,
1419 dpm_table,
1420 dep_pix_table);
1421
1422 vega10_init_dpm_state(&(dpm_table->dpm_state));
1423
1424 dpm_table = &(data->dpm_table.display_table);
1425 vega10_setup_default_single_dpm_table(hwmgr,
1426 dpm_table,
1427 dep_disp_table);
1428
1429 vega10_init_dpm_state(&(dpm_table->dpm_state));
1430
1431 dpm_table = &(data->dpm_table.phy_table);
1432 vega10_setup_default_single_dpm_table(hwmgr,
1433 dpm_table,
1434 dep_phy_table);
1435
1436 vega10_init_dpm_state(&(dpm_table->dpm_state));
1437
1438 vega10_setup_default_pcie_table(hwmgr);
1439
1440
1441
1442
1443
1444 data->custom_profile_mode[0] = 0;
1445 data->custom_profile_mode[1] = 0;
1446 data->custom_profile_mode[2] = 0;
1447 data->custom_profile_mode[3] = 0;
1448
1449
1450 memcpy(&(data->golden_dpm_table), &(data->dpm_table),
1451 sizeof(struct vega10_dpm_table));
1452
1453 return 0;
1454 }
1455
1456
1457
1458
1459
1460
1461
1462
1463 static int vega10_populate_ulv_state(struct pp_hwmgr *hwmgr)
1464 {
1465 struct vega10_hwmgr *data = hwmgr->backend;
1466 struct phm_ppt_v2_information *table_info =
1467 (struct phm_ppt_v2_information *)(hwmgr->pptable);
1468
1469 data->smc_state_table.pp_table.UlvOffsetVid =
1470 (uint8_t)table_info->us_ulv_voltage_offset;
1471
1472 data->smc_state_table.pp_table.UlvSmnclkDid =
1473 (uint8_t)(table_info->us_ulv_smnclk_did);
1474 data->smc_state_table.pp_table.UlvMp1clkDid =
1475 (uint8_t)(table_info->us_ulv_mp1clk_did);
1476 data->smc_state_table.pp_table.UlvGfxclkBypass =
1477 (uint8_t)(table_info->us_ulv_gfxclk_bypass);
1478 data->smc_state_table.pp_table.UlvPhaseSheddingPsi0 =
1479 (uint8_t)(data->vddc_voltage_table.psi0_enable);
1480 data->smc_state_table.pp_table.UlvPhaseSheddingPsi1 =
1481 (uint8_t)(data->vddc_voltage_table.psi1_enable);
1482
1483 return 0;
1484 }
1485
1486 static int vega10_populate_single_lclk_level(struct pp_hwmgr *hwmgr,
1487 uint32_t lclock, uint8_t *curr_lclk_did)
1488 {
1489 struct pp_atomfwctrl_clock_dividers_soc15 dividers;
1490
1491 PP_ASSERT_WITH_CODE(!pp_atomfwctrl_get_gpu_pll_dividers_vega10(
1492 hwmgr,
1493 COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK,
1494 lclock, ÷rs),
1495 "Failed to get LCLK clock settings from VBIOS!",
1496 return -1);
1497
1498 *curr_lclk_did = dividers.ulDid;
1499
1500 return 0;
1501 }
1502
1503 static int vega10_populate_smc_link_levels(struct pp_hwmgr *hwmgr)
1504 {
1505 int result = -1;
1506 struct vega10_hwmgr *data = hwmgr->backend;
1507 PPTable_t *pp_table = &(data->smc_state_table.pp_table);
1508 struct vega10_pcie_table *pcie_table =
1509 &(data->dpm_table.pcie_table);
1510 uint32_t i, j;
1511
1512 for (i = 0; i < pcie_table->count; i++) {
1513 pp_table->PcieGenSpeed[i] = pcie_table->pcie_gen[i];
1514 pp_table->PcieLaneCount[i] = pcie_table->pcie_lane[i];
1515
1516 result = vega10_populate_single_lclk_level(hwmgr,
1517 pcie_table->lclk[i], &(pp_table->LclkDid[i]));
1518 if (result) {
1519 pr_info("Populate LClock Level %d Failed!\n", i);
1520 return result;
1521 }
1522 }
1523
1524 j = i - 1;
1525 while (i < NUM_LINK_LEVELS) {
1526 pp_table->PcieGenSpeed[i] = pcie_table->pcie_gen[j];
1527 pp_table->PcieLaneCount[i] = pcie_table->pcie_lane[j];
1528
1529 result = vega10_populate_single_lclk_level(hwmgr,
1530 pcie_table->lclk[j], &(pp_table->LclkDid[i]));
1531 if (result) {
1532 pr_info("Populate LClock Level %d Failed!\n", i);
1533 return result;
1534 }
1535 i++;
1536 }
1537
1538 return result;
1539 }
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549 static int vega10_populate_single_gfx_level(struct pp_hwmgr *hwmgr,
1550 uint32_t gfx_clock, PllSetting_t *current_gfxclk_level,
1551 uint32_t *acg_freq)
1552 {
1553 struct phm_ppt_v2_information *table_info =
1554 (struct phm_ppt_v2_information *)(hwmgr->pptable);
1555 struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_sclk;
1556 struct vega10_hwmgr *data = hwmgr->backend;
1557 struct pp_atomfwctrl_clock_dividers_soc15 dividers;
1558 uint32_t gfx_max_clock =
1559 hwmgr->platform_descriptor.overdriveLimit.engineClock;
1560 uint32_t i = 0;
1561
1562 if (hwmgr->od_enabled)
1563 dep_on_sclk = (struct phm_ppt_v1_clock_voltage_dependency_table *)
1564 &(data->odn_dpm_table.vdd_dep_on_sclk);
1565 else
1566 dep_on_sclk = table_info->vdd_dep_on_sclk;
1567
1568 PP_ASSERT_WITH_CODE(dep_on_sclk,
1569 "Invalid SOC_VDD-GFX_CLK Dependency Table!",
1570 return -EINVAL);
1571
1572 if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_SCLK)
1573 gfx_clock = gfx_clock > gfx_max_clock ? gfx_max_clock : gfx_clock;
1574 else {
1575 for (i = 0; i < dep_on_sclk->count; i++) {
1576 if (dep_on_sclk->entries[i].clk == gfx_clock)
1577 break;
1578 }
1579 PP_ASSERT_WITH_CODE(dep_on_sclk->count > i,
1580 "Cannot find gfx_clk in SOC_VDD-GFX_CLK!",
1581 return -EINVAL);
1582 }
1583
1584 PP_ASSERT_WITH_CODE(!pp_atomfwctrl_get_gpu_pll_dividers_vega10(hwmgr,
1585 COMPUTE_GPUCLK_INPUT_FLAG_GFXCLK,
1586 gfx_clock, ÷rs),
1587 "Failed to get GFX Clock settings from VBIOS!",
1588 return -EINVAL);
1589
1590
1591 current_gfxclk_level->FbMult =
1592 cpu_to_le32(dividers.ulPll_fb_mult);
1593
1594 current_gfxclk_level->SsOn = dividers.ucPll_ss_enable;
1595 current_gfxclk_level->SsFbMult =
1596 cpu_to_le32(dividers.ulPll_ss_fbsmult);
1597 current_gfxclk_level->SsSlewFrac =
1598 cpu_to_le16(dividers.usPll_ss_slew_frac);
1599 current_gfxclk_level->Did = (uint8_t)(dividers.ulDid);
1600
1601 *acg_freq = gfx_clock / 100;
1602
1603 return 0;
1604 }
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614 static int vega10_populate_single_soc_level(struct pp_hwmgr *hwmgr,
1615 uint32_t soc_clock, uint8_t *current_soc_did,
1616 uint8_t *current_vol_index)
1617 {
1618 struct vega10_hwmgr *data = hwmgr->backend;
1619 struct phm_ppt_v2_information *table_info =
1620 (struct phm_ppt_v2_information *)(hwmgr->pptable);
1621 struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_soc;
1622 struct pp_atomfwctrl_clock_dividers_soc15 dividers;
1623 uint32_t i;
1624
1625 if (hwmgr->od_enabled) {
1626 dep_on_soc = (struct phm_ppt_v1_clock_voltage_dependency_table *)
1627 &data->odn_dpm_table.vdd_dep_on_socclk;
1628 for (i = 0; i < dep_on_soc->count; i++) {
1629 if (dep_on_soc->entries[i].clk >= soc_clock)
1630 break;
1631 }
1632 } else {
1633 dep_on_soc = table_info->vdd_dep_on_socclk;
1634 for (i = 0; i < dep_on_soc->count; i++) {
1635 if (dep_on_soc->entries[i].clk == soc_clock)
1636 break;
1637 }
1638 }
1639
1640 PP_ASSERT_WITH_CODE(dep_on_soc->count > i,
1641 "Cannot find SOC_CLK in SOC_VDD-SOC_CLK Dependency Table",
1642 return -EINVAL);
1643
1644 PP_ASSERT_WITH_CODE(!pp_atomfwctrl_get_gpu_pll_dividers_vega10(hwmgr,
1645 COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK,
1646 soc_clock, ÷rs),
1647 "Failed to get SOC Clock settings from VBIOS!",
1648 return -EINVAL);
1649
1650 *current_soc_did = (uint8_t)dividers.ulDid;
1651 *current_vol_index = (uint8_t)(dep_on_soc->entries[i].vddInd);
1652 return 0;
1653 }
1654
1655
1656
1657
1658
1659
1660 static int vega10_populate_all_graphic_levels(struct pp_hwmgr *hwmgr)
1661 {
1662 struct vega10_hwmgr *data = hwmgr->backend;
1663 struct phm_ppt_v2_information *table_info =
1664 (struct phm_ppt_v2_information *)(hwmgr->pptable);
1665 PPTable_t *pp_table = &(data->smc_state_table.pp_table);
1666 struct vega10_single_dpm_table *dpm_table = &(data->dpm_table.gfx_table);
1667 int result = 0;
1668 uint32_t i, j;
1669
1670 for (i = 0; i < dpm_table->count; i++) {
1671 result = vega10_populate_single_gfx_level(hwmgr,
1672 dpm_table->dpm_levels[i].value,
1673 &(pp_table->GfxclkLevel[i]),
1674 &(pp_table->AcgFreqTable[i]));
1675 if (result)
1676 return result;
1677 }
1678
1679 j = i - 1;
1680 while (i < NUM_GFXCLK_DPM_LEVELS) {
1681 result = vega10_populate_single_gfx_level(hwmgr,
1682 dpm_table->dpm_levels[j].value,
1683 &(pp_table->GfxclkLevel[i]),
1684 &(pp_table->AcgFreqTable[i]));
1685 if (result)
1686 return result;
1687 i++;
1688 }
1689
1690 pp_table->GfxclkSlewRate =
1691 cpu_to_le16(table_info->us_gfxclk_slew_rate);
1692
1693 dpm_table = &(data->dpm_table.soc_table);
1694 for (i = 0; i < dpm_table->count; i++) {
1695 result = vega10_populate_single_soc_level(hwmgr,
1696 dpm_table->dpm_levels[i].value,
1697 &(pp_table->SocclkDid[i]),
1698 &(pp_table->SocDpmVoltageIndex[i]));
1699 if (result)
1700 return result;
1701 }
1702
1703 j = i - 1;
1704 while (i < NUM_SOCCLK_DPM_LEVELS) {
1705 result = vega10_populate_single_soc_level(hwmgr,
1706 dpm_table->dpm_levels[j].value,
1707 &(pp_table->SocclkDid[i]),
1708 &(pp_table->SocDpmVoltageIndex[i]));
1709 if (result)
1710 return result;
1711 i++;
1712 }
1713
1714 return result;
1715 }
1716
1717 static void vega10_populate_vddc_soc_levels(struct pp_hwmgr *hwmgr)
1718 {
1719 struct vega10_hwmgr *data = hwmgr->backend;
1720 PPTable_t *pp_table = &(data->smc_state_table.pp_table);
1721 struct phm_ppt_v2_information *table_info = hwmgr->pptable;
1722 struct phm_ppt_v1_voltage_lookup_table *vddc_lookup_table;
1723
1724 uint8_t soc_vid = 0;
1725 uint32_t i, max_vddc_level;
1726
1727 if (hwmgr->od_enabled)
1728 vddc_lookup_table = (struct phm_ppt_v1_voltage_lookup_table *)&data->odn_dpm_table.vddc_lookup_table;
1729 else
1730 vddc_lookup_table = table_info->vddc_lookup_table;
1731
1732 max_vddc_level = vddc_lookup_table->count;
1733 for (i = 0; i < max_vddc_level; i++) {
1734 soc_vid = (uint8_t)convert_to_vid(vddc_lookup_table->entries[i].us_vdd);
1735 pp_table->SocVid[i] = soc_vid;
1736 }
1737 while (i < MAX_REGULAR_DPM_NUMBER) {
1738 pp_table->SocVid[i] = soc_vid;
1739 i++;
1740 }
1741 }
1742
1743
1744
1745
1746
1747
1748
1749
1750 static int vega10_populate_single_memory_level(struct pp_hwmgr *hwmgr,
1751 uint32_t mem_clock, uint8_t *current_mem_vid,
1752 PllSetting_t *current_memclk_level, uint8_t *current_mem_soc_vind)
1753 {
1754 struct vega10_hwmgr *data = hwmgr->backend;
1755 struct phm_ppt_v2_information *table_info =
1756 (struct phm_ppt_v2_information *)(hwmgr->pptable);
1757 struct phm_ppt_v1_clock_voltage_dependency_table *dep_on_mclk;
1758 struct pp_atomfwctrl_clock_dividers_soc15 dividers;
1759 uint32_t mem_max_clock =
1760 hwmgr->platform_descriptor.overdriveLimit.memoryClock;
1761 uint32_t i = 0;
1762
1763 if (hwmgr->od_enabled)
1764 dep_on_mclk = (struct phm_ppt_v1_clock_voltage_dependency_table *)
1765 &data->odn_dpm_table.vdd_dep_on_mclk;
1766 else
1767 dep_on_mclk = table_info->vdd_dep_on_mclk;
1768
1769 PP_ASSERT_WITH_CODE(dep_on_mclk,
1770 "Invalid SOC_VDD-UCLK Dependency Table!",
1771 return -EINVAL);
1772
1773 if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_MCLK) {
1774 mem_clock = mem_clock > mem_max_clock ? mem_max_clock : mem_clock;
1775 } else {
1776 for (i = 0; i < dep_on_mclk->count; i++) {
1777 if (dep_on_mclk->entries[i].clk == mem_clock)
1778 break;
1779 }
1780 PP_ASSERT_WITH_CODE(dep_on_mclk->count > i,
1781 "Cannot find UCLK in SOC_VDD-UCLK Dependency Table!",
1782 return -EINVAL);
1783 }
1784
1785 PP_ASSERT_WITH_CODE(!pp_atomfwctrl_get_gpu_pll_dividers_vega10(
1786 hwmgr, COMPUTE_GPUCLK_INPUT_FLAG_UCLK, mem_clock, ÷rs),
1787 "Failed to get UCLK settings from VBIOS!",
1788 return -1);
1789
1790 *current_mem_vid =
1791 (uint8_t)(convert_to_vid(dep_on_mclk->entries[i].mvdd));
1792 *current_mem_soc_vind =
1793 (uint8_t)(dep_on_mclk->entries[i].vddInd);
1794 current_memclk_level->FbMult = cpu_to_le32(dividers.ulPll_fb_mult);
1795 current_memclk_level->Did = (uint8_t)(dividers.ulDid);
1796
1797 PP_ASSERT_WITH_CODE(current_memclk_level->Did >= 1,
1798 "Invalid Divider ID!",
1799 return -EINVAL);
1800
1801 return 0;
1802 }
1803
1804
1805
1806
1807
1808
1809
1810 static int vega10_populate_all_memory_levels(struct pp_hwmgr *hwmgr)
1811 {
1812 struct vega10_hwmgr *data = hwmgr->backend;
1813 PPTable_t *pp_table = &(data->smc_state_table.pp_table);
1814 struct vega10_single_dpm_table *dpm_table =
1815 &(data->dpm_table.mem_table);
1816 int result = 0;
1817 uint32_t i, j;
1818
1819 for (i = 0; i < dpm_table->count; i++) {
1820 result = vega10_populate_single_memory_level(hwmgr,
1821 dpm_table->dpm_levels[i].value,
1822 &(pp_table->MemVid[i]),
1823 &(pp_table->UclkLevel[i]),
1824 &(pp_table->MemSocVoltageIndex[i]));
1825 if (result)
1826 return result;
1827 }
1828
1829 j = i - 1;
1830 while (i < NUM_UCLK_DPM_LEVELS) {
1831 result = vega10_populate_single_memory_level(hwmgr,
1832 dpm_table->dpm_levels[j].value,
1833 &(pp_table->MemVid[i]),
1834 &(pp_table->UclkLevel[i]),
1835 &(pp_table->MemSocVoltageIndex[i]));
1836 if (result)
1837 return result;
1838 i++;
1839 }
1840
1841 pp_table->NumMemoryChannels = (uint16_t)(data->mem_channels);
1842 pp_table->MemoryChannelWidth =
1843 (uint16_t)(HBM_MEMORY_CHANNEL_WIDTH *
1844 channel_number[data->mem_channels]);
1845
1846 pp_table->LowestUclkReservedForUlv =
1847 (uint8_t)(data->lowest_uclk_reserved_for_ulv);
1848
1849 return result;
1850 }
1851
1852 static int vega10_populate_single_display_type(struct pp_hwmgr *hwmgr,
1853 DSPCLK_e disp_clock)
1854 {
1855 struct vega10_hwmgr *data = hwmgr->backend;
1856 PPTable_t *pp_table = &(data->smc_state_table.pp_table);
1857 struct phm_ppt_v2_information *table_info =
1858 (struct phm_ppt_v2_information *)
1859 (hwmgr->pptable);
1860 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table;
1861 uint32_t i;
1862 uint16_t clk = 0, vddc = 0;
1863 uint8_t vid = 0;
1864
1865 switch (disp_clock) {
1866 case DSPCLK_DCEFCLK:
1867 dep_table = table_info->vdd_dep_on_dcefclk;
1868 break;
1869 case DSPCLK_DISPCLK:
1870 dep_table = table_info->vdd_dep_on_dispclk;
1871 break;
1872 case DSPCLK_PIXCLK:
1873 dep_table = table_info->vdd_dep_on_pixclk;
1874 break;
1875 case DSPCLK_PHYCLK:
1876 dep_table = table_info->vdd_dep_on_phyclk;
1877 break;
1878 default:
1879 return -1;
1880 }
1881
1882 PP_ASSERT_WITH_CODE(dep_table->count <= NUM_DSPCLK_LEVELS,
1883 "Number Of Entries Exceeded maximum!",
1884 return -1);
1885
1886 for (i = 0; i < dep_table->count; i++) {
1887 clk = (uint16_t)(dep_table->entries[i].clk / 100);
1888 vddc = table_info->vddc_lookup_table->
1889 entries[dep_table->entries[i].vddInd].us_vdd;
1890 vid = (uint8_t)convert_to_vid(vddc);
1891 pp_table->DisplayClockTable[disp_clock][i].Freq =
1892 cpu_to_le16(clk);
1893 pp_table->DisplayClockTable[disp_clock][i].Vid =
1894 cpu_to_le16(vid);
1895 }
1896
1897 while (i < NUM_DSPCLK_LEVELS) {
1898 pp_table->DisplayClockTable[disp_clock][i].Freq =
1899 cpu_to_le16(clk);
1900 pp_table->DisplayClockTable[disp_clock][i].Vid =
1901 cpu_to_le16(vid);
1902 i++;
1903 }
1904
1905 return 0;
1906 }
1907
1908 static int vega10_populate_all_display_clock_levels(struct pp_hwmgr *hwmgr)
1909 {
1910 uint32_t i;
1911
1912 for (i = 0; i < DSPCLK_COUNT; i++) {
1913 PP_ASSERT_WITH_CODE(!vega10_populate_single_display_type(hwmgr, i),
1914 "Failed to populate Clock in DisplayClockTable!",
1915 return -1);
1916 }
1917
1918 return 0;
1919 }
1920
1921 static int vega10_populate_single_eclock_level(struct pp_hwmgr *hwmgr,
1922 uint32_t eclock, uint8_t *current_eclk_did,
1923 uint8_t *current_soc_vol)
1924 {
1925 struct phm_ppt_v2_information *table_info =
1926 (struct phm_ppt_v2_information *)(hwmgr->pptable);
1927 struct phm_ppt_v1_mm_clock_voltage_dependency_table *dep_table =
1928 table_info->mm_dep_table;
1929 struct pp_atomfwctrl_clock_dividers_soc15 dividers;
1930 uint32_t i;
1931
1932 PP_ASSERT_WITH_CODE(!pp_atomfwctrl_get_gpu_pll_dividers_vega10(hwmgr,
1933 COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK,
1934 eclock, ÷rs),
1935 "Failed to get ECLK clock settings from VBIOS!",
1936 return -1);
1937
1938 *current_eclk_did = (uint8_t)dividers.ulDid;
1939
1940 for (i = 0; i < dep_table->count; i++) {
1941 if (dep_table->entries[i].eclk == eclock)
1942 *current_soc_vol = dep_table->entries[i].vddcInd;
1943 }
1944
1945 return 0;
1946 }
1947
1948 static int vega10_populate_smc_vce_levels(struct pp_hwmgr *hwmgr)
1949 {
1950 struct vega10_hwmgr *data = hwmgr->backend;
1951 PPTable_t *pp_table = &(data->smc_state_table.pp_table);
1952 struct vega10_single_dpm_table *dpm_table = &(data->dpm_table.eclk_table);
1953 int result = -EINVAL;
1954 uint32_t i, j;
1955
1956 for (i = 0; i < dpm_table->count; i++) {
1957 result = vega10_populate_single_eclock_level(hwmgr,
1958 dpm_table->dpm_levels[i].value,
1959 &(pp_table->EclkDid[i]),
1960 &(pp_table->VceDpmVoltageIndex[i]));
1961 if (result)
1962 return result;
1963 }
1964
1965 j = i - 1;
1966 while (i < NUM_VCE_DPM_LEVELS) {
1967 result = vega10_populate_single_eclock_level(hwmgr,
1968 dpm_table->dpm_levels[j].value,
1969 &(pp_table->EclkDid[i]),
1970 &(pp_table->VceDpmVoltageIndex[i]));
1971 if (result)
1972 return result;
1973 i++;
1974 }
1975
1976 return result;
1977 }
1978
1979 static int vega10_populate_single_vclock_level(struct pp_hwmgr *hwmgr,
1980 uint32_t vclock, uint8_t *current_vclk_did)
1981 {
1982 struct pp_atomfwctrl_clock_dividers_soc15 dividers;
1983
1984 PP_ASSERT_WITH_CODE(!pp_atomfwctrl_get_gpu_pll_dividers_vega10(hwmgr,
1985 COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK,
1986 vclock, ÷rs),
1987 "Failed to get VCLK clock settings from VBIOS!",
1988 return -EINVAL);
1989
1990 *current_vclk_did = (uint8_t)dividers.ulDid;
1991
1992 return 0;
1993 }
1994
1995 static int vega10_populate_single_dclock_level(struct pp_hwmgr *hwmgr,
1996 uint32_t dclock, uint8_t *current_dclk_did)
1997 {
1998 struct pp_atomfwctrl_clock_dividers_soc15 dividers;
1999
2000 PP_ASSERT_WITH_CODE(!pp_atomfwctrl_get_gpu_pll_dividers_vega10(hwmgr,
2001 COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK,
2002 dclock, ÷rs),
2003 "Failed to get DCLK clock settings from VBIOS!",
2004 return -EINVAL);
2005
2006 *current_dclk_did = (uint8_t)dividers.ulDid;
2007
2008 return 0;
2009 }
2010
2011 static int vega10_populate_smc_uvd_levels(struct pp_hwmgr *hwmgr)
2012 {
2013 struct vega10_hwmgr *data = hwmgr->backend;
2014 PPTable_t *pp_table = &(data->smc_state_table.pp_table);
2015 struct vega10_single_dpm_table *vclk_dpm_table =
2016 &(data->dpm_table.vclk_table);
2017 struct vega10_single_dpm_table *dclk_dpm_table =
2018 &(data->dpm_table.dclk_table);
2019 struct phm_ppt_v2_information *table_info =
2020 (struct phm_ppt_v2_information *)(hwmgr->pptable);
2021 struct phm_ppt_v1_mm_clock_voltage_dependency_table *dep_table =
2022 table_info->mm_dep_table;
2023 int result = -EINVAL;
2024 uint32_t i, j;
2025
2026 for (i = 0; i < vclk_dpm_table->count; i++) {
2027 result = vega10_populate_single_vclock_level(hwmgr,
2028 vclk_dpm_table->dpm_levels[i].value,
2029 &(pp_table->VclkDid[i]));
2030 if (result)
2031 return result;
2032 }
2033
2034 j = i - 1;
2035 while (i < NUM_UVD_DPM_LEVELS) {
2036 result = vega10_populate_single_vclock_level(hwmgr,
2037 vclk_dpm_table->dpm_levels[j].value,
2038 &(pp_table->VclkDid[i]));
2039 if (result)
2040 return result;
2041 i++;
2042 }
2043
2044 for (i = 0; i < dclk_dpm_table->count; i++) {
2045 result = vega10_populate_single_dclock_level(hwmgr,
2046 dclk_dpm_table->dpm_levels[i].value,
2047 &(pp_table->DclkDid[i]));
2048 if (result)
2049 return result;
2050 }
2051
2052 j = i - 1;
2053 while (i < NUM_UVD_DPM_LEVELS) {
2054 result = vega10_populate_single_dclock_level(hwmgr,
2055 dclk_dpm_table->dpm_levels[j].value,
2056 &(pp_table->DclkDid[i]));
2057 if (result)
2058 return result;
2059 i++;
2060 }
2061
2062 for (i = 0; i < dep_table->count; i++) {
2063 if (dep_table->entries[i].vclk ==
2064 vclk_dpm_table->dpm_levels[i].value &&
2065 dep_table->entries[i].dclk ==
2066 dclk_dpm_table->dpm_levels[i].value)
2067 pp_table->UvdDpmVoltageIndex[i] =
2068 dep_table->entries[i].vddcInd;
2069 else
2070 return -1;
2071 }
2072
2073 j = i - 1;
2074 while (i < NUM_UVD_DPM_LEVELS) {
2075 pp_table->UvdDpmVoltageIndex[i] = dep_table->entries[j].vddcInd;
2076 i++;
2077 }
2078
2079 return 0;
2080 }
2081
2082 static int vega10_populate_clock_stretcher_table(struct pp_hwmgr *hwmgr)
2083 {
2084 struct vega10_hwmgr *data = hwmgr->backend;
2085 PPTable_t *pp_table = &(data->smc_state_table.pp_table);
2086 struct phm_ppt_v2_information *table_info =
2087 (struct phm_ppt_v2_information *)(hwmgr->pptable);
2088 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table =
2089 table_info->vdd_dep_on_sclk;
2090 uint32_t i;
2091
2092 for (i = 0; i < dep_table->count; i++) {
2093 pp_table->CksEnable[i] = dep_table->entries[i].cks_enable;
2094 pp_table->CksVidOffset[i] = (uint8_t)(dep_table->entries[i].cks_voffset
2095 * VOLTAGE_VID_OFFSET_SCALE2 / VOLTAGE_VID_OFFSET_SCALE1);
2096 }
2097
2098 return 0;
2099 }
2100
2101 static int vega10_populate_avfs_parameters(struct pp_hwmgr *hwmgr)
2102 {
2103 struct vega10_hwmgr *data = hwmgr->backend;
2104 PPTable_t *pp_table = &(data->smc_state_table.pp_table);
2105 struct phm_ppt_v2_information *table_info =
2106 (struct phm_ppt_v2_information *)(hwmgr->pptable);
2107 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table =
2108 table_info->vdd_dep_on_sclk;
2109 struct pp_atomfwctrl_avfs_parameters avfs_params = {0};
2110 int result = 0;
2111 uint32_t i;
2112
2113 pp_table->MinVoltageVid = (uint8_t)0xff;
2114 pp_table->MaxVoltageVid = (uint8_t)0;
2115
2116 if (data->smu_features[GNLD_AVFS].supported) {
2117 result = pp_atomfwctrl_get_avfs_information(hwmgr, &avfs_params);
2118 if (!result) {
2119 pp_table->MinVoltageVid = (uint8_t)
2120 convert_to_vid((uint16_t)(avfs_params.ulMinVddc));
2121 pp_table->MaxVoltageVid = (uint8_t)
2122 convert_to_vid((uint16_t)(avfs_params.ulMaxVddc));
2123
2124 pp_table->AConstant[0] = cpu_to_le32(avfs_params.ulMeanNsigmaAcontant0);
2125 pp_table->AConstant[1] = cpu_to_le32(avfs_params.ulMeanNsigmaAcontant1);
2126 pp_table->AConstant[2] = cpu_to_le32(avfs_params.ulMeanNsigmaAcontant2);
2127 pp_table->DC_tol_sigma = cpu_to_le16(avfs_params.usMeanNsigmaDcTolSigma);
2128 pp_table->Platform_mean = cpu_to_le16(avfs_params.usMeanNsigmaPlatformMean);
2129 pp_table->Platform_sigma = cpu_to_le16(avfs_params.usMeanNsigmaDcTolSigma);
2130 pp_table->PSM_Age_CompFactor = cpu_to_le16(avfs_params.usPsmAgeComfactor);
2131
2132 pp_table->BtcGbVdroopTableCksOff.a0 =
2133 cpu_to_le32(avfs_params.ulGbVdroopTableCksoffA0);
2134 pp_table->BtcGbVdroopTableCksOff.a0_shift = 20;
2135 pp_table->BtcGbVdroopTableCksOff.a1 =
2136 cpu_to_le32(avfs_params.ulGbVdroopTableCksoffA1);
2137 pp_table->BtcGbVdroopTableCksOff.a1_shift = 20;
2138 pp_table->BtcGbVdroopTableCksOff.a2 =
2139 cpu_to_le32(avfs_params.ulGbVdroopTableCksoffA2);
2140 pp_table->BtcGbVdroopTableCksOff.a2_shift = 20;
2141
2142 pp_table->OverrideBtcGbCksOn = avfs_params.ucEnableGbVdroopTableCkson;
2143 pp_table->BtcGbVdroopTableCksOn.a0 =
2144 cpu_to_le32(avfs_params.ulGbVdroopTableCksonA0);
2145 pp_table->BtcGbVdroopTableCksOn.a0_shift = 20;
2146 pp_table->BtcGbVdroopTableCksOn.a1 =
2147 cpu_to_le32(avfs_params.ulGbVdroopTableCksonA1);
2148 pp_table->BtcGbVdroopTableCksOn.a1_shift = 20;
2149 pp_table->BtcGbVdroopTableCksOn.a2 =
2150 cpu_to_le32(avfs_params.ulGbVdroopTableCksonA2);
2151 pp_table->BtcGbVdroopTableCksOn.a2_shift = 20;
2152
2153 pp_table->AvfsGbCksOn.m1 =
2154 cpu_to_le32(avfs_params.ulGbFuseTableCksonM1);
2155 pp_table->AvfsGbCksOn.m2 =
2156 cpu_to_le32(avfs_params.ulGbFuseTableCksonM2);
2157 pp_table->AvfsGbCksOn.b =
2158 cpu_to_le32(avfs_params.ulGbFuseTableCksonB);
2159 pp_table->AvfsGbCksOn.m1_shift = 24;
2160 pp_table->AvfsGbCksOn.m2_shift = 12;
2161 pp_table->AvfsGbCksOn.b_shift = 0;
2162
2163 pp_table->OverrideAvfsGbCksOn =
2164 avfs_params.ucEnableGbFuseTableCkson;
2165 pp_table->AvfsGbCksOff.m1 =
2166 cpu_to_le32(avfs_params.ulGbFuseTableCksoffM1);
2167 pp_table->AvfsGbCksOff.m2 =
2168 cpu_to_le32(avfs_params.ulGbFuseTableCksoffM2);
2169 pp_table->AvfsGbCksOff.b =
2170 cpu_to_le32(avfs_params.ulGbFuseTableCksoffB);
2171 pp_table->AvfsGbCksOff.m1_shift = 24;
2172 pp_table->AvfsGbCksOff.m2_shift = 12;
2173 pp_table->AvfsGbCksOff.b_shift = 0;
2174
2175 for (i = 0; i < dep_table->count; i++)
2176 pp_table->StaticVoltageOffsetVid[i] =
2177 convert_to_vid((uint8_t)(dep_table->entries[i].sclk_offset));
2178
2179 if ((PPREGKEY_VEGA10QUADRATICEQUATION_DFLT !=
2180 data->disp_clk_quad_eqn_a) &&
2181 (PPREGKEY_VEGA10QUADRATICEQUATION_DFLT !=
2182 data->disp_clk_quad_eqn_b)) {
2183 pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].m1 =
2184 (int32_t)data->disp_clk_quad_eqn_a;
2185 pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].m2 =
2186 (int32_t)data->disp_clk_quad_eqn_b;
2187 pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].b =
2188 (int32_t)data->disp_clk_quad_eqn_c;
2189 } else {
2190 pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].m1 =
2191 (int32_t)avfs_params.ulDispclk2GfxclkM1;
2192 pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].m2 =
2193 (int32_t)avfs_params.ulDispclk2GfxclkM2;
2194 pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].b =
2195 (int32_t)avfs_params.ulDispclk2GfxclkB;
2196 }
2197
2198 pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].m1_shift = 24;
2199 pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].m2_shift = 12;
2200 pp_table->DisplayClock2Gfxclk[DSPCLK_DISPCLK].b_shift = 12;
2201
2202 if ((PPREGKEY_VEGA10QUADRATICEQUATION_DFLT !=
2203 data->dcef_clk_quad_eqn_a) &&
2204 (PPREGKEY_VEGA10QUADRATICEQUATION_DFLT !=
2205 data->dcef_clk_quad_eqn_b)) {
2206 pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].m1 =
2207 (int32_t)data->dcef_clk_quad_eqn_a;
2208 pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].m2 =
2209 (int32_t)data->dcef_clk_quad_eqn_b;
2210 pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].b =
2211 (int32_t)data->dcef_clk_quad_eqn_c;
2212 } else {
2213 pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].m1 =
2214 (int32_t)avfs_params.ulDcefclk2GfxclkM1;
2215 pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].m2 =
2216 (int32_t)avfs_params.ulDcefclk2GfxclkM2;
2217 pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].b =
2218 (int32_t)avfs_params.ulDcefclk2GfxclkB;
2219 }
2220
2221 pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].m1_shift = 24;
2222 pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].m2_shift = 12;
2223 pp_table->DisplayClock2Gfxclk[DSPCLK_DCEFCLK].b_shift = 12;
2224
2225 if ((PPREGKEY_VEGA10QUADRATICEQUATION_DFLT !=
2226 data->pixel_clk_quad_eqn_a) &&
2227 (PPREGKEY_VEGA10QUADRATICEQUATION_DFLT !=
2228 data->pixel_clk_quad_eqn_b)) {
2229 pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].m1 =
2230 (int32_t)data->pixel_clk_quad_eqn_a;
2231 pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].m2 =
2232 (int32_t)data->pixel_clk_quad_eqn_b;
2233 pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].b =
2234 (int32_t)data->pixel_clk_quad_eqn_c;
2235 } else {
2236 pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].m1 =
2237 (int32_t)avfs_params.ulPixelclk2GfxclkM1;
2238 pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].m2 =
2239 (int32_t)avfs_params.ulPixelclk2GfxclkM2;
2240 pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].b =
2241 (int32_t)avfs_params.ulPixelclk2GfxclkB;
2242 }
2243
2244 pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].m1_shift = 24;
2245 pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].m2_shift = 12;
2246 pp_table->DisplayClock2Gfxclk[DSPCLK_PIXCLK].b_shift = 12;
2247 if ((PPREGKEY_VEGA10QUADRATICEQUATION_DFLT !=
2248 data->phy_clk_quad_eqn_a) &&
2249 (PPREGKEY_VEGA10QUADRATICEQUATION_DFLT !=
2250 data->phy_clk_quad_eqn_b)) {
2251 pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].m1 =
2252 (int32_t)data->phy_clk_quad_eqn_a;
2253 pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].m2 =
2254 (int32_t)data->phy_clk_quad_eqn_b;
2255 pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].b =
2256 (int32_t)data->phy_clk_quad_eqn_c;
2257 } else {
2258 pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].m1 =
2259 (int32_t)avfs_params.ulPhyclk2GfxclkM1;
2260 pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].m2 =
2261 (int32_t)avfs_params.ulPhyclk2GfxclkM2;
2262 pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].b =
2263 (int32_t)avfs_params.ulPhyclk2GfxclkB;
2264 }
2265
2266 pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].m1_shift = 24;
2267 pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].m2_shift = 12;
2268 pp_table->DisplayClock2Gfxclk[DSPCLK_PHYCLK].b_shift = 12;
2269
2270 pp_table->AcgBtcGbVdroopTable.a0 = avfs_params.ulAcgGbVdroopTableA0;
2271 pp_table->AcgBtcGbVdroopTable.a0_shift = 20;
2272 pp_table->AcgBtcGbVdroopTable.a1 = avfs_params.ulAcgGbVdroopTableA1;
2273 pp_table->AcgBtcGbVdroopTable.a1_shift = 20;
2274 pp_table->AcgBtcGbVdroopTable.a2 = avfs_params.ulAcgGbVdroopTableA2;
2275 pp_table->AcgBtcGbVdroopTable.a2_shift = 20;
2276
2277 pp_table->AcgAvfsGb.m1 = avfs_params.ulAcgGbFuseTableM1;
2278 pp_table->AcgAvfsGb.m2 = avfs_params.ulAcgGbFuseTableM2;
2279 pp_table->AcgAvfsGb.b = avfs_params.ulAcgGbFuseTableB;
2280 pp_table->AcgAvfsGb.m1_shift = 24;
2281 pp_table->AcgAvfsGb.m2_shift = 12;
2282 pp_table->AcgAvfsGb.b_shift = 0;
2283
2284 } else {
2285 data->smu_features[GNLD_AVFS].supported = false;
2286 }
2287 }
2288
2289 return 0;
2290 }
2291
2292 static int vega10_acg_enable(struct pp_hwmgr *hwmgr)
2293 {
2294 struct vega10_hwmgr *data = hwmgr->backend;
2295 uint32_t agc_btc_response;
2296
2297 if (data->smu_features[GNLD_ACG].supported) {
2298 if (0 == vega10_enable_smc_features(hwmgr, true,
2299 data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_bitmap))
2300 data->smu_features[GNLD_DPM_PREFETCHER].enabled = true;
2301
2302 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_InitializeAcg);
2303
2304 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAcgBtc);
2305 agc_btc_response = smum_get_argument(hwmgr);
2306
2307 if (1 == agc_btc_response) {
2308 if (1 == data->acg_loop_state)
2309 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAcgInClosedLoop);
2310 else if (2 == data->acg_loop_state)
2311 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_RunAcgInOpenLoop);
2312 if (0 == vega10_enable_smc_features(hwmgr, true,
2313 data->smu_features[GNLD_ACG].smu_feature_bitmap))
2314 data->smu_features[GNLD_ACG].enabled = true;
2315 } else {
2316 pr_info("[ACG_Enable] ACG BTC Returned Failed Status!\n");
2317 data->smu_features[GNLD_ACG].enabled = false;
2318 }
2319 }
2320
2321 return 0;
2322 }
2323
2324 static int vega10_acg_disable(struct pp_hwmgr *hwmgr)
2325 {
2326 struct vega10_hwmgr *data = hwmgr->backend;
2327
2328 if (data->smu_features[GNLD_ACG].supported &&
2329 data->smu_features[GNLD_ACG].enabled)
2330 if (!vega10_enable_smc_features(hwmgr, false,
2331 data->smu_features[GNLD_ACG].smu_feature_bitmap))
2332 data->smu_features[GNLD_ACG].enabled = false;
2333
2334 return 0;
2335 }
2336
2337 static int vega10_populate_gpio_parameters(struct pp_hwmgr *hwmgr)
2338 {
2339 struct vega10_hwmgr *data = hwmgr->backend;
2340 PPTable_t *pp_table = &(data->smc_state_table.pp_table);
2341 struct pp_atomfwctrl_gpio_parameters gpio_params = {0};
2342 int result;
2343
2344 result = pp_atomfwctrl_get_gpio_information(hwmgr, &gpio_params);
2345 if (!result) {
2346 if (PP_CAP(PHM_PlatformCaps_RegulatorHot) &&
2347 data->registry_data.regulator_hot_gpio_support) {
2348 pp_table->VR0HotGpio = gpio_params.ucVR0HotGpio;
2349 pp_table->VR0HotPolarity = gpio_params.ucVR0HotPolarity;
2350 pp_table->VR1HotGpio = gpio_params.ucVR1HotGpio;
2351 pp_table->VR1HotPolarity = gpio_params.ucVR1HotPolarity;
2352 } else {
2353 pp_table->VR0HotGpio = 0;
2354 pp_table->VR0HotPolarity = 0;
2355 pp_table->VR1HotGpio = 0;
2356 pp_table->VR1HotPolarity = 0;
2357 }
2358
2359 if (PP_CAP(PHM_PlatformCaps_AutomaticDCTransition) &&
2360 data->registry_data.ac_dc_switch_gpio_support) {
2361 pp_table->AcDcGpio = gpio_params.ucAcDcGpio;
2362 pp_table->AcDcPolarity = gpio_params.ucAcDcPolarity;
2363 } else {
2364 pp_table->AcDcGpio = 0;
2365 pp_table->AcDcPolarity = 0;
2366 }
2367 }
2368
2369 return result;
2370 }
2371
2372 static int vega10_avfs_enable(struct pp_hwmgr *hwmgr, bool enable)
2373 {
2374 struct vega10_hwmgr *data = hwmgr->backend;
2375
2376 if (data->smu_features[GNLD_AVFS].supported) {
2377
2378 if (!(enable ^ data->smu_features[GNLD_AVFS].enabled))
2379 return 0;
2380
2381 if (enable) {
2382 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
2383 true,
2384 data->smu_features[GNLD_AVFS].smu_feature_bitmap),
2385 "[avfs_control] Attempt to Enable AVFS feature Failed!",
2386 return -1);
2387 data->smu_features[GNLD_AVFS].enabled = true;
2388 } else {
2389 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
2390 false,
2391 data->smu_features[GNLD_AVFS].smu_feature_bitmap),
2392 "[avfs_control] Attempt to Disable AVFS feature Failed!",
2393 return -1);
2394 data->smu_features[GNLD_AVFS].enabled = false;
2395 }
2396 }
2397
2398 return 0;
2399 }
2400
2401 static int vega10_update_avfs(struct pp_hwmgr *hwmgr)
2402 {
2403 struct vega10_hwmgr *data = hwmgr->backend;
2404
2405 if (data->need_update_dpm_table & DPMTABLE_OD_UPDATE_VDDC) {
2406 vega10_avfs_enable(hwmgr, false);
2407 } else if (data->need_update_dpm_table) {
2408 vega10_avfs_enable(hwmgr, false);
2409 vega10_avfs_enable(hwmgr, true);
2410 } else {
2411 vega10_avfs_enable(hwmgr, true);
2412 }
2413
2414 return 0;
2415 }
2416
2417 static int vega10_populate_and_upload_avfs_fuse_override(struct pp_hwmgr *hwmgr)
2418 {
2419 int result = 0;
2420
2421 uint64_t serial_number = 0;
2422 uint32_t top32, bottom32;
2423 struct phm_fuses_default fuse;
2424
2425 struct vega10_hwmgr *data = hwmgr->backend;
2426 AvfsFuseOverride_t *avfs_fuse_table = &(data->smc_state_table.avfs_fuse_override_table);
2427
2428 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumTop32);
2429 top32 = smum_get_argument(hwmgr);
2430
2431 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_ReadSerialNumBottom32);
2432 bottom32 = smum_get_argument(hwmgr);
2433
2434 serial_number = ((uint64_t)bottom32 << 32) | top32;
2435
2436 if (pp_override_get_default_fuse_value(serial_number, &fuse) == 0) {
2437 avfs_fuse_table->VFT0_b = fuse.VFT0_b;
2438 avfs_fuse_table->VFT0_m1 = fuse.VFT0_m1;
2439 avfs_fuse_table->VFT0_m2 = fuse.VFT0_m2;
2440 avfs_fuse_table->VFT1_b = fuse.VFT1_b;
2441 avfs_fuse_table->VFT1_m1 = fuse.VFT1_m1;
2442 avfs_fuse_table->VFT1_m2 = fuse.VFT1_m2;
2443 avfs_fuse_table->VFT2_b = fuse.VFT2_b;
2444 avfs_fuse_table->VFT2_m1 = fuse.VFT2_m1;
2445 avfs_fuse_table->VFT2_m2 = fuse.VFT2_m2;
2446 result = smum_smc_table_manager(hwmgr, (uint8_t *)avfs_fuse_table,
2447 AVFSFUSETABLE, false);
2448 PP_ASSERT_WITH_CODE(!result,
2449 "Failed to upload FuseOVerride!",
2450 );
2451 }
2452
2453 return result;
2454 }
2455
2456 static void vega10_check_dpm_table_updated(struct pp_hwmgr *hwmgr)
2457 {
2458 struct vega10_hwmgr *data = hwmgr->backend;
2459 struct vega10_odn_dpm_table *odn_table = &(data->odn_dpm_table);
2460 struct phm_ppt_v2_information *table_info = hwmgr->pptable;
2461 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table;
2462 struct phm_ppt_v1_clock_voltage_dependency_table *odn_dep_table;
2463 uint32_t i;
2464
2465 dep_table = table_info->vdd_dep_on_mclk;
2466 odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dep_on_mclk);
2467
2468 for (i = 0; i < dep_table->count; i++) {
2469 if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {
2470 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_MCLK;
2471 return;
2472 }
2473 }
2474
2475 dep_table = table_info->vdd_dep_on_sclk;
2476 odn_dep_table = (struct phm_ppt_v1_clock_voltage_dependency_table *)&(odn_table->vdd_dep_on_sclk);
2477 for (i = 0; i < dep_table->count; i++) {
2478 if (dep_table->entries[i].vddc != odn_dep_table->entries[i].vddc) {
2479 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC | DPMTABLE_OD_UPDATE_SCLK;
2480 return;
2481 }
2482 }
2483 }
2484
2485
2486
2487
2488
2489
2490
2491
2492 static int vega10_init_smc_table(struct pp_hwmgr *hwmgr)
2493 {
2494 int result;
2495 struct vega10_hwmgr *data = hwmgr->backend;
2496 struct phm_ppt_v2_information *table_info =
2497 (struct phm_ppt_v2_information *)(hwmgr->pptable);
2498 PPTable_t *pp_table = &(data->smc_state_table.pp_table);
2499 struct pp_atomfwctrl_voltage_table voltage_table;
2500 struct pp_atomfwctrl_bios_boot_up_values boot_up_values;
2501 struct vega10_odn_dpm_table *odn_table = &(data->odn_dpm_table);
2502
2503 result = vega10_setup_default_dpm_tables(hwmgr);
2504 PP_ASSERT_WITH_CODE(!result,
2505 "Failed to setup default DPM tables!",
2506 return result);
2507
2508
2509 if (hwmgr->od_enabled) {
2510 if (odn_table->max_vddc) {
2511 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK | DPMTABLE_OD_UPDATE_MCLK;
2512 vega10_check_dpm_table_updated(hwmgr);
2513 } else {
2514 vega10_odn_initial_default_setting(hwmgr);
2515 }
2516 }
2517
2518 pp_atomfwctrl_get_voltage_table_v4(hwmgr, VOLTAGE_TYPE_VDDC,
2519 VOLTAGE_OBJ_SVID2, &voltage_table);
2520 pp_table->MaxVidStep = voltage_table.max_vid_step;
2521
2522 pp_table->GfxDpmVoltageMode =
2523 (uint8_t)(table_info->uc_gfx_dpm_voltage_mode);
2524 pp_table->SocDpmVoltageMode =
2525 (uint8_t)(table_info->uc_soc_dpm_voltage_mode);
2526 pp_table->UclkDpmVoltageMode =
2527 (uint8_t)(table_info->uc_uclk_dpm_voltage_mode);
2528 pp_table->UvdDpmVoltageMode =
2529 (uint8_t)(table_info->uc_uvd_dpm_voltage_mode);
2530 pp_table->VceDpmVoltageMode =
2531 (uint8_t)(table_info->uc_vce_dpm_voltage_mode);
2532 pp_table->Mp0DpmVoltageMode =
2533 (uint8_t)(table_info->uc_mp0_dpm_voltage_mode);
2534
2535 pp_table->DisplayDpmVoltageMode =
2536 (uint8_t)(table_info->uc_dcef_dpm_voltage_mode);
2537
2538 data->vddc_voltage_table.psi0_enable = voltage_table.psi0_enable;
2539 data->vddc_voltage_table.psi1_enable = voltage_table.psi1_enable;
2540
2541 if (data->registry_data.ulv_support &&
2542 table_info->us_ulv_voltage_offset) {
2543 result = vega10_populate_ulv_state(hwmgr);
2544 PP_ASSERT_WITH_CODE(!result,
2545 "Failed to initialize ULV state!",
2546 return result);
2547 }
2548
2549 result = vega10_populate_smc_link_levels(hwmgr);
2550 PP_ASSERT_WITH_CODE(!result,
2551 "Failed to initialize Link Level!",
2552 return result);
2553
2554 result = vega10_populate_all_graphic_levels(hwmgr);
2555 PP_ASSERT_WITH_CODE(!result,
2556 "Failed to initialize Graphics Level!",
2557 return result);
2558
2559 result = vega10_populate_all_memory_levels(hwmgr);
2560 PP_ASSERT_WITH_CODE(!result,
2561 "Failed to initialize Memory Level!",
2562 return result);
2563
2564 vega10_populate_vddc_soc_levels(hwmgr);
2565
2566 result = vega10_populate_all_display_clock_levels(hwmgr);
2567 PP_ASSERT_WITH_CODE(!result,
2568 "Failed to initialize Display Level!",
2569 return result);
2570
2571 result = vega10_populate_smc_vce_levels(hwmgr);
2572 PP_ASSERT_WITH_CODE(!result,
2573 "Failed to initialize VCE Level!",
2574 return result);
2575
2576 result = vega10_populate_smc_uvd_levels(hwmgr);
2577 PP_ASSERT_WITH_CODE(!result,
2578 "Failed to initialize UVD Level!",
2579 return result);
2580
2581 if (data->registry_data.clock_stretcher_support) {
2582 result = vega10_populate_clock_stretcher_table(hwmgr);
2583 PP_ASSERT_WITH_CODE(!result,
2584 "Failed to populate Clock Stretcher Table!",
2585 return result);
2586 }
2587
2588 result = pp_atomfwctrl_get_vbios_bootup_values(hwmgr, &boot_up_values);
2589 if (!result) {
2590 data->vbios_boot_state.vddc = boot_up_values.usVddc;
2591 data->vbios_boot_state.vddci = boot_up_values.usVddci;
2592 data->vbios_boot_state.mvddc = boot_up_values.usMvddc;
2593 data->vbios_boot_state.gfx_clock = boot_up_values.ulGfxClk;
2594 data->vbios_boot_state.mem_clock = boot_up_values.ulUClk;
2595 pp_atomfwctrl_get_clk_information_by_clkid(hwmgr,
2596 SMU9_SYSPLL0_SOCCLK_ID, 0, &boot_up_values.ulSocClk);
2597
2598 pp_atomfwctrl_get_clk_information_by_clkid(hwmgr,
2599 SMU9_SYSPLL0_DCEFCLK_ID, 0, &boot_up_values.ulDCEFClk);
2600
2601 data->vbios_boot_state.soc_clock = boot_up_values.ulSocClk;
2602 data->vbios_boot_state.dcef_clock = boot_up_values.ulDCEFClk;
2603 if (0 != boot_up_values.usVddc) {
2604 smum_send_msg_to_smc_with_parameter(hwmgr,
2605 PPSMC_MSG_SetFloorSocVoltage,
2606 (boot_up_values.usVddc * 4));
2607 data->vbios_boot_state.bsoc_vddc_lock = true;
2608 } else {
2609 data->vbios_boot_state.bsoc_vddc_lock = false;
2610 }
2611 smum_send_msg_to_smc_with_parameter(hwmgr,
2612 PPSMC_MSG_SetMinDeepSleepDcefclk,
2613 (uint32_t)(data->vbios_boot_state.dcef_clock / 100));
2614 }
2615
2616 result = vega10_populate_avfs_parameters(hwmgr);
2617 PP_ASSERT_WITH_CODE(!result,
2618 "Failed to initialize AVFS Parameters!",
2619 return result);
2620
2621 result = vega10_populate_gpio_parameters(hwmgr);
2622 PP_ASSERT_WITH_CODE(!result,
2623 "Failed to initialize GPIO Parameters!",
2624 return result);
2625
2626 pp_table->GfxclkAverageAlpha = (uint8_t)
2627 (data->gfxclk_average_alpha);
2628 pp_table->SocclkAverageAlpha = (uint8_t)
2629 (data->socclk_average_alpha);
2630 pp_table->UclkAverageAlpha = (uint8_t)
2631 (data->uclk_average_alpha);
2632 pp_table->GfxActivityAverageAlpha = (uint8_t)
2633 (data->gfx_activity_average_alpha);
2634
2635 vega10_populate_and_upload_avfs_fuse_override(hwmgr);
2636
2637 result = smum_smc_table_manager(hwmgr, (uint8_t *)pp_table, PPTABLE, false);
2638
2639 PP_ASSERT_WITH_CODE(!result,
2640 "Failed to upload PPtable!", return result);
2641
2642 result = vega10_avfs_enable(hwmgr, true);
2643 PP_ASSERT_WITH_CODE(!result, "Attempt to enable AVFS feature Failed!",
2644 return result);
2645 vega10_acg_enable(hwmgr);
2646
2647 return 0;
2648 }
2649
2650 static int vega10_enable_thermal_protection(struct pp_hwmgr *hwmgr)
2651 {
2652 struct vega10_hwmgr *data = hwmgr->backend;
2653
2654 if (data->smu_features[GNLD_THERMAL].supported) {
2655 if (data->smu_features[GNLD_THERMAL].enabled)
2656 pr_info("THERMAL Feature Already enabled!");
2657
2658 PP_ASSERT_WITH_CODE(
2659 !vega10_enable_smc_features(hwmgr,
2660 true,
2661 data->smu_features[GNLD_THERMAL].smu_feature_bitmap),
2662 "Enable THERMAL Feature Failed!",
2663 return -1);
2664 data->smu_features[GNLD_THERMAL].enabled = true;
2665 }
2666
2667 return 0;
2668 }
2669
2670 static int vega10_disable_thermal_protection(struct pp_hwmgr *hwmgr)
2671 {
2672 struct vega10_hwmgr *data = hwmgr->backend;
2673
2674 if (data->smu_features[GNLD_THERMAL].supported) {
2675 if (!data->smu_features[GNLD_THERMAL].enabled)
2676 pr_info("THERMAL Feature Already disabled!");
2677
2678 PP_ASSERT_WITH_CODE(
2679 !vega10_enable_smc_features(hwmgr,
2680 false,
2681 data->smu_features[GNLD_THERMAL].smu_feature_bitmap),
2682 "disable THERMAL Feature Failed!",
2683 return -1);
2684 data->smu_features[GNLD_THERMAL].enabled = false;
2685 }
2686
2687 return 0;
2688 }
2689
2690 static int vega10_enable_vrhot_feature(struct pp_hwmgr *hwmgr)
2691 {
2692 struct vega10_hwmgr *data = hwmgr->backend;
2693
2694 if (PP_CAP(PHM_PlatformCaps_RegulatorHot)) {
2695 if (data->smu_features[GNLD_VR0HOT].supported) {
2696 PP_ASSERT_WITH_CODE(
2697 !vega10_enable_smc_features(hwmgr,
2698 true,
2699 data->smu_features[GNLD_VR0HOT].smu_feature_bitmap),
2700 "Attempt to Enable VR0 Hot feature Failed!",
2701 return -1);
2702 data->smu_features[GNLD_VR0HOT].enabled = true;
2703 } else {
2704 if (data->smu_features[GNLD_VR1HOT].supported) {
2705 PP_ASSERT_WITH_CODE(
2706 !vega10_enable_smc_features(hwmgr,
2707 true,
2708 data->smu_features[GNLD_VR1HOT].smu_feature_bitmap),
2709 "Attempt to Enable VR0 Hot feature Failed!",
2710 return -1);
2711 data->smu_features[GNLD_VR1HOT].enabled = true;
2712 }
2713 }
2714 }
2715 return 0;
2716 }
2717
2718 static int vega10_enable_ulv(struct pp_hwmgr *hwmgr)
2719 {
2720 struct vega10_hwmgr *data = hwmgr->backend;
2721
2722 if (data->registry_data.ulv_support) {
2723 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
2724 true, data->smu_features[GNLD_ULV].smu_feature_bitmap),
2725 "Enable ULV Feature Failed!",
2726 return -1);
2727 data->smu_features[GNLD_ULV].enabled = true;
2728 }
2729
2730 return 0;
2731 }
2732
2733 static int vega10_disable_ulv(struct pp_hwmgr *hwmgr)
2734 {
2735 struct vega10_hwmgr *data = hwmgr->backend;
2736
2737 if (data->registry_data.ulv_support) {
2738 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
2739 false, data->smu_features[GNLD_ULV].smu_feature_bitmap),
2740 "disable ULV Feature Failed!",
2741 return -EINVAL);
2742 data->smu_features[GNLD_ULV].enabled = false;
2743 }
2744
2745 return 0;
2746 }
2747
2748 static int vega10_enable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
2749 {
2750 struct vega10_hwmgr *data = hwmgr->backend;
2751
2752 if (data->smu_features[GNLD_DS_GFXCLK].supported) {
2753 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
2754 true, data->smu_features[GNLD_DS_GFXCLK].smu_feature_bitmap),
2755 "Attempt to Enable DS_GFXCLK Feature Failed!",
2756 return -EINVAL);
2757 data->smu_features[GNLD_DS_GFXCLK].enabled = true;
2758 }
2759
2760 if (data->smu_features[GNLD_DS_SOCCLK].supported) {
2761 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
2762 true, data->smu_features[GNLD_DS_SOCCLK].smu_feature_bitmap),
2763 "Attempt to Enable DS_SOCCLK Feature Failed!",
2764 return -EINVAL);
2765 data->smu_features[GNLD_DS_SOCCLK].enabled = true;
2766 }
2767
2768 if (data->smu_features[GNLD_DS_LCLK].supported) {
2769 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
2770 true, data->smu_features[GNLD_DS_LCLK].smu_feature_bitmap),
2771 "Attempt to Enable DS_LCLK Feature Failed!",
2772 return -EINVAL);
2773 data->smu_features[GNLD_DS_LCLK].enabled = true;
2774 }
2775
2776 if (data->smu_features[GNLD_DS_DCEFCLK].supported) {
2777 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
2778 true, data->smu_features[GNLD_DS_DCEFCLK].smu_feature_bitmap),
2779 "Attempt to Enable DS_DCEFCLK Feature Failed!",
2780 return -EINVAL);
2781 data->smu_features[GNLD_DS_DCEFCLK].enabled = true;
2782 }
2783
2784 return 0;
2785 }
2786
2787 static int vega10_disable_deep_sleep_master_switch(struct pp_hwmgr *hwmgr)
2788 {
2789 struct vega10_hwmgr *data = hwmgr->backend;
2790
2791 if (data->smu_features[GNLD_DS_GFXCLK].supported) {
2792 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
2793 false, data->smu_features[GNLD_DS_GFXCLK].smu_feature_bitmap),
2794 "Attempt to disable DS_GFXCLK Feature Failed!",
2795 return -EINVAL);
2796 data->smu_features[GNLD_DS_GFXCLK].enabled = false;
2797 }
2798
2799 if (data->smu_features[GNLD_DS_SOCCLK].supported) {
2800 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
2801 false, data->smu_features[GNLD_DS_SOCCLK].smu_feature_bitmap),
2802 "Attempt to disable DS_ Feature Failed!",
2803 return -EINVAL);
2804 data->smu_features[GNLD_DS_SOCCLK].enabled = false;
2805 }
2806
2807 if (data->smu_features[GNLD_DS_LCLK].supported) {
2808 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
2809 false, data->smu_features[GNLD_DS_LCLK].smu_feature_bitmap),
2810 "Attempt to disable DS_LCLK Feature Failed!",
2811 return -EINVAL);
2812 data->smu_features[GNLD_DS_LCLK].enabled = false;
2813 }
2814
2815 if (data->smu_features[GNLD_DS_DCEFCLK].supported) {
2816 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
2817 false, data->smu_features[GNLD_DS_DCEFCLK].smu_feature_bitmap),
2818 "Attempt to disable DS_DCEFCLK Feature Failed!",
2819 return -EINVAL);
2820 data->smu_features[GNLD_DS_DCEFCLK].enabled = false;
2821 }
2822
2823 return 0;
2824 }
2825
2826 static int vega10_stop_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap)
2827 {
2828 struct vega10_hwmgr *data = hwmgr->backend;
2829 uint32_t i, feature_mask = 0;
2830
2831
2832 if(data->smu_features[GNLD_LED_DISPLAY].supported == true){
2833 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
2834 false, data->smu_features[GNLD_LED_DISPLAY].smu_feature_bitmap),
2835 "Attempt to disable LED DPM feature failed!", return -EINVAL);
2836 data->smu_features[GNLD_LED_DISPLAY].enabled = false;
2837 }
2838
2839 for (i = 0; i < GNLD_DPM_MAX; i++) {
2840 if (data->smu_features[i].smu_feature_bitmap & bitmap) {
2841 if (data->smu_features[i].supported) {
2842 if (data->smu_features[i].enabled) {
2843 feature_mask |= data->smu_features[i].
2844 smu_feature_bitmap;
2845 data->smu_features[i].enabled = false;
2846 }
2847 }
2848 }
2849 }
2850
2851 vega10_enable_smc_features(hwmgr, false, feature_mask);
2852
2853 return 0;
2854 }
2855
2856
2857
2858
2859
2860
2861
2862
2863 static int vega10_start_dpm(struct pp_hwmgr *hwmgr, uint32_t bitmap)
2864 {
2865 struct vega10_hwmgr *data = hwmgr->backend;
2866 uint32_t i, feature_mask = 0;
2867
2868 for (i = 0; i < GNLD_DPM_MAX; i++) {
2869 if (data->smu_features[i].smu_feature_bitmap & bitmap) {
2870 if (data->smu_features[i].supported) {
2871 if (!data->smu_features[i].enabled) {
2872 feature_mask |= data->smu_features[i].
2873 smu_feature_bitmap;
2874 data->smu_features[i].enabled = true;
2875 }
2876 }
2877 }
2878 }
2879
2880 if (vega10_enable_smc_features(hwmgr,
2881 true, feature_mask)) {
2882 for (i = 0; i < GNLD_DPM_MAX; i++) {
2883 if (data->smu_features[i].smu_feature_bitmap &
2884 feature_mask)
2885 data->smu_features[i].enabled = false;
2886 }
2887 }
2888
2889 if(data->smu_features[GNLD_LED_DISPLAY].supported == true){
2890 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
2891 true, data->smu_features[GNLD_LED_DISPLAY].smu_feature_bitmap),
2892 "Attempt to Enable LED DPM feature Failed!", return -EINVAL);
2893 data->smu_features[GNLD_LED_DISPLAY].enabled = true;
2894 }
2895
2896 if (data->vbios_boot_state.bsoc_vddc_lock) {
2897 smum_send_msg_to_smc_with_parameter(hwmgr,
2898 PPSMC_MSG_SetFloorSocVoltage, 0);
2899 data->vbios_boot_state.bsoc_vddc_lock = false;
2900 }
2901
2902 if (PP_CAP(PHM_PlatformCaps_Falcon_QuickTransition)) {
2903 if (data->smu_features[GNLD_ACDC].supported) {
2904 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
2905 true, data->smu_features[GNLD_ACDC].smu_feature_bitmap),
2906 "Attempt to Enable DS_GFXCLK Feature Failed!",
2907 return -1);
2908 data->smu_features[GNLD_ACDC].enabled = true;
2909 }
2910 }
2911
2912 return 0;
2913 }
2914
2915 static int vega10_enable_disable_PCC_limit_feature(struct pp_hwmgr *hwmgr, bool enable)
2916 {
2917 struct vega10_hwmgr *data = hwmgr->backend;
2918
2919 if (data->smu_features[GNLD_PCC_LIMIT].supported) {
2920 if (enable == data->smu_features[GNLD_PCC_LIMIT].enabled)
2921 pr_info("GNLD_PCC_LIMIT has been %s \n", enable ? "enabled" : "disabled");
2922 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
2923 enable, data->smu_features[GNLD_PCC_LIMIT].smu_feature_bitmap),
2924 "Attempt to Enable PCC Limit feature Failed!",
2925 return -EINVAL);
2926 data->smu_features[GNLD_PCC_LIMIT].enabled = enable;
2927 }
2928
2929 return 0;
2930 }
2931
2932 static int vega10_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
2933 {
2934 struct vega10_hwmgr *data = hwmgr->backend;
2935 int tmp_result, result = 0;
2936
2937 vega10_enable_disable_PCC_limit_feature(hwmgr, true);
2938
2939 smum_send_msg_to_smc_with_parameter(hwmgr,
2940 PPSMC_MSG_ConfigureTelemetry, data->config_telemetry);
2941
2942 tmp_result = vega10_construct_voltage_tables(hwmgr);
2943 PP_ASSERT_WITH_CODE(!tmp_result,
2944 "Failed to construct voltage tables!",
2945 result = tmp_result);
2946
2947 tmp_result = vega10_init_smc_table(hwmgr);
2948 PP_ASSERT_WITH_CODE(!tmp_result,
2949 "Failed to initialize SMC table!",
2950 result = tmp_result);
2951
2952 if (PP_CAP(PHM_PlatformCaps_ThermalController)) {
2953 tmp_result = vega10_enable_thermal_protection(hwmgr);
2954 PP_ASSERT_WITH_CODE(!tmp_result,
2955 "Failed to enable thermal protection!",
2956 result = tmp_result);
2957 }
2958
2959 tmp_result = vega10_enable_vrhot_feature(hwmgr);
2960 PP_ASSERT_WITH_CODE(!tmp_result,
2961 "Failed to enable VR hot feature!",
2962 result = tmp_result);
2963
2964 tmp_result = vega10_enable_deep_sleep_master_switch(hwmgr);
2965 PP_ASSERT_WITH_CODE(!tmp_result,
2966 "Failed to enable deep sleep master switch!",
2967 result = tmp_result);
2968
2969 tmp_result = vega10_start_dpm(hwmgr, SMC_DPM_FEATURES);
2970 PP_ASSERT_WITH_CODE(!tmp_result,
2971 "Failed to start DPM!", result = tmp_result);
2972
2973
2974 tmp_result = vega10_enable_didt_config(hwmgr);
2975 PP_ASSERT(!tmp_result,
2976 "Failed to enable didt config!");
2977
2978 tmp_result = vega10_enable_power_containment(hwmgr);
2979 PP_ASSERT_WITH_CODE(!tmp_result,
2980 "Failed to enable power containment!",
2981 result = tmp_result);
2982
2983 tmp_result = vega10_power_control_set_level(hwmgr);
2984 PP_ASSERT_WITH_CODE(!tmp_result,
2985 "Failed to power control set level!",
2986 result = tmp_result);
2987
2988 tmp_result = vega10_enable_ulv(hwmgr);
2989 PP_ASSERT_WITH_CODE(!tmp_result,
2990 "Failed to enable ULV!",
2991 result = tmp_result);
2992
2993 return result;
2994 }
2995
2996 static int vega10_get_power_state_size(struct pp_hwmgr *hwmgr)
2997 {
2998 return sizeof(struct vega10_power_state);
2999 }
3000
3001 static int vega10_get_pp_table_entry_callback_func(struct pp_hwmgr *hwmgr,
3002 void *state, struct pp_power_state *power_state,
3003 void *pp_table, uint32_t classification_flag)
3004 {
3005 ATOM_Vega10_GFXCLK_Dependency_Record_V2 *patom_record_V2;
3006 struct vega10_power_state *vega10_power_state =
3007 cast_phw_vega10_power_state(&(power_state->hardware));
3008 struct vega10_performance_level *performance_level;
3009 ATOM_Vega10_State *state_entry = (ATOM_Vega10_State *)state;
3010 ATOM_Vega10_POWERPLAYTABLE *powerplay_table =
3011 (ATOM_Vega10_POWERPLAYTABLE *)pp_table;
3012 ATOM_Vega10_SOCCLK_Dependency_Table *socclk_dep_table =
3013 (ATOM_Vega10_SOCCLK_Dependency_Table *)
3014 (((unsigned long)powerplay_table) +
3015 le16_to_cpu(powerplay_table->usSocclkDependencyTableOffset));
3016 ATOM_Vega10_GFXCLK_Dependency_Table *gfxclk_dep_table =
3017 (ATOM_Vega10_GFXCLK_Dependency_Table *)
3018 (((unsigned long)powerplay_table) +
3019 le16_to_cpu(powerplay_table->usGfxclkDependencyTableOffset));
3020 ATOM_Vega10_MCLK_Dependency_Table *mclk_dep_table =
3021 (ATOM_Vega10_MCLK_Dependency_Table *)
3022 (((unsigned long)powerplay_table) +
3023 le16_to_cpu(powerplay_table->usMclkDependencyTableOffset));
3024
3025
3026
3027
3028
3029 power_state->classification.ui_label =
3030 (le16_to_cpu(state_entry->usClassification) &
3031 ATOM_PPLIB_CLASSIFICATION_UI_MASK) >>
3032 ATOM_PPLIB_CLASSIFICATION_UI_SHIFT;
3033 power_state->classification.flags = classification_flag;
3034
3035
3036
3037 power_state->classification.temporary_state = false;
3038 power_state->classification.to_be_deleted = false;
3039
3040 power_state->validation.disallowOnDC =
3041 ((le32_to_cpu(state_entry->ulCapsAndSettings) &
3042 ATOM_Vega10_DISALLOW_ON_DC) != 0);
3043
3044 power_state->display.disableFrameModulation = false;
3045 power_state->display.limitRefreshrate = false;
3046 power_state->display.enableVariBright =
3047 ((le32_to_cpu(state_entry->ulCapsAndSettings) &
3048 ATOM_Vega10_ENABLE_VARIBRIGHT) != 0);
3049
3050 power_state->validation.supportedPowerLevels = 0;
3051 power_state->uvd_clocks.VCLK = 0;
3052 power_state->uvd_clocks.DCLK = 0;
3053 power_state->temperatures.min = 0;
3054 power_state->temperatures.max = 0;
3055
3056 performance_level = &(vega10_power_state->performance_levels
3057 [vega10_power_state->performance_level_count++]);
3058
3059 PP_ASSERT_WITH_CODE(
3060 (vega10_power_state->performance_level_count <
3061 NUM_GFXCLK_DPM_LEVELS),
3062 "Performance levels exceeds SMC limit!",
3063 return -1);
3064
3065 PP_ASSERT_WITH_CODE(
3066 (vega10_power_state->performance_level_count <=
3067 hwmgr->platform_descriptor.
3068 hardwareActivityPerformanceLevels),
3069 "Performance levels exceeds Driver limit!",
3070 return -1);
3071
3072
3073 performance_level->soc_clock = socclk_dep_table->entries
3074 [state_entry->ucSocClockIndexLow].ulClk;
3075 performance_level->gfx_clock = gfxclk_dep_table->entries
3076 [state_entry->ucGfxClockIndexLow].ulClk;
3077 performance_level->mem_clock = mclk_dep_table->entries
3078 [state_entry->ucMemClockIndexLow].ulMemClk;
3079
3080 performance_level = &(vega10_power_state->performance_levels
3081 [vega10_power_state->performance_level_count++]);
3082 performance_level->soc_clock = socclk_dep_table->entries
3083 [state_entry->ucSocClockIndexHigh].ulClk;
3084 if (gfxclk_dep_table->ucRevId == 0) {
3085 performance_level->gfx_clock = gfxclk_dep_table->entries
3086 [state_entry->ucGfxClockIndexHigh].ulClk;
3087 } else if (gfxclk_dep_table->ucRevId == 1) {
3088 patom_record_V2 = (ATOM_Vega10_GFXCLK_Dependency_Record_V2 *)gfxclk_dep_table->entries;
3089 performance_level->gfx_clock = patom_record_V2[state_entry->ucGfxClockIndexHigh].ulClk;
3090 }
3091
3092 performance_level->mem_clock = mclk_dep_table->entries
3093 [state_entry->ucMemClockIndexHigh].ulMemClk;
3094 return 0;
3095 }
3096
3097 static int vega10_get_pp_table_entry(struct pp_hwmgr *hwmgr,
3098 unsigned long entry_index, struct pp_power_state *state)
3099 {
3100 int result;
3101 struct vega10_power_state *ps;
3102
3103 state->hardware.magic = PhwVega10_Magic;
3104
3105 ps = cast_phw_vega10_power_state(&state->hardware);
3106
3107 result = vega10_get_powerplay_table_entry(hwmgr, entry_index, state,
3108 vega10_get_pp_table_entry_callback_func);
3109
3110
3111
3112
3113
3114
3115 if (!state->validation.disallowOnDC)
3116 ps->dc_compatible = true;
3117
3118 ps->uvd_clks.vclk = state->uvd_clocks.VCLK;
3119 ps->uvd_clks.dclk = state->uvd_clocks.DCLK;
3120
3121 return 0;
3122 }
3123
3124 static int vega10_patch_boot_state(struct pp_hwmgr *hwmgr,
3125 struct pp_hw_power_state *hw_ps)
3126 {
3127 return 0;
3128 }
3129
3130 static int vega10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
3131 struct pp_power_state *request_ps,
3132 const struct pp_power_state *current_ps)
3133 {
3134 struct amdgpu_device *adev = hwmgr->adev;
3135 struct vega10_power_state *vega10_ps =
3136 cast_phw_vega10_power_state(&request_ps->hardware);
3137 uint32_t sclk;
3138 uint32_t mclk;
3139 struct PP_Clocks minimum_clocks = {0};
3140 bool disable_mclk_switching;
3141 bool disable_mclk_switching_for_frame_lock;
3142 bool disable_mclk_switching_for_vr;
3143 bool force_mclk_high;
3144 const struct phm_clock_and_voltage_limits *max_limits;
3145 uint32_t i;
3146 struct vega10_hwmgr *data = hwmgr->backend;
3147 struct phm_ppt_v2_information *table_info =
3148 (struct phm_ppt_v2_information *)(hwmgr->pptable);
3149 int32_t count;
3150 uint32_t stable_pstate_sclk_dpm_percentage;
3151 uint32_t stable_pstate_sclk = 0, stable_pstate_mclk = 0;
3152 uint32_t latency;
3153
3154 data->battery_state = (PP_StateUILabel_Battery ==
3155 request_ps->classification.ui_label);
3156
3157 if (vega10_ps->performance_level_count != 2)
3158 pr_info("VI should always have 2 performance levels");
3159
3160 max_limits = adev->pm.ac_power ?
3161 &(hwmgr->dyn_state.max_clock_voltage_on_ac) :
3162 &(hwmgr->dyn_state.max_clock_voltage_on_dc);
3163
3164
3165 if (!adev->pm.ac_power) {
3166 for (i = 0; i < vega10_ps->performance_level_count; i++) {
3167 if (vega10_ps->performance_levels[i].mem_clock >
3168 max_limits->mclk)
3169 vega10_ps->performance_levels[i].mem_clock =
3170 max_limits->mclk;
3171 if (vega10_ps->performance_levels[i].gfx_clock >
3172 max_limits->sclk)
3173 vega10_ps->performance_levels[i].gfx_clock =
3174 max_limits->sclk;
3175 }
3176 }
3177
3178
3179 minimum_clocks.engineClock = hwmgr->display_config->min_core_set_clock;
3180 minimum_clocks.memoryClock = hwmgr->display_config->min_mem_set_clock;
3181
3182 if (PP_CAP(PHM_PlatformCaps_StablePState)) {
3183 stable_pstate_sclk_dpm_percentage =
3184 data->registry_data.stable_pstate_sclk_dpm_percentage;
3185 PP_ASSERT_WITH_CODE(
3186 data->registry_data.stable_pstate_sclk_dpm_percentage >= 1 &&
3187 data->registry_data.stable_pstate_sclk_dpm_percentage <= 100,
3188 "percent sclk value must range from 1% to 100%, setting default value",
3189 stable_pstate_sclk_dpm_percentage = 75);
3190
3191 max_limits = &(hwmgr->dyn_state.max_clock_voltage_on_ac);
3192 stable_pstate_sclk = (max_limits->sclk *
3193 stable_pstate_sclk_dpm_percentage) / 100;
3194
3195 for (count = table_info->vdd_dep_on_sclk->count - 1;
3196 count >= 0; count--) {
3197 if (stable_pstate_sclk >=
3198 table_info->vdd_dep_on_sclk->entries[count].clk) {
3199 stable_pstate_sclk =
3200 table_info->vdd_dep_on_sclk->entries[count].clk;
3201 break;
3202 }
3203 }
3204
3205 if (count < 0)
3206 stable_pstate_sclk = table_info->vdd_dep_on_sclk->entries[0].clk;
3207
3208 stable_pstate_mclk = max_limits->mclk;
3209
3210 minimum_clocks.engineClock = stable_pstate_sclk;
3211 minimum_clocks.memoryClock = stable_pstate_mclk;
3212 }
3213
3214 disable_mclk_switching_for_frame_lock =
3215 PP_CAP(PHM_PlatformCaps_DisableMclkSwitchingForFrameLock);
3216 disable_mclk_switching_for_vr =
3217 PP_CAP(PHM_PlatformCaps_DisableMclkSwitchForVR);
3218 force_mclk_high = PP_CAP(PHM_PlatformCaps_ForceMclkHigh);
3219
3220 if (hwmgr->display_config->num_display == 0)
3221 disable_mclk_switching = false;
3222 else
3223 disable_mclk_switching = ((1 < hwmgr->display_config->num_display) &&
3224 !hwmgr->display_config->multi_monitor_in_sync) ||
3225 disable_mclk_switching_for_frame_lock ||
3226 disable_mclk_switching_for_vr ||
3227 force_mclk_high;
3228
3229 sclk = vega10_ps->performance_levels[0].gfx_clock;
3230 mclk = vega10_ps->performance_levels[0].mem_clock;
3231
3232 if (sclk < minimum_clocks.engineClock)
3233 sclk = (minimum_clocks.engineClock > max_limits->sclk) ?
3234 max_limits->sclk : minimum_clocks.engineClock;
3235
3236 if (mclk < minimum_clocks.memoryClock)
3237 mclk = (minimum_clocks.memoryClock > max_limits->mclk) ?
3238 max_limits->mclk : minimum_clocks.memoryClock;
3239
3240 vega10_ps->performance_levels[0].gfx_clock = sclk;
3241 vega10_ps->performance_levels[0].mem_clock = mclk;
3242
3243 if (vega10_ps->performance_levels[1].gfx_clock <
3244 vega10_ps->performance_levels[0].gfx_clock)
3245 vega10_ps->performance_levels[0].gfx_clock =
3246 vega10_ps->performance_levels[1].gfx_clock;
3247
3248 if (disable_mclk_switching) {
3249
3250 if (mclk < vega10_ps->performance_levels[1].mem_clock)
3251 mclk = vega10_ps->performance_levels[1].mem_clock;
3252
3253
3254
3255
3256 latency = hwmgr->display_config->dce_tolerable_mclk_in_active_latency;
3257 for (i = 0; i < data->mclk_latency_table.count; i++) {
3258 if ((data->mclk_latency_table.entries[i].latency <= latency) &&
3259 (data->mclk_latency_table.entries[i].frequency >=
3260 vega10_ps->performance_levels[0].mem_clock) &&
3261 (data->mclk_latency_table.entries[i].frequency <=
3262 vega10_ps->performance_levels[1].mem_clock))
3263 mclk = data->mclk_latency_table.entries[i].frequency;
3264 }
3265 vega10_ps->performance_levels[0].mem_clock = mclk;
3266 } else {
3267 if (vega10_ps->performance_levels[1].mem_clock <
3268 vega10_ps->performance_levels[0].mem_clock)
3269 vega10_ps->performance_levels[0].mem_clock =
3270 vega10_ps->performance_levels[1].mem_clock;
3271 }
3272
3273 if (PP_CAP(PHM_PlatformCaps_StablePState)) {
3274 for (i = 0; i < vega10_ps->performance_level_count; i++) {
3275 vega10_ps->performance_levels[i].gfx_clock = stable_pstate_sclk;
3276 vega10_ps->performance_levels[i].mem_clock = stable_pstate_mclk;
3277 }
3278 }
3279
3280 return 0;
3281 }
3282
3283 static int vega10_find_dpm_states_clocks_in_dpm_table(struct pp_hwmgr *hwmgr, const void *input)
3284 {
3285 struct vega10_hwmgr *data = hwmgr->backend;
3286 const struct phm_set_power_state_input *states =
3287 (const struct phm_set_power_state_input *)input;
3288 const struct vega10_power_state *vega10_ps =
3289 cast_const_phw_vega10_power_state(states->pnew_state);
3290 struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
3291 uint32_t sclk = vega10_ps->performance_levels
3292 [vega10_ps->performance_level_count - 1].gfx_clock;
3293 struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
3294 uint32_t mclk = vega10_ps->performance_levels
3295 [vega10_ps->performance_level_count - 1].mem_clock;
3296 uint32_t i;
3297
3298 for (i = 0; i < sclk_table->count; i++) {
3299 if (sclk == sclk_table->dpm_levels[i].value)
3300 break;
3301 }
3302
3303 if (i >= sclk_table->count) {
3304 if (sclk > sclk_table->dpm_levels[i-1].value) {
3305 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
3306 sclk_table->dpm_levels[i-1].value = sclk;
3307 }
3308 }
3309
3310 for (i = 0; i < mclk_table->count; i++) {
3311 if (mclk == mclk_table->dpm_levels[i].value)
3312 break;
3313 }
3314
3315 if (i >= mclk_table->count) {
3316 if (mclk > mclk_table->dpm_levels[i-1].value) {
3317 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
3318 mclk_table->dpm_levels[i-1].value = mclk;
3319 }
3320 }
3321
3322 if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display)
3323 data->need_update_dpm_table |= DPMTABLE_UPDATE_MCLK;
3324
3325 return 0;
3326 }
3327
3328 static int vega10_populate_and_upload_sclk_mclk_dpm_levels(
3329 struct pp_hwmgr *hwmgr, const void *input)
3330 {
3331 int result = 0;
3332 struct vega10_hwmgr *data = hwmgr->backend;
3333 struct vega10_dpm_table *dpm_table = &data->dpm_table;
3334 struct vega10_odn_dpm_table *odn_table = &data->odn_dpm_table;
3335 struct vega10_odn_clock_voltage_dependency_table *odn_clk_table = &odn_table->vdd_dep_on_sclk;
3336 int count;
3337
3338 if (!data->need_update_dpm_table)
3339 return 0;
3340
3341 if (hwmgr->od_enabled && data->need_update_dpm_table & DPMTABLE_OD_UPDATE_SCLK) {
3342 for (count = 0; count < dpm_table->gfx_table.count; count++)
3343 dpm_table->gfx_table.dpm_levels[count].value = odn_clk_table->entries[count].clk;
3344 }
3345
3346 odn_clk_table = &odn_table->vdd_dep_on_mclk;
3347 if (hwmgr->od_enabled && data->need_update_dpm_table & DPMTABLE_OD_UPDATE_MCLK) {
3348 for (count = 0; count < dpm_table->mem_table.count; count++)
3349 dpm_table->mem_table.dpm_levels[count].value = odn_clk_table->entries[count].clk;
3350 }
3351
3352 if (data->need_update_dpm_table &
3353 (DPMTABLE_OD_UPDATE_SCLK + DPMTABLE_UPDATE_SCLK + DPMTABLE_UPDATE_SOCCLK)) {
3354 result = vega10_populate_all_graphic_levels(hwmgr);
3355 PP_ASSERT_WITH_CODE((0 == result),
3356 "Failed to populate SCLK during PopulateNewDPMClocksStates Function!",
3357 return result);
3358 }
3359
3360 if (data->need_update_dpm_table &
3361 (DPMTABLE_OD_UPDATE_MCLK + DPMTABLE_UPDATE_MCLK)) {
3362 result = vega10_populate_all_memory_levels(hwmgr);
3363 PP_ASSERT_WITH_CODE((0 == result),
3364 "Failed to populate MCLK during PopulateNewDPMClocksStates Function!",
3365 return result);
3366 }
3367
3368 vega10_populate_vddc_soc_levels(hwmgr);
3369
3370 return result;
3371 }
3372
3373 static int vega10_trim_single_dpm_states(struct pp_hwmgr *hwmgr,
3374 struct vega10_single_dpm_table *dpm_table,
3375 uint32_t low_limit, uint32_t high_limit)
3376 {
3377 uint32_t i;
3378
3379 for (i = 0; i < dpm_table->count; i++) {
3380 if ((dpm_table->dpm_levels[i].value < low_limit) ||
3381 (dpm_table->dpm_levels[i].value > high_limit))
3382 dpm_table->dpm_levels[i].enabled = false;
3383 else
3384 dpm_table->dpm_levels[i].enabled = true;
3385 }
3386 return 0;
3387 }
3388
3389 static int vega10_trim_single_dpm_states_with_mask(struct pp_hwmgr *hwmgr,
3390 struct vega10_single_dpm_table *dpm_table,
3391 uint32_t low_limit, uint32_t high_limit,
3392 uint32_t disable_dpm_mask)
3393 {
3394 uint32_t i;
3395
3396 for (i = 0; i < dpm_table->count; i++) {
3397 if ((dpm_table->dpm_levels[i].value < low_limit) ||
3398 (dpm_table->dpm_levels[i].value > high_limit))
3399 dpm_table->dpm_levels[i].enabled = false;
3400 else if (!((1 << i) & disable_dpm_mask))
3401 dpm_table->dpm_levels[i].enabled = false;
3402 else
3403 dpm_table->dpm_levels[i].enabled = true;
3404 }
3405 return 0;
3406 }
3407
3408 static int vega10_trim_dpm_states(struct pp_hwmgr *hwmgr,
3409 const struct vega10_power_state *vega10_ps)
3410 {
3411 struct vega10_hwmgr *data = hwmgr->backend;
3412 uint32_t high_limit_count;
3413
3414 PP_ASSERT_WITH_CODE((vega10_ps->performance_level_count >= 1),
3415 "power state did not have any performance level",
3416 return -1);
3417
3418 high_limit_count = (vega10_ps->performance_level_count == 1) ? 0 : 1;
3419
3420 vega10_trim_single_dpm_states(hwmgr,
3421 &(data->dpm_table.soc_table),
3422 vega10_ps->performance_levels[0].soc_clock,
3423 vega10_ps->performance_levels[high_limit_count].soc_clock);
3424
3425 vega10_trim_single_dpm_states_with_mask(hwmgr,
3426 &(data->dpm_table.gfx_table),
3427 vega10_ps->performance_levels[0].gfx_clock,
3428 vega10_ps->performance_levels[high_limit_count].gfx_clock,
3429 data->disable_dpm_mask);
3430
3431 vega10_trim_single_dpm_states(hwmgr,
3432 &(data->dpm_table.mem_table),
3433 vega10_ps->performance_levels[0].mem_clock,
3434 vega10_ps->performance_levels[high_limit_count].mem_clock);
3435
3436 return 0;
3437 }
3438
3439 static uint32_t vega10_find_lowest_dpm_level(
3440 struct vega10_single_dpm_table *table)
3441 {
3442 uint32_t i;
3443
3444 for (i = 0; i < table->count; i++) {
3445 if (table->dpm_levels[i].enabled)
3446 break;
3447 }
3448
3449 return i;
3450 }
3451
3452 static uint32_t vega10_find_highest_dpm_level(
3453 struct vega10_single_dpm_table *table)
3454 {
3455 uint32_t i = 0;
3456
3457 if (table->count <= MAX_REGULAR_DPM_NUMBER) {
3458 for (i = table->count; i > 0; i--) {
3459 if (table->dpm_levels[i - 1].enabled)
3460 return i - 1;
3461 }
3462 } else {
3463 pr_info("DPM Table Has Too Many Entries!");
3464 return MAX_REGULAR_DPM_NUMBER - 1;
3465 }
3466
3467 return i;
3468 }
3469
3470 static void vega10_apply_dal_minimum_voltage_request(
3471 struct pp_hwmgr *hwmgr)
3472 {
3473 return;
3474 }
3475
3476 static int vega10_get_soc_index_for_max_uclk(struct pp_hwmgr *hwmgr)
3477 {
3478 struct phm_ppt_v1_clock_voltage_dependency_table *vdd_dep_table_on_mclk;
3479 struct phm_ppt_v2_information *table_info =
3480 (struct phm_ppt_v2_information *)(hwmgr->pptable);
3481
3482 vdd_dep_table_on_mclk = table_info->vdd_dep_on_mclk;
3483
3484 return vdd_dep_table_on_mclk->entries[NUM_UCLK_DPM_LEVELS - 1].vddInd + 1;
3485 }
3486
3487 static int vega10_upload_dpm_bootup_level(struct pp_hwmgr *hwmgr)
3488 {
3489 struct vega10_hwmgr *data = hwmgr->backend;
3490 uint32_t socclk_idx;
3491
3492 vega10_apply_dal_minimum_voltage_request(hwmgr);
3493
3494 if (!data->registry_data.sclk_dpm_key_disabled) {
3495 if (data->smc_state_table.gfx_boot_level !=
3496 data->dpm_table.gfx_table.dpm_state.soft_min_level) {
3497 smum_send_msg_to_smc_with_parameter(hwmgr,
3498 PPSMC_MSG_SetSoftMinGfxclkByIndex,
3499 data->smc_state_table.gfx_boot_level);
3500 data->dpm_table.gfx_table.dpm_state.soft_min_level =
3501 data->smc_state_table.gfx_boot_level;
3502 }
3503 }
3504
3505 if (!data->registry_data.mclk_dpm_key_disabled) {
3506 if (data->smc_state_table.mem_boot_level !=
3507 data->dpm_table.mem_table.dpm_state.soft_min_level) {
3508 if (data->smc_state_table.mem_boot_level == NUM_UCLK_DPM_LEVELS - 1) {
3509 socclk_idx = vega10_get_soc_index_for_max_uclk(hwmgr);
3510 smum_send_msg_to_smc_with_parameter(hwmgr,
3511 PPSMC_MSG_SetSoftMinSocclkByIndex,
3512 socclk_idx);
3513 } else {
3514 smum_send_msg_to_smc_with_parameter(hwmgr,
3515 PPSMC_MSG_SetSoftMinUclkByIndex,
3516 data->smc_state_table.mem_boot_level);
3517 }
3518 data->dpm_table.mem_table.dpm_state.soft_min_level =
3519 data->smc_state_table.mem_boot_level;
3520 }
3521 }
3522
3523 if (!data->registry_data.socclk_dpm_key_disabled) {
3524 if (data->smc_state_table.soc_boot_level !=
3525 data->dpm_table.soc_table.dpm_state.soft_min_level) {
3526 smum_send_msg_to_smc_with_parameter(hwmgr,
3527 PPSMC_MSG_SetSoftMinSocclkByIndex,
3528 data->smc_state_table.soc_boot_level);
3529 data->dpm_table.soc_table.dpm_state.soft_min_level =
3530 data->smc_state_table.soc_boot_level;
3531 }
3532 }
3533
3534 return 0;
3535 }
3536
3537 static int vega10_upload_dpm_max_level(struct pp_hwmgr *hwmgr)
3538 {
3539 struct vega10_hwmgr *data = hwmgr->backend;
3540
3541 vega10_apply_dal_minimum_voltage_request(hwmgr);
3542
3543 if (!data->registry_data.sclk_dpm_key_disabled) {
3544 if (data->smc_state_table.gfx_max_level !=
3545 data->dpm_table.gfx_table.dpm_state.soft_max_level) {
3546 smum_send_msg_to_smc_with_parameter(hwmgr,
3547 PPSMC_MSG_SetSoftMaxGfxclkByIndex,
3548 data->smc_state_table.gfx_max_level);
3549 data->dpm_table.gfx_table.dpm_state.soft_max_level =
3550 data->smc_state_table.gfx_max_level;
3551 }
3552 }
3553
3554 if (!data->registry_data.mclk_dpm_key_disabled) {
3555 if (data->smc_state_table.mem_max_level !=
3556 data->dpm_table.mem_table.dpm_state.soft_max_level) {
3557 smum_send_msg_to_smc_with_parameter(hwmgr,
3558 PPSMC_MSG_SetSoftMaxUclkByIndex,
3559 data->smc_state_table.mem_max_level);
3560 data->dpm_table.mem_table.dpm_state.soft_max_level =
3561 data->smc_state_table.mem_max_level;
3562 }
3563 }
3564
3565 if (!data->registry_data.socclk_dpm_key_disabled) {
3566 if (data->smc_state_table.soc_max_level !=
3567 data->dpm_table.soc_table.dpm_state.soft_max_level) {
3568 smum_send_msg_to_smc_with_parameter(hwmgr,
3569 PPSMC_MSG_SetSoftMaxSocclkByIndex,
3570 data->smc_state_table.soc_max_level);
3571 data->dpm_table.soc_table.dpm_state.soft_max_level =
3572 data->smc_state_table.soc_max_level;
3573 }
3574 }
3575
3576 return 0;
3577 }
3578
3579 static int vega10_generate_dpm_level_enable_mask(
3580 struct pp_hwmgr *hwmgr, const void *input)
3581 {
3582 struct vega10_hwmgr *data = hwmgr->backend;
3583 const struct phm_set_power_state_input *states =
3584 (const struct phm_set_power_state_input *)input;
3585 const struct vega10_power_state *vega10_ps =
3586 cast_const_phw_vega10_power_state(states->pnew_state);
3587 int i;
3588
3589 PP_ASSERT_WITH_CODE(!vega10_trim_dpm_states(hwmgr, vega10_ps),
3590 "Attempt to Trim DPM States Failed!",
3591 return -1);
3592
3593 data->smc_state_table.gfx_boot_level =
3594 vega10_find_lowest_dpm_level(&(data->dpm_table.gfx_table));
3595 data->smc_state_table.gfx_max_level =
3596 vega10_find_highest_dpm_level(&(data->dpm_table.gfx_table));
3597 data->smc_state_table.mem_boot_level =
3598 vega10_find_lowest_dpm_level(&(data->dpm_table.mem_table));
3599 data->smc_state_table.mem_max_level =
3600 vega10_find_highest_dpm_level(&(data->dpm_table.mem_table));
3601 data->smc_state_table.soc_boot_level =
3602 vega10_find_lowest_dpm_level(&(data->dpm_table.soc_table));
3603 data->smc_state_table.soc_max_level =
3604 vega10_find_highest_dpm_level(&(data->dpm_table.soc_table));
3605
3606 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_bootup_level(hwmgr),
3607 "Attempt to upload DPM Bootup Levels Failed!",
3608 return -1);
3609 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_max_level(hwmgr),
3610 "Attempt to upload DPM Max Levels Failed!",
3611 return -1);
3612 for(i = data->smc_state_table.gfx_boot_level; i < data->smc_state_table.gfx_max_level; i++)
3613 data->dpm_table.gfx_table.dpm_levels[i].enabled = true;
3614
3615
3616 for(i = data->smc_state_table.mem_boot_level; i < data->smc_state_table.mem_max_level; i++)
3617 data->dpm_table.mem_table.dpm_levels[i].enabled = true;
3618
3619 for (i = data->smc_state_table.soc_boot_level; i < data->smc_state_table.soc_max_level; i++)
3620 data->dpm_table.soc_table.dpm_levels[i].enabled = true;
3621
3622 return 0;
3623 }
3624
3625 int vega10_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
3626 {
3627 struct vega10_hwmgr *data = hwmgr->backend;
3628
3629 if (data->smu_features[GNLD_DPM_VCE].supported) {
3630 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
3631 enable,
3632 data->smu_features[GNLD_DPM_VCE].smu_feature_bitmap),
3633 "Attempt to Enable/Disable DPM VCE Failed!",
3634 return -1);
3635 data->smu_features[GNLD_DPM_VCE].enabled = enable;
3636 }
3637
3638 return 0;
3639 }
3640
3641 static int vega10_update_sclk_threshold(struct pp_hwmgr *hwmgr)
3642 {
3643 struct vega10_hwmgr *data = hwmgr->backend;
3644 uint32_t low_sclk_interrupt_threshold = 0;
3645
3646 if (PP_CAP(PHM_PlatformCaps_SclkThrottleLowNotification) &&
3647 (data->low_sclk_interrupt_threshold != 0)) {
3648 low_sclk_interrupt_threshold =
3649 data->low_sclk_interrupt_threshold;
3650
3651 data->smc_state_table.pp_table.LowGfxclkInterruptThreshold =
3652 cpu_to_le32(low_sclk_interrupt_threshold);
3653
3654
3655 smum_send_msg_to_smc_with_parameter(hwmgr,
3656 PPSMC_MSG_SetLowGfxclkInterruptThreshold,
3657 (uint32_t)low_sclk_interrupt_threshold);
3658 }
3659
3660 return 0;
3661 }
3662
3663 static int vega10_set_power_state_tasks(struct pp_hwmgr *hwmgr,
3664 const void *input)
3665 {
3666 int tmp_result, result = 0;
3667 struct vega10_hwmgr *data = hwmgr->backend;
3668 PPTable_t *pp_table = &(data->smc_state_table.pp_table);
3669
3670 tmp_result = vega10_find_dpm_states_clocks_in_dpm_table(hwmgr, input);
3671 PP_ASSERT_WITH_CODE(!tmp_result,
3672 "Failed to find DPM states clocks in DPM table!",
3673 result = tmp_result);
3674
3675 tmp_result = vega10_populate_and_upload_sclk_mclk_dpm_levels(hwmgr, input);
3676 PP_ASSERT_WITH_CODE(!tmp_result,
3677 "Failed to populate and upload SCLK MCLK DPM levels!",
3678 result = tmp_result);
3679
3680 tmp_result = vega10_generate_dpm_level_enable_mask(hwmgr, input);
3681 PP_ASSERT_WITH_CODE(!tmp_result,
3682 "Failed to generate DPM level enabled mask!",
3683 result = tmp_result);
3684
3685 tmp_result = vega10_update_sclk_threshold(hwmgr);
3686 PP_ASSERT_WITH_CODE(!tmp_result,
3687 "Failed to update SCLK threshold!",
3688 result = tmp_result);
3689
3690 result = smum_smc_table_manager(hwmgr, (uint8_t *)pp_table, PPTABLE, false);
3691 PP_ASSERT_WITH_CODE(!result,
3692 "Failed to upload PPtable!", return result);
3693
3694 vega10_update_avfs(hwmgr);
3695
3696
3697
3698
3699
3700 data->need_update_dpm_table &= DPMTABLE_OD_UPDATE_VDDC;
3701
3702 return 0;
3703 }
3704
3705 static uint32_t vega10_dpm_get_sclk(struct pp_hwmgr *hwmgr, bool low)
3706 {
3707 struct pp_power_state *ps;
3708 struct vega10_power_state *vega10_ps;
3709
3710 if (hwmgr == NULL)
3711 return -EINVAL;
3712
3713 ps = hwmgr->request_ps;
3714
3715 if (ps == NULL)
3716 return -EINVAL;
3717
3718 vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
3719
3720 if (low)
3721 return vega10_ps->performance_levels[0].gfx_clock;
3722 else
3723 return vega10_ps->performance_levels
3724 [vega10_ps->performance_level_count - 1].gfx_clock;
3725 }
3726
3727 static uint32_t vega10_dpm_get_mclk(struct pp_hwmgr *hwmgr, bool low)
3728 {
3729 struct pp_power_state *ps;
3730 struct vega10_power_state *vega10_ps;
3731
3732 if (hwmgr == NULL)
3733 return -EINVAL;
3734
3735 ps = hwmgr->request_ps;
3736
3737 if (ps == NULL)
3738 return -EINVAL;
3739
3740 vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
3741
3742 if (low)
3743 return vega10_ps->performance_levels[0].mem_clock;
3744 else
3745 return vega10_ps->performance_levels
3746 [vega10_ps->performance_level_count-1].mem_clock;
3747 }
3748
3749 static int vega10_get_gpu_power(struct pp_hwmgr *hwmgr,
3750 uint32_t *query)
3751 {
3752 uint32_t value;
3753
3754 if (!query)
3755 return -EINVAL;
3756
3757 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrPkgPwr);
3758 value = smum_get_argument(hwmgr);
3759
3760
3761 *query = value << 8;
3762
3763 return 0;
3764 }
3765
3766 static int vega10_read_sensor(struct pp_hwmgr *hwmgr, int idx,
3767 void *value, int *size)
3768 {
3769 struct amdgpu_device *adev = hwmgr->adev;
3770 uint32_t sclk_mhz, mclk_idx, activity_percent = 0;
3771 struct vega10_hwmgr *data = hwmgr->backend;
3772 struct vega10_dpm_table *dpm_table = &data->dpm_table;
3773 int ret = 0;
3774 uint32_t val_vid;
3775
3776 switch (idx) {
3777 case AMDGPU_PP_SENSOR_GFX_SCLK:
3778 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetAverageGfxclkActualFrequency);
3779 sclk_mhz = smum_get_argument(hwmgr);
3780 *((uint32_t *)value) = sclk_mhz * 100;
3781 break;
3782 case AMDGPU_PP_SENSOR_GFX_MCLK:
3783 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex);
3784 mclk_idx = smum_get_argument(hwmgr);
3785 if (mclk_idx < dpm_table->mem_table.count) {
3786 *((uint32_t *)value) = dpm_table->mem_table.dpm_levels[mclk_idx].value;
3787 *size = 4;
3788 } else {
3789 ret = -EINVAL;
3790 }
3791 break;
3792 case AMDGPU_PP_SENSOR_GPU_LOAD:
3793 smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetAverageGfxActivity, 0);
3794 activity_percent = smum_get_argument(hwmgr);
3795 *((uint32_t *)value) = activity_percent > 100 ? 100 : activity_percent;
3796 *size = 4;
3797 break;
3798 case AMDGPU_PP_SENSOR_GPU_TEMP:
3799 *((uint32_t *)value) = vega10_thermal_get_temperature(hwmgr);
3800 *size = 4;
3801 break;
3802 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
3803 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetTemperatureHotspot);
3804 *((uint32_t *)value) = smum_get_argument(hwmgr) *
3805 PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
3806 *size = 4;
3807 break;
3808 case AMDGPU_PP_SENSOR_MEM_TEMP:
3809 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetTemperatureHBM);
3810 *((uint32_t *)value) = smum_get_argument(hwmgr) *
3811 PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
3812 *size = 4;
3813 break;
3814 case AMDGPU_PP_SENSOR_UVD_POWER:
3815 *((uint32_t *)value) = data->uvd_power_gated ? 0 : 1;
3816 *size = 4;
3817 break;
3818 case AMDGPU_PP_SENSOR_VCE_POWER:
3819 *((uint32_t *)value) = data->vce_power_gated ? 0 : 1;
3820 *size = 4;
3821 break;
3822 case AMDGPU_PP_SENSOR_GPU_POWER:
3823 ret = vega10_get_gpu_power(hwmgr, (uint32_t *)value);
3824 break;
3825 case AMDGPU_PP_SENSOR_VDDGFX:
3826 val_vid = (RREG32_SOC15(SMUIO, 0, mmSMUSVI0_PLANE0_CURRENTVID) &
3827 SMUSVI0_PLANE0_CURRENTVID__CURRENT_SVI0_PLANE0_VID_MASK) >>
3828 SMUSVI0_PLANE0_CURRENTVID__CURRENT_SVI0_PLANE0_VID__SHIFT;
3829 *((uint32_t *)value) = (uint32_t)convert_to_vddc((uint8_t)val_vid);
3830 return 0;
3831 case AMDGPU_PP_SENSOR_ENABLED_SMC_FEATURES_MASK:
3832 ret = vega10_get_enabled_smc_features(hwmgr, (uint64_t *)value);
3833 if (!ret)
3834 *size = 8;
3835 break;
3836 default:
3837 ret = -EINVAL;
3838 break;
3839 }
3840
3841 return ret;
3842 }
3843
3844 static void vega10_notify_smc_display_change(struct pp_hwmgr *hwmgr,
3845 bool has_disp)
3846 {
3847 smum_send_msg_to_smc_with_parameter(hwmgr,
3848 PPSMC_MSG_SetUclkFastSwitch,
3849 has_disp ? 1 : 0);
3850 }
3851
3852 int vega10_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
3853 struct pp_display_clock_request *clock_req)
3854 {
3855 int result = 0;
3856 enum amd_pp_clock_type clk_type = clock_req->clock_type;
3857 uint32_t clk_freq = clock_req->clock_freq_in_khz / 1000;
3858 DSPCLK_e clk_select = 0;
3859 uint32_t clk_request = 0;
3860
3861 switch (clk_type) {
3862 case amd_pp_dcef_clock:
3863 clk_select = DSPCLK_DCEFCLK;
3864 break;
3865 case amd_pp_disp_clock:
3866 clk_select = DSPCLK_DISPCLK;
3867 break;
3868 case amd_pp_pixel_clock:
3869 clk_select = DSPCLK_PIXCLK;
3870 break;
3871 case amd_pp_phy_clock:
3872 clk_select = DSPCLK_PHYCLK;
3873 break;
3874 default:
3875 pr_info("[DisplayClockVoltageRequest]Invalid Clock Type!");
3876 result = -1;
3877 break;
3878 }
3879
3880 if (!result) {
3881 clk_request = (clk_freq << 16) | clk_select;
3882 smum_send_msg_to_smc_with_parameter(hwmgr,
3883 PPSMC_MSG_RequestDisplayClockByFreq,
3884 clk_request);
3885 }
3886
3887 return result;
3888 }
3889
3890 static uint8_t vega10_get_uclk_index(struct pp_hwmgr *hwmgr,
3891 struct phm_ppt_v1_clock_voltage_dependency_table *mclk_table,
3892 uint32_t frequency)
3893 {
3894 uint8_t count;
3895 uint8_t i;
3896
3897 if (mclk_table == NULL || mclk_table->count == 0)
3898 return 0;
3899
3900 count = (uint8_t)(mclk_table->count);
3901
3902 for(i = 0; i < count; i++) {
3903 if(mclk_table->entries[i].clk >= frequency)
3904 return i;
3905 }
3906
3907 return i-1;
3908 }
3909
3910 static int vega10_notify_smc_display_config_after_ps_adjustment(
3911 struct pp_hwmgr *hwmgr)
3912 {
3913 struct vega10_hwmgr *data = hwmgr->backend;
3914 struct vega10_single_dpm_table *dpm_table =
3915 &data->dpm_table.dcef_table;
3916 struct phm_ppt_v2_information *table_info =
3917 (struct phm_ppt_v2_information *)hwmgr->pptable;
3918 struct phm_ppt_v1_clock_voltage_dependency_table *mclk_table = table_info->vdd_dep_on_mclk;
3919 uint32_t idx;
3920 struct PP_Clocks min_clocks = {0};
3921 uint32_t i;
3922 struct pp_display_clock_request clock_req;
3923
3924 if ((hwmgr->display_config->num_display > 1) &&
3925 !hwmgr->display_config->multi_monitor_in_sync &&
3926 !hwmgr->display_config->nb_pstate_switch_disable)
3927 vega10_notify_smc_display_change(hwmgr, false);
3928 else
3929 vega10_notify_smc_display_change(hwmgr, true);
3930
3931 min_clocks.dcefClock = hwmgr->display_config->min_dcef_set_clk;
3932 min_clocks.dcefClockInSR = hwmgr->display_config->min_dcef_deep_sleep_set_clk;
3933 min_clocks.memoryClock = hwmgr->display_config->min_mem_set_clock;
3934
3935 for (i = 0; i < dpm_table->count; i++) {
3936 if (dpm_table->dpm_levels[i].value == min_clocks.dcefClock)
3937 break;
3938 }
3939
3940 if (i < dpm_table->count) {
3941 clock_req.clock_type = amd_pp_dcef_clock;
3942 clock_req.clock_freq_in_khz = dpm_table->dpm_levels[i].value * 10;
3943 if (!vega10_display_clock_voltage_request(hwmgr, &clock_req)) {
3944 smum_send_msg_to_smc_with_parameter(
3945 hwmgr, PPSMC_MSG_SetMinDeepSleepDcefclk,
3946 min_clocks.dcefClockInSR / 100);
3947 } else {
3948 pr_info("Attempt to set Hard Min for DCEFCLK Failed!");
3949 }
3950 } else {
3951 pr_debug("Cannot find requested DCEFCLK!");
3952 }
3953
3954 if (min_clocks.memoryClock != 0) {
3955 idx = vega10_get_uclk_index(hwmgr, mclk_table, min_clocks.memoryClock);
3956 smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetSoftMinUclkByIndex, idx);
3957 data->dpm_table.mem_table.dpm_state.soft_min_level= idx;
3958 }
3959
3960 return 0;
3961 }
3962
3963 static int vega10_force_dpm_highest(struct pp_hwmgr *hwmgr)
3964 {
3965 struct vega10_hwmgr *data = hwmgr->backend;
3966
3967 data->smc_state_table.gfx_boot_level =
3968 data->smc_state_table.gfx_max_level =
3969 vega10_find_highest_dpm_level(&(data->dpm_table.gfx_table));
3970 data->smc_state_table.mem_boot_level =
3971 data->smc_state_table.mem_max_level =
3972 vega10_find_highest_dpm_level(&(data->dpm_table.mem_table));
3973
3974 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_bootup_level(hwmgr),
3975 "Failed to upload boot level to highest!",
3976 return -1);
3977
3978 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_max_level(hwmgr),
3979 "Failed to upload dpm max level to highest!",
3980 return -1);
3981
3982 return 0;
3983 }
3984
3985 static int vega10_force_dpm_lowest(struct pp_hwmgr *hwmgr)
3986 {
3987 struct vega10_hwmgr *data = hwmgr->backend;
3988
3989 data->smc_state_table.gfx_boot_level =
3990 data->smc_state_table.gfx_max_level =
3991 vega10_find_lowest_dpm_level(&(data->dpm_table.gfx_table));
3992 data->smc_state_table.mem_boot_level =
3993 data->smc_state_table.mem_max_level =
3994 vega10_find_lowest_dpm_level(&(data->dpm_table.mem_table));
3995
3996 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_bootup_level(hwmgr),
3997 "Failed to upload boot level to highest!",
3998 return -1);
3999
4000 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_max_level(hwmgr),
4001 "Failed to upload dpm max level to highest!",
4002 return -1);
4003
4004 return 0;
4005
4006 }
4007
4008 static int vega10_unforce_dpm_levels(struct pp_hwmgr *hwmgr)
4009 {
4010 struct vega10_hwmgr *data = hwmgr->backend;
4011
4012 data->smc_state_table.gfx_boot_level =
4013 vega10_find_lowest_dpm_level(&(data->dpm_table.gfx_table));
4014 data->smc_state_table.gfx_max_level =
4015 vega10_find_highest_dpm_level(&(data->dpm_table.gfx_table));
4016 data->smc_state_table.mem_boot_level =
4017 vega10_find_lowest_dpm_level(&(data->dpm_table.mem_table));
4018 data->smc_state_table.mem_max_level =
4019 vega10_find_highest_dpm_level(&(data->dpm_table.mem_table));
4020
4021 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_bootup_level(hwmgr),
4022 "Failed to upload DPM Bootup Levels!",
4023 return -1);
4024
4025 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_max_level(hwmgr),
4026 "Failed to upload DPM Max Levels!",
4027 return -1);
4028 return 0;
4029 }
4030
4031 static int vega10_get_profiling_clk_mask(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level,
4032 uint32_t *sclk_mask, uint32_t *mclk_mask, uint32_t *soc_mask)
4033 {
4034 struct phm_ppt_v2_information *table_info =
4035 (struct phm_ppt_v2_information *)(hwmgr->pptable);
4036
4037 if (table_info->vdd_dep_on_sclk->count > VEGA10_UMD_PSTATE_GFXCLK_LEVEL &&
4038 table_info->vdd_dep_on_socclk->count > VEGA10_UMD_PSTATE_SOCCLK_LEVEL &&
4039 table_info->vdd_dep_on_mclk->count > VEGA10_UMD_PSTATE_MCLK_LEVEL) {
4040 *sclk_mask = VEGA10_UMD_PSTATE_GFXCLK_LEVEL;
4041 *soc_mask = VEGA10_UMD_PSTATE_SOCCLK_LEVEL;
4042 *mclk_mask = VEGA10_UMD_PSTATE_MCLK_LEVEL;
4043 hwmgr->pstate_sclk = table_info->vdd_dep_on_sclk->entries[VEGA10_UMD_PSTATE_GFXCLK_LEVEL].clk;
4044 hwmgr->pstate_mclk = table_info->vdd_dep_on_mclk->entries[VEGA10_UMD_PSTATE_MCLK_LEVEL].clk;
4045 }
4046
4047 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) {
4048 *sclk_mask = 0;
4049 } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) {
4050 *mclk_mask = 0;
4051 } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) {
4052 *sclk_mask = table_info->vdd_dep_on_sclk->count - 1;
4053 *soc_mask = table_info->vdd_dep_on_socclk->count - 1;
4054 *mclk_mask = table_info->vdd_dep_on_mclk->count - 1;
4055 }
4056 return 0;
4057 }
4058
4059 static void vega10_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
4060 {
4061 switch (mode) {
4062 case AMD_FAN_CTRL_NONE:
4063 vega10_fan_ctrl_set_fan_speed_percent(hwmgr, 100);
4064 break;
4065 case AMD_FAN_CTRL_MANUAL:
4066 if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
4067 vega10_fan_ctrl_stop_smc_fan_control(hwmgr);
4068 break;
4069 case AMD_FAN_CTRL_AUTO:
4070 if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
4071 vega10_fan_ctrl_start_smc_fan_control(hwmgr);
4072 break;
4073 default:
4074 break;
4075 }
4076 }
4077
4078 static int vega10_force_clock_level(struct pp_hwmgr *hwmgr,
4079 enum pp_clock_type type, uint32_t mask)
4080 {
4081 struct vega10_hwmgr *data = hwmgr->backend;
4082
4083 switch (type) {
4084 case PP_SCLK:
4085 data->smc_state_table.gfx_boot_level = mask ? (ffs(mask) - 1) : 0;
4086 data->smc_state_table.gfx_max_level = mask ? (fls(mask) - 1) : 0;
4087
4088 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_bootup_level(hwmgr),
4089 "Failed to upload boot level to lowest!",
4090 return -EINVAL);
4091
4092 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_max_level(hwmgr),
4093 "Failed to upload dpm max level to highest!",
4094 return -EINVAL);
4095 break;
4096
4097 case PP_MCLK:
4098 data->smc_state_table.mem_boot_level = mask ? (ffs(mask) - 1) : 0;
4099 data->smc_state_table.mem_max_level = mask ? (fls(mask) - 1) : 0;
4100
4101 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_bootup_level(hwmgr),
4102 "Failed to upload boot level to lowest!",
4103 return -EINVAL);
4104
4105 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_max_level(hwmgr),
4106 "Failed to upload dpm max level to highest!",
4107 return -EINVAL);
4108
4109 break;
4110
4111 case PP_SOCCLK:
4112 data->smc_state_table.soc_boot_level = mask ? (ffs(mask) - 1) : 0;
4113 data->smc_state_table.soc_max_level = mask ? (fls(mask) - 1) : 0;
4114
4115 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_bootup_level(hwmgr),
4116 "Failed to upload boot level to lowest!",
4117 return -EINVAL);
4118
4119 PP_ASSERT_WITH_CODE(!vega10_upload_dpm_max_level(hwmgr),
4120 "Failed to upload dpm max level to highest!",
4121 return -EINVAL);
4122
4123 break;
4124
4125 case PP_DCEFCLK:
4126 pr_info("Setting DCEFCLK min/max dpm level is not supported!\n");
4127 break;
4128
4129 case PP_PCIE:
4130 default:
4131 break;
4132 }
4133
4134 return 0;
4135 }
4136
4137 static int vega10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
4138 enum amd_dpm_forced_level level)
4139 {
4140 int ret = 0;
4141 uint32_t sclk_mask = 0;
4142 uint32_t mclk_mask = 0;
4143 uint32_t soc_mask = 0;
4144
4145 if (hwmgr->pstate_sclk == 0)
4146 vega10_get_profiling_clk_mask(hwmgr, level, &sclk_mask, &mclk_mask, &soc_mask);
4147
4148 switch (level) {
4149 case AMD_DPM_FORCED_LEVEL_HIGH:
4150 ret = vega10_force_dpm_highest(hwmgr);
4151 break;
4152 case AMD_DPM_FORCED_LEVEL_LOW:
4153 ret = vega10_force_dpm_lowest(hwmgr);
4154 break;
4155 case AMD_DPM_FORCED_LEVEL_AUTO:
4156 ret = vega10_unforce_dpm_levels(hwmgr);
4157 break;
4158 case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
4159 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
4160 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
4161 case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
4162 ret = vega10_get_profiling_clk_mask(hwmgr, level, &sclk_mask, &mclk_mask, &soc_mask);
4163 if (ret)
4164 return ret;
4165 vega10_force_clock_level(hwmgr, PP_SCLK, 1<<sclk_mask);
4166 vega10_force_clock_level(hwmgr, PP_MCLK, 1<<mclk_mask);
4167 break;
4168 case AMD_DPM_FORCED_LEVEL_MANUAL:
4169 case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
4170 default:
4171 break;
4172 }
4173
4174 if (!ret) {
4175 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK && hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
4176 vega10_set_fan_control_mode(hwmgr, AMD_FAN_CTRL_NONE);
4177 else if (level != AMD_DPM_FORCED_LEVEL_PROFILE_PEAK && hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
4178 vega10_set_fan_control_mode(hwmgr, AMD_FAN_CTRL_AUTO);
4179 }
4180
4181 return ret;
4182 }
4183
4184 static uint32_t vega10_get_fan_control_mode(struct pp_hwmgr *hwmgr)
4185 {
4186 struct vega10_hwmgr *data = hwmgr->backend;
4187
4188 if (data->smu_features[GNLD_FAN_CONTROL].enabled == false)
4189 return AMD_FAN_CTRL_MANUAL;
4190 else
4191 return AMD_FAN_CTRL_AUTO;
4192 }
4193
4194 static int vega10_get_dal_power_level(struct pp_hwmgr *hwmgr,
4195 struct amd_pp_simple_clock_info *info)
4196 {
4197 struct phm_ppt_v2_information *table_info =
4198 (struct phm_ppt_v2_information *)hwmgr->pptable;
4199 struct phm_clock_and_voltage_limits *max_limits =
4200 &table_info->max_clock_voltage_on_ac;
4201
4202 info->engine_max_clock = max_limits->sclk;
4203 info->memory_max_clock = max_limits->mclk;
4204
4205 return 0;
4206 }
4207
4208 static void vega10_get_sclks(struct pp_hwmgr *hwmgr,
4209 struct pp_clock_levels_with_latency *clocks)
4210 {
4211 struct phm_ppt_v2_information *table_info =
4212 (struct phm_ppt_v2_information *)hwmgr->pptable;
4213 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table =
4214 table_info->vdd_dep_on_sclk;
4215 uint32_t i;
4216
4217 clocks->num_levels = 0;
4218 for (i = 0; i < dep_table->count; i++) {
4219 if (dep_table->entries[i].clk) {
4220 clocks->data[clocks->num_levels].clocks_in_khz =
4221 dep_table->entries[i].clk * 10;
4222 clocks->num_levels++;
4223 }
4224 }
4225
4226 }
4227
4228 static void vega10_get_memclocks(struct pp_hwmgr *hwmgr,
4229 struct pp_clock_levels_with_latency *clocks)
4230 {
4231 struct phm_ppt_v2_information *table_info =
4232 (struct phm_ppt_v2_information *)hwmgr->pptable;
4233 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table =
4234 table_info->vdd_dep_on_mclk;
4235 struct vega10_hwmgr *data = hwmgr->backend;
4236 uint32_t j = 0;
4237 uint32_t i;
4238
4239 for (i = 0; i < dep_table->count; i++) {
4240 if (dep_table->entries[i].clk) {
4241
4242 clocks->data[j].clocks_in_khz =
4243 dep_table->entries[i].clk * 10;
4244 data->mclk_latency_table.entries[j].frequency =
4245 dep_table->entries[i].clk;
4246 clocks->data[j].latency_in_us =
4247 data->mclk_latency_table.entries[j].latency = 25;
4248 j++;
4249 }
4250 }
4251 clocks->num_levels = data->mclk_latency_table.count = j;
4252 }
4253
4254 static void vega10_get_dcefclocks(struct pp_hwmgr *hwmgr,
4255 struct pp_clock_levels_with_latency *clocks)
4256 {
4257 struct phm_ppt_v2_information *table_info =
4258 (struct phm_ppt_v2_information *)hwmgr->pptable;
4259 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table =
4260 table_info->vdd_dep_on_dcefclk;
4261 uint32_t i;
4262
4263 for (i = 0; i < dep_table->count; i++) {
4264 clocks->data[i].clocks_in_khz = dep_table->entries[i].clk * 10;
4265 clocks->data[i].latency_in_us = 0;
4266 clocks->num_levels++;
4267 }
4268 }
4269
4270 static void vega10_get_socclocks(struct pp_hwmgr *hwmgr,
4271 struct pp_clock_levels_with_latency *clocks)
4272 {
4273 struct phm_ppt_v2_information *table_info =
4274 (struct phm_ppt_v2_information *)hwmgr->pptable;
4275 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table =
4276 table_info->vdd_dep_on_socclk;
4277 uint32_t i;
4278
4279 for (i = 0; i < dep_table->count; i++) {
4280 clocks->data[i].clocks_in_khz = dep_table->entries[i].clk * 10;
4281 clocks->data[i].latency_in_us = 0;
4282 clocks->num_levels++;
4283 }
4284 }
4285
4286 static int vega10_get_clock_by_type_with_latency(struct pp_hwmgr *hwmgr,
4287 enum amd_pp_clock_type type,
4288 struct pp_clock_levels_with_latency *clocks)
4289 {
4290 switch (type) {
4291 case amd_pp_sys_clock:
4292 vega10_get_sclks(hwmgr, clocks);
4293 break;
4294 case amd_pp_mem_clock:
4295 vega10_get_memclocks(hwmgr, clocks);
4296 break;
4297 case amd_pp_dcef_clock:
4298 vega10_get_dcefclocks(hwmgr, clocks);
4299 break;
4300 case amd_pp_soc_clock:
4301 vega10_get_socclocks(hwmgr, clocks);
4302 break;
4303 default:
4304 return -1;
4305 }
4306
4307 return 0;
4308 }
4309
4310 static int vega10_get_clock_by_type_with_voltage(struct pp_hwmgr *hwmgr,
4311 enum amd_pp_clock_type type,
4312 struct pp_clock_levels_with_voltage *clocks)
4313 {
4314 struct phm_ppt_v2_information *table_info =
4315 (struct phm_ppt_v2_information *)hwmgr->pptable;
4316 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table;
4317 uint32_t i;
4318
4319 switch (type) {
4320 case amd_pp_mem_clock:
4321 dep_table = table_info->vdd_dep_on_mclk;
4322 break;
4323 case amd_pp_dcef_clock:
4324 dep_table = table_info->vdd_dep_on_dcefclk;
4325 break;
4326 case amd_pp_disp_clock:
4327 dep_table = table_info->vdd_dep_on_dispclk;
4328 break;
4329 case amd_pp_pixel_clock:
4330 dep_table = table_info->vdd_dep_on_pixclk;
4331 break;
4332 case amd_pp_phy_clock:
4333 dep_table = table_info->vdd_dep_on_phyclk;
4334 break;
4335 default:
4336 return -1;
4337 }
4338
4339 for (i = 0; i < dep_table->count; i++) {
4340 clocks->data[i].clocks_in_khz = dep_table->entries[i].clk * 10;
4341 clocks->data[i].voltage_in_mv = (uint32_t)(table_info->vddc_lookup_table->
4342 entries[dep_table->entries[i].vddInd].us_vdd);
4343 clocks->num_levels++;
4344 }
4345
4346 if (i < dep_table->count)
4347 return -1;
4348
4349 return 0;
4350 }
4351
4352 static int vega10_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr,
4353 void *clock_range)
4354 {
4355 struct vega10_hwmgr *data = hwmgr->backend;
4356 struct dm_pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges = clock_range;
4357 Watermarks_t *table = &(data->smc_state_table.water_marks_table);
4358 int result = 0;
4359
4360 if (!data->registry_data.disable_water_mark) {
4361 smu_set_watermarks_for_clocks_ranges(table, wm_with_clock_ranges);
4362 data->water_marks_bitmap = WaterMarksExist;
4363 }
4364
4365 return result;
4366 }
4367
4368 static int vega10_get_ppfeature_status(struct pp_hwmgr *hwmgr, char *buf)
4369 {
4370 static const char *ppfeature_name[] = {
4371 "DPM_PREFETCHER",
4372 "GFXCLK_DPM",
4373 "UCLK_DPM",
4374 "SOCCLK_DPM",
4375 "UVD_DPM",
4376 "VCE_DPM",
4377 "ULV",
4378 "MP0CLK_DPM",
4379 "LINK_DPM",
4380 "DCEFCLK_DPM",
4381 "AVFS",
4382 "GFXCLK_DS",
4383 "SOCCLK_DS",
4384 "LCLK_DS",
4385 "PPT",
4386 "TDC",
4387 "THERMAL",
4388 "GFX_PER_CU_CG",
4389 "RM",
4390 "DCEFCLK_DS",
4391 "ACDC",
4392 "VR0HOT",
4393 "VR1HOT",
4394 "FW_CTF",
4395 "LED_DISPLAY",
4396 "FAN_CONTROL",
4397 "FAST_PPT",
4398 "DIDT",
4399 "ACG",
4400 "PCC_LIMIT"};
4401 static const char *output_title[] = {
4402 "FEATURES",
4403 "BITMASK",
4404 "ENABLEMENT"};
4405 uint64_t features_enabled;
4406 int i;
4407 int ret = 0;
4408 int size = 0;
4409
4410 ret = vega10_get_enabled_smc_features(hwmgr, &features_enabled);
4411 PP_ASSERT_WITH_CODE(!ret,
4412 "[EnableAllSmuFeatures] Failed to get enabled smc features!",
4413 return ret);
4414
4415 size += sprintf(buf + size, "Current ppfeatures: 0x%016llx\n", features_enabled);
4416 size += sprintf(buf + size, "%-19s %-22s %s\n",
4417 output_title[0],
4418 output_title[1],
4419 output_title[2]);
4420 for (i = 0; i < GNLD_FEATURES_MAX; i++) {
4421 size += sprintf(buf + size, "%-19s 0x%016llx %6s\n",
4422 ppfeature_name[i],
4423 1ULL << i,
4424 (features_enabled & (1ULL << i)) ? "Y" : "N");
4425 }
4426
4427 return size;
4428 }
4429
4430 static int vega10_set_ppfeature_status(struct pp_hwmgr *hwmgr, uint64_t new_ppfeature_masks)
4431 {
4432 uint64_t features_enabled;
4433 uint64_t features_to_enable;
4434 uint64_t features_to_disable;
4435 int ret = 0;
4436
4437 if (new_ppfeature_masks >= (1ULL << GNLD_FEATURES_MAX))
4438 return -EINVAL;
4439
4440 ret = vega10_get_enabled_smc_features(hwmgr, &features_enabled);
4441 if (ret)
4442 return ret;
4443
4444 features_to_disable =
4445 features_enabled & ~new_ppfeature_masks;
4446 features_to_enable =
4447 ~features_enabled & new_ppfeature_masks;
4448
4449 pr_debug("features_to_disable 0x%llx\n", features_to_disable);
4450 pr_debug("features_to_enable 0x%llx\n", features_to_enable);
4451
4452 if (features_to_disable) {
4453 ret = vega10_enable_smc_features(hwmgr, false, features_to_disable);
4454 if (ret)
4455 return ret;
4456 }
4457
4458 if (features_to_enable) {
4459 ret = vega10_enable_smc_features(hwmgr, true, features_to_enable);
4460 if (ret)
4461 return ret;
4462 }
4463
4464 return 0;
4465 }
4466
4467 static int vega10_print_clock_levels(struct pp_hwmgr *hwmgr,
4468 enum pp_clock_type type, char *buf)
4469 {
4470 struct vega10_hwmgr *data = hwmgr->backend;
4471 struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
4472 struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
4473 struct vega10_single_dpm_table *soc_table = &(data->dpm_table.soc_table);
4474 struct vega10_single_dpm_table *dcef_table = &(data->dpm_table.dcef_table);
4475 struct vega10_pcie_table *pcie_table = &(data->dpm_table.pcie_table);
4476 struct vega10_odn_clock_voltage_dependency_table *podn_vdd_dep = NULL;
4477
4478 int i, now, size = 0;
4479
4480 switch (type) {
4481 case PP_SCLK:
4482 if (data->registry_data.sclk_dpm_key_disabled)
4483 break;
4484
4485 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentGfxclkIndex);
4486 now = smum_get_argument(hwmgr);
4487
4488 for (i = 0; i < sclk_table->count; i++)
4489 size += sprintf(buf + size, "%d: %uMhz %s\n",
4490 i, sclk_table->dpm_levels[i].value / 100,
4491 (i == now) ? "*" : "");
4492 break;
4493 case PP_MCLK:
4494 if (data->registry_data.mclk_dpm_key_disabled)
4495 break;
4496
4497 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentUclkIndex);
4498 now = smum_get_argument(hwmgr);
4499
4500 for (i = 0; i < mclk_table->count; i++)
4501 size += sprintf(buf + size, "%d: %uMhz %s\n",
4502 i, mclk_table->dpm_levels[i].value / 100,
4503 (i == now) ? "*" : "");
4504 break;
4505 case PP_SOCCLK:
4506 if (data->registry_data.socclk_dpm_key_disabled)
4507 break;
4508
4509 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentSocclkIndex);
4510 now = smum_get_argument(hwmgr);
4511
4512 for (i = 0; i < soc_table->count; i++)
4513 size += sprintf(buf + size, "%d: %uMhz %s\n",
4514 i, soc_table->dpm_levels[i].value / 100,
4515 (i == now) ? "*" : "");
4516 break;
4517 case PP_DCEFCLK:
4518 if (data->registry_data.dcefclk_dpm_key_disabled)
4519 break;
4520
4521 smum_send_msg_to_smc_with_parameter(hwmgr,
4522 PPSMC_MSG_GetClockFreqMHz, CLK_DCEFCLK);
4523 now = smum_get_argument(hwmgr);
4524
4525 for (i = 0; i < dcef_table->count; i++)
4526 size += sprintf(buf + size, "%d: %uMhz %s\n",
4527 i, dcef_table->dpm_levels[i].value / 100,
4528 (dcef_table->dpm_levels[i].value / 100 == now) ?
4529 "*" : "");
4530 break;
4531 case PP_PCIE:
4532 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetCurrentLinkIndex);
4533 now = smum_get_argument(hwmgr);
4534
4535 for (i = 0; i < pcie_table->count; i++)
4536 size += sprintf(buf + size, "%d: %s %s\n", i,
4537 (pcie_table->pcie_gen[i] == 0) ? "2.5GT/s, x1" :
4538 (pcie_table->pcie_gen[i] == 1) ? "5.0GT/s, x16" :
4539 (pcie_table->pcie_gen[i] == 2) ? "8.0GT/s, x16" : "",
4540 (i == now) ? "*" : "");
4541 break;
4542 case OD_SCLK:
4543 if (hwmgr->od_enabled) {
4544 size = sprintf(buf, "%s:\n", "OD_SCLK");
4545 podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_sclk;
4546 for (i = 0; i < podn_vdd_dep->count; i++)
4547 size += sprintf(buf + size, "%d: %10uMhz %10umV\n",
4548 i, podn_vdd_dep->entries[i].clk / 100,
4549 podn_vdd_dep->entries[i].vddc);
4550 }
4551 break;
4552 case OD_MCLK:
4553 if (hwmgr->od_enabled) {
4554 size = sprintf(buf, "%s:\n", "OD_MCLK");
4555 podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_mclk;
4556 for (i = 0; i < podn_vdd_dep->count; i++)
4557 size += sprintf(buf + size, "%d: %10uMhz %10umV\n",
4558 i, podn_vdd_dep->entries[i].clk/100,
4559 podn_vdd_dep->entries[i].vddc);
4560 }
4561 break;
4562 case OD_RANGE:
4563 if (hwmgr->od_enabled) {
4564 size = sprintf(buf, "%s:\n", "OD_RANGE");
4565 size += sprintf(buf + size, "SCLK: %7uMHz %10uMHz\n",
4566 data->golden_dpm_table.gfx_table.dpm_levels[0].value/100,
4567 hwmgr->platform_descriptor.overdriveLimit.engineClock/100);
4568 size += sprintf(buf + size, "MCLK: %7uMHz %10uMHz\n",
4569 data->golden_dpm_table.mem_table.dpm_levels[0].value/100,
4570 hwmgr->platform_descriptor.overdriveLimit.memoryClock/100);
4571 size += sprintf(buf + size, "VDDC: %7umV %11umV\n",
4572 data->odn_dpm_table.min_vddc,
4573 data->odn_dpm_table.max_vddc);
4574 }
4575 break;
4576 default:
4577 break;
4578 }
4579 return size;
4580 }
4581
4582 static int vega10_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
4583 {
4584 struct vega10_hwmgr *data = hwmgr->backend;
4585 Watermarks_t *wm_table = &(data->smc_state_table.water_marks_table);
4586 int result = 0;
4587
4588 if ((data->water_marks_bitmap & WaterMarksExist) &&
4589 !(data->water_marks_bitmap & WaterMarksLoaded)) {
4590 result = smum_smc_table_manager(hwmgr, (uint8_t *)wm_table, WMTABLE, false);
4591 PP_ASSERT_WITH_CODE(result, "Failed to update WMTABLE!", return EINVAL);
4592 data->water_marks_bitmap |= WaterMarksLoaded;
4593 }
4594
4595 if (data->water_marks_bitmap & WaterMarksLoaded) {
4596 smum_send_msg_to_smc_with_parameter(hwmgr,
4597 PPSMC_MSG_NumOfDisplays, hwmgr->display_config->num_display);
4598 }
4599
4600 return result;
4601 }
4602
4603 int vega10_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
4604 {
4605 struct vega10_hwmgr *data = hwmgr->backend;
4606
4607 if (data->smu_features[GNLD_DPM_UVD].supported) {
4608 PP_ASSERT_WITH_CODE(!vega10_enable_smc_features(hwmgr,
4609 enable,
4610 data->smu_features[GNLD_DPM_UVD].smu_feature_bitmap),
4611 "Attempt to Enable/Disable DPM UVD Failed!",
4612 return -1);
4613 data->smu_features[GNLD_DPM_UVD].enabled = enable;
4614 }
4615 return 0;
4616 }
4617
4618 static void vega10_power_gate_vce(struct pp_hwmgr *hwmgr, bool bgate)
4619 {
4620 struct vega10_hwmgr *data = hwmgr->backend;
4621
4622 data->vce_power_gated = bgate;
4623 vega10_enable_disable_vce_dpm(hwmgr, !bgate);
4624 }
4625
4626 static void vega10_power_gate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
4627 {
4628 struct vega10_hwmgr *data = hwmgr->backend;
4629
4630 data->uvd_power_gated = bgate;
4631 vega10_enable_disable_uvd_dpm(hwmgr, !bgate);
4632 }
4633
4634 static inline bool vega10_are_power_levels_equal(
4635 const struct vega10_performance_level *pl1,
4636 const struct vega10_performance_level *pl2)
4637 {
4638 return ((pl1->soc_clock == pl2->soc_clock) &&
4639 (pl1->gfx_clock == pl2->gfx_clock) &&
4640 (pl1->mem_clock == pl2->mem_clock));
4641 }
4642
4643 static int vega10_check_states_equal(struct pp_hwmgr *hwmgr,
4644 const struct pp_hw_power_state *pstate1,
4645 const struct pp_hw_power_state *pstate2, bool *equal)
4646 {
4647 const struct vega10_power_state *psa;
4648 const struct vega10_power_state *psb;
4649 int i;
4650
4651 if (pstate1 == NULL || pstate2 == NULL || equal == NULL)
4652 return -EINVAL;
4653
4654 psa = cast_const_phw_vega10_power_state(pstate1);
4655 psb = cast_const_phw_vega10_power_state(pstate2);
4656
4657 if (psa->performance_level_count != psb->performance_level_count) {
4658 *equal = false;
4659 return 0;
4660 }
4661
4662 for (i = 0; i < psa->performance_level_count; i++) {
4663 if (!vega10_are_power_levels_equal(&(psa->performance_levels[i]), &(psb->performance_levels[i]))) {
4664
4665 *equal = false;
4666 return 0;
4667 }
4668 }
4669
4670
4671 *equal = ((psa->uvd_clks.vclk == psb->uvd_clks.vclk) && (psa->uvd_clks.dclk == psb->uvd_clks.dclk));
4672 *equal &= ((psa->vce_clks.evclk == psb->vce_clks.evclk) && (psa->vce_clks.ecclk == psb->vce_clks.ecclk));
4673 *equal &= (psa->sclk_threshold == psb->sclk_threshold);
4674
4675 return 0;
4676 }
4677
4678 static bool
4679 vega10_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr)
4680 {
4681 struct vega10_hwmgr *data = hwmgr->backend;
4682 bool is_update_required = false;
4683
4684 if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display)
4685 is_update_required = true;
4686
4687 if (PP_CAP(PHM_PlatformCaps_SclkDeepSleep)) {
4688 if (data->display_timing.min_clock_in_sr != hwmgr->display_config->min_core_set_clock_in_sr)
4689 is_update_required = true;
4690 }
4691
4692 return is_update_required;
4693 }
4694
4695 static int vega10_disable_dpm_tasks(struct pp_hwmgr *hwmgr)
4696 {
4697 int tmp_result, result = 0;
4698
4699 if (PP_CAP(PHM_PlatformCaps_ThermalController))
4700 vega10_disable_thermal_protection(hwmgr);
4701
4702 tmp_result = vega10_disable_power_containment(hwmgr);
4703 PP_ASSERT_WITH_CODE((tmp_result == 0),
4704 "Failed to disable power containment!", result = tmp_result);
4705
4706 tmp_result = vega10_disable_didt_config(hwmgr);
4707 PP_ASSERT_WITH_CODE((tmp_result == 0),
4708 "Failed to disable didt config!", result = tmp_result);
4709
4710 tmp_result = vega10_avfs_enable(hwmgr, false);
4711 PP_ASSERT_WITH_CODE((tmp_result == 0),
4712 "Failed to disable AVFS!", result = tmp_result);
4713
4714 tmp_result = vega10_stop_dpm(hwmgr, SMC_DPM_FEATURES);
4715 PP_ASSERT_WITH_CODE((tmp_result == 0),
4716 "Failed to stop DPM!", result = tmp_result);
4717
4718 tmp_result = vega10_disable_deep_sleep_master_switch(hwmgr);
4719 PP_ASSERT_WITH_CODE((tmp_result == 0),
4720 "Failed to disable deep sleep!", result = tmp_result);
4721
4722 tmp_result = vega10_disable_ulv(hwmgr);
4723 PP_ASSERT_WITH_CODE((tmp_result == 0),
4724 "Failed to disable ulv!", result = tmp_result);
4725
4726 tmp_result = vega10_acg_disable(hwmgr);
4727 PP_ASSERT_WITH_CODE((tmp_result == 0),
4728 "Failed to disable acg!", result = tmp_result);
4729
4730 vega10_enable_disable_PCC_limit_feature(hwmgr, false);
4731 return result;
4732 }
4733
4734 static int vega10_power_off_asic(struct pp_hwmgr *hwmgr)
4735 {
4736 struct vega10_hwmgr *data = hwmgr->backend;
4737 int result;
4738
4739 result = vega10_disable_dpm_tasks(hwmgr);
4740 PP_ASSERT_WITH_CODE((0 == result),
4741 "[disable_dpm_tasks] Failed to disable DPM!",
4742 );
4743 data->water_marks_bitmap &= ~(WaterMarksLoaded);
4744
4745 return result;
4746 }
4747
4748 static int vega10_get_sclk_od(struct pp_hwmgr *hwmgr)
4749 {
4750 struct vega10_hwmgr *data = hwmgr->backend;
4751 struct vega10_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
4752 struct vega10_single_dpm_table *golden_sclk_table =
4753 &(data->golden_dpm_table.gfx_table);
4754 int value = sclk_table->dpm_levels[sclk_table->count - 1].value;
4755 int golden_value = golden_sclk_table->dpm_levels
4756 [golden_sclk_table->count - 1].value;
4757
4758 value -= golden_value;
4759 value = DIV_ROUND_UP(value * 100, golden_value);
4760
4761 return value;
4762 }
4763
4764 static int vega10_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
4765 {
4766 struct vega10_hwmgr *data = hwmgr->backend;
4767 struct vega10_single_dpm_table *golden_sclk_table =
4768 &(data->golden_dpm_table.gfx_table);
4769 struct pp_power_state *ps;
4770 struct vega10_power_state *vega10_ps;
4771
4772 ps = hwmgr->request_ps;
4773
4774 if (ps == NULL)
4775 return -EINVAL;
4776
4777 vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
4778
4779 vega10_ps->performance_levels
4780 [vega10_ps->performance_level_count - 1].gfx_clock =
4781 golden_sclk_table->dpm_levels
4782 [golden_sclk_table->count - 1].value *
4783 value / 100 +
4784 golden_sclk_table->dpm_levels
4785 [golden_sclk_table->count - 1].value;
4786
4787 if (vega10_ps->performance_levels
4788 [vega10_ps->performance_level_count - 1].gfx_clock >
4789 hwmgr->platform_descriptor.overdriveLimit.engineClock) {
4790 vega10_ps->performance_levels
4791 [vega10_ps->performance_level_count - 1].gfx_clock =
4792 hwmgr->platform_descriptor.overdriveLimit.engineClock;
4793 pr_warn("max sclk supported by vbios is %d\n",
4794 hwmgr->platform_descriptor.overdriveLimit.engineClock);
4795 }
4796 return 0;
4797 }
4798
4799 static int vega10_get_mclk_od(struct pp_hwmgr *hwmgr)
4800 {
4801 struct vega10_hwmgr *data = hwmgr->backend;
4802 struct vega10_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
4803 struct vega10_single_dpm_table *golden_mclk_table =
4804 &(data->golden_dpm_table.mem_table);
4805 int value = mclk_table->dpm_levels[mclk_table->count - 1].value;
4806 int golden_value = golden_mclk_table->dpm_levels
4807 [golden_mclk_table->count - 1].value;
4808
4809 value -= golden_value;
4810 value = DIV_ROUND_UP(value * 100, golden_value);
4811
4812 return value;
4813 }
4814
4815 static int vega10_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
4816 {
4817 struct vega10_hwmgr *data = hwmgr->backend;
4818 struct vega10_single_dpm_table *golden_mclk_table =
4819 &(data->golden_dpm_table.mem_table);
4820 struct pp_power_state *ps;
4821 struct vega10_power_state *vega10_ps;
4822
4823 ps = hwmgr->request_ps;
4824
4825 if (ps == NULL)
4826 return -EINVAL;
4827
4828 vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
4829
4830 vega10_ps->performance_levels
4831 [vega10_ps->performance_level_count - 1].mem_clock =
4832 golden_mclk_table->dpm_levels
4833 [golden_mclk_table->count - 1].value *
4834 value / 100 +
4835 golden_mclk_table->dpm_levels
4836 [golden_mclk_table->count - 1].value;
4837
4838 if (vega10_ps->performance_levels
4839 [vega10_ps->performance_level_count - 1].mem_clock >
4840 hwmgr->platform_descriptor.overdriveLimit.memoryClock) {
4841 vega10_ps->performance_levels
4842 [vega10_ps->performance_level_count - 1].mem_clock =
4843 hwmgr->platform_descriptor.overdriveLimit.memoryClock;
4844 pr_warn("max mclk supported by vbios is %d\n",
4845 hwmgr->platform_descriptor.overdriveLimit.memoryClock);
4846 }
4847
4848 return 0;
4849 }
4850
4851 static int vega10_notify_cac_buffer_info(struct pp_hwmgr *hwmgr,
4852 uint32_t virtual_addr_low,
4853 uint32_t virtual_addr_hi,
4854 uint32_t mc_addr_low,
4855 uint32_t mc_addr_hi,
4856 uint32_t size)
4857 {
4858 smum_send_msg_to_smc_with_parameter(hwmgr,
4859 PPSMC_MSG_SetSystemVirtualDramAddrHigh,
4860 virtual_addr_hi);
4861 smum_send_msg_to_smc_with_parameter(hwmgr,
4862 PPSMC_MSG_SetSystemVirtualDramAddrLow,
4863 virtual_addr_low);
4864 smum_send_msg_to_smc_with_parameter(hwmgr,
4865 PPSMC_MSG_DramLogSetDramAddrHigh,
4866 mc_addr_hi);
4867
4868 smum_send_msg_to_smc_with_parameter(hwmgr,
4869 PPSMC_MSG_DramLogSetDramAddrLow,
4870 mc_addr_low);
4871
4872 smum_send_msg_to_smc_with_parameter(hwmgr,
4873 PPSMC_MSG_DramLogSetDramSize,
4874 size);
4875 return 0;
4876 }
4877
4878 static int vega10_get_thermal_temperature_range(struct pp_hwmgr *hwmgr,
4879 struct PP_TemperatureRange *thermal_data)
4880 {
4881 struct vega10_hwmgr *data = hwmgr->backend;
4882 PPTable_t *pp_table = &(data->smc_state_table.pp_table);
4883
4884 memcpy(thermal_data, &SMU7ThermalWithDelayPolicy[0], sizeof(struct PP_TemperatureRange));
4885
4886 thermal_data->max = pp_table->TedgeLimit *
4887 PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
4888 thermal_data->edge_emergency_max = (pp_table->TedgeLimit + CTF_OFFSET_EDGE) *
4889 PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
4890 thermal_data->hotspot_crit_max = pp_table->ThotspotLimit *
4891 PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
4892 thermal_data->hotspot_emergency_max = (pp_table->ThotspotLimit + CTF_OFFSET_HOTSPOT) *
4893 PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
4894 thermal_data->mem_crit_max = pp_table->ThbmLimit *
4895 PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
4896 thermal_data->mem_emergency_max = (pp_table->ThbmLimit + CTF_OFFSET_HBM)*
4897 PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
4898
4899 return 0;
4900 }
4901
4902 static int vega10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf)
4903 {
4904 struct vega10_hwmgr *data = hwmgr->backend;
4905 uint32_t i, size = 0;
4906 static const uint8_t profile_mode_setting[6][4] = {{70, 60, 0, 0,},
4907 {70, 60, 1, 3,},
4908 {90, 60, 0, 0,},
4909 {70, 60, 0, 0,},
4910 {70, 90, 0, 0,},
4911 {30, 60, 0, 6,},
4912 };
4913 static const char *profile_name[7] = {"BOOTUP_DEFAULT",
4914 "3D_FULL_SCREEN",
4915 "POWER_SAVING",
4916 "VIDEO",
4917 "VR",
4918 "COMPUTE",
4919 "CUSTOM"};
4920 static const char *title[6] = {"NUM",
4921 "MODE_NAME",
4922 "BUSY_SET_POINT",
4923 "FPS",
4924 "USE_RLC_BUSY",
4925 "MIN_ACTIVE_LEVEL"};
4926
4927 if (!buf)
4928 return -EINVAL;
4929
4930 size += sprintf(buf + size, "%s %16s %s %s %s %s\n",title[0],
4931 title[1], title[2], title[3], title[4], title[5]);
4932
4933 for (i = 0; i < PP_SMC_POWER_PROFILE_CUSTOM; i++)
4934 size += sprintf(buf + size, "%3d %14s%s: %14d %3d %10d %14d\n",
4935 i, profile_name[i], (i == hwmgr->power_profile_mode) ? "*" : " ",
4936 profile_mode_setting[i][0], profile_mode_setting[i][1],
4937 profile_mode_setting[i][2], profile_mode_setting[i][3]);
4938 size += sprintf(buf + size, "%3d %14s%s: %14d %3d %10d %14d\n", i,
4939 profile_name[i], (i == hwmgr->power_profile_mode) ? "*" : " ",
4940 data->custom_profile_mode[0], data->custom_profile_mode[1],
4941 data->custom_profile_mode[2], data->custom_profile_mode[3]);
4942 return size;
4943 }
4944
4945 static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, uint32_t size)
4946 {
4947 struct vega10_hwmgr *data = hwmgr->backend;
4948 uint8_t busy_set_point;
4949 uint8_t FPS;
4950 uint8_t use_rlc_busy;
4951 uint8_t min_active_level;
4952 uint32_t power_profile_mode = input[size];
4953
4954 if (power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
4955 if (size != 0 && size != 4)
4956 return -EINVAL;
4957
4958
4959
4960
4961
4962 if (size == 0) {
4963 if (data->custom_profile_mode[0] != 0)
4964 goto out;
4965 else
4966 return -EINVAL;
4967 }
4968
4969 data->custom_profile_mode[0] = busy_set_point = input[0];
4970 data->custom_profile_mode[1] = FPS = input[1];
4971 data->custom_profile_mode[2] = use_rlc_busy = input[2];
4972 data->custom_profile_mode[3] = min_active_level = input[3];
4973 smum_send_msg_to_smc_with_parameter(hwmgr,
4974 PPSMC_MSG_SetCustomGfxDpmParameters,
4975 busy_set_point | FPS<<8 |
4976 use_rlc_busy << 16 | min_active_level<<24);
4977 }
4978
4979 out:
4980 smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask,
4981 1 << power_profile_mode);
4982 hwmgr->power_profile_mode = power_profile_mode;
4983
4984 return 0;
4985 }
4986
4987
4988 static bool vega10_check_clk_voltage_valid(struct pp_hwmgr *hwmgr,
4989 enum PP_OD_DPM_TABLE_COMMAND type,
4990 uint32_t clk,
4991 uint32_t voltage)
4992 {
4993 struct vega10_hwmgr *data = hwmgr->backend;
4994 struct vega10_odn_dpm_table *odn_table = &(data->odn_dpm_table);
4995 struct vega10_single_dpm_table *golden_table;
4996
4997 if (voltage < odn_table->min_vddc || voltage > odn_table->max_vddc) {
4998 pr_info("OD voltage is out of range [%d - %d] mV\n", odn_table->min_vddc, odn_table->max_vddc);
4999 return false;
5000 }
5001
5002 if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) {
5003 golden_table = &(data->golden_dpm_table.gfx_table);
5004 if (golden_table->dpm_levels[0].value > clk ||
5005 hwmgr->platform_descriptor.overdriveLimit.engineClock < clk) {
5006 pr_info("OD engine clock is out of range [%d - %d] MHz\n",
5007 golden_table->dpm_levels[0].value/100,
5008 hwmgr->platform_descriptor.overdriveLimit.engineClock/100);
5009 return false;
5010 }
5011 } else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) {
5012 golden_table = &(data->golden_dpm_table.mem_table);
5013 if (golden_table->dpm_levels[0].value > clk ||
5014 hwmgr->platform_descriptor.overdriveLimit.memoryClock < clk) {
5015 pr_info("OD memory clock is out of range [%d - %d] MHz\n",
5016 golden_table->dpm_levels[0].value/100,
5017 hwmgr->platform_descriptor.overdriveLimit.memoryClock/100);
5018 return false;
5019 }
5020 } else {
5021 return false;
5022 }
5023
5024 return true;
5025 }
5026
5027 static void vega10_odn_update_power_state(struct pp_hwmgr *hwmgr)
5028 {
5029 struct vega10_hwmgr *data = hwmgr->backend;
5030 struct pp_power_state *ps = hwmgr->request_ps;
5031 struct vega10_power_state *vega10_ps;
5032 struct vega10_single_dpm_table *gfx_dpm_table =
5033 &data->dpm_table.gfx_table;
5034 struct vega10_single_dpm_table *soc_dpm_table =
5035 &data->dpm_table.soc_table;
5036 struct vega10_single_dpm_table *mem_dpm_table =
5037 &data->dpm_table.mem_table;
5038 int max_level;
5039
5040 if (!ps)
5041 return;
5042
5043 vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
5044 max_level = vega10_ps->performance_level_count - 1;
5045
5046 if (vega10_ps->performance_levels[max_level].gfx_clock !=
5047 gfx_dpm_table->dpm_levels[gfx_dpm_table->count - 1].value)
5048 vega10_ps->performance_levels[max_level].gfx_clock =
5049 gfx_dpm_table->dpm_levels[gfx_dpm_table->count - 1].value;
5050
5051 if (vega10_ps->performance_levels[max_level].soc_clock !=
5052 soc_dpm_table->dpm_levels[soc_dpm_table->count - 1].value)
5053 vega10_ps->performance_levels[max_level].soc_clock =
5054 soc_dpm_table->dpm_levels[soc_dpm_table->count - 1].value;
5055
5056 if (vega10_ps->performance_levels[max_level].mem_clock !=
5057 mem_dpm_table->dpm_levels[mem_dpm_table->count - 1].value)
5058 vega10_ps->performance_levels[max_level].mem_clock =
5059 mem_dpm_table->dpm_levels[mem_dpm_table->count - 1].value;
5060
5061 if (!hwmgr->ps)
5062 return;
5063
5064 ps = (struct pp_power_state *)((unsigned long)(hwmgr->ps) + hwmgr->ps_size * (hwmgr->num_ps - 1));
5065 vega10_ps = cast_phw_vega10_power_state(&ps->hardware);
5066 max_level = vega10_ps->performance_level_count - 1;
5067
5068 if (vega10_ps->performance_levels[max_level].gfx_clock !=
5069 gfx_dpm_table->dpm_levels[gfx_dpm_table->count - 1].value)
5070 vega10_ps->performance_levels[max_level].gfx_clock =
5071 gfx_dpm_table->dpm_levels[gfx_dpm_table->count - 1].value;
5072
5073 if (vega10_ps->performance_levels[max_level].soc_clock !=
5074 soc_dpm_table->dpm_levels[soc_dpm_table->count - 1].value)
5075 vega10_ps->performance_levels[max_level].soc_clock =
5076 soc_dpm_table->dpm_levels[soc_dpm_table->count - 1].value;
5077
5078 if (vega10_ps->performance_levels[max_level].mem_clock !=
5079 mem_dpm_table->dpm_levels[mem_dpm_table->count - 1].value)
5080 vega10_ps->performance_levels[max_level].mem_clock =
5081 mem_dpm_table->dpm_levels[mem_dpm_table->count - 1].value;
5082 }
5083
5084 static void vega10_odn_update_soc_table(struct pp_hwmgr *hwmgr,
5085 enum PP_OD_DPM_TABLE_COMMAND type)
5086 {
5087 struct vega10_hwmgr *data = hwmgr->backend;
5088 struct phm_ppt_v2_information *table_info = hwmgr->pptable;
5089 struct phm_ppt_v1_clock_voltage_dependency_table *dep_table = table_info->vdd_dep_on_socclk;
5090 struct vega10_single_dpm_table *dpm_table = &data->golden_dpm_table.mem_table;
5091
5092 struct vega10_odn_clock_voltage_dependency_table *podn_vdd_dep_on_socclk =
5093 &data->odn_dpm_table.vdd_dep_on_socclk;
5094 struct vega10_odn_vddc_lookup_table *od_vddc_lookup_table = &data->odn_dpm_table.vddc_lookup_table;
5095
5096 struct vega10_odn_clock_voltage_dependency_table *podn_vdd_dep;
5097 uint8_t i, j;
5098
5099 if (type == PP_OD_EDIT_SCLK_VDDC_TABLE) {
5100 podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_sclk;
5101 for (i = 0; i < podn_vdd_dep->count; i++)
5102 od_vddc_lookup_table->entries[i].us_vdd = podn_vdd_dep->entries[i].vddc;
5103 } else if (type == PP_OD_EDIT_MCLK_VDDC_TABLE) {
5104 podn_vdd_dep = &data->odn_dpm_table.vdd_dep_on_mclk;
5105 for (i = 0; i < dpm_table->count; i++) {
5106 for (j = 0; j < od_vddc_lookup_table->count; j++) {
5107 if (od_vddc_lookup_table->entries[j].us_vdd >
5108 podn_vdd_dep->entries[i].vddc)
5109 break;
5110 }
5111 if (j == od_vddc_lookup_table->count) {
5112 j = od_vddc_lookup_table->count - 1;
5113 od_vddc_lookup_table->entries[j].us_vdd =
5114 podn_vdd_dep->entries[i].vddc;
5115 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_VDDC;
5116 }
5117 podn_vdd_dep->entries[i].vddInd = j;
5118 }
5119 dpm_table = &data->dpm_table.soc_table;
5120 for (i = 0; i < dep_table->count; i++) {
5121 if (dep_table->entries[i].vddInd == podn_vdd_dep->entries[podn_vdd_dep->count-1].vddInd &&
5122 dep_table->entries[i].clk < podn_vdd_dep->entries[podn_vdd_dep->count-1].clk) {
5123 data->need_update_dpm_table |= DPMTABLE_UPDATE_SOCCLK;
5124 for (; (i < dep_table->count) &&
5125 (dep_table->entries[i].clk < podn_vdd_dep->entries[podn_vdd_dep->count - 1].clk); i++) {
5126 podn_vdd_dep_on_socclk->entries[i].clk = podn_vdd_dep->entries[podn_vdd_dep->count-1].clk;
5127 dpm_table->dpm_levels[i].value = podn_vdd_dep_on_socclk->entries[i].clk;
5128 }
5129 break;
5130 } else {
5131 dpm_table->dpm_levels[i].value = dep_table->entries[i].clk;
5132 podn_vdd_dep_on_socclk->entries[i].vddc = dep_table->entries[i].vddc;
5133 podn_vdd_dep_on_socclk->entries[i].vddInd = dep_table->entries[i].vddInd;
5134 podn_vdd_dep_on_socclk->entries[i].clk = dep_table->entries[i].clk;
5135 }
5136 }
5137 if (podn_vdd_dep_on_socclk->entries[podn_vdd_dep_on_socclk->count - 1].clk <
5138 podn_vdd_dep->entries[podn_vdd_dep->count - 1].clk) {
5139 data->need_update_dpm_table |= DPMTABLE_UPDATE_SOCCLK;
5140 podn_vdd_dep_on_socclk->entries[podn_vdd_dep_on_socclk->count - 1].clk =
5141 podn_vdd_dep->entries[podn_vdd_dep->count - 1].clk;
5142 dpm_table->dpm_levels[podn_vdd_dep_on_socclk->count - 1].value =
5143 podn_vdd_dep->entries[podn_vdd_dep->count - 1].clk;
5144 }
5145 if (podn_vdd_dep_on_socclk->entries[podn_vdd_dep_on_socclk->count - 1].vddInd <
5146 podn_vdd_dep->entries[podn_vdd_dep->count - 1].vddInd) {
5147 data->need_update_dpm_table |= DPMTABLE_UPDATE_SOCCLK;
5148 podn_vdd_dep_on_socclk->entries[podn_vdd_dep_on_socclk->count - 1].vddInd =
5149 podn_vdd_dep->entries[podn_vdd_dep->count - 1].vddInd;
5150 }
5151 }
5152 vega10_odn_update_power_state(hwmgr);
5153 }
5154
5155 static int vega10_odn_edit_dpm_table(struct pp_hwmgr *hwmgr,
5156 enum PP_OD_DPM_TABLE_COMMAND type,
5157 long *input, uint32_t size)
5158 {
5159 struct vega10_hwmgr *data = hwmgr->backend;
5160 struct vega10_odn_clock_voltage_dependency_table *podn_vdd_dep_table;
5161 struct vega10_single_dpm_table *dpm_table;
5162
5163 uint32_t input_clk;
5164 uint32_t input_vol;
5165 uint32_t input_level;
5166 uint32_t i;
5167
5168 PP_ASSERT_WITH_CODE(input, "NULL user input for clock and voltage",
5169 return -EINVAL);
5170
5171 if (!hwmgr->od_enabled) {
5172 pr_info("OverDrive feature not enabled\n");
5173 return -EINVAL;
5174 }
5175
5176 if (PP_OD_EDIT_SCLK_VDDC_TABLE == type) {
5177 dpm_table = &data->dpm_table.gfx_table;
5178 podn_vdd_dep_table = &data->odn_dpm_table.vdd_dep_on_sclk;
5179 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_SCLK;
5180 } else if (PP_OD_EDIT_MCLK_VDDC_TABLE == type) {
5181 dpm_table = &data->dpm_table.mem_table;
5182 podn_vdd_dep_table = &data->odn_dpm_table.vdd_dep_on_mclk;
5183 data->need_update_dpm_table |= DPMTABLE_OD_UPDATE_MCLK;
5184 } else if (PP_OD_RESTORE_DEFAULT_TABLE == type) {
5185 memcpy(&(data->dpm_table), &(data->golden_dpm_table), sizeof(struct vega10_dpm_table));
5186 vega10_odn_initial_default_setting(hwmgr);
5187 vega10_odn_update_power_state(hwmgr);
5188
5189 data->need_update_dpm_table = DPMTABLE_UPDATE_SCLK |
5190 DPMTABLE_UPDATE_MCLK |
5191 DPMTABLE_UPDATE_SOCCLK;
5192 return 0;
5193 } else if (PP_OD_COMMIT_DPM_TABLE == type) {
5194 vega10_check_dpm_table_updated(hwmgr);
5195 return 0;
5196 } else {
5197 return -EINVAL;
5198 }
5199
5200 for (i = 0; i < size; i += 3) {
5201 if (i + 3 > size || input[i] >= podn_vdd_dep_table->count) {
5202 pr_info("invalid clock voltage input\n");
5203 return 0;
5204 }
5205 input_level = input[i];
5206 input_clk = input[i+1] * 100;
5207 input_vol = input[i+2];
5208
5209 if (vega10_check_clk_voltage_valid(hwmgr, type, input_clk, input_vol)) {
5210 dpm_table->dpm_levels[input_level].value = input_clk;
5211 podn_vdd_dep_table->entries[input_level].clk = input_clk;
5212 podn_vdd_dep_table->entries[input_level].vddc = input_vol;
5213 } else {
5214 return -EINVAL;
5215 }
5216 }
5217 vega10_odn_update_soc_table(hwmgr, type);
5218 return 0;
5219 }
5220
5221 static int vega10_set_mp1_state(struct pp_hwmgr *hwmgr,
5222 enum pp_mp1_state mp1_state)
5223 {
5224 uint16_t msg;
5225 int ret;
5226
5227 switch (mp1_state) {
5228 case PP_MP1_STATE_UNLOAD:
5229 msg = PPSMC_MSG_PrepareMp1ForUnload;
5230 break;
5231 case PP_MP1_STATE_SHUTDOWN:
5232 case PP_MP1_STATE_RESET:
5233 case PP_MP1_STATE_NONE:
5234 default:
5235 return 0;
5236 }
5237
5238 PP_ASSERT_WITH_CODE((ret = smum_send_msg_to_smc(hwmgr, msg)) == 0,
5239 "[PrepareMp1] Failed!",
5240 return ret);
5241
5242 return 0;
5243 }
5244
5245 static int vega10_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state,
5246 PHM_PerformanceLevelDesignation designation, uint32_t index,
5247 PHM_PerformanceLevel *level)
5248 {
5249 const struct vega10_power_state *ps;
5250 struct vega10_hwmgr *data;
5251 uint32_t i;
5252
5253 if (level == NULL || hwmgr == NULL || state == NULL)
5254 return -EINVAL;
5255
5256 data = hwmgr->backend;
5257 ps = cast_const_phw_vega10_power_state(state);
5258
5259 i = index > ps->performance_level_count - 1 ?
5260 ps->performance_level_count - 1 : index;
5261
5262 level->coreClock = ps->performance_levels[i].gfx_clock;
5263 level->memory_clock = ps->performance_levels[i].mem_clock;
5264
5265 return 0;
5266 }
5267
5268 static const struct pp_hwmgr_func vega10_hwmgr_funcs = {
5269 .backend_init = vega10_hwmgr_backend_init,
5270 .backend_fini = vega10_hwmgr_backend_fini,
5271 .asic_setup = vega10_setup_asic_task,
5272 .dynamic_state_management_enable = vega10_enable_dpm_tasks,
5273 .dynamic_state_management_disable = vega10_disable_dpm_tasks,
5274 .get_num_of_pp_table_entries =
5275 vega10_get_number_of_powerplay_table_entries,
5276 .get_power_state_size = vega10_get_power_state_size,
5277 .get_pp_table_entry = vega10_get_pp_table_entry,
5278 .patch_boot_state = vega10_patch_boot_state,
5279 .apply_state_adjust_rules = vega10_apply_state_adjust_rules,
5280 .power_state_set = vega10_set_power_state_tasks,
5281 .get_sclk = vega10_dpm_get_sclk,
5282 .get_mclk = vega10_dpm_get_mclk,
5283 .notify_smc_display_config_after_ps_adjustment =
5284 vega10_notify_smc_display_config_after_ps_adjustment,
5285 .force_dpm_level = vega10_dpm_force_dpm_level,
5286 .stop_thermal_controller = vega10_thermal_stop_thermal_controller,
5287 .get_fan_speed_info = vega10_fan_ctrl_get_fan_speed_info,
5288 .get_fan_speed_percent = vega10_fan_ctrl_get_fan_speed_percent,
5289 .set_fan_speed_percent = vega10_fan_ctrl_set_fan_speed_percent,
5290 .reset_fan_speed_to_default =
5291 vega10_fan_ctrl_reset_fan_speed_to_default,
5292 .get_fan_speed_rpm = vega10_fan_ctrl_get_fan_speed_rpm,
5293 .set_fan_speed_rpm = vega10_fan_ctrl_set_fan_speed_rpm,
5294 .uninitialize_thermal_controller =
5295 vega10_thermal_ctrl_uninitialize_thermal_controller,
5296 .set_fan_control_mode = vega10_set_fan_control_mode,
5297 .get_fan_control_mode = vega10_get_fan_control_mode,
5298 .read_sensor = vega10_read_sensor,
5299 .get_dal_power_level = vega10_get_dal_power_level,
5300 .get_clock_by_type_with_latency = vega10_get_clock_by_type_with_latency,
5301 .get_clock_by_type_with_voltage = vega10_get_clock_by_type_with_voltage,
5302 .set_watermarks_for_clocks_ranges = vega10_set_watermarks_for_clocks_ranges,
5303 .display_clock_voltage_request = vega10_display_clock_voltage_request,
5304 .force_clock_level = vega10_force_clock_level,
5305 .print_clock_levels = vega10_print_clock_levels,
5306 .display_config_changed = vega10_display_configuration_changed_task,
5307 .powergate_uvd = vega10_power_gate_uvd,
5308 .powergate_vce = vega10_power_gate_vce,
5309 .check_states_equal = vega10_check_states_equal,
5310 .check_smc_update_required_for_display_configuration =
5311 vega10_check_smc_update_required_for_display_configuration,
5312 .power_off_asic = vega10_power_off_asic,
5313 .disable_smc_firmware_ctf = vega10_thermal_disable_alert,
5314 .get_sclk_od = vega10_get_sclk_od,
5315 .set_sclk_od = vega10_set_sclk_od,
5316 .get_mclk_od = vega10_get_mclk_od,
5317 .set_mclk_od = vega10_set_mclk_od,
5318 .avfs_control = vega10_avfs_enable,
5319 .notify_cac_buffer_info = vega10_notify_cac_buffer_info,
5320 .get_thermal_temperature_range = vega10_get_thermal_temperature_range,
5321 .register_irq_handlers = smu9_register_irq_handlers,
5322 .start_thermal_controller = vega10_start_thermal_controller,
5323 .get_power_profile_mode = vega10_get_power_profile_mode,
5324 .set_power_profile_mode = vega10_set_power_profile_mode,
5325 .set_power_limit = vega10_set_power_limit,
5326 .odn_edit_dpm_table = vega10_odn_edit_dpm_table,
5327 .get_performance_level = vega10_get_performance_level,
5328 .get_asic_baco_capability = smu9_baco_get_capability,
5329 .get_asic_baco_state = smu9_baco_get_state,
5330 .set_asic_baco_state = vega10_baco_set_state,
5331 .enable_mgpu_fan_boost = vega10_enable_mgpu_fan_boost,
5332 .get_ppfeature_status = vega10_get_ppfeature_status,
5333 .set_ppfeature_status = vega10_set_ppfeature_status,
5334 .set_mp1_state = vega10_set_mp1_state,
5335 };
5336
5337 int vega10_hwmgr_init(struct pp_hwmgr *hwmgr)
5338 {
5339 struct amdgpu_device *adev = hwmgr->adev;
5340
5341 hwmgr->hwmgr_func = &vega10_hwmgr_funcs;
5342 hwmgr->pptable_func = &vega10_pptable_funcs;
5343 if (amdgpu_passthrough(adev))
5344 return vega10_baco_set_cap(hwmgr);
5345
5346 return 0;
5347 }