1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#define SWSMU_CODE_LAYER_L2
25
26#include <linux/firmware.h>
27#include <linux/pci.h>
28#include <linux/i2c.h>
29#include "amdgpu.h"
30#include "amdgpu_smu.h"
31#include "atomfirmware.h"
32#include "amdgpu_atomfirmware.h"
33#include "amdgpu_atombios.h"
34#include "soc15_common.h"
35#include "smu_v11_0.h"
36#include "smu11_driver_if_navi10.h"
37#include "atom.h"
38#include "navi10_ppt.h"
39#include "smu_v11_0_pptable.h"
40#include "smu_v11_0_ppsmc.h"
41#include "nbio/nbio_2_3_offset.h"
42#include "nbio/nbio_2_3_sh_mask.h"
43#include "thm/thm_11_0_2_offset.h"
44#include "thm/thm_11_0_2_sh_mask.h"
45
46#include "asic_reg/mp/mp_11_0_sh_mask.h"
47#include "smu_cmn.h"
48#include "smu_11_0_cdr_table.h"
49
50
51
52
53
54
55#undef pr_err
56#undef pr_warn
57#undef pr_info
58#undef pr_debug
59
60#define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c))
61
62#define FEATURE_MASK(feature) (1ULL << feature)
63#define SMC_DPM_FEATURE ( \
64 FEATURE_MASK(FEATURE_DPM_PREFETCHER_BIT) | \
65 FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT) | \
66 FEATURE_MASK(FEATURE_DPM_GFX_PACE_BIT) | \
67 FEATURE_MASK(FEATURE_DPM_UCLK_BIT) | \
68 FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT) | \
69 FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT) | \
70 FEATURE_MASK(FEATURE_DPM_LINK_BIT) | \
71 FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT))
72
73static struct cmn2asic_msg_mapping navi10_message_map[SMU_MSG_MAX_COUNT] = {
74 MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1),
75 MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1),
76 MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 1),
77 MSG_MAP(SetAllowedFeaturesMaskLow, PPSMC_MSG_SetAllowedFeaturesMaskLow, 0),
78 MSG_MAP(SetAllowedFeaturesMaskHigh, PPSMC_MSG_SetAllowedFeaturesMaskHigh, 0),
79 MSG_MAP(EnableAllSmuFeatures, PPSMC_MSG_EnableAllSmuFeatures, 0),
80 MSG_MAP(DisableAllSmuFeatures, PPSMC_MSG_DisableAllSmuFeatures, 0),
81 MSG_MAP(EnableSmuFeaturesLow, PPSMC_MSG_EnableSmuFeaturesLow, 1),
82 MSG_MAP(EnableSmuFeaturesHigh, PPSMC_MSG_EnableSmuFeaturesHigh, 1),
83 MSG_MAP(DisableSmuFeaturesLow, PPSMC_MSG_DisableSmuFeaturesLow, 1),
84 MSG_MAP(DisableSmuFeaturesHigh, PPSMC_MSG_DisableSmuFeaturesHigh, 1),
85 MSG_MAP(GetEnabledSmuFeaturesLow, PPSMC_MSG_GetEnabledSmuFeaturesLow, 1),
86 MSG_MAP(GetEnabledSmuFeaturesHigh, PPSMC_MSG_GetEnabledSmuFeaturesHigh, 1),
87 MSG_MAP(SetWorkloadMask, PPSMC_MSG_SetWorkloadMask, 1),
88 MSG_MAP(SetPptLimit, PPSMC_MSG_SetPptLimit, 0),
89 MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 0),
90 MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 0),
91 MSG_MAP(SetToolsDramAddrHigh, PPSMC_MSG_SetToolsDramAddrHigh, 0),
92 MSG_MAP(SetToolsDramAddrLow, PPSMC_MSG_SetToolsDramAddrLow, 0),
93 MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 0),
94 MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 0),
95 MSG_MAP(UseDefaultPPTable, PPSMC_MSG_UseDefaultPPTable, 0),
96 MSG_MAP(UseBackupPPTable, PPSMC_MSG_UseBackupPPTable, 0),
97 MSG_MAP(RunBtc, PPSMC_MSG_RunBtc, 0),
98 MSG_MAP(EnterBaco, PPSMC_MSG_EnterBaco, 0),
99 MSG_MAP(SetSoftMinByFreq, PPSMC_MSG_SetSoftMinByFreq, 0),
100 MSG_MAP(SetSoftMaxByFreq, PPSMC_MSG_SetSoftMaxByFreq, 0),
101 MSG_MAP(SetHardMinByFreq, PPSMC_MSG_SetHardMinByFreq, 1),
102 MSG_MAP(SetHardMaxByFreq, PPSMC_MSG_SetHardMaxByFreq, 0),
103 MSG_MAP(GetMinDpmFreq, PPSMC_MSG_GetMinDpmFreq, 1),
104 MSG_MAP(GetMaxDpmFreq, PPSMC_MSG_GetMaxDpmFreq, 1),
105 MSG_MAP(GetDpmFreqByIndex, PPSMC_MSG_GetDpmFreqByIndex, 1),
106 MSG_MAP(SetMemoryChannelConfig, PPSMC_MSG_SetMemoryChannelConfig, 0),
107 MSG_MAP(SetGeminiMode, PPSMC_MSG_SetGeminiMode, 0),
108 MSG_MAP(SetGeminiApertureHigh, PPSMC_MSG_SetGeminiApertureHigh, 0),
109 MSG_MAP(SetGeminiApertureLow, PPSMC_MSG_SetGeminiApertureLow, 0),
110 MSG_MAP(OverridePcieParameters, PPSMC_MSG_OverridePcieParameters, 0),
111 MSG_MAP(SetMinDeepSleepDcefclk, PPSMC_MSG_SetMinDeepSleepDcefclk, 0),
112 MSG_MAP(ReenableAcDcInterrupt, PPSMC_MSG_ReenableAcDcInterrupt, 0),
113 MSG_MAP(NotifyPowerSource, PPSMC_MSG_NotifyPowerSource, 0),
114 MSG_MAP(SetUclkFastSwitch, PPSMC_MSG_SetUclkFastSwitch, 0),
115 MSG_MAP(SetVideoFps, PPSMC_MSG_SetVideoFps, 0),
116 MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 1),
117 MSG_MAP(DramLogSetDramAddrHigh, PPSMC_MSG_DramLogSetDramAddrHigh, 0),
118 MSG_MAP(DramLogSetDramAddrLow, PPSMC_MSG_DramLogSetDramAddrLow, 0),
119 MSG_MAP(DramLogSetDramSize, PPSMC_MSG_DramLogSetDramSize, 0),
120 MSG_MAP(ConfigureGfxDidt, PPSMC_MSG_ConfigureGfxDidt, 0),
121 MSG_MAP(NumOfDisplays, PPSMC_MSG_NumOfDisplays, 0),
122 MSG_MAP(SetSystemVirtualDramAddrHigh, PPSMC_MSG_SetSystemVirtualDramAddrHigh, 0),
123 MSG_MAP(SetSystemVirtualDramAddrLow, PPSMC_MSG_SetSystemVirtualDramAddrLow, 0),
124 MSG_MAP(AllowGfxOff, PPSMC_MSG_AllowGfxOff, 0),
125 MSG_MAP(DisallowGfxOff, PPSMC_MSG_DisallowGfxOff, 0),
126 MSG_MAP(GetPptLimit, PPSMC_MSG_GetPptLimit, 0),
127 MSG_MAP(GetDcModeMaxDpmFreq, PPSMC_MSG_GetDcModeMaxDpmFreq, 1),
128 MSG_MAP(GetDebugData, PPSMC_MSG_GetDebugData, 0),
129 MSG_MAP(ExitBaco, PPSMC_MSG_ExitBaco, 0),
130 MSG_MAP(PrepareMp1ForReset, PPSMC_MSG_PrepareMp1ForReset, 0),
131 MSG_MAP(PrepareMp1ForShutdown, PPSMC_MSG_PrepareMp1ForShutdown, 0),
132 MSG_MAP(PowerUpVcn, PPSMC_MSG_PowerUpVcn, 0),
133 MSG_MAP(PowerDownVcn, PPSMC_MSG_PowerDownVcn, 0),
134 MSG_MAP(PowerUpJpeg, PPSMC_MSG_PowerUpJpeg, 0),
135 MSG_MAP(PowerDownJpeg, PPSMC_MSG_PowerDownJpeg, 0),
136 MSG_MAP(BacoAudioD3PME, PPSMC_MSG_BacoAudioD3PME, 0),
137 MSG_MAP(ArmD3, PPSMC_MSG_ArmD3, 0),
138 MSG_MAP(DAL_DISABLE_DUMMY_PSTATE_CHANGE,PPSMC_MSG_DALDisableDummyPstateChange, 0),
139 MSG_MAP(DAL_ENABLE_DUMMY_PSTATE_CHANGE, PPSMC_MSG_DALEnableDummyPstateChange, 0),
140 MSG_MAP(GetVoltageByDpm, PPSMC_MSG_GetVoltageByDpm, 0),
141 MSG_MAP(GetVoltageByDpmOverdrive, PPSMC_MSG_GetVoltageByDpmOverdrive, 0),
142 MSG_MAP(SetMGpuFanBoostLimitRpm, PPSMC_MSG_SetMGpuFanBoostLimitRpm, 0),
143 MSG_MAP(SET_DRIVER_DUMMY_TABLE_DRAM_ADDR_HIGH, PPSMC_MSG_SetDriverDummyTableDramAddrHigh, 0),
144 MSG_MAP(SET_DRIVER_DUMMY_TABLE_DRAM_ADDR_LOW, PPSMC_MSG_SetDriverDummyTableDramAddrLow, 0),
145 MSG_MAP(GET_UMC_FW_WA, PPSMC_MSG_GetUMCFWWA, 0),
146};
147
148static struct cmn2asic_mapping navi10_clk_map[SMU_CLK_COUNT] = {
149 CLK_MAP(GFXCLK, PPCLK_GFXCLK),
150 CLK_MAP(SCLK, PPCLK_GFXCLK),
151 CLK_MAP(SOCCLK, PPCLK_SOCCLK),
152 CLK_MAP(FCLK, PPCLK_SOCCLK),
153 CLK_MAP(UCLK, PPCLK_UCLK),
154 CLK_MAP(MCLK, PPCLK_UCLK),
155 CLK_MAP(DCLK, PPCLK_DCLK),
156 CLK_MAP(VCLK, PPCLK_VCLK),
157 CLK_MAP(DCEFCLK, PPCLK_DCEFCLK),
158 CLK_MAP(DISPCLK, PPCLK_DISPCLK),
159 CLK_MAP(PIXCLK, PPCLK_PIXCLK),
160 CLK_MAP(PHYCLK, PPCLK_PHYCLK),
161};
162
163static struct cmn2asic_mapping navi10_feature_mask_map[SMU_FEATURE_COUNT] = {
164 FEA_MAP(DPM_PREFETCHER),
165 FEA_MAP(DPM_GFXCLK),
166 FEA_MAP(DPM_GFX_PACE),
167 FEA_MAP(DPM_UCLK),
168 FEA_MAP(DPM_SOCCLK),
169 FEA_MAP(DPM_MP0CLK),
170 FEA_MAP(DPM_LINK),
171 FEA_MAP(DPM_DCEFCLK),
172 FEA_MAP(MEM_VDDCI_SCALING),
173 FEA_MAP(MEM_MVDD_SCALING),
174 FEA_MAP(DS_GFXCLK),
175 FEA_MAP(DS_SOCCLK),
176 FEA_MAP(DS_LCLK),
177 FEA_MAP(DS_DCEFCLK),
178 FEA_MAP(DS_UCLK),
179 FEA_MAP(GFX_ULV),
180 FEA_MAP(FW_DSTATE),
181 FEA_MAP(GFXOFF),
182 FEA_MAP(BACO),
183 FEA_MAP(VCN_PG),
184 FEA_MAP(JPEG_PG),
185 FEA_MAP(USB_PG),
186 FEA_MAP(RSMU_SMN_CG),
187 FEA_MAP(PPT),
188 FEA_MAP(TDC),
189 FEA_MAP(GFX_EDC),
190 FEA_MAP(APCC_PLUS),
191 FEA_MAP(GTHR),
192 FEA_MAP(ACDC),
193 FEA_MAP(VR0HOT),
194 FEA_MAP(VR1HOT),
195 FEA_MAP(FW_CTF),
196 FEA_MAP(FAN_CONTROL),
197 FEA_MAP(THERMAL),
198 FEA_MAP(GFX_DCS),
199 FEA_MAP(RM),
200 FEA_MAP(LED_DISPLAY),
201 FEA_MAP(GFX_SS),
202 FEA_MAP(OUT_OF_BAND_MONITOR),
203 FEA_MAP(TEMP_DEPENDENT_VMIN),
204 FEA_MAP(MMHUB_PG),
205 FEA_MAP(ATHUB_PG),
206 FEA_MAP(APCC_DFLL),
207};
208
209static struct cmn2asic_mapping navi10_table_map[SMU_TABLE_COUNT] = {
210 TAB_MAP(PPTABLE),
211 TAB_MAP(WATERMARKS),
212 TAB_MAP(AVFS),
213 TAB_MAP(AVFS_PSM_DEBUG),
214 TAB_MAP(AVFS_FUSE_OVERRIDE),
215 TAB_MAP(PMSTATUSLOG),
216 TAB_MAP(SMU_METRICS),
217 TAB_MAP(DRIVER_SMU_CONFIG),
218 TAB_MAP(ACTIVITY_MONITOR_COEFF),
219 TAB_MAP(OVERDRIVE),
220 TAB_MAP(I2C_COMMANDS),
221 TAB_MAP(PACE),
222};
223
224static struct cmn2asic_mapping navi10_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
225 PWR_MAP(AC),
226 PWR_MAP(DC),
227};
228
229static struct cmn2asic_mapping navi10_workload_map[PP_SMC_POWER_PROFILE_COUNT] = {
230 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT, WORKLOAD_PPLIB_DEFAULT_BIT),
231 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_FULLSCREEN3D, WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT),
232 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING, WORKLOAD_PPLIB_POWER_SAVING_BIT),
233 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO, WORKLOAD_PPLIB_VIDEO_BIT),
234 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VR, WORKLOAD_PPLIB_VR_BIT),
235 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE, WORKLOAD_PPLIB_COMPUTE_BIT),
236 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT),
237};
238
239static bool is_asic_secure(struct smu_context *smu)
240{
241 struct amdgpu_device *adev = smu->adev;
242 bool is_secure = true;
243 uint32_t mp0_fw_intf;
244
245 mp0_fw_intf = RREG32_PCIE(MP0_Public |
246 (smnMP0_FW_INTF & 0xffffffff));
247
248 if (!(mp0_fw_intf & (1 << 19)))
249 is_secure = false;
250
251 return is_secure;
252}
253
254static int
255navi10_get_allowed_feature_mask(struct smu_context *smu,
256 uint32_t *feature_mask, uint32_t num)
257{
258 struct amdgpu_device *adev = smu->adev;
259
260 if (num > 2)
261 return -EINVAL;
262
263 memset(feature_mask, 0, sizeof(uint32_t) * num);
264
265 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_PREFETCHER_BIT)
266 | FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT)
267 | FEATURE_MASK(FEATURE_RSMU_SMN_CG_BIT)
268 | FEATURE_MASK(FEATURE_DS_SOCCLK_BIT)
269 | FEATURE_MASK(FEATURE_PPT_BIT)
270 | FEATURE_MASK(FEATURE_TDC_BIT)
271 | FEATURE_MASK(FEATURE_GFX_EDC_BIT)
272 | FEATURE_MASK(FEATURE_APCC_PLUS_BIT)
273 | FEATURE_MASK(FEATURE_VR0HOT_BIT)
274 | FEATURE_MASK(FEATURE_FAN_CONTROL_BIT)
275 | FEATURE_MASK(FEATURE_THERMAL_BIT)
276 | FEATURE_MASK(FEATURE_LED_DISPLAY_BIT)
277 | FEATURE_MASK(FEATURE_DS_LCLK_BIT)
278 | FEATURE_MASK(FEATURE_DS_DCEFCLK_BIT)
279 | FEATURE_MASK(FEATURE_FW_DSTATE_BIT)
280 | FEATURE_MASK(FEATURE_BACO_BIT)
281 | FEATURE_MASK(FEATURE_GFX_SS_BIT)
282 | FEATURE_MASK(FEATURE_APCC_DFLL_BIT)
283 | FEATURE_MASK(FEATURE_FW_CTF_BIT)
284 | FEATURE_MASK(FEATURE_OUT_OF_BAND_MONITOR_BIT);
285
286 if (adev->pm.pp_feature & PP_SCLK_DPM_MASK)
287 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT);
288
289 if (adev->pm.pp_feature & PP_PCIE_DPM_MASK)
290 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_LINK_BIT);
291
292 if (adev->pm.pp_feature & PP_DCEFCLK_DPM_MASK)
293 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT);
294
295 if (adev->pm.pp_feature & PP_ULV_MASK)
296 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFX_ULV_BIT);
297
298 if (adev->pm.pp_feature & PP_SCLK_DEEP_SLEEP_MASK)
299 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DS_GFXCLK_BIT);
300
301 if (adev->pm.pp_feature & PP_GFXOFF_MASK)
302 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFXOFF_BIT);
303
304 if (smu->adev->pg_flags & AMD_PG_SUPPORT_MMHUB)
305 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_MMHUB_PG_BIT);
306
307 if (smu->adev->pg_flags & AMD_PG_SUPPORT_ATHUB)
308 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_ATHUB_PG_BIT);
309
310 if (smu->adev->pg_flags & AMD_PG_SUPPORT_VCN)
311 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_VCN_PG_BIT);
312
313 if (smu->adev->pg_flags & AMD_PG_SUPPORT_JPEG)
314 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_JPEG_PG_BIT);
315
316 if (smu->dc_controlled_by_gpio)
317 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_ACDC_BIT);
318
319 if (adev->pm.pp_feature & PP_SOCCLK_DPM_MASK)
320 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT);
321
322
323 if (!(is_asic_secure(smu) &&
324 (adev->asic_type == CHIP_NAVI10) &&
325 (adev->rev_id == 0)) &&
326 (adev->pm.pp_feature & PP_MCLK_DPM_MASK))
327 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_UCLK_BIT)
328 | FEATURE_MASK(FEATURE_MEM_VDDCI_SCALING_BIT)
329 | FEATURE_MASK(FEATURE_MEM_MVDD_SCALING_BIT);
330
331
332 if (is_asic_secure(smu) &&
333 (adev->asic_type == CHIP_NAVI10) &&
334 (adev->rev_id == 0))
335 *(uint64_t *)feature_mask &=
336 ~FEATURE_MASK(FEATURE_DS_SOCCLK_BIT);
337
338 return 0;
339}
340
341static int navi10_check_powerplay_table(struct smu_context *smu)
342{
343 struct smu_table_context *table_context = &smu->smu_table;
344 struct smu_11_0_powerplay_table *powerplay_table =
345 table_context->power_play_table;
346 struct smu_baco_context *smu_baco = &smu->smu_baco;
347
348 if (powerplay_table->platform_caps & SMU_11_0_PP_PLATFORM_CAP_HARDWAREDC)
349 smu->dc_controlled_by_gpio = true;
350
351 if (powerplay_table->platform_caps & SMU_11_0_PP_PLATFORM_CAP_BACO ||
352 powerplay_table->platform_caps & SMU_11_0_PP_PLATFORM_CAP_MACO)
353 smu_baco->platform_support = true;
354
355 table_context->thermal_controller_type =
356 powerplay_table->thermal_controller_type;
357
358
359
360
361
362 smu->od_settings = &powerplay_table->overdrive_table;
363
364 return 0;
365}
366
367static int navi10_append_powerplay_table(struct smu_context *smu)
368{
369 struct amdgpu_device *adev = smu->adev;
370 struct smu_table_context *table_context = &smu->smu_table;
371 PPTable_t *smc_pptable = table_context->driver_pptable;
372 struct atom_smc_dpm_info_v4_5 *smc_dpm_table;
373 struct atom_smc_dpm_info_v4_7 *smc_dpm_table_v4_7;
374 int index, ret;
375
376 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
377 smc_dpm_info);
378
379 ret = amdgpu_atombios_get_data_table(adev, index, NULL, NULL, NULL,
380 (uint8_t **)&smc_dpm_table);
381 if (ret)
382 return ret;
383
384 dev_info(adev->dev, "smc_dpm_info table revision(format.content): %d.%d\n",
385 smc_dpm_table->table_header.format_revision,
386 smc_dpm_table->table_header.content_revision);
387
388 if (smc_dpm_table->table_header.format_revision != 4) {
389 dev_err(adev->dev, "smc_dpm_info table format revision is not 4!\n");
390 return -EINVAL;
391 }
392
393 switch (smc_dpm_table->table_header.content_revision) {
394 case 5:
395 memcpy(smc_pptable->I2cControllers, smc_dpm_table->I2cControllers,
396 sizeof(*smc_dpm_table) - sizeof(smc_dpm_table->table_header));
397 break;
398 case 7:
399 ret = amdgpu_atombios_get_data_table(adev, index, NULL, NULL, NULL,
400 (uint8_t **)&smc_dpm_table_v4_7);
401 if (ret)
402 return ret;
403 memcpy(smc_pptable->I2cControllers, smc_dpm_table_v4_7->I2cControllers,
404 sizeof(*smc_dpm_table_v4_7) - sizeof(smc_dpm_table_v4_7->table_header));
405 break;
406 default:
407 dev_err(smu->adev->dev, "smc_dpm_info with unsupported content revision %d!\n",
408 smc_dpm_table->table_header.content_revision);
409 return -EINVAL;
410 }
411
412 if (adev->pm.pp_feature & PP_GFXOFF_MASK) {
413
414 smc_pptable->DebugOverrides |= DPM_OVERRIDE_DISABLE_DFLL_PLL_SHUTDOWN;
415 }
416
417 return 0;
418}
419
420static int navi10_store_powerplay_table(struct smu_context *smu)
421{
422 struct smu_table_context *table_context = &smu->smu_table;
423 struct smu_11_0_powerplay_table *powerplay_table =
424 table_context->power_play_table;
425
426 memcpy(table_context->driver_pptable, &powerplay_table->smc_pptable,
427 sizeof(PPTable_t));
428
429 return 0;
430}
431
432static int navi10_setup_pptable(struct smu_context *smu)
433{
434 int ret = 0;
435
436 ret = smu_v11_0_setup_pptable(smu);
437 if (ret)
438 return ret;
439
440 ret = navi10_store_powerplay_table(smu);
441 if (ret)
442 return ret;
443
444 ret = navi10_append_powerplay_table(smu);
445 if (ret)
446 return ret;
447
448 ret = navi10_check_powerplay_table(smu);
449 if (ret)
450 return ret;
451
452 return ret;
453}
454
455static int navi10_tables_init(struct smu_context *smu)
456{
457 struct smu_table_context *smu_table = &smu->smu_table;
458 struct smu_table *tables = smu_table->tables;
459 struct amdgpu_device *adev = smu->adev;
460
461 SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t),
462 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
463 SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
464 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
465 if (adev->asic_type == CHIP_NAVI12)
466 SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_NV12_t),
467 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
468 else
469 SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
470 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
471 SMU_TABLE_INIT(tables, SMU_TABLE_I2C_COMMANDS, sizeof(SwI2cRequest_t),
472 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
473 SMU_TABLE_INIT(tables, SMU_TABLE_OVERDRIVE, sizeof(OverDriveTable_t),
474 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
475 SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU11_TOOL_SIZE,
476 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
477 SMU_TABLE_INIT(tables, SMU_TABLE_ACTIVITY_MONITOR_COEFF,
478 sizeof(DpmActivityMonitorCoeffInt_t), PAGE_SIZE,
479 AMDGPU_GEM_DOMAIN_VRAM);
480
481 smu_table->metrics_table = kzalloc(adev->asic_type == CHIP_NAVI12 ?
482 sizeof(SmuMetrics_NV12_t) :
483 sizeof(SmuMetrics_t), GFP_KERNEL);
484 if (!smu_table->metrics_table)
485 goto err0_out;
486 smu_table->metrics_time = 0;
487
488 smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_0);
489 smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
490 if (!smu_table->gpu_metrics_table)
491 goto err1_out;
492
493 smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL);
494 if (!smu_table->watermarks_table)
495 goto err2_out;
496
497 return 0;
498
499err2_out:
500 kfree(smu_table->gpu_metrics_table);
501err1_out:
502 kfree(smu_table->metrics_table);
503err0_out:
504 return -ENOMEM;
505}
506
507static int navi10_get_smu_metrics_data(struct smu_context *smu,
508 MetricsMember_t member,
509 uint32_t *value)
510{
511 struct smu_table_context *smu_table= &smu->smu_table;
512
513
514
515
516
517 SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table;
518 int ret = 0;
519
520 mutex_lock(&smu->metrics_lock);
521
522 ret = smu_cmn_get_metrics_table_locked(smu,
523 NULL,
524 false);
525 if (ret) {
526 mutex_unlock(&smu->metrics_lock);
527 return ret;
528 }
529
530 switch (member) {
531 case METRICS_CURR_GFXCLK:
532 *value = metrics->CurrClock[PPCLK_GFXCLK];
533 break;
534 case METRICS_CURR_SOCCLK:
535 *value = metrics->CurrClock[PPCLK_SOCCLK];
536 break;
537 case METRICS_CURR_UCLK:
538 *value = metrics->CurrClock[PPCLK_UCLK];
539 break;
540 case METRICS_CURR_VCLK:
541 *value = metrics->CurrClock[PPCLK_VCLK];
542 break;
543 case METRICS_CURR_DCLK:
544 *value = metrics->CurrClock[PPCLK_DCLK];
545 break;
546 case METRICS_CURR_DCEFCLK:
547 *value = metrics->CurrClock[PPCLK_DCEFCLK];
548 break;
549 case METRICS_AVERAGE_GFXCLK:
550 *value = metrics->AverageGfxclkFrequency;
551 break;
552 case METRICS_AVERAGE_SOCCLK:
553 *value = metrics->AverageSocclkFrequency;
554 break;
555 case METRICS_AVERAGE_UCLK:
556 *value = metrics->AverageUclkFrequency;
557 break;
558 case METRICS_AVERAGE_GFXACTIVITY:
559 *value = metrics->AverageGfxActivity;
560 break;
561 case METRICS_AVERAGE_MEMACTIVITY:
562 *value = metrics->AverageUclkActivity;
563 break;
564 case METRICS_AVERAGE_SOCKETPOWER:
565 *value = metrics->AverageSocketPower << 8;
566 break;
567 case METRICS_TEMPERATURE_EDGE:
568 *value = metrics->TemperatureEdge *
569 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
570 break;
571 case METRICS_TEMPERATURE_HOTSPOT:
572 *value = metrics->TemperatureHotspot *
573 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
574 break;
575 case METRICS_TEMPERATURE_MEM:
576 *value = metrics->TemperatureMem *
577 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
578 break;
579 case METRICS_TEMPERATURE_VRGFX:
580 *value = metrics->TemperatureVrGfx *
581 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
582 break;
583 case METRICS_TEMPERATURE_VRSOC:
584 *value = metrics->TemperatureVrSoc *
585 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
586 break;
587 case METRICS_THROTTLER_STATUS:
588 *value = metrics->ThrottlerStatus;
589 break;
590 case METRICS_CURR_FANSPEED:
591 *value = metrics->CurrFanSpeed;
592 break;
593 default:
594 *value = UINT_MAX;
595 break;
596 }
597
598 mutex_unlock(&smu->metrics_lock);
599
600 return ret;
601}
602
603static int navi10_allocate_dpm_context(struct smu_context *smu)
604{
605 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
606
607 smu_dpm->dpm_context = kzalloc(sizeof(struct smu_11_0_dpm_context),
608 GFP_KERNEL);
609 if (!smu_dpm->dpm_context)
610 return -ENOMEM;
611
612 smu_dpm->dpm_context_size = sizeof(struct smu_11_0_dpm_context);
613
614 return 0;
615}
616
617static int navi10_init_smc_tables(struct smu_context *smu)
618{
619 int ret = 0;
620
621 ret = navi10_tables_init(smu);
622 if (ret)
623 return ret;
624
625 ret = navi10_allocate_dpm_context(smu);
626 if (ret)
627 return ret;
628
629 return smu_v11_0_init_smc_tables(smu);
630}
631
632static int navi10_set_default_dpm_table(struct smu_context *smu)
633{
634 struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
635 PPTable_t *driver_ppt = smu->smu_table.driver_pptable;
636 struct smu_11_0_dpm_table *dpm_table;
637 int ret = 0;
638
639
640 dpm_table = &dpm_context->dpm_tables.soc_table;
641 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
642 ret = smu_v11_0_set_single_dpm_table(smu,
643 SMU_SOCCLK,
644 dpm_table);
645 if (ret)
646 return ret;
647 dpm_table->is_fine_grained =
648 !driver_ppt->DpmDescriptor[PPCLK_SOCCLK].SnapToDiscrete;
649 } else {
650 dpm_table->count = 1;
651 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.socclk / 100;
652 dpm_table->dpm_levels[0].enabled = true;
653 dpm_table->min = dpm_table->dpm_levels[0].value;
654 dpm_table->max = dpm_table->dpm_levels[0].value;
655 }
656
657
658 dpm_table = &dpm_context->dpm_tables.gfx_table;
659 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT)) {
660 ret = smu_v11_0_set_single_dpm_table(smu,
661 SMU_GFXCLK,
662 dpm_table);
663 if (ret)
664 return ret;
665 dpm_table->is_fine_grained =
666 !driver_ppt->DpmDescriptor[PPCLK_GFXCLK].SnapToDiscrete;
667 } else {
668 dpm_table->count = 1;
669 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
670 dpm_table->dpm_levels[0].enabled = true;
671 dpm_table->min = dpm_table->dpm_levels[0].value;
672 dpm_table->max = dpm_table->dpm_levels[0].value;
673 }
674
675
676 dpm_table = &dpm_context->dpm_tables.uclk_table;
677 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
678 ret = smu_v11_0_set_single_dpm_table(smu,
679 SMU_UCLK,
680 dpm_table);
681 if (ret)
682 return ret;
683 dpm_table->is_fine_grained =
684 !driver_ppt->DpmDescriptor[PPCLK_UCLK].SnapToDiscrete;
685 } else {
686 dpm_table->count = 1;
687 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.uclk / 100;
688 dpm_table->dpm_levels[0].enabled = true;
689 dpm_table->min = dpm_table->dpm_levels[0].value;
690 dpm_table->max = dpm_table->dpm_levels[0].value;
691 }
692
693
694 dpm_table = &dpm_context->dpm_tables.vclk_table;
695 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
696 ret = smu_v11_0_set_single_dpm_table(smu,
697 SMU_VCLK,
698 dpm_table);
699 if (ret)
700 return ret;
701 dpm_table->is_fine_grained =
702 !driver_ppt->DpmDescriptor[PPCLK_VCLK].SnapToDiscrete;
703 } else {
704 dpm_table->count = 1;
705 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.vclk / 100;
706 dpm_table->dpm_levels[0].enabled = true;
707 dpm_table->min = dpm_table->dpm_levels[0].value;
708 dpm_table->max = dpm_table->dpm_levels[0].value;
709 }
710
711
712 dpm_table = &dpm_context->dpm_tables.dclk_table;
713 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
714 ret = smu_v11_0_set_single_dpm_table(smu,
715 SMU_DCLK,
716 dpm_table);
717 if (ret)
718 return ret;
719 dpm_table->is_fine_grained =
720 !driver_ppt->DpmDescriptor[PPCLK_DCLK].SnapToDiscrete;
721 } else {
722 dpm_table->count = 1;
723 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dclk / 100;
724 dpm_table->dpm_levels[0].enabled = true;
725 dpm_table->min = dpm_table->dpm_levels[0].value;
726 dpm_table->max = dpm_table->dpm_levels[0].value;
727 }
728
729
730 dpm_table = &dpm_context->dpm_tables.dcef_table;
731 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
732 ret = smu_v11_0_set_single_dpm_table(smu,
733 SMU_DCEFCLK,
734 dpm_table);
735 if (ret)
736 return ret;
737 dpm_table->is_fine_grained =
738 !driver_ppt->DpmDescriptor[PPCLK_DCEFCLK].SnapToDiscrete;
739 } else {
740 dpm_table->count = 1;
741 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100;
742 dpm_table->dpm_levels[0].enabled = true;
743 dpm_table->min = dpm_table->dpm_levels[0].value;
744 dpm_table->max = dpm_table->dpm_levels[0].value;
745 }
746
747
748 dpm_table = &dpm_context->dpm_tables.pixel_table;
749 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
750 ret = smu_v11_0_set_single_dpm_table(smu,
751 SMU_PIXCLK,
752 dpm_table);
753 if (ret)
754 return ret;
755 dpm_table->is_fine_grained =
756 !driver_ppt->DpmDescriptor[PPCLK_PIXCLK].SnapToDiscrete;
757 } else {
758 dpm_table->count = 1;
759 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100;
760 dpm_table->dpm_levels[0].enabled = true;
761 dpm_table->min = dpm_table->dpm_levels[0].value;
762 dpm_table->max = dpm_table->dpm_levels[0].value;
763 }
764
765
766 dpm_table = &dpm_context->dpm_tables.display_table;
767 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
768 ret = smu_v11_0_set_single_dpm_table(smu,
769 SMU_DISPCLK,
770 dpm_table);
771 if (ret)
772 return ret;
773 dpm_table->is_fine_grained =
774 !driver_ppt->DpmDescriptor[PPCLK_DISPCLK].SnapToDiscrete;
775 } else {
776 dpm_table->count = 1;
777 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100;
778 dpm_table->dpm_levels[0].enabled = true;
779 dpm_table->min = dpm_table->dpm_levels[0].value;
780 dpm_table->max = dpm_table->dpm_levels[0].value;
781 }
782
783
784 dpm_table = &dpm_context->dpm_tables.phy_table;
785 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
786 ret = smu_v11_0_set_single_dpm_table(smu,
787 SMU_PHYCLK,
788 dpm_table);
789 if (ret)
790 return ret;
791 dpm_table->is_fine_grained =
792 !driver_ppt->DpmDescriptor[PPCLK_PHYCLK].SnapToDiscrete;
793 } else {
794 dpm_table->count = 1;
795 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100;
796 dpm_table->dpm_levels[0].enabled = true;
797 dpm_table->min = dpm_table->dpm_levels[0].value;
798 dpm_table->max = dpm_table->dpm_levels[0].value;
799 }
800
801 return 0;
802}
803
804static int navi10_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
805{
806 int ret = 0;
807
808 if (enable) {
809
810 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
811 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 1, NULL);
812 if (ret)
813 return ret;
814 }
815 } else {
816 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
817 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownVcn, NULL);
818 if (ret)
819 return ret;
820 }
821 }
822
823 return ret;
824}
825
826static int navi10_dpm_set_jpeg_enable(struct smu_context *smu, bool enable)
827{
828 int ret = 0;
829
830 if (enable) {
831 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) {
832 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerUpJpeg, NULL);
833 if (ret)
834 return ret;
835 }
836 } else {
837 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) {
838 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownJpeg, NULL);
839 if (ret)
840 return ret;
841 }
842 }
843
844 return ret;
845}
846
847static int navi10_get_current_clk_freq_by_table(struct smu_context *smu,
848 enum smu_clk_type clk_type,
849 uint32_t *value)
850{
851 MetricsMember_t member_type;
852 int clk_id = 0;
853
854 clk_id = smu_cmn_to_asic_specific_index(smu,
855 CMN2ASIC_MAPPING_CLK,
856 clk_type);
857 if (clk_id < 0)
858 return clk_id;
859
860 switch (clk_id) {
861 case PPCLK_GFXCLK:
862 member_type = METRICS_CURR_GFXCLK;
863 break;
864 case PPCLK_UCLK:
865 member_type = METRICS_CURR_UCLK;
866 break;
867 case PPCLK_SOCCLK:
868 member_type = METRICS_CURR_SOCCLK;
869 break;
870 case PPCLK_VCLK:
871 member_type = METRICS_CURR_VCLK;
872 break;
873 case PPCLK_DCLK:
874 member_type = METRICS_CURR_DCLK;
875 break;
876 case PPCLK_DCEFCLK:
877 member_type = METRICS_CURR_DCEFCLK;
878 break;
879 default:
880 return -EINVAL;
881 }
882
883 return navi10_get_smu_metrics_data(smu,
884 member_type,
885 value);
886}
887
888static bool navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu_clk_type clk_type)
889{
890 PPTable_t *pptable = smu->smu_table.driver_pptable;
891 DpmDescriptor_t *dpm_desc = NULL;
892 uint32_t clk_index = 0;
893
894 clk_index = smu_cmn_to_asic_specific_index(smu,
895 CMN2ASIC_MAPPING_CLK,
896 clk_type);
897 dpm_desc = &pptable->DpmDescriptor[clk_index];
898
899
900 return dpm_desc->SnapToDiscrete == 0 ? true : false;
901}
902
903static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_CAP cap)
904{
905 return od_table->cap[cap];
906}
907
908static void navi10_od_setting_get_range(struct smu_11_0_overdrive_table *od_table,
909 enum SMU_11_0_ODSETTING_ID setting,
910 uint32_t *min, uint32_t *max)
911{
912 if (min)
913 *min = od_table->min[setting];
914 if (max)
915 *max = od_table->max[setting];
916}
917
918static int navi10_print_clk_levels(struct smu_context *smu,
919 enum smu_clk_type clk_type, char *buf)
920{
921 uint16_t *curve_settings;
922 int i, size = 0, ret = 0;
923 uint32_t cur_value = 0, value = 0, count = 0;
924 uint32_t freq_values[3] = {0};
925 uint32_t mark_index = 0;
926 struct smu_table_context *table_context = &smu->smu_table;
927 uint32_t gen_speed, lane_width;
928 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
929 struct smu_11_0_dpm_context *dpm_context = smu_dpm->dpm_context;
930 PPTable_t *pptable = (PPTable_t *)table_context->driver_pptable;
931 OverDriveTable_t *od_table =
932 (OverDriveTable_t *)table_context->overdrive_table;
933 struct smu_11_0_overdrive_table *od_settings = smu->od_settings;
934 uint32_t min_value, max_value;
935
936 switch (clk_type) {
937 case SMU_GFXCLK:
938 case SMU_SCLK:
939 case SMU_SOCCLK:
940 case SMU_MCLK:
941 case SMU_UCLK:
942 case SMU_FCLK:
943 case SMU_DCEFCLK:
944 ret = navi10_get_current_clk_freq_by_table(smu, clk_type, &cur_value);
945 if (ret)
946 return size;
947
948 ret = smu_v11_0_get_dpm_level_count(smu, clk_type, &count);
949 if (ret)
950 return size;
951
952 if (!navi10_is_support_fine_grained_dpm(smu, clk_type)) {
953 for (i = 0; i < count; i++) {
954 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &value);
955 if (ret)
956 return size;
957
958 size += sprintf(buf + size, "%d: %uMhz %s\n", i, value,
959 cur_value == value ? "*" : "");
960 }
961 } else {
962 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, 0, &freq_values[0]);
963 if (ret)
964 return size;
965 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, count - 1, &freq_values[2]);
966 if (ret)
967 return size;
968
969 freq_values[1] = cur_value;
970 mark_index = cur_value == freq_values[0] ? 0 :
971 cur_value == freq_values[2] ? 2 : 1;
972 if (mark_index != 1)
973 freq_values[1] = (freq_values[0] + freq_values[2]) / 2;
974
975 for (i = 0; i < 3; i++) {
976 size += sprintf(buf + size, "%d: %uMhz %s\n", i, freq_values[i],
977 i == mark_index ? "*" : "");
978 }
979
980 }
981 break;
982 case SMU_PCIE:
983 gen_speed = smu_v11_0_get_current_pcie_link_speed_level(smu);
984 lane_width = smu_v11_0_get_current_pcie_link_width_level(smu);
985 for (i = 0; i < NUM_LINK_LEVELS; i++)
986 size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i,
987 (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 0) ? "2.5GT/s," :
988 (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 1) ? "5.0GT/s," :
989 (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 2) ? "8.0GT/s," :
990 (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 3) ? "16.0GT/s," : "",
991 (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 1) ? "x1" :
992 (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 2) ? "x2" :
993 (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 3) ? "x4" :
994 (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 4) ? "x8" :
995 (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 5) ? "x12" :
996 (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 6) ? "x16" : "",
997 pptable->LclkFreq[i],
998 (gen_speed == dpm_context->dpm_tables.pcie_table.pcie_gen[i]) &&
999 (lane_width == dpm_context->dpm_tables.pcie_table.pcie_lane[i]) ?
1000 "*" : "");
1001 break;
1002 case SMU_OD_SCLK:
1003 if (!smu->od_enabled || !od_table || !od_settings)
1004 break;
1005 if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_LIMITS))
1006 break;
1007 size += sprintf(buf + size, "OD_SCLK:\n");
1008 size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table->GfxclkFmin, od_table->GfxclkFmax);
1009 break;
1010 case SMU_OD_MCLK:
1011 if (!smu->od_enabled || !od_table || !od_settings)
1012 break;
1013 if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_UCLK_MAX))
1014 break;
1015 size += sprintf(buf + size, "OD_MCLK:\n");
1016 size += sprintf(buf + size, "1: %uMHz\n", od_table->UclkFmax);
1017 break;
1018 case SMU_OD_VDDC_CURVE:
1019 if (!smu->od_enabled || !od_table || !od_settings)
1020 break;
1021 if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_CURVE))
1022 break;
1023 size += sprintf(buf + size, "OD_VDDC_CURVE:\n");
1024 for (i = 0; i < 3; i++) {
1025 switch (i) {
1026 case 0:
1027 curve_settings = &od_table->GfxclkFreq1;
1028 break;
1029 case 1:
1030 curve_settings = &od_table->GfxclkFreq2;
1031 break;
1032 case 2:
1033 curve_settings = &od_table->GfxclkFreq3;
1034 break;
1035 default:
1036 break;
1037 }
1038 size += sprintf(buf + size, "%d: %uMHz %umV\n", i, curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE);
1039 }
1040 break;
1041 case SMU_OD_RANGE:
1042 if (!smu->od_enabled || !od_table || !od_settings)
1043 break;
1044 size = sprintf(buf, "%s:\n", "OD_RANGE");
1045
1046 if (navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_LIMITS)) {
1047 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_GFXCLKFMIN,
1048 &min_value, NULL);
1049 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_GFXCLKFMAX,
1050 NULL, &max_value);
1051 size += sprintf(buf + size, "SCLK: %7uMhz %10uMhz\n",
1052 min_value, max_value);
1053 }
1054
1055 if (navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_UCLK_MAX)) {
1056 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_UCLKFMAX,
1057 &min_value, &max_value);
1058 size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n",
1059 min_value, max_value);
1060 }
1061
1062 if (navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_CURVE)) {
1063 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1,
1064 &min_value, &max_value);
1065 size += sprintf(buf + size, "VDDC_CURVE_SCLK[0]: %7uMhz %10uMhz\n",
1066 min_value, max_value);
1067 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1,
1068 &min_value, &max_value);
1069 size += sprintf(buf + size, "VDDC_CURVE_VOLT[0]: %7dmV %11dmV\n",
1070 min_value, max_value);
1071 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2,
1072 &min_value, &max_value);
1073 size += sprintf(buf + size, "VDDC_CURVE_SCLK[1]: %7uMhz %10uMhz\n",
1074 min_value, max_value);
1075 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2,
1076 &min_value, &max_value);
1077 size += sprintf(buf + size, "VDDC_CURVE_VOLT[1]: %7dmV %11dmV\n",
1078 min_value, max_value);
1079 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3,
1080 &min_value, &max_value);
1081 size += sprintf(buf + size, "VDDC_CURVE_SCLK[2]: %7uMhz %10uMhz\n",
1082 min_value, max_value);
1083 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3,
1084 &min_value, &max_value);
1085 size += sprintf(buf + size, "VDDC_CURVE_VOLT[2]: %7dmV %11dmV\n",
1086 min_value, max_value);
1087 }
1088
1089 break;
1090 default:
1091 break;
1092 }
1093
1094 return size;
1095}
1096
1097static int navi10_force_clk_levels(struct smu_context *smu,
1098 enum smu_clk_type clk_type, uint32_t mask)
1099{
1100
1101 int ret = 0, size = 0;
1102 uint32_t soft_min_level = 0, soft_max_level = 0, min_freq = 0, max_freq = 0;
1103
1104 soft_min_level = mask ? (ffs(mask) - 1) : 0;
1105 soft_max_level = mask ? (fls(mask) - 1) : 0;
1106
1107 switch (clk_type) {
1108 case SMU_GFXCLK:
1109 case SMU_SCLK:
1110 case SMU_SOCCLK:
1111 case SMU_MCLK:
1112 case SMU_UCLK:
1113 case SMU_DCEFCLK:
1114 case SMU_FCLK:
1115
1116 if (navi10_is_support_fine_grained_dpm(smu, clk_type)) {
1117 soft_max_level = (soft_max_level >= 1 ? 1 : 0);
1118 soft_min_level = (soft_min_level >= 1 ? 1 : 0);
1119 }
1120
1121 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, soft_min_level, &min_freq);
1122 if (ret)
1123 return size;
1124
1125 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, soft_max_level, &max_freq);
1126 if (ret)
1127 return size;
1128
1129 ret = smu_v11_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq);
1130 if (ret)
1131 return size;
1132 break;
1133 default:
1134 break;
1135 }
1136
1137 return size;
1138}
1139
1140static int navi10_populate_umd_state_clk(struct smu_context *smu)
1141{
1142 struct smu_11_0_dpm_context *dpm_context =
1143 smu->smu_dpm.dpm_context;
1144 struct smu_11_0_dpm_table *gfx_table =
1145 &dpm_context->dpm_tables.gfx_table;
1146 struct smu_11_0_dpm_table *mem_table =
1147 &dpm_context->dpm_tables.uclk_table;
1148 struct smu_11_0_dpm_table *soc_table =
1149 &dpm_context->dpm_tables.soc_table;
1150 struct smu_umd_pstate_table *pstate_table =
1151 &smu->pstate_table;
1152 struct amdgpu_device *adev = smu->adev;
1153 uint32_t sclk_freq;
1154
1155 pstate_table->gfxclk_pstate.min = gfx_table->min;
1156 switch (adev->asic_type) {
1157 case CHIP_NAVI10:
1158 switch (adev->pdev->revision) {
1159 case 0xf0:
1160 case 0xc0:
1161 sclk_freq = NAVI10_PEAK_SCLK_XTX;
1162 break;
1163 case 0xf1:
1164 case 0xc1:
1165 sclk_freq = NAVI10_PEAK_SCLK_XT;
1166 break;
1167 default:
1168 sclk_freq = NAVI10_PEAK_SCLK_XL;
1169 break;
1170 }
1171 break;
1172 case CHIP_NAVI14:
1173 switch (adev->pdev->revision) {
1174 case 0xc7:
1175 case 0xf4:
1176 sclk_freq = NAVI14_UMD_PSTATE_PEAK_XT_GFXCLK;
1177 break;
1178 case 0xc1:
1179 case 0xf2:
1180 sclk_freq = NAVI14_UMD_PSTATE_PEAK_XTM_GFXCLK;
1181 break;
1182 case 0xc3:
1183 case 0xf3:
1184 sclk_freq = NAVI14_UMD_PSTATE_PEAK_XLM_GFXCLK;
1185 break;
1186 case 0xc5:
1187 case 0xf6:
1188 sclk_freq = NAVI14_UMD_PSTATE_PEAK_XLM_GFXCLK;
1189 break;
1190 default:
1191 sclk_freq = NAVI14_UMD_PSTATE_PEAK_XL_GFXCLK;
1192 break;
1193 }
1194 break;
1195 case CHIP_NAVI12:
1196 sclk_freq = NAVI12_UMD_PSTATE_PEAK_GFXCLK;
1197 break;
1198 default:
1199 sclk_freq = gfx_table->dpm_levels[gfx_table->count - 1].value;
1200 break;
1201 }
1202 pstate_table->gfxclk_pstate.peak = sclk_freq;
1203
1204 pstate_table->uclk_pstate.min = mem_table->min;
1205 pstate_table->uclk_pstate.peak = mem_table->max;
1206
1207 pstate_table->socclk_pstate.min = soc_table->min;
1208 pstate_table->socclk_pstate.peak = soc_table->max;
1209
1210 if (gfx_table->max > NAVI10_UMD_PSTATE_PROFILING_GFXCLK &&
1211 mem_table->max > NAVI10_UMD_PSTATE_PROFILING_MEMCLK &&
1212 soc_table->max > NAVI10_UMD_PSTATE_PROFILING_SOCCLK) {
1213 pstate_table->gfxclk_pstate.standard =
1214 NAVI10_UMD_PSTATE_PROFILING_GFXCLK;
1215 pstate_table->uclk_pstate.standard =
1216 NAVI10_UMD_PSTATE_PROFILING_MEMCLK;
1217 pstate_table->socclk_pstate.standard =
1218 NAVI10_UMD_PSTATE_PROFILING_SOCCLK;
1219 } else {
1220 pstate_table->gfxclk_pstate.standard =
1221 pstate_table->gfxclk_pstate.min;
1222 pstate_table->uclk_pstate.standard =
1223 pstate_table->uclk_pstate.min;
1224 pstate_table->socclk_pstate.standard =
1225 pstate_table->socclk_pstate.min;
1226 }
1227
1228 return 0;
1229}
1230
1231static int navi10_get_clock_by_type_with_latency(struct smu_context *smu,
1232 enum smu_clk_type clk_type,
1233 struct pp_clock_levels_with_latency *clocks)
1234{
1235 int ret = 0, i = 0;
1236 uint32_t level_count = 0, freq = 0;
1237
1238 switch (clk_type) {
1239 case SMU_GFXCLK:
1240 case SMU_DCEFCLK:
1241 case SMU_SOCCLK:
1242 case SMU_MCLK:
1243 case SMU_UCLK:
1244 ret = smu_v11_0_get_dpm_level_count(smu, clk_type, &level_count);
1245 if (ret)
1246 return ret;
1247
1248 level_count = min(level_count, (uint32_t)MAX_NUM_CLOCKS);
1249 clocks->num_levels = level_count;
1250
1251 for (i = 0; i < level_count; i++) {
1252 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &freq);
1253 if (ret)
1254 return ret;
1255
1256 clocks->data[i].clocks_in_khz = freq * 1000;
1257 clocks->data[i].latency_in_us = 0;
1258 }
1259 break;
1260 default:
1261 break;
1262 }
1263
1264 return ret;
1265}
1266
1267static int navi10_pre_display_config_changed(struct smu_context *smu)
1268{
1269 int ret = 0;
1270 uint32_t max_freq = 0;
1271
1272 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_NumOfDisplays, 0, NULL);
1273 if (ret)
1274 return ret;
1275
1276 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
1277 ret = smu_v11_0_get_dpm_ultimate_freq(smu, SMU_UCLK, NULL, &max_freq);
1278 if (ret)
1279 return ret;
1280 ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, 0, max_freq);
1281 if (ret)
1282 return ret;
1283 }
1284
1285 return ret;
1286}
1287
1288static int navi10_display_config_changed(struct smu_context *smu)
1289{
1290 int ret = 0;
1291
1292 if ((smu->watermarks_bitmap & WATERMARKS_EXIST) &&
1293 smu_cmn_feature_is_supported(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) &&
1294 smu_cmn_feature_is_supported(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
1295 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_NumOfDisplays,
1296 smu->display_config->num_display,
1297 NULL);
1298 if (ret)
1299 return ret;
1300 }
1301
1302 return ret;
1303}
1304
1305static int navi10_get_gpu_power(struct smu_context *smu, uint32_t *value)
1306{
1307 if (!value)
1308 return -EINVAL;
1309
1310 return navi10_get_smu_metrics_data(smu,
1311 METRICS_AVERAGE_SOCKETPOWER,
1312 value);
1313}
1314
1315static int navi10_get_current_activity_percent(struct smu_context *smu,
1316 enum amd_pp_sensors sensor,
1317 uint32_t *value)
1318{
1319 int ret = 0;
1320
1321 if (!value)
1322 return -EINVAL;
1323
1324 switch (sensor) {
1325 case AMDGPU_PP_SENSOR_GPU_LOAD:
1326 ret = navi10_get_smu_metrics_data(smu,
1327 METRICS_AVERAGE_GFXACTIVITY,
1328 value);
1329 break;
1330 case AMDGPU_PP_SENSOR_MEM_LOAD:
1331 ret = navi10_get_smu_metrics_data(smu,
1332 METRICS_AVERAGE_MEMACTIVITY,
1333 value);
1334 break;
1335 default:
1336 dev_err(smu->adev->dev, "Invalid sensor for retrieving clock activity\n");
1337 return -EINVAL;
1338 }
1339
1340 return ret;
1341}
1342
1343static bool navi10_is_dpm_running(struct smu_context *smu)
1344{
1345 int ret = 0;
1346 uint32_t feature_mask[2];
1347 uint64_t feature_enabled;
1348
1349 ret = smu_cmn_get_enabled_mask(smu, feature_mask, 2);
1350 if (ret)
1351 return false;
1352
1353 feature_enabled = (uint64_t)feature_mask[1] << 32 | feature_mask[0];
1354
1355 return !!(feature_enabled & SMC_DPM_FEATURE);
1356}
1357
1358static int navi10_get_fan_speed_rpm(struct smu_context *smu,
1359 uint32_t *speed)
1360{
1361 if (!speed)
1362 return -EINVAL;
1363
1364 return navi10_get_smu_metrics_data(smu,
1365 METRICS_CURR_FANSPEED,
1366 speed);
1367}
1368
1369static int navi10_get_fan_parameters(struct smu_context *smu)
1370{
1371 PPTable_t *pptable = smu->smu_table.driver_pptable;
1372
1373 smu->fan_max_rpm = pptable->FanMaximumRpm;
1374
1375 return 0;
1376}
1377
1378static int navi10_get_power_profile_mode(struct smu_context *smu, char *buf)
1379{
1380 DpmActivityMonitorCoeffInt_t activity_monitor;
1381 uint32_t i, size = 0;
1382 int16_t workload_type = 0;
1383 static const char *profile_name[] = {
1384 "BOOTUP_DEFAULT",
1385 "3D_FULL_SCREEN",
1386 "POWER_SAVING",
1387 "VIDEO",
1388 "VR",
1389 "COMPUTE",
1390 "CUSTOM"};
1391 static const char *title[] = {
1392 "PROFILE_INDEX(NAME)",
1393 "CLOCK_TYPE(NAME)",
1394 "FPS",
1395 "MinFreqType",
1396 "MinActiveFreqType",
1397 "MinActiveFreq",
1398 "BoosterFreqType",
1399 "BoosterFreq",
1400 "PD_Data_limit_c",
1401 "PD_Data_error_coeff",
1402 "PD_Data_error_rate_coeff"};
1403 int result = 0;
1404
1405 if (!buf)
1406 return -EINVAL;
1407
1408 size += sprintf(buf + size, "%16s %s %s %s %s %s %s %s %s %s %s\n",
1409 title[0], title[1], title[2], title[3], title[4], title[5],
1410 title[6], title[7], title[8], title[9], title[10]);
1411
1412 for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
1413
1414 workload_type = smu_cmn_to_asic_specific_index(smu,
1415 CMN2ASIC_MAPPING_WORKLOAD,
1416 i);
1417 if (workload_type < 0)
1418 return -EINVAL;
1419
1420 result = smu_cmn_update_table(smu,
1421 SMU_TABLE_ACTIVITY_MONITOR_COEFF, workload_type,
1422 (void *)(&activity_monitor), false);
1423 if (result) {
1424 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
1425 return result;
1426 }
1427
1428 size += sprintf(buf + size, "%2d %14s%s:\n",
1429 i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " ");
1430
1431 size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
1432 " ",
1433 0,
1434 "GFXCLK",
1435 activity_monitor.Gfx_FPS,
1436 activity_monitor.Gfx_MinFreqStep,
1437 activity_monitor.Gfx_MinActiveFreqType,
1438 activity_monitor.Gfx_MinActiveFreq,
1439 activity_monitor.Gfx_BoosterFreqType,
1440 activity_monitor.Gfx_BoosterFreq,
1441 activity_monitor.Gfx_PD_Data_limit_c,
1442 activity_monitor.Gfx_PD_Data_error_coeff,
1443 activity_monitor.Gfx_PD_Data_error_rate_coeff);
1444
1445 size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
1446 " ",
1447 1,
1448 "SOCCLK",
1449 activity_monitor.Soc_FPS,
1450 activity_monitor.Soc_MinFreqStep,
1451 activity_monitor.Soc_MinActiveFreqType,
1452 activity_monitor.Soc_MinActiveFreq,
1453 activity_monitor.Soc_BoosterFreqType,
1454 activity_monitor.Soc_BoosterFreq,
1455 activity_monitor.Soc_PD_Data_limit_c,
1456 activity_monitor.Soc_PD_Data_error_coeff,
1457 activity_monitor.Soc_PD_Data_error_rate_coeff);
1458
1459 size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
1460 " ",
1461 2,
1462 "MEMLK",
1463 activity_monitor.Mem_FPS,
1464 activity_monitor.Mem_MinFreqStep,
1465 activity_monitor.Mem_MinActiveFreqType,
1466 activity_monitor.Mem_MinActiveFreq,
1467 activity_monitor.Mem_BoosterFreqType,
1468 activity_monitor.Mem_BoosterFreq,
1469 activity_monitor.Mem_PD_Data_limit_c,
1470 activity_monitor.Mem_PD_Data_error_coeff,
1471 activity_monitor.Mem_PD_Data_error_rate_coeff);
1472 }
1473
1474 return size;
1475}
1476
1477static int navi10_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size)
1478{
1479 DpmActivityMonitorCoeffInt_t activity_monitor;
1480 int workload_type, ret = 0;
1481
1482 smu->power_profile_mode = input[size];
1483
1484 if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
1485 dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode);
1486 return -EINVAL;
1487 }
1488
1489 if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) {
1490
1491 ret = smu_cmn_update_table(smu,
1492 SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
1493 (void *)(&activity_monitor), false);
1494 if (ret) {
1495 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
1496 return ret;
1497 }
1498
1499 switch (input[0]) {
1500 case 0:
1501 activity_monitor.Gfx_FPS = input[1];
1502 activity_monitor.Gfx_MinFreqStep = input[2];
1503 activity_monitor.Gfx_MinActiveFreqType = input[3];
1504 activity_monitor.Gfx_MinActiveFreq = input[4];
1505 activity_monitor.Gfx_BoosterFreqType = input[5];
1506 activity_monitor.Gfx_BoosterFreq = input[6];
1507 activity_monitor.Gfx_PD_Data_limit_c = input[7];
1508 activity_monitor.Gfx_PD_Data_error_coeff = input[8];
1509 activity_monitor.Gfx_PD_Data_error_rate_coeff = input[9];
1510 break;
1511 case 1:
1512 activity_monitor.Soc_FPS = input[1];
1513 activity_monitor.Soc_MinFreqStep = input[2];
1514 activity_monitor.Soc_MinActiveFreqType = input[3];
1515 activity_monitor.Soc_MinActiveFreq = input[4];
1516 activity_monitor.Soc_BoosterFreqType = input[5];
1517 activity_monitor.Soc_BoosterFreq = input[6];
1518 activity_monitor.Soc_PD_Data_limit_c = input[7];
1519 activity_monitor.Soc_PD_Data_error_coeff = input[8];
1520 activity_monitor.Soc_PD_Data_error_rate_coeff = input[9];
1521 break;
1522 case 2:
1523 activity_monitor.Mem_FPS = input[1];
1524 activity_monitor.Mem_MinFreqStep = input[2];
1525 activity_monitor.Mem_MinActiveFreqType = input[3];
1526 activity_monitor.Mem_MinActiveFreq = input[4];
1527 activity_monitor.Mem_BoosterFreqType = input[5];
1528 activity_monitor.Mem_BoosterFreq = input[6];
1529 activity_monitor.Mem_PD_Data_limit_c = input[7];
1530 activity_monitor.Mem_PD_Data_error_coeff = input[8];
1531 activity_monitor.Mem_PD_Data_error_rate_coeff = input[9];
1532 break;
1533 }
1534
1535 ret = smu_cmn_update_table(smu,
1536 SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT,
1537 (void *)(&activity_monitor), true);
1538 if (ret) {
1539 dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);
1540 return ret;
1541 }
1542 }
1543
1544
1545 workload_type = smu_cmn_to_asic_specific_index(smu,
1546 CMN2ASIC_MAPPING_WORKLOAD,
1547 smu->power_profile_mode);
1548 if (workload_type < 0)
1549 return -EINVAL;
1550 smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask,
1551 1 << workload_type, NULL);
1552
1553 return ret;
1554}
1555
1556static int navi10_notify_smc_display_config(struct smu_context *smu)
1557{
1558 struct smu_clocks min_clocks = {0};
1559 struct pp_display_clock_request clock_req;
1560 int ret = 0;
1561
1562 min_clocks.dcef_clock = smu->display_config->min_dcef_set_clk;
1563 min_clocks.dcef_clock_in_sr = smu->display_config->min_dcef_deep_sleep_set_clk;
1564 min_clocks.memory_clock = smu->display_config->min_mem_set_clock;
1565
1566 if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) {
1567 clock_req.clock_type = amd_pp_dcef_clock;
1568 clock_req.clock_freq_in_khz = min_clocks.dcef_clock * 10;
1569
1570 ret = smu_v11_0_display_clock_voltage_request(smu, &clock_req);
1571 if (!ret) {
1572 if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_DCEFCLK_BIT)) {
1573 ret = smu_cmn_send_smc_msg_with_param(smu,
1574 SMU_MSG_SetMinDeepSleepDcefclk,
1575 min_clocks.dcef_clock_in_sr/100,
1576 NULL);
1577 if (ret) {
1578 dev_err(smu->adev->dev, "Attempt to set divider for DCEFCLK Failed!");
1579 return ret;
1580 }
1581 }
1582 } else {
1583 dev_info(smu->adev->dev, "Attempt to set Hard Min for DCEFCLK Failed!");
1584 }
1585 }
1586
1587 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
1588 ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, min_clocks.memory_clock/100, 0);
1589 if (ret) {
1590 dev_err(smu->adev->dev, "[%s] Set hard min uclk failed!", __func__);
1591 return ret;
1592 }
1593 }
1594
1595 return 0;
1596}
1597
1598static int navi10_set_watermarks_table(struct smu_context *smu,
1599 struct pp_smu_wm_range_sets *clock_ranges)
1600{
1601 Watermarks_t *table = smu->smu_table.watermarks_table;
1602 int ret = 0;
1603 int i;
1604
1605 if (clock_ranges) {
1606 if (clock_ranges->num_reader_wm_sets > NUM_WM_RANGES ||
1607 clock_ranges->num_writer_wm_sets > NUM_WM_RANGES)
1608 return -EINVAL;
1609
1610 for (i = 0; i < clock_ranges->num_reader_wm_sets; i++) {
1611 table->WatermarkRow[WM_DCEFCLK][i].MinClock =
1612 clock_ranges->reader_wm_sets[i].min_drain_clk_mhz;
1613 table->WatermarkRow[WM_DCEFCLK][i].MaxClock =
1614 clock_ranges->reader_wm_sets[i].max_drain_clk_mhz;
1615 table->WatermarkRow[WM_DCEFCLK][i].MinUclk =
1616 clock_ranges->reader_wm_sets[i].min_fill_clk_mhz;
1617 table->WatermarkRow[WM_DCEFCLK][i].MaxUclk =
1618 clock_ranges->reader_wm_sets[i].max_fill_clk_mhz;
1619
1620 table->WatermarkRow[WM_DCEFCLK][i].WmSetting =
1621 clock_ranges->reader_wm_sets[i].wm_inst;
1622 }
1623
1624 for (i = 0; i < clock_ranges->num_writer_wm_sets; i++) {
1625 table->WatermarkRow[WM_SOCCLK][i].MinClock =
1626 clock_ranges->writer_wm_sets[i].min_fill_clk_mhz;
1627 table->WatermarkRow[WM_SOCCLK][i].MaxClock =
1628 clock_ranges->writer_wm_sets[i].max_fill_clk_mhz;
1629 table->WatermarkRow[WM_SOCCLK][i].MinUclk =
1630 clock_ranges->writer_wm_sets[i].min_drain_clk_mhz;
1631 table->WatermarkRow[WM_SOCCLK][i].MaxUclk =
1632 clock_ranges->writer_wm_sets[i].max_drain_clk_mhz;
1633
1634 table->WatermarkRow[WM_SOCCLK][i].WmSetting =
1635 clock_ranges->writer_wm_sets[i].wm_inst;
1636 }
1637
1638 smu->watermarks_bitmap |= WATERMARKS_EXIST;
1639 }
1640
1641
1642 if ((smu->watermarks_bitmap & WATERMARKS_EXIST) &&
1643 !(smu->watermarks_bitmap & WATERMARKS_LOADED)) {
1644 ret = smu_cmn_write_watermarks_table(smu);
1645 if (ret) {
1646 dev_err(smu->adev->dev, "Failed to update WMTABLE!");
1647 return ret;
1648 }
1649 smu->watermarks_bitmap |= WATERMARKS_LOADED;
1650 }
1651
1652 return 0;
1653}
1654
1655static int navi10_thermal_get_temperature(struct smu_context *smu,
1656 enum amd_pp_sensors sensor,
1657 uint32_t *value)
1658{
1659 int ret = 0;
1660
1661 if (!value)
1662 return -EINVAL;
1663
1664 switch (sensor) {
1665 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
1666 ret = navi10_get_smu_metrics_data(smu,
1667 METRICS_TEMPERATURE_HOTSPOT,
1668 value);
1669 break;
1670 case AMDGPU_PP_SENSOR_EDGE_TEMP:
1671 ret = navi10_get_smu_metrics_data(smu,
1672 METRICS_TEMPERATURE_EDGE,
1673 value);
1674 break;
1675 case AMDGPU_PP_SENSOR_MEM_TEMP:
1676 ret = navi10_get_smu_metrics_data(smu,
1677 METRICS_TEMPERATURE_MEM,
1678 value);
1679 break;
1680 default:
1681 dev_err(smu->adev->dev, "Invalid sensor for retrieving temp\n");
1682 return -EINVAL;
1683 }
1684
1685 return ret;
1686}
1687
1688static int navi10_read_sensor(struct smu_context *smu,
1689 enum amd_pp_sensors sensor,
1690 void *data, uint32_t *size)
1691{
1692 int ret = 0;
1693 struct smu_table_context *table_context = &smu->smu_table;
1694 PPTable_t *pptable = table_context->driver_pptable;
1695
1696 if(!data || !size)
1697 return -EINVAL;
1698
1699 mutex_lock(&smu->sensor_lock);
1700 switch (sensor) {
1701 case AMDGPU_PP_SENSOR_MAX_FAN_RPM:
1702 *(uint32_t *)data = pptable->FanMaximumRpm;
1703 *size = 4;
1704 break;
1705 case AMDGPU_PP_SENSOR_MEM_LOAD:
1706 case AMDGPU_PP_SENSOR_GPU_LOAD:
1707 ret = navi10_get_current_activity_percent(smu, sensor, (uint32_t *)data);
1708 *size = 4;
1709 break;
1710 case AMDGPU_PP_SENSOR_GPU_POWER:
1711 ret = navi10_get_gpu_power(smu, (uint32_t *)data);
1712 *size = 4;
1713 break;
1714 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
1715 case AMDGPU_PP_SENSOR_EDGE_TEMP:
1716 case AMDGPU_PP_SENSOR_MEM_TEMP:
1717 ret = navi10_thermal_get_temperature(smu, sensor, (uint32_t *)data);
1718 *size = 4;
1719 break;
1720 case AMDGPU_PP_SENSOR_GFX_MCLK:
1721 ret = navi10_get_current_clk_freq_by_table(smu, SMU_UCLK, (uint32_t *)data);
1722 *(uint32_t *)data *= 100;
1723 *size = 4;
1724 break;
1725 case AMDGPU_PP_SENSOR_GFX_SCLK:
1726 ret = navi10_get_current_clk_freq_by_table(smu, SMU_GFXCLK, (uint32_t *)data);
1727 *(uint32_t *)data *= 100;
1728 *size = 4;
1729 break;
1730 case AMDGPU_PP_SENSOR_VDDGFX:
1731 ret = smu_v11_0_get_gfx_vdd(smu, (uint32_t *)data);
1732 *size = 4;
1733 break;
1734 default:
1735 ret = -EOPNOTSUPP;
1736 break;
1737 }
1738 mutex_unlock(&smu->sensor_lock);
1739
1740 return ret;
1741}
1742
1743static int navi10_get_uclk_dpm_states(struct smu_context *smu, uint32_t *clocks_in_khz, uint32_t *num_states)
1744{
1745 uint32_t num_discrete_levels = 0;
1746 uint16_t *dpm_levels = NULL;
1747 uint16_t i = 0;
1748 struct smu_table_context *table_context = &smu->smu_table;
1749 PPTable_t *driver_ppt = NULL;
1750
1751 if (!clocks_in_khz || !num_states || !table_context->driver_pptable)
1752 return -EINVAL;
1753
1754 driver_ppt = table_context->driver_pptable;
1755 num_discrete_levels = driver_ppt->DpmDescriptor[PPCLK_UCLK].NumDiscreteLevels;
1756 dpm_levels = driver_ppt->FreqTableUclk;
1757
1758 if (num_discrete_levels == 0 || dpm_levels == NULL)
1759 return -EINVAL;
1760
1761 *num_states = num_discrete_levels;
1762 for (i = 0; i < num_discrete_levels; i++) {
1763
1764 *clocks_in_khz = (*dpm_levels) * 1000;
1765 clocks_in_khz++;
1766 dpm_levels++;
1767 }
1768
1769 return 0;
1770}
1771
1772static int navi10_get_thermal_temperature_range(struct smu_context *smu,
1773 struct smu_temperature_range *range)
1774{
1775 struct smu_table_context *table_context = &smu->smu_table;
1776 struct smu_11_0_powerplay_table *powerplay_table =
1777 table_context->power_play_table;
1778 PPTable_t *pptable = smu->smu_table.driver_pptable;
1779
1780 if (!range)
1781 return -EINVAL;
1782
1783 memcpy(range, &smu11_thermal_policy[0], sizeof(struct smu_temperature_range));
1784
1785 range->max = pptable->TedgeLimit *
1786 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1787 range->edge_emergency_max = (pptable->TedgeLimit + CTF_OFFSET_EDGE) *
1788 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1789 range->hotspot_crit_max = pptable->ThotspotLimit *
1790 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1791 range->hotspot_emergency_max = (pptable->ThotspotLimit + CTF_OFFSET_HOTSPOT) *
1792 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1793 range->mem_crit_max = pptable->TmemLimit *
1794 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1795 range->mem_emergency_max = (pptable->TmemLimit + CTF_OFFSET_MEM)*
1796 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1797 range->software_shutdown_temp = powerplay_table->software_shutdown_temp;
1798
1799 return 0;
1800}
1801
1802static int navi10_display_disable_memory_clock_switch(struct smu_context *smu,
1803 bool disable_memory_clock_switch)
1804{
1805 int ret = 0;
1806 struct smu_11_0_max_sustainable_clocks *max_sustainable_clocks =
1807 (struct smu_11_0_max_sustainable_clocks *)
1808 smu->smu_table.max_sustainable_clocks;
1809 uint32_t min_memory_clock = smu->hard_min_uclk_req_from_dal;
1810 uint32_t max_memory_clock = max_sustainable_clocks->uclock;
1811
1812 if(smu->disable_uclk_switch == disable_memory_clock_switch)
1813 return 0;
1814
1815 if(disable_memory_clock_switch)
1816 ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, max_memory_clock, 0);
1817 else
1818 ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, min_memory_clock, 0);
1819
1820 if(!ret)
1821 smu->disable_uclk_switch = disable_memory_clock_switch;
1822
1823 return ret;
1824}
1825
1826static int navi10_get_power_limit(struct smu_context *smu)
1827{
1828 struct smu_11_0_powerplay_table *powerplay_table =
1829 (struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
1830 struct smu_11_0_overdrive_table *od_settings = smu->od_settings;
1831 PPTable_t *pptable = smu->smu_table.driver_pptable;
1832 uint32_t power_limit, od_percent;
1833
1834 if (smu_v11_0_get_current_power_limit(smu, &power_limit)) {
1835
1836 if (!pptable) {
1837 dev_err(smu->adev->dev, "Cannot get PPT limit due to pptable missing!");
1838 return -EINVAL;
1839 }
1840 power_limit =
1841 pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
1842 }
1843 smu->current_power_limit = power_limit;
1844
1845 if (smu->od_enabled &&
1846 navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT)) {
1847 od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
1848
1849 dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
1850
1851 power_limit *= (100 + od_percent);
1852 power_limit /= 100;
1853 }
1854 smu->max_power_limit = power_limit;
1855
1856 return 0;
1857}
1858
1859static int navi10_update_pcie_parameters(struct smu_context *smu,
1860 uint32_t pcie_gen_cap,
1861 uint32_t pcie_width_cap)
1862{
1863 struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
1864 PPTable_t *pptable = smu->smu_table.driver_pptable;
1865 uint32_t smu_pcie_arg;
1866 int ret, i;
1867
1868
1869 for (i = 0; i < MAX_PCIE_CONF; i++) {
1870 dpm_context->dpm_tables.pcie_table.pcie_gen[i] = pptable->PcieGenSpeed[i];
1871 dpm_context->dpm_tables.pcie_table.pcie_lane[i] = pptable->PcieLaneCount[i];
1872 }
1873
1874 for (i = 0; i < NUM_LINK_LEVELS; i++) {
1875 smu_pcie_arg = (i << 16) |
1876 ((pptable->PcieGenSpeed[i] <= pcie_gen_cap) ? (pptable->PcieGenSpeed[i] << 8) :
1877 (pcie_gen_cap << 8)) | ((pptable->PcieLaneCount[i] <= pcie_width_cap) ?
1878 pptable->PcieLaneCount[i] : pcie_width_cap);
1879 ret = smu_cmn_send_smc_msg_with_param(smu,
1880 SMU_MSG_OverridePcieParameters,
1881 smu_pcie_arg,
1882 NULL);
1883
1884 if (ret)
1885 return ret;
1886
1887 if (pptable->PcieGenSpeed[i] > pcie_gen_cap)
1888 dpm_context->dpm_tables.pcie_table.pcie_gen[i] = pcie_gen_cap;
1889 if (pptable->PcieLaneCount[i] > pcie_width_cap)
1890 dpm_context->dpm_tables.pcie_table.pcie_lane[i] = pcie_width_cap;
1891 }
1892
1893 return 0;
1894}
1895
1896static inline void navi10_dump_od_table(struct smu_context *smu,
1897 OverDriveTable_t *od_table)
1898{
1899 dev_dbg(smu->adev->dev, "OD: Gfxclk: (%d, %d)\n", od_table->GfxclkFmin, od_table->GfxclkFmax);
1900 dev_dbg(smu->adev->dev, "OD: Gfx1: (%d, %d)\n", od_table->GfxclkFreq1, od_table->GfxclkVolt1);
1901 dev_dbg(smu->adev->dev, "OD: Gfx2: (%d, %d)\n", od_table->GfxclkFreq2, od_table->GfxclkVolt2);
1902 dev_dbg(smu->adev->dev, "OD: Gfx3: (%d, %d)\n", od_table->GfxclkFreq3, od_table->GfxclkVolt3);
1903 dev_dbg(smu->adev->dev, "OD: UclkFmax: %d\n", od_table->UclkFmax);
1904 dev_dbg(smu->adev->dev, "OD: OverDrivePct: %d\n", od_table->OverDrivePct);
1905}
1906
1907static int navi10_od_setting_check_range(struct smu_context *smu,
1908 struct smu_11_0_overdrive_table *od_table,
1909 enum SMU_11_0_ODSETTING_ID setting,
1910 uint32_t value)
1911{
1912 if (value < od_table->min[setting]) {
1913 dev_warn(smu->adev->dev, "OD setting (%d, %d) is less than the minimum allowed (%d)\n", setting, value, od_table->min[setting]);
1914 return -EINVAL;
1915 }
1916 if (value > od_table->max[setting]) {
1917 dev_warn(smu->adev->dev, "OD setting (%d, %d) is greater than the maximum allowed (%d)\n", setting, value, od_table->max[setting]);
1918 return -EINVAL;
1919 }
1920 return 0;
1921}
1922
1923static int navi10_overdrive_get_gfx_clk_base_voltage(struct smu_context *smu,
1924 uint16_t *voltage,
1925 uint32_t freq)
1926{
1927 uint32_t param = (freq & 0xFFFF) | (PPCLK_GFXCLK << 16);
1928 uint32_t value = 0;
1929 int ret;
1930
1931 ret = smu_cmn_send_smc_msg_with_param(smu,
1932 SMU_MSG_GetVoltageByDpm,
1933 param,
1934 &value);
1935 if (ret) {
1936 dev_err(smu->adev->dev, "[GetBaseVoltage] failed to get GFXCLK AVFS voltage from SMU!");
1937 return ret;
1938 }
1939
1940 *voltage = (uint16_t)value;
1941
1942 return 0;
1943}
1944
1945static bool navi10_is_baco_supported(struct smu_context *smu)
1946{
1947 struct amdgpu_device *adev = smu->adev;
1948 uint32_t val;
1949
1950 if (amdgpu_sriov_vf(adev) || (!smu_v11_0_baco_is_support(smu)))
1951 return false;
1952
1953 val = RREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP0);
1954 return (val & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK) ? true : false;
1955}
1956
1957static int navi10_set_default_od_settings(struct smu_context *smu)
1958{
1959 OverDriveTable_t *od_table =
1960 (OverDriveTable_t *)smu->smu_table.overdrive_table;
1961 OverDriveTable_t *boot_od_table =
1962 (OverDriveTable_t *)smu->smu_table.boot_overdrive_table;
1963 int ret = 0;
1964
1965 ret = smu_cmn_update_table(smu, SMU_TABLE_OVERDRIVE, 0, (void *)od_table, false);
1966 if (ret) {
1967 dev_err(smu->adev->dev, "Failed to get overdrive table!\n");
1968 return ret;
1969 }
1970
1971 if (!od_table->GfxclkVolt1) {
1972 ret = navi10_overdrive_get_gfx_clk_base_voltage(smu,
1973 &od_table->GfxclkVolt1,
1974 od_table->GfxclkFreq1);
1975 if (ret)
1976 return ret;
1977 }
1978
1979 if (!od_table->GfxclkVolt2) {
1980 ret = navi10_overdrive_get_gfx_clk_base_voltage(smu,
1981 &od_table->GfxclkVolt2,
1982 od_table->GfxclkFreq2);
1983 if (ret)
1984 return ret;
1985 }
1986
1987 if (!od_table->GfxclkVolt3) {
1988 ret = navi10_overdrive_get_gfx_clk_base_voltage(smu,
1989 &od_table->GfxclkVolt3,
1990 od_table->GfxclkFreq3);
1991 if (ret)
1992 return ret;
1993 }
1994
1995 memcpy(boot_od_table, od_table, sizeof(OverDriveTable_t));
1996
1997 navi10_dump_od_table(smu, od_table);
1998
1999 return 0;
2000}
2001
2002static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, long input[], uint32_t size) {
2003 int i;
2004 int ret = 0;
2005 struct smu_table_context *table_context = &smu->smu_table;
2006 OverDriveTable_t *od_table;
2007 struct smu_11_0_overdrive_table *od_settings;
2008 enum SMU_11_0_ODSETTING_ID freq_setting, voltage_setting;
2009 uint16_t *freq_ptr, *voltage_ptr;
2010 od_table = (OverDriveTable_t *)table_context->overdrive_table;
2011
2012 if (!smu->od_enabled) {
2013 dev_warn(smu->adev->dev, "OverDrive is not enabled!\n");
2014 return -EINVAL;
2015 }
2016
2017 if (!smu->od_settings) {
2018 dev_err(smu->adev->dev, "OD board limits are not set!\n");
2019 return -ENOENT;
2020 }
2021
2022 od_settings = smu->od_settings;
2023
2024 switch (type) {
2025 case PP_OD_EDIT_SCLK_VDDC_TABLE:
2026 if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_LIMITS)) {
2027 dev_warn(smu->adev->dev, "GFXCLK_LIMITS not supported!\n");
2028 return -ENOTSUPP;
2029 }
2030 if (!table_context->overdrive_table) {
2031 dev_err(smu->adev->dev, "Overdrive is not initialized\n");
2032 return -EINVAL;
2033 }
2034 for (i = 0; i < size; i += 2) {
2035 if (i + 2 > size) {
2036 dev_info(smu->adev->dev, "invalid number of input parameters %d\n", size);
2037 return -EINVAL;
2038 }
2039 switch (input[i]) {
2040 case 0:
2041 freq_setting = SMU_11_0_ODSETTING_GFXCLKFMIN;
2042 freq_ptr = &od_table->GfxclkFmin;
2043 if (input[i + 1] > od_table->GfxclkFmax) {
2044 dev_info(smu->adev->dev, "GfxclkFmin (%ld) must be <= GfxclkFmax (%u)!\n",
2045 input[i + 1],
2046 od_table->GfxclkFmin);
2047 return -EINVAL;
2048 }
2049 break;
2050 case 1:
2051 freq_setting = SMU_11_0_ODSETTING_GFXCLKFMAX;
2052 freq_ptr = &od_table->GfxclkFmax;
2053 if (input[i + 1] < od_table->GfxclkFmin) {
2054 dev_info(smu->adev->dev, "GfxclkFmax (%ld) must be >= GfxclkFmin (%u)!\n",
2055 input[i + 1],
2056 od_table->GfxclkFmax);
2057 return -EINVAL;
2058 }
2059 break;
2060 default:
2061 dev_info(smu->adev->dev, "Invalid SCLK_VDDC_TABLE index: %ld\n", input[i]);
2062 dev_info(smu->adev->dev, "Supported indices: [0:min,1:max]\n");
2063 return -EINVAL;
2064 }
2065 ret = navi10_od_setting_check_range(smu, od_settings, freq_setting, input[i + 1]);
2066 if (ret)
2067 return ret;
2068 *freq_ptr = input[i + 1];
2069 }
2070 break;
2071 case PP_OD_EDIT_MCLK_VDDC_TABLE:
2072 if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_UCLK_MAX)) {
2073 dev_warn(smu->adev->dev, "UCLK_MAX not supported!\n");
2074 return -ENOTSUPP;
2075 }
2076 if (size < 2) {
2077 dev_info(smu->adev->dev, "invalid number of parameters: %d\n", size);
2078 return -EINVAL;
2079 }
2080 if (input[0] != 1) {
2081 dev_info(smu->adev->dev, "Invalid MCLK_VDDC_TABLE index: %ld\n", input[0]);
2082 dev_info(smu->adev->dev, "Supported indices: [1:max]\n");
2083 return -EINVAL;
2084 }
2085 ret = navi10_od_setting_check_range(smu, od_settings, SMU_11_0_ODSETTING_UCLKFMAX, input[1]);
2086 if (ret)
2087 return ret;
2088 od_table->UclkFmax = input[1];
2089 break;
2090 case PP_OD_RESTORE_DEFAULT_TABLE:
2091 if (!(table_context->overdrive_table && table_context->boot_overdrive_table)) {
2092 dev_err(smu->adev->dev, "Overdrive table was not initialized!\n");
2093 return -EINVAL;
2094 }
2095 memcpy(table_context->overdrive_table, table_context->boot_overdrive_table, sizeof(OverDriveTable_t));
2096 break;
2097 case PP_OD_COMMIT_DPM_TABLE:
2098 navi10_dump_od_table(smu, od_table);
2099 ret = smu_cmn_update_table(smu, SMU_TABLE_OVERDRIVE, 0, (void *)od_table, true);
2100 if (ret) {
2101 dev_err(smu->adev->dev, "Failed to import overdrive table!\n");
2102 return ret;
2103 }
2104 break;
2105 case PP_OD_EDIT_VDDC_CURVE:
2106 if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_CURVE)) {
2107 dev_warn(smu->adev->dev, "GFXCLK_CURVE not supported!\n");
2108 return -ENOTSUPP;
2109 }
2110 if (size < 3) {
2111 dev_info(smu->adev->dev, "invalid number of parameters: %d\n", size);
2112 return -EINVAL;
2113 }
2114 if (!od_table) {
2115 dev_info(smu->adev->dev, "Overdrive is not initialized\n");
2116 return -EINVAL;
2117 }
2118
2119 switch (input[0]) {
2120 case 0:
2121 freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1;
2122 voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1;
2123 freq_ptr = &od_table->GfxclkFreq1;
2124 voltage_ptr = &od_table->GfxclkVolt1;
2125 break;
2126 case 1:
2127 freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2;
2128 voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2;
2129 freq_ptr = &od_table->GfxclkFreq2;
2130 voltage_ptr = &od_table->GfxclkVolt2;
2131 break;
2132 case 2:
2133 freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3;
2134 voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3;
2135 freq_ptr = &od_table->GfxclkFreq3;
2136 voltage_ptr = &od_table->GfxclkVolt3;
2137 break;
2138 default:
2139 dev_info(smu->adev->dev, "Invalid VDDC_CURVE index: %ld\n", input[0]);
2140 dev_info(smu->adev->dev, "Supported indices: [0, 1, 2]\n");
2141 return -EINVAL;
2142 }
2143 ret = navi10_od_setting_check_range(smu, od_settings, freq_setting, input[1]);
2144 if (ret)
2145 return ret;
2146
2147 if (input[2] != 0) {
2148 ret = navi10_od_setting_check_range(smu, od_settings, voltage_setting, input[2]);
2149 if (ret)
2150 return ret;
2151 *freq_ptr = input[1];
2152 *voltage_ptr = ((uint16_t)input[2]) * NAVI10_VOLTAGE_SCALE;
2153 dev_dbg(smu->adev->dev, "OD: set curve %ld: (%d, %d)\n", input[0], *freq_ptr, *voltage_ptr);
2154 } else {
2155
2156 od_table->GfxclkVolt1 = 0;
2157 od_table->GfxclkVolt2 = 0;
2158 od_table->GfxclkVolt3 = 0;
2159 }
2160 navi10_dump_od_table(smu, od_table);
2161 break;
2162 default:
2163 return -ENOSYS;
2164 }
2165 return ret;
2166}
2167
2168static int navi10_run_btc(struct smu_context *smu)
2169{
2170 int ret = 0;
2171
2172 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_RunBtc, NULL);
2173 if (ret)
2174 dev_err(smu->adev->dev, "RunBtc failed!\n");
2175
2176 return ret;
2177}
2178
2179static bool navi10_need_umc_cdr_workaround(struct smu_context *smu)
2180{
2181 struct amdgpu_device *adev = smu->adev;
2182
2183 if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT))
2184 return false;
2185
2186 if (adev->asic_type == CHIP_NAVI10 ||
2187 adev->asic_type == CHIP_NAVI14)
2188 return true;
2189
2190 return false;
2191}
2192
2193static int navi10_umc_hybrid_cdr_workaround(struct smu_context *smu)
2194{
2195 uint32_t uclk_count, uclk_min, uclk_max;
2196 int ret = 0;
2197
2198
2199 if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT))
2200 return 0;
2201
2202 ret = smu_v11_0_get_dpm_level_count(smu, SMU_UCLK, &uclk_count);
2203 if (ret)
2204 return ret;
2205
2206 ret = smu_v11_0_get_dpm_freq_by_index(smu, SMU_UCLK, (uint16_t)(uclk_count - 1), &uclk_max);
2207 if (ret)
2208 return ret;
2209
2210
2211
2212
2213
2214
2215 if (uclk_max > 0x2EE)
2216 return 0;
2217
2218 ret = smu_v11_0_get_dpm_freq_by_index(smu, SMU_UCLK, (uint16_t)0, &uclk_min);
2219 if (ret)
2220 return ret;
2221
2222
2223 ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, 0, uclk_min);
2224 if (ret)
2225 return ret;
2226
2227
2228 ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, 0, uclk_max);
2229 if (ret)
2230 return ret;
2231
2232
2233
2234
2235
2236 return smu_cmn_send_smc_msg(smu, SMU_MSG_DAL_ENABLE_DUMMY_PSTATE_CHANGE, NULL);
2237}
2238
2239static int navi10_set_dummy_pstates_table_location(struct smu_context *smu)
2240{
2241 struct smu_table_context *smu_table = &smu->smu_table;
2242 struct smu_table *dummy_read_table =
2243 &smu_table->dummy_read_1_table;
2244 char *dummy_table = dummy_read_table->cpu_addr;
2245 int ret = 0;
2246 uint32_t i;
2247
2248 for (i = 0; i < 0x40000; i += 0x1000 * 2) {
2249 memcpy(dummy_table, &NoDbiPrbs7[0], 0x1000);
2250 dummy_table += 0x1000;
2251 memcpy(dummy_table, &DbiPrbs7[0], 0x1000);
2252 dummy_table += 0x1000;
2253 }
2254
2255 amdgpu_asic_flush_hdp(smu->adev, NULL);
2256
2257 ret = smu_cmn_send_smc_msg_with_param(smu,
2258 SMU_MSG_SET_DRIVER_DUMMY_TABLE_DRAM_ADDR_HIGH,
2259 upper_32_bits(dummy_read_table->mc_address),
2260 NULL);
2261 if (ret)
2262 return ret;
2263
2264 return smu_cmn_send_smc_msg_with_param(smu,
2265 SMU_MSG_SET_DRIVER_DUMMY_TABLE_DRAM_ADDR_LOW,
2266 lower_32_bits(dummy_read_table->mc_address),
2267 NULL);
2268}
2269
2270static int navi10_run_umc_cdr_workaround(struct smu_context *smu)
2271{
2272 struct amdgpu_device *adev = smu->adev;
2273 uint8_t umc_fw_greater_than_v136 = false;
2274 uint8_t umc_fw_disable_cdr = false;
2275 uint32_t pmfw_version;
2276 uint32_t param;
2277 int ret = 0;
2278
2279 if (!navi10_need_umc_cdr_workaround(smu))
2280 return 0;
2281
2282 ret = smu_cmn_get_smc_version(smu, NULL, &pmfw_version);
2283 if (ret) {
2284 dev_err(adev->dev, "Failed to get smu version!\n");
2285 return ret;
2286 }
2287
2288
2289
2290
2291
2292
2293
2294
2295 if (((adev->asic_type == CHIP_NAVI10) && (pmfw_version >= 0x2a3500)) ||
2296 ((adev->asic_type == CHIP_NAVI14) && (pmfw_version >= 0x351D00))) {
2297 ret = smu_cmn_send_smc_msg_with_param(smu,
2298 SMU_MSG_GET_UMC_FW_WA,
2299 0,
2300 ¶m);
2301 if (ret)
2302 return ret;
2303
2304
2305 umc_fw_greater_than_v136 = param & 0x1;
2306
2307
2308 umc_fw_disable_cdr = param & 0x2;
2309
2310
2311 if (umc_fw_greater_than_v136)
2312 return 0;
2313
2314 if (umc_fw_disable_cdr) {
2315 if (adev->asic_type == CHIP_NAVI10)
2316 return navi10_umc_hybrid_cdr_workaround(smu);
2317 } else {
2318 return navi10_set_dummy_pstates_table_location(smu);
2319 }
2320 } else {
2321 if (adev->asic_type == CHIP_NAVI10)
2322 return navi10_umc_hybrid_cdr_workaround(smu);
2323 }
2324
2325 return 0;
2326}
2327
2328static void navi10_fill_i2c_req(SwI2cRequest_t *req, bool write,
2329 uint8_t address, uint32_t numbytes,
2330 uint8_t *data)
2331{
2332 int i;
2333
2334 req->I2CcontrollerPort = 0;
2335 req->I2CSpeed = 2;
2336 req->SlaveAddress = address;
2337 req->NumCmds = numbytes;
2338
2339 for (i = 0; i < numbytes; i++) {
2340 SwI2cCmd_t *cmd = &req->SwI2cCmds[i];
2341
2342
2343 if (i < 2)
2344 cmd->Cmd = 1;
2345 else
2346 cmd->Cmd = write;
2347
2348
2349
2350 cmd->CmdConfig |= (i == 2 && !write) ? CMDCONFIG_RESTART_MASK : 0;
2351
2352
2353 cmd->CmdConfig |= (i == (numbytes - 1)) ? CMDCONFIG_STOP_MASK : 0;
2354
2355
2356 cmd->RegisterAddr = data[i];
2357 }
2358}
2359
2360static int navi10_i2c_read_data(struct i2c_adapter *control,
2361 uint8_t address,
2362 uint8_t *data,
2363 uint32_t numbytes)
2364{
2365 uint32_t i, ret = 0;
2366 SwI2cRequest_t req;
2367 struct amdgpu_device *adev = to_amdgpu_device(control);
2368 struct smu_table_context *smu_table = &adev->smu.smu_table;
2369 struct smu_table *table = &smu_table->driver_table;
2370
2371 if (numbytes > MAX_SW_I2C_COMMANDS) {
2372 dev_err(adev->dev, "numbytes requested %d is over max allowed %d\n",
2373 numbytes, MAX_SW_I2C_COMMANDS);
2374 return -EINVAL;
2375 }
2376
2377 memset(&req, 0, sizeof(req));
2378 navi10_fill_i2c_req(&req, false, address, numbytes, data);
2379
2380 mutex_lock(&adev->smu.mutex);
2381
2382 ret = smu_cmn_update_table(&adev->smu, SMU_TABLE_I2C_COMMANDS, 0, &req,
2383 true);
2384 mutex_unlock(&adev->smu.mutex);
2385
2386 if (!ret) {
2387 SwI2cRequest_t *res = (SwI2cRequest_t *)table->cpu_addr;
2388
2389
2390 for (i = 0; i < numbytes; i++)
2391 data[i] = res->SwI2cCmds[i].Data;
2392
2393 dev_dbg(adev->dev, "navi10_i2c_read_data, address = %x, bytes = %d, data :",
2394 (uint16_t)address, numbytes);
2395
2396 print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE,
2397 8, 1, data, numbytes, false);
2398 } else
2399 dev_err(adev->dev, "navi10_i2c_read_data - error occurred :%x", ret);
2400
2401 return ret;
2402}
2403
2404static int navi10_i2c_write_data(struct i2c_adapter *control,
2405 uint8_t address,
2406 uint8_t *data,
2407 uint32_t numbytes)
2408{
2409 uint32_t ret;
2410 SwI2cRequest_t req;
2411 struct amdgpu_device *adev = to_amdgpu_device(control);
2412
2413 if (numbytes > MAX_SW_I2C_COMMANDS) {
2414 dev_err(adev->dev, "numbytes requested %d is over max allowed %d\n",
2415 numbytes, MAX_SW_I2C_COMMANDS);
2416 return -EINVAL;
2417 }
2418
2419 memset(&req, 0, sizeof(req));
2420 navi10_fill_i2c_req(&req, true, address, numbytes, data);
2421
2422 mutex_lock(&adev->smu.mutex);
2423 ret = smu_cmn_update_table(&adev->smu, SMU_TABLE_I2C_COMMANDS, 0, &req, true);
2424 mutex_unlock(&adev->smu.mutex);
2425
2426 if (!ret) {
2427 dev_dbg(adev->dev, "navi10_i2c_write(), address = %x, bytes = %d , data: ",
2428 (uint16_t)address, numbytes);
2429
2430 print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE,
2431 8, 1, data, numbytes, false);
2432
2433
2434
2435
2436
2437
2438 msleep(10);
2439
2440 } else
2441 dev_err(adev->dev, "navi10_i2c_write- error occurred :%x", ret);
2442
2443 return ret;
2444}
2445
2446static int navi10_i2c_xfer(struct i2c_adapter *i2c_adap,
2447 struct i2c_msg *msgs, int num)
2448{
2449 uint32_t i, j, ret, data_size, data_chunk_size, next_eeprom_addr = 0;
2450 uint8_t *data_ptr, data_chunk[MAX_SW_I2C_COMMANDS] = { 0 };
2451
2452 for (i = 0; i < num; i++) {
2453
2454
2455
2456
2457
2458 data_size = msgs[i].len - 2;
2459 data_chunk_size = MAX_SW_I2C_COMMANDS - 2;
2460 next_eeprom_addr = (msgs[i].buf[0] << 8 & 0xff00) | (msgs[i].buf[1] & 0xff);
2461 data_ptr = msgs[i].buf + 2;
2462
2463 for (j = 0; j < data_size / data_chunk_size; j++) {
2464
2465 data_chunk[0] = ((next_eeprom_addr >> 8) & 0xff);
2466 data_chunk[1] = (next_eeprom_addr & 0xff);
2467
2468 if (msgs[i].flags & I2C_M_RD) {
2469 ret = navi10_i2c_read_data(i2c_adap,
2470 (uint8_t)msgs[i].addr,
2471 data_chunk, MAX_SW_I2C_COMMANDS);
2472
2473 memcpy(data_ptr, data_chunk + 2, data_chunk_size);
2474 } else {
2475
2476 memcpy(data_chunk + 2, data_ptr, data_chunk_size);
2477
2478 ret = navi10_i2c_write_data(i2c_adap,
2479 (uint8_t)msgs[i].addr,
2480 data_chunk, MAX_SW_I2C_COMMANDS);
2481 }
2482
2483 if (ret) {
2484 num = -EIO;
2485 goto fail;
2486 }
2487
2488 next_eeprom_addr += data_chunk_size;
2489 data_ptr += data_chunk_size;
2490 }
2491
2492 if (data_size % data_chunk_size) {
2493 data_chunk[0] = ((next_eeprom_addr >> 8) & 0xff);
2494 data_chunk[1] = (next_eeprom_addr & 0xff);
2495
2496 if (msgs[i].flags & I2C_M_RD) {
2497 ret = navi10_i2c_read_data(i2c_adap,
2498 (uint8_t)msgs[i].addr,
2499 data_chunk, (data_size % data_chunk_size) + 2);
2500
2501 memcpy(data_ptr, data_chunk + 2, data_size % data_chunk_size);
2502 } else {
2503 memcpy(data_chunk + 2, data_ptr, data_size % data_chunk_size);
2504
2505 ret = navi10_i2c_write_data(i2c_adap,
2506 (uint8_t)msgs[i].addr,
2507 data_chunk, (data_size % data_chunk_size) + 2);
2508 }
2509
2510 if (ret) {
2511 num = -EIO;
2512 goto fail;
2513 }
2514 }
2515 }
2516
2517fail:
2518 return num;
2519}
2520
2521static u32 navi10_i2c_func(struct i2c_adapter *adap)
2522{
2523 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
2524}
2525
2526
2527static const struct i2c_algorithm navi10_i2c_algo = {
2528 .master_xfer = navi10_i2c_xfer,
2529 .functionality = navi10_i2c_func,
2530};
2531
2532static ssize_t navi10_get_gpu_metrics(struct smu_context *smu,
2533 void **table)
2534{
2535 struct smu_table_context *smu_table = &smu->smu_table;
2536 struct gpu_metrics_v1_0 *gpu_metrics =
2537 (struct gpu_metrics_v1_0 *)smu_table->gpu_metrics_table;
2538 struct amdgpu_device *adev = smu->adev;
2539 SmuMetrics_NV12_t nv12_metrics = { 0 };
2540 SmuMetrics_t metrics;
2541 int ret = 0;
2542
2543 mutex_lock(&smu->metrics_lock);
2544
2545 ret = smu_cmn_get_metrics_table_locked(smu,
2546 NULL,
2547 true);
2548 if (ret) {
2549 mutex_unlock(&smu->metrics_lock);
2550 return ret;
2551 }
2552
2553 memcpy(&metrics, smu_table->metrics_table, sizeof(SmuMetrics_t));
2554 if (adev->asic_type == CHIP_NAVI12)
2555 memcpy(&nv12_metrics, smu_table->metrics_table, sizeof(SmuMetrics_NV12_t));
2556
2557 mutex_unlock(&smu->metrics_lock);
2558
2559 smu_v11_0_init_gpu_metrics_v1_0(gpu_metrics);
2560
2561 gpu_metrics->temperature_edge = metrics.TemperatureEdge;
2562 gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot;
2563 gpu_metrics->temperature_mem = metrics.TemperatureMem;
2564 gpu_metrics->temperature_vrgfx = metrics.TemperatureVrGfx;
2565 gpu_metrics->temperature_vrsoc = metrics.TemperatureVrSoc;
2566 gpu_metrics->temperature_vrmem = metrics.TemperatureVrMem0;
2567
2568 gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity;
2569 gpu_metrics->average_umc_activity = metrics.AverageUclkActivity;
2570
2571 gpu_metrics->average_socket_power = metrics.AverageSocketPower;
2572
2573 gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequency;
2574 gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency;
2575 gpu_metrics->average_uclk_frequency = metrics.AverageUclkFrequency;
2576
2577 if (adev->asic_type == CHIP_NAVI12) {
2578 gpu_metrics->energy_accumulator = nv12_metrics.EnergyAccumulator;
2579 gpu_metrics->average_vclk0_frequency = nv12_metrics.AverageVclkFrequency;
2580 gpu_metrics->average_dclk0_frequency = nv12_metrics.AverageDclkFrequency;
2581 gpu_metrics->average_mm_activity = nv12_metrics.VcnActivityPercentage;
2582 }
2583
2584 gpu_metrics->current_gfxclk = metrics.CurrClock[PPCLK_GFXCLK];
2585 gpu_metrics->current_socclk = metrics.CurrClock[PPCLK_SOCCLK];
2586 gpu_metrics->current_uclk = metrics.CurrClock[PPCLK_UCLK];
2587 gpu_metrics->current_vclk0 = metrics.CurrClock[PPCLK_VCLK];
2588 gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK];
2589
2590 gpu_metrics->throttle_status = metrics.ThrottlerStatus;
2591
2592 gpu_metrics->current_fan_speed = metrics.CurrFanSpeed;
2593
2594 gpu_metrics->pcie_link_width =
2595 smu_v11_0_get_current_pcie_link_width(smu);
2596 gpu_metrics->pcie_link_speed =
2597 smu_v11_0_get_current_pcie_link_speed(smu);
2598
2599 *table = (void *)gpu_metrics;
2600
2601 return sizeof(struct gpu_metrics_v1_0);
2602}
2603
2604static int navi10_enable_mgpu_fan_boost(struct smu_context *smu)
2605{
2606 struct amdgpu_device *adev = smu->adev;
2607 uint32_t param = 0;
2608
2609
2610 if (adev->asic_type == CHIP_NAVI12)
2611 return 0;
2612
2613
2614 if (adev->pdev->device == 0x7312 &&
2615 adev->pdev->revision == 0)
2616 param = 0xD188;
2617
2618 return smu_cmn_send_smc_msg_with_param(smu,
2619 SMU_MSG_SetMGpuFanBoostLimitRpm,
2620 param,
2621 NULL);
2622}
2623
2624static int navi10_post_smu_init(struct smu_context *smu)
2625{
2626 struct amdgpu_device *adev = smu->adev;
2627 int ret = 0;
2628
2629 if (amdgpu_sriov_vf(adev))
2630 return 0;
2631
2632 ret = navi10_run_umc_cdr_workaround(smu);
2633 if (ret) {
2634 dev_err(adev->dev, "Failed to apply umc cdr workaround!\n");
2635 return ret;
2636 }
2637
2638 if (!smu->dc_controlled_by_gpio) {
2639
2640
2641
2642
2643 ret = smu_v11_0_set_power_source(smu,
2644 adev->pm.ac_power ?
2645 SMU_POWER_SOURCE_AC :
2646 SMU_POWER_SOURCE_DC);
2647 if (ret) {
2648 dev_err(adev->dev, "Failed to switch to %s mode!\n",
2649 adev->pm.ac_power ? "AC" : "DC");
2650 return ret;
2651 }
2652 }
2653
2654 return ret;
2655}
2656
2657static const struct pptable_funcs navi10_ppt_funcs = {
2658 .get_allowed_feature_mask = navi10_get_allowed_feature_mask,
2659 .set_default_dpm_table = navi10_set_default_dpm_table,
2660 .dpm_set_vcn_enable = navi10_dpm_set_vcn_enable,
2661 .dpm_set_jpeg_enable = navi10_dpm_set_jpeg_enable,
2662 .print_clk_levels = navi10_print_clk_levels,
2663 .force_clk_levels = navi10_force_clk_levels,
2664 .populate_umd_state_clk = navi10_populate_umd_state_clk,
2665 .get_clock_by_type_with_latency = navi10_get_clock_by_type_with_latency,
2666 .pre_display_config_changed = navi10_pre_display_config_changed,
2667 .display_config_changed = navi10_display_config_changed,
2668 .notify_smc_display_config = navi10_notify_smc_display_config,
2669 .is_dpm_running = navi10_is_dpm_running,
2670 .get_fan_speed_rpm = navi10_get_fan_speed_rpm,
2671 .get_power_profile_mode = navi10_get_power_profile_mode,
2672 .set_power_profile_mode = navi10_set_power_profile_mode,
2673 .set_watermarks_table = navi10_set_watermarks_table,
2674 .read_sensor = navi10_read_sensor,
2675 .get_uclk_dpm_states = navi10_get_uclk_dpm_states,
2676 .set_performance_level = smu_v11_0_set_performance_level,
2677 .get_thermal_temperature_range = navi10_get_thermal_temperature_range,
2678 .display_disable_memory_clock_switch = navi10_display_disable_memory_clock_switch,
2679 .get_power_limit = navi10_get_power_limit,
2680 .update_pcie_parameters = navi10_update_pcie_parameters,
2681 .init_microcode = smu_v11_0_init_microcode,
2682 .load_microcode = smu_v11_0_load_microcode,
2683 .fini_microcode = smu_v11_0_fini_microcode,
2684 .init_smc_tables = navi10_init_smc_tables,
2685 .fini_smc_tables = smu_v11_0_fini_smc_tables,
2686 .init_power = smu_v11_0_init_power,
2687 .fini_power = smu_v11_0_fini_power,
2688 .check_fw_status = smu_v11_0_check_fw_status,
2689 .setup_pptable = navi10_setup_pptable,
2690 .get_vbios_bootup_values = smu_v11_0_get_vbios_bootup_values,
2691 .check_fw_version = smu_v11_0_check_fw_version,
2692 .write_pptable = smu_cmn_write_pptable,
2693 .set_driver_table_location = smu_v11_0_set_driver_table_location,
2694 .set_tool_table_location = smu_v11_0_set_tool_table_location,
2695 .notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
2696 .system_features_control = smu_v11_0_system_features_control,
2697 .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param,
2698 .send_smc_msg = smu_cmn_send_smc_msg,
2699 .init_display_count = smu_v11_0_init_display_count,
2700 .set_allowed_mask = smu_v11_0_set_allowed_mask,
2701 .get_enabled_mask = smu_cmn_get_enabled_mask,
2702 .feature_is_enabled = smu_cmn_feature_is_enabled,
2703 .disable_all_features_with_exception = smu_cmn_disable_all_features_with_exception,
2704 .notify_display_change = smu_v11_0_notify_display_change,
2705 .set_power_limit = smu_v11_0_set_power_limit,
2706 .init_max_sustainable_clocks = smu_v11_0_init_max_sustainable_clocks,
2707 .enable_thermal_alert = smu_v11_0_enable_thermal_alert,
2708 .disable_thermal_alert = smu_v11_0_disable_thermal_alert,
2709 .set_min_dcef_deep_sleep = smu_v11_0_set_min_deep_sleep_dcefclk,
2710 .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
2711 .get_fan_control_mode = smu_v11_0_get_fan_control_mode,
2712 .set_fan_control_mode = smu_v11_0_set_fan_control_mode,
2713 .set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
2714 .set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
2715 .gfx_off_control = smu_v11_0_gfx_off_control,
2716 .register_irq_handler = smu_v11_0_register_irq_handler,
2717 .set_azalia_d3_pme = smu_v11_0_set_azalia_d3_pme,
2718 .get_max_sustainable_clocks_by_dc = smu_v11_0_get_max_sustainable_clocks_by_dc,
2719 .baco_is_support= navi10_is_baco_supported,
2720 .baco_get_state = smu_v11_0_baco_get_state,
2721 .baco_set_state = smu_v11_0_baco_set_state,
2722 .baco_enter = smu_v11_0_baco_enter,
2723 .baco_exit = smu_v11_0_baco_exit,
2724 .get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq,
2725 .set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range,
2726 .set_default_od_settings = navi10_set_default_od_settings,
2727 .od_edit_dpm_table = navi10_od_edit_dpm_table,
2728 .run_btc = navi10_run_btc,
2729 .set_power_source = smu_v11_0_set_power_source,
2730 .get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
2731 .set_pp_feature_mask = smu_cmn_set_pp_feature_mask,
2732 .get_gpu_metrics = navi10_get_gpu_metrics,
2733 .enable_mgpu_fan_boost = navi10_enable_mgpu_fan_boost,
2734 .gfx_ulv_control = smu_v11_0_gfx_ulv_control,
2735 .deep_sleep_control = smu_v11_0_deep_sleep_control,
2736 .get_fan_parameters = navi10_get_fan_parameters,
2737 .post_init = navi10_post_smu_init,
2738 .interrupt_work = smu_v11_0_interrupt_work,
2739};
2740
2741void navi10_set_ppt_funcs(struct smu_context *smu)
2742{
2743 smu->ppt_funcs = &navi10_ppt_funcs;
2744 smu->message_map = navi10_message_map;
2745 smu->clock_map = navi10_clk_map;
2746 smu->feature_map = navi10_feature_mask_map;
2747 smu->table_map = navi10_table_map;
2748 smu->pwr_src_map = navi10_pwr_src_map;
2749 smu->workload_map = navi10_workload_map;
2750}
2751