2 * Copyright 2019 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
25 #include <linux/firmware.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.h"
32 #include "soc15_common.h"
34 #include "vega20_ppt.h"
35 #include "vega20_pptable.h"
36 #include "vega20_ppsmc.h"
38 #define MSG_MAP(msg, index) \
39 [SMU_MSG_##msg] = index
41 static int vega20_message_map[SMU_MSG_MAX_COUNT] = {
42 MSG_MAP(TestMessage, PPSMC_MSG_TestMessage),
43 MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion),
44 MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion),
45 MSG_MAP(SetAllowedFeaturesMaskLow, PPSMC_MSG_SetAllowedFeaturesMaskLow),
46 MSG_MAP(SetAllowedFeaturesMaskHigh, PPSMC_MSG_SetAllowedFeaturesMaskHigh),
47 MSG_MAP(EnableAllSmuFeatures, PPSMC_MSG_EnableAllSmuFeatures),
48 MSG_MAP(DisableAllSmuFeatures, PPSMC_MSG_DisableAllSmuFeatures),
49 MSG_MAP(EnableSmuFeaturesLow, PPSMC_MSG_EnableSmuFeaturesLow),
50 MSG_MAP(EnableSmuFeaturesHigh, PPSMC_MSG_EnableSmuFeaturesHigh),
51 MSG_MAP(DisableSmuFeaturesLow, PPSMC_MSG_DisableSmuFeaturesLow),
52 MSG_MAP(DisableSmuFeaturesHigh, PPSMC_MSG_DisableSmuFeaturesHigh),
53 MSG_MAP(GetEnabledSmuFeaturesLow, PPSMC_MSG_GetEnabledSmuFeaturesLow),
54 MSG_MAP(GetEnabledSmuFeaturesHigh, PPSMC_MSG_GetEnabledSmuFeaturesHigh),
55 MSG_MAP(SetWorkloadMask, PPSMC_MSG_SetWorkloadMask),
56 MSG_MAP(SetPptLimit, PPSMC_MSG_SetPptLimit),
57 MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh),
58 MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow),
59 MSG_MAP(SetToolsDramAddrHigh, PPSMC_MSG_SetToolsDramAddrHigh),
60 MSG_MAP(SetToolsDramAddrLow, PPSMC_MSG_SetToolsDramAddrLow),
61 MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram),
62 MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu),
63 MSG_MAP(UseDefaultPPTable, PPSMC_MSG_UseDefaultPPTable),
64 MSG_MAP(UseBackupPPTable, PPSMC_MSG_UseBackupPPTable),
65 MSG_MAP(RunBtc, PPSMC_MSG_RunBtc),
66 MSG_MAP(RequestI2CBus, PPSMC_MSG_RequestI2CBus),
67 MSG_MAP(ReleaseI2CBus, PPSMC_MSG_ReleaseI2CBus),
68 MSG_MAP(SetFloorSocVoltage, PPSMC_MSG_SetFloorSocVoltage),
69 MSG_MAP(SoftReset, PPSMC_MSG_SoftReset),
70 MSG_MAP(StartBacoMonitor, PPSMC_MSG_StartBacoMonitor),
71 MSG_MAP(CancelBacoMonitor, PPSMC_MSG_CancelBacoMonitor),
72 MSG_MAP(EnterBaco, PPSMC_MSG_EnterBaco),
73 MSG_MAP(SetSoftMinByFreq, PPSMC_MSG_SetSoftMinByFreq),
74 MSG_MAP(SetSoftMaxByFreq, PPSMC_MSG_SetSoftMaxByFreq),
75 MSG_MAP(SetHardMinByFreq, PPSMC_MSG_SetHardMinByFreq),
76 MSG_MAP(SetHardMaxByFreq, PPSMC_MSG_SetHardMaxByFreq),
77 MSG_MAP(GetMinDpmFreq, PPSMC_MSG_GetMinDpmFreq),
78 MSG_MAP(GetMaxDpmFreq, PPSMC_MSG_GetMaxDpmFreq),
79 MSG_MAP(GetDpmFreqByIndex, PPSMC_MSG_GetDpmFreqByIndex),
80 MSG_MAP(GetDpmClockFreq, PPSMC_MSG_GetDpmClockFreq),
81 MSG_MAP(GetSsVoltageByDpm, PPSMC_MSG_GetSsVoltageByDpm),
82 MSG_MAP(SetMemoryChannelConfig, PPSMC_MSG_SetMemoryChannelConfig),
83 MSG_MAP(SetGeminiMode, PPSMC_MSG_SetGeminiMode),
84 MSG_MAP(SetGeminiApertureHigh, PPSMC_MSG_SetGeminiApertureHigh),
85 MSG_MAP(SetGeminiApertureLow, PPSMC_MSG_SetGeminiApertureLow),
86 MSG_MAP(SetMinLinkDpmByIndex, PPSMC_MSG_SetMinLinkDpmByIndex),
87 MSG_MAP(OverridePcieParameters, PPSMC_MSG_OverridePcieParameters),
88 MSG_MAP(OverDriveSetPercentage, PPSMC_MSG_OverDriveSetPercentage),
89 MSG_MAP(SetMinDeepSleepDcefclk, PPSMC_MSG_SetMinDeepSleepDcefclk),
90 MSG_MAP(ReenableAcDcInterrupt, PPSMC_MSG_ReenableAcDcInterrupt),
91 MSG_MAP(NotifyPowerSource, PPSMC_MSG_NotifyPowerSource),
92 MSG_MAP(SetUclkFastSwitch, PPSMC_MSG_SetUclkFastSwitch),
93 MSG_MAP(SetUclkDownHyst, PPSMC_MSG_SetUclkDownHyst),
94 MSG_MAP(GetCurrentRpm, PPSMC_MSG_GetCurrentRpm),
95 MSG_MAP(SetVideoFps, PPSMC_MSG_SetVideoFps),
96 MSG_MAP(SetTjMax, PPSMC_MSG_SetTjMax),
97 MSG_MAP(SetFanTemperatureTarget, PPSMC_MSG_SetFanTemperatureTarget),
98 MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload),
99 MSG_MAP(DramLogSetDramAddrHigh, PPSMC_MSG_DramLogSetDramAddrHigh),
100 MSG_MAP(DramLogSetDramAddrLow, PPSMC_MSG_DramLogSetDramAddrLow),
101 MSG_MAP(DramLogSetDramSize, PPSMC_MSG_DramLogSetDramSize),
102 MSG_MAP(SetFanMaxRpm, PPSMC_MSG_SetFanMaxRpm),
103 MSG_MAP(SetFanMinPwm, PPSMC_MSG_SetFanMinPwm),
104 MSG_MAP(ConfigureGfxDidt, PPSMC_MSG_ConfigureGfxDidt),
105 MSG_MAP(NumOfDisplays, PPSMC_MSG_NumOfDisplays),
106 MSG_MAP(RemoveMargins, PPSMC_MSG_RemoveMargins),
107 MSG_MAP(ReadSerialNumTop32, PPSMC_MSG_ReadSerialNumTop32),
108 MSG_MAP(ReadSerialNumBottom32, PPSMC_MSG_ReadSerialNumBottom32),
109 MSG_MAP(SetSystemVirtualDramAddrHigh, PPSMC_MSG_SetSystemVirtualDramAddrHigh),
110 MSG_MAP(SetSystemVirtualDramAddrLow, PPSMC_MSG_SetSystemVirtualDramAddrLow),
111 MSG_MAP(WaflTest, PPSMC_MSG_WaflTest),
112 MSG_MAP(SetFclkGfxClkRatio, PPSMC_MSG_SetFclkGfxClkRatio),
113 MSG_MAP(AllowGfxOff, PPSMC_MSG_AllowGfxOff),
114 MSG_MAP(DisallowGfxOff, PPSMC_MSG_DisallowGfxOff),
115 MSG_MAP(GetPptLimit, PPSMC_MSG_GetPptLimit),
116 MSG_MAP(GetDcModeMaxDpmFreq, PPSMC_MSG_GetDcModeMaxDpmFreq),
117 MSG_MAP(GetDebugData, PPSMC_MSG_GetDebugData),
118 MSG_MAP(SetXgmiMode, PPSMC_MSG_SetXgmiMode),
119 MSG_MAP(RunAfllBtc, PPSMC_MSG_RunAfllBtc),
120 MSG_MAP(ExitBaco, PPSMC_MSG_ExitBaco),
121 MSG_MAP(PrepareMp1ForReset, PPSMC_MSG_PrepareMp1ForReset),
122 MSG_MAP(PrepareMp1ForShutdown, PPSMC_MSG_PrepareMp1ForShutdown),
123 MSG_MAP(SetMGpuFanBoostLimitRpm, PPSMC_MSG_SetMGpuFanBoostLimitRpm),
124 MSG_MAP(GetAVFSVoltageByDpm, PPSMC_MSG_GetAVFSVoltageByDpm),
127 static int vega20_get_smu_msg_index(struct smu_context *smc, uint32_t index)
129 if (index > SMU_MSG_MAX_COUNT || index > PPSMC_Message_Count)
131 return vega20_message_map[index];
135 static int vega20_allocate_dpm_context(struct smu_context *smu)
137 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
139 smu_dpm->dpm_context = kzalloc(sizeof(struct vega20_dpm_table),
141 if (!smu_dpm->dpm_context)
144 smu_dpm->dpm_context_size = sizeof(struct vega20_dpm_table);
149 static int vega20_setup_od8_information(struct smu_context *smu)
151 ATOM_Vega20_POWERPLAYTABLE *powerplay_table = NULL;
152 struct smu_table_context *table_context = &smu->smu_table;
154 uint32_t od_feature_count, od_feature_array_size,
155 od_setting_count, od_setting_array_size;
157 if (!table_context->power_play_table)
160 powerplay_table = table_context->power_play_table;
162 if (powerplay_table->OverDrive8Table.ucODTableRevision == 1) {
163 /* Setup correct ODFeatureCount, and store ODFeatureArray from
164 * powerplay table to od_feature_capabilities */
166 (le32_to_cpu(powerplay_table->OverDrive8Table.ODFeatureCount) >
167 ATOM_VEGA20_ODFEATURE_COUNT) ?
168 ATOM_VEGA20_ODFEATURE_COUNT :
169 le32_to_cpu(powerplay_table->OverDrive8Table.ODFeatureCount);
171 od_feature_array_size = sizeof(uint8_t) * od_feature_count;
173 if (table_context->od_feature_capabilities)
176 table_context->od_feature_capabilities = kzalloc(od_feature_array_size, GFP_KERNEL);
177 if (!table_context->od_feature_capabilities)
180 memcpy(table_context->od_feature_capabilities,
181 &powerplay_table->OverDrive8Table.ODFeatureCapabilities,
182 od_feature_array_size);
184 /* Setup correct ODSettingCount, and store ODSettingArray from
185 * powerplay table to od_settings_max and od_setting_min */
187 (le32_to_cpu(powerplay_table->OverDrive8Table.ODSettingCount) >
188 ATOM_VEGA20_ODSETTING_COUNT) ?
189 ATOM_VEGA20_ODSETTING_COUNT :
190 le32_to_cpu(powerplay_table->OverDrive8Table.ODSettingCount);
192 od_setting_array_size = sizeof(uint32_t) * od_setting_count;
194 if (table_context->od_settings_max)
197 table_context->od_settings_max = kzalloc(od_setting_array_size, GFP_KERNEL);
199 if (!table_context->od_settings_max) {
200 kfree(table_context->od_feature_capabilities);
201 table_context->od_feature_capabilities = NULL;
205 memcpy(table_context->od_settings_max,
206 &powerplay_table->OverDrive8Table.ODSettingsMax,
207 od_setting_array_size);
209 if (table_context->od_settings_min)
212 table_context->od_settings_min = kzalloc(od_setting_array_size, GFP_KERNEL);
214 if (!table_context->od_settings_min) {
215 kfree(table_context->od_feature_capabilities);
216 table_context->od_feature_capabilities = NULL;
217 kfree(table_context->od_settings_max);
218 table_context->od_settings_max = NULL;
222 memcpy(table_context->od_settings_min,
223 &powerplay_table->OverDrive8Table.ODSettingsMin,
224 od_setting_array_size);
230 static int vega20_store_powerplay_table(struct smu_context *smu)
232 ATOM_Vega20_POWERPLAYTABLE *powerplay_table = NULL;
233 struct smu_table_context *table_context = &smu->smu_table;
236 if (!table_context->power_play_table)
239 powerplay_table = table_context->power_play_table;
241 memcpy(table_context->driver_pptable, &powerplay_table->smcPPTable,
244 table_context->software_shutdown_temp = powerplay_table->usSoftwareShutdownTemp;
245 table_context->thermal_controller_type = powerplay_table->ucThermalControllerType;
247 ret = vega20_setup_od8_information(smu);
252 static int vega20_append_powerplay_table(struct smu_context *smu)
254 struct smu_table_context *table_context = &smu->smu_table;
255 PPTable_t *smc_pptable = table_context->driver_pptable;
256 struct atom_smc_dpm_info_v4_4 *smc_dpm_table;
259 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
262 ret = smu_get_atom_data_table(smu, index, NULL, NULL, NULL,
263 (uint8_t **)&smc_dpm_table);
267 smc_pptable->MaxVoltageStepGfx = smc_dpm_table->maxvoltagestepgfx;
268 smc_pptable->MaxVoltageStepSoc = smc_dpm_table->maxvoltagestepsoc;
270 smc_pptable->VddGfxVrMapping = smc_dpm_table->vddgfxvrmapping;
271 smc_pptable->VddSocVrMapping = smc_dpm_table->vddsocvrmapping;
272 smc_pptable->VddMem0VrMapping = smc_dpm_table->vddmem0vrmapping;
273 smc_pptable->VddMem1VrMapping = smc_dpm_table->vddmem1vrmapping;
275 smc_pptable->GfxUlvPhaseSheddingMask = smc_dpm_table->gfxulvphasesheddingmask;
276 smc_pptable->SocUlvPhaseSheddingMask = smc_dpm_table->soculvphasesheddingmask;
277 smc_pptable->ExternalSensorPresent = smc_dpm_table->externalsensorpresent;
279 smc_pptable->GfxMaxCurrent = smc_dpm_table->gfxmaxcurrent;
280 smc_pptable->GfxOffset = smc_dpm_table->gfxoffset;
281 smc_pptable->Padding_TelemetryGfx = smc_dpm_table->padding_telemetrygfx;
283 smc_pptable->SocMaxCurrent = smc_dpm_table->socmaxcurrent;
284 smc_pptable->SocOffset = smc_dpm_table->socoffset;
285 smc_pptable->Padding_TelemetrySoc = smc_dpm_table->padding_telemetrysoc;
287 smc_pptable->Mem0MaxCurrent = smc_dpm_table->mem0maxcurrent;
288 smc_pptable->Mem0Offset = smc_dpm_table->mem0offset;
289 smc_pptable->Padding_TelemetryMem0 = smc_dpm_table->padding_telemetrymem0;
291 smc_pptable->Mem1MaxCurrent = smc_dpm_table->mem1maxcurrent;
292 smc_pptable->Mem1Offset = smc_dpm_table->mem1offset;
293 smc_pptable->Padding_TelemetryMem1 = smc_dpm_table->padding_telemetrymem1;
295 smc_pptable->AcDcGpio = smc_dpm_table->acdcgpio;
296 smc_pptable->AcDcPolarity = smc_dpm_table->acdcpolarity;
297 smc_pptable->VR0HotGpio = smc_dpm_table->vr0hotgpio;
298 smc_pptable->VR0HotPolarity = smc_dpm_table->vr0hotpolarity;
300 smc_pptable->VR1HotGpio = smc_dpm_table->vr1hotgpio;
301 smc_pptable->VR1HotPolarity = smc_dpm_table->vr1hotpolarity;
302 smc_pptable->Padding1 = smc_dpm_table->padding1;
303 smc_pptable->Padding2 = smc_dpm_table->padding2;
305 smc_pptable->LedPin0 = smc_dpm_table->ledpin0;
306 smc_pptable->LedPin1 = smc_dpm_table->ledpin1;
307 smc_pptable->LedPin2 = smc_dpm_table->ledpin2;
309 smc_pptable->PllGfxclkSpreadEnabled = smc_dpm_table->pllgfxclkspreadenabled;
310 smc_pptable->PllGfxclkSpreadPercent = smc_dpm_table->pllgfxclkspreadpercent;
311 smc_pptable->PllGfxclkSpreadFreq = smc_dpm_table->pllgfxclkspreadfreq;
313 smc_pptable->UclkSpreadEnabled = 0;
314 smc_pptable->UclkSpreadPercent = smc_dpm_table->uclkspreadpercent;
315 smc_pptable->UclkSpreadFreq = smc_dpm_table->uclkspreadfreq;
317 smc_pptable->FclkSpreadEnabled = smc_dpm_table->fclkspreadenabled;
318 smc_pptable->FclkSpreadPercent = smc_dpm_table->fclkspreadpercent;
319 smc_pptable->FclkSpreadFreq = smc_dpm_table->fclkspreadfreq;
321 smc_pptable->FllGfxclkSpreadEnabled = smc_dpm_table->fllgfxclkspreadenabled;
322 smc_pptable->FllGfxclkSpreadPercent = smc_dpm_table->fllgfxclkspreadpercent;
323 smc_pptable->FllGfxclkSpreadFreq = smc_dpm_table->fllgfxclkspreadfreq;
325 for (i = 0; i < I2C_CONTROLLER_NAME_COUNT; i++) {
326 smc_pptable->I2cControllers[i].Enabled =
327 smc_dpm_table->i2ccontrollers[i].enabled;
328 smc_pptable->I2cControllers[i].SlaveAddress =
329 smc_dpm_table->i2ccontrollers[i].slaveaddress;
330 smc_pptable->I2cControllers[i].ControllerPort =
331 smc_dpm_table->i2ccontrollers[i].controllerport;
332 smc_pptable->I2cControllers[i].ThermalThrottler =
333 smc_dpm_table->i2ccontrollers[i].thermalthrottler;
334 smc_pptable->I2cControllers[i].I2cProtocol =
335 smc_dpm_table->i2ccontrollers[i].i2cprotocol;
336 smc_pptable->I2cControllers[i].I2cSpeed =
337 smc_dpm_table->i2ccontrollers[i].i2cspeed;
343 static int vega20_check_powerplay_table(struct smu_context *smu)
345 ATOM_Vega20_POWERPLAYTABLE *powerplay_table = NULL;
346 struct smu_table_context *table_context = &smu->smu_table;
348 powerplay_table = table_context->power_play_table;
350 if (powerplay_table->sHeader.format_revision < ATOM_VEGA20_TABLE_REVISION_VEGA20) {
351 pr_err("Unsupported PPTable format!");
355 if (!powerplay_table->sHeader.structuresize) {
356 pr_err("Invalid PowerPlay Table!");
363 static int vega20_run_btc_afll(struct smu_context *smu)
365 return smu_send_smc_msg(smu, SMU_MSG_RunAfllBtc);
369 vega20_get_unallowed_feature_mask(struct smu_context *smu,
370 uint32_t *feature_mask, uint32_t num)
375 feature_mask[0] = 0xE0041C00;
376 feature_mask[1] = 0xFFFFFFFE; /* bit32~bit63 is Unsupported */
382 vega20_set_single_dpm_table(struct smu_context *smu,
383 struct vega20_single_dpm_table *single_dpm_table,
387 uint32_t i, num_of_levels, clk;
389 ret = smu_send_smc_msg_with_param(smu,
390 SMU_MSG_GetDpmFreqByIndex,
391 (clk_id << 16 | 0xFF));
393 pr_err("[GetNumOfDpmLevel] failed to get dpm levels!");
397 smu_read_smc_arg(smu, &num_of_levels);
398 if (!num_of_levels) {
399 pr_err("[GetNumOfDpmLevel] number of clk levels is invalid!");
403 single_dpm_table->count = num_of_levels;
405 for (i = 0; i < num_of_levels; i++) {
406 ret = smu_send_smc_msg_with_param(smu,
407 SMU_MSG_GetDpmFreqByIndex,
410 pr_err("[GetDpmFreqByIndex] failed to get dpm freq by index!");
413 smu_read_smc_arg(smu, &clk);
415 pr_err("[GetDpmFreqByIndex] clk value is invalid!");
418 single_dpm_table->dpm_levels[i].value = clk;
419 single_dpm_table->dpm_levels[i].enabled = true;
424 static void vega20_init_single_dpm_state(struct vega20_dpm_state *dpm_state)
426 dpm_state->soft_min_level = 0x0;
427 dpm_state->soft_max_level = 0xffff;
428 dpm_state->hard_min_level = 0x0;
429 dpm_state->hard_max_level = 0xffff;
432 static int vega20_set_default_dpm_table(struct smu_context *smu)
436 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
437 struct vega20_dpm_table *dpm_table = NULL;
438 struct vega20_single_dpm_table *single_dpm_table;
440 dpm_table = smu_dpm->dpm_context;
443 single_dpm_table = &(dpm_table->soc_table);
445 if (smu_feature_is_enabled(smu, FEATURE_DPM_SOCCLK_BIT)) {
446 ret = vega20_set_single_dpm_table(smu, single_dpm_table,
449 pr_err("[SetupDefaultDpmTable] failed to get socclk dpm levels!");
453 single_dpm_table->count = 1;
454 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.socclk / 100;
456 vega20_init_single_dpm_state(&(single_dpm_table->dpm_state));
459 single_dpm_table = &(dpm_table->gfx_table);
461 if (smu_feature_is_enabled(smu, FEATURE_DPM_GFXCLK_BIT)) {
462 ret = vega20_set_single_dpm_table(smu, single_dpm_table,
465 pr_err("[SetupDefaultDpmTable] failed to get gfxclk dpm levels!");
469 single_dpm_table->count = 1;
470 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
472 vega20_init_single_dpm_state(&(single_dpm_table->dpm_state));
475 single_dpm_table = &(dpm_table->mem_table);
477 if (smu_feature_is_enabled(smu, FEATURE_DPM_UCLK_BIT)) {
478 ret = vega20_set_single_dpm_table(smu, single_dpm_table,
481 pr_err("[SetupDefaultDpmTable] failed to get memclk dpm levels!");
485 single_dpm_table->count = 1;
486 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.uclk / 100;
488 vega20_init_single_dpm_state(&(single_dpm_table->dpm_state));
492 single_dpm_table = &(dpm_table->eclk_table);
494 if (feature->fea_enabled[FEATURE_DPM_VCE_BIT]) {
495 ret = vega20_set_single_dpm_table(smu, single_dpm_table, PPCLK_ECLK);
497 pr_err("[SetupDefaultDpmTable] failed to get eclk dpm levels!");
501 single_dpm_table->count = 1;
502 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.eclock / 100;
504 vega20_init_single_dpm_state(&(single_dpm_table->dpm_state));
507 single_dpm_table = &(dpm_table->vclk_table);
509 if (feature->fea_enabled[FEATURE_DPM_UVD_BIT]) {
510 ret = vega20_set_single_dpm_table(smu, single_dpm_table, PPCLK_VCLK);
512 pr_err("[SetupDefaultDpmTable] failed to get vclk dpm levels!");
516 single_dpm_table->count = 1;
517 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.vclock / 100;
519 vega20_init_single_dpm_state(&(single_dpm_table->dpm_state));
522 single_dpm_table = &(dpm_table->dclk_table);
524 if (feature->fea_enabled[FEATURE_DPM_UVD_BIT]) {
525 ret = vega20_set_single_dpm_table(smu, single_dpm_table, PPCLK_DCLK);
527 pr_err("[SetupDefaultDpmTable] failed to get dclk dpm levels!");
531 single_dpm_table->count = 1;
532 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dclock / 100;
534 vega20_init_single_dpm_state(&(single_dpm_table->dpm_state));
538 single_dpm_table = &(dpm_table->dcef_table);
540 if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) {
541 ret = vega20_set_single_dpm_table(smu, single_dpm_table,
544 pr_err("[SetupDefaultDpmTable] failed to get dcefclk dpm levels!");
548 single_dpm_table->count = 1;
549 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100;
551 vega20_init_single_dpm_state(&(single_dpm_table->dpm_state));
554 single_dpm_table = &(dpm_table->pixel_table);
556 if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) {
557 ret = vega20_set_single_dpm_table(smu, single_dpm_table,
560 pr_err("[SetupDefaultDpmTable] failed to get pixclk dpm levels!");
564 single_dpm_table->count = 0;
566 vega20_init_single_dpm_state(&(single_dpm_table->dpm_state));
569 single_dpm_table = &(dpm_table->display_table);
571 if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) {
572 ret = vega20_set_single_dpm_table(smu, single_dpm_table,
575 pr_err("[SetupDefaultDpmTable] failed to get dispclk dpm levels!");
579 single_dpm_table->count = 0;
581 vega20_init_single_dpm_state(&(single_dpm_table->dpm_state));
584 single_dpm_table = &(dpm_table->phy_table);
586 if (smu_feature_is_enabled(smu, FEATURE_DPM_DCEFCLK_BIT)) {
587 ret = vega20_set_single_dpm_table(smu, single_dpm_table,
590 pr_err("[SetupDefaultDpmTable] failed to get phyclk dpm levels!");
594 single_dpm_table->count = 0;
596 vega20_init_single_dpm_state(&(single_dpm_table->dpm_state));
599 single_dpm_table = &(dpm_table->fclk_table);
601 if (smu_feature_is_enabled(smu,FEATURE_DPM_FCLK_BIT)) {
602 ret = vega20_set_single_dpm_table(smu, single_dpm_table,
605 pr_err("[SetupDefaultDpmTable] failed to get fclk dpm levels!");
609 single_dpm_table->count = 0;
611 vega20_init_single_dpm_state(&(single_dpm_table->dpm_state));
616 static int vega20_populate_umd_state_clk(struct smu_context *smu)
618 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
619 struct vega20_dpm_table *dpm_table = NULL;
620 struct vega20_single_dpm_table *gfx_table = NULL;
621 struct vega20_single_dpm_table *mem_table = NULL;
623 dpm_table = smu_dpm->dpm_context;
624 gfx_table = &(dpm_table->gfx_table);
625 mem_table = &(dpm_table->mem_table);
627 smu->pstate_sclk = gfx_table->dpm_levels[0].value;
628 smu->pstate_mclk = mem_table->dpm_levels[0].value;
630 if (gfx_table->count > VEGA20_UMD_PSTATE_GFXCLK_LEVEL &&
631 mem_table->count > VEGA20_UMD_PSTATE_MCLK_LEVEL) {
632 smu->pstate_sclk = gfx_table->dpm_levels[VEGA20_UMD_PSTATE_GFXCLK_LEVEL].value;
633 smu->pstate_mclk = mem_table->dpm_levels[VEGA20_UMD_PSTATE_MCLK_LEVEL].value;
636 smu->pstate_sclk = smu->pstate_sclk * 100;
637 smu->pstate_mclk = smu->pstate_mclk * 100;
642 static int vega20_get_clk_table(struct smu_context *smu,
643 struct pp_clock_levels_with_latency *clocks,
644 struct vega20_single_dpm_table *dpm_table)
648 count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count;
649 clocks->num_levels = count;
651 for (i = 0; i < count; i++) {
652 clocks->data[i].clocks_in_khz =
653 dpm_table->dpm_levels[i].value * 1000;
654 clocks->data[i].latency_in_us = 0;
660 static int vega20_print_clk_levels(struct smu_context *smu,
661 enum pp_clock_type type, char *buf)
663 int i, now, size = 0;
665 struct pp_clock_levels_with_latency clocks;
666 struct vega20_single_dpm_table *single_dpm_table;
667 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
668 struct vega20_dpm_table *dpm_table = NULL;
670 dpm_table = smu_dpm->dpm_context;
674 ret = smu_get_current_clk_freq(smu, PPCLK_GFXCLK, &now);
676 pr_err("Attempt to get current gfx clk Failed!");
680 single_dpm_table = &(dpm_table->gfx_table);
681 ret = vega20_get_clk_table(smu, &clocks, single_dpm_table);
683 pr_err("Attempt to get gfx clk levels Failed!");
687 for (i = 0; i < clocks.num_levels; i++)
688 size += sprintf(buf + size, "%d: %uMhz %s\n", i,
689 clocks.data[i].clocks_in_khz / 1000,
690 (clocks.data[i].clocks_in_khz == now * 10)
695 ret = smu_get_current_clk_freq(smu, PPCLK_UCLK, &now);
697 pr_err("Attempt to get current mclk Failed!");
701 single_dpm_table = &(dpm_table->mem_table);
702 ret = vega20_get_clk_table(smu, &clocks, single_dpm_table);
704 pr_err("Attempt to get memory clk levels Failed!");
708 for (i = 0; i < clocks.num_levels; i++)
709 size += sprintf(buf + size, "%d: %uMhz %s\n",
710 i, clocks.data[i].clocks_in_khz / 1000,
711 (clocks.data[i].clocks_in_khz == now * 10)
720 static int vega20_upload_dpm_min_level(struct smu_context *smu)
722 struct vega20_dpm_table *dpm_table;
723 struct vega20_single_dpm_table *single_dpm_table;
727 dpm_table = smu->smu_dpm.dpm_context;
729 if (smu_feature_is_enabled(smu, FEATURE_DPM_GFXCLK_BIT)) {
730 single_dpm_table = &(dpm_table->gfx_table);
731 min_freq = single_dpm_table->dpm_state.soft_min_level;
732 ret = smu_send_smc_msg_with_param(smu,
733 SMU_MSG_SetSoftMinByFreq,
734 (PPCLK_GFXCLK << 16) | (min_freq & 0xffff));
736 pr_err("Failed to set soft min gfxclk !\n");
741 if (smu_feature_is_enabled(smu, FEATURE_DPM_UCLK_BIT)) {
742 single_dpm_table = &(dpm_table->mem_table);
743 min_freq = single_dpm_table->dpm_state.soft_min_level;
744 ret = smu_send_smc_msg_with_param(smu,
745 SMU_MSG_SetSoftMinByFreq,
746 (PPCLK_UCLK << 16) | (min_freq & 0xffff));
748 pr_err("Failed to set soft min memclk !\n");
756 static int vega20_upload_dpm_max_level(struct smu_context *smu)
758 struct vega20_dpm_table *dpm_table;
759 struct vega20_single_dpm_table *single_dpm_table;
763 dpm_table = smu->smu_dpm.dpm_context;
765 if (smu_feature_is_enabled(smu, FEATURE_DPM_GFXCLK_BIT)) {
766 single_dpm_table = &(dpm_table->gfx_table);
767 max_freq = single_dpm_table->dpm_state.soft_max_level;
768 ret = smu_send_smc_msg_with_param(smu,
769 SMU_MSG_SetSoftMaxByFreq,
770 (PPCLK_GFXCLK << 16) | (max_freq & 0xffff));
772 pr_err("Failed to set soft max gfxclk !\n");
777 if (smu_feature_is_enabled(smu, FEATURE_DPM_UCLK_BIT)) {
778 single_dpm_table = &(dpm_table->mem_table);
779 max_freq = single_dpm_table->dpm_state.soft_max_level;
780 ret = smu_send_smc_msg_with_param(smu,
781 SMU_MSG_SetSoftMaxByFreq,
782 (PPCLK_UCLK << 16) | (max_freq & 0xffff));
784 pr_err("Failed to set soft max memclk !\n");
792 static int vega20_force_clk_levels(struct smu_context *smu,
793 enum pp_clock_type type, uint32_t mask)
795 struct vega20_dpm_table *dpm_table;
796 struct vega20_single_dpm_table *single_dpm_table;
797 uint32_t soft_min_level, soft_max_level;
800 soft_min_level = mask ? (ffs(mask) - 1) : 0;
801 soft_max_level = mask ? (fls(mask) - 1) : 0;
803 dpm_table = smu->smu_dpm.dpm_context;
807 single_dpm_table = &(dpm_table->gfx_table);
809 if (soft_max_level >= single_dpm_table->count) {
810 pr_err("Clock level specified %d is over max allowed %d\n",
811 soft_max_level, single_dpm_table->count - 1);
815 single_dpm_table->dpm_state.soft_min_level =
816 single_dpm_table->dpm_levels[soft_min_level].value;
817 single_dpm_table->dpm_state.soft_max_level =
818 single_dpm_table->dpm_levels[soft_max_level].value;
820 ret = vega20_upload_dpm_min_level(smu);
822 pr_err("Failed to upload boot level to lowest!\n");
826 ret = vega20_upload_dpm_max_level(smu);
828 pr_err("Failed to upload dpm max level to highest!\n");
835 single_dpm_table = &(dpm_table->mem_table);
837 if (soft_max_level >= single_dpm_table->count) {
838 pr_err("Clock level specified %d is over max allowed %d\n",
839 soft_max_level, single_dpm_table->count - 1);
843 single_dpm_table->dpm_state.soft_min_level =
844 single_dpm_table->dpm_levels[soft_min_level].value;
845 single_dpm_table->dpm_state.soft_max_level =
846 single_dpm_table->dpm_levels[soft_max_level].value;
848 ret = vega20_upload_dpm_min_level(smu);
850 pr_err("Failed to upload boot level to lowest!\n");
854 ret = vega20_upload_dpm_max_level(smu);
856 pr_err("Failed to upload dpm max level to highest!\n");
869 static int vega20_get_clock_by_type_with_latency(struct smu_context *smu,
870 enum amd_pp_clock_type type,
871 struct pp_clock_levels_with_latency *clocks)
874 struct vega20_single_dpm_table *single_dpm_table;
875 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
876 struct vega20_dpm_table *dpm_table = NULL;
878 dpm_table = smu_dpm->dpm_context;
880 mutex_lock(&smu->mutex);
883 case amd_pp_sys_clock:
884 single_dpm_table = &(dpm_table->gfx_table);
885 ret = vega20_get_clk_table(smu, clocks, single_dpm_table);
887 case amd_pp_mem_clock:
888 single_dpm_table = &(dpm_table->mem_table);
889 ret = vega20_get_clk_table(smu, clocks, single_dpm_table);
891 case amd_pp_dcef_clock:
892 single_dpm_table = &(dpm_table->dcef_table);
893 ret = vega20_get_clk_table(smu, clocks, single_dpm_table);
895 case amd_pp_soc_clock:
896 single_dpm_table = &(dpm_table->soc_table);
897 ret = vega20_get_clk_table(smu, clocks, single_dpm_table);
903 mutex_unlock(&smu->mutex);
907 static int vega20_overdrive_get_gfx_clk_base_voltage(struct smu_context *smu,
913 ret = smu_send_smc_msg_with_param(smu,
914 SMU_MSG_GetAVFSVoltageByDpm,
915 ((AVFS_CURVE << 24) | (OD8_HOTCURVE_TEMPERATURE << 16) | freq));
917 pr_err("[GetBaseVoltage] failed to get GFXCLK AVFS voltage from SMU!");
921 smu_read_smc_arg(smu, voltage);
922 *voltage = *voltage / VOLTAGE_SCALE;
927 static int vega20_set_default_od8_setttings(struct smu_context *smu)
929 struct smu_table_context *table_context = &smu->smu_table;
930 OverDriveTable_t *od_table = (OverDriveTable_t *)(table_context->overdrive_table);
931 struct vega20_od8_settings *od8_settings = NULL;
932 PPTable_t *smc_pptable = table_context->driver_pptable;
935 if (table_context->od8_settings)
938 table_context->od8_settings = kzalloc(sizeof(struct vega20_od8_settings), GFP_KERNEL);
940 if (!table_context->od8_settings)
943 memset(table_context->od8_settings, 0, sizeof(struct vega20_od8_settings));
944 od8_settings = (struct vega20_od8_settings *)table_context->od8_settings;
946 if (smu_feature_is_enabled(smu, FEATURE_DPM_SOCCLK_BIT)) {
947 if (table_context->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_GFXCLK_LIMITS] &&
948 table_context->od_settings_max[OD8_SETTING_GFXCLK_FMAX] > 0 &&
949 table_context->od_settings_min[OD8_SETTING_GFXCLK_FMIN] > 0 &&
950 (table_context->od_settings_max[OD8_SETTING_GFXCLK_FMAX] >=
951 table_context->od_settings_min[OD8_SETTING_GFXCLK_FMIN])) {
952 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMIN].feature_id =
954 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMAX].feature_id =
956 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMIN].default_value =
957 od_table->GfxclkFmin;
958 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FMAX].default_value =
959 od_table->GfxclkFmax;
962 if (table_context->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_GFXCLK_CURVE] &&
963 (table_context->od_settings_min[OD8_SETTING_GFXCLK_VOLTAGE1] >=
964 smc_pptable->MinVoltageGfx / VOLTAGE_SCALE) &&
965 (table_context->od_settings_max[OD8_SETTING_GFXCLK_VOLTAGE3] <=
966 smc_pptable->MaxVoltageGfx / VOLTAGE_SCALE) &&
967 (table_context->od_settings_min[OD8_SETTING_GFXCLK_VOLTAGE1] <=
968 table_context->od_settings_max[OD8_SETTING_GFXCLK_VOLTAGE3])) {
969 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ1].feature_id =
971 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].feature_id =
973 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ2].feature_id =
975 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].feature_id =
977 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ3].feature_id =
979 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].feature_id =
982 od_table->GfxclkFreq1 = od_table->GfxclkFmin;
983 od_table->GfxclkFreq2 = (od_table->GfxclkFmin + od_table->GfxclkFmax) / 2;
984 od_table->GfxclkFreq3 = od_table->GfxclkFmax;
985 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ1].default_value =
986 od_table->GfxclkFreq1;
987 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ2].default_value =
988 od_table->GfxclkFreq2;
989 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_FREQ3].default_value =
990 od_table->GfxclkFreq3;
992 ret = vega20_overdrive_get_gfx_clk_base_voltage(smu,
993 &od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].default_value,
994 od_table->GfxclkFreq1);
996 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].default_value = 0;
997 od_table->GfxclkVolt1 =
998 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE1].default_value
1000 ret = vega20_overdrive_get_gfx_clk_base_voltage(smu,
1001 &od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].default_value,
1002 od_table->GfxclkFreq2);
1004 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].default_value = 0;
1005 od_table->GfxclkVolt2 =
1006 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE2].default_value
1008 ret = vega20_overdrive_get_gfx_clk_base_voltage(smu,
1009 &od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].default_value,
1010 od_table->GfxclkFreq3);
1012 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].default_value = 0;
1013 od_table->GfxclkVolt3 =
1014 od8_settings->od8_settings_array[OD8_SETTING_GFXCLK_VOLTAGE3].default_value
1019 if (smu_feature_is_enabled(smu, FEATURE_DPM_UCLK_BIT)) {
1020 if (table_context->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_UCLK_MAX] &&
1021 table_context->od_settings_min[OD8_SETTING_UCLK_FMAX] > 0 &&
1022 table_context->od_settings_max[OD8_SETTING_UCLK_FMAX] > 0 &&
1023 (table_context->od_settings_max[OD8_SETTING_UCLK_FMAX] >=
1024 table_context->od_settings_min[OD8_SETTING_UCLK_FMAX])) {
1025 od8_settings->od8_settings_array[OD8_SETTING_UCLK_FMAX].feature_id =
1027 od8_settings->od8_settings_array[OD8_SETTING_UCLK_FMAX].default_value =
1032 if (table_context->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_POWER_LIMIT] &&
1033 table_context->od_settings_min[OD8_SETTING_POWER_PERCENTAGE] > 0 &&
1034 table_context->od_settings_min[OD8_SETTING_POWER_PERCENTAGE] <= 100 &&
1035 table_context->od_settings_max[OD8_SETTING_POWER_PERCENTAGE] > 0 &&
1036 table_context->od_settings_max[OD8_SETTING_POWER_PERCENTAGE] <= 100) {
1037 od8_settings->od8_settings_array[OD8_SETTING_POWER_PERCENTAGE].feature_id =
1039 od8_settings->od8_settings_array[OD8_SETTING_POWER_PERCENTAGE].default_value =
1040 od_table->OverDrivePct;
1043 if (smu_feature_is_enabled(smu, FEATURE_FAN_CONTROL_BIT)) {
1044 if (table_context->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_FAN_ACOUSTIC_LIMIT] &&
1045 table_context->od_settings_min[OD8_SETTING_FAN_ACOUSTIC_LIMIT] > 0 &&
1046 table_context->od_settings_max[OD8_SETTING_FAN_ACOUSTIC_LIMIT] > 0 &&
1047 (table_context->od_settings_max[OD8_SETTING_FAN_ACOUSTIC_LIMIT] >=
1048 table_context->od_settings_min[OD8_SETTING_FAN_ACOUSTIC_LIMIT])) {
1049 od8_settings->od8_settings_array[OD8_SETTING_FAN_ACOUSTIC_LIMIT].feature_id =
1050 OD8_ACOUSTIC_LIMIT_SCLK;
1051 od8_settings->od8_settings_array[OD8_SETTING_FAN_ACOUSTIC_LIMIT].default_value =
1052 od_table->FanMaximumRpm;
1055 if (table_context->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_FAN_SPEED_MIN] &&
1056 table_context->od_settings_min[OD8_SETTING_FAN_MIN_SPEED] > 0 &&
1057 table_context->od_settings_max[OD8_SETTING_FAN_MIN_SPEED] > 0 &&
1058 (table_context->od_settings_max[OD8_SETTING_FAN_MIN_SPEED] >=
1059 table_context->od_settings_min[OD8_SETTING_FAN_MIN_SPEED])) {
1060 od8_settings->od8_settings_array[OD8_SETTING_FAN_MIN_SPEED].feature_id =
1062 od8_settings->od8_settings_array[OD8_SETTING_FAN_MIN_SPEED].default_value =
1063 od_table->FanMinimumPwm * smc_pptable->FanMaximumRpm / 100;
1067 if (smu_feature_is_enabled(smu, FEATURE_THERMAL_BIT)) {
1068 if (table_context->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_TEMPERATURE_FAN] &&
1069 table_context->od_settings_min[OD8_SETTING_FAN_TARGET_TEMP] > 0 &&
1070 table_context->od_settings_max[OD8_SETTING_FAN_TARGET_TEMP] > 0 &&
1071 (table_context->od_settings_max[OD8_SETTING_FAN_TARGET_TEMP] >=
1072 table_context->od_settings_min[OD8_SETTING_FAN_TARGET_TEMP])) {
1073 od8_settings->od8_settings_array[OD8_SETTING_FAN_TARGET_TEMP].feature_id =
1074 OD8_TEMPERATURE_FAN;
1075 od8_settings->od8_settings_array[OD8_SETTING_FAN_TARGET_TEMP].default_value =
1076 od_table->FanTargetTemperature;
1079 if (table_context->od_feature_capabilities[ATOM_VEGA20_ODFEATURE_TEMPERATURE_SYSTEM] &&
1080 table_context->od_settings_min[OD8_SETTING_OPERATING_TEMP_MAX] > 0 &&
1081 table_context->od_settings_max[OD8_SETTING_OPERATING_TEMP_MAX] > 0 &&
1082 (table_context->od_settings_max[OD8_SETTING_OPERATING_TEMP_MAX] >=
1083 table_context->od_settings_min[OD8_SETTING_OPERATING_TEMP_MAX])) {
1084 od8_settings->od8_settings_array[OD8_SETTING_OPERATING_TEMP_MAX].feature_id =
1085 OD8_TEMPERATURE_SYSTEM;
1086 od8_settings->od8_settings_array[OD8_SETTING_OPERATING_TEMP_MAX].default_value =
1087 od_table->MaxOpTemp;
1091 for (i = 0; i < OD8_SETTING_COUNT; i++) {
1092 if (od8_settings->od8_settings_array[i].feature_id) {
1093 od8_settings->od8_settings_array[i].min_value =
1094 table_context->od_settings_min[i];
1095 od8_settings->od8_settings_array[i].max_value =
1096 table_context->od_settings_max[i];
1097 od8_settings->od8_settings_array[i].current_value =
1098 od8_settings->od8_settings_array[i].default_value;
1100 od8_settings->od8_settings_array[i].min_value = 0;
1101 od8_settings->od8_settings_array[i].max_value = 0;
1102 od8_settings->od8_settings_array[i].current_value = 0;
1109 static const struct pptable_funcs vega20_ppt_funcs = {
1110 .alloc_dpm_context = vega20_allocate_dpm_context,
1111 .store_powerplay_table = vega20_store_powerplay_table,
1112 .check_powerplay_table = vega20_check_powerplay_table,
1113 .append_powerplay_table = vega20_append_powerplay_table,
1114 .get_smu_msg_index = vega20_get_smu_msg_index,
1115 .run_afll_btc = vega20_run_btc_afll,
1116 .get_unallowed_feature_mask = vega20_get_unallowed_feature_mask,
1117 .set_default_dpm_table = vega20_set_default_dpm_table,
1118 .populate_umd_state_clk = vega20_populate_umd_state_clk,
1119 .print_clk_levels = vega20_print_clk_levels,
1120 .force_clk_levels = vega20_force_clk_levels,
1121 .get_clock_by_type_with_latency = vega20_get_clock_by_type_with_latency,
1122 .set_default_od8_settings = vega20_set_default_od8_setttings,
1125 void vega20_set_ppt_funcs(struct smu_context *smu)
1127 smu->ppt_funcs = &vega20_ppt_funcs;