]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c
drm/amd/powerplay: use the flag to decide whether send gfxoff smc message
[linux.git] / drivers / gpu / drm / amd / powerplay / hwmgr / smu10_hwmgr.c
1 /*
2  * Copyright 2015 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 #include "pp_debug.h"
24 #include <linux/types.h>
25 #include <linux/kernel.h>
26 #include <linux/slab.h>
27 #include "atom-types.h"
28 #include "atombios.h"
29 #include "processpptables.h"
30 #include "cgs_common.h"
31 #include "smumgr.h"
32 #include "hwmgr.h"
33 #include "hardwaremanager.h"
34 #include "rv_ppsmc.h"
35 #include "smu10_hwmgr.h"
36 #include "power_state.h"
37 #include "soc15_common.h"
38
39 #define SMU10_MAX_DEEPSLEEP_DIVIDER_ID     5
40 #define SMU10_MINIMUM_ENGINE_CLOCK         800   /* 8Mhz, the low boundary of engine clock allowed on this chip */
41 #define SCLK_MIN_DIV_INTV_SHIFT         12
42 #define SMU10_DISPCLK_BYPASS_THRESHOLD     10000 /* 100Mhz */
43 #define SMC_RAM_END                     0x40000
44
45 #define mmPWR_MISC_CNTL_STATUS                                  0x0183
46 #define mmPWR_MISC_CNTL_STATUS_BASE_IDX                         0
47 #define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN__SHIFT        0x0
48 #define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS__SHIFT          0x1
49 #define PWR_MISC_CNTL_STATUS__PWR_GFX_RLC_CGPG_EN_MASK          0x00000001L
50 #define PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK            0x00000006L
51
52 static const unsigned long SMU10_Magic = (unsigned long) PHM_Rv_Magic;
53
54
55 static int smu10_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
56                 struct pp_display_clock_request *clock_req);
57
58
59 static struct smu10_power_state *cast_smu10_ps(struct pp_hw_power_state *hw_ps)
60 {
61         if (SMU10_Magic != hw_ps->magic)
62                 return NULL;
63
64         return (struct smu10_power_state *)hw_ps;
65 }
66
67 static const struct smu10_power_state *cast_const_smu10_ps(
68                                 const struct pp_hw_power_state *hw_ps)
69 {
70         if (SMU10_Magic != hw_ps->magic)
71                 return NULL;
72
73         return (struct smu10_power_state *)hw_ps;
74 }
75
76 static int smu10_initialize_dpm_defaults(struct pp_hwmgr *hwmgr)
77 {
78         struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
79
80         smu10_data->dce_slow_sclk_threshold = 30000;
81         smu10_data->thermal_auto_throttling_treshold = 0;
82         smu10_data->is_nb_dpm_enabled = 1;
83         smu10_data->dpm_flags = 1;
84         smu10_data->need_min_deep_sleep_dcefclk = true;
85         smu10_data->num_active_display = 0;
86         smu10_data->deep_sleep_dcefclk = 0;
87
88         if (hwmgr->feature_mask & PP_GFXOFF_MASK)
89                 smu10_data->gfx_off_controled_by_driver = true;
90         else
91                 smu10_data->gfx_off_controled_by_driver = false;
92
93         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
94                                         PHM_PlatformCaps_SclkDeepSleep);
95
96         phm_cap_unset(hwmgr->platform_descriptor.platformCaps,
97                                 PHM_PlatformCaps_SclkThrottleLowNotification);
98
99         phm_cap_set(hwmgr->platform_descriptor.platformCaps,
100                                 PHM_PlatformCaps_PowerPlaySupport);
101         return 0;
102 }
103
104 static int smu10_construct_max_power_limits_table(struct pp_hwmgr *hwmgr,
105                         struct phm_clock_and_voltage_limits *table)
106 {
107         return 0;
108 }
109
110 static int smu10_init_dynamic_state_adjustment_rule_settings(
111                                                         struct pp_hwmgr *hwmgr)
112 {
113         uint32_t table_size =
114                 sizeof(struct phm_clock_voltage_dependency_table) +
115                 (7 * sizeof(struct phm_clock_voltage_dependency_record));
116
117         struct phm_clock_voltage_dependency_table *table_clk_vlt =
118                                         kzalloc(table_size, GFP_KERNEL);
119
120         if (NULL == table_clk_vlt) {
121                 pr_err("Can not allocate memory!\n");
122                 return -ENOMEM;
123         }
124
125         table_clk_vlt->count = 8;
126         table_clk_vlt->entries[0].clk = PP_DAL_POWERLEVEL_0;
127         table_clk_vlt->entries[0].v = 0;
128         table_clk_vlt->entries[1].clk = PP_DAL_POWERLEVEL_1;
129         table_clk_vlt->entries[1].v = 1;
130         table_clk_vlt->entries[2].clk = PP_DAL_POWERLEVEL_2;
131         table_clk_vlt->entries[2].v = 2;
132         table_clk_vlt->entries[3].clk = PP_DAL_POWERLEVEL_3;
133         table_clk_vlt->entries[3].v = 3;
134         table_clk_vlt->entries[4].clk = PP_DAL_POWERLEVEL_4;
135         table_clk_vlt->entries[4].v = 4;
136         table_clk_vlt->entries[5].clk = PP_DAL_POWERLEVEL_5;
137         table_clk_vlt->entries[5].v = 5;
138         table_clk_vlt->entries[6].clk = PP_DAL_POWERLEVEL_6;
139         table_clk_vlt->entries[6].v = 6;
140         table_clk_vlt->entries[7].clk = PP_DAL_POWERLEVEL_7;
141         table_clk_vlt->entries[7].v = 7;
142         hwmgr->dyn_state.vddc_dep_on_dal_pwrl = table_clk_vlt;
143
144         return 0;
145 }
146
147 static int smu10_get_system_info_data(struct pp_hwmgr *hwmgr)
148 {
149         struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)hwmgr->backend;
150
151         smu10_data->sys_info.htc_hyst_lmt = 5;
152         smu10_data->sys_info.htc_tmp_lmt = 203;
153
154         if (smu10_data->thermal_auto_throttling_treshold == 0)
155                  smu10_data->thermal_auto_throttling_treshold = 203;
156
157         smu10_construct_max_power_limits_table (hwmgr,
158                                     &hwmgr->dyn_state.max_clock_voltage_on_ac);
159
160         smu10_init_dynamic_state_adjustment_rule_settings(hwmgr);
161
162         return 0;
163 }
164
165 static int smu10_construct_boot_state(struct pp_hwmgr *hwmgr)
166 {
167         return 0;
168 }
169
170 static int smu10_set_clock_limit(struct pp_hwmgr *hwmgr, const void *input)
171 {
172         struct PP_Clocks clocks = {0};
173         struct pp_display_clock_request clock_req;
174
175         clocks.dcefClock = hwmgr->display_config->min_dcef_set_clk;
176         clock_req.clock_type = amd_pp_dcf_clock;
177         clock_req.clock_freq_in_khz = clocks.dcefClock * 10;
178
179         PP_ASSERT_WITH_CODE(!smu10_display_clock_voltage_request(hwmgr, &clock_req),
180                                 "Attempt to set DCF Clock Failed!", return -EINVAL);
181
182         return 0;
183 }
184
185 static int smu10_set_deep_sleep_dcefclk(struct pp_hwmgr *hwmgr, uint32_t clock)
186 {
187         struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
188
189         if (smu10_data->need_min_deep_sleep_dcefclk && smu10_data->deep_sleep_dcefclk != clock/100) {
190                 smu10_data->deep_sleep_dcefclk = clock/100;
191                 smum_send_msg_to_smc_with_parameter(hwmgr,
192                                         PPSMC_MSG_SetMinDeepSleepDcefclk,
193                                         smu10_data->deep_sleep_dcefclk);
194         }
195         return 0;
196 }
197
198 static int smu10_set_active_display_count(struct pp_hwmgr *hwmgr, uint32_t count)
199 {
200         struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
201
202         if (smu10_data->num_active_display != count) {
203                 smu10_data->num_active_display = count;
204                 smum_send_msg_to_smc_with_parameter(hwmgr,
205                                 PPSMC_MSG_SetDisplayCount,
206                                 smu10_data->num_active_display);
207         }
208
209         return 0;
210 }
211
212 static int smu10_set_power_state_tasks(struct pp_hwmgr *hwmgr, const void *input)
213 {
214         return smu10_set_clock_limit(hwmgr, input);
215 }
216
217 static int smu10_init_power_gate_state(struct pp_hwmgr *hwmgr)
218 {
219         struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
220         struct amdgpu_device *adev = hwmgr->adev;
221
222         smu10_data->vcn_power_gated = true;
223         smu10_data->isp_tileA_power_gated = true;
224         smu10_data->isp_tileB_power_gated = true;
225
226         if (adev->pg_flags & AMD_PG_SUPPORT_GFX_PG)
227                 return smum_send_msg_to_smc_with_parameter(hwmgr,
228                                                            PPSMC_MSG_SetGfxCGPG,
229                                                            true);
230         else
231                 return 0;
232 }
233
234
235 static int smu10_setup_asic_task(struct pp_hwmgr *hwmgr)
236 {
237         return smu10_init_power_gate_state(hwmgr);
238 }
239
240 static int smu10_reset_cc6_data(struct pp_hwmgr *hwmgr)
241 {
242         struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
243
244         smu10_data->separation_time = 0;
245         smu10_data->cc6_disable = false;
246         smu10_data->pstate_disable = false;
247         smu10_data->cc6_setting_changed = false;
248
249         return 0;
250 }
251
252 static int smu10_power_off_asic(struct pp_hwmgr *hwmgr)
253 {
254         return smu10_reset_cc6_data(hwmgr);
255 }
256
257 static bool smu10_is_gfx_on(struct pp_hwmgr *hwmgr)
258 {
259         uint32_t reg;
260         struct amdgpu_device *adev = hwmgr->adev;
261
262         reg = RREG32_SOC15(PWR, 0, mmPWR_MISC_CNTL_STATUS);
263         if ((reg & PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS_MASK) ==
264             (0x2 << PWR_MISC_CNTL_STATUS__PWR_GFXOFF_STATUS__SHIFT))
265                 return true;
266
267         return false;
268 }
269
270 static int smu10_disable_gfx_off(struct pp_hwmgr *hwmgr)
271 {
272         struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
273
274         if (smu10_data->gfx_off_controled_by_driver) {
275                 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_DisableGfxOff);
276
277                 /* confirm gfx is back to "on" state */
278                 while (!smu10_is_gfx_on(hwmgr))
279                         msleep(1);
280         }
281
282         return 0;
283 }
284
285 static int smu10_disable_dpm_tasks(struct pp_hwmgr *hwmgr)
286 {
287         return smu10_disable_gfx_off(hwmgr);
288 }
289
290 static int smu10_enable_gfx_off(struct pp_hwmgr *hwmgr)
291 {
292         struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
293
294         if (smu10_data->gfx_off_controled_by_driver)
295                 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_EnableGfxOff);
296
297         return 0;
298 }
299
300 static int smu10_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
301 {
302         return smu10_enable_gfx_off(hwmgr);
303 }
304
305 static int smu10_gfx_off_control(struct pp_hwmgr *hwmgr, bool enable)
306 {
307         if (enable)
308                 return smu10_enable_gfx_off(hwmgr);
309         else
310                 return smu10_disable_gfx_off(hwmgr);
311 }
312
313 static int smu10_apply_state_adjust_rules(struct pp_hwmgr *hwmgr,
314                                 struct pp_power_state  *prequest_ps,
315                         const struct pp_power_state *pcurrent_ps)
316 {
317         return 0;
318 }
319
320 /* temporary hardcoded clock voltage breakdown tables */
321 static const DpmClock_t VddDcfClk[]= {
322         { 300, 2600},
323         { 600, 3200},
324         { 600, 3600},
325 };
326
327 static const DpmClock_t VddSocClk[]= {
328         { 478, 2600},
329         { 722, 3200},
330         { 722, 3600},
331 };
332
333 static const DpmClock_t VddFClk[]= {
334         { 400, 2600},
335         {1200, 3200},
336         {1200, 3600},
337 };
338
339 static const DpmClock_t VddDispClk[]= {
340         { 435, 2600},
341         { 661, 3200},
342         {1086, 3600},
343 };
344
345 static const DpmClock_t VddDppClk[]= {
346         { 435, 2600},
347         { 661, 3200},
348         { 661, 3600},
349 };
350
351 static const DpmClock_t VddPhyClk[]= {
352         { 540, 2600},
353         { 810, 3200},
354         { 810, 3600},
355 };
356
357 static int smu10_get_clock_voltage_dependency_table(struct pp_hwmgr *hwmgr,
358                         struct smu10_voltage_dependency_table **pptable,
359                         uint32_t num_entry, const DpmClock_t *pclk_dependency_table)
360 {
361         uint32_t table_size, i;
362         struct smu10_voltage_dependency_table *ptable;
363
364         table_size = sizeof(uint32_t) + sizeof(struct smu10_voltage_dependency_table) * num_entry;
365         ptable = kzalloc(table_size, GFP_KERNEL);
366
367         if (NULL == ptable)
368                 return -ENOMEM;
369
370         ptable->count = num_entry;
371
372         for (i = 0; i < ptable->count; i++) {
373                 ptable->entries[i].clk         = pclk_dependency_table->Freq * 100;
374                 ptable->entries[i].vol         = pclk_dependency_table->Vol;
375                 pclk_dependency_table++;
376         }
377
378         *pptable = ptable;
379
380         return 0;
381 }
382
383
384 static int smu10_populate_clock_table(struct pp_hwmgr *hwmgr)
385 {
386         int result;
387
388         struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
389         DpmClocks_t  *table = &(smu10_data->clock_table);
390         struct smu10_clock_voltage_information *pinfo = &(smu10_data->clock_vol_info);
391
392         result = smum_smc_table_manager(hwmgr, (uint8_t *)table, SMU10_CLOCKTABLE, true);
393
394         PP_ASSERT_WITH_CODE((0 == result),
395                         "Attempt to copy clock table from smc failed",
396                         return result);
397
398         if (0 == result && table->DcefClocks[0].Freq != 0) {
399                 smu10_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_dcefclk,
400                                                 NUM_DCEFCLK_DPM_LEVELS,
401                                                 &smu10_data->clock_table.DcefClocks[0]);
402                 smu10_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_socclk,
403                                                 NUM_SOCCLK_DPM_LEVELS,
404                                                 &smu10_data->clock_table.SocClocks[0]);
405                 smu10_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_fclk,
406                                                 NUM_FCLK_DPM_LEVELS,
407                                                 &smu10_data->clock_table.FClocks[0]);
408                 smu10_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_mclk,
409                                                 NUM_MEMCLK_DPM_LEVELS,
410                                                 &smu10_data->clock_table.MemClocks[0]);
411         } else {
412                 smu10_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_dcefclk,
413                                                 ARRAY_SIZE(VddDcfClk),
414                                                 &VddDcfClk[0]);
415                 smu10_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_socclk,
416                                                 ARRAY_SIZE(VddSocClk),
417                                                 &VddSocClk[0]);
418                 smu10_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_fclk,
419                                                 ARRAY_SIZE(VddFClk),
420                                                 &VddFClk[0]);
421         }
422         smu10_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_dispclk,
423                                         ARRAY_SIZE(VddDispClk),
424                                         &VddDispClk[0]);
425         smu10_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_dppclk,
426                                         ARRAY_SIZE(VddDppClk), &VddDppClk[0]);
427         smu10_get_clock_voltage_dependency_table(hwmgr, &pinfo->vdd_dep_on_phyclk,
428                                         ARRAY_SIZE(VddPhyClk), &VddPhyClk[0]);
429
430         smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMinGfxclkFrequency);
431         result = smum_get_argument(hwmgr);
432         smu10_data->gfx_min_freq_limit = result * 100;
433
434         smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetMaxGfxclkFrequency);
435         result = smum_get_argument(hwmgr);
436         smu10_data->gfx_max_freq_limit = result * 100;
437
438         return 0;
439 }
440
441 static int smu10_hwmgr_backend_init(struct pp_hwmgr *hwmgr)
442 {
443         int result = 0;
444         struct smu10_hwmgr *data;
445
446         data = kzalloc(sizeof(struct smu10_hwmgr), GFP_KERNEL);
447         if (data == NULL)
448                 return -ENOMEM;
449
450         hwmgr->backend = data;
451
452         result = smu10_initialize_dpm_defaults(hwmgr);
453         if (result != 0) {
454                 pr_err("smu10_initialize_dpm_defaults failed\n");
455                 return result;
456         }
457
458         smu10_populate_clock_table(hwmgr);
459
460         result = smu10_get_system_info_data(hwmgr);
461         if (result != 0) {
462                 pr_err("smu10_get_system_info_data failed\n");
463                 return result;
464         }
465
466         smu10_construct_boot_state(hwmgr);
467
468         hwmgr->platform_descriptor.hardwareActivityPerformanceLevels =
469                                                 SMU10_MAX_HARDWARE_POWERLEVELS;
470
471         hwmgr->platform_descriptor.hardwarePerformanceLevels =
472                                                 SMU10_MAX_HARDWARE_POWERLEVELS;
473
474         hwmgr->platform_descriptor.vbiosInterruptId = 0;
475
476         hwmgr->platform_descriptor.clockStep.engineClock = 500;
477
478         hwmgr->platform_descriptor.clockStep.memoryClock = 500;
479
480         hwmgr->platform_descriptor.minimumClocksReductionPercentage = 50;
481
482         hwmgr->pstate_sclk = SMU10_UMD_PSTATE_GFXCLK;
483         hwmgr->pstate_mclk = SMU10_UMD_PSTATE_FCLK;
484
485         return result;
486 }
487
488 static int smu10_hwmgr_backend_fini(struct pp_hwmgr *hwmgr)
489 {
490         struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
491         struct smu10_clock_voltage_information *pinfo = &(smu10_data->clock_vol_info);
492
493         kfree(pinfo->vdd_dep_on_dcefclk);
494         pinfo->vdd_dep_on_dcefclk = NULL;
495         kfree(pinfo->vdd_dep_on_socclk);
496         pinfo->vdd_dep_on_socclk = NULL;
497         kfree(pinfo->vdd_dep_on_fclk);
498         pinfo->vdd_dep_on_fclk = NULL;
499         kfree(pinfo->vdd_dep_on_dispclk);
500         pinfo->vdd_dep_on_dispclk = NULL;
501         kfree(pinfo->vdd_dep_on_dppclk);
502         pinfo->vdd_dep_on_dppclk = NULL;
503         kfree(pinfo->vdd_dep_on_phyclk);
504         pinfo->vdd_dep_on_phyclk = NULL;
505
506         kfree(hwmgr->dyn_state.vddc_dep_on_dal_pwrl);
507         hwmgr->dyn_state.vddc_dep_on_dal_pwrl = NULL;
508
509         kfree(hwmgr->backend);
510         hwmgr->backend = NULL;
511
512         return 0;
513 }
514
515 static int smu10_dpm_force_dpm_level(struct pp_hwmgr *hwmgr,
516                                 enum amd_dpm_forced_level level)
517 {
518         if (hwmgr->smu_version < 0x1E3700) {
519                 pr_info("smu firmware version too old, can not set dpm level\n");
520                 return 0;
521         }
522
523         switch (level) {
524         case AMD_DPM_FORCED_LEVEL_HIGH:
525         case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
526                 smum_send_msg_to_smc_with_parameter(hwmgr,
527                                                 PPSMC_MSG_SetHardMinGfxClk,
528                                                 SMU10_UMD_PSTATE_PEAK_GFXCLK);
529                 smum_send_msg_to_smc_with_parameter(hwmgr,
530                                                 PPSMC_MSG_SetHardMinFclkByFreq,
531                                                 SMU10_UMD_PSTATE_PEAK_FCLK);
532                 smum_send_msg_to_smc_with_parameter(hwmgr,
533                                                 PPSMC_MSG_SetHardMinSocclkByFreq,
534                                                 SMU10_UMD_PSTATE_PEAK_SOCCLK);
535                 smum_send_msg_to_smc_with_parameter(hwmgr,
536                                                 PPSMC_MSG_SetHardMinVcn,
537                                                 SMU10_UMD_PSTATE_VCE);
538
539                 smum_send_msg_to_smc_with_parameter(hwmgr,
540                                                 PPSMC_MSG_SetSoftMaxGfxClk,
541                                                 SMU10_UMD_PSTATE_PEAK_GFXCLK);
542                 smum_send_msg_to_smc_with_parameter(hwmgr,
543                                                 PPSMC_MSG_SetSoftMaxFclkByFreq,
544                                                 SMU10_UMD_PSTATE_PEAK_FCLK);
545                 smum_send_msg_to_smc_with_parameter(hwmgr,
546                                                 PPSMC_MSG_SetSoftMaxSocclkByFreq,
547                                                 SMU10_UMD_PSTATE_PEAK_SOCCLK);
548                 smum_send_msg_to_smc_with_parameter(hwmgr,
549                                                 PPSMC_MSG_SetSoftMaxVcn,
550                                                 SMU10_UMD_PSTATE_VCE);
551                 break;
552         case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
553                 smum_send_msg_to_smc_with_parameter(hwmgr,
554                                                 PPSMC_MSG_SetHardMinGfxClk,
555                                                 SMU10_UMD_PSTATE_MIN_GFXCLK);
556                 smum_send_msg_to_smc_with_parameter(hwmgr,
557                                                 PPSMC_MSG_SetSoftMaxGfxClk,
558                                                 SMU10_UMD_PSTATE_MIN_GFXCLK);
559                 break;
560         case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
561                 smum_send_msg_to_smc_with_parameter(hwmgr,
562                                                 PPSMC_MSG_SetHardMinFclkByFreq,
563                                                 SMU10_UMD_PSTATE_MIN_FCLK);
564                 smum_send_msg_to_smc_with_parameter(hwmgr,
565                                                 PPSMC_MSG_SetSoftMaxFclkByFreq,
566                                                 SMU10_UMD_PSTATE_MIN_FCLK);
567                 break;
568         case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
569                 smum_send_msg_to_smc_with_parameter(hwmgr,
570                                                 PPSMC_MSG_SetHardMinGfxClk,
571                                                 SMU10_UMD_PSTATE_GFXCLK);
572                 smum_send_msg_to_smc_with_parameter(hwmgr,
573                                                 PPSMC_MSG_SetHardMinFclkByFreq,
574                                                 SMU10_UMD_PSTATE_FCLK);
575                 smum_send_msg_to_smc_with_parameter(hwmgr,
576                                                 PPSMC_MSG_SetHardMinSocclkByFreq,
577                                                 SMU10_UMD_PSTATE_SOCCLK);
578                 smum_send_msg_to_smc_with_parameter(hwmgr,
579                                                 PPSMC_MSG_SetHardMinVcn,
580                                                 SMU10_UMD_PSTATE_VCE);
581
582                 smum_send_msg_to_smc_with_parameter(hwmgr,
583                                                 PPSMC_MSG_SetSoftMaxGfxClk,
584                                                 SMU10_UMD_PSTATE_GFXCLK);
585                 smum_send_msg_to_smc_with_parameter(hwmgr,
586                                                 PPSMC_MSG_SetSoftMaxFclkByFreq,
587                                                 SMU10_UMD_PSTATE_FCLK);
588                 smum_send_msg_to_smc_with_parameter(hwmgr,
589                                                 PPSMC_MSG_SetSoftMaxSocclkByFreq,
590                                                 SMU10_UMD_PSTATE_SOCCLK);
591                 smum_send_msg_to_smc_with_parameter(hwmgr,
592                                                 PPSMC_MSG_SetSoftMaxVcn,
593                                                 SMU10_UMD_PSTATE_VCE);
594                 break;
595         case AMD_DPM_FORCED_LEVEL_AUTO:
596                 smum_send_msg_to_smc_with_parameter(hwmgr,
597                                                 PPSMC_MSG_SetHardMinGfxClk,
598                                                 SMU10_UMD_PSTATE_MIN_GFXCLK);
599                 smum_send_msg_to_smc_with_parameter(hwmgr,
600                                                 PPSMC_MSG_SetHardMinFclkByFreq,
601                                                 SMU10_UMD_PSTATE_MIN_FCLK);
602                 smum_send_msg_to_smc_with_parameter(hwmgr,
603                                                 PPSMC_MSG_SetHardMinSocclkByFreq,
604                                                 SMU10_UMD_PSTATE_MIN_SOCCLK);
605                 smum_send_msg_to_smc_with_parameter(hwmgr,
606                                                 PPSMC_MSG_SetHardMinVcn,
607                                                 SMU10_UMD_PSTATE_MIN_VCE);
608
609                 smum_send_msg_to_smc_with_parameter(hwmgr,
610                                                 PPSMC_MSG_SetSoftMaxGfxClk,
611                                                 SMU10_UMD_PSTATE_PEAK_GFXCLK);
612                 smum_send_msg_to_smc_with_parameter(hwmgr,
613                                                 PPSMC_MSG_SetSoftMaxFclkByFreq,
614                                                 SMU10_UMD_PSTATE_PEAK_FCLK);
615                 smum_send_msg_to_smc_with_parameter(hwmgr,
616                                                 PPSMC_MSG_SetSoftMaxSocclkByFreq,
617                                                 SMU10_UMD_PSTATE_PEAK_SOCCLK);
618                 smum_send_msg_to_smc_with_parameter(hwmgr,
619                                                 PPSMC_MSG_SetSoftMaxVcn,
620                                                 SMU10_UMD_PSTATE_VCE);
621                 break;
622         case AMD_DPM_FORCED_LEVEL_LOW:
623                 smum_send_msg_to_smc_with_parameter(hwmgr,
624                                                 PPSMC_MSG_SetHardMinGfxClk,
625                                                 SMU10_UMD_PSTATE_MIN_GFXCLK);
626                 smum_send_msg_to_smc_with_parameter(hwmgr,
627                                                 PPSMC_MSG_SetSoftMaxGfxClk,
628                                                 SMU10_UMD_PSTATE_MIN_GFXCLK);
629                 smum_send_msg_to_smc_with_parameter(hwmgr,
630                                                 PPSMC_MSG_SetHardMinFclkByFreq,
631                                                 SMU10_UMD_PSTATE_MIN_FCLK);
632                 smum_send_msg_to_smc_with_parameter(hwmgr,
633                                                 PPSMC_MSG_SetSoftMaxFclkByFreq,
634                                                 SMU10_UMD_PSTATE_MIN_FCLK);
635                 break;
636         case AMD_DPM_FORCED_LEVEL_MANUAL:
637         case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
638         default:
639                 break;
640         }
641         return 0;
642 }
643
644 static uint32_t smu10_dpm_get_mclk(struct pp_hwmgr *hwmgr, bool low)
645 {
646         struct smu10_hwmgr *data;
647
648         if (hwmgr == NULL)
649                 return -EINVAL;
650
651         data = (struct smu10_hwmgr *)(hwmgr->backend);
652
653         if (low)
654                 return data->clock_vol_info.vdd_dep_on_fclk->entries[0].clk;
655         else
656                 return data->clock_vol_info.vdd_dep_on_fclk->entries[
657                         data->clock_vol_info.vdd_dep_on_fclk->count - 1].clk;
658 }
659
660 static uint32_t smu10_dpm_get_sclk(struct pp_hwmgr *hwmgr, bool low)
661 {
662         struct smu10_hwmgr *data;
663
664         if (hwmgr == NULL)
665                 return -EINVAL;
666
667         data = (struct smu10_hwmgr *)(hwmgr->backend);
668
669         if (low)
670                 return data->gfx_min_freq_limit;
671         else
672                 return data->gfx_max_freq_limit;
673 }
674
675 static int smu10_dpm_patch_boot_state(struct pp_hwmgr *hwmgr,
676                                         struct pp_hw_power_state *hw_ps)
677 {
678         return 0;
679 }
680
681 static int smu10_dpm_get_pp_table_entry_callback(
682                                                      struct pp_hwmgr *hwmgr,
683                                            struct pp_hw_power_state *hw_ps,
684                                                           unsigned int index,
685                                                      const void *clock_info)
686 {
687         struct smu10_power_state *smu10_ps = cast_smu10_ps(hw_ps);
688
689         smu10_ps->levels[index].engine_clock = 0;
690
691         smu10_ps->levels[index].vddc_index = 0;
692         smu10_ps->level = index + 1;
693
694         if (phm_cap_enabled(hwmgr->platform_descriptor.platformCaps, PHM_PlatformCaps_SclkDeepSleep)) {
695                 smu10_ps->levels[index].ds_divider_index = 5;
696                 smu10_ps->levels[index].ss_divider_index = 5;
697         }
698
699         return 0;
700 }
701
702 static int smu10_dpm_get_num_of_pp_table_entries(struct pp_hwmgr *hwmgr)
703 {
704         int result;
705         unsigned long ret = 0;
706
707         result = pp_tables_get_num_of_entries(hwmgr, &ret);
708
709         return result ? 0 : ret;
710 }
711
712 static int smu10_dpm_get_pp_table_entry(struct pp_hwmgr *hwmgr,
713                     unsigned long entry, struct pp_power_state *ps)
714 {
715         int result;
716         struct smu10_power_state *smu10_ps;
717
718         ps->hardware.magic = SMU10_Magic;
719
720         smu10_ps = cast_smu10_ps(&(ps->hardware));
721
722         result = pp_tables_get_entry(hwmgr, entry, ps,
723                         smu10_dpm_get_pp_table_entry_callback);
724
725         smu10_ps->uvd_clocks.vclk = ps->uvd_clocks.VCLK;
726         smu10_ps->uvd_clocks.dclk = ps->uvd_clocks.DCLK;
727
728         return result;
729 }
730
731 static int smu10_get_power_state_size(struct pp_hwmgr *hwmgr)
732 {
733         return sizeof(struct smu10_power_state);
734 }
735
736 static int smu10_set_cpu_power_state(struct pp_hwmgr *hwmgr)
737 {
738         return 0;
739 }
740
741
742 static int smu10_store_cc6_data(struct pp_hwmgr *hwmgr, uint32_t separation_time,
743                         bool cc6_disable, bool pstate_disable, bool pstate_switch_disable)
744 {
745         struct smu10_hwmgr *data = (struct smu10_hwmgr *)(hwmgr->backend);
746
747         if (separation_time != data->separation_time ||
748                         cc6_disable != data->cc6_disable ||
749                         pstate_disable != data->pstate_disable) {
750                 data->separation_time = separation_time;
751                 data->cc6_disable = cc6_disable;
752                 data->pstate_disable = pstate_disable;
753                 data->cc6_setting_changed = true;
754         }
755         return 0;
756 }
757
758 static int smu10_get_dal_power_level(struct pp_hwmgr *hwmgr,
759                 struct amd_pp_simple_clock_info *info)
760 {
761         return -EINVAL;
762 }
763
764 static int smu10_force_clock_level(struct pp_hwmgr *hwmgr,
765                 enum pp_clock_type type, uint32_t mask)
766 {
767         return 0;
768 }
769
770 static int smu10_print_clock_levels(struct pp_hwmgr *hwmgr,
771                 enum pp_clock_type type, char *buf)
772 {
773         struct smu10_hwmgr *data = (struct smu10_hwmgr *)(hwmgr->backend);
774         struct smu10_voltage_dependency_table *mclk_table =
775                         data->clock_vol_info.vdd_dep_on_fclk;
776         int i, now, size = 0;
777
778         switch (type) {
779         case PP_SCLK:
780                 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency);
781                 now = smum_get_argument(hwmgr);
782
783                 size += sprintf(buf + size, "0: %uMhz %s\n",
784                                 data->gfx_min_freq_limit / 100,
785                                 ((data->gfx_min_freq_limit / 100)
786                                  == now) ? "*" : "");
787                 size += sprintf(buf + size, "1: %uMhz %s\n",
788                                 data->gfx_max_freq_limit / 100,
789                                 ((data->gfx_max_freq_limit / 100)
790                                  == now) ? "*" : "");
791                 break;
792         case PP_MCLK:
793                 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency);
794                 now = smum_get_argument(hwmgr);
795
796                 for (i = 0; i < mclk_table->count; i++)
797                         size += sprintf(buf + size, "%d: %uMhz %s\n",
798                                         i,
799                                         mclk_table->entries[i].clk / 100,
800                                         ((mclk_table->entries[i].clk / 100)
801                                          == now) ? "*" : "");
802                 break;
803         default:
804                 break;
805         }
806
807         return size;
808 }
809
810 static int smu10_get_performance_level(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *state,
811                                 PHM_PerformanceLevelDesignation designation, uint32_t index,
812                                 PHM_PerformanceLevel *level)
813 {
814         struct smu10_hwmgr *data;
815
816         if (level == NULL || hwmgr == NULL || state == NULL)
817                 return -EINVAL;
818
819         data = (struct smu10_hwmgr *)(hwmgr->backend);
820
821         if (index == 0) {
822                 level->memory_clock = data->clock_vol_info.vdd_dep_on_fclk->entries[0].clk;
823                 level->coreClock = data->gfx_min_freq_limit;
824         } else {
825                 level->memory_clock = data->clock_vol_info.vdd_dep_on_fclk->entries[
826                         data->clock_vol_info.vdd_dep_on_fclk->count - 1].clk;
827                 level->coreClock = data->gfx_max_freq_limit;
828         }
829
830         level->nonLocalMemoryFreq = 0;
831         level->nonLocalMemoryWidth = 0;
832
833         return 0;
834 }
835
836 static int smu10_get_current_shallow_sleep_clocks(struct pp_hwmgr *hwmgr,
837         const struct pp_hw_power_state *state, struct pp_clock_info *clock_info)
838 {
839         const struct smu10_power_state *ps = cast_const_smu10_ps(state);
840
841         clock_info->min_eng_clk = ps->levels[0].engine_clock / (1 << (ps->levels[0].ss_divider_index));
842         clock_info->max_eng_clk = ps->levels[ps->level - 1].engine_clock / (1 << (ps->levels[ps->level - 1].ss_divider_index));
843
844         return 0;
845 }
846
847 #define MEM_FREQ_LOW_LATENCY        25000
848 #define MEM_FREQ_HIGH_LATENCY       80000
849 #define MEM_LATENCY_HIGH            245
850 #define MEM_LATENCY_LOW             35
851 #define MEM_LATENCY_ERR             0xFFFF
852
853
854 static uint32_t smu10_get_mem_latency(struct pp_hwmgr *hwmgr,
855                 uint32_t clock)
856 {
857         if (clock >= MEM_FREQ_LOW_LATENCY &&
858                         clock < MEM_FREQ_HIGH_LATENCY)
859                 return MEM_LATENCY_HIGH;
860         else if (clock >= MEM_FREQ_HIGH_LATENCY)
861                 return MEM_LATENCY_LOW;
862         else
863                 return MEM_LATENCY_ERR;
864 }
865
866 static int smu10_get_clock_by_type_with_latency(struct pp_hwmgr *hwmgr,
867                 enum amd_pp_clock_type type,
868                 struct pp_clock_levels_with_latency *clocks)
869 {
870         uint32_t i;
871         struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
872         struct smu10_clock_voltage_information *pinfo = &(smu10_data->clock_vol_info);
873         struct smu10_voltage_dependency_table *pclk_vol_table;
874         bool latency_required = false;
875
876         if (pinfo == NULL)
877                 return -EINVAL;
878
879         switch (type) {
880         case amd_pp_mem_clock:
881                 pclk_vol_table = pinfo->vdd_dep_on_mclk;
882                 latency_required = true;
883                 break;
884         case amd_pp_f_clock:
885                 pclk_vol_table = pinfo->vdd_dep_on_fclk;
886                 latency_required = true;
887                 break;
888         case amd_pp_dcf_clock:
889                 pclk_vol_table = pinfo->vdd_dep_on_dcefclk;
890                 break;
891         case amd_pp_disp_clock:
892                 pclk_vol_table = pinfo->vdd_dep_on_dispclk;
893                 break;
894         case amd_pp_phy_clock:
895                 pclk_vol_table = pinfo->vdd_dep_on_phyclk;
896                 break;
897         case amd_pp_dpp_clock:
898                 pclk_vol_table = pinfo->vdd_dep_on_dppclk;
899         default:
900                 return -EINVAL;
901         }
902
903         if (pclk_vol_table == NULL || pclk_vol_table->count == 0)
904                 return -EINVAL;
905
906         clocks->num_levels = 0;
907         for (i = 0; i < pclk_vol_table->count; i++) {
908                 clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk;
909                 clocks->data[i].latency_in_us = latency_required ?
910                                                 smu10_get_mem_latency(hwmgr,
911                                                 pclk_vol_table->entries[i].clk) :
912                                                 0;
913                 clocks->num_levels++;
914         }
915
916         return 0;
917 }
918
919 static int smu10_get_clock_by_type_with_voltage(struct pp_hwmgr *hwmgr,
920                 enum amd_pp_clock_type type,
921                 struct pp_clock_levels_with_voltage *clocks)
922 {
923         uint32_t i;
924         struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
925         struct smu10_clock_voltage_information *pinfo = &(smu10_data->clock_vol_info);
926         struct smu10_voltage_dependency_table *pclk_vol_table = NULL;
927
928         if (pinfo == NULL)
929                 return -EINVAL;
930
931         switch (type) {
932         case amd_pp_mem_clock:
933                 pclk_vol_table = pinfo->vdd_dep_on_mclk;
934                 break;
935         case amd_pp_f_clock:
936                 pclk_vol_table = pinfo->vdd_dep_on_fclk;
937                 break;
938         case amd_pp_dcf_clock:
939                 pclk_vol_table = pinfo->vdd_dep_on_dcefclk;
940                 break;
941         case amd_pp_soc_clock:
942                 pclk_vol_table = pinfo->vdd_dep_on_socclk;
943                 break;
944         default:
945                 return -EINVAL;
946         }
947
948         if (pclk_vol_table == NULL || pclk_vol_table->count == 0)
949                 return -EINVAL;
950
951         clocks->num_levels = 0;
952         for (i = 0; i < pclk_vol_table->count; i++) {
953                 clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk;
954                 clocks->data[i].voltage_in_mv = pclk_vol_table->entries[i].vol;
955                 clocks->num_levels++;
956         }
957
958         return 0;
959 }
960
961 static int smu10_display_clock_voltage_request(struct pp_hwmgr *hwmgr,
962                 struct pp_display_clock_request *clock_req)
963 {
964         struct smu10_hwmgr *smu10_data = (struct smu10_hwmgr *)(hwmgr->backend);
965         enum amd_pp_clock_type clk_type = clock_req->clock_type;
966         uint32_t clk_freq = clock_req->clock_freq_in_khz / 1000;
967         PPSMC_Msg        msg;
968
969         switch (clk_type) {
970         case amd_pp_dcf_clock:
971                 if (clk_freq == smu10_data->dcf_actual_hard_min_freq)
972                         return 0;
973                 msg =  PPSMC_MSG_SetHardMinDcefclkByFreq;
974                 smu10_data->dcf_actual_hard_min_freq = clk_freq;
975                 break;
976         case amd_pp_soc_clock:
977                  msg = PPSMC_MSG_SetHardMinSocclkByFreq;
978                 break;
979         case amd_pp_f_clock:
980                 if (clk_freq == smu10_data->f_actual_hard_min_freq)
981                         return 0;
982                 smu10_data->f_actual_hard_min_freq = clk_freq;
983                 msg = PPSMC_MSG_SetHardMinFclkByFreq;
984                 break;
985         default:
986                 pr_info("[DisplayClockVoltageRequest]Invalid Clock Type!");
987                 return -EINVAL;
988         }
989
990         smum_send_msg_to_smc_with_parameter(hwmgr, msg, clk_freq);
991
992         return 0;
993 }
994
995 static int smu10_get_max_high_clocks(struct pp_hwmgr *hwmgr, struct amd_pp_simple_clock_info *clocks)
996 {
997         clocks->engine_max_clock = 80000; /* driver can't get engine clock, temp hard code to 800MHz */
998         return 0;
999 }
1000
1001 static int smu10_thermal_get_temperature(struct pp_hwmgr *hwmgr)
1002 {
1003         struct amdgpu_device *adev = hwmgr->adev;
1004         uint32_t reg_value = RREG32_SOC15(THM, 0, mmTHM_TCON_CUR_TMP);
1005         int cur_temp =
1006                 (reg_value & THM_TCON_CUR_TMP__CUR_TEMP_MASK) >> THM_TCON_CUR_TMP__CUR_TEMP__SHIFT;
1007
1008         if (cur_temp & THM_TCON_CUR_TMP__CUR_TEMP_RANGE_SEL_MASK)
1009                 cur_temp = ((cur_temp / 8) - 49) * PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
1010         else
1011                 cur_temp = (cur_temp / 8) * PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
1012
1013         return cur_temp;
1014 }
1015
1016 static int smu10_read_sensor(struct pp_hwmgr *hwmgr, int idx,
1017                           void *value, int *size)
1018 {
1019         uint32_t sclk, mclk;
1020         int ret = 0;
1021
1022         switch (idx) {
1023         case AMDGPU_PP_SENSOR_GFX_SCLK:
1024                 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetGfxclkFrequency);
1025                 sclk = smum_get_argument(hwmgr);
1026                         /* in units of 10KHZ */
1027                 *((uint32_t *)value) = sclk * 100;
1028                 *size = 4;
1029                 break;
1030         case AMDGPU_PP_SENSOR_GFX_MCLK:
1031                 smum_send_msg_to_smc(hwmgr, PPSMC_MSG_GetFclkFrequency);
1032                 mclk = smum_get_argument(hwmgr);
1033                         /* in units of 10KHZ */
1034                 *((uint32_t *)value) = mclk * 100;
1035                 *size = 4;
1036                 break;
1037         case AMDGPU_PP_SENSOR_GPU_TEMP:
1038                 *((uint32_t *)value) = smu10_thermal_get_temperature(hwmgr);
1039                 break;
1040         default:
1041                 ret = -EINVAL;
1042                 break;
1043         }
1044
1045         return ret;
1046 }
1047
1048 static int smu10_set_watermarks_for_clocks_ranges(struct pp_hwmgr *hwmgr,
1049                 struct pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges)
1050 {
1051         struct smu10_hwmgr *data = hwmgr->backend;
1052         Watermarks_t *table = &(data->water_marks_table);
1053         int result = 0;
1054
1055         smu_set_watermarks_for_clocks_ranges(table,wm_with_clock_ranges);
1056         smum_smc_table_manager(hwmgr, (uint8_t *)table, (uint16_t)SMU10_WMTABLE, false);
1057         data->water_marks_exist = true;
1058         return result;
1059 }
1060 static int smu10_set_mmhub_powergating_by_smu(struct pp_hwmgr *hwmgr)
1061 {
1062         return smum_send_msg_to_smc(hwmgr, PPSMC_MSG_PowerGateMmHub);
1063 }
1064
1065 static const struct pp_hwmgr_func smu10_hwmgr_funcs = {
1066         .backend_init = smu10_hwmgr_backend_init,
1067         .backend_fini = smu10_hwmgr_backend_fini,
1068         .asic_setup = NULL,
1069         .apply_state_adjust_rules = smu10_apply_state_adjust_rules,
1070         .force_dpm_level = smu10_dpm_force_dpm_level,
1071         .get_power_state_size = smu10_get_power_state_size,
1072         .powerdown_uvd = NULL,
1073         .powergate_uvd = NULL,
1074         .powergate_vce = NULL,
1075         .get_mclk = smu10_dpm_get_mclk,
1076         .get_sclk = smu10_dpm_get_sclk,
1077         .patch_boot_state = smu10_dpm_patch_boot_state,
1078         .get_pp_table_entry = smu10_dpm_get_pp_table_entry,
1079         .get_num_of_pp_table_entries = smu10_dpm_get_num_of_pp_table_entries,
1080         .set_cpu_power_state = smu10_set_cpu_power_state,
1081         .store_cc6_data = smu10_store_cc6_data,
1082         .force_clock_level = smu10_force_clock_level,
1083         .print_clock_levels = smu10_print_clock_levels,
1084         .get_dal_power_level = smu10_get_dal_power_level,
1085         .get_performance_level = smu10_get_performance_level,
1086         .get_current_shallow_sleep_clocks = smu10_get_current_shallow_sleep_clocks,
1087         .get_clock_by_type_with_latency = smu10_get_clock_by_type_with_latency,
1088         .get_clock_by_type_with_voltage = smu10_get_clock_by_type_with_voltage,
1089         .set_watermarks_for_clocks_ranges = smu10_set_watermarks_for_clocks_ranges,
1090         .get_max_high_clocks = smu10_get_max_high_clocks,
1091         .read_sensor = smu10_read_sensor,
1092         .set_active_display_count = smu10_set_active_display_count,
1093         .set_deep_sleep_dcefclk = smu10_set_deep_sleep_dcefclk,
1094         .dynamic_state_management_enable = smu10_enable_dpm_tasks,
1095         .power_off_asic = smu10_power_off_asic,
1096         .asic_setup = smu10_setup_asic_task,
1097         .power_state_set = smu10_set_power_state_tasks,
1098         .dynamic_state_management_disable = smu10_disable_dpm_tasks,
1099         .set_mmhub_powergating_by_smu = smu10_set_mmhub_powergating_by_smu,
1100         .gfx_off_control = smu10_gfx_off_control,
1101 };
1102
1103 int smu10_init_function_pointers(struct pp_hwmgr *hwmgr)
1104 {
1105         hwmgr->hwmgr_func = &smu10_hwmgr_funcs;
1106         hwmgr->pptable_func = &pptable_funcs;
1107         return 0;
1108 }