]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/gpu/drm/amd/powerplay/arcturus_ppt.c
5f911f09231143f38769c142e8c27bbc9e40a321
[linux.git] / drivers / gpu / drm / amd / powerplay / arcturus_ppt.c
1 /*
2  * Copyright 2019 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 "pp_debug.h"
25 #include <linux/firmware.h>
26 #include "amdgpu.h"
27 #include "amdgpu_smu.h"
28 #include "atomfirmware.h"
29 #include "amdgpu_atomfirmware.h"
30 #include "smu_v11_0.h"
31 #include "smu11_driver_if_arcturus.h"
32 #include "soc15_common.h"
33 #include "atom.h"
34 #include "power_state.h"
35 #include "arcturus_ppt.h"
36 #include "smu_v11_0_pptable.h"
37 #include "arcturus_ppsmc.h"
38 #include "nbio/nbio_7_4_sh_mask.h"
39
40 #define CTF_OFFSET_EDGE                 5
41 #define CTF_OFFSET_HOTSPOT              5
42 #define CTF_OFFSET_HBM                  5
43
44 #define MSG_MAP(msg, index) \
45         [SMU_MSG_##msg] = {1, (index)}
46
47 #define SMU_FEATURES_LOW_MASK        0x00000000FFFFFFFF
48 #define SMU_FEATURES_LOW_SHIFT       0
49 #define SMU_FEATURES_HIGH_MASK       0xFFFFFFFF00000000
50 #define SMU_FEATURES_HIGH_SHIFT      32
51
52 static struct smu_11_0_cmn2aisc_mapping arcturus_message_map[SMU_MSG_MAX_COUNT] = {
53         MSG_MAP(TestMessage,                         PPSMC_MSG_TestMessage),
54         MSG_MAP(GetSmuVersion,                       PPSMC_MSG_GetSmuVersion),
55         MSG_MAP(GetDriverIfVersion,                  PPSMC_MSG_GetDriverIfVersion),
56         MSG_MAP(SetAllowedFeaturesMaskLow,           PPSMC_MSG_SetAllowedFeaturesMaskLow),
57         MSG_MAP(SetAllowedFeaturesMaskHigh,          PPSMC_MSG_SetAllowedFeaturesMaskHigh),
58         MSG_MAP(EnableAllSmuFeatures,                PPSMC_MSG_EnableAllSmuFeatures),
59         MSG_MAP(DisableAllSmuFeatures,               PPSMC_MSG_DisableAllSmuFeatures),
60         MSG_MAP(EnableSmuFeaturesLow,                PPSMC_MSG_EnableSmuFeaturesLow),
61         MSG_MAP(EnableSmuFeaturesHigh,               PPSMC_MSG_EnableSmuFeaturesHigh),
62         MSG_MAP(DisableSmuFeaturesLow,               PPSMC_MSG_DisableSmuFeaturesLow),
63         MSG_MAP(DisableSmuFeaturesHigh,              PPSMC_MSG_DisableSmuFeaturesHigh),
64         MSG_MAP(GetEnabledSmuFeaturesLow,            PPSMC_MSG_GetEnabledSmuFeaturesLow),
65         MSG_MAP(GetEnabledSmuFeaturesHigh,           PPSMC_MSG_GetEnabledSmuFeaturesHigh),
66         MSG_MAP(SetDriverDramAddrHigh,               PPSMC_MSG_SetDriverDramAddrHigh),
67         MSG_MAP(SetDriverDramAddrLow,                PPSMC_MSG_SetDriverDramAddrLow),
68         MSG_MAP(SetToolsDramAddrHigh,                PPSMC_MSG_SetToolsDramAddrHigh),
69         MSG_MAP(SetToolsDramAddrLow,                 PPSMC_MSG_SetToolsDramAddrLow),
70         MSG_MAP(TransferTableSmu2Dram,               PPSMC_MSG_TransferTableSmu2Dram),
71         MSG_MAP(TransferTableDram2Smu,               PPSMC_MSG_TransferTableDram2Smu),
72         MSG_MAP(UseDefaultPPTable,                   PPSMC_MSG_UseDefaultPPTable),
73         MSG_MAP(UseBackupPPTable,                    PPSMC_MSG_UseBackupPPTable),
74         MSG_MAP(SetSystemVirtualDramAddrHigh,        PPSMC_MSG_SetSystemVirtualDramAddrHigh),
75         MSG_MAP(SetSystemVirtualDramAddrLow,         PPSMC_MSG_SetSystemVirtualDramAddrLow),
76         MSG_MAP(EnterBaco,                           PPSMC_MSG_EnterBaco),
77         MSG_MAP(ExitBaco,                            PPSMC_MSG_ExitBaco),
78         MSG_MAP(ArmD3,                               PPSMC_MSG_ArmD3),
79         MSG_MAP(SetSoftMinByFreq,                    PPSMC_MSG_SetSoftMinByFreq),
80         MSG_MAP(SetSoftMaxByFreq,                    PPSMC_MSG_SetSoftMaxByFreq),
81         MSG_MAP(SetHardMinByFreq,                    PPSMC_MSG_SetHardMinByFreq),
82         MSG_MAP(SetHardMaxByFreq,                    PPSMC_MSG_SetHardMaxByFreq),
83         MSG_MAP(GetMinDpmFreq,                       PPSMC_MSG_GetMinDpmFreq),
84         MSG_MAP(GetMaxDpmFreq,                       PPSMC_MSG_GetMaxDpmFreq),
85         MSG_MAP(GetDpmFreqByIndex,                   PPSMC_MSG_GetDpmFreqByIndex),
86         MSG_MAP(SetWorkloadMask,                     PPSMC_MSG_SetWorkloadMask),
87         MSG_MAP(SetDfSwitchType,                     PPSMC_MSG_SetDfSwitchType),
88         MSG_MAP(GetVoltageByDpm,                     PPSMC_MSG_GetVoltageByDpm),
89         MSG_MAP(GetVoltageByDpmOverdrive,            PPSMC_MSG_GetVoltageByDpmOverdrive),
90         MSG_MAP(SetPptLimit,                         PPSMC_MSG_SetPptLimit),
91         MSG_MAP(GetPptLimit,                         PPSMC_MSG_GetPptLimit),
92         MSG_MAP(PowerUpVcn0,                         PPSMC_MSG_PowerUpVcn0),
93         MSG_MAP(PowerDownVcn0,                       PPSMC_MSG_PowerDownVcn0),
94         MSG_MAP(PowerUpVcn1,                         PPSMC_MSG_PowerUpVcn1),
95         MSG_MAP(PowerDownVcn1,                       PPSMC_MSG_PowerDownVcn1),
96         MSG_MAP(PrepareMp1ForUnload,                 PPSMC_MSG_PrepareMp1ForUnload),
97         MSG_MAP(PrepareMp1ForReset,                  PPSMC_MSG_PrepareMp1ForReset),
98         MSG_MAP(PrepareMp1ForShutdown,               PPSMC_MSG_PrepareMp1ForShutdown),
99         MSG_MAP(SoftReset,                           PPSMC_MSG_SoftReset),
100         MSG_MAP(RunAfllBtc,                          PPSMC_MSG_RunAfllBtc),
101         MSG_MAP(RunGfxDcBtc,                         PPSMC_MSG_RunGfxDcBtc),
102         MSG_MAP(RunSocDcBtc,                         PPSMC_MSG_RunSocDcBtc),
103         MSG_MAP(DramLogSetDramAddrHigh,              PPSMC_MSG_DramLogSetDramAddrHigh),
104         MSG_MAP(DramLogSetDramAddrLow,               PPSMC_MSG_DramLogSetDramAddrLow),
105         MSG_MAP(DramLogSetDramSize,                  PPSMC_MSG_DramLogSetDramSize),
106         MSG_MAP(GetDebugData,                        PPSMC_MSG_GetDebugData),
107         MSG_MAP(WaflTest,                            PPSMC_MSG_WaflTest),
108         MSG_MAP(SetXgmiMode,                         PPSMC_MSG_SetXgmiMode),
109         MSG_MAP(SetMemoryChannelEnable,              PPSMC_MSG_SetMemoryChannelEnable),
110 };
111
112 static struct smu_11_0_cmn2aisc_mapping arcturus_clk_map[SMU_CLK_COUNT] = {
113         CLK_MAP(GFXCLK, PPCLK_GFXCLK),
114         CLK_MAP(SCLK,   PPCLK_GFXCLK),
115         CLK_MAP(SOCCLK, PPCLK_SOCCLK),
116         CLK_MAP(FCLK, PPCLK_FCLK),
117         CLK_MAP(UCLK, PPCLK_UCLK),
118         CLK_MAP(MCLK, PPCLK_UCLK),
119         CLK_MAP(DCLK, PPCLK_DCLK),
120         CLK_MAP(VCLK, PPCLK_VCLK),
121 };
122
123 static struct smu_11_0_cmn2aisc_mapping arcturus_feature_mask_map[SMU_FEATURE_COUNT] = {
124         FEA_MAP(DPM_PREFETCHER),
125         FEA_MAP(DPM_GFXCLK),
126         FEA_MAP(DPM_UCLK),
127         FEA_MAP(DPM_SOCCLK),
128         FEA_MAP(DPM_MP0CLK),
129         FEA_MAP(DS_GFXCLK),
130         FEA_MAP(DS_SOCCLK),
131         FEA_MAP(DS_LCLK),
132         FEA_MAP(DS_UCLK),
133         FEA_MAP(GFX_ULV),
134         FEA_MAP(RSMU_SMN_CG),
135         FEA_MAP(PPT),
136         FEA_MAP(TDC),
137         FEA_MAP(APCC_PLUS),
138         FEA_MAP(VR0HOT),
139         FEA_MAP(VR1HOT),
140         FEA_MAP(FW_CTF),
141         FEA_MAP(FAN_CONTROL),
142         FEA_MAP(THERMAL),
143         FEA_MAP(OUT_OF_BAND_MONITOR),
144         FEA_MAP(TEMP_DEPENDENT_VMIN),
145 };
146
147 static struct smu_11_0_cmn2aisc_mapping arcturus_table_map[SMU_TABLE_COUNT] = {
148         TAB_MAP(PPTABLE),
149         TAB_MAP(AVFS),
150         TAB_MAP(AVFS_PSM_DEBUG),
151         TAB_MAP(AVFS_FUSE_OVERRIDE),
152         TAB_MAP(PMSTATUSLOG),
153         TAB_MAP(SMU_METRICS),
154         TAB_MAP(DRIVER_SMU_CONFIG),
155         TAB_MAP(OVERDRIVE),
156 };
157
158 static struct smu_11_0_cmn2aisc_mapping arcturus_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
159         PWR_MAP(AC),
160         PWR_MAP(DC),
161 };
162
163 static struct smu_11_0_cmn2aisc_mapping arcturus_workload_map[PP_SMC_POWER_PROFILE_COUNT] = {
164         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT,       WORKLOAD_PPLIB_DEFAULT_BIT),
165         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING,          WORKLOAD_PPLIB_POWER_SAVING_BIT),
166         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO,                WORKLOAD_PPLIB_VIDEO_BIT),
167         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE,              WORKLOAD_PPLIB_CUSTOM_BIT),
168         WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM,               WORKLOAD_PPLIB_CUSTOM_BIT),
169 };
170
171 static int arcturus_get_smu_msg_index(struct smu_context *smc, uint32_t index)
172 {
173         struct smu_11_0_cmn2aisc_mapping mapping;
174
175         if (index >= SMU_MSG_MAX_COUNT)
176                 return -EINVAL;
177
178         mapping = arcturus_message_map[index];
179         if (!(mapping.valid_mapping)) {
180                 pr_warn("Unsupported SMU message: %d\n", index);
181                 return -EINVAL;
182         }
183
184         return mapping.map_to;
185 }
186
187 static int arcturus_get_smu_clk_index(struct smu_context *smc, uint32_t index)
188 {
189         struct smu_11_0_cmn2aisc_mapping mapping;
190
191         if (index >= SMU_CLK_COUNT)
192                 return -EINVAL;
193
194         mapping = arcturus_clk_map[index];
195         if (!(mapping.valid_mapping)) {
196                 pr_warn("Unsupported SMU clk: %d\n", index);
197                 return -EINVAL;
198         }
199
200         return mapping.map_to;
201 }
202
203 static int arcturus_get_smu_feature_index(struct smu_context *smc, uint32_t index)
204 {
205         struct smu_11_0_cmn2aisc_mapping mapping;
206
207         if (index >= SMU_FEATURE_COUNT)
208                 return -EINVAL;
209
210         mapping = arcturus_feature_mask_map[index];
211         if (!(mapping.valid_mapping)) {
212                 pr_warn("Unsupported SMU feature: %d\n", index);
213                 return -EINVAL;
214         }
215
216         return mapping.map_to;
217 }
218
219 static int arcturus_get_smu_table_index(struct smu_context *smc, uint32_t index)
220 {
221         struct smu_11_0_cmn2aisc_mapping mapping;
222
223         if (index >= SMU_TABLE_COUNT)
224                 return -EINVAL;
225
226         mapping = arcturus_table_map[index];
227         if (!(mapping.valid_mapping)) {
228                 pr_warn("Unsupported SMU table: %d\n", index);
229                 return -EINVAL;
230         }
231
232         return mapping.map_to;
233 }
234
235 static int arcturus_get_pwr_src_index(struct smu_context *smc, uint32_t index)
236 {
237         struct smu_11_0_cmn2aisc_mapping mapping;
238
239         if (index >= SMU_POWER_SOURCE_COUNT)
240                 return -EINVAL;
241
242         mapping = arcturus_pwr_src_map[index];
243         if (!(mapping.valid_mapping)) {
244                 pr_warn("Unsupported SMU power source: %d\n", index);
245                 return -EINVAL;
246         }
247
248         return mapping.map_to;
249 }
250
251
252 static int arcturus_get_workload_type(struct smu_context *smu, enum PP_SMC_POWER_PROFILE profile)
253 {
254         struct smu_11_0_cmn2aisc_mapping mapping;
255
256         if (profile > PP_SMC_POWER_PROFILE_CUSTOM)
257                 return -EINVAL;
258
259         mapping = arcturus_workload_map[profile];
260         if (!(mapping.valid_mapping)) {
261                 pr_warn("Unsupported SMU power source: %d\n", profile);
262                 return -EINVAL;
263         }
264
265         return mapping.map_to;
266 }
267
268 static int arcturus_tables_init(struct smu_context *smu, struct smu_table *tables)
269 {
270         struct smu_table_context *smu_table = &smu->smu_table;
271
272         SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t),
273                        PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
274
275         SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU11_TOOL_SIZE,
276                        PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
277
278         SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
279                        PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
280
281         smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
282         if (!smu_table->metrics_table)
283                 return -ENOMEM;
284         smu_table->metrics_time = 0;
285
286         return 0;
287 }
288
289 static int arcturus_allocate_dpm_context(struct smu_context *smu)
290 {
291         struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
292
293         if (smu_dpm->dpm_context)
294                 return -EINVAL;
295
296         smu_dpm->dpm_context = kzalloc(sizeof(struct arcturus_dpm_table),
297                                        GFP_KERNEL);
298         if (!smu_dpm->dpm_context)
299                 return -ENOMEM;
300
301         if (smu_dpm->golden_dpm_context)
302                 return -EINVAL;
303
304         smu_dpm->golden_dpm_context = kzalloc(sizeof(struct arcturus_dpm_table),
305                                               GFP_KERNEL);
306         if (!smu_dpm->golden_dpm_context)
307                 return -ENOMEM;
308
309         smu_dpm->dpm_context_size = sizeof(struct arcturus_dpm_table);
310
311         smu_dpm->dpm_current_power_state = kzalloc(sizeof(struct smu_power_state),
312                                        GFP_KERNEL);
313         if (!smu_dpm->dpm_current_power_state)
314                 return -ENOMEM;
315
316         smu_dpm->dpm_request_power_state = kzalloc(sizeof(struct smu_power_state),
317                                        GFP_KERNEL);
318         if (!smu_dpm->dpm_request_power_state)
319                 return -ENOMEM;
320
321         return 0;
322 }
323
324 #define FEATURE_MASK(feature) (1ULL << feature)
325 static int
326 arcturus_get_allowed_feature_mask(struct smu_context *smu,
327                                   uint32_t *feature_mask, uint32_t num)
328 {
329         if (num > 2)
330                 return -EINVAL;
331
332         memset(feature_mask, 0, sizeof(uint32_t) * num);
333
334         *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_PREFETCHER_BIT);
335
336         return 0;
337 }
338
339 static int
340 arcturus_set_single_dpm_table(struct smu_context *smu,
341                             struct arcturus_single_dpm_table *single_dpm_table,
342                             PPCLK_e clk_id)
343 {
344         int ret = 0;
345         uint32_t i, num_of_levels = 0, clk;
346
347         ret = smu_send_smc_msg_with_param(smu,
348                         SMU_MSG_GetDpmFreqByIndex,
349                         (clk_id << 16 | 0xFF));
350         if (ret) {
351                 pr_err("[%s] failed to get dpm levels!\n", __func__);
352                 return ret;
353         }
354
355         smu_read_smc_arg(smu, &num_of_levels);
356         if (!num_of_levels) {
357                 pr_err("[%s] number of clk levels is invalid!\n", __func__);
358                 return -EINVAL;
359         }
360
361         single_dpm_table->count = num_of_levels;
362         for (i = 0; i < num_of_levels; i++) {
363                 ret = smu_send_smc_msg_with_param(smu,
364                                 SMU_MSG_GetDpmFreqByIndex,
365                                 (clk_id << 16 | i));
366                 if (ret) {
367                         pr_err("[%s] failed to get dpm freq by index!\n", __func__);
368                         return ret;
369                 }
370                 smu_read_smc_arg(smu, &clk);
371                 if (!clk) {
372                         pr_err("[%s] clk value is invalid!\n", __func__);
373                         return -EINVAL;
374                 }
375                 single_dpm_table->dpm_levels[i].value = clk;
376                 single_dpm_table->dpm_levels[i].enabled = true;
377         }
378         return 0;
379 }
380
381 static void arcturus_init_single_dpm_state(struct arcturus_dpm_state *dpm_state)
382 {
383         dpm_state->soft_min_level = 0x0;
384         dpm_state->soft_max_level = 0xffff;
385         dpm_state->hard_min_level = 0x0;
386         dpm_state->hard_max_level = 0xffff;
387 }
388
389 static int arcturus_set_default_dpm_table(struct smu_context *smu)
390 {
391         int ret;
392
393         struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
394         struct arcturus_dpm_table *dpm_table = NULL;
395         struct arcturus_single_dpm_table *single_dpm_table;
396
397         dpm_table = smu_dpm->dpm_context;
398
399         /* socclk */
400         single_dpm_table = &(dpm_table->soc_table);
401         if (smu_feature_is_enabled(smu, FEATURE_DPM_SOCCLK_BIT)) {
402                 ret = arcturus_set_single_dpm_table(smu, single_dpm_table,
403                                                   PPCLK_SOCCLK);
404                 if (ret) {
405                         pr_err("[%s] failed to get socclk dpm levels!\n", __func__);
406                         return ret;
407                 }
408         } else {
409                 single_dpm_table->count = 1;
410                 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.socclk / 100;
411         }
412         arcturus_init_single_dpm_state(&(single_dpm_table->dpm_state));
413
414         /* gfxclk */
415         single_dpm_table = &(dpm_table->gfx_table);
416         if (smu_feature_is_enabled(smu, FEATURE_DPM_GFXCLK_BIT)) {
417                 ret = arcturus_set_single_dpm_table(smu, single_dpm_table,
418                                                   PPCLK_GFXCLK);
419                 if (ret) {
420                         pr_err("[SetupDefaultDpmTable] failed to get gfxclk dpm levels!");
421                         return ret;
422                 }
423         } else {
424                 single_dpm_table->count = 1;
425                 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
426         }
427         arcturus_init_single_dpm_state(&(single_dpm_table->dpm_state));
428
429         /* memclk */
430         single_dpm_table = &(dpm_table->mem_table);
431         if (smu_feature_is_enabled(smu, FEATURE_DPM_UCLK_BIT)) {
432                 ret = arcturus_set_single_dpm_table(smu, single_dpm_table,
433                                                   PPCLK_UCLK);
434                 if (ret) {
435                         pr_err("[SetupDefaultDpmTable] failed to get memclk dpm levels!");
436                         return ret;
437                 }
438         } else {
439                 single_dpm_table->count = 1;
440                 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.uclk / 100;
441         }
442         arcturus_init_single_dpm_state(&(single_dpm_table->dpm_state));
443
444         /* fclk */
445         single_dpm_table = &(dpm_table->fclk_table);
446         if (smu_feature_is_enabled(smu,FEATURE_DPM_FCLK_BIT)) {
447                 ret = arcturus_set_single_dpm_table(smu, single_dpm_table,
448                                                   PPCLK_FCLK);
449                 if (ret) {
450                         pr_err("[SetupDefaultDpmTable] failed to get fclk dpm levels!");
451                         return ret;
452                 }
453         } else {
454                 single_dpm_table->count = 0;
455         }
456         arcturus_init_single_dpm_state(&(single_dpm_table->dpm_state));
457
458         memcpy(smu_dpm->golden_dpm_context, dpm_table,
459                sizeof(struct arcturus_dpm_table));
460
461         return 0;
462 }
463
464 static int arcturus_check_powerplay_table(struct smu_context *smu)
465 {
466         return 0;
467 }
468
469 static int arcturus_store_powerplay_table(struct smu_context *smu)
470 {
471         struct smu_11_0_powerplay_table *powerplay_table = NULL;
472         struct smu_table_context *table_context = &smu->smu_table;
473         int ret = 0;
474
475         if (!table_context->power_play_table)
476                 return -EINVAL;
477
478         powerplay_table = table_context->power_play_table;
479
480         memcpy(table_context->driver_pptable, &powerplay_table->smc_pptable,
481                sizeof(PPTable_t));
482
483         table_context->thermal_controller_type = powerplay_table->thermal_controller_type;
484
485         return ret;
486 }
487
488 static int arcturus_append_powerplay_table(struct smu_context *smu)
489 {
490         struct smu_table_context *table_context = &smu->smu_table;
491         PPTable_t *smc_pptable = table_context->driver_pptable;
492         struct atom_smc_dpm_info_v4_6 *smc_dpm_table;
493         int index, ret;
494
495         index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
496                                            smc_dpm_info);
497
498         ret = smu_get_atom_data_table(smu, index, NULL, NULL, NULL,
499                                       (uint8_t **)&smc_dpm_table);
500         if (ret)
501                 return ret;
502
503         pr_info("smc_dpm_info table revision(format.content): %d.%d\n",
504                         smc_dpm_table->table_header.format_revision,
505                         smc_dpm_table->table_header.content_revision);
506
507         if ((smc_dpm_table->table_header.format_revision == 4) &&
508             (smc_dpm_table->table_header.content_revision == 6))
509                 memcpy(&smc_pptable->MaxVoltageStepGfx,
510                        &smc_dpm_table->maxvoltagestepgfx,
511                        sizeof(*smc_dpm_table) - offsetof(struct atom_smc_dpm_info_v4_6, maxvoltagestepgfx));
512
513         return 0;
514 }
515
516 static int arcturus_run_btc_afll(struct smu_context *smu)
517 {
518         return smu_send_smc_msg(smu, SMU_MSG_RunAfllBtc);
519 }
520
521 static int arcturus_populate_umd_state_clk(struct smu_context *smu)
522 {
523         struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
524         struct arcturus_dpm_table *dpm_table = NULL;
525         struct arcturus_single_dpm_table *gfx_table = NULL;
526         struct arcturus_single_dpm_table *mem_table = NULL;
527
528         dpm_table = smu_dpm->dpm_context;
529         gfx_table = &(dpm_table->gfx_table);
530         mem_table = &(dpm_table->mem_table);
531
532         smu->pstate_sclk = gfx_table->dpm_levels[0].value;
533         smu->pstate_mclk = mem_table->dpm_levels[0].value;
534
535         if (gfx_table->count > ARCTURUS_UMD_PSTATE_GFXCLK_LEVEL &&
536             mem_table->count > ARCTURUS_UMD_PSTATE_MCLK_LEVEL) {
537                 smu->pstate_sclk = gfx_table->dpm_levels[ARCTURUS_UMD_PSTATE_GFXCLK_LEVEL].value;
538                 smu->pstate_mclk = mem_table->dpm_levels[ARCTURUS_UMD_PSTATE_MCLK_LEVEL].value;
539         }
540
541         smu->pstate_sclk = smu->pstate_sclk * 100;
542         smu->pstate_mclk = smu->pstate_mclk * 100;
543
544         return 0;
545 }
546
547 static int arcturus_get_clk_table(struct smu_context *smu,
548                         struct pp_clock_levels_with_latency *clocks,
549                         struct arcturus_single_dpm_table *dpm_table)
550 {
551         int i, count;
552
553         count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count;
554         clocks->num_levels = count;
555
556         for (i = 0; i < count; i++) {
557                 clocks->data[i].clocks_in_khz =
558                         dpm_table->dpm_levels[i].value * 1000;
559                 clocks->data[i].latency_in_us = 0;
560         }
561
562         return 0;
563 }
564
565 static int arcturus_print_clk_levels(struct smu_context *smu,
566                         enum smu_clk_type type, char *buf)
567 {
568         int i, now, size = 0;
569         int ret = 0;
570         struct pp_clock_levels_with_latency clocks;
571         struct arcturus_single_dpm_table *single_dpm_table;
572         struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
573         struct arcturus_dpm_table *dpm_table = NULL;
574
575         dpm_table = smu_dpm->dpm_context;
576
577         switch (type) {
578         case SMU_SCLK:
579                 ret = smu_get_current_clk_freq(smu, SMU_GFXCLK, &now);
580                 if (ret) {
581                         pr_err("Attempt to get current gfx clk Failed!");
582                         return ret;
583                 }
584
585                 single_dpm_table = &(dpm_table->gfx_table);
586                 ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table);
587                 if (ret) {
588                         pr_err("Attempt to get gfx clk levels Failed!");
589                         return ret;
590                 }
591
592                 for (i = 0; i < clocks.num_levels; i++)
593                         size += sprintf(buf + size, "%d: %uMhz %s\n", i,
594                                         clocks.data[i].clocks_in_khz / 1000,
595                                         (clocks.data[i].clocks_in_khz == now * 10)
596                                         ? "*" : "");
597                 break;
598
599         case SMU_MCLK:
600                 ret = smu_get_current_clk_freq(smu, SMU_UCLK, &now);
601                 if (ret) {
602                         pr_err("Attempt to get current mclk Failed!");
603                         return ret;
604                 }
605
606                 single_dpm_table = &(dpm_table->mem_table);
607                 ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table);
608                 if (ret) {
609                         pr_err("Attempt to get memory clk levels Failed!");
610                         return ret;
611                 }
612
613                 for (i = 0; i < clocks.num_levels; i++)
614                         size += sprintf(buf + size, "%d: %uMhz %s\n",
615                                 i, clocks.data[i].clocks_in_khz / 1000,
616                                 (clocks.data[i].clocks_in_khz == now * 10)
617                                 ? "*" : "");
618                 break;
619
620         case SMU_SOCCLK:
621                 ret = smu_get_current_clk_freq(smu, SMU_SOCCLK, &now);
622                 if (ret) {
623                         pr_err("Attempt to get current socclk Failed!");
624                         return ret;
625                 }
626
627                 single_dpm_table = &(dpm_table->soc_table);
628                 ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table);
629                 if (ret) {
630                         pr_err("Attempt to get socclk levels Failed!");
631                         return ret;
632                 }
633
634                 for (i = 0; i < clocks.num_levels; i++)
635                         size += sprintf(buf + size, "%d: %uMhz %s\n",
636                                 i, clocks.data[i].clocks_in_khz / 1000,
637                                 (clocks.data[i].clocks_in_khz == now * 10)
638                                 ? "*" : "");
639                 break;
640
641         case SMU_FCLK:
642                 ret = smu_get_current_clk_freq(smu, SMU_FCLK, &now);
643                 if (ret) {
644                         pr_err("Attempt to get current fclk Failed!");
645                         return ret;
646                 }
647
648                 single_dpm_table = &(dpm_table->fclk_table);
649                 for (i = 0; i < single_dpm_table->count; i++)
650                         size += sprintf(buf + size, "%d: %uMhz %s\n",
651                                 i, single_dpm_table->dpm_levels[i].value,
652                                 (single_dpm_table->dpm_levels[i].value == now / 100)
653                                 ? "*" : "");
654                 break;
655
656         default:
657                 break;
658         }
659
660         return size;
661 }
662
663 static int arcturus_upload_dpm_level(struct smu_context *smu, bool max,
664                                    uint32_t feature_mask)
665 {
666         struct arcturus_dpm_table *dpm_table;
667         struct arcturus_single_dpm_table *single_dpm_table;
668         uint32_t freq;
669         int ret = 0;
670
671         dpm_table = smu->smu_dpm.dpm_context;
672         if (smu_feature_is_enabled(smu, FEATURE_DPM_GFXCLK_BIT) &&
673             (feature_mask & FEATURE_DPM_GFXCLK_MASK)) {
674                 single_dpm_table = &(dpm_table->gfx_table);
675                 freq = max ? single_dpm_table->dpm_state.soft_max_level :
676                         single_dpm_table->dpm_state.soft_min_level;
677                 ret = smu_send_smc_msg_with_param(smu,
678                         (max ? SMU_MSG_SetSoftMaxByFreq : SMU_MSG_SetSoftMinByFreq),
679                         (PPCLK_GFXCLK << 16) | (freq & 0xffff));
680                 if (ret) {
681                         pr_err("Failed to set soft %s gfxclk !\n",
682                                                 max ? "max" : "min");
683                         return ret;
684                 }
685         }
686
687         return ret;
688 }
689
690 static int arcturus_force_clk_levels(struct smu_context *smu,
691                         enum smu_clk_type type, uint32_t mask)
692 {
693         struct arcturus_dpm_table *dpm_table;
694         struct arcturus_single_dpm_table *single_dpm_table;
695         uint32_t soft_min_level, soft_max_level;
696         int ret = 0;
697
698         mutex_lock(&(smu->mutex));
699
700         soft_min_level = mask ? (ffs(mask) - 1) : 0;
701         soft_max_level = mask ? (fls(mask) - 1) : 0;
702
703         dpm_table = smu->smu_dpm.dpm_context;
704
705         switch (type) {
706         case SMU_SCLK:
707                 single_dpm_table = &(dpm_table->gfx_table);
708
709                 if (soft_max_level >= single_dpm_table->count) {
710                         pr_err("Clock level specified %d is over max allowed %d\n",
711                                         soft_max_level, single_dpm_table->count - 1);
712                         ret = -EINVAL;
713                         break;
714                 }
715
716                 single_dpm_table->dpm_state.soft_min_level =
717                         single_dpm_table->dpm_levels[soft_min_level].value;
718                 single_dpm_table->dpm_state.soft_max_level =
719                         single_dpm_table->dpm_levels[soft_max_level].value;
720
721                 ret = arcturus_upload_dpm_level(smu, false, FEATURE_DPM_GFXCLK_MASK);
722                 if (ret) {
723                         pr_err("Failed to upload boot level to lowest!\n");
724                         break;
725                 }
726
727                 ret = arcturus_upload_dpm_level(smu, true, FEATURE_DPM_GFXCLK_MASK);
728                 if (ret)
729                         pr_err("Failed to upload dpm max level to highest!\n");
730
731                 break;
732
733         case SMU_MCLK:
734                 single_dpm_table = &(dpm_table->mem_table);
735
736                 if (soft_max_level >= single_dpm_table->count) {
737                         pr_err("Clock level specified %d is over max allowed %d\n",
738                                         soft_max_level, single_dpm_table->count - 1);
739                         ret = -EINVAL;
740                         break;
741                 }
742
743                 single_dpm_table->dpm_state.soft_min_level =
744                         single_dpm_table->dpm_levels[soft_min_level].value;
745                 single_dpm_table->dpm_state.soft_max_level =
746                         single_dpm_table->dpm_levels[soft_max_level].value;
747
748                 ret = arcturus_upload_dpm_level(smu, false, FEATURE_DPM_UCLK_MASK);
749                 if (ret) {
750                         pr_err("Failed to upload boot level to lowest!\n");
751                         break;
752                 }
753
754                 ret = arcturus_upload_dpm_level(smu, true, FEATURE_DPM_UCLK_MASK);
755                 if (ret)
756                         pr_err("Failed to upload dpm max level to highest!\n");
757
758                 break;
759
760         case SMU_SOCCLK:
761                 single_dpm_table = &(dpm_table->soc_table);
762
763                 if (soft_max_level >= single_dpm_table->count) {
764                         pr_err("Clock level specified %d is over max allowed %d\n",
765                                         soft_max_level, single_dpm_table->count - 1);
766                         ret = -EINVAL;
767                         break;
768                 }
769
770                 single_dpm_table->dpm_state.soft_min_level =
771                         single_dpm_table->dpm_levels[soft_min_level].value;
772                 single_dpm_table->dpm_state.soft_max_level =
773                         single_dpm_table->dpm_levels[soft_max_level].value;
774
775                 ret = arcturus_upload_dpm_level(smu, false, FEATURE_DPM_SOCCLK_MASK);
776                 if (ret) {
777                         pr_err("Failed to upload boot level to lowest!\n");
778                         break;
779                 }
780
781                 ret = arcturus_upload_dpm_level(smu, true, FEATURE_DPM_SOCCLK_MASK);
782                 if (ret)
783                         pr_err("Failed to upload dpm max level to highest!\n");
784
785                 break;
786
787         case SMU_FCLK:
788                 single_dpm_table = &(dpm_table->fclk_table);
789
790                 if (soft_max_level >= single_dpm_table->count) {
791                         pr_err("Clock level specified %d is over max allowed %d\n",
792                                         soft_max_level, single_dpm_table->count - 1);
793                         ret = -EINVAL;
794                         break;
795                 }
796
797                 single_dpm_table->dpm_state.soft_min_level =
798                         single_dpm_table->dpm_levels[soft_min_level].value;
799                 single_dpm_table->dpm_state.soft_max_level =
800                         single_dpm_table->dpm_levels[soft_max_level].value;
801
802                 ret = arcturus_upload_dpm_level(smu, false, FEATURE_DPM_FCLK_MASK);
803                 if (ret) {
804                         pr_err("Failed to upload boot level to lowest!\n");
805                         break;
806                 }
807
808                 ret = arcturus_upload_dpm_level(smu, true, FEATURE_DPM_FCLK_MASK);
809                 if (ret)
810                         pr_err("Failed to upload dpm max level to highest!\n");
811
812                 break;
813
814         default:
815                 break;
816         }
817
818         mutex_unlock(&(smu->mutex));
819         return ret;
820 }
821
822 static const struct smu_temperature_range arcturus_thermal_policy[] =
823 {
824         {-273150,  99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000},
825         { 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000},
826 };
827
828 static int arcturus_get_thermal_temperature_range(struct smu_context *smu,
829                                                 struct smu_temperature_range *range)
830 {
831
832         PPTable_t *pptable = smu->smu_table.driver_pptable;
833
834         if (!range)
835                 return -EINVAL;
836
837         memcpy(range, &arcturus_thermal_policy[0], sizeof(struct smu_temperature_range));
838
839         range->max = pptable->TedgeLimit *
840                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
841         range->edge_emergency_max = (pptable->TedgeLimit + CTF_OFFSET_EDGE) *
842                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
843         range->hotspot_crit_max = pptable->ThotspotLimit *
844                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
845         range->hotspot_emergency_max = (pptable->ThotspotLimit + CTF_OFFSET_HOTSPOT) *
846                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
847         range->mem_crit_max = pptable->TmemLimit *
848                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
849         range->mem_emergency_max = (pptable->TmemLimit + CTF_OFFSET_HBM)*
850                 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
851
852
853         return 0;
854 }
855
856 static void arcturus_dump_pptable(struct smu_context *smu)
857 {
858         struct smu_table_context *table_context = &smu->smu_table;
859         PPTable_t *pptable = table_context->driver_pptable;
860         int i;
861
862         pr_info("Dumped PPTable:\n");
863
864         pr_info("Version = 0x%08x\n", pptable->Version);
865
866         pr_info("FeaturesToRun[0] = 0x%08x\n", pptable->FeaturesToRun[0]);
867         pr_info("FeaturesToRun[1] = 0x%08x\n", pptable->FeaturesToRun[1]);
868
869         for (i = 0; i < PPT_THROTTLER_COUNT; i++) {
870                 pr_info("SocketPowerLimitAc[%d] = %d\n", i, pptable->SocketPowerLimitAc[i]);
871                 pr_info("SocketPowerLimitAcTau[%d] = %d\n", i, pptable->SocketPowerLimitAcTau[i]);
872         }
873
874         pr_info("TdcLimitSoc = %d\n", pptable->TdcLimitSoc);
875         pr_info("TdcLimitSocTau = %d\n", pptable->TdcLimitSocTau);
876         pr_info("TdcLimitGfx = %d\n", pptable->TdcLimitGfx);
877         pr_info("TdcLimitGfxTau = %d\n", pptable->TdcLimitGfxTau);
878
879         pr_info("TedgeLimit = %d\n", pptable->TedgeLimit);
880         pr_info("ThotspotLimit = %d\n", pptable->ThotspotLimit);
881         pr_info("TmemLimit = %d\n", pptable->TmemLimit);
882         pr_info("Tvr_gfxLimit = %d\n", pptable->Tvr_gfxLimit);
883         pr_info("Tvr_memLimit = %d\n", pptable->Tvr_memLimit);
884         pr_info("Tvr_socLimit = %d\n", pptable->Tvr_socLimit);
885         pr_info("FitLimit = %d\n", pptable->FitLimit);
886
887         pr_info("PpmPowerLimit = %d\n", pptable->PpmPowerLimit);
888         pr_info("PpmTemperatureThreshold = %d\n", pptable->PpmTemperatureThreshold);
889
890         pr_info("ThrottlerControlMask = %d\n", pptable->ThrottlerControlMask);
891
892         pr_info("UlvVoltageOffsetGfx = %d\n", pptable->UlvVoltageOffsetGfx);
893         pr_info("UlvPadding = 0x%08x\n", pptable->UlvPadding);
894
895         pr_info("UlvGfxclkBypass = %d\n", pptable->UlvGfxclkBypass);
896         pr_info("Padding234[0] = 0x%02x\n", pptable->Padding234[0]);
897         pr_info("Padding234[1] = 0x%02x\n", pptable->Padding234[1]);
898         pr_info("Padding234[2] = 0x%02x\n", pptable->Padding234[2]);
899
900         pr_info("MinVoltageGfx = %d\n", pptable->MinVoltageGfx);
901         pr_info("MinVoltageSoc = %d\n", pptable->MinVoltageSoc);
902         pr_info("MaxVoltageGfx = %d\n", pptable->MaxVoltageGfx);
903         pr_info("MaxVoltageSoc = %d\n", pptable->MaxVoltageSoc);
904
905         pr_info("LoadLineResistanceGfx = %d\n", pptable->LoadLineResistanceGfx);
906         pr_info("LoadLineResistanceSoc = %d\n", pptable->LoadLineResistanceSoc);
907
908         pr_info("[PPCLK_GFXCLK]\n"
909                         "  .VoltageMode          = 0x%02x\n"
910                         "  .SnapToDiscrete       = 0x%02x\n"
911                         "  .NumDiscreteLevels    = 0x%02x\n"
912                         "  .padding              = 0x%02x\n"
913                         "  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
914                         "  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
915                         "  .SsFmin               = 0x%04x\n"
916                         "  .Padding_16           = 0x%04x\n",
917                         pptable->DpmDescriptor[PPCLK_GFXCLK].VoltageMode,
918                         pptable->DpmDescriptor[PPCLK_GFXCLK].SnapToDiscrete,
919                         pptable->DpmDescriptor[PPCLK_GFXCLK].NumDiscreteLevels,
920                         pptable->DpmDescriptor[PPCLK_GFXCLK].padding,
921                         pptable->DpmDescriptor[PPCLK_GFXCLK].ConversionToAvfsClk.m,
922                         pptable->DpmDescriptor[PPCLK_GFXCLK].ConversionToAvfsClk.b,
923                         pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.a,
924                         pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.b,
925                         pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.c,
926                         pptable->DpmDescriptor[PPCLK_GFXCLK].SsFmin,
927                         pptable->DpmDescriptor[PPCLK_GFXCLK].Padding16);
928
929         pr_info("[PPCLK_VCLK]\n"
930                         "  .VoltageMode          = 0x%02x\n"
931                         "  .SnapToDiscrete       = 0x%02x\n"
932                         "  .NumDiscreteLevels    = 0x%02x\n"
933                         "  .padding              = 0x%02x\n"
934                         "  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
935                         "  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
936                         "  .SsFmin               = 0x%04x\n"
937                         "  .Padding_16           = 0x%04x\n",
938                         pptable->DpmDescriptor[PPCLK_VCLK].VoltageMode,
939                         pptable->DpmDescriptor[PPCLK_VCLK].SnapToDiscrete,
940                         pptable->DpmDescriptor[PPCLK_VCLK].NumDiscreteLevels,
941                         pptable->DpmDescriptor[PPCLK_VCLK].padding,
942                         pptable->DpmDescriptor[PPCLK_VCLK].ConversionToAvfsClk.m,
943                         pptable->DpmDescriptor[PPCLK_VCLK].ConversionToAvfsClk.b,
944                         pptable->DpmDescriptor[PPCLK_VCLK].SsCurve.a,
945                         pptable->DpmDescriptor[PPCLK_VCLK].SsCurve.b,
946                         pptable->DpmDescriptor[PPCLK_VCLK].SsCurve.c,
947                         pptable->DpmDescriptor[PPCLK_VCLK].SsFmin,
948                         pptable->DpmDescriptor[PPCLK_VCLK].Padding16);
949
950         pr_info("[PPCLK_DCLK]\n"
951                         "  .VoltageMode          = 0x%02x\n"
952                         "  .SnapToDiscrete       = 0x%02x\n"
953                         "  .NumDiscreteLevels    = 0x%02x\n"
954                         "  .padding              = 0x%02x\n"
955                         "  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
956                         "  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
957                         "  .SsFmin               = 0x%04x\n"
958                         "  .Padding_16           = 0x%04x\n",
959                         pptable->DpmDescriptor[PPCLK_DCLK].VoltageMode,
960                         pptable->DpmDescriptor[PPCLK_DCLK].SnapToDiscrete,
961                         pptable->DpmDescriptor[PPCLK_DCLK].NumDiscreteLevels,
962                         pptable->DpmDescriptor[PPCLK_DCLK].padding,
963                         pptable->DpmDescriptor[PPCLK_DCLK].ConversionToAvfsClk.m,
964                         pptable->DpmDescriptor[PPCLK_DCLK].ConversionToAvfsClk.b,
965                         pptable->DpmDescriptor[PPCLK_DCLK].SsCurve.a,
966                         pptable->DpmDescriptor[PPCLK_DCLK].SsCurve.b,
967                         pptable->DpmDescriptor[PPCLK_DCLK].SsCurve.c,
968                         pptable->DpmDescriptor[PPCLK_DCLK].SsFmin,
969                         pptable->DpmDescriptor[PPCLK_DCLK].Padding16);
970
971         pr_info("[PPCLK_SOCCLK]\n"
972                         "  .VoltageMode          = 0x%02x\n"
973                         "  .SnapToDiscrete       = 0x%02x\n"
974                         "  .NumDiscreteLevels    = 0x%02x\n"
975                         "  .padding              = 0x%02x\n"
976                         "  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
977                         "  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
978                         "  .SsFmin               = 0x%04x\n"
979                         "  .Padding_16           = 0x%04x\n",
980                         pptable->DpmDescriptor[PPCLK_SOCCLK].VoltageMode,
981                         pptable->DpmDescriptor[PPCLK_SOCCLK].SnapToDiscrete,
982                         pptable->DpmDescriptor[PPCLK_SOCCLK].NumDiscreteLevels,
983                         pptable->DpmDescriptor[PPCLK_SOCCLK].padding,
984                         pptable->DpmDescriptor[PPCLK_SOCCLK].ConversionToAvfsClk.m,
985                         pptable->DpmDescriptor[PPCLK_SOCCLK].ConversionToAvfsClk.b,
986                         pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.a,
987                         pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.b,
988                         pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.c,
989                         pptable->DpmDescriptor[PPCLK_SOCCLK].SsFmin,
990                         pptable->DpmDescriptor[PPCLK_SOCCLK].Padding16);
991
992         pr_info("[PPCLK_UCLK]\n"
993                         "  .VoltageMode          = 0x%02x\n"
994                         "  .SnapToDiscrete       = 0x%02x\n"
995                         "  .NumDiscreteLevels    = 0x%02x\n"
996                         "  .padding              = 0x%02x\n"
997                         "  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
998                         "  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
999                         "  .SsFmin               = 0x%04x\n"
1000                         "  .Padding_16           = 0x%04x\n",
1001                         pptable->DpmDescriptor[PPCLK_UCLK].VoltageMode,
1002                         pptable->DpmDescriptor[PPCLK_UCLK].SnapToDiscrete,
1003                         pptable->DpmDescriptor[PPCLK_UCLK].NumDiscreteLevels,
1004                         pptable->DpmDescriptor[PPCLK_UCLK].padding,
1005                         pptable->DpmDescriptor[PPCLK_UCLK].ConversionToAvfsClk.m,
1006                         pptable->DpmDescriptor[PPCLK_UCLK].ConversionToAvfsClk.b,
1007                         pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.a,
1008                         pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.b,
1009                         pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.c,
1010                         pptable->DpmDescriptor[PPCLK_UCLK].SsFmin,
1011                         pptable->DpmDescriptor[PPCLK_UCLK].Padding16);
1012
1013         pr_info("[PPCLK_FCLK]\n"
1014                         "  .VoltageMode          = 0x%02x\n"
1015                         "  .SnapToDiscrete       = 0x%02x\n"
1016                         "  .NumDiscreteLevels    = 0x%02x\n"
1017                         "  .padding              = 0x%02x\n"
1018                         "  .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1019                         "  .SsCurve            {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1020                         "  .SsFmin               = 0x%04x\n"
1021                         "  .Padding_16           = 0x%04x\n",
1022                         pptable->DpmDescriptor[PPCLK_FCLK].VoltageMode,
1023                         pptable->DpmDescriptor[PPCLK_FCLK].SnapToDiscrete,
1024                         pptable->DpmDescriptor[PPCLK_FCLK].NumDiscreteLevels,
1025                         pptable->DpmDescriptor[PPCLK_FCLK].padding,
1026                         pptable->DpmDescriptor[PPCLK_FCLK].ConversionToAvfsClk.m,
1027                         pptable->DpmDescriptor[PPCLK_FCLK].ConversionToAvfsClk.b,
1028                         pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.a,
1029                         pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.b,
1030                         pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.c,
1031                         pptable->DpmDescriptor[PPCLK_FCLK].SsFmin,
1032                         pptable->DpmDescriptor[PPCLK_FCLK].Padding16);
1033
1034
1035         pr_info("FreqTableGfx\n");
1036         for (i = 0; i < NUM_GFXCLK_DPM_LEVELS; i++)
1037                 pr_info("  .[%02d] = %d\n", i, pptable->FreqTableGfx[i]);
1038
1039         pr_info("FreqTableVclk\n");
1040         for (i = 0; i < NUM_VCLK_DPM_LEVELS; i++)
1041                 pr_info("  .[%02d] = %d\n", i, pptable->FreqTableVclk[i]);
1042
1043         pr_info("FreqTableDclk\n");
1044         for (i = 0; i < NUM_DCLK_DPM_LEVELS; i++)
1045                 pr_info("  .[%02d] = %d\n", i, pptable->FreqTableDclk[i]);
1046
1047         pr_info("FreqTableSocclk\n");
1048         for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++)
1049                 pr_info("  .[%02d] = %d\n", i, pptable->FreqTableSocclk[i]);
1050
1051         pr_info("FreqTableUclk\n");
1052         for (i = 0; i < NUM_UCLK_DPM_LEVELS; i++)
1053                 pr_info("  .[%02d] = %d\n", i, pptable->FreqTableUclk[i]);
1054
1055         pr_info("FreqTableFclk\n");
1056         for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++)
1057                 pr_info("  .[%02d] = %d\n", i, pptable->FreqTableFclk[i]);
1058
1059         pr_info("Mp0clkFreq\n");
1060         for (i = 0; i < NUM_MP0CLK_DPM_LEVELS; i++)
1061                 pr_info("  .[%d] = %d\n", i, pptable->Mp0clkFreq[i]);
1062
1063         pr_info("Mp0DpmVoltage\n");
1064         for (i = 0; i < NUM_MP0CLK_DPM_LEVELS; i++)
1065                 pr_info("  .[%d] = %d\n", i, pptable->Mp0DpmVoltage[i]);
1066
1067         pr_info("GfxclkFidle = 0x%x\n", pptable->GfxclkFidle);
1068         pr_info("GfxclkSlewRate = 0x%x\n", pptable->GfxclkSlewRate);
1069         pr_info("Padding567[0] = 0x%x\n", pptable->Padding567[0]);
1070         pr_info("Padding567[1] = 0x%x\n", pptable->Padding567[1]);
1071         pr_info("Padding567[2] = 0x%x\n", pptable->Padding567[2]);
1072         pr_info("Padding567[3] = 0x%x\n", pptable->Padding567[3]);
1073         pr_info("GfxclkDsMaxFreq = %d\n", pptable->GfxclkDsMaxFreq);
1074         pr_info("GfxclkSource = 0x%x\n", pptable->GfxclkSource);
1075         pr_info("Padding456 = 0x%x\n", pptable->Padding456);
1076
1077         pr_info("EnableTdpm = %d\n", pptable->EnableTdpm);
1078         pr_info("TdpmHighHystTemperature = %d\n", pptable->TdpmHighHystTemperature);
1079         pr_info("TdpmLowHystTemperature = %d\n", pptable->TdpmLowHystTemperature);
1080         pr_info("GfxclkFreqHighTempLimit = %d\n", pptable->GfxclkFreqHighTempLimit);
1081
1082         pr_info("FanStopTemp = %d\n", pptable->FanStopTemp);
1083         pr_info("FanStartTemp = %d\n", pptable->FanStartTemp);
1084
1085         pr_info("FanGainEdge = %d\n", pptable->FanGainEdge);
1086         pr_info("FanGainHotspot = %d\n", pptable->FanGainHotspot);
1087         pr_info("FanGainVrGfx = %d\n", pptable->FanGainVrGfx);
1088         pr_info("FanGainVrSoc = %d\n", pptable->FanGainVrSoc);
1089         pr_info("FanGainVrMem = %d\n", pptable->FanGainVrMem);
1090         pr_info("FanGainHbm = %d\n", pptable->FanGainHbm);
1091
1092         pr_info("FanPwmMin = %d\n", pptable->FanPwmMin);
1093         pr_info("FanAcousticLimitRpm = %d\n", pptable->FanAcousticLimitRpm);
1094         pr_info("FanThrottlingRpm = %d\n", pptable->FanThrottlingRpm);
1095         pr_info("FanMaximumRpm = %d\n", pptable->FanMaximumRpm);
1096         pr_info("FanTargetTemperature = %d\n", pptable->FanTargetTemperature);
1097         pr_info("FanTargetGfxclk = %d\n", pptable->FanTargetGfxclk);
1098         pr_info("FanZeroRpmEnable = %d\n", pptable->FanZeroRpmEnable);
1099         pr_info("FanTachEdgePerRev = %d\n", pptable->FanTachEdgePerRev);
1100         pr_info("FanTempInputSelect = %d\n", pptable->FanTempInputSelect);
1101
1102         pr_info("FuzzyFan_ErrorSetDelta = %d\n", pptable->FuzzyFan_ErrorSetDelta);
1103         pr_info("FuzzyFan_ErrorRateSetDelta = %d\n", pptable->FuzzyFan_ErrorRateSetDelta);
1104         pr_info("FuzzyFan_PwmSetDelta = %d\n", pptable->FuzzyFan_PwmSetDelta);
1105         pr_info("FuzzyFan_Reserved = %d\n", pptable->FuzzyFan_Reserved);
1106
1107         pr_info("OverrideAvfsGb[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->OverrideAvfsGb[AVFS_VOLTAGE_GFX]);
1108         pr_info("OverrideAvfsGb[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->OverrideAvfsGb[AVFS_VOLTAGE_SOC]);
1109         pr_info("Padding8_Avfs[0] = %d\n", pptable->Padding8_Avfs[0]);
1110         pr_info("Padding8_Avfs[1] = %d\n", pptable->Padding8_Avfs[1]);
1111
1112         pr_info("dBtcGbGfxPll{a = 0x%x b = 0x%x c = 0x%x}\n",
1113                         pptable->dBtcGbGfxPll.a,
1114                         pptable->dBtcGbGfxPll.b,
1115                         pptable->dBtcGbGfxPll.c);
1116         pr_info("dBtcGbGfxAfll{a = 0x%x b = 0x%x c = 0x%x}\n",
1117                         pptable->dBtcGbGfxAfll.a,
1118                         pptable->dBtcGbGfxAfll.b,
1119                         pptable->dBtcGbGfxAfll.c);
1120         pr_info("dBtcGbSoc{a = 0x%x b = 0x%x c = 0x%x}\n",
1121                         pptable->dBtcGbSoc.a,
1122                         pptable->dBtcGbSoc.b,
1123                         pptable->dBtcGbSoc.c);
1124
1125         pr_info("qAgingGb[AVFS_VOLTAGE_GFX]{m = 0x%x b = 0x%x}\n",
1126                         pptable->qAgingGb[AVFS_VOLTAGE_GFX].m,
1127                         pptable->qAgingGb[AVFS_VOLTAGE_GFX].b);
1128         pr_info("qAgingGb[AVFS_VOLTAGE_SOC]{m = 0x%x b = 0x%x}\n",
1129                         pptable->qAgingGb[AVFS_VOLTAGE_SOC].m,
1130                         pptable->qAgingGb[AVFS_VOLTAGE_SOC].b);
1131
1132         pr_info("qStaticVoltageOffset[AVFS_VOLTAGE_GFX]{a = 0x%x b = 0x%x c = 0x%x}\n",
1133                         pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].a,
1134                         pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].b,
1135                         pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].c);
1136         pr_info("qStaticVoltageOffset[AVFS_VOLTAGE_SOC]{a = 0x%x b = 0x%x c = 0x%x}\n",
1137                         pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].a,
1138                         pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].b,
1139                         pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].c);
1140
1141         pr_info("DcTol[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcTol[AVFS_VOLTAGE_GFX]);
1142         pr_info("DcTol[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcTol[AVFS_VOLTAGE_SOC]);
1143
1144         pr_info("DcBtcEnabled[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcEnabled[AVFS_VOLTAGE_GFX]);
1145         pr_info("DcBtcEnabled[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcEnabled[AVFS_VOLTAGE_SOC]);
1146         pr_info("Padding8_GfxBtc[0] = 0x%x\n", pptable->Padding8_GfxBtc[0]);
1147         pr_info("Padding8_GfxBtc[1] = 0x%x\n", pptable->Padding8_GfxBtc[1]);
1148
1149         pr_info("DcBtcMin[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcMin[AVFS_VOLTAGE_GFX]);
1150         pr_info("DcBtcMin[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcMin[AVFS_VOLTAGE_SOC]);
1151         pr_info("DcBtcMax[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcMax[AVFS_VOLTAGE_GFX]);
1152         pr_info("DcBtcMax[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcMax[AVFS_VOLTAGE_SOC]);
1153
1154         pr_info("DcBtcGb[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcGb[AVFS_VOLTAGE_GFX]);
1155         pr_info("DcBtcGb[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcGb[AVFS_VOLTAGE_SOC]);
1156
1157         pr_info("XgmiDpmPstates\n");
1158         for (i = 0; i < NUM_XGMI_LEVELS; i++)
1159                 pr_info("  .[%d] = %d\n", i, pptable->XgmiDpmPstates[i]);
1160         pr_info("XgmiDpmSpare[0] = 0x%02x\n", pptable->XgmiDpmSpare[0]);
1161         pr_info("XgmiDpmSpare[1] = 0x%02x\n", pptable->XgmiDpmSpare[1]);
1162
1163         pr_info("VDDGFX_TVmin = %d\n", pptable->VDDGFX_TVmin);
1164         pr_info("VDDSOC_TVmin = %d\n", pptable->VDDSOC_TVmin);
1165         pr_info("VDDGFX_Vmin_HiTemp = %d\n", pptable->VDDGFX_Vmin_HiTemp);
1166         pr_info("VDDGFX_Vmin_LoTemp = %d\n", pptable->VDDGFX_Vmin_LoTemp);
1167         pr_info("VDDSOC_Vmin_HiTemp = %d\n", pptable->VDDSOC_Vmin_HiTemp);
1168         pr_info("VDDSOC_Vmin_LoTemp = %d\n", pptable->VDDSOC_Vmin_LoTemp);
1169         pr_info("VDDGFX_TVminHystersis = %d\n", pptable->VDDGFX_TVminHystersis);
1170         pr_info("VDDSOC_TVminHystersis = %d\n", pptable->VDDSOC_TVminHystersis);
1171
1172         pr_info("DebugOverrides = 0x%x\n", pptable->DebugOverrides);
1173         pr_info("ReservedEquation0{a = 0x%x b = 0x%x c = 0x%x}\n",
1174                         pptable->ReservedEquation0.a,
1175                         pptable->ReservedEquation0.b,
1176                         pptable->ReservedEquation0.c);
1177         pr_info("ReservedEquation1{a = 0x%x b = 0x%x c = 0x%x}\n",
1178                         pptable->ReservedEquation1.a,
1179                         pptable->ReservedEquation1.b,
1180                         pptable->ReservedEquation1.c);
1181         pr_info("ReservedEquation2{a = 0x%x b = 0x%x c = 0x%x}\n",
1182                         pptable->ReservedEquation2.a,
1183                         pptable->ReservedEquation2.b,
1184                         pptable->ReservedEquation2.c);
1185         pr_info("ReservedEquation3{a = 0x%x b = 0x%x c = 0x%x}\n",
1186                         pptable->ReservedEquation3.a,
1187                         pptable->ReservedEquation3.b,
1188                         pptable->ReservedEquation3.c);
1189
1190         pr_info("MinVoltageUlvGfx = %d\n", pptable->MinVoltageUlvGfx);
1191         pr_info("PaddingUlv = %d\n", pptable->PaddingUlv);
1192
1193         pr_info("TotalPowerConfig = %d\n", pptable->TotalPowerConfig);
1194         pr_info("TotalPowerSpare1 = %d\n", pptable->TotalPowerSpare1);
1195         pr_info("TotalPowerSpare2 = %d\n", pptable->TotalPowerSpare2);
1196
1197         pr_info("PccThresholdLow = %d\n", pptable->PccThresholdLow);
1198         pr_info("PccThresholdHigh = %d\n", pptable->PccThresholdHigh);
1199
1200         pr_info("Board Parameters:\n");
1201         pr_info("MaxVoltageStepGfx = 0x%x\n", pptable->MaxVoltageStepGfx);
1202         pr_info("MaxVoltageStepSoc = 0x%x\n", pptable->MaxVoltageStepSoc);
1203
1204         pr_info("VddGfxVrMapping = 0x%x\n", pptable->VddGfxVrMapping);
1205         pr_info("VddSocVrMapping = 0x%x\n", pptable->VddSocVrMapping);
1206         pr_info("VddMemVrMapping = 0x%x\n", pptable->VddMemVrMapping);
1207         pr_info("BoardVrMapping = 0x%x\n", pptable->BoardVrMapping);
1208
1209         pr_info("GfxUlvPhaseSheddingMask = 0x%x\n", pptable->GfxUlvPhaseSheddingMask);
1210         pr_info("ExternalSensorPresent = 0x%x\n", pptable->ExternalSensorPresent);
1211
1212         pr_info("GfxMaxCurrent = 0x%x\n", pptable->GfxMaxCurrent);
1213         pr_info("GfxOffset = 0x%x\n", pptable->GfxOffset);
1214         pr_info("Padding_TelemetryGfx = 0x%x\n", pptable->Padding_TelemetryGfx);
1215
1216         pr_info("SocMaxCurrent = 0x%x\n", pptable->SocMaxCurrent);
1217         pr_info("SocOffset = 0x%x\n", pptable->SocOffset);
1218         pr_info("Padding_TelemetrySoc = 0x%x\n", pptable->Padding_TelemetrySoc);
1219
1220         pr_info("MemMaxCurrent = 0x%x\n", pptable->MemMaxCurrent);
1221         pr_info("MemOffset = 0x%x\n", pptable->MemOffset);
1222         pr_info("Padding_TelemetryMem = 0x%x\n", pptable->Padding_TelemetryMem);
1223
1224         pr_info("BoardMaxCurrent = 0x%x\n", pptable->BoardMaxCurrent);
1225         pr_info("BoardOffset = 0x%x\n", pptable->BoardOffset);
1226         pr_info("Padding_TelemetryBoardInput = 0x%x\n", pptable->Padding_TelemetryBoardInput);
1227
1228         pr_info("VR0HotGpio = %d\n", pptable->VR0HotGpio);
1229         pr_info("VR0HotPolarity = %d\n", pptable->VR0HotPolarity);
1230         pr_info("VR1HotGpio = %d\n", pptable->VR1HotGpio);
1231         pr_info("VR1HotPolarity = %d\n", pptable->VR1HotPolarity);
1232
1233         pr_info("PllGfxclkSpreadEnabled = %d\n", pptable->PllGfxclkSpreadEnabled);
1234         pr_info("PllGfxclkSpreadPercent = %d\n", pptable->PllGfxclkSpreadPercent);
1235         pr_info("PllGfxclkSpreadFreq = %d\n", pptable->PllGfxclkSpreadFreq);
1236
1237         pr_info("UclkSpreadEnabled = %d\n", pptable->UclkSpreadEnabled);
1238         pr_info("UclkSpreadPercent = %d\n", pptable->UclkSpreadPercent);
1239         pr_info("UclkSpreadFreq = %d\n", pptable->UclkSpreadFreq);
1240
1241         pr_info("FclkSpreadEnabled = %d\n", pptable->FclkSpreadEnabled);
1242         pr_info("FclkSpreadPercent = %d\n", pptable->FclkSpreadPercent);
1243         pr_info("FclkSpreadFreq = %d\n", pptable->FclkSpreadFreq);
1244
1245         pr_info("FllGfxclkSpreadEnabled = %d\n", pptable->FllGfxclkSpreadEnabled);
1246         pr_info("FllGfxclkSpreadPercent = %d\n", pptable->FllGfxclkSpreadPercent);
1247         pr_info("FllGfxclkSpreadFreq = %d\n", pptable->FllGfxclkSpreadFreq);
1248
1249         for (i = 0; i < NUM_I2C_CONTROLLERS; i++) {
1250                 pr_info("I2cControllers[%d]:\n", i);
1251                 pr_info("                   .Enabled = %d\n",
1252                                 pptable->I2cControllers[i].Enabled);
1253                 pr_info("                   .SlaveAddress = 0x%x\n",
1254                                 pptable->I2cControllers[i].SlaveAddress);
1255                 pr_info("                   .ControllerPort = %d\n",
1256                                 pptable->I2cControllers[i].ControllerPort);
1257                 pr_info("                   .ControllerName = %d\n",
1258                                 pptable->I2cControllers[i].ControllerName);
1259                 pr_info("                   .ThermalThrottler = %d\n",
1260                                 pptable->I2cControllers[i].ThermalThrotter);
1261                 pr_info("                   .I2cProtocol = %d\n",
1262                                 pptable->I2cControllers[i].I2cProtocol);
1263                 pr_info("                   .Speed = %d\n",
1264                                 pptable->I2cControllers[i].Speed);
1265         }
1266
1267         pr_info("MemoryChannelEnabled = %d\n", pptable->MemoryChannelEnabled);
1268         pr_info("DramBitWidth = %d\n", pptable->DramBitWidth);
1269
1270         pr_info("TotalBoardPower = %d\n", pptable->TotalBoardPower);
1271
1272         pr_info("XgmiLinkSpeed\n");
1273         for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
1274                 pr_info("  .[%d] = %d\n", i, pptable->XgmiLinkSpeed[i]);
1275         pr_info("XgmiLinkWidth\n");
1276         for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
1277                 pr_info("  .[%d] = %d\n", i, pptable->XgmiLinkWidth[i]);
1278         pr_info("XgmiFclkFreq\n");
1279         for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
1280                 pr_info("  .[%d] = %d\n", i, pptable->XgmiFclkFreq[i]);
1281         pr_info("XgmiSocVoltage\n");
1282         for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
1283                 pr_info("  .[%d] = %d\n", i, pptable->XgmiSocVoltage[i]);
1284
1285 }
1286
1287 static const struct pptable_funcs arcturus_ppt_funcs = {
1288         /* translate smu index into arcturus specific index */
1289         .get_smu_msg_index = arcturus_get_smu_msg_index,
1290         .get_smu_clk_index = arcturus_get_smu_clk_index,
1291         .get_smu_feature_index = arcturus_get_smu_feature_index,
1292         .get_smu_table_index = arcturus_get_smu_table_index,
1293         .get_smu_power_index= arcturus_get_pwr_src_index,
1294         .get_workload_type = arcturus_get_workload_type,
1295         /* internal structurs allocations */
1296         .tables_init = arcturus_tables_init,
1297         .alloc_dpm_context = arcturus_allocate_dpm_context,
1298         /* pptable related */
1299         .check_powerplay_table = arcturus_check_powerplay_table,
1300         .store_powerplay_table = arcturus_store_powerplay_table,
1301         .append_powerplay_table = arcturus_append_powerplay_table,
1302         /* init dpm */
1303         .get_allowed_feature_mask = arcturus_get_allowed_feature_mask,
1304         /* btc */
1305         .run_afll_btc = arcturus_run_btc_afll,
1306         /* dpm/clk tables */
1307         .set_default_dpm_table = arcturus_set_default_dpm_table,
1308         .populate_umd_state_clk = arcturus_populate_umd_state_clk,
1309         .get_thermal_temperature_range = arcturus_get_thermal_temperature_range,
1310         .print_clk_levels = arcturus_print_clk_levels,
1311         .force_clk_levels = arcturus_force_clk_levels,
1312         /* debug (internal used) */
1313         .dump_pptable = arcturus_dump_pptable,
1314 };
1315
1316 void arcturus_set_ppt_funcs(struct smu_context *smu)
1317 {
1318         struct smu_table_context *smu_table = &smu->smu_table;
1319
1320         smu->ppt_funcs = &arcturus_ppt_funcs;
1321         smu->smc_if_version = SMU11_DRIVER_IF_VERSION;
1322         smu_table->table_count = TABLE_COUNT;
1323 }