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