This source file includes following definitions.
- arcturus_get_smu_msg_index
- arcturus_get_smu_clk_index
- arcturus_get_smu_feature_index
- arcturus_get_smu_table_index
- arcturus_get_pwr_src_index
- arcturus_get_workload_type
- arcturus_tables_init
- arcturus_allocate_dpm_context
- arcturus_get_allowed_feature_mask
- arcturus_set_single_dpm_table
- arcturus_init_single_dpm_state
- arcturus_set_default_dpm_table
- arcturus_check_powerplay_table
- arcturus_store_powerplay_table
- arcturus_append_powerplay_table
- arcturus_run_btc_afll
- arcturus_populate_umd_state_clk
- arcturus_get_clk_table
- arcturus_freqs_in_same_level
- arcturus_print_clk_levels
- arcturus_upload_dpm_level
- arcturus_force_clk_levels
- arcturus_get_thermal_temperature_range
- arcturus_get_metrics_table
- arcturus_get_current_activity_percent
- arcturus_get_gpu_power
- arcturus_thermal_get_temperature
- arcturus_read_sensor
- arcturus_get_fan_speed_rpm
- arcturus_get_fan_speed_percent
- arcturus_get_current_clk_freq_by_table
- arcturus_find_lowest_dpm_level
- arcturus_find_highest_dpm_level
- arcturus_force_dpm_limit_value
- arcturus_unforce_dpm_levels
- arcturus_get_profiling_clk_mask
- arcturus_get_power_limit
- arcturus_get_power_profile_mode
- arcturus_set_power_profile_mode
- arcturus_dump_pptable
- arcturus_is_dpm_running
- arcturus_set_ppt_funcs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include "pp_debug.h"
25 #include <linux/firmware.h>
26 #include "amdgpu.h"
27 #include "amdgpu_smu.h"
28 #include "atomfirmware.h"
29 #include "amdgpu_atomfirmware.h"
30 #include "smu_v11_0.h"
31 #include "smu11_driver_if_arcturus.h"
32 #include "soc15_common.h"
33 #include "atom.h"
34 #include "power_state.h"
35 #include "arcturus_ppt.h"
36 #include "smu_v11_0_pptable.h"
37 #include "arcturus_ppsmc.h"
38 #include "nbio/nbio_7_4_sh_mask.h"
39
40 #define CTF_OFFSET_EDGE 5
41 #define CTF_OFFSET_HOTSPOT 5
42 #define CTF_OFFSET_HBM 5
43
44 #define MSG_MAP(msg, index) \
45 [SMU_MSG_##msg] = {1, (index)}
46 #define ARCTURUS_FEA_MAP(smu_feature, arcturus_feature) \
47 [smu_feature] = {1, (arcturus_feature)}
48
49 #define SMU_FEATURES_LOW_MASK 0x00000000FFFFFFFF
50 #define SMU_FEATURES_LOW_SHIFT 0
51 #define SMU_FEATURES_HIGH_MASK 0xFFFFFFFF00000000
52 #define SMU_FEATURES_HIGH_SHIFT 32
53
54 #define SMC_DPM_FEATURE ( \
55 FEATURE_DPM_PREFETCHER_MASK | \
56 FEATURE_DPM_GFXCLK_MASK | \
57 FEATURE_DPM_UCLK_MASK | \
58 FEATURE_DPM_SOCCLK_MASK | \
59 FEATURE_DPM_MP0CLK_MASK | \
60 FEATURE_DPM_FCLK_MASK | \
61 FEATURE_DPM_XGMI_MASK)
62
63
64 #define EPSILON 1
65
66 static struct smu_11_0_cmn2aisc_mapping arcturus_message_map[SMU_MSG_MAX_COUNT] = {
67 MSG_MAP(TestMessage, PPSMC_MSG_TestMessage),
68 MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion),
69 MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion),
70 MSG_MAP(SetAllowedFeaturesMaskLow, PPSMC_MSG_SetAllowedFeaturesMaskLow),
71 MSG_MAP(SetAllowedFeaturesMaskHigh, PPSMC_MSG_SetAllowedFeaturesMaskHigh),
72 MSG_MAP(EnableAllSmuFeatures, PPSMC_MSG_EnableAllSmuFeatures),
73 MSG_MAP(DisableAllSmuFeatures, PPSMC_MSG_DisableAllSmuFeatures),
74 MSG_MAP(EnableSmuFeaturesLow, PPSMC_MSG_EnableSmuFeaturesLow),
75 MSG_MAP(EnableSmuFeaturesHigh, PPSMC_MSG_EnableSmuFeaturesHigh),
76 MSG_MAP(DisableSmuFeaturesLow, PPSMC_MSG_DisableSmuFeaturesLow),
77 MSG_MAP(DisableSmuFeaturesHigh, PPSMC_MSG_DisableSmuFeaturesHigh),
78 MSG_MAP(GetEnabledSmuFeaturesLow, PPSMC_MSG_GetEnabledSmuFeaturesLow),
79 MSG_MAP(GetEnabledSmuFeaturesHigh, PPSMC_MSG_GetEnabledSmuFeaturesHigh),
80 MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh),
81 MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow),
82 MSG_MAP(SetToolsDramAddrHigh, PPSMC_MSG_SetToolsDramAddrHigh),
83 MSG_MAP(SetToolsDramAddrLow, PPSMC_MSG_SetToolsDramAddrLow),
84 MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram),
85 MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu),
86 MSG_MAP(UseDefaultPPTable, PPSMC_MSG_UseDefaultPPTable),
87 MSG_MAP(UseBackupPPTable, PPSMC_MSG_UseBackupPPTable),
88 MSG_MAP(SetSystemVirtualDramAddrHigh, PPSMC_MSG_SetSystemVirtualDramAddrHigh),
89 MSG_MAP(SetSystemVirtualDramAddrLow, PPSMC_MSG_SetSystemVirtualDramAddrLow),
90 MSG_MAP(EnterBaco, PPSMC_MSG_EnterBaco),
91 MSG_MAP(ExitBaco, PPSMC_MSG_ExitBaco),
92 MSG_MAP(ArmD3, PPSMC_MSG_ArmD3),
93 MSG_MAP(SetSoftMinByFreq, PPSMC_MSG_SetSoftMinByFreq),
94 MSG_MAP(SetSoftMaxByFreq, PPSMC_MSG_SetSoftMaxByFreq),
95 MSG_MAP(SetHardMinByFreq, PPSMC_MSG_SetHardMinByFreq),
96 MSG_MAP(SetHardMaxByFreq, PPSMC_MSG_SetHardMaxByFreq),
97 MSG_MAP(GetMinDpmFreq, PPSMC_MSG_GetMinDpmFreq),
98 MSG_MAP(GetMaxDpmFreq, PPSMC_MSG_GetMaxDpmFreq),
99 MSG_MAP(GetDpmFreqByIndex, PPSMC_MSG_GetDpmFreqByIndex),
100 MSG_MAP(SetWorkloadMask, PPSMC_MSG_SetWorkloadMask),
101 MSG_MAP(SetDfSwitchType, PPSMC_MSG_SetDfSwitchType),
102 MSG_MAP(GetVoltageByDpm, PPSMC_MSG_GetVoltageByDpm),
103 MSG_MAP(GetVoltageByDpmOverdrive, PPSMC_MSG_GetVoltageByDpmOverdrive),
104 MSG_MAP(SetPptLimit, PPSMC_MSG_SetPptLimit),
105 MSG_MAP(GetPptLimit, PPSMC_MSG_GetPptLimit),
106 MSG_MAP(PowerUpVcn0, PPSMC_MSG_PowerUpVcn0),
107 MSG_MAP(PowerDownVcn0, PPSMC_MSG_PowerDownVcn0),
108 MSG_MAP(PowerUpVcn1, PPSMC_MSG_PowerUpVcn1),
109 MSG_MAP(PowerDownVcn1, PPSMC_MSG_PowerDownVcn1),
110 MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload),
111 MSG_MAP(PrepareMp1ForReset, PPSMC_MSG_PrepareMp1ForReset),
112 MSG_MAP(PrepareMp1ForShutdown, PPSMC_MSG_PrepareMp1ForShutdown),
113 MSG_MAP(SoftReset, PPSMC_MSG_SoftReset),
114 MSG_MAP(RunAfllBtc, PPSMC_MSG_RunAfllBtc),
115 MSG_MAP(RunGfxDcBtc, PPSMC_MSG_RunGfxDcBtc),
116 MSG_MAP(RunSocDcBtc, PPSMC_MSG_RunSocDcBtc),
117 MSG_MAP(DramLogSetDramAddrHigh, PPSMC_MSG_DramLogSetDramAddrHigh),
118 MSG_MAP(DramLogSetDramAddrLow, PPSMC_MSG_DramLogSetDramAddrLow),
119 MSG_MAP(DramLogSetDramSize, PPSMC_MSG_DramLogSetDramSize),
120 MSG_MAP(GetDebugData, PPSMC_MSG_GetDebugData),
121 MSG_MAP(WaflTest, PPSMC_MSG_WaflTest),
122 MSG_MAP(SetXgmiMode, PPSMC_MSG_SetXgmiMode),
123 MSG_MAP(SetMemoryChannelEnable, PPSMC_MSG_SetMemoryChannelEnable),
124 };
125
126 static struct smu_11_0_cmn2aisc_mapping arcturus_clk_map[SMU_CLK_COUNT] = {
127 CLK_MAP(GFXCLK, PPCLK_GFXCLK),
128 CLK_MAP(SCLK, PPCLK_GFXCLK),
129 CLK_MAP(SOCCLK, PPCLK_SOCCLK),
130 CLK_MAP(FCLK, PPCLK_FCLK),
131 CLK_MAP(UCLK, PPCLK_UCLK),
132 CLK_MAP(MCLK, PPCLK_UCLK),
133 CLK_MAP(DCLK, PPCLK_DCLK),
134 CLK_MAP(VCLK, PPCLK_VCLK),
135 };
136
137 static struct smu_11_0_cmn2aisc_mapping arcturus_feature_mask_map[SMU_FEATURE_COUNT] = {
138 FEA_MAP(DPM_PREFETCHER),
139 FEA_MAP(DPM_GFXCLK),
140 FEA_MAP(DPM_UCLK),
141 FEA_MAP(DPM_SOCCLK),
142 FEA_MAP(DPM_FCLK),
143 FEA_MAP(DPM_MP0CLK),
144 ARCTURUS_FEA_MAP(SMU_FEATURE_XGMI_BIT, FEATURE_DPM_XGMI_BIT),
145 FEA_MAP(DS_GFXCLK),
146 FEA_MAP(DS_SOCCLK),
147 FEA_MAP(DS_LCLK),
148 FEA_MAP(DS_FCLK),
149 FEA_MAP(DS_UCLK),
150 FEA_MAP(GFX_ULV),
151 ARCTURUS_FEA_MAP(SMU_FEATURE_VCN_PG_BIT, FEATURE_DPM_VCN_BIT),
152 FEA_MAP(RSMU_SMN_CG),
153 FEA_MAP(WAFL_CG),
154 FEA_MAP(PPT),
155 FEA_MAP(TDC),
156 FEA_MAP(APCC_PLUS),
157 FEA_MAP(VR0HOT),
158 FEA_MAP(VR1HOT),
159 FEA_MAP(FW_CTF),
160 FEA_MAP(FAN_CONTROL),
161 FEA_MAP(THERMAL),
162 FEA_MAP(OUT_OF_BAND_MONITOR),
163 FEA_MAP(TEMP_DEPENDENT_VMIN),
164 };
165
166 static struct smu_11_0_cmn2aisc_mapping arcturus_table_map[SMU_TABLE_COUNT] = {
167 TAB_MAP(PPTABLE),
168 TAB_MAP(AVFS),
169 TAB_MAP(AVFS_PSM_DEBUG),
170 TAB_MAP(AVFS_FUSE_OVERRIDE),
171 TAB_MAP(PMSTATUSLOG),
172 TAB_MAP(SMU_METRICS),
173 TAB_MAP(DRIVER_SMU_CONFIG),
174 TAB_MAP(OVERDRIVE),
175 };
176
177 static struct smu_11_0_cmn2aisc_mapping arcturus_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
178 PWR_MAP(AC),
179 PWR_MAP(DC),
180 };
181
182 static struct smu_11_0_cmn2aisc_mapping arcturus_workload_map[PP_SMC_POWER_PROFILE_COUNT] = {
183 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT, WORKLOAD_PPLIB_DEFAULT_BIT),
184 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING, WORKLOAD_PPLIB_POWER_SAVING_BIT),
185 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO, WORKLOAD_PPLIB_VIDEO_BIT),
186 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE, WORKLOAD_PPLIB_COMPUTE_BIT),
187 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT),
188 };
189
190 static int arcturus_get_smu_msg_index(struct smu_context *smc, uint32_t index)
191 {
192 struct smu_11_0_cmn2aisc_mapping mapping;
193
194 if (index >= SMU_MSG_MAX_COUNT)
195 return -EINVAL;
196
197 mapping = arcturus_message_map[index];
198 if (!(mapping.valid_mapping))
199 return -EINVAL;
200
201 return mapping.map_to;
202 }
203
204 static int arcturus_get_smu_clk_index(struct smu_context *smc, uint32_t index)
205 {
206 struct smu_11_0_cmn2aisc_mapping mapping;
207
208 if (index >= SMU_CLK_COUNT)
209 return -EINVAL;
210
211 mapping = arcturus_clk_map[index];
212 if (!(mapping.valid_mapping)) {
213 pr_warn("Unsupported SMU clk: %d\n", index);
214 return -EINVAL;
215 }
216
217 return mapping.map_to;
218 }
219
220 static int arcturus_get_smu_feature_index(struct smu_context *smc, uint32_t index)
221 {
222 struct smu_11_0_cmn2aisc_mapping mapping;
223
224 if (index >= SMU_FEATURE_COUNT)
225 return -EINVAL;
226
227 mapping = arcturus_feature_mask_map[index];
228 if (!(mapping.valid_mapping)) {
229 return -EINVAL;
230 }
231
232 return mapping.map_to;
233 }
234
235 static int arcturus_get_smu_table_index(struct smu_context *smc, uint32_t index)
236 {
237 struct smu_11_0_cmn2aisc_mapping mapping;
238
239 if (index >= SMU_TABLE_COUNT)
240 return -EINVAL;
241
242 mapping = arcturus_table_map[index];
243 if (!(mapping.valid_mapping)) {
244 pr_warn("Unsupported SMU table: %d\n", index);
245 return -EINVAL;
246 }
247
248 return mapping.map_to;
249 }
250
251 static int arcturus_get_pwr_src_index(struct smu_context *smc, uint32_t index)
252 {
253 struct smu_11_0_cmn2aisc_mapping mapping;
254
255 if (index >= SMU_POWER_SOURCE_COUNT)
256 return -EINVAL;
257
258 mapping = arcturus_pwr_src_map[index];
259 if (!(mapping.valid_mapping)) {
260 pr_warn("Unsupported SMU power source: %d\n", index);
261 return -EINVAL;
262 }
263
264 return mapping.map_to;
265 }
266
267
268 static int arcturus_get_workload_type(struct smu_context *smu, enum PP_SMC_POWER_PROFILE profile)
269 {
270 struct smu_11_0_cmn2aisc_mapping mapping;
271
272 if (profile > PP_SMC_POWER_PROFILE_CUSTOM)
273 return -EINVAL;
274
275 mapping = arcturus_workload_map[profile];
276 if (!(mapping.valid_mapping)) {
277 pr_warn("Unsupported SMU power source: %d\n", profile);
278 return -EINVAL;
279 }
280
281 return mapping.map_to;
282 }
283
284 static int arcturus_tables_init(struct smu_context *smu, struct smu_table *tables)
285 {
286 struct smu_table_context *smu_table = &smu->smu_table;
287
288 SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t),
289 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
290
291 SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU11_TOOL_SIZE,
292 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
293
294 SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
295 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
296
297 smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
298 if (!smu_table->metrics_table)
299 return -ENOMEM;
300 smu_table->metrics_time = 0;
301
302 return 0;
303 }
304
305 static int arcturus_allocate_dpm_context(struct smu_context *smu)
306 {
307 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
308
309 if (smu_dpm->dpm_context)
310 return -EINVAL;
311
312 smu_dpm->dpm_context = kzalloc(sizeof(struct arcturus_dpm_table),
313 GFP_KERNEL);
314 if (!smu_dpm->dpm_context)
315 return -ENOMEM;
316
317 if (smu_dpm->golden_dpm_context)
318 return -EINVAL;
319
320 smu_dpm->golden_dpm_context = kzalloc(sizeof(struct arcturus_dpm_table),
321 GFP_KERNEL);
322 if (!smu_dpm->golden_dpm_context)
323 return -ENOMEM;
324
325 smu_dpm->dpm_context_size = sizeof(struct arcturus_dpm_table);
326
327 smu_dpm->dpm_current_power_state = kzalloc(sizeof(struct smu_power_state),
328 GFP_KERNEL);
329 if (!smu_dpm->dpm_current_power_state)
330 return -ENOMEM;
331
332 smu_dpm->dpm_request_power_state = kzalloc(sizeof(struct smu_power_state),
333 GFP_KERNEL);
334 if (!smu_dpm->dpm_request_power_state)
335 return -ENOMEM;
336
337 return 0;
338 }
339
340 static int
341 arcturus_get_allowed_feature_mask(struct smu_context *smu,
342 uint32_t *feature_mask, uint32_t num)
343 {
344 if (num > 2)
345 return -EINVAL;
346
347
348 memset(feature_mask, 0xFF, sizeof(uint32_t) * num);
349
350 return 0;
351 }
352
353 static int
354 arcturus_set_single_dpm_table(struct smu_context *smu,
355 struct arcturus_single_dpm_table *single_dpm_table,
356 PPCLK_e clk_id)
357 {
358 int ret = 0;
359 uint32_t i, num_of_levels = 0, clk;
360
361 ret = smu_send_smc_msg_with_param(smu,
362 SMU_MSG_GetDpmFreqByIndex,
363 (clk_id << 16 | 0xFF));
364 if (ret) {
365 pr_err("[%s] failed to get dpm levels!\n", __func__);
366 return ret;
367 }
368
369 smu_read_smc_arg(smu, &num_of_levels);
370 if (!num_of_levels) {
371 pr_err("[%s] number of clk levels is invalid!\n", __func__);
372 return -EINVAL;
373 }
374
375 single_dpm_table->count = num_of_levels;
376 for (i = 0; i < num_of_levels; i++) {
377 ret = smu_send_smc_msg_with_param(smu,
378 SMU_MSG_GetDpmFreqByIndex,
379 (clk_id << 16 | i));
380 if (ret) {
381 pr_err("[%s] failed to get dpm freq by index!\n", __func__);
382 return ret;
383 }
384 smu_read_smc_arg(smu, &clk);
385 if (!clk) {
386 pr_err("[%s] clk value is invalid!\n", __func__);
387 return -EINVAL;
388 }
389 single_dpm_table->dpm_levels[i].value = clk;
390 single_dpm_table->dpm_levels[i].enabled = true;
391 }
392 return 0;
393 }
394
395 static void arcturus_init_single_dpm_state(struct arcturus_dpm_state *dpm_state)
396 {
397 dpm_state->soft_min_level = 0x0;
398 dpm_state->soft_max_level = 0xffff;
399 dpm_state->hard_min_level = 0x0;
400 dpm_state->hard_max_level = 0xffff;
401 }
402
403 static int arcturus_set_default_dpm_table(struct smu_context *smu)
404 {
405 int ret;
406
407 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
408 struct arcturus_dpm_table *dpm_table = NULL;
409 struct arcturus_single_dpm_table *single_dpm_table;
410
411 dpm_table = smu_dpm->dpm_context;
412
413
414 single_dpm_table = &(dpm_table->soc_table);
415 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
416 ret = arcturus_set_single_dpm_table(smu, single_dpm_table,
417 PPCLK_SOCCLK);
418 if (ret) {
419 pr_err("[%s] failed to get socclk dpm levels!\n", __func__);
420 return ret;
421 }
422 } else {
423 single_dpm_table->count = 1;
424 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.socclk / 100;
425 }
426 arcturus_init_single_dpm_state(&(single_dpm_table->dpm_state));
427
428
429 single_dpm_table = &(dpm_table->gfx_table);
430 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT)) {
431 ret = arcturus_set_single_dpm_table(smu, single_dpm_table,
432 PPCLK_GFXCLK);
433 if (ret) {
434 pr_err("[SetupDefaultDpmTable] failed to get gfxclk dpm levels!");
435 return ret;
436 }
437 } else {
438 single_dpm_table->count = 1;
439 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
440 }
441 arcturus_init_single_dpm_state(&(single_dpm_table->dpm_state));
442
443
444 single_dpm_table = &(dpm_table->mem_table);
445 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
446 ret = arcturus_set_single_dpm_table(smu, single_dpm_table,
447 PPCLK_UCLK);
448 if (ret) {
449 pr_err("[SetupDefaultDpmTable] failed to get memclk dpm levels!");
450 return ret;
451 }
452 } else {
453 single_dpm_table->count = 1;
454 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.uclk / 100;
455 }
456 arcturus_init_single_dpm_state(&(single_dpm_table->dpm_state));
457
458
459 single_dpm_table = &(dpm_table->fclk_table);
460 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_FCLK_BIT)) {
461 ret = arcturus_set_single_dpm_table(smu, single_dpm_table,
462 PPCLK_FCLK);
463 if (ret) {
464 pr_err("[SetupDefaultDpmTable] failed to get fclk dpm levels!");
465 return ret;
466 }
467 } else {
468 single_dpm_table->count = 1;
469 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.fclk / 100;
470 }
471 arcturus_init_single_dpm_state(&(single_dpm_table->dpm_state));
472
473 memcpy(smu_dpm->golden_dpm_context, dpm_table,
474 sizeof(struct arcturus_dpm_table));
475
476 return 0;
477 }
478
479 static int arcturus_check_powerplay_table(struct smu_context *smu)
480 {
481 return 0;
482 }
483
484 static int arcturus_store_powerplay_table(struct smu_context *smu)
485 {
486 struct smu_11_0_powerplay_table *powerplay_table = NULL;
487 struct smu_table_context *table_context = &smu->smu_table;
488 int ret = 0;
489
490 if (!table_context->power_play_table)
491 return -EINVAL;
492
493 powerplay_table = table_context->power_play_table;
494
495 memcpy(table_context->driver_pptable, &powerplay_table->smc_pptable,
496 sizeof(PPTable_t));
497
498 table_context->thermal_controller_type = powerplay_table->thermal_controller_type;
499
500 return ret;
501 }
502
503 static int arcturus_append_powerplay_table(struct smu_context *smu)
504 {
505 struct smu_table_context *table_context = &smu->smu_table;
506 PPTable_t *smc_pptable = table_context->driver_pptable;
507 struct atom_smc_dpm_info_v4_6 *smc_dpm_table;
508 int index, ret;
509
510 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
511 smc_dpm_info);
512
513 ret = smu_get_atom_data_table(smu, index, NULL, NULL, NULL,
514 (uint8_t **)&smc_dpm_table);
515 if (ret)
516 return ret;
517
518 pr_info("smc_dpm_info table revision(format.content): %d.%d\n",
519 smc_dpm_table->table_header.format_revision,
520 smc_dpm_table->table_header.content_revision);
521
522 if ((smc_dpm_table->table_header.format_revision == 4) &&
523 (smc_dpm_table->table_header.content_revision == 6))
524 memcpy(&smc_pptable->MaxVoltageStepGfx,
525 &smc_dpm_table->maxvoltagestepgfx,
526 sizeof(*smc_dpm_table) - offsetof(struct atom_smc_dpm_info_v4_6, maxvoltagestepgfx));
527
528 return 0;
529 }
530
531 static int arcturus_run_btc_afll(struct smu_context *smu)
532 {
533 return smu_send_smc_msg(smu, SMU_MSG_RunAfllBtc);
534 }
535
536 static int arcturus_populate_umd_state_clk(struct smu_context *smu)
537 {
538 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
539 struct arcturus_dpm_table *dpm_table = NULL;
540 struct arcturus_single_dpm_table *gfx_table = NULL;
541 struct arcturus_single_dpm_table *mem_table = NULL;
542
543 dpm_table = smu_dpm->dpm_context;
544 gfx_table = &(dpm_table->gfx_table);
545 mem_table = &(dpm_table->mem_table);
546
547 smu->pstate_sclk = gfx_table->dpm_levels[0].value;
548 smu->pstate_mclk = mem_table->dpm_levels[0].value;
549
550 if (gfx_table->count > ARCTURUS_UMD_PSTATE_GFXCLK_LEVEL &&
551 mem_table->count > ARCTURUS_UMD_PSTATE_MCLK_LEVEL) {
552 smu->pstate_sclk = gfx_table->dpm_levels[ARCTURUS_UMD_PSTATE_GFXCLK_LEVEL].value;
553 smu->pstate_mclk = mem_table->dpm_levels[ARCTURUS_UMD_PSTATE_MCLK_LEVEL].value;
554 }
555
556 smu->pstate_sclk = smu->pstate_sclk * 100;
557 smu->pstate_mclk = smu->pstate_mclk * 100;
558
559 return 0;
560 }
561
562 static int arcturus_get_clk_table(struct smu_context *smu,
563 struct pp_clock_levels_with_latency *clocks,
564 struct arcturus_single_dpm_table *dpm_table)
565 {
566 int i, count;
567
568 count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count;
569 clocks->num_levels = count;
570
571 for (i = 0; i < count; i++) {
572 clocks->data[i].clocks_in_khz =
573 dpm_table->dpm_levels[i].value * 1000;
574 clocks->data[i].latency_in_us = 0;
575 }
576
577 return 0;
578 }
579
580 static int arcturus_freqs_in_same_level(int32_t frequency1,
581 int32_t frequency2)
582 {
583 return (abs(frequency1 - frequency2) <= EPSILON);
584 }
585
586 static int arcturus_print_clk_levels(struct smu_context *smu,
587 enum smu_clk_type type, char *buf)
588 {
589 int i, now, size = 0;
590 int ret = 0;
591 struct pp_clock_levels_with_latency clocks;
592 struct arcturus_single_dpm_table *single_dpm_table;
593 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
594 struct arcturus_dpm_table *dpm_table = NULL;
595
596 dpm_table = smu_dpm->dpm_context;
597
598 switch (type) {
599 case SMU_SCLK:
600 ret = smu_get_current_clk_freq(smu, SMU_GFXCLK, &now);
601 if (ret) {
602 pr_err("Attempt to get current gfx clk Failed!");
603 return ret;
604 }
605
606 single_dpm_table = &(dpm_table->gfx_table);
607 ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table);
608 if (ret) {
609 pr_err("Attempt to get gfx clk levels Failed!");
610 return ret;
611 }
612
613 for (i = 0; i < clocks.num_levels; i++)
614 size += sprintf(buf + size, "%d: %uMhz %s\n", i,
615 clocks.data[i].clocks_in_khz / 1000,
616 arcturus_freqs_in_same_level(
617 clocks.data[i].clocks_in_khz / 1000,
618 now / 100) ? "*" : "");
619 break;
620
621 case SMU_MCLK:
622 ret = smu_get_current_clk_freq(smu, SMU_UCLK, &now);
623 if (ret) {
624 pr_err("Attempt to get current mclk Failed!");
625 return ret;
626 }
627
628 single_dpm_table = &(dpm_table->mem_table);
629 ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table);
630 if (ret) {
631 pr_err("Attempt to get memory clk levels Failed!");
632 return ret;
633 }
634
635 for (i = 0; i < clocks.num_levels; i++)
636 size += sprintf(buf + size, "%d: %uMhz %s\n",
637 i, clocks.data[i].clocks_in_khz / 1000,
638 arcturus_freqs_in_same_level(
639 clocks.data[i].clocks_in_khz / 1000,
640 now / 100) ? "*" : "");
641 break;
642
643 case SMU_SOCCLK:
644 ret = smu_get_current_clk_freq(smu, SMU_SOCCLK, &now);
645 if (ret) {
646 pr_err("Attempt to get current socclk Failed!");
647 return ret;
648 }
649
650 single_dpm_table = &(dpm_table->soc_table);
651 ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table);
652 if (ret) {
653 pr_err("Attempt to get socclk levels Failed!");
654 return ret;
655 }
656
657 for (i = 0; i < clocks.num_levels; i++)
658 size += sprintf(buf + size, "%d: %uMhz %s\n",
659 i, clocks.data[i].clocks_in_khz / 1000,
660 arcturus_freqs_in_same_level(
661 clocks.data[i].clocks_in_khz / 1000,
662 now / 100) ? "*" : "");
663 break;
664
665 case SMU_FCLK:
666 ret = smu_get_current_clk_freq(smu, SMU_FCLK, &now);
667 if (ret) {
668 pr_err("Attempt to get current fclk Failed!");
669 return ret;
670 }
671
672 single_dpm_table = &(dpm_table->fclk_table);
673 ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table);
674 if (ret) {
675 pr_err("Attempt to get fclk levels Failed!");
676 return ret;
677 }
678
679 for (i = 0; i < single_dpm_table->count; i++)
680 size += sprintf(buf + size, "%d: %uMhz %s\n",
681 i, single_dpm_table->dpm_levels[i].value,
682 arcturus_freqs_in_same_level(
683 clocks.data[i].clocks_in_khz / 1000,
684 now / 100) ? "*" : "");
685 break;
686
687 default:
688 break;
689 }
690
691 return size;
692 }
693
694 static int arcturus_upload_dpm_level(struct smu_context *smu, bool max,
695 uint32_t feature_mask)
696 {
697 struct arcturus_single_dpm_table *single_dpm_table;
698 struct arcturus_dpm_table *dpm_table =
699 smu->smu_dpm.dpm_context;
700 uint32_t freq;
701 int ret = 0;
702
703 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT) &&
704 (feature_mask & FEATURE_DPM_GFXCLK_MASK)) {
705 single_dpm_table = &(dpm_table->gfx_table);
706 freq = max ? single_dpm_table->dpm_state.soft_max_level :
707 single_dpm_table->dpm_state.soft_min_level;
708 ret = smu_send_smc_msg_with_param(smu,
709 (max ? SMU_MSG_SetSoftMaxByFreq : SMU_MSG_SetSoftMinByFreq),
710 (PPCLK_GFXCLK << 16) | (freq & 0xffff));
711 if (ret) {
712 pr_err("Failed to set soft %s gfxclk !\n",
713 max ? "max" : "min");
714 return ret;
715 }
716 }
717
718 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT) &&
719 (feature_mask & FEATURE_DPM_UCLK_MASK)) {
720 single_dpm_table = &(dpm_table->mem_table);
721 freq = max ? single_dpm_table->dpm_state.soft_max_level :
722 single_dpm_table->dpm_state.soft_min_level;
723 ret = smu_send_smc_msg_with_param(smu,
724 (max ? SMU_MSG_SetSoftMaxByFreq : SMU_MSG_SetSoftMinByFreq),
725 (PPCLK_UCLK << 16) | (freq & 0xffff));
726 if (ret) {
727 pr_err("Failed to set soft %s memclk !\n",
728 max ? "max" : "min");
729 return ret;
730 }
731 }
732
733 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT) &&
734 (feature_mask & FEATURE_DPM_SOCCLK_MASK)) {
735 single_dpm_table = &(dpm_table->soc_table);
736 freq = max ? single_dpm_table->dpm_state.soft_max_level :
737 single_dpm_table->dpm_state.soft_min_level;
738 ret = smu_send_smc_msg_with_param(smu,
739 (max ? SMU_MSG_SetSoftMaxByFreq : SMU_MSG_SetSoftMinByFreq),
740 (PPCLK_SOCCLK << 16) | (freq & 0xffff));
741 if (ret) {
742 pr_err("Failed to set soft %s socclk !\n",
743 max ? "max" : "min");
744 return ret;
745 }
746 }
747
748 return ret;
749 }
750
751 static int arcturus_force_clk_levels(struct smu_context *smu,
752 enum smu_clk_type type, uint32_t mask)
753 {
754 struct arcturus_dpm_table *dpm_table;
755 struct arcturus_single_dpm_table *single_dpm_table;
756 uint32_t soft_min_level, soft_max_level;
757 int ret = 0;
758
759 mutex_lock(&(smu->mutex));
760
761 soft_min_level = mask ? (ffs(mask) - 1) : 0;
762 soft_max_level = mask ? (fls(mask) - 1) : 0;
763
764 dpm_table = smu->smu_dpm.dpm_context;
765
766 switch (type) {
767 case SMU_SCLK:
768 single_dpm_table = &(dpm_table->gfx_table);
769
770 if (soft_max_level >= single_dpm_table->count) {
771 pr_err("Clock level specified %d is over max allowed %d\n",
772 soft_max_level, single_dpm_table->count - 1);
773 ret = -EINVAL;
774 break;
775 }
776
777 single_dpm_table->dpm_state.soft_min_level =
778 single_dpm_table->dpm_levels[soft_min_level].value;
779 single_dpm_table->dpm_state.soft_max_level =
780 single_dpm_table->dpm_levels[soft_max_level].value;
781
782 ret = arcturus_upload_dpm_level(smu, false, FEATURE_DPM_GFXCLK_MASK);
783 if (ret) {
784 pr_err("Failed to upload boot level to lowest!\n");
785 break;
786 }
787
788 ret = arcturus_upload_dpm_level(smu, true, FEATURE_DPM_GFXCLK_MASK);
789 if (ret)
790 pr_err("Failed to upload dpm max level to highest!\n");
791
792 break;
793
794 case SMU_MCLK:
795 single_dpm_table = &(dpm_table->mem_table);
796
797 if (soft_max_level >= single_dpm_table->count) {
798 pr_err("Clock level specified %d is over max allowed %d\n",
799 soft_max_level, single_dpm_table->count - 1);
800 ret = -EINVAL;
801 break;
802 }
803
804 single_dpm_table->dpm_state.soft_min_level =
805 single_dpm_table->dpm_levels[soft_min_level].value;
806 single_dpm_table->dpm_state.soft_max_level =
807 single_dpm_table->dpm_levels[soft_max_level].value;
808
809 ret = arcturus_upload_dpm_level(smu, false, FEATURE_DPM_UCLK_MASK);
810 if (ret) {
811 pr_err("Failed to upload boot level to lowest!\n");
812 break;
813 }
814
815 ret = arcturus_upload_dpm_level(smu, true, FEATURE_DPM_UCLK_MASK);
816 if (ret)
817 pr_err("Failed to upload dpm max level to highest!\n");
818
819 break;
820
821 case SMU_SOCCLK:
822 single_dpm_table = &(dpm_table->soc_table);
823
824 if (soft_max_level >= single_dpm_table->count) {
825 pr_err("Clock level specified %d is over max allowed %d\n",
826 soft_max_level, single_dpm_table->count - 1);
827 ret = -EINVAL;
828 break;
829 }
830
831 single_dpm_table->dpm_state.soft_min_level =
832 single_dpm_table->dpm_levels[soft_min_level].value;
833 single_dpm_table->dpm_state.soft_max_level =
834 single_dpm_table->dpm_levels[soft_max_level].value;
835
836 ret = arcturus_upload_dpm_level(smu, false, FEATURE_DPM_SOCCLK_MASK);
837 if (ret) {
838 pr_err("Failed to upload boot level to lowest!\n");
839 break;
840 }
841
842 ret = arcturus_upload_dpm_level(smu, true, FEATURE_DPM_SOCCLK_MASK);
843 if (ret)
844 pr_err("Failed to upload dpm max level to highest!\n");
845
846 break;
847
848 case SMU_FCLK:
849 single_dpm_table = &(dpm_table->fclk_table);
850
851 if (soft_max_level >= single_dpm_table->count) {
852 pr_err("Clock level specified %d is over max allowed %d\n",
853 soft_max_level, single_dpm_table->count - 1);
854 ret = -EINVAL;
855 break;
856 }
857
858 single_dpm_table->dpm_state.soft_min_level =
859 single_dpm_table->dpm_levels[soft_min_level].value;
860 single_dpm_table->dpm_state.soft_max_level =
861 single_dpm_table->dpm_levels[soft_max_level].value;
862
863 ret = arcturus_upload_dpm_level(smu, false, FEATURE_DPM_FCLK_MASK);
864 if (ret) {
865 pr_err("Failed to upload boot level to lowest!\n");
866 break;
867 }
868
869 ret = arcturus_upload_dpm_level(smu, true, FEATURE_DPM_FCLK_MASK);
870 if (ret)
871 pr_err("Failed to upload dpm max level to highest!\n");
872
873 break;
874
875 default:
876 break;
877 }
878
879 mutex_unlock(&(smu->mutex));
880 return ret;
881 }
882
883 static int arcturus_get_thermal_temperature_range(struct smu_context *smu,
884 struct smu_temperature_range *range)
885 {
886 PPTable_t *pptable = smu->smu_table.driver_pptable;
887
888 if (!range)
889 return -EINVAL;
890
891 range->max = pptable->TedgeLimit *
892 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
893 range->edge_emergency_max = (pptable->TedgeLimit + CTF_OFFSET_EDGE) *
894 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
895 range->hotspot_crit_max = pptable->ThotspotLimit *
896 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
897 range->hotspot_emergency_max = (pptable->ThotspotLimit + CTF_OFFSET_HOTSPOT) *
898 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
899 range->mem_crit_max = pptable->TmemLimit *
900 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
901 range->mem_emergency_max = (pptable->TmemLimit + CTF_OFFSET_HBM)*
902 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
903
904 return 0;
905 }
906
907 static int arcturus_get_metrics_table(struct smu_context *smu,
908 SmuMetrics_t *metrics_table)
909 {
910 struct smu_table_context *smu_table= &smu->smu_table;
911 int ret = 0;
912
913 mutex_lock(&smu->metrics_lock);
914 if (!smu_table->metrics_time ||
915 time_after(jiffies, smu_table->metrics_time + HZ / 1000)) {
916 ret = smu_update_table(smu, SMU_TABLE_SMU_METRICS, 0,
917 (void *)smu_table->metrics_table, false);
918 if (ret) {
919 pr_info("Failed to export SMU metrics table!\n");
920 mutex_unlock(&smu->metrics_lock);
921 return ret;
922 }
923 smu_table->metrics_time = jiffies;
924 }
925
926 memcpy(metrics_table, smu_table->metrics_table, sizeof(SmuMetrics_t));
927 mutex_unlock(&smu->metrics_lock);
928
929 return ret;
930 }
931
932 static int arcturus_get_current_activity_percent(struct smu_context *smu,
933 enum amd_pp_sensors sensor,
934 uint32_t *value)
935 {
936 SmuMetrics_t metrics;
937 int ret = 0;
938
939 if (!value)
940 return -EINVAL;
941
942 ret = arcturus_get_metrics_table(smu, &metrics);
943 if (ret)
944 return ret;
945
946 switch (sensor) {
947 case AMDGPU_PP_SENSOR_GPU_LOAD:
948 *value = metrics.AverageGfxActivity;
949 break;
950 case AMDGPU_PP_SENSOR_MEM_LOAD:
951 *value = metrics.AverageUclkActivity;
952 break;
953 default:
954 pr_err("Invalid sensor for retrieving clock activity\n");
955 return -EINVAL;
956 }
957
958 return 0;
959 }
960
961 static int arcturus_get_gpu_power(struct smu_context *smu, uint32_t *value)
962 {
963 SmuMetrics_t metrics;
964 int ret = 0;
965
966 if (!value)
967 return -EINVAL;
968
969 ret = arcturus_get_metrics_table(smu, &metrics);
970 if (ret)
971 return ret;
972
973 *value = metrics.AverageSocketPower << 8;
974
975 return 0;
976 }
977
978 static int arcturus_thermal_get_temperature(struct smu_context *smu,
979 enum amd_pp_sensors sensor,
980 uint32_t *value)
981 {
982 SmuMetrics_t metrics;
983 int ret = 0;
984
985 if (!value)
986 return -EINVAL;
987
988 ret = arcturus_get_metrics_table(smu, &metrics);
989 if (ret)
990 return ret;
991
992 switch (sensor) {
993 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
994 *value = metrics.TemperatureHotspot *
995 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
996 break;
997 case AMDGPU_PP_SENSOR_EDGE_TEMP:
998 *value = metrics.TemperatureEdge *
999 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1000 break;
1001 case AMDGPU_PP_SENSOR_MEM_TEMP:
1002 *value = metrics.TemperatureHBM *
1003 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1004 break;
1005 default:
1006 pr_err("Invalid sensor for retrieving temp\n");
1007 return -EINVAL;
1008 }
1009
1010 return 0;
1011 }
1012
1013 static int arcturus_read_sensor(struct smu_context *smu,
1014 enum amd_pp_sensors sensor,
1015 void *data, uint32_t *size)
1016 {
1017 struct smu_table_context *table_context = &smu->smu_table;
1018 PPTable_t *pptable = table_context->driver_pptable;
1019 int ret = 0;
1020
1021 if (!data || !size)
1022 return -EINVAL;
1023
1024 mutex_lock(&smu->sensor_lock);
1025 switch (sensor) {
1026 case AMDGPU_PP_SENSOR_MAX_FAN_RPM:
1027 *(uint32_t *)data = pptable->FanMaximumRpm;
1028 *size = 4;
1029 break;
1030 case AMDGPU_PP_SENSOR_MEM_LOAD:
1031 case AMDGPU_PP_SENSOR_GPU_LOAD:
1032 ret = arcturus_get_current_activity_percent(smu,
1033 sensor,
1034 (uint32_t *)data);
1035 *size = 4;
1036 break;
1037 case AMDGPU_PP_SENSOR_GPU_POWER:
1038 ret = arcturus_get_gpu_power(smu, (uint32_t *)data);
1039 *size = 4;
1040 break;
1041 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
1042 case AMDGPU_PP_SENSOR_EDGE_TEMP:
1043 case AMDGPU_PP_SENSOR_MEM_TEMP:
1044 ret = arcturus_thermal_get_temperature(smu, sensor,
1045 (uint32_t *)data);
1046 *size = 4;
1047 break;
1048 default:
1049 ret = smu_smc_read_sensor(smu, sensor, data, size);
1050 }
1051 mutex_unlock(&smu->sensor_lock);
1052
1053 return ret;
1054 }
1055
1056 static int arcturus_get_fan_speed_rpm(struct smu_context *smu,
1057 uint32_t *speed)
1058 {
1059 SmuMetrics_t metrics;
1060 int ret = 0;
1061
1062 if (!speed)
1063 return -EINVAL;
1064
1065 ret = arcturus_get_metrics_table(smu, &metrics);
1066 if (ret)
1067 return ret;
1068
1069 *speed = metrics.CurrFanSpeed;
1070
1071 return ret;
1072 }
1073
1074 static int arcturus_get_fan_speed_percent(struct smu_context *smu,
1075 uint32_t *speed)
1076 {
1077 PPTable_t *pptable = smu->smu_table.driver_pptable;
1078 uint32_t percent, current_rpm;
1079 int ret = 0;
1080
1081 if (!speed)
1082 return -EINVAL;
1083
1084 ret = arcturus_get_fan_speed_rpm(smu, ¤t_rpm);
1085 if (ret)
1086 return ret;
1087
1088 percent = current_rpm * 100 / pptable->FanMaximumRpm;
1089 *speed = percent > 100 ? 100 : percent;
1090
1091 return ret;
1092 }
1093
1094 static int arcturus_get_current_clk_freq_by_table(struct smu_context *smu,
1095 enum smu_clk_type clk_type,
1096 uint32_t *value)
1097 {
1098 static SmuMetrics_t metrics;
1099 int ret = 0, clk_id = 0;
1100
1101 if (!value)
1102 return -EINVAL;
1103
1104 clk_id = smu_clk_get_index(smu, clk_type);
1105 if (clk_id < 0)
1106 return -EINVAL;
1107
1108 ret = arcturus_get_metrics_table(smu, &metrics);
1109 if (ret)
1110 return ret;
1111
1112 switch (clk_id) {
1113 case PPCLK_GFXCLK:
1114
1115
1116
1117
1118
1119
1120 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT))
1121 *value = metrics.CurrClock[PPCLK_GFXCLK];
1122 else
1123 *value = metrics.AverageGfxclkFrequency;
1124 break;
1125 case PPCLK_UCLK:
1126 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT))
1127 *value = metrics.CurrClock[PPCLK_UCLK];
1128 else
1129 *value = metrics.AverageUclkFrequency;
1130 break;
1131 case PPCLK_SOCCLK:
1132 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT))
1133 *value = metrics.CurrClock[PPCLK_SOCCLK];
1134 else
1135 *value = metrics.AverageSocclkFrequency;
1136 break;
1137 default:
1138 *value = metrics.CurrClock[clk_id];
1139 break;
1140 }
1141
1142 return ret;
1143 }
1144
1145 static uint32_t arcturus_find_lowest_dpm_level(struct arcturus_single_dpm_table *table)
1146 {
1147 uint32_t i;
1148
1149 for (i = 0; i < table->count; i++) {
1150 if (table->dpm_levels[i].enabled)
1151 break;
1152 }
1153 if (i >= table->count) {
1154 i = 0;
1155 table->dpm_levels[i].enabled = true;
1156 }
1157
1158 return i;
1159 }
1160
1161 static uint32_t arcturus_find_highest_dpm_level(struct arcturus_single_dpm_table *table)
1162 {
1163 int i = 0;
1164
1165 if (table->count <= 0) {
1166 pr_err("[%s] DPM Table has no entry!", __func__);
1167 return 0;
1168 }
1169 if (table->count > MAX_DPM_NUMBER) {
1170 pr_err("[%s] DPM Table has too many entries!", __func__);
1171 return MAX_DPM_NUMBER - 1;
1172 }
1173
1174 for (i = table->count - 1; i >= 0; i--) {
1175 if (table->dpm_levels[i].enabled)
1176 break;
1177 }
1178 if (i < 0) {
1179 i = 0;
1180 table->dpm_levels[i].enabled = true;
1181 }
1182
1183 return i;
1184 }
1185
1186
1187
1188 static int arcturus_force_dpm_limit_value(struct smu_context *smu, bool highest)
1189 {
1190 struct arcturus_dpm_table *dpm_table =
1191 (struct arcturus_dpm_table *)smu->smu_dpm.dpm_context;
1192 uint32_t soft_level;
1193 int ret = 0;
1194
1195
1196 if (highest)
1197 soft_level = arcturus_find_highest_dpm_level(&(dpm_table->gfx_table));
1198 else
1199 soft_level = arcturus_find_lowest_dpm_level(&(dpm_table->gfx_table));
1200
1201 dpm_table->gfx_table.dpm_state.soft_min_level =
1202 dpm_table->gfx_table.dpm_state.soft_max_level =
1203 dpm_table->gfx_table.dpm_levels[soft_level].value;
1204
1205
1206 if (highest)
1207 soft_level = arcturus_find_highest_dpm_level(&(dpm_table->mem_table));
1208 else
1209 soft_level = arcturus_find_lowest_dpm_level(&(dpm_table->mem_table));
1210
1211 dpm_table->mem_table.dpm_state.soft_min_level =
1212 dpm_table->mem_table.dpm_state.soft_max_level =
1213 dpm_table->mem_table.dpm_levels[soft_level].value;
1214
1215
1216 if (highest)
1217 soft_level = arcturus_find_highest_dpm_level(&(dpm_table->soc_table));
1218 else
1219 soft_level = arcturus_find_lowest_dpm_level(&(dpm_table->soc_table));
1220
1221 dpm_table->soc_table.dpm_state.soft_min_level =
1222 dpm_table->soc_table.dpm_state.soft_max_level =
1223 dpm_table->soc_table.dpm_levels[soft_level].value;
1224
1225 ret = arcturus_upload_dpm_level(smu, false, 0xFFFFFFFF);
1226 if (ret) {
1227 pr_err("Failed to upload boot level to %s!\n",
1228 highest ? "highest" : "lowest");
1229 return ret;
1230 }
1231
1232 ret = arcturus_upload_dpm_level(smu, true, 0xFFFFFFFF);
1233 if (ret) {
1234 pr_err("Failed to upload dpm max level to %s!\n!",
1235 highest ? "highest" : "lowest");
1236 return ret;
1237 }
1238
1239 return ret;
1240 }
1241
1242 static int arcturus_unforce_dpm_levels(struct smu_context *smu)
1243 {
1244 struct arcturus_dpm_table *dpm_table =
1245 (struct arcturus_dpm_table *)smu->smu_dpm.dpm_context;
1246 uint32_t soft_min_level, soft_max_level;
1247 int ret = 0;
1248
1249
1250 soft_min_level = arcturus_find_lowest_dpm_level(&(dpm_table->gfx_table));
1251 soft_max_level = arcturus_find_highest_dpm_level(&(dpm_table->gfx_table));
1252 dpm_table->gfx_table.dpm_state.soft_min_level =
1253 dpm_table->gfx_table.dpm_levels[soft_min_level].value;
1254 dpm_table->gfx_table.dpm_state.soft_max_level =
1255 dpm_table->gfx_table.dpm_levels[soft_max_level].value;
1256
1257
1258 soft_min_level = arcturus_find_lowest_dpm_level(&(dpm_table->mem_table));
1259 soft_max_level = arcturus_find_highest_dpm_level(&(dpm_table->mem_table));
1260 dpm_table->mem_table.dpm_state.soft_min_level =
1261 dpm_table->gfx_table.dpm_levels[soft_min_level].value;
1262 dpm_table->mem_table.dpm_state.soft_max_level =
1263 dpm_table->gfx_table.dpm_levels[soft_max_level].value;
1264
1265
1266 soft_min_level = arcturus_find_lowest_dpm_level(&(dpm_table->soc_table));
1267 soft_max_level = arcturus_find_highest_dpm_level(&(dpm_table->soc_table));
1268 dpm_table->soc_table.dpm_state.soft_min_level =
1269 dpm_table->soc_table.dpm_levels[soft_min_level].value;
1270 dpm_table->soc_table.dpm_state.soft_max_level =
1271 dpm_table->soc_table.dpm_levels[soft_max_level].value;
1272
1273 ret = arcturus_upload_dpm_level(smu, false, 0xFFFFFFFF);
1274 if (ret) {
1275 pr_err("Failed to upload DPM Bootup Levels!");
1276 return ret;
1277 }
1278
1279 ret = arcturus_upload_dpm_level(smu, true, 0xFFFFFFFF);
1280 if (ret) {
1281 pr_err("Failed to upload DPM Max Levels!");
1282 return ret;
1283 }
1284
1285 return ret;
1286 }
1287
1288 static int
1289 arcturus_get_profiling_clk_mask(struct smu_context *smu,
1290 enum amd_dpm_forced_level level,
1291 uint32_t *sclk_mask,
1292 uint32_t *mclk_mask,
1293 uint32_t *soc_mask)
1294 {
1295 struct arcturus_dpm_table *dpm_table =
1296 (struct arcturus_dpm_table *)smu->smu_dpm.dpm_context;
1297 struct arcturus_single_dpm_table *gfx_dpm_table;
1298 struct arcturus_single_dpm_table *mem_dpm_table;
1299 struct arcturus_single_dpm_table *soc_dpm_table;
1300
1301 if (!smu->smu_dpm.dpm_context)
1302 return -EINVAL;
1303
1304 gfx_dpm_table = &dpm_table->gfx_table;
1305 mem_dpm_table = &dpm_table->mem_table;
1306 soc_dpm_table = &dpm_table->soc_table;
1307
1308 *sclk_mask = 0;
1309 *mclk_mask = 0;
1310 *soc_mask = 0;
1311
1312 if (gfx_dpm_table->count > ARCTURUS_UMD_PSTATE_GFXCLK_LEVEL &&
1313 mem_dpm_table->count > ARCTURUS_UMD_PSTATE_MCLK_LEVEL &&
1314 soc_dpm_table->count > ARCTURUS_UMD_PSTATE_SOCCLK_LEVEL) {
1315 *sclk_mask = ARCTURUS_UMD_PSTATE_GFXCLK_LEVEL;
1316 *mclk_mask = ARCTURUS_UMD_PSTATE_MCLK_LEVEL;
1317 *soc_mask = ARCTURUS_UMD_PSTATE_SOCCLK_LEVEL;
1318 }
1319
1320 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) {
1321 *sclk_mask = 0;
1322 } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) {
1323 *mclk_mask = 0;
1324 } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) {
1325 *sclk_mask = gfx_dpm_table->count - 1;
1326 *mclk_mask = mem_dpm_table->count - 1;
1327 *soc_mask = soc_dpm_table->count - 1;
1328 }
1329
1330 return 0;
1331 }
1332
1333 static int arcturus_get_power_limit(struct smu_context *smu,
1334 uint32_t *limit,
1335 bool asic_default)
1336 {
1337 PPTable_t *pptable = smu->smu_table.driver_pptable;
1338 uint32_t asic_default_power_limit = 0;
1339 int ret = 0;
1340 int power_src;
1341
1342 if (!smu->default_power_limit ||
1343 !smu->power_limit) {
1344 if (smu_feature_is_enabled(smu, SMU_FEATURE_PPT_BIT)) {
1345 power_src = smu_power_get_index(smu, SMU_POWER_SOURCE_AC);
1346 if (power_src < 0)
1347 return -EINVAL;
1348
1349 ret = smu_send_smc_msg_with_param(smu, SMU_MSG_GetPptLimit,
1350 power_src << 16);
1351 if (ret) {
1352 pr_err("[%s] get PPT limit failed!", __func__);
1353 return ret;
1354 }
1355 smu_read_smc_arg(smu, &asic_default_power_limit);
1356 } else {
1357
1358 if (!pptable) {
1359 pr_err("Cannot get PPT limit due to pptable missing!");
1360 return -EINVAL;
1361 }
1362 asic_default_power_limit =
1363 pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
1364 }
1365
1366 if (smu->od_enabled) {
1367 asic_default_power_limit *= (100 + smu->smu_table.TDPODLimit);
1368 asic_default_power_limit /= 100;
1369 }
1370
1371 smu->default_power_limit = asic_default_power_limit;
1372 smu->power_limit = asic_default_power_limit;
1373 }
1374
1375 if (asic_default)
1376 *limit = smu->default_power_limit;
1377 else
1378 *limit = smu->power_limit;
1379
1380 return 0;
1381 }
1382
1383 static int arcturus_get_power_profile_mode(struct smu_context *smu,
1384 char *buf)
1385 {
1386 static const char *profile_name[] = {
1387 "BOOTUP_DEFAULT",
1388 "3D_FULL_SCREEN",
1389 "POWER_SAVING",
1390 "VIDEO",
1391 "VR",
1392 "COMPUTE",
1393 "CUSTOM"};
1394 static const char *title[] = {
1395 "PROFILE_INDEX(NAME)"};
1396 uint32_t i, size = 0;
1397 int16_t workload_type = 0;
1398
1399 if (!smu->pm_enabled || !buf)
1400 return -EINVAL;
1401
1402 size += sprintf(buf + size, "%16s\n",
1403 title[0]);
1404
1405 for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
1406
1407
1408
1409
1410 workload_type = smu_workload_get_type(smu, i);
1411 if (workload_type < 0)
1412 continue;
1413
1414 size += sprintf(buf + size, "%2d %14s%s\n",
1415 i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " ");
1416 }
1417
1418 return size;
1419 }
1420
1421 static int arcturus_set_power_profile_mode(struct smu_context *smu,
1422 long *input,
1423 uint32_t size)
1424 {
1425 int workload_type = 0;
1426 uint32_t profile_mode = input[size];
1427 int ret = 0;
1428
1429 if (!smu->pm_enabled)
1430 return -EINVAL;
1431
1432 if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
1433 pr_err("Invalid power profile mode %d\n", profile_mode);
1434 return -EINVAL;
1435 }
1436
1437
1438
1439
1440
1441 workload_type = smu_workload_get_type(smu, profile_mode);
1442 if (workload_type < 0) {
1443 pr_err("Unsupported power profile mode %d on arcturus\n", profile_mode);
1444 return -EINVAL;
1445 }
1446
1447 ret = smu_send_smc_msg_with_param(smu,
1448 SMU_MSG_SetWorkloadMask,
1449 1 << workload_type);
1450 if (ret) {
1451 pr_err("Fail to set workload type %d\n", workload_type);
1452 return ret;
1453 }
1454
1455 smu->power_profile_mode = profile_mode;
1456
1457 return 0;
1458 }
1459
1460 static void arcturus_dump_pptable(struct smu_context *smu)
1461 {
1462 struct smu_table_context *table_context = &smu->smu_table;
1463 PPTable_t *pptable = table_context->driver_pptable;
1464 int i;
1465
1466 pr_info("Dumped PPTable:\n");
1467
1468 pr_info("Version = 0x%08x\n", pptable->Version);
1469
1470 pr_info("FeaturesToRun[0] = 0x%08x\n", pptable->FeaturesToRun[0]);
1471 pr_info("FeaturesToRun[1] = 0x%08x\n", pptable->FeaturesToRun[1]);
1472
1473 for (i = 0; i < PPT_THROTTLER_COUNT; i++) {
1474 pr_info("SocketPowerLimitAc[%d] = %d\n", i, pptable->SocketPowerLimitAc[i]);
1475 pr_info("SocketPowerLimitAcTau[%d] = %d\n", i, pptable->SocketPowerLimitAcTau[i]);
1476 }
1477
1478 pr_info("TdcLimitSoc = %d\n", pptable->TdcLimitSoc);
1479 pr_info("TdcLimitSocTau = %d\n", pptable->TdcLimitSocTau);
1480 pr_info("TdcLimitGfx = %d\n", pptable->TdcLimitGfx);
1481 pr_info("TdcLimitGfxTau = %d\n", pptable->TdcLimitGfxTau);
1482
1483 pr_info("TedgeLimit = %d\n", pptable->TedgeLimit);
1484 pr_info("ThotspotLimit = %d\n", pptable->ThotspotLimit);
1485 pr_info("TmemLimit = %d\n", pptable->TmemLimit);
1486 pr_info("Tvr_gfxLimit = %d\n", pptable->Tvr_gfxLimit);
1487 pr_info("Tvr_memLimit = %d\n", pptable->Tvr_memLimit);
1488 pr_info("Tvr_socLimit = %d\n", pptable->Tvr_socLimit);
1489 pr_info("FitLimit = %d\n", pptable->FitLimit);
1490
1491 pr_info("PpmPowerLimit = %d\n", pptable->PpmPowerLimit);
1492 pr_info("PpmTemperatureThreshold = %d\n", pptable->PpmTemperatureThreshold);
1493
1494 pr_info("ThrottlerControlMask = %d\n", pptable->ThrottlerControlMask);
1495
1496 pr_info("UlvVoltageOffsetGfx = %d\n", pptable->UlvVoltageOffsetGfx);
1497 pr_info("UlvPadding = 0x%08x\n", pptable->UlvPadding);
1498
1499 pr_info("UlvGfxclkBypass = %d\n", pptable->UlvGfxclkBypass);
1500 pr_info("Padding234[0] = 0x%02x\n", pptable->Padding234[0]);
1501 pr_info("Padding234[1] = 0x%02x\n", pptable->Padding234[1]);
1502 pr_info("Padding234[2] = 0x%02x\n", pptable->Padding234[2]);
1503
1504 pr_info("MinVoltageGfx = %d\n", pptable->MinVoltageGfx);
1505 pr_info("MinVoltageSoc = %d\n", pptable->MinVoltageSoc);
1506 pr_info("MaxVoltageGfx = %d\n", pptable->MaxVoltageGfx);
1507 pr_info("MaxVoltageSoc = %d\n", pptable->MaxVoltageSoc);
1508
1509 pr_info("LoadLineResistanceGfx = %d\n", pptable->LoadLineResistanceGfx);
1510 pr_info("LoadLineResistanceSoc = %d\n", pptable->LoadLineResistanceSoc);
1511
1512 pr_info("[PPCLK_GFXCLK]\n"
1513 " .VoltageMode = 0x%02x\n"
1514 " .SnapToDiscrete = 0x%02x\n"
1515 " .NumDiscreteLevels = 0x%02x\n"
1516 " .padding = 0x%02x\n"
1517 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1518 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1519 " .SsFmin = 0x%04x\n"
1520 " .Padding_16 = 0x%04x\n",
1521 pptable->DpmDescriptor[PPCLK_GFXCLK].VoltageMode,
1522 pptable->DpmDescriptor[PPCLK_GFXCLK].SnapToDiscrete,
1523 pptable->DpmDescriptor[PPCLK_GFXCLK].NumDiscreteLevels,
1524 pptable->DpmDescriptor[PPCLK_GFXCLK].padding,
1525 pptable->DpmDescriptor[PPCLK_GFXCLK].ConversionToAvfsClk.m,
1526 pptable->DpmDescriptor[PPCLK_GFXCLK].ConversionToAvfsClk.b,
1527 pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.a,
1528 pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.b,
1529 pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.c,
1530 pptable->DpmDescriptor[PPCLK_GFXCLK].SsFmin,
1531 pptable->DpmDescriptor[PPCLK_GFXCLK].Padding16);
1532
1533 pr_info("[PPCLK_VCLK]\n"
1534 " .VoltageMode = 0x%02x\n"
1535 " .SnapToDiscrete = 0x%02x\n"
1536 " .NumDiscreteLevels = 0x%02x\n"
1537 " .padding = 0x%02x\n"
1538 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1539 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1540 " .SsFmin = 0x%04x\n"
1541 " .Padding_16 = 0x%04x\n",
1542 pptable->DpmDescriptor[PPCLK_VCLK].VoltageMode,
1543 pptable->DpmDescriptor[PPCLK_VCLK].SnapToDiscrete,
1544 pptable->DpmDescriptor[PPCLK_VCLK].NumDiscreteLevels,
1545 pptable->DpmDescriptor[PPCLK_VCLK].padding,
1546 pptable->DpmDescriptor[PPCLK_VCLK].ConversionToAvfsClk.m,
1547 pptable->DpmDescriptor[PPCLK_VCLK].ConversionToAvfsClk.b,
1548 pptable->DpmDescriptor[PPCLK_VCLK].SsCurve.a,
1549 pptable->DpmDescriptor[PPCLK_VCLK].SsCurve.b,
1550 pptable->DpmDescriptor[PPCLK_VCLK].SsCurve.c,
1551 pptable->DpmDescriptor[PPCLK_VCLK].SsFmin,
1552 pptable->DpmDescriptor[PPCLK_VCLK].Padding16);
1553
1554 pr_info("[PPCLK_DCLK]\n"
1555 " .VoltageMode = 0x%02x\n"
1556 " .SnapToDiscrete = 0x%02x\n"
1557 " .NumDiscreteLevels = 0x%02x\n"
1558 " .padding = 0x%02x\n"
1559 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1560 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1561 " .SsFmin = 0x%04x\n"
1562 " .Padding_16 = 0x%04x\n",
1563 pptable->DpmDescriptor[PPCLK_DCLK].VoltageMode,
1564 pptable->DpmDescriptor[PPCLK_DCLK].SnapToDiscrete,
1565 pptable->DpmDescriptor[PPCLK_DCLK].NumDiscreteLevels,
1566 pptable->DpmDescriptor[PPCLK_DCLK].padding,
1567 pptable->DpmDescriptor[PPCLK_DCLK].ConversionToAvfsClk.m,
1568 pptable->DpmDescriptor[PPCLK_DCLK].ConversionToAvfsClk.b,
1569 pptable->DpmDescriptor[PPCLK_DCLK].SsCurve.a,
1570 pptable->DpmDescriptor[PPCLK_DCLK].SsCurve.b,
1571 pptable->DpmDescriptor[PPCLK_DCLK].SsCurve.c,
1572 pptable->DpmDescriptor[PPCLK_DCLK].SsFmin,
1573 pptable->DpmDescriptor[PPCLK_DCLK].Padding16);
1574
1575 pr_info("[PPCLK_SOCCLK]\n"
1576 " .VoltageMode = 0x%02x\n"
1577 " .SnapToDiscrete = 0x%02x\n"
1578 " .NumDiscreteLevels = 0x%02x\n"
1579 " .padding = 0x%02x\n"
1580 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1581 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1582 " .SsFmin = 0x%04x\n"
1583 " .Padding_16 = 0x%04x\n",
1584 pptable->DpmDescriptor[PPCLK_SOCCLK].VoltageMode,
1585 pptable->DpmDescriptor[PPCLK_SOCCLK].SnapToDiscrete,
1586 pptable->DpmDescriptor[PPCLK_SOCCLK].NumDiscreteLevels,
1587 pptable->DpmDescriptor[PPCLK_SOCCLK].padding,
1588 pptable->DpmDescriptor[PPCLK_SOCCLK].ConversionToAvfsClk.m,
1589 pptable->DpmDescriptor[PPCLK_SOCCLK].ConversionToAvfsClk.b,
1590 pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.a,
1591 pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.b,
1592 pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.c,
1593 pptable->DpmDescriptor[PPCLK_SOCCLK].SsFmin,
1594 pptable->DpmDescriptor[PPCLK_SOCCLK].Padding16);
1595
1596 pr_info("[PPCLK_UCLK]\n"
1597 " .VoltageMode = 0x%02x\n"
1598 " .SnapToDiscrete = 0x%02x\n"
1599 " .NumDiscreteLevels = 0x%02x\n"
1600 " .padding = 0x%02x\n"
1601 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1602 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1603 " .SsFmin = 0x%04x\n"
1604 " .Padding_16 = 0x%04x\n",
1605 pptable->DpmDescriptor[PPCLK_UCLK].VoltageMode,
1606 pptable->DpmDescriptor[PPCLK_UCLK].SnapToDiscrete,
1607 pptable->DpmDescriptor[PPCLK_UCLK].NumDiscreteLevels,
1608 pptable->DpmDescriptor[PPCLK_UCLK].padding,
1609 pptable->DpmDescriptor[PPCLK_UCLK].ConversionToAvfsClk.m,
1610 pptable->DpmDescriptor[PPCLK_UCLK].ConversionToAvfsClk.b,
1611 pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.a,
1612 pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.b,
1613 pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.c,
1614 pptable->DpmDescriptor[PPCLK_UCLK].SsFmin,
1615 pptable->DpmDescriptor[PPCLK_UCLK].Padding16);
1616
1617 pr_info("[PPCLK_FCLK]\n"
1618 " .VoltageMode = 0x%02x\n"
1619 " .SnapToDiscrete = 0x%02x\n"
1620 " .NumDiscreteLevels = 0x%02x\n"
1621 " .padding = 0x%02x\n"
1622 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1623 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1624 " .SsFmin = 0x%04x\n"
1625 " .Padding_16 = 0x%04x\n",
1626 pptable->DpmDescriptor[PPCLK_FCLK].VoltageMode,
1627 pptable->DpmDescriptor[PPCLK_FCLK].SnapToDiscrete,
1628 pptable->DpmDescriptor[PPCLK_FCLK].NumDiscreteLevels,
1629 pptable->DpmDescriptor[PPCLK_FCLK].padding,
1630 pptable->DpmDescriptor[PPCLK_FCLK].ConversionToAvfsClk.m,
1631 pptable->DpmDescriptor[PPCLK_FCLK].ConversionToAvfsClk.b,
1632 pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.a,
1633 pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.b,
1634 pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.c,
1635 pptable->DpmDescriptor[PPCLK_FCLK].SsFmin,
1636 pptable->DpmDescriptor[PPCLK_FCLK].Padding16);
1637
1638
1639 pr_info("FreqTableGfx\n");
1640 for (i = 0; i < NUM_GFXCLK_DPM_LEVELS; i++)
1641 pr_info(" .[%02d] = %d\n", i, pptable->FreqTableGfx[i]);
1642
1643 pr_info("FreqTableVclk\n");
1644 for (i = 0; i < NUM_VCLK_DPM_LEVELS; i++)
1645 pr_info(" .[%02d] = %d\n", i, pptable->FreqTableVclk[i]);
1646
1647 pr_info("FreqTableDclk\n");
1648 for (i = 0; i < NUM_DCLK_DPM_LEVELS; i++)
1649 pr_info(" .[%02d] = %d\n", i, pptable->FreqTableDclk[i]);
1650
1651 pr_info("FreqTableSocclk\n");
1652 for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++)
1653 pr_info(" .[%02d] = %d\n", i, pptable->FreqTableSocclk[i]);
1654
1655 pr_info("FreqTableUclk\n");
1656 for (i = 0; i < NUM_UCLK_DPM_LEVELS; i++)
1657 pr_info(" .[%02d] = %d\n", i, pptable->FreqTableUclk[i]);
1658
1659 pr_info("FreqTableFclk\n");
1660 for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++)
1661 pr_info(" .[%02d] = %d\n", i, pptable->FreqTableFclk[i]);
1662
1663 pr_info("Mp0clkFreq\n");
1664 for (i = 0; i < NUM_MP0CLK_DPM_LEVELS; i++)
1665 pr_info(" .[%d] = %d\n", i, pptable->Mp0clkFreq[i]);
1666
1667 pr_info("Mp0DpmVoltage\n");
1668 for (i = 0; i < NUM_MP0CLK_DPM_LEVELS; i++)
1669 pr_info(" .[%d] = %d\n", i, pptable->Mp0DpmVoltage[i]);
1670
1671 pr_info("GfxclkFidle = 0x%x\n", pptable->GfxclkFidle);
1672 pr_info("GfxclkSlewRate = 0x%x\n", pptable->GfxclkSlewRate);
1673 pr_info("Padding567[0] = 0x%x\n", pptable->Padding567[0]);
1674 pr_info("Padding567[1] = 0x%x\n", pptable->Padding567[1]);
1675 pr_info("Padding567[2] = 0x%x\n", pptable->Padding567[2]);
1676 pr_info("Padding567[3] = 0x%x\n", pptable->Padding567[3]);
1677 pr_info("GfxclkDsMaxFreq = %d\n", pptable->GfxclkDsMaxFreq);
1678 pr_info("GfxclkSource = 0x%x\n", pptable->GfxclkSource);
1679 pr_info("Padding456 = 0x%x\n", pptable->Padding456);
1680
1681 pr_info("EnableTdpm = %d\n", pptable->EnableTdpm);
1682 pr_info("TdpmHighHystTemperature = %d\n", pptable->TdpmHighHystTemperature);
1683 pr_info("TdpmLowHystTemperature = %d\n", pptable->TdpmLowHystTemperature);
1684 pr_info("GfxclkFreqHighTempLimit = %d\n", pptable->GfxclkFreqHighTempLimit);
1685
1686 pr_info("FanStopTemp = %d\n", pptable->FanStopTemp);
1687 pr_info("FanStartTemp = %d\n", pptable->FanStartTemp);
1688
1689 pr_info("FanGainEdge = %d\n", pptable->FanGainEdge);
1690 pr_info("FanGainHotspot = %d\n", pptable->FanGainHotspot);
1691 pr_info("FanGainVrGfx = %d\n", pptable->FanGainVrGfx);
1692 pr_info("FanGainVrSoc = %d\n", pptable->FanGainVrSoc);
1693 pr_info("FanGainVrMem = %d\n", pptable->FanGainVrMem);
1694 pr_info("FanGainHbm = %d\n", pptable->FanGainHbm);
1695
1696 pr_info("FanPwmMin = %d\n", pptable->FanPwmMin);
1697 pr_info("FanAcousticLimitRpm = %d\n", pptable->FanAcousticLimitRpm);
1698 pr_info("FanThrottlingRpm = %d\n", pptable->FanThrottlingRpm);
1699 pr_info("FanMaximumRpm = %d\n", pptable->FanMaximumRpm);
1700 pr_info("FanTargetTemperature = %d\n", pptable->FanTargetTemperature);
1701 pr_info("FanTargetGfxclk = %d\n", pptable->FanTargetGfxclk);
1702 pr_info("FanZeroRpmEnable = %d\n", pptable->FanZeroRpmEnable);
1703 pr_info("FanTachEdgePerRev = %d\n", pptable->FanTachEdgePerRev);
1704 pr_info("FanTempInputSelect = %d\n", pptable->FanTempInputSelect);
1705
1706 pr_info("FuzzyFan_ErrorSetDelta = %d\n", pptable->FuzzyFan_ErrorSetDelta);
1707 pr_info("FuzzyFan_ErrorRateSetDelta = %d\n", pptable->FuzzyFan_ErrorRateSetDelta);
1708 pr_info("FuzzyFan_PwmSetDelta = %d\n", pptable->FuzzyFan_PwmSetDelta);
1709 pr_info("FuzzyFan_Reserved = %d\n", pptable->FuzzyFan_Reserved);
1710
1711 pr_info("OverrideAvfsGb[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->OverrideAvfsGb[AVFS_VOLTAGE_GFX]);
1712 pr_info("OverrideAvfsGb[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->OverrideAvfsGb[AVFS_VOLTAGE_SOC]);
1713 pr_info("Padding8_Avfs[0] = %d\n", pptable->Padding8_Avfs[0]);
1714 pr_info("Padding8_Avfs[1] = %d\n", pptable->Padding8_Avfs[1]);
1715
1716 pr_info("dBtcGbGfxPll{a = 0x%x b = 0x%x c = 0x%x}\n",
1717 pptable->dBtcGbGfxPll.a,
1718 pptable->dBtcGbGfxPll.b,
1719 pptable->dBtcGbGfxPll.c);
1720 pr_info("dBtcGbGfxAfll{a = 0x%x b = 0x%x c = 0x%x}\n",
1721 pptable->dBtcGbGfxAfll.a,
1722 pptable->dBtcGbGfxAfll.b,
1723 pptable->dBtcGbGfxAfll.c);
1724 pr_info("dBtcGbSoc{a = 0x%x b = 0x%x c = 0x%x}\n",
1725 pptable->dBtcGbSoc.a,
1726 pptable->dBtcGbSoc.b,
1727 pptable->dBtcGbSoc.c);
1728
1729 pr_info("qAgingGb[AVFS_VOLTAGE_GFX]{m = 0x%x b = 0x%x}\n",
1730 pptable->qAgingGb[AVFS_VOLTAGE_GFX].m,
1731 pptable->qAgingGb[AVFS_VOLTAGE_GFX].b);
1732 pr_info("qAgingGb[AVFS_VOLTAGE_SOC]{m = 0x%x b = 0x%x}\n",
1733 pptable->qAgingGb[AVFS_VOLTAGE_SOC].m,
1734 pptable->qAgingGb[AVFS_VOLTAGE_SOC].b);
1735
1736 pr_info("qStaticVoltageOffset[AVFS_VOLTAGE_GFX]{a = 0x%x b = 0x%x c = 0x%x}\n",
1737 pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].a,
1738 pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].b,
1739 pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].c);
1740 pr_info("qStaticVoltageOffset[AVFS_VOLTAGE_SOC]{a = 0x%x b = 0x%x c = 0x%x}\n",
1741 pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].a,
1742 pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].b,
1743 pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].c);
1744
1745 pr_info("DcTol[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcTol[AVFS_VOLTAGE_GFX]);
1746 pr_info("DcTol[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcTol[AVFS_VOLTAGE_SOC]);
1747
1748 pr_info("DcBtcEnabled[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcEnabled[AVFS_VOLTAGE_GFX]);
1749 pr_info("DcBtcEnabled[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcEnabled[AVFS_VOLTAGE_SOC]);
1750 pr_info("Padding8_GfxBtc[0] = 0x%x\n", pptable->Padding8_GfxBtc[0]);
1751 pr_info("Padding8_GfxBtc[1] = 0x%x\n", pptable->Padding8_GfxBtc[1]);
1752
1753 pr_info("DcBtcMin[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcMin[AVFS_VOLTAGE_GFX]);
1754 pr_info("DcBtcMin[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcMin[AVFS_VOLTAGE_SOC]);
1755 pr_info("DcBtcMax[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcMax[AVFS_VOLTAGE_GFX]);
1756 pr_info("DcBtcMax[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcMax[AVFS_VOLTAGE_SOC]);
1757
1758 pr_info("DcBtcGb[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcGb[AVFS_VOLTAGE_GFX]);
1759 pr_info("DcBtcGb[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcGb[AVFS_VOLTAGE_SOC]);
1760
1761 pr_info("XgmiDpmPstates\n");
1762 for (i = 0; i < NUM_XGMI_LEVELS; i++)
1763 pr_info(" .[%d] = %d\n", i, pptable->XgmiDpmPstates[i]);
1764 pr_info("XgmiDpmSpare[0] = 0x%02x\n", pptable->XgmiDpmSpare[0]);
1765 pr_info("XgmiDpmSpare[1] = 0x%02x\n", pptable->XgmiDpmSpare[1]);
1766
1767 pr_info("VDDGFX_TVmin = %d\n", pptable->VDDGFX_TVmin);
1768 pr_info("VDDSOC_TVmin = %d\n", pptable->VDDSOC_TVmin);
1769 pr_info("VDDGFX_Vmin_HiTemp = %d\n", pptable->VDDGFX_Vmin_HiTemp);
1770 pr_info("VDDGFX_Vmin_LoTemp = %d\n", pptable->VDDGFX_Vmin_LoTemp);
1771 pr_info("VDDSOC_Vmin_HiTemp = %d\n", pptable->VDDSOC_Vmin_HiTemp);
1772 pr_info("VDDSOC_Vmin_LoTemp = %d\n", pptable->VDDSOC_Vmin_LoTemp);
1773 pr_info("VDDGFX_TVminHystersis = %d\n", pptable->VDDGFX_TVminHystersis);
1774 pr_info("VDDSOC_TVminHystersis = %d\n", pptable->VDDSOC_TVminHystersis);
1775
1776 pr_info("DebugOverrides = 0x%x\n", pptable->DebugOverrides);
1777 pr_info("ReservedEquation0{a = 0x%x b = 0x%x c = 0x%x}\n",
1778 pptable->ReservedEquation0.a,
1779 pptable->ReservedEquation0.b,
1780 pptable->ReservedEquation0.c);
1781 pr_info("ReservedEquation1{a = 0x%x b = 0x%x c = 0x%x}\n",
1782 pptable->ReservedEquation1.a,
1783 pptable->ReservedEquation1.b,
1784 pptable->ReservedEquation1.c);
1785 pr_info("ReservedEquation2{a = 0x%x b = 0x%x c = 0x%x}\n",
1786 pptable->ReservedEquation2.a,
1787 pptable->ReservedEquation2.b,
1788 pptable->ReservedEquation2.c);
1789 pr_info("ReservedEquation3{a = 0x%x b = 0x%x c = 0x%x}\n",
1790 pptable->ReservedEquation3.a,
1791 pptable->ReservedEquation3.b,
1792 pptable->ReservedEquation3.c);
1793
1794 pr_info("MinVoltageUlvGfx = %d\n", pptable->MinVoltageUlvGfx);
1795 pr_info("PaddingUlv = %d\n", pptable->PaddingUlv);
1796
1797 pr_info("TotalPowerConfig = %d\n", pptable->TotalPowerConfig);
1798 pr_info("TotalPowerSpare1 = %d\n", pptable->TotalPowerSpare1);
1799 pr_info("TotalPowerSpare2 = %d\n", pptable->TotalPowerSpare2);
1800
1801 pr_info("PccThresholdLow = %d\n", pptable->PccThresholdLow);
1802 pr_info("PccThresholdHigh = %d\n", pptable->PccThresholdHigh);
1803
1804 pr_info("Board Parameters:\n");
1805 pr_info("MaxVoltageStepGfx = 0x%x\n", pptable->MaxVoltageStepGfx);
1806 pr_info("MaxVoltageStepSoc = 0x%x\n", pptable->MaxVoltageStepSoc);
1807
1808 pr_info("VddGfxVrMapping = 0x%x\n", pptable->VddGfxVrMapping);
1809 pr_info("VddSocVrMapping = 0x%x\n", pptable->VddSocVrMapping);
1810 pr_info("VddMemVrMapping = 0x%x\n", pptable->VddMemVrMapping);
1811 pr_info("BoardVrMapping = 0x%x\n", pptable->BoardVrMapping);
1812
1813 pr_info("GfxUlvPhaseSheddingMask = 0x%x\n", pptable->GfxUlvPhaseSheddingMask);
1814 pr_info("ExternalSensorPresent = 0x%x\n", pptable->ExternalSensorPresent);
1815
1816 pr_info("GfxMaxCurrent = 0x%x\n", pptable->GfxMaxCurrent);
1817 pr_info("GfxOffset = 0x%x\n", pptable->GfxOffset);
1818 pr_info("Padding_TelemetryGfx = 0x%x\n", pptable->Padding_TelemetryGfx);
1819
1820 pr_info("SocMaxCurrent = 0x%x\n", pptable->SocMaxCurrent);
1821 pr_info("SocOffset = 0x%x\n", pptable->SocOffset);
1822 pr_info("Padding_TelemetrySoc = 0x%x\n", pptable->Padding_TelemetrySoc);
1823
1824 pr_info("MemMaxCurrent = 0x%x\n", pptable->MemMaxCurrent);
1825 pr_info("MemOffset = 0x%x\n", pptable->MemOffset);
1826 pr_info("Padding_TelemetryMem = 0x%x\n", pptable->Padding_TelemetryMem);
1827
1828 pr_info("BoardMaxCurrent = 0x%x\n", pptable->BoardMaxCurrent);
1829 pr_info("BoardOffset = 0x%x\n", pptable->BoardOffset);
1830 pr_info("Padding_TelemetryBoardInput = 0x%x\n", pptable->Padding_TelemetryBoardInput);
1831
1832 pr_info("VR0HotGpio = %d\n", pptable->VR0HotGpio);
1833 pr_info("VR0HotPolarity = %d\n", pptable->VR0HotPolarity);
1834 pr_info("VR1HotGpio = %d\n", pptable->VR1HotGpio);
1835 pr_info("VR1HotPolarity = %d\n", pptable->VR1HotPolarity);
1836
1837 pr_info("PllGfxclkSpreadEnabled = %d\n", pptable->PllGfxclkSpreadEnabled);
1838 pr_info("PllGfxclkSpreadPercent = %d\n", pptable->PllGfxclkSpreadPercent);
1839 pr_info("PllGfxclkSpreadFreq = %d\n", pptable->PllGfxclkSpreadFreq);
1840
1841 pr_info("UclkSpreadEnabled = %d\n", pptable->UclkSpreadEnabled);
1842 pr_info("UclkSpreadPercent = %d\n", pptable->UclkSpreadPercent);
1843 pr_info("UclkSpreadFreq = %d\n", pptable->UclkSpreadFreq);
1844
1845 pr_info("FclkSpreadEnabled = %d\n", pptable->FclkSpreadEnabled);
1846 pr_info("FclkSpreadPercent = %d\n", pptable->FclkSpreadPercent);
1847 pr_info("FclkSpreadFreq = %d\n", pptable->FclkSpreadFreq);
1848
1849 pr_info("FllGfxclkSpreadEnabled = %d\n", pptable->FllGfxclkSpreadEnabled);
1850 pr_info("FllGfxclkSpreadPercent = %d\n", pptable->FllGfxclkSpreadPercent);
1851 pr_info("FllGfxclkSpreadFreq = %d\n", pptable->FllGfxclkSpreadFreq);
1852
1853 for (i = 0; i < NUM_I2C_CONTROLLERS; i++) {
1854 pr_info("I2cControllers[%d]:\n", i);
1855 pr_info(" .Enabled = %d\n",
1856 pptable->I2cControllers[i].Enabled);
1857 pr_info(" .SlaveAddress = 0x%x\n",
1858 pptable->I2cControllers[i].SlaveAddress);
1859 pr_info(" .ControllerPort = %d\n",
1860 pptable->I2cControllers[i].ControllerPort);
1861 pr_info(" .ControllerName = %d\n",
1862 pptable->I2cControllers[i].ControllerName);
1863 pr_info(" .ThermalThrottler = %d\n",
1864 pptable->I2cControllers[i].ThermalThrotter);
1865 pr_info(" .I2cProtocol = %d\n",
1866 pptable->I2cControllers[i].I2cProtocol);
1867 pr_info(" .Speed = %d\n",
1868 pptable->I2cControllers[i].Speed);
1869 }
1870
1871 pr_info("MemoryChannelEnabled = %d\n", pptable->MemoryChannelEnabled);
1872 pr_info("DramBitWidth = %d\n", pptable->DramBitWidth);
1873
1874 pr_info("TotalBoardPower = %d\n", pptable->TotalBoardPower);
1875
1876 pr_info("XgmiLinkSpeed\n");
1877 for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
1878 pr_info(" .[%d] = %d\n", i, pptable->XgmiLinkSpeed[i]);
1879 pr_info("XgmiLinkWidth\n");
1880 for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
1881 pr_info(" .[%d] = %d\n", i, pptable->XgmiLinkWidth[i]);
1882 pr_info("XgmiFclkFreq\n");
1883 for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
1884 pr_info(" .[%d] = %d\n", i, pptable->XgmiFclkFreq[i]);
1885 pr_info("XgmiSocVoltage\n");
1886 for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
1887 pr_info(" .[%d] = %d\n", i, pptable->XgmiSocVoltage[i]);
1888
1889 }
1890
1891 static bool arcturus_is_dpm_running(struct smu_context *smu)
1892 {
1893 int ret = 0;
1894 uint32_t feature_mask[2];
1895 unsigned long feature_enabled;
1896 ret = smu_feature_get_enabled_mask(smu, feature_mask, 2);
1897 feature_enabled = (unsigned long)((uint64_t)feature_mask[0] |
1898 ((uint64_t)feature_mask[1] << 32));
1899 return !!(feature_enabled & SMC_DPM_FEATURE);
1900 }
1901
1902 static const struct pptable_funcs arcturus_ppt_funcs = {
1903
1904 .get_smu_msg_index = arcturus_get_smu_msg_index,
1905 .get_smu_clk_index = arcturus_get_smu_clk_index,
1906 .get_smu_feature_index = arcturus_get_smu_feature_index,
1907 .get_smu_table_index = arcturus_get_smu_table_index,
1908 .get_smu_power_index= arcturus_get_pwr_src_index,
1909 .get_workload_type = arcturus_get_workload_type,
1910
1911 .tables_init = arcturus_tables_init,
1912 .alloc_dpm_context = arcturus_allocate_dpm_context,
1913
1914 .check_powerplay_table = arcturus_check_powerplay_table,
1915 .store_powerplay_table = arcturus_store_powerplay_table,
1916 .append_powerplay_table = arcturus_append_powerplay_table,
1917
1918 .get_allowed_feature_mask = arcturus_get_allowed_feature_mask,
1919
1920 .run_afll_btc = arcturus_run_btc_afll,
1921
1922 .set_default_dpm_table = arcturus_set_default_dpm_table,
1923 .populate_umd_state_clk = arcturus_populate_umd_state_clk,
1924 .get_thermal_temperature_range = arcturus_get_thermal_temperature_range,
1925 .get_current_clk_freq_by_table = arcturus_get_current_clk_freq_by_table,
1926 .print_clk_levels = arcturus_print_clk_levels,
1927 .force_clk_levels = arcturus_force_clk_levels,
1928 .read_sensor = arcturus_read_sensor,
1929 .get_fan_speed_percent = arcturus_get_fan_speed_percent,
1930 .get_fan_speed_rpm = arcturus_get_fan_speed_rpm,
1931 .force_dpm_limit_value = arcturus_force_dpm_limit_value,
1932 .unforce_dpm_levels = arcturus_unforce_dpm_levels,
1933 .get_profiling_clk_mask = arcturus_get_profiling_clk_mask,
1934 .get_power_profile_mode = arcturus_get_power_profile_mode,
1935 .set_power_profile_mode = arcturus_set_power_profile_mode,
1936
1937 .dump_pptable = arcturus_dump_pptable,
1938 .get_power_limit = arcturus_get_power_limit,
1939 .is_dpm_running = arcturus_is_dpm_running,
1940 };
1941
1942 void arcturus_set_ppt_funcs(struct smu_context *smu)
1943 {
1944 struct smu_table_context *smu_table = &smu->smu_table;
1945
1946 smu->ppt_funcs = &arcturus_ppt_funcs;
1947 smu_table->table_count = TABLE_COUNT;
1948 }