Merge branch 'mlx5-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox...
[sfrench/cifs-2.6.git] / drivers / gpu / drm / amd / powerplay / hwmgr / vega12_hwmgr.c
1 /*
2  * Copyright 2017 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  */
23
24 #include <linux/delay.h>
25 #include <linux/fb.h>
26 #include <linux/module.h>
27 #include <linux/slab.h>
28
29 #include "hwmgr.h"
30 #include "amd_powerplay.h"
31 #include "vega12_smumgr.h"
32 #include "hardwaremanager.h"
33 #include "ppatomfwctrl.h"
34 #include "atomfirmware.h"
35 #include "cgs_common.h"
36 #include "vega12_inc.h"
37 #include "pppcielanes.h"
38 #include "vega12_hwmgr.h"
39 #include "vega12_processpptables.h"
40 #include "vega12_pptable.h"
41 #include "vega12_thermal.h"
42 #include "vega12_ppsmc.h"
43 #include "pp_debug.h"
44 #include "amd_pcie_helpers.h"
45 #include "ppinterrupt.h"
46 #include "pp_overdriver.h"
47 #include "pp_thermal.h"
48
49
50 static int vega12_force_clock_level(struct pp_hwmgr *hwmgr,
51                 enum pp_clock_type type, uint32_t mask);
52 static int vega12_get_clock_ranges(struct pp_hwmgr *hwmgr,
53                 uint32_t *clock,
54                 PPCLK_e clock_select,
55                 bool max);
56
57 static void vega12_set_default_registry_data(struct pp_hwmgr *hwmgr)
58 {
59         struct vega12_hwmgr *data =
60                         (struct vega12_hwmgr *)(hwmgr->backend);
61
62         data->gfxclk_average_alpha = PPVEGA12_VEGA12GFXCLKAVERAGEALPHA_DFLT;
63         data->socclk_average_alpha = PPVEGA12_VEGA12SOCCLKAVERAGEALPHA_DFLT;
64         data->uclk_average_alpha = PPVEGA12_VEGA12UCLKCLKAVERAGEALPHA_DFLT;
65         data->gfx_activity_average_alpha = PPVEGA12_VEGA12GFXACTIVITYAVERAGEALPHA_DFLT;
66         data->lowest_uclk_reserved_for_ulv = PPVEGA12_VEGA12LOWESTUCLKRESERVEDFORULV_DFLT;
67
68         data->display_voltage_mode = PPVEGA12_VEGA12DISPLAYVOLTAGEMODE_DFLT;
69         data->dcef_clk_quad_eqn_a = PPREGKEY_VEGA12QUADRATICEQUATION_DFLT;
70         data->dcef_clk_quad_eqn_b = PPREGKEY_VEGA12QUADRATICEQUATION_DFLT;
71         data->dcef_clk_quad_eqn_c = PPREGKEY_VEGA12QUADRATICEQUATION_DFLT;
72         data->disp_clk_quad_eqn_a = PPREGKEY_VEGA12QUADRATICEQUATION_DFLT;
73         data->disp_clk_quad_eqn_b = PPREGKEY_VEGA12QUADRATICEQUATION_DFLT;
74         data->disp_clk_quad_eqn_c = PPREGKEY_VEGA12QUADRATICEQUATION_DFLT;
75         data->pixel_clk_quad_eqn_a = PPREGKEY_VEGA12QUADRATICEQUATION_DFLT;
76         data->pixel_clk_quad_eqn_b = PPREGKEY_VEGA12QUADRATICEQUATION_DFLT;
77         data->pixel_clk_quad_eqn_c = PPREGKEY_VEGA12QUADRATICEQUATION_DFLT;
78         data->phy_clk_quad_eqn_a = PPREGKEY_VEGA12QUADRATICEQUATION_DFLT;
79         data->phy_clk_quad_eqn_b = PPREGKEY_VEGA12QUADRATICEQUATION_DFLT;
80         data->phy_clk_quad_eqn_c = PPREGKEY_VEGA12QUADRATICEQUATION_DFLT;
81
82         data->registry_data.disallowed_features = 0x0;
83         data->registry_data.od_state_in_dc_support = 0;
84         data->registry_data.thermal_support = 1;
85         data->registry_data.skip_baco_hardware = 0;
86
87         data->registry_data.log_avfs_param = 0;
88         data->registry_data.sclk_throttle_low_notification = 1;
89         data->registry_data.force_dpm_high = 0;
90         data->registry_data.stable_pstate_sclk_dpm_percentage = 75;
91
92         data->registry_data.didt_support = 0;
93         if (data->registry_data.didt_support) {
94                 data->registry_data.didt_mode = 6;
95                 data->registry_data.sq_ramping_support = 1;
96                 data->registry_data.db_ramping_support = 0;
97                 data->registry_data.td_ramping_support = 0;
98                 data->registry_data.tcp_ramping_support = 0;
99                 data->registry_data.dbr_ramping_support = 0;
100                 data->registry_data.edc_didt_support = 1;
101                 data->registry_data.gc_didt_support = 0;
102                 data->registry_data.psm_didt_support = 0;
103         }
104
105         data->registry_data.pcie_lane_override = 0xff;
106         data->registry_data.pcie_speed_override = 0xff;
107         data->registry_data.pcie_clock_override = 0xffffffff;
108         data->registry_data.regulator_hot_gpio_support = 1;
109         data->registry_data.ac_dc_switch_gpio_support = 0;
110         data->registry_data.quick_transition_support = 0;
111         data->registry_data.zrpm_start_temp = 0xffff;
112         data->registry_data.zrpm_stop_temp = 0xffff;
113         data->registry_data.odn_feature_enable = 1;
114         data->registry_data.disable_water_mark = 0;
115         data->registry_data.disable_pp_tuning = 0;
116         data->registry_data.disable_xlpp_tuning = 0;
117         data->registry_data.disable_workload_policy = 0;
118         data->registry_data.perf_ui_tuning_profile_turbo = 0x19190F0F;
119         data->registry_data.perf_ui_tuning_profile_powerSave = 0x19191919;
120         data->registry_data.perf_ui_tuning_profile_xl = 0x00000F0A;
121         data->registry_data.force_workload_policy_mask = 0;
122         data->registry_data.disable_3d_fs_detection = 0;
123         data->registry_data.fps_support = 1;
124         data->registry_data.disable_auto_wattman = 1;
125         data->registry_data.auto_wattman_debug = 0;
126         data->registry_data.auto_wattman_sample_period = 100;
127         data->registry_data.auto_wattman_threshold = 50;
128 }
129
130 static int vega12_set_features_platform_caps(struct pp_hwmgr *hwmgr)
131 {
132         struct vega12_hwmgr *data =
133                         (struct vega12_hwmgr *)(hwmgr->backend);
134         struct amdgpu_device *adev = hwmgr->adev;
135
136         if (data->vddci_control == VEGA12_VOLTAGE_CONTROL_NONE)
137                 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
138                                 PHM_PlatformCaps_ControlVDDCI);
139
140         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
141                         PHM_PlatformCaps_TablelessHardwareInterface);
142
143         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
144                         PHM_PlatformCaps_EnableSMU7ThermalManagement);
145
146         if (adev->pg_flags & AMD_PG_SUPPORT_UVD) {
147                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
148                                 PHM_PlatformCaps_UVDPowerGating);
149                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
150                                 PHM_PlatformCaps_UVDDynamicPowerGating);
151         }
152
153         if (adev->pg_flags & AMD_PG_SUPPORT_VCE)
154                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
155                                 PHM_PlatformCaps_VCEPowerGating);
156
157         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
158                         PHM_PlatformCaps_UnTabledHardwareInterface);
159
160         if (data->registry_data.odn_feature_enable)
161                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
162                                 PHM_PlatformCaps_ODNinACSupport);
163         else {
164                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
165                                 PHM_PlatformCaps_OD6inACSupport);
166                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
167                                 PHM_PlatformCaps_OD6PlusinACSupport);
168         }
169
170         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
171                         PHM_PlatformCaps_ActivityReporting);
172         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
173                         PHM_PlatformCaps_FanSpeedInTableIsRPM);
174
175         if (data->registry_data.od_state_in_dc_support) {
176                 if (data->registry_data.odn_feature_enable)
177                         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
178                                         PHM_PlatformCaps_ODNinDCSupport);
179                 else {
180                         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
181                                         PHM_PlatformCaps_OD6inDCSupport);
182                         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
183                                         PHM_PlatformCaps_OD6PlusinDCSupport);
184                 }
185         }
186
187         if (data->registry_data.thermal_support
188                         && data->registry_data.fuzzy_fan_control_support
189                         && hwmgr->thermal_controller.advanceFanControlParameters.usTMax)
190                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
191                                 PHM_PlatformCaps_ODFuzzyFanControlSupport);
192
193         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
194                                 PHM_PlatformCaps_DynamicPowerManagement);
195         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
196                         PHM_PlatformCaps_SMC);
197         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
198                         PHM_PlatformCaps_ThermalPolicyDelay);
199
200         if (data->registry_data.force_dpm_high)
201                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
202                                 PHM_PlatformCaps_ExclusiveModeAlwaysHigh);
203
204         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
205                         PHM_PlatformCaps_DynamicUVDState);
206
207         if (data->registry_data.sclk_throttle_low_notification)
208                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
209                                 PHM_PlatformCaps_SclkThrottleLowNotification);
210
211         /* power tune caps */
212         /* assume disabled */
213         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
214                         PHM_PlatformCaps_PowerContainment);
215         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
216                         PHM_PlatformCaps_DiDtSupport);
217         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
218                         PHM_PlatformCaps_SQRamping);
219         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
220                         PHM_PlatformCaps_DBRamping);
221         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
222                         PHM_PlatformCaps_TDRamping);
223         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
224                         PHM_PlatformCaps_TCPRamping);
225         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
226                         PHM_PlatformCaps_DBRRamping);
227         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
228                         PHM_PlatformCaps_DiDtEDCEnable);
229         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
230                         PHM_PlatformCaps_GCEDC);
231         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
232                         PHM_PlatformCaps_PSM);
233
234         if (data->registry_data.didt_support) {
235                 phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DiDtSupport);
236                 if (data->registry_data.sq_ramping_support)
237                         phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SQRamping);
238                 if (data->registry_data.db_ramping_support)
239                         phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DBRamping);
240                 if (data->registry_data.td_ramping_support)
241                         phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TDRamping);
242                 if (data->registry_data.tcp_ramping_support)
243                         phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_TCPRamping);
244                 if (data->registry_data.dbr_ramping_support)
245                         phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DBRRamping);
246                 if (data->registry_data.edc_didt_support)
247                         phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_DiDtEDCEnable);
248                 if (data->registry_data.gc_didt_support)
249                         phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_GCEDC);
250                 if (data->registry_data.psm_didt_support)
251                         phm_cap_set(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_PSM);
252         }
253
254         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
255                         PHM_PlatformCaps_RegulatorHot);
256
257         if (data->registry_data.ac_dc_switch_gpio_support) {
258                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
259                                 PHM_PlatformCaps_AutomaticDCTransition);
260                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
261                                 PHM_PlatformCaps_SMCtoPPLIBAcdcGpioScheme);
262         }
263
264         if (data->registry_data.quick_transition_support) {
265                 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
266                                 PHM_PlatformCaps_AutomaticDCTransition);
267                 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
268                                 PHM_PlatformCaps_SMCtoPPLIBAcdcGpioScheme);
269                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
270                                 PHM_PlatformCaps_Falcon_QuickTransition);
271         }
272
273         if (data->lowest_uclk_reserved_for_ulv != PPVEGA12_VEGA12LOWESTUCLKRESERVEDFORULV_DFLT) {
274                 phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
275                                 PHM_PlatformCaps_LowestUclkReservedForUlv);
276                 if (data->lowest_uclk_reserved_for_ulv == 1)
277                         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
278                                         PHM_PlatformCaps_LowestUclkReservedForUlv);
279         }
280
281         if (data->registry_data.custom_fan_support)
282                 phm_cap_set(hwmgr->platform_descriptor.platformCaps,
283                                 PHM_PlatformCaps_CustomFanControlSupport);
284
285         return 0;
286 }
287
288 static void vega12_init_dpm_defaults(struct pp_hwmgr *hwmgr)
289 {
290         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
291         int i;
292
293         data->smu_features[GNLD_DPM_PREFETCHER].smu_feature_id =
294                         FEATURE_DPM_PREFETCHER_BIT;
295         data->smu_features[GNLD_DPM_GFXCLK].smu_feature_id =
296                         FEATURE_DPM_GFXCLK_BIT;
297         data->smu_features[GNLD_DPM_UCLK].smu_feature_id =
298                         FEATURE_DPM_UCLK_BIT;
299         data->smu_features[GNLD_DPM_SOCCLK].smu_feature_id =
300                         FEATURE_DPM_SOCCLK_BIT;
301         data->smu_features[GNLD_DPM_UVD].smu_feature_id =
302                         FEATURE_DPM_UVD_BIT;
303         data->smu_features[GNLD_DPM_VCE].smu_feature_id =
304                         FEATURE_DPM_VCE_BIT;
305         data->smu_features[GNLD_ULV].smu_feature_id =
306                         FEATURE_ULV_BIT;
307         data->smu_features[GNLD_DPM_MP0CLK].smu_feature_id =
308                         FEATURE_DPM_MP0CLK_BIT;
309         data->smu_features[GNLD_DPM_LINK].smu_feature_id =
310                         FEATURE_DPM_LINK_BIT;
311         data->smu_features[GNLD_DPM_DCEFCLK].smu_feature_id =
312                         FEATURE_DPM_DCEFCLK_BIT;
313         data->smu_features[GNLD_DS_GFXCLK].smu_feature_id =
314                         FEATURE_DS_GFXCLK_BIT;
315         data->smu_features[GNLD_DS_SOCCLK].smu_feature_id =
316                         FEATURE_DS_SOCCLK_BIT;
317         data->smu_features[GNLD_DS_LCLK].smu_feature_id =
318                         FEATURE_DS_LCLK_BIT;
319         data->smu_features[GNLD_PPT].smu_feature_id =
320                         FEATURE_PPT_BIT;
321         data->smu_features[GNLD_TDC].smu_feature_id =
322                         FEATURE_TDC_BIT;
323         data->smu_features[GNLD_THERMAL].smu_feature_id =
324                         FEATURE_THERMAL_BIT;
325         data->smu_features[GNLD_GFX_PER_CU_CG].smu_feature_id =
326                         FEATURE_GFX_PER_CU_CG_BIT;
327         data->smu_features[GNLD_RM].smu_feature_id =
328                         FEATURE_RM_BIT;
329         data->smu_features[GNLD_DS_DCEFCLK].smu_feature_id =
330                         FEATURE_DS_DCEFCLK_BIT;
331         data->smu_features[GNLD_ACDC].smu_feature_id =
332                         FEATURE_ACDC_BIT;
333         data->smu_features[GNLD_VR0HOT].smu_feature_id =
334                         FEATURE_VR0HOT_BIT;
335         data->smu_features[GNLD_VR1HOT].smu_feature_id =
336                         FEATURE_VR1HOT_BIT;
337         data->smu_features[GNLD_FW_CTF].smu_feature_id =
338                         FEATURE_FW_CTF_BIT;
339         data->smu_features[GNLD_LED_DISPLAY].smu_feature_id =
340                         FEATURE_LED_DISPLAY_BIT;
341         data->smu_features[GNLD_FAN_CONTROL].smu_feature_id =
342                         FEATURE_FAN_CONTROL_BIT;
343         data->smu_features[GNLD_DIDT].smu_feature_id = FEATURE_GFX_EDC_BIT;
344         data->smu_features[GNLD_GFXOFF].smu_feature_id = FEATURE_GFXOFF_BIT;
345         data->smu_features[GNLD_CG].smu_feature_id = FEATURE_CG_BIT;
346         data->smu_features[GNLD_ACG].smu_feature_id = FEATURE_ACG_BIT;
347
348         for (i = 0; i < GNLD_FEATURES_MAX; i++) {
349                 data->smu_features[i].smu_feature_bitmap =
350                         (uint64_t)(1ULL << data->smu_features[i].smu_feature_id);
351                 data->smu_features[i].allowed =
352                         ((data->registry_data.disallowed_features >> i) & 1) ?
353                         false : true;
354         }
355 }
356
357 static int vega12_set_private_data_based_on_pptable(struct pp_hwmgr *hwmgr)
358 {
359         return 0;
360 }
361
362 static int vega12_hwmgr_backend_fini(struct pp_hwmgr *hwmgr)
363 {
364         kfree(hwmgr->backend);
365         hwmgr->backend = NULL;
366
367         return 0;
368 }
369
370 static int vega12_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
371 {
372         int result = 0;
373         struct vega12_hwmgr *data;
374         struct amdgpu_device *adev = hwmgr->adev;
375
376         data = kzalloc(sizeof(struct vega12_hwmgr), GFP_KERNEL);
377         if (data == NULL)
378                 return -ENOMEM;
379
380         hwmgr->backend = data;
381
382         vega12_set_default_registry_data(hwmgr);
383
384         data->disable_dpm_mask = 0xff;
385         data->workload_mask = 0xff;
386
387         /* need to set voltage control types before EVV patching */
388         data->vddc_control = VEGA12_VOLTAGE_CONTROL_NONE;
389         data->mvdd_control = VEGA12_VOLTAGE_CONTROL_NONE;
390         data->vddci_control = VEGA12_VOLTAGE_CONTROL_NONE;
391
392         data->water_marks_bitmap = 0;
393         data->avfs_exist = false;
394
395         vega12_set_features_platform_caps(hwmgr);
396
397         vega12_init_dpm_defaults(hwmgr);
398
399         /* Parse pptable data read from VBIOS */
400         vega12_set_private_data_based_on_pptable(hwmgr);
401
402         data->is_tlu_enabled = false;
403
404         hwmgr->platform_descriptor.hardwareActivityPerformanceLevels =
405                         VEGA12_MAX_HARDWARE_POWERLEVELS;
406         hwmgr->platform_descriptor.hardwarePerformanceLevels = 2;
407         hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50;
408
409         hwmgr->platform_descriptor.vbiosInterruptId = 0x20000400; /* IRQ_SOURCE1_SW_INT */
410         /* The true clock step depends on the frequency, typically 4.5 or 9 MHz. Here we use 5. */
411         hwmgr->platform_descriptor.clockStep.engineClock = 500;
412         hwmgr->platform_descriptor.clockStep.memoryClock = 500;
413
414         data->total_active_cus = adev->gfx.cu_info.number;
415         /* Setup default Overdrive Fan control settings */
416         data->odn_fan_table.target_fan_speed =
417                         hwmgr->thermal_controller.advanceFanControlParameters.usMaxFanRPM;
418         data->odn_fan_table.target_temperature =
419                         hwmgr->thermal_controller.advanceFanControlParameters.ucTargetTemperature;
420         data->odn_fan_table.min_performance_clock =
421                         hwmgr->thermal_controller.advanceFanControlParameters.ulMinFanSCLKAcousticLimit;
422         data->odn_fan_table.min_fan_limit =
423                         hwmgr->thermal_controller.advanceFanControlParameters.usFanPWMMinLimit *
424                         hwmgr->thermal_controller.fanInfo.ulMaxRPM / 100;
425
426         return result;
427 }
428
429 static int vega12_init_sclk_threshold(struct pp_hwmgr *hwmgr)
430 {
431         struct vega12_hwmgr *data =
432                         (struct vega12_hwmgr *)(hwmgr->backend);
433
434         data->low_sclk_interrupt_threshold = 0;
435
436         return 0;
437 }
438
439 static int vega12_setup_asic_task(struct pp_hwmgr *hwmgr)
440 {
441         PP_ASSERT_WITH_CODE(!vega12_init_sclk_threshold(hwmgr),
442                         "Failed to init sclk threshold!",
443                         return -EINVAL);
444
445         return 0;
446 }
447
448 /*
449  * @fn vega12_init_dpm_state
450  * @brief Function to initialize all Soft Min/Max and Hard Min/Max to 0xff.
451  *
452  * @param    dpm_state - the address of the DPM Table to initiailize.
453  * @return   None.
454  */
455 static void vega12_init_dpm_state(struct vega12_dpm_state *dpm_state)
456 {
457         dpm_state->soft_min_level = 0xff;
458         dpm_state->soft_max_level = 0xff;
459         dpm_state->hard_min_level = 0xff;
460         dpm_state->hard_max_level = 0xff;
461 }
462
463 static int vega12_get_number_dpm_level(struct pp_hwmgr *hwmgr,
464                 PPCLK_e clkID, uint32_t *num_dpm_level)
465 {
466         int result;
467         /*
468          * SMU expects the Clock ID to be in the top 16 bits.
469          * Lower 16 bits specify the level however 0xFF is a
470          * special argument the returns the total number of levels
471          */
472         PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr,
473                 PPSMC_MSG_GetDpmFreqByIndex, (clkID << 16 | 0xFF)) == 0,
474                 "[GetNumberDpmLevel] Failed to get DPM levels from SMU for CLKID!",
475                 return -EINVAL);
476
477         result = vega12_read_arg_from_smc(hwmgr, num_dpm_level);
478
479         PP_ASSERT_WITH_CODE(*num_dpm_level < MAX_REGULAR_DPM_NUMBER,
480                 "[GetNumberDPMLevel] Number of DPM levels is greater than limit",
481                 return -EINVAL);
482
483         PP_ASSERT_WITH_CODE(*num_dpm_level != 0,
484                 "[GetNumberDPMLevel] Number of CLK Levels is zero!",
485                 return -EINVAL);
486
487         return result;
488 }
489
490 static int vega12_get_dpm_frequency_by_index(struct pp_hwmgr *hwmgr,
491                 PPCLK_e clkID, uint32_t index, uint32_t *clock)
492 {
493         int result;
494
495         /*
496          *SMU expects the Clock ID to be in the top 16 bits.
497          *Lower 16 bits specify the level
498          */
499         PP_ASSERT_WITH_CODE(smum_send_msg_to_smc_with_parameter(hwmgr,
500                 PPSMC_MSG_GetDpmFreqByIndex, (clkID << 16 | index)) == 0,
501                 "[GetDpmFrequencyByIndex] Failed to get dpm frequency from SMU!",
502                 return -EINVAL);
503
504         result = vega12_read_arg_from_smc(hwmgr, clock);
505
506         PP_ASSERT_WITH_CODE(*clock != 0,
507                 "[GetDPMFrequencyByIndex] Failed to get dpm frequency by index.!",
508                 return -EINVAL);
509
510         return result;
511 }
512
513 /*
514  * This function is to initialize all DPM state tables
515  * for SMU based on the dependency table.
516  * Dynamic state patching function will then trim these
517  * state tables to the allowed range based
518  * on the power policy or external client requests,
519  * such as UVD request, etc.
520  */
521 static int vega12_setup_default_dpm_tables(struct pp_hwmgr *hwmgr)
522 {
523         uint32_t num_levels, i, clock;
524
525         struct vega12_hwmgr *data =
526                         (struct vega12_hwmgr *)(hwmgr->backend);
527
528         struct vega12_single_dpm_table *dpm_table;
529
530         memset(&data->dpm_table, 0, sizeof(data->dpm_table));
531
532         /* Initialize Sclk DPM and SOC DPM table based on allow Sclk values */
533         dpm_table = &(data->dpm_table.soc_table);
534
535         PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_SOCCLK,
536                 &num_levels) == 0,
537                 "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for SOCCLK!",
538                 return -EINVAL);
539
540         dpm_table->count = num_levels;
541
542         for (i = 0; i < num_levels; i++) {
543                 PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr,
544                         PPCLK_SOCCLK, i, &clock) == 0,
545                         "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for SOCCLK!",
546                         return -EINVAL);
547
548                 dpm_table->dpm_levels[i].value = clock;
549                 dpm_table->dpm_levels[i].enabled = true;
550         }
551
552         vega12_init_dpm_state(&(dpm_table->dpm_state));
553
554         dpm_table = &(data->dpm_table.gfx_table);
555
556         PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_GFXCLK,
557                 &num_levels) == 0,
558                 "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for GFXCLK!",
559                 return -EINVAL);
560
561         dpm_table->count = num_levels;
562         for (i = 0; i < num_levels; i++) {
563                 PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr,
564                         PPCLK_GFXCLK, i, &clock) == 0,
565                         "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for GFXCLK!",
566                         return -EINVAL);
567
568                 dpm_table->dpm_levels[i].value = clock;
569                 dpm_table->dpm_levels[i].enabled = true;
570         }
571
572         vega12_init_dpm_state(&(dpm_table->dpm_state));
573         /* Initialize Mclk DPM table based on allow Mclk values */
574         dpm_table = &(data->dpm_table.mem_table);
575
576         PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_UCLK,
577                 &num_levels) == 0,
578                 "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for UCLK!",
579                 return -EINVAL);
580
581         dpm_table->count = num_levels;
582
583         for (i = 0; i < num_levels; i++) {
584                 PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr,
585                         PPCLK_UCLK, i, &clock) == 0,
586                         "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for UCLK!",
587                         return -EINVAL);
588
589                 dpm_table->dpm_levels[i].value = clock;
590                 dpm_table->dpm_levels[i].enabled = true;
591         }
592
593         vega12_init_dpm_state(&(dpm_table->dpm_state));
594
595         dpm_table = &(data->dpm_table.eclk_table);
596
597         PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_ECLK,
598                 &num_levels) == 0,
599                 "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for ECLK!",
600                 return -EINVAL);
601
602         dpm_table->count = num_levels;
603
604         for (i = 0; i < num_levels; i++) {
605                 PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr,
606                 PPCLK_ECLK, i, &clock) == 0,
607                 "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for ECLK!",
608                 return -EINVAL);
609
610                 dpm_table->dpm_levels[i].value = clock;
611                 dpm_table->dpm_levels[i].enabled = true;
612         }
613
614         vega12_init_dpm_state(&(dpm_table->dpm_state));
615
616         dpm_table = &(data->dpm_table.vclk_table);
617
618         PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_VCLK,
619                 &num_levels) == 0,
620                 "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for VCLK!",
621                 return -EINVAL);
622
623         dpm_table->count = num_levels;
624
625         for (i = 0; i < num_levels; i++) {
626                 PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr,
627                         PPCLK_VCLK, i, &clock) == 0,
628                         "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for VCLK!",
629                         return -EINVAL);
630
631                 dpm_table->dpm_levels[i].value = clock;
632                 dpm_table->dpm_levels[i].enabled = true;
633         }
634
635         vega12_init_dpm_state(&(dpm_table->dpm_state));
636
637         dpm_table = &(data->dpm_table.dclk_table);
638
639         PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr, PPCLK_DCLK,
640                 &num_levels) == 0,
641                 "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DCLK!",
642                 return -EINVAL);
643
644         dpm_table->count = num_levels;
645
646         for (i = 0; i < num_levels; i++) {
647                 PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr,
648                         PPCLK_DCLK, i, &clock) == 0,
649                 "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DCLK!",
650                 return -EINVAL);
651
652                 dpm_table->dpm_levels[i].value = clock;
653                 dpm_table->dpm_levels[i].enabled = true;
654         }
655
656         vega12_init_dpm_state(&(dpm_table->dpm_state));
657
658         /* Assume there is no headless Vega12 for now */
659         dpm_table = &(data->dpm_table.dcef_table);
660
661         PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr,
662                 PPCLK_DCEFCLK, &num_levels) == 0,
663                 "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DCEFCLK!",
664                 return -EINVAL);
665
666         dpm_table->count = num_levels;
667
668         for (i = 0; i < num_levels; i++) {
669                 PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr,
670                         PPCLK_DCEFCLK, i, &clock) == 0,
671                         "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DCEFCLK!",
672                         return -EINVAL);
673
674                 dpm_table->dpm_levels[i].value = clock;
675                 dpm_table->dpm_levels[i].enabled = true;
676         }
677
678         vega12_init_dpm_state(&(dpm_table->dpm_state));
679
680         dpm_table = &(data->dpm_table.pixel_table);
681
682         PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr,
683                 PPCLK_PIXCLK, &num_levels) == 0,
684                 "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for PIXCLK!",
685                 return -EINVAL);
686
687         dpm_table->count = num_levels;
688
689         for (i = 0; i < num_levels; i++) {
690                 PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr,
691                         PPCLK_PIXCLK, i, &clock) == 0,
692                         "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for PIXCLK!",
693                         return -EINVAL);
694
695                 dpm_table->dpm_levels[i].value = clock;
696                 dpm_table->dpm_levels[i].enabled = true;
697         }
698
699         vega12_init_dpm_state(&(dpm_table->dpm_state));
700
701         dpm_table = &(data->dpm_table.display_table);
702
703         PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr,
704                 PPCLK_DISPCLK, &num_levels) == 0,
705                 "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DISPCLK!",
706                 return -EINVAL);
707
708         dpm_table->count = num_levels;
709
710         for (i = 0; i < num_levels; i++) {
711                 PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr,
712                         PPCLK_DISPCLK, i, &clock) == 0,
713                         "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for DISPCLK!",
714                         return -EINVAL);
715
716                 dpm_table->dpm_levels[i].value = clock;
717                 dpm_table->dpm_levels[i].enabled = true;
718         }
719
720         vega12_init_dpm_state(&(dpm_table->dpm_state));
721
722         dpm_table = &(data->dpm_table.phy_table);
723
724         PP_ASSERT_WITH_CODE(vega12_get_number_dpm_level(hwmgr,
725                 PPCLK_PHYCLK, &num_levels) == 0,
726                 "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for PHYCLK!",
727                 return -EINVAL);
728
729         dpm_table->count = num_levels;
730
731         for (i = 0; i < num_levels; i++) {
732                 PP_ASSERT_WITH_CODE(vega12_get_dpm_frequency_by_index(hwmgr,
733                         PPCLK_PHYCLK, i, &clock) == 0,
734                         "[SetupDefaultDPMTables] Failed to get DPM levels from SMU for PHYCLK!",
735                         return -EINVAL);
736
737                 dpm_table->dpm_levels[i].value = clock;
738                 dpm_table->dpm_levels[i].enabled = true;
739         }
740
741         vega12_init_dpm_state(&(dpm_table->dpm_state));
742
743         /* save a copy of the default DPM table */
744         memcpy(&(data->golden_dpm_table), &(data->dpm_table),
745                         sizeof(struct vega12_dpm_table));
746
747         return 0;
748 }
749
750 #if 0
751 static int vega12_save_default_power_profile(struct pp_hwmgr *hwmgr)
752 {
753         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
754         struct vega12_single_dpm_table *dpm_table = &(data->dpm_table.gfx_table);
755         uint32_t min_level;
756
757         hwmgr->default_gfx_power_profile.type = AMD_PP_GFX_PROFILE;
758         hwmgr->default_compute_power_profile.type = AMD_PP_COMPUTE_PROFILE;
759
760         /* Optimize compute power profile: Use only highest
761          * 2 power levels (if more than 2 are available)
762          */
763         if (dpm_table->count > 2)
764                 min_level = dpm_table->count - 2;
765         else if (dpm_table->count == 2)
766                 min_level = 1;
767         else
768                 min_level = 0;
769
770         hwmgr->default_compute_power_profile.min_sclk =
771                         dpm_table->dpm_levels[min_level].value;
772
773         hwmgr->gfx_power_profile = hwmgr->default_gfx_power_profile;
774         hwmgr->compute_power_profile = hwmgr->default_compute_power_profile;
775
776         return 0;
777 }
778 #endif
779
780 /**
781 * Initializes the SMC table and uploads it
782 *
783 * @param    hwmgr  the address of the powerplay hardware manager.
784 * @param    pInput  the pointer to input data (PowerState)
785 * @return   always 0
786 */
787 static int vega12_init_smc_table(struct pp_hwmgr *hwmgr)
788 {
789         int result;
790         struct vega12_hwmgr *data =
791                         (struct vega12_hwmgr *)(hwmgr->backend);
792         PPTable_t *pp_table = &(data->smc_state_table.pp_table);
793         struct pp_atomfwctrl_bios_boot_up_values boot_up_values;
794         struct phm_ppt_v3_information *pptable_information =
795                 (struct phm_ppt_v3_information *)hwmgr->pptable;
796
797         result = pp_atomfwctrl_get_vbios_bootup_values(hwmgr, &boot_up_values);
798         if (!result) {
799                 data->vbios_boot_state.vddc     = boot_up_values.usVddc;
800                 data->vbios_boot_state.vddci    = boot_up_values.usVddci;
801                 data->vbios_boot_state.mvddc    = boot_up_values.usMvddc;
802                 data->vbios_boot_state.gfx_clock = boot_up_values.ulGfxClk;
803                 data->vbios_boot_state.mem_clock = boot_up_values.ulUClk;
804                 data->vbios_boot_state.soc_clock = boot_up_values.ulSocClk;
805                 data->vbios_boot_state.dcef_clock = boot_up_values.ulDCEFClk;
806                 data->vbios_boot_state.uc_cooling_id = boot_up_values.ucCoolingID;
807                 data->vbios_boot_state.eclock = boot_up_values.ulEClk;
808                 data->vbios_boot_state.dclock = boot_up_values.ulDClk;
809                 data->vbios_boot_state.vclock = boot_up_values.ulVClk;
810                 smum_send_msg_to_smc_with_parameter(hwmgr,
811                                 PPSMC_MSG_SetMinDeepSleepDcefclk,
812                         (uint32_t)(data->vbios_boot_state.dcef_clock / 100));
813         }
814
815         memcpy(pp_table, pptable_information->smc_pptable, sizeof(PPTable_t));
816
817         result = vega12_copy_table_to_smc(hwmgr,
818                         (uint8_t *)pp_table, TABLE_PPTABLE);
819         PP_ASSERT_WITH_CODE(!result,
820                         "Failed to upload PPtable!", return result);
821
822         return 0;
823 }
824
825 static int vega12_set_allowed_featuresmask(struct pp_hwmgr *hwmgr)
826 {
827         struct vega12_hwmgr *data =
828                         (struct vega12_hwmgr *)(hwmgr->backend);
829         int i;
830         uint32_t allowed_features_low = 0, allowed_features_high = 0;
831
832         for (i = 0; i < GNLD_FEATURES_MAX; i++)
833                 if (data->smu_features[i].allowed)
834                         data->smu_features[i].smu_feature_id > 31 ?
835                                 (allowed_features_high |= ((data->smu_features[i].smu_feature_bitmap >> SMU_FEATURES_HIGH_SHIFT) & 0xFFFFFFFF)) :
836                                 (allowed_features_low |= ((data->smu_features[i].smu_feature_bitmap >> SMU_FEATURES_LOW_SHIFT) & 0xFFFFFFFF));
837
838         PP_ASSERT_WITH_CODE(
839                 smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetAllowedFeaturesMaskHigh, allowed_features_high) == 0,
840                 "[SetAllowedFeaturesMask] Attempt to set allowed features mask (high) failed!",
841                 return -1);
842
843         PP_ASSERT_WITH_CODE(
844                 smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetAllowedFeaturesMaskLow, allowed_features_low) == 0,
845                 "[SetAllowedFeaturesMask] Attempt to set allowed features mask (low) failed!",
846                 return -1);
847
848         return 0;
849 }
850
851 static int vega12_enable_all_smu_features(struct pp_hwmgr *hwmgr)
852 {
853         struct vega12_hwmgr *data =
854                         (struct vega12_hwmgr *)(hwmgr->backend);
855         uint64_t features_enabled;
856         int i;
857         bool enabled;
858
859         PP_ASSERT_WITH_CODE(
860                 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableAllSmuFeatures) == 0,
861                 "[EnableAllSMUFeatures] Failed to enable all smu features!",
862                 return -1);
863
864         if (vega12_get_enabled_smc_features(hwmgr, &features_enabled) == 0) {
865                 for (i = 0; i < GNLD_FEATURES_MAX; i++) {
866                         enabled = (features_enabled & data->smu_features[i].smu_feature_bitmap) ? true : false;
867                         data->smu_features[i].enabled = enabled;
868                         data->smu_features[i].supported = enabled;
869                         PP_ASSERT(
870                                 !data->smu_features[i].allowed || enabled,
871                                 "[EnableAllSMUFeatures] Enabled feature is different from allowed, expected disabled!");
872                 }
873         }
874
875         return 0;
876 }
877
878 static int vega12_disable_all_smu_features(struct pp_hwmgr *hwmgr)
879 {
880         struct vega12_hwmgr *data =
881                         (struct vega12_hwmgr *)(hwmgr->backend);
882         uint64_t features_enabled;
883         int i;
884         bool enabled;
885
886         PP_ASSERT_WITH_CODE(
887                 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableAllSmuFeatures) == 0,
888                 "[DisableAllSMUFeatures] Failed to disable all smu features!",
889                 return -1);
890
891         if (vega12_get_enabled_smc_features(hwmgr, &features_enabled) == 0) {
892                 for (i = 0; i < GNLD_FEATURES_MAX; i++) {
893                         enabled = (features_enabled & data->smu_features[i].smu_feature_bitmap) ? true : false;
894                         data->smu_features[i].enabled = enabled;
895                         data->smu_features[i].supported = enabled;
896                 }
897         }
898
899         return 0;
900 }
901
902 static int vega12_odn_initialize_default_settings(
903                 struct pp_hwmgr *hwmgr)
904 {
905         return 0;
906 }
907
908 static int vega12_set_overdrive_target_percentage(struct pp_hwmgr *hwmgr,
909                 uint32_t adjust_percent)
910 {
911         return smum_send_msg_to_smc_with_parameter(hwmgr,
912                         PPSMC_MSG_OverDriveSetPercentage, adjust_percent);
913 }
914
915 static int vega12_power_control_set_level(struct pp_hwmgr *hwmgr)
916 {
917         int adjust_percent, result = 0;
918
919         if (PP_CAP(PHM_PlatformCaps_PowerContainment)) {
920                 adjust_percent =
921                                 hwmgr->platform_descriptor.TDPAdjustmentPolarity ?
922                                 hwmgr->platform_descriptor.TDPAdjustment :
923                                 (-1 * hwmgr->platform_descriptor.TDPAdjustment);
924                 result = vega12_set_overdrive_target_percentage(hwmgr,
925                                 (uint32_t)adjust_percent);
926         }
927         return result;
928 }
929
930 static int vega12_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
931 {
932         int tmp_result, result = 0;
933
934         smum_send_msg_to_smc_with_parameter(hwmgr,
935                         PPSMC_MSG_NumOfDisplays, 0);
936
937         result = vega12_set_allowed_featuresmask(hwmgr);
938         PP_ASSERT_WITH_CODE(result == 0,
939                         "[EnableDPMTasks] Failed to set allowed featuresmask!\n",
940                         return result);
941
942         tmp_result = vega12_init_smc_table(hwmgr);
943         PP_ASSERT_WITH_CODE(!tmp_result,
944                         "Failed to initialize SMC table!",
945                         result = tmp_result);
946
947         result = vega12_enable_all_smu_features(hwmgr);
948         PP_ASSERT_WITH_CODE(!result,
949                         "Failed to enable all smu features!",
950                         return result);
951
952         tmp_result = vega12_power_control_set_level(hwmgr);
953         PP_ASSERT_WITH_CODE(!tmp_result,
954                         "Failed to power control set level!",
955                         result = tmp_result);
956
957         result = vega12_odn_initialize_default_settings(hwmgr);
958         PP_ASSERT_WITH_CODE(!result,
959                         "Failed to power control set level!",
960                         return result);
961
962         result = vega12_setup_default_dpm_tables(hwmgr);
963         PP_ASSERT_WITH_CODE(!result,
964                         "Failed to setup default DPM tables!",
965                         return result);
966         return result;
967 }
968
969 static int vega12_patch_boot_state(struct pp_hwmgr *hwmgr,
970              struct pp_hw_power_state *hw_ps)
971 {
972         return 0;
973 }
974
975 static uint32_t vega12_find_lowest_dpm_level(
976                 struct vega12_single_dpm_table *table)
977 {
978         uint32_t i;
979
980         for (i = 0; i < table->count; i++) {
981                 if (table->dpm_levels[i].enabled)
982                         break;
983         }
984
985         return i;
986 }
987
988 static uint32_t vega12_find_highest_dpm_level(
989                 struct vega12_single_dpm_table *table)
990 {
991         uint32_t i = 0;
992
993         if (table->count <= MAX_REGULAR_DPM_NUMBER) {
994                 for (i = table->count; i > 0; i--) {
995                         if (table->dpm_levels[i - 1].enabled)
996                                 return i - 1;
997                 }
998         } else {
999                 pr_info("DPM Table Has Too Many Entries!");
1000                 return MAX_REGULAR_DPM_NUMBER - 1;
1001         }
1002
1003         return i;
1004 }
1005
1006 static int vega12_upload_dpm_min_level(struct pp_hwmgr *hwmgr)
1007 {
1008         struct vega12_hwmgr *data = hwmgr->backend;
1009         if (data->smc_state_table.gfx_boot_level !=
1010                         data->dpm_table.gfx_table.dpm_state.soft_min_level) {
1011                 smum_send_msg_to_smc_with_parameter(hwmgr,
1012                         PPSMC_MSG_SetSoftMinByFreq,
1013                         PPCLK_GFXCLK<<16 | data->dpm_table.gfx_table.dpm_levels[data->smc_state_table.gfx_boot_level].value);
1014                 data->dpm_table.gfx_table.dpm_state.soft_min_level =
1015                                 data->smc_state_table.gfx_boot_level;
1016         }
1017
1018         if (data->smc_state_table.mem_boot_level !=
1019                         data->dpm_table.mem_table.dpm_state.soft_min_level) {
1020                 smum_send_msg_to_smc_with_parameter(hwmgr,
1021                         PPSMC_MSG_SetSoftMinByFreq,
1022                         PPCLK_UCLK<<16 | data->dpm_table.mem_table.dpm_levels[data->smc_state_table.mem_boot_level].value);
1023                 data->dpm_table.mem_table.dpm_state.soft_min_level =
1024                                 data->smc_state_table.mem_boot_level;
1025         }
1026
1027         return 0;
1028
1029 }
1030
1031 static int vega12_upload_dpm_max_level(struct pp_hwmgr *hwmgr)
1032 {
1033         struct vega12_hwmgr *data = hwmgr->backend;
1034         if (data->smc_state_table.gfx_max_level !=
1035                 data->dpm_table.gfx_table.dpm_state.soft_max_level) {
1036                 smum_send_msg_to_smc_with_parameter(hwmgr,
1037                         PPSMC_MSG_SetSoftMaxByFreq,
1038                         /* plus the vale by 1 to align the resolution */
1039                         PPCLK_GFXCLK<<16 | (data->dpm_table.gfx_table.dpm_levels[data->smc_state_table.gfx_max_level].value + 1));
1040                 data->dpm_table.gfx_table.dpm_state.soft_max_level =
1041                                 data->smc_state_table.gfx_max_level;
1042         }
1043
1044         if (data->smc_state_table.mem_max_level !=
1045                 data->dpm_table.mem_table.dpm_state.soft_max_level) {
1046                 smum_send_msg_to_smc_with_parameter(hwmgr,
1047                         PPSMC_MSG_SetSoftMaxByFreq,
1048                         /* plus the vale by 1 to align the resolution */
1049                         PPCLK_UCLK<<16 | (data->dpm_table.mem_table.dpm_levels[data->smc_state_table.mem_max_level].value + 1));
1050                 data->dpm_table.mem_table.dpm_state.soft_max_level =
1051                                 data->smc_state_table.mem_max_level;
1052         }
1053
1054         return 0;
1055 }
1056
1057 int vega12_enable_disable_vce_dpm(struct pp_hwmgr *hwmgr, bool enable)
1058 {
1059         struct vega12_hwmgr *data =
1060                         (struct vega12_hwmgr *)(hwmgr->backend);
1061
1062         if (data->smu_features[GNLD_DPM_VCE].supported) {
1063                 PP_ASSERT_WITH_CODE(!vega12_enable_smc_features(hwmgr,
1064                                 enable,
1065                                 data->smu_features[GNLD_DPM_VCE].smu_feature_bitmap),
1066                                 "Attempt to Enable/Disable DPM VCE Failed!",
1067                                 return -1);
1068                 data->smu_features[GNLD_DPM_VCE].enabled = enable;
1069         }
1070
1071         return 0;
1072 }
1073
1074 static uint32_t vega12_dpm_get_sclk(struct pp_hwmgr *hwmgr, bool low)
1075 {
1076         struct vega12_hwmgr *data =
1077                         (struct vega12_hwmgr *)(hwmgr->backend);
1078         uint32_t gfx_clk;
1079
1080         if (!data->smu_features[GNLD_DPM_GFXCLK].enabled)
1081                 return -1;
1082
1083         if (low)
1084                 PP_ASSERT_WITH_CODE(
1085                         vega12_get_clock_ranges(hwmgr, &gfx_clk, PPCLK_GFXCLK, false) == 0,
1086                         "[GetSclks]: fail to get min PPCLK_GFXCLK\n",
1087                         return -1);
1088         else
1089                 PP_ASSERT_WITH_CODE(
1090                         vega12_get_clock_ranges(hwmgr, &gfx_clk, PPCLK_GFXCLK, true) == 0,
1091                         "[GetSclks]: fail to get max PPCLK_GFXCLK\n",
1092                         return -1);
1093
1094         return (gfx_clk * 100);
1095 }
1096
1097 static uint32_t vega12_dpm_get_mclk(struct pp_hwmgr *hwmgr, bool low)
1098 {
1099         struct vega12_hwmgr *data =
1100                         (struct vega12_hwmgr *)(hwmgr->backend);
1101         uint32_t mem_clk;
1102
1103         if (!data->smu_features[GNLD_DPM_UCLK].enabled)
1104                 return -1;
1105
1106         if (low)
1107                 PP_ASSERT_WITH_CODE(
1108                         vega12_get_clock_ranges(hwmgr, &mem_clk, PPCLK_UCLK, false) == 0,
1109                         "[GetMclks]: fail to get min PPCLK_UCLK\n",
1110                         return -1);
1111         else
1112                 PP_ASSERT_WITH_CODE(
1113                         vega12_get_clock_ranges(hwmgr, &mem_clk, PPCLK_UCLK, true) == 0,
1114                         "[GetMclks]: fail to get max PPCLK_UCLK\n",
1115                         return -1);
1116
1117         return (mem_clk * 100);
1118 }
1119
1120 static int vega12_get_gpu_power(struct pp_hwmgr *hwmgr, uint32_t *query)
1121 {
1122 #if 0
1123         uint32_t value;
1124
1125         PP_ASSERT_WITH_CODE(!smum_send_msg_to_smc(hwmgr,
1126                         PPSMC_MSG_GetCurrPkgPwr),
1127                         "Failed to get current package power!",
1128                         return -EINVAL);
1129
1130         vega12_read_arg_from_smc(hwmgr, &value);
1131         /* power value is an integer */
1132         *query = value << 8;
1133 #endif
1134         return 0;
1135 }
1136
1137 static int vega12_get_current_gfx_clk_freq(struct pp_hwmgr *hwmgr, uint32_t *gfx_freq)
1138 {
1139         uint32_t gfx_clk = 0;
1140
1141         *gfx_freq = 0;
1142
1143         PP_ASSERT_WITH_CODE(
1144                         smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetDpmClockFreq, (PPCLK_GFXCLK << 16)) == 0,
1145                         "[GetCurrentGfxClkFreq] Attempt to get Current GFXCLK Frequency Failed!",
1146                         return -1);
1147         PP_ASSERT_WITH_CODE(
1148                         vega12_read_arg_from_smc(hwmgr, &gfx_clk) == 0,
1149                         "[GetCurrentGfxClkFreq] Attempt to read arg from SMC Failed",
1150                         return -1);
1151
1152         *gfx_freq = gfx_clk * 100;
1153
1154         return 0;
1155 }
1156
1157 static int vega12_get_current_mclk_freq(struct pp_hwmgr *hwmgr, uint32_t *mclk_freq)
1158 {
1159         uint32_t mem_clk = 0;
1160
1161         *mclk_freq = 0;
1162
1163         PP_ASSERT_WITH_CODE(
1164                         smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetDpmClockFreq, (PPCLK_UCLK << 16)) == 0,
1165                         "[GetCurrentMClkFreq] Attempt to get Current MCLK Frequency Failed!",
1166                         return -1);
1167         PP_ASSERT_WITH_CODE(
1168                         vega12_read_arg_from_smc(hwmgr, &mem_clk) == 0,
1169                         "[GetCurrentMClkFreq] Attempt to read arg from SMC Failed",
1170                         return -1);
1171
1172         *mclk_freq = mem_clk * 100;
1173
1174         return 0;
1175 }
1176
1177 static int vega12_get_current_activity_percent(
1178                 struct pp_hwmgr *hwmgr,
1179                 uint32_t *activity_percent)
1180 {
1181         int ret = 0;
1182         uint32_t current_activity = 50;
1183
1184 #if 0
1185         ret = smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetAverageGfxActivity, 0);
1186         if (!ret) {
1187                 ret = vega12_read_arg_from_smc(hwmgr, &current_activity);
1188                 if (!ret) {
1189                         if (current_activity > 100) {
1190                                 PP_ASSERT(false,
1191                                         "[GetCurrentActivityPercent] Activity Percentage Exceeds 100!");
1192                                 current_activity = 100;
1193                         }
1194                 } else
1195                         PP_ASSERT(false,
1196                                 "[GetCurrentActivityPercent] Attempt To Read Average Graphics Activity from SMU Failed!");
1197         } else
1198                 PP_ASSERT(false,
1199                         "[GetCurrentActivityPercent] Attempt To Send Get Average Graphics Activity to SMU Failed!");
1200 #endif
1201         *activity_percent = current_activity;
1202
1203         return ret;
1204 }
1205
1206 static int vega12_read_sensor(struct pp_hwmgr *hwmgr, int idx,
1207                               void *value, int *size)
1208 {
1209         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1210         int ret = 0;
1211
1212         switch (idx) {
1213         case AMDGPU_PP_SENSOR_GFX_SCLK:
1214                 ret = vega12_get_current_gfx_clk_freq(hwmgr, (uint32_t *)value);
1215                 if (!ret)
1216                         *size = 4;
1217                 break;
1218         case AMDGPU_PP_SENSOR_GFX_MCLK:
1219                 ret = vega12_get_current_mclk_freq(hwmgr, (uint32_t *)value);
1220                 if (!ret)
1221                         *size = 4;
1222                 break;
1223         case AMDGPU_PP_SENSOR_GPU_LOAD:
1224                 ret = vega12_get_current_activity_percent(hwmgr, (uint32_t *)value);
1225                 if (!ret)
1226                         *size = 4;
1227                 break;
1228         case AMDGPU_PP_SENSOR_GPU_TEMP:
1229                 *((uint32_t *)value) = vega12_thermal_get_temperature(hwmgr);
1230                 *size = 4;
1231                 break;
1232         case AMDGPU_PP_SENSOR_UVD_POWER:
1233                 *((uint32_t *)value) = data->uvd_power_gated ? 0 : 1;
1234                 *size = 4;
1235                 break;
1236         case AMDGPU_PP_SENSOR_VCE_POWER:
1237                 *((uint32_t *)value) = data->vce_power_gated ? 0 : 1;
1238                 *size = 4;
1239                 break;
1240         case AMDGPU_PP_SENSOR_GPU_POWER:
1241                 ret = vega12_get_gpu_power(hwmgr, (uint32_t *)value);
1242
1243                 break;
1244         default:
1245                 ret = -EINVAL;
1246                 break;
1247         }
1248         return ret;
1249 }
1250
1251 static int vega12_notify_smc_display_change(struct pp_hwmgr *hwmgr,
1252                 bool has_disp)
1253 {
1254         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1255
1256         if (data->smu_features[GNLD_DPM_UCLK].enabled)
1257                 return smum_send_msg_to_smc_with_parameter(hwmgr,
1258                         PPSMC_MSG_SetUclkFastSwitch,
1259                         has_disp ? 0 : 1);
1260
1261         return 0;
1262 }
1263
1264 int vega12_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
1265                 struct pp_display_clock_request *clock_req)
1266 {
1267         int result = 0;
1268         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1269         enum amd_pp_clock_type clk_type = clock_req->clock_type;
1270         uint32_t clk_freq = clock_req->clock_freq_in_khz / 1000;
1271         PPCLK_e clk_select = 0;
1272         uint32_t clk_request = 0;
1273
1274         if (data->smu_features[GNLD_DPM_DCEFCLK].enabled) {
1275                 switch (clk_type) {
1276                 case amd_pp_dcef_clock:
1277                         clk_freq = clock_req->clock_freq_in_khz / 100;
1278                         clk_select = PPCLK_DCEFCLK;
1279                         break;
1280                 case amd_pp_disp_clock:
1281                         clk_select = PPCLK_DISPCLK;
1282                         break;
1283                 case amd_pp_pixel_clock:
1284                         clk_select = PPCLK_PIXCLK;
1285                         break;
1286                 case amd_pp_phy_clock:
1287                         clk_select = PPCLK_PHYCLK;
1288                         break;
1289                 default:
1290                         pr_info("[DisplayClockVoltageRequest]Invalid Clock Type!");
1291                         result = -1;
1292                         break;
1293                 }
1294
1295                 if (!result) {
1296                         clk_request = (clk_select << 16) | clk_freq;
1297                         result = smum_send_msg_to_smc_with_parameter(hwmgr,
1298                                         PPSMC_MSG_SetHardMinByFreq,
1299                                         clk_request);
1300                 }
1301         }
1302
1303         return result;
1304 }
1305
1306 static int vega12_notify_smc_display_config_after_ps_adjustment(
1307                 struct pp_hwmgr *hwmgr)
1308 {
1309         struct vega12_hwmgr *data =
1310                         (struct vega12_hwmgr *)(hwmgr->backend);
1311         struct PP_Clocks min_clocks = {0};
1312         struct pp_display_clock_request clock_req;
1313         uint32_t clk_request;
1314
1315         if (hwmgr->display_config->num_display > 1)
1316                 vega12_notify_smc_display_change(hwmgr, false);
1317         else
1318                 vega12_notify_smc_display_change(hwmgr, true);
1319
1320         min_clocks.dcefClock = hwmgr->display_config->min_dcef_set_clk;
1321         min_clocks.dcefClockInSR = hwmgr->display_config->min_dcef_deep_sleep_set_clk;
1322         min_clocks.memoryClock = hwmgr->display_config->min_mem_set_clock;
1323
1324         if (data->smu_features[GNLD_DPM_DCEFCLK].supported) {
1325                 clock_req.clock_type = amd_pp_dcef_clock;
1326                 clock_req.clock_freq_in_khz = min_clocks.dcefClock;
1327                 if (!vega12_display_clock_voltage_request(hwmgr, &clock_req)) {
1328                         if (data->smu_features[GNLD_DS_DCEFCLK].supported)
1329                                 PP_ASSERT_WITH_CODE(
1330                                         !smum_send_msg_to_smc_with_parameter(
1331                                         hwmgr, PPSMC_MSG_SetMinDeepSleepDcefclk,
1332                                         min_clocks.dcefClockInSR /100),
1333                                         "Attempt to set divider for DCEFCLK Failed!",
1334                                         return -1);
1335                 } else {
1336                         pr_info("Attempt to set Hard Min for DCEFCLK Failed!");
1337                 }
1338         }
1339
1340         if (data->smu_features[GNLD_DPM_UCLK].enabled) {
1341                 clk_request = (PPCLK_UCLK << 16) | (min_clocks.memoryClock) / 100;
1342                 PP_ASSERT_WITH_CODE(
1343                         smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetHardMinByFreq, clk_request) == 0,
1344                         "[PhwVega12_NotifySMCDisplayConfigAfterPowerStateAdjustment] Attempt to set UCLK HardMin Failed!",
1345                         return -1);
1346                 data->dpm_table.mem_table.dpm_state.hard_min_level = min_clocks.memoryClock;
1347         }
1348
1349         return 0;
1350 }
1351
1352 static int vega12_force_dpm_highest(struct pp_hwmgr *hwmgr)
1353 {
1354         struct vega12_hwmgr *data =
1355                         (struct vega12_hwmgr *)(hwmgr->backend);
1356
1357         data->smc_state_table.gfx_boot_level =
1358         data->smc_state_table.gfx_max_level =
1359                         vega12_find_highest_dpm_level(&(data->dpm_table.gfx_table));
1360         data->smc_state_table.mem_boot_level =
1361         data->smc_state_table.mem_max_level =
1362                         vega12_find_highest_dpm_level(&(data->dpm_table.mem_table));
1363
1364         PP_ASSERT_WITH_CODE(!vega12_upload_dpm_min_level(hwmgr),
1365                         "Failed to upload boot level to highest!",
1366                         return -1);
1367
1368         PP_ASSERT_WITH_CODE(!vega12_upload_dpm_max_level(hwmgr),
1369                         "Failed to upload dpm max level to highest!",
1370                         return -1);
1371
1372         return 0;
1373 }
1374
1375 static int vega12_force_dpm_lowest(struct pp_hwmgr *hwmgr)
1376 {
1377         struct vega12_hwmgr *data =
1378                         (struct vega12_hwmgr *)(hwmgr->backend);
1379
1380         data->smc_state_table.gfx_boot_level =
1381         data->smc_state_table.gfx_max_level =
1382                         vega12_find_lowest_dpm_level(&(data->dpm_table.gfx_table));
1383         data->smc_state_table.mem_boot_level =
1384         data->smc_state_table.mem_max_level =
1385                         vega12_find_lowest_dpm_level(&(data->dpm_table.mem_table));
1386
1387         PP_ASSERT_WITH_CODE(!vega12_upload_dpm_min_level(hwmgr),
1388                         "Failed to upload boot level to highest!",
1389                         return -1);
1390
1391         PP_ASSERT_WITH_CODE(!vega12_upload_dpm_max_level(hwmgr),
1392                         "Failed to upload dpm max level to highest!",
1393                         return -1);
1394
1395         return 0;
1396
1397 }
1398
1399 static int vega12_unforce_dpm_levels(struct pp_hwmgr *hwmgr)
1400 {
1401         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1402
1403         data->smc_state_table.gfx_boot_level =
1404                         vega12_find_lowest_dpm_level(&(data->dpm_table.gfx_table));
1405         data->smc_state_table.gfx_max_level =
1406                         vega12_find_highest_dpm_level(&(data->dpm_table.gfx_table));
1407         data->smc_state_table.mem_boot_level =
1408                         vega12_find_lowest_dpm_level(&(data->dpm_table.mem_table));
1409         data->smc_state_table.mem_max_level =
1410                         vega12_find_highest_dpm_level(&(data->dpm_table.mem_table));
1411
1412         PP_ASSERT_WITH_CODE(!vega12_upload_dpm_min_level(hwmgr),
1413                         "Failed to upload DPM Bootup Levels!",
1414                         return -1);
1415
1416         PP_ASSERT_WITH_CODE(!vega12_upload_dpm_max_level(hwmgr),
1417                         "Failed to upload DPM Max Levels!",
1418                         return -1);
1419         return 0;
1420 }
1421
1422 #if 0
1423 static int vega12_get_profiling_clk_mask(struct pp_hwmgr *hwmgr, enum amd_dpm_forced_level level,
1424                                 uint32_t *sclk_mask, uint32_t *mclk_mask, uint32_t *soc_mask)
1425 {
1426         struct phm_ppt_v2_information *table_info =
1427                         (struct phm_ppt_v2_information *)(hwmgr->pptable);
1428
1429         if (table_info->vdd_dep_on_sclk->count > VEGA12_UMD_PSTATE_GFXCLK_LEVEL &&
1430                 table_info->vdd_dep_on_socclk->count > VEGA12_UMD_PSTATE_SOCCLK_LEVEL &&
1431                 table_info->vdd_dep_on_mclk->count > VEGA12_UMD_PSTATE_MCLK_LEVEL) {
1432                 *sclk_mask = VEGA12_UMD_PSTATE_GFXCLK_LEVEL;
1433                 *soc_mask = VEGA12_UMD_PSTATE_SOCCLK_LEVEL;
1434                 *mclk_mask = VEGA12_UMD_PSTATE_MCLK_LEVEL;
1435         }
1436
1437         if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) {
1438                 *sclk_mask = 0;
1439         } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) {
1440                 *mclk_mask = 0;
1441         } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) {
1442                 *sclk_mask = table_info->vdd_dep_on_sclk->count - 1;
1443                 *soc_mask = table_info->vdd_dep_on_socclk->count - 1;
1444                 *mclk_mask = table_info->vdd_dep_on_mclk->count - 1;
1445         }
1446         return 0;
1447 }
1448 #endif
1449
1450 static void vega12_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
1451 {
1452         switch (mode) {
1453         case AMD_FAN_CTRL_NONE:
1454                 break;
1455         case AMD_FAN_CTRL_MANUAL:
1456                 if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
1457                         vega12_fan_ctrl_stop_smc_fan_control(hwmgr);
1458                 break;
1459         case AMD_FAN_CTRL_AUTO:
1460                 if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
1461                         vega12_fan_ctrl_start_smc_fan_control(hwmgr);
1462                 break;
1463         default:
1464                 break;
1465         }
1466 }
1467
1468 static int vega12_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
1469                                 enum amd_dpm_forced_level level)
1470 {
1471         int ret = 0;
1472 #if 0
1473         uint32_t sclk_mask = 0;
1474         uint32_t mclk_mask = 0;
1475         uint32_t soc_mask = 0;
1476 #endif
1477
1478         switch (level) {
1479         case AMD_DPM_FORCED_LEVEL_HIGH:
1480                 ret = vega12_force_dpm_highest(hwmgr);
1481                 break;
1482         case AMD_DPM_FORCED_LEVEL_LOW:
1483                 ret = vega12_force_dpm_lowest(hwmgr);
1484                 break;
1485         case AMD_DPM_FORCED_LEVEL_AUTO:
1486                 ret = vega12_unforce_dpm_levels(hwmgr);
1487                 break;
1488         case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
1489         case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
1490         case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
1491         case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
1492 #if 0
1493                 ret = vega12_get_profiling_clk_mask(hwmgr, level, &sclk_mask, &mclk_mask, &soc_mask);
1494                 if (ret)
1495                         return ret;
1496                 vega12_force_clock_level(hwmgr, PP_SCLK, 1<<sclk_mask);
1497                 vega12_force_clock_level(hwmgr, PP_MCLK, 1<<mclk_mask);
1498 #endif
1499                 break;
1500         case AMD_DPM_FORCED_LEVEL_MANUAL:
1501         case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
1502         default:
1503                 break;
1504         }
1505 #if 0
1506         if (!ret) {
1507                 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK && hwmgr->dpm_level != AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
1508                         vega12_set_fan_control_mode(hwmgr, AMD_FAN_CTRL_NONE);
1509                 else if (level != AMD_DPM_FORCED_LEVEL_PROFILE_PEAK && hwmgr->dpm_level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
1510                         vega12_set_fan_control_mode(hwmgr, AMD_FAN_CTRL_AUTO);
1511         }
1512 #endif
1513         return ret;
1514 }
1515
1516 static uint32_t vega12_get_fan_control_mode(struct pp_hwmgr *hwmgr)
1517 {
1518         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1519
1520         if (data->smu_features[GNLD_FAN_CONTROL].enabled == false)
1521                 return AMD_FAN_CTRL_MANUAL;
1522         else
1523                 return AMD_FAN_CTRL_AUTO;
1524 }
1525
1526 static int vega12_get_dal_power_level(struct pp_hwmgr *hwmgr,
1527                 struct amd_pp_simple_clock_info *info)
1528 {
1529 #if 0
1530         struct phm_ppt_v2_information *table_info =
1531                         (struct phm_ppt_v2_information *)hwmgr->pptable;
1532         struct phm_clock_and_voltage_limits *max_limits =
1533                         &table_info->max_clock_voltage_on_ac;
1534
1535         info->engine_max_clock = max_limits->sclk;
1536         info->memory_max_clock = max_limits->mclk;
1537 #endif
1538         return 0;
1539 }
1540
1541 static int vega12_get_clock_ranges(struct pp_hwmgr *hwmgr,
1542                 uint32_t *clock,
1543                 PPCLK_e clock_select,
1544                 bool max)
1545 {
1546         int result;
1547         *clock = 0;
1548
1549         if (max) {
1550                  PP_ASSERT_WITH_CODE(
1551                         smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMaxDpmFreq, (clock_select << 16)) == 0,
1552                         "[GetClockRanges] Failed to get max clock from SMC!",
1553                         return -1);
1554                 result = vega12_read_arg_from_smc(hwmgr, clock);
1555         } else {
1556                 PP_ASSERT_WITH_CODE(
1557                         smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_GetMinDpmFreq, (clock_select << 16)) == 0,
1558                         "[GetClockRanges] Failed to get min clock from SMC!",
1559                         return -1);
1560                 result = vega12_read_arg_from_smc(hwmgr, clock);
1561         }
1562
1563         return result;
1564 }
1565
1566 static int vega12_get_sclks(struct pp_hwmgr *hwmgr,
1567                 struct pp_clock_levels_with_latency *clocks)
1568 {
1569         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1570         uint32_t ucount;
1571         int i;
1572         struct vega12_single_dpm_table *dpm_table;
1573
1574         if (!data->smu_features[GNLD_DPM_GFXCLK].enabled)
1575                 return -1;
1576
1577         dpm_table = &(data->dpm_table.gfx_table);
1578         ucount = (dpm_table->count > VG12_PSUEDO_NUM_GFXCLK_DPM_LEVELS) ?
1579                 VG12_PSUEDO_NUM_GFXCLK_DPM_LEVELS : dpm_table->count;
1580
1581         for (i = 0; i < ucount; i++) {
1582                 clocks->data[i].clocks_in_khz =
1583                         dpm_table->dpm_levels[i].value * 100;
1584
1585                 clocks->data[i].latency_in_us = 0;
1586         }
1587
1588         clocks->num_levels = ucount;
1589
1590         return 0;
1591 }
1592
1593 static uint32_t vega12_get_mem_latency(struct pp_hwmgr *hwmgr,
1594                 uint32_t clock)
1595 {
1596         return 25;
1597 }
1598
1599 static int vega12_get_memclocks(struct pp_hwmgr *hwmgr,
1600                 struct pp_clock_levels_with_latency *clocks)
1601 {
1602         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1603         uint32_t ucount;
1604         int i;
1605         struct vega12_single_dpm_table *dpm_table;
1606         if (!data->smu_features[GNLD_DPM_UCLK].enabled)
1607                 return -1;
1608
1609         dpm_table = &(data->dpm_table.mem_table);
1610         ucount = (dpm_table->count > VG12_PSUEDO_NUM_UCLK_DPM_LEVELS) ?
1611                 VG12_PSUEDO_NUM_UCLK_DPM_LEVELS : dpm_table->count;
1612
1613         for (i = 0; i < ucount; i++) {
1614                 clocks->data[i].clocks_in_khz =
1615                         dpm_table->dpm_levels[i].value * 100;
1616
1617                 clocks->data[i].latency_in_us =
1618                         data->mclk_latency_table.entries[i].latency =
1619                         vega12_get_mem_latency(hwmgr, dpm_table->dpm_levels[i].value);
1620         }
1621
1622         clocks->num_levels = data->mclk_latency_table.count = ucount;
1623
1624         return 0;
1625 }
1626
1627 static int vega12_get_dcefclocks(struct pp_hwmgr *hwmgr,
1628                 struct pp_clock_levels_with_latency *clocks)
1629 {
1630         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1631         uint32_t ucount;
1632         int i;
1633         struct vega12_single_dpm_table *dpm_table;
1634
1635         if (!data->smu_features[GNLD_DPM_DCEFCLK].enabled)
1636                 return -1;
1637
1638
1639         dpm_table = &(data->dpm_table.dcef_table);
1640         ucount = (dpm_table->count > VG12_PSUEDO_NUM_DCEFCLK_DPM_LEVELS) ?
1641                 VG12_PSUEDO_NUM_DCEFCLK_DPM_LEVELS : dpm_table->count;
1642
1643         for (i = 0; i < ucount; i++) {
1644                 clocks->data[i].clocks_in_khz =
1645                         dpm_table->dpm_levels[i].value * 100;
1646
1647                 clocks->data[i].latency_in_us = 0;
1648         }
1649
1650         clocks->num_levels = ucount;
1651
1652         return 0;
1653 }
1654
1655 static int vega12_get_socclocks(struct pp_hwmgr *hwmgr,
1656                 struct pp_clock_levels_with_latency *clocks)
1657 {
1658         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1659         uint32_t ucount;
1660         int i;
1661         struct vega12_single_dpm_table *dpm_table;
1662
1663         if (!data->smu_features[GNLD_DPM_SOCCLK].enabled)
1664                 return -1;
1665
1666
1667         dpm_table = &(data->dpm_table.soc_table);
1668         ucount = (dpm_table->count > VG12_PSUEDO_NUM_SOCCLK_DPM_LEVELS) ?
1669                 VG12_PSUEDO_NUM_SOCCLK_DPM_LEVELS : dpm_table->count;
1670
1671         for (i = 0; i < ucount; i++) {
1672                 clocks->data[i].clocks_in_khz =
1673                         dpm_table->dpm_levels[i].value * 100;
1674
1675                 clocks->data[i].latency_in_us = 0;
1676         }
1677
1678         clocks->num_levels = ucount;
1679
1680         return 0;
1681
1682 }
1683
1684 static int vega12_get_clock_by_type_with_latency(struct pp_hwmgr *hwmgr,
1685                 enum amd_pp_clock_type type,
1686                 struct pp_clock_levels_with_latency *clocks)
1687 {
1688         int ret;
1689
1690         switch (type) {
1691         case amd_pp_sys_clock:
1692                 ret = vega12_get_sclks(hwmgr, clocks);
1693                 break;
1694         case amd_pp_mem_clock:
1695                 ret = vega12_get_memclocks(hwmgr, clocks);
1696                 break;
1697         case amd_pp_dcef_clock:
1698                 ret = vega12_get_dcefclocks(hwmgr, clocks);
1699                 break;
1700         case amd_pp_soc_clock:
1701                 ret = vega12_get_socclocks(hwmgr, clocks);
1702                 break;
1703         default:
1704                 return -EINVAL;
1705         }
1706
1707         return ret;
1708 }
1709
1710 static int vega12_get_clock_by_type_with_voltage(struct pp_hwmgr *hwmgr,
1711                 enum amd_pp_clock_type type,
1712                 struct pp_clock_levels_with_voltage *clocks)
1713 {
1714         clocks->num_levels = 0;
1715
1716         return 0;
1717 }
1718
1719 static int vega12_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr,
1720                 struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges)
1721 {
1722         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1723         Watermarks_t *table = &(data->smc_state_table.water_marks_table);
1724         int result = 0;
1725         uint32_t i;
1726
1727         if (!data->registry_data.disable_water_mark &&
1728                         data->smu_features[GNLD_DPM_DCEFCLK].supported &&
1729                         data->smu_features[GNLD_DPM_SOCCLK].supported) {
1730                 for (i = 0; i < wm_with_clock_ranges->num_wm_sets_dmif; i++) {
1731                         table->WatermarkRow[WM_DCEFCLK][i].MinClock =
1732                                 cpu_to_le16((uint16_t)
1733                                 (wm_with_clock_ranges->wm_sets_dmif[i].wm_min_dcefclk_in_khz) /
1734                                 100);
1735                         table->WatermarkRow[WM_DCEFCLK][i].MaxClock =
1736                                 cpu_to_le16((uint16_t)
1737                                 (wm_with_clock_ranges->wm_sets_dmif[i].wm_max_dcefclk_in_khz) /
1738                                 100);
1739                         table->WatermarkRow[WM_DCEFCLK][i].MinUclk =
1740                                 cpu_to_le16((uint16_t)
1741                                 (wm_with_clock_ranges->wm_sets_dmif[i].wm_min_memclk_in_khz) /
1742                                 100);
1743                         table->WatermarkRow[WM_DCEFCLK][i].MaxUclk =
1744                                 cpu_to_le16((uint16_t)
1745                                 (wm_with_clock_ranges->wm_sets_dmif[i].wm_max_memclk_in_khz) /
1746                                 100);
1747                         table->WatermarkRow[WM_DCEFCLK][i].WmSetting = (uint8_t)
1748                                         wm_with_clock_ranges->wm_sets_dmif[i].wm_set_id;
1749                 }
1750
1751                 for (i = 0; i < wm_with_clock_ranges->num_wm_sets_mcif; i++) {
1752                         table->WatermarkRow[WM_SOCCLK][i].MinClock =
1753                                 cpu_to_le16((uint16_t)
1754                                 (wm_with_clock_ranges->wm_sets_mcif[i].wm_min_socclk_in_khz) /
1755                                 100);
1756                         table->WatermarkRow[WM_SOCCLK][i].MaxClock =
1757                                 cpu_to_le16((uint16_t)
1758                                 (wm_with_clock_ranges->wm_sets_mcif[i].wm_max_socclk_in_khz) /
1759                                 100);
1760                         table->WatermarkRow[WM_SOCCLK][i].MinUclk =
1761                                 cpu_to_le16((uint16_t)
1762                                 (wm_with_clock_ranges->wm_sets_mcif[i].wm_min_memclk_in_khz) /
1763                                 100);
1764                         table->WatermarkRow[WM_SOCCLK][i].MaxUclk =
1765                                 cpu_to_le16((uint16_t)
1766                                 (wm_with_clock_ranges->wm_sets_mcif[i].wm_max_memclk_in_khz) /
1767                                 100);
1768                         table->WatermarkRow[WM_SOCCLK][i].WmSetting = (uint8_t)
1769                                         wm_with_clock_ranges->wm_sets_mcif[i].wm_set_id;
1770                 }
1771                 data->water_marks_bitmap |= WaterMarksExist;
1772                 data->water_marks_bitmap &= ~WaterMarksLoaded;
1773         }
1774
1775         return result;
1776 }
1777
1778 static int vega12_force_clock_level(struct pp_hwmgr *hwmgr,
1779                 enum pp_clock_type type, uint32_t mask)
1780 {
1781         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1782
1783         if (hwmgr->request_dpm_level & (AMD_DPM_FORCED_LEVEL_AUTO |
1784                                 AMD_DPM_FORCED_LEVEL_LOW |
1785                                 AMD_DPM_FORCED_LEVEL_HIGH))
1786                 return -EINVAL;
1787
1788         switch (type) {
1789         case PP_SCLK:
1790                 data->smc_state_table.gfx_boot_level = mask ? (ffs(mask) - 1) : 0;
1791                 data->smc_state_table.gfx_max_level = mask ? (fls(mask) - 1) : 0;
1792
1793                 PP_ASSERT_WITH_CODE(!vega12_upload_dpm_min_level(hwmgr),
1794                         "Failed to upload boot level to lowest!",
1795                         return -EINVAL);
1796
1797                 PP_ASSERT_WITH_CODE(!vega12_upload_dpm_max_level(hwmgr),
1798                         "Failed to upload dpm max level to highest!",
1799                         return -EINVAL);
1800                 break;
1801
1802         case PP_MCLK:
1803                 data->smc_state_table.mem_boot_level = mask ? (ffs(mask) - 1) : 0;
1804                 data->smc_state_table.mem_max_level = mask ? (fls(mask) - 1) : 0;
1805
1806                 PP_ASSERT_WITH_CODE(!vega12_upload_dpm_min_level(hwmgr),
1807                         "Failed to upload boot level to lowest!",
1808                         return -EINVAL);
1809
1810                 PP_ASSERT_WITH_CODE(!vega12_upload_dpm_max_level(hwmgr),
1811                         "Failed to upload dpm max level to highest!",
1812                         return -EINVAL);
1813
1814                 break;
1815
1816         case PP_PCIE:
1817                 break;
1818
1819         default:
1820                 break;
1821         }
1822
1823         return 0;
1824 }
1825
1826 static int vega12_print_clock_levels(struct pp_hwmgr *hwmgr,
1827                 enum pp_clock_type type, char *buf)
1828 {
1829         int i, now, size = 0;
1830         struct pp_clock_levels_with_latency clocks;
1831
1832         switch (type) {
1833         case PP_SCLK:
1834                 PP_ASSERT_WITH_CODE(
1835                                 vega12_get_current_gfx_clk_freq(hwmgr, &now) == 0,
1836                                 "Attempt to get current gfx clk Failed!",
1837                                 return -1);
1838
1839                 PP_ASSERT_WITH_CODE(
1840                                 vega12_get_sclks(hwmgr, &clocks) == 0,
1841                                 "Attempt to get gfx clk levels Failed!",
1842                                 return -1);
1843                 for (i = 0; i < clocks.num_levels; i++)
1844                         size += sprintf(buf + size, "%d: %uMhz %s\n",
1845                                 i, clocks.data[i].clocks_in_khz / 100,
1846                                 (clocks.data[i].clocks_in_khz == now) ? "*" : "");
1847                 break;
1848
1849         case PP_MCLK:
1850                 PP_ASSERT_WITH_CODE(
1851                                 vega12_get_current_mclk_freq(hwmgr, &now) == 0,
1852                                 "Attempt to get current mclk freq Failed!",
1853                                 return -1);
1854
1855                 PP_ASSERT_WITH_CODE(
1856                                 vega12_get_memclocks(hwmgr, &clocks) == 0,
1857                                 "Attempt to get memory clk levels Failed!",
1858                                 return -1);
1859                 for (i = 0; i < clocks.num_levels; i++)
1860                         size += sprintf(buf + size, "%d: %uMhz %s\n",
1861                                 i, clocks.data[i].clocks_in_khz / 100,
1862                                 (clocks.data[i].clocks_in_khz == now) ? "*" : "");
1863                 break;
1864
1865         case PP_PCIE:
1866                 break;
1867
1868         default:
1869                 break;
1870         }
1871         return size;
1872 }
1873
1874 static int vega12_display_configuration_changed_task(struct pp_hwmgr *hwmgr)
1875 {
1876         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1877         int result = 0;
1878         Watermarks_t *wm_table = &(data->smc_state_table.water_marks_table);
1879
1880         if ((data->water_marks_bitmap & WaterMarksExist) &&
1881                         !(data->water_marks_bitmap & WaterMarksLoaded)) {
1882                 result = vega12_copy_table_to_smc(hwmgr,
1883                         (uint8_t *)wm_table, TABLE_WATERMARKS);
1884                 PP_ASSERT_WITH_CODE(result, "Failed to update WMTABLE!", return EINVAL);
1885                 data->water_marks_bitmap |= WaterMarksLoaded;
1886         }
1887
1888         if ((data->water_marks_bitmap & WaterMarksExist) &&
1889                 data->smu_features[GNLD_DPM_DCEFCLK].supported &&
1890                 data->smu_features[GNLD_DPM_SOCCLK].supported)
1891                 smum_send_msg_to_smc_with_parameter(hwmgr,
1892                         PPSMC_MSG_NumOfDisplays, hwmgr->display_config->num_display);
1893
1894         return result;
1895 }
1896
1897 int vega12_enable_disable_uvd_dpm(struct pp_hwmgr *hwmgr, bool enable)
1898 {
1899         struct vega12_hwmgr *data =
1900                         (struct vega12_hwmgr *)(hwmgr->backend);
1901
1902         if (data->smu_features[GNLD_DPM_UVD].supported) {
1903                 PP_ASSERT_WITH_CODE(!vega12_enable_smc_features(hwmgr,
1904                                 enable,
1905                                 data->smu_features[GNLD_DPM_UVD].smu_feature_bitmap),
1906                                 "Attempt to Enable/Disable DPM UVD Failed!",
1907                                 return -1);
1908                 data->smu_features[GNLD_DPM_UVD].enabled = enable;
1909         }
1910
1911         return 0;
1912 }
1913
1914 static void vega12_power_gate_vce(struct pp_hwmgr *hwmgr, bool bgate)
1915 {
1916         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1917
1918         data->vce_power_gated = bgate;
1919         vega12_enable_disable_vce_dpm(hwmgr, !bgate);
1920 }
1921
1922 static void vega12_power_gate_uvd(struct pp_hwmgr *hwmgr, bool bgate)
1923 {
1924         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1925
1926         data->uvd_power_gated = bgate;
1927         vega12_enable_disable_uvd_dpm(hwmgr, !bgate);
1928 }
1929
1930 static bool
1931 vega12_check_smc_update_required_for_display_configuration(struct pp_hwmgr *hwmgr)
1932 {
1933         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1934         bool is_update_required = false;
1935
1936         if (data->display_timing.num_existing_displays != hwmgr->display_config->num_display)
1937                 is_update_required = true;
1938
1939         if (data->registry_data.gfx_clk_deep_sleep_support) {
1940                 if (data->display_timing.min_clock_in_sr != hwmgr->display_config->min_core_set_clock_in_sr)
1941                         is_update_required = true;
1942         }
1943
1944         return is_update_required;
1945 }
1946
1947 static int vega12_disable_dpm_tasks(struct pp_hwmgr *hwmgr)
1948 {
1949         int tmp_result, result = 0;
1950
1951         tmp_result = vega12_disable_all_smu_features(hwmgr);
1952         PP_ASSERT_WITH_CODE((tmp_result == 0),
1953                         "Failed to disable all smu features!", result = tmp_result);
1954
1955         return result;
1956 }
1957
1958 static int vega12_power_off_asic(struct pp_hwmgr *hwmgr)
1959 {
1960         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1961         int result;
1962
1963         result = vega12_disable_dpm_tasks(hwmgr);
1964         PP_ASSERT_WITH_CODE((0 == result),
1965                         "[disable_dpm_tasks] Failed to disable DPM!",
1966                         );
1967         data->water_marks_bitmap &= ~(WaterMarksLoaded);
1968
1969         return result;
1970 }
1971
1972 #if 0
1973 static void vega12_find_min_clock_index(struct pp_hwmgr *hwmgr,
1974                 uint32_t *sclk_idx, uint32_t *mclk_idx,
1975                 uint32_t min_sclk, uint32_t min_mclk)
1976 {
1977         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
1978         struct vega12_dpm_table *dpm_table = &(data->dpm_table);
1979         uint32_t i;
1980
1981         for (i = 0; i < dpm_table->gfx_table.count; i++) {
1982                 if (dpm_table->gfx_table.dpm_levels[i].enabled &&
1983                         dpm_table->gfx_table.dpm_levels[i].value >= min_sclk) {
1984                         *sclk_idx = i;
1985                         break;
1986                 }
1987         }
1988
1989         for (i = 0; i < dpm_table->mem_table.count; i++) {
1990                 if (dpm_table->mem_table.dpm_levels[i].enabled &&
1991                         dpm_table->mem_table.dpm_levels[i].value >= min_mclk) {
1992                         *mclk_idx = i;
1993                         break;
1994                 }
1995         }
1996 }
1997 #endif
1998
1999 #if 0
2000 static int vega12_set_power_profile_state(struct pp_hwmgr *hwmgr,
2001                 struct amd_pp_profile *request)
2002 {
2003         return 0;
2004 }
2005
2006 static int vega12_get_sclk_od(struct pp_hwmgr *hwmgr)
2007 {
2008         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
2009         struct vega12_single_dpm_table *sclk_table = &(data->dpm_table.gfx_table);
2010         struct vega12_single_dpm_table *golden_sclk_table =
2011                         &(data->golden_dpm_table.gfx_table);
2012         int value;
2013
2014         value = (sclk_table->dpm_levels[sclk_table->count - 1].value -
2015                         golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) *
2016                         100 /
2017                         golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value;
2018
2019         return value;
2020 }
2021
2022 static int vega12_set_sclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
2023 {
2024         return 0;
2025 }
2026
2027 static int vega12_get_mclk_od(struct pp_hwmgr *hwmgr)
2028 {
2029         struct vega12_hwmgr *data = (struct vega12_hwmgr *)(hwmgr->backend);
2030         struct vega12_single_dpm_table *mclk_table = &(data->dpm_table.mem_table);
2031         struct vega12_single_dpm_table *golden_mclk_table =
2032                         &(data->golden_dpm_table.mem_table);
2033         int value;
2034
2035         value = (mclk_table->dpm_levels
2036                         [mclk_table->count - 1].value -
2037                         golden_mclk_table->dpm_levels
2038                         [golden_mclk_table->count - 1].value) *
2039                         100 /
2040                         golden_mclk_table->dpm_levels
2041                         [golden_mclk_table->count - 1].value;
2042
2043         return value;
2044 }
2045
2046 static int vega12_set_mclk_od(struct pp_hwmgr *hwmgr, uint32_t value)
2047 {
2048         return 0;
2049 }
2050 #endif
2051
2052 static int vega12_notify_cac_buffer_info(struct pp_hwmgr *hwmgr,
2053                                         uint32_t virtual_addr_low,
2054                                         uint32_t virtual_addr_hi,
2055                                         uint32_t mc_addr_low,
2056                                         uint32_t mc_addr_hi,
2057                                         uint32_t size)
2058 {
2059         smum_send_msg_to_smc_with_parameter(hwmgr,
2060                                         PPSMC_MSG_SetSystemVirtualDramAddrHigh,
2061                                         virtual_addr_hi);
2062         smum_send_msg_to_smc_with_parameter(hwmgr,
2063                                         PPSMC_MSG_SetSystemVirtualDramAddrLow,
2064                                         virtual_addr_low);
2065         smum_send_msg_to_smc_with_parameter(hwmgr,
2066                                         PPSMC_MSG_DramLogSetDramAddrHigh,
2067                                         mc_addr_hi);
2068
2069         smum_send_msg_to_smc_with_parameter(hwmgr,
2070                                         PPSMC_MSG_DramLogSetDramAddrLow,
2071                                         mc_addr_low);
2072
2073         smum_send_msg_to_smc_with_parameter(hwmgr,
2074                                         PPSMC_MSG_DramLogSetDramSize,
2075                                         size);
2076         return 0;
2077 }
2078
2079 static int vega12_get_thermal_temperature_range(struct pp_hwmgr *hwmgr,
2080                 struct PP_TemperatureRange *thermal_data)
2081 {
2082         struct phm_ppt_v3_information *pptable_information =
2083                 (struct phm_ppt_v3_information *)hwmgr->pptable;
2084
2085         memcpy(thermal_data, &SMU7ThermalWithDelayPolicy[0], sizeof(struct PP_TemperatureRange));
2086
2087         thermal_data->max = pptable_information->us_software_shutdown_temp *
2088                 PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
2089
2090         return 0;
2091 }
2092
2093 static const struct pp_hwmgr_func vega12_hwmgr_funcs = {
2094         .backend_init = vega12_hwmgr_backend_init,
2095         .backend_fini = vega12_hwmgr_backend_fini,
2096         .asic_setup = vega12_setup_asic_task,
2097         .dynamic_state_management_enable = vega12_enable_dpm_tasks,
2098         .dynamic_state_management_disable = vega12_disable_dpm_tasks,
2099         .patch_boot_state = vega12_patch_boot_state,
2100         .get_sclk = vega12_dpm_get_sclk,
2101         .get_mclk = vega12_dpm_get_mclk,
2102         .notify_smc_display_config_after_ps_adjustment =
2103                         vega12_notify_smc_display_config_after_ps_adjustment,
2104         .force_dpm_level = vega12_dpm_force_dpm_level,
2105         .stop_thermal_controller = vega12_thermal_stop_thermal_controller,
2106         .get_fan_speed_info = vega12_fan_ctrl_get_fan_speed_info,
2107         .reset_fan_speed_to_default =
2108                         vega12_fan_ctrl_reset_fan_speed_to_default,
2109         .get_fan_speed_rpm = vega12_fan_ctrl_get_fan_speed_rpm,
2110         .set_fan_control_mode = vega12_set_fan_control_mode,
2111         .get_fan_control_mode = vega12_get_fan_control_mode,
2112         .read_sensor = vega12_read_sensor,
2113         .get_dal_power_level = vega12_get_dal_power_level,
2114         .get_clock_by_type_with_latency = vega12_get_clock_by_type_with_latency,
2115         .get_clock_by_type_with_voltage = vega12_get_clock_by_type_with_voltage,
2116         .set_watermarks_for_clocks_ranges = vega12_set_watermarks_for_clocks_ranges,
2117         .display_clock_voltage_request = vega12_display_clock_voltage_request,
2118         .force_clock_level = vega12_force_clock_level,
2119         .print_clock_levels = vega12_print_clock_levels,
2120         .display_config_changed = vega12_display_configuration_changed_task,
2121         .powergate_uvd = vega12_power_gate_uvd,
2122         .powergate_vce = vega12_power_gate_vce,
2123         .check_smc_update_required_for_display_configuration =
2124                         vega12_check_smc_update_required_for_display_configuration,
2125         .power_off_asic = vega12_power_off_asic,
2126         .disable_smc_firmware_ctf = vega12_thermal_disable_alert,
2127 #if 0
2128         .set_power_profile_state = vega12_set_power_profile_state,
2129         .get_sclk_od = vega12_get_sclk_od,
2130         .set_sclk_od = vega12_set_sclk_od,
2131         .get_mclk_od = vega12_get_mclk_od,
2132         .set_mclk_od = vega12_set_mclk_od,
2133 #endif
2134         .notify_cac_buffer_info = vega12_notify_cac_buffer_info,
2135         .get_thermal_temperature_range = vega12_get_thermal_temperature_range,
2136         .register_irq_handlers = smu9_register_irq_handlers,
2137         .start_thermal_controller = vega12_start_thermal_controller,
2138 };
2139
2140 int vega12_hwmgr_init(struct pp_hwmgr *hwmgr)
2141 {
2142         hwmgr->hwmgr_func = &vega12_hwmgr_funcs;
2143         hwmgr->pptable_func = &vega12_pptable_funcs;
2144
2145         return 0;
2146 }