1 /*
2 * Copyright 2023 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24 #include "smu_types.h"
25 #define SWSMU_CODE_LAYER_L2
26
27 #include "amdgpu.h"
28 #include "amdgpu_smu.h"
29 #include "smu_v14_0.h"
30 #include "smu14_driver_if_v14_0_0.h"
31 #include "smu_v14_0_0_ppt.h"
32 #include "smu_v14_0_0_ppsmc.h"
33 #include "smu_v14_0_0_pmfw.h"
34 #include "smu_cmn.h"
35
36 /*
37 * DO NOT use these for err/warn/info/debug messages.
38 * Use dev_err, dev_warn, dev_info and dev_dbg instead.
39 * They are more MGPU friendly.
40 */
41 #undef pr_err
42 #undef pr_warn
43 #undef pr_info
44 #undef pr_debug
45
46 #define mmMP1_SMN_C2PMSG_66 0x0282
47 #define mmMP1_SMN_C2PMSG_66_BASE_IDX 0
48
49 #define mmMP1_SMN_C2PMSG_82 0x0292
50 #define mmMP1_SMN_C2PMSG_82_BASE_IDX 0
51
52 #define mmMP1_SMN_C2PMSG_90 0x029a
53 #define mmMP1_SMN_C2PMSG_90_BASE_IDX 0
54
55 /* MALLPowerController message arguments (Defines for the Cache mode control) */
56 #define SMU_MALL_PMFW_CONTROL 0
57 #define SMU_MALL_DRIVER_CONTROL 1
58
59 /*
60 * MALLPowerState message arguments
61 * (Defines for the Allocate/Release Cache mode if in driver mode)
62 */
63 #define SMU_MALL_EXIT_PG 0
64 #define SMU_MALL_ENTER_PG 1
65
66 #define SMU_MALL_PG_CONFIG_DEFAULT SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_ON
67
68 #define SMU14_DRIVER_IF_VERSION_SMU_V14_0_0 0x7
69 #define SMU14_DRIVER_IF_VERSION_SMU_V14_0_1 0x6
70
71 #define SMU_14_0_0_UMD_PSTATE_GFXCLK 700
72 #define SMU_14_0_0_UMD_PSTATE_SOCCLK 678
73 #define SMU_14_0_0_UMD_PSTATE_FCLK 1800
74
75 #define SMU_14_0_4_UMD_PSTATE_GFXCLK 938
76 #define SMU_14_0_4_UMD_PSTATE_SOCCLK 938
77
78 static const struct smu_feature_bits smu_v14_0_0_dpm_features = {
79 .bits = {
80 SMU_FEATURE_BIT_INIT(FEATURE_CCLK_DPM_BIT),
81 SMU_FEATURE_BIT_INIT(FEATURE_VCN_DPM_BIT),
82 SMU_FEATURE_BIT_INIT(FEATURE_FCLK_DPM_BIT),
83 SMU_FEATURE_BIT_INIT(FEATURE_SOCCLK_DPM_BIT),
84 SMU_FEATURE_BIT_INIT(FEATURE_LCLK_DPM_BIT),
85 SMU_FEATURE_BIT_INIT(FEATURE_SHUBCLK_DPM_BIT),
86 SMU_FEATURE_BIT_INIT(FEATURE_DCFCLK_DPM_BIT),
87 SMU_FEATURE_BIT_INIT(FEATURE_ISP_DPM_BIT),
88 SMU_FEATURE_BIT_INIT(FEATURE_IPU_DPM_BIT),
89 SMU_FEATURE_BIT_INIT(FEATURE_GFX_DPM_BIT),
90 SMU_FEATURE_BIT_INIT(FEATURE_VPE_DPM_BIT)
91 }
92 };
93
94 enum smu_mall_pg_config {
95 SMU_MALL_PG_CONFIG_PMFW_CONTROL = 0,
96 SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_ON = 1,
97 SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_OFF = 2,
98 };
99
100 static struct cmn2asic_msg_mapping smu_v14_0_0_message_map[SMU_MSG_MAX_COUNT] = {
101 MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1),
102 MSG_MAP(GetSmuVersion, PPSMC_MSG_GetPmfwVersion, 1),
103 MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 1),
104 MSG_MAP(PowerDownVcn0, PPSMC_MSG_PowerDownVcn0, 1),
105 MSG_MAP(PowerUpVcn0, PPSMC_MSG_PowerUpVcn0, 1),
106 MSG_MAP(SetHardMinVcn0, PPSMC_MSG_SetHardMinVcn0, 1),
107 MSG_MAP(PowerDownVcn1, PPSMC_MSG_PowerDownVcn1, 1),
108 MSG_MAP(PowerUpVcn1, PPSMC_MSG_PowerUpVcn1, 1),
109 MSG_MAP(SetHardMinVcn1, PPSMC_MSG_SetHardMinVcn1, 1),
110 MSG_MAP(SetSoftMinGfxclk, PPSMC_MSG_SetSoftMinGfxclk, 1),
111 MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 1),
112 MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 1),
113 MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 1),
114 MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 1),
115 MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 1),
116 MSG_MAP(GfxDeviceDriverReset, PPSMC_MSG_GfxDeviceDriverReset, 1),
117 MSG_MAP(GetEnabledSmuFeatures, PPSMC_MSG_GetEnabledSmuFeatures, 1),
118 MSG_MAP(SetHardMinSocclkByFreq, PPSMC_MSG_SetHardMinSocclkByFreq, 1),
119 MSG_MAP(SetSoftMinFclk, PPSMC_MSG_SetSoftMinFclk, 1),
120 MSG_MAP(SetSoftMinVcn0, PPSMC_MSG_SetSoftMinVcn0, 1),
121 MSG_MAP(SetSoftMinVcn1, PPSMC_MSG_SetSoftMinVcn1, 1),
122 MSG_MAP(EnableGfxImu, PPSMC_MSG_EnableGfxImu, 1),
123 MSG_MAP(AllowGfxOff, PPSMC_MSG_AllowGfxOff, 1),
124 MSG_MAP(DisallowGfxOff, PPSMC_MSG_DisallowGfxOff, 1),
125 MSG_MAP(SetSoftMaxGfxClk, PPSMC_MSG_SetSoftMaxGfxClk, 1),
126 MSG_MAP(SetHardMinGfxClk, PPSMC_MSG_SetHardMinGfxClk, 1),
127 MSG_MAP(SetSoftMaxSocclkByFreq, PPSMC_MSG_SetSoftMaxSocclkByFreq, 1),
128 MSG_MAP(SetSoftMaxFclkByFreq, PPSMC_MSG_SetSoftMaxFclkByFreq, 1),
129 MSG_MAP(SetSoftMaxVcn0, PPSMC_MSG_SetSoftMaxVcn0, 1),
130 MSG_MAP(SetSoftMaxVcn1, PPSMC_MSG_SetSoftMaxVcn1, 1),
131 MSG_MAP(PowerDownJpeg0, PPSMC_MSG_PowerDownJpeg0, 1),
132 MSG_MAP(PowerUpJpeg0, PPSMC_MSG_PowerUpJpeg0, 1),
133 MSG_MAP(PowerDownJpeg1, PPSMC_MSG_PowerDownJpeg1, 1),
134 MSG_MAP(PowerUpJpeg1, PPSMC_MSG_PowerUpJpeg1, 1),
135 MSG_MAP(SetHardMinFclkByFreq, PPSMC_MSG_SetHardMinFclkByFreq, 1),
136 MSG_MAP(SetSoftMinSocclkByFreq, PPSMC_MSG_SetSoftMinSocclkByFreq, 1),
137 MSG_MAP(PowerDownIspByTile, PPSMC_MSG_PowerDownIspByTile, 1),
138 MSG_MAP(PowerUpIspByTile, PPSMC_MSG_PowerUpIspByTile, 1),
139 MSG_MAP(SetHardMinIspiclkByFreq, PPSMC_MSG_SetHardMinIspiclkByFreq, 1),
140 MSG_MAP(SetHardMinIspxclkByFreq, PPSMC_MSG_SetHardMinIspxclkByFreq, 1),
141 MSG_MAP(PowerUpVpe, PPSMC_MSG_PowerUpVpe, 1),
142 MSG_MAP(PowerDownVpe, PPSMC_MSG_PowerDownVpe, 1),
143 MSG_MAP(PowerUpUmsch, PPSMC_MSG_PowerUpUmsch, 1),
144 MSG_MAP(PowerDownUmsch, PPSMC_MSG_PowerDownUmsch, 1),
145 MSG_MAP(SetSoftMaxVpe, PPSMC_MSG_SetSoftMaxVpe, 1),
146 MSG_MAP(SetSoftMinVpe, PPSMC_MSG_SetSoftMinVpe, 1),
147 MSG_MAP(MALLPowerController, PPSMC_MSG_MALLPowerController, 1),
148 MSG_MAP(MALLPowerState, PPSMC_MSG_MALLPowerState, 1),
149 };
150
151 static struct cmn2asic_mapping smu_v14_0_0_feature_mask_map[SMU_FEATURE_COUNT] = {
152 FEA_MAP(CCLK_DPM),
153 FEA_MAP(FAN_CONTROLLER),
154 FEA_MAP(PPT),
155 FEA_MAP(TDC),
156 FEA_MAP(THERMAL),
157 FEA_MAP(VCN_DPM),
158 FEA_MAP_REVERSE(FCLK),
159 FEA_MAP_REVERSE(SOCCLK),
160 FEA_MAP(LCLK_DPM),
161 FEA_MAP(SHUBCLK_DPM),
162 FEA_MAP(DCFCLK_DPM),
163 FEA_MAP_HALF_REVERSE(GFX),
164 FEA_MAP(DS_GFXCLK),
165 FEA_MAP(DS_SOCCLK),
166 FEA_MAP(DS_LCLK),
167 FEA_MAP(LOW_POWER_DCNCLKS),
168 FEA_MAP(DS_FCLK),
169 FEA_MAP(DS_MP1CLK),
170 FEA_MAP(PSI),
171 FEA_MAP(PROCHOT),
172 FEA_MAP(CPUOFF),
173 FEA_MAP(STAPM),
174 FEA_MAP(S0I3),
175 FEA_MAP(PERF_LIMIT),
176 FEA_MAP(CORE_DLDO),
177 FEA_MAP(DS_VCN),
178 FEA_MAP(CPPC),
179 FEA_MAP(DF_CSTATES),
180 FEA_MAP(ATHUB_PG),
181 };
182
183 static struct cmn2asic_mapping smu_v14_0_0_table_map[SMU_TABLE_COUNT] = {
184 TAB_MAP_VALID(WATERMARKS),
185 TAB_MAP_VALID(SMU_METRICS),
186 TAB_MAP_VALID(CUSTOM_DPM),
187 TAB_MAP_VALID(DPMCLOCKS),
188 };
189
smu_v14_0_0_init_smc_tables(struct smu_context * smu)190 static int smu_v14_0_0_init_smc_tables(struct smu_context *smu)
191 {
192 struct smu_table_context *smu_table = &smu->smu_table;
193 struct smu_table *tables = smu_table->tables;
194 int ret;
195
196 SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
197 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
198 SMU_TABLE_INIT(tables, SMU_TABLE_DPMCLOCKS, max(sizeof(DpmClocks_t), sizeof(DpmClocks_t_v14_0_1)),
199 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
200 SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
201 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
202
203 smu_table->metrics_table = kzalloc_obj(SmuMetrics_t);
204 if (!smu_table->metrics_table)
205 goto err0_out;
206 smu_table->metrics_time = 0;
207
208 smu_table->clocks_table = kzalloc(max(sizeof(DpmClocks_t), sizeof(DpmClocks_t_v14_0_1)), GFP_KERNEL);
209 if (!smu_table->clocks_table)
210 goto err1_out;
211
212 smu_table->watermarks_table = kzalloc_obj(Watermarks_t);
213 if (!smu_table->watermarks_table)
214 goto err2_out;
215
216 ret = smu_driver_table_init(smu, SMU_DRIVER_TABLE_GPU_METRICS,
217 sizeof(struct gpu_metrics_v3_0),
218 SMU_GPU_METRICS_CACHE_INTERVAL);
219 if (ret)
220 goto err3_out;
221
222 return 0;
223
224 err3_out:
225 kfree(smu_table->watermarks_table);
226 err2_out:
227 kfree(smu_table->clocks_table);
228 err1_out:
229 kfree(smu_table->metrics_table);
230 err0_out:
231 return -ENOMEM;
232 }
233
smu_v14_0_0_fini_smc_tables(struct smu_context * smu)234 static int smu_v14_0_0_fini_smc_tables(struct smu_context *smu)
235 {
236 struct smu_table_context *smu_table = &smu->smu_table;
237
238 kfree(smu_table->clocks_table);
239 smu_table->clocks_table = NULL;
240
241 kfree(smu_table->metrics_table);
242 smu_table->metrics_table = NULL;
243
244 kfree(smu_table->watermarks_table);
245 smu_table->watermarks_table = NULL;
246
247 smu_driver_table_fini(smu, SMU_DRIVER_TABLE_GPU_METRICS);
248
249 return 0;
250 }
251
smu_v14_0_0_system_features_control(struct smu_context * smu,bool en)252 static int smu_v14_0_0_system_features_control(struct smu_context *smu, bool en)
253 {
254 struct amdgpu_device *adev = smu->adev;
255 int ret = 0;
256
257 if (!en && !adev->in_s0ix)
258 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL);
259
260 return ret;
261 }
262
smu_v14_0_0_get_smu_metrics_data(struct smu_context * smu,MetricsMember_t member,uint32_t * value)263 static int smu_v14_0_0_get_smu_metrics_data(struct smu_context *smu,
264 MetricsMember_t member,
265 uint32_t *value)
266 {
267 struct smu_table_context *smu_table = &smu->smu_table;
268
269 SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table;
270 int ret = 0;
271
272 ret = smu_cmn_get_metrics_table(smu, NULL, false);
273 if (ret)
274 return ret;
275
276 switch (member) {
277 case METRICS_AVERAGE_GFXCLK:
278 *value = metrics->GfxclkFrequency;
279 break;
280 case METRICS_AVERAGE_SOCCLK:
281 *value = metrics->SocclkFrequency;
282 break;
283 case METRICS_AVERAGE_VCLK:
284 *value = metrics->VclkFrequency;
285 break;
286 case METRICS_AVERAGE_DCLK:
287 *value = 0;
288 break;
289 case METRICS_AVERAGE_UCLK:
290 *value = metrics->MemclkFrequency;
291 break;
292 case METRICS_AVERAGE_FCLK:
293 *value = metrics->FclkFrequency;
294 break;
295 case METRICS_AVERAGE_VPECLK:
296 *value = metrics->VpeclkFrequency;
297 break;
298 case METRICS_AVERAGE_IPUCLK:
299 *value = metrics->IpuclkFrequency;
300 break;
301 case METRICS_AVERAGE_MPIPUCLK:
302 *value = metrics->MpipuclkFrequency;
303 break;
304 case METRICS_AVERAGE_GFXACTIVITY:
305 if ((smu->smc_fw_version > 0x5d4600))
306 *value = metrics->GfxActivity;
307 else
308 *value = metrics->GfxActivity / 100;
309 break;
310 case METRICS_AVERAGE_VCNACTIVITY:
311 *value = metrics->VcnActivity / 100;
312 break;
313 case METRICS_AVERAGE_SOCKETPOWER:
314 case METRICS_CURR_SOCKETPOWER:
315 *value = metrics->SocketPower;
316 break;
317 case METRICS_TEMPERATURE_EDGE:
318 *value = metrics->GfxTemperature / 100 *
319 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
320 break;
321 case METRICS_TEMPERATURE_HOTSPOT:
322 *value = metrics->SocTemperature / 100 *
323 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
324 break;
325 case METRICS_THROTTLER_RESIDENCY_PROCHOT:
326 *value = metrics->ThrottleResidency_PROCHOT;
327 break;
328 case METRICS_THROTTLER_RESIDENCY_SPL:
329 *value = metrics->ThrottleResidency_SPL;
330 break;
331 case METRICS_THROTTLER_RESIDENCY_FPPT:
332 *value = metrics->ThrottleResidency_FPPT;
333 break;
334 case METRICS_THROTTLER_RESIDENCY_SPPT:
335 *value = metrics->ThrottleResidency_SPPT;
336 break;
337 case METRICS_THROTTLER_RESIDENCY_THM_CORE:
338 *value = metrics->ThrottleResidency_THM_CORE;
339 break;
340 case METRICS_THROTTLER_RESIDENCY_THM_GFX:
341 *value = metrics->ThrottleResidency_THM_GFX;
342 break;
343 case METRICS_THROTTLER_RESIDENCY_THM_SOC:
344 *value = metrics->ThrottleResidency_THM_SOC;
345 break;
346 case METRICS_VOLTAGE_VDDGFX:
347 *value = 0;
348 break;
349 case METRICS_VOLTAGE_VDDSOC:
350 *value = 0;
351 break;
352 case METRICS_SS_APU_SHARE:
353 /* return the percentage of APU power with respect to APU's power limit.
354 * percentage is reported, this isn't boost value. Smartshift power
355 * boost/shift is only when the percentage is more than 100.
356 */
357 if (metrics->StapmOpnLimit > 0)
358 *value = (metrics->ApuPower * 100) / metrics->StapmOpnLimit;
359 else
360 *value = 0;
361 break;
362 case METRICS_SS_DGPU_SHARE:
363 /* return the percentage of dGPU power with respect to dGPU's power limit.
364 * percentage is reported, this isn't boost value. Smartshift power
365 * boost/shift is only when the percentage is more than 100.
366 */
367 if ((metrics->dGpuPower > 0) &&
368 (metrics->StapmCurrentLimit > metrics->StapmOpnLimit))
369 *value = (metrics->dGpuPower * 100) /
370 (metrics->StapmCurrentLimit - metrics->StapmOpnLimit);
371 else
372 *value = 0;
373 break;
374 default:
375 *value = UINT_MAX;
376 break;
377 }
378
379 return ret;
380 }
381
smu_v14_0_0_read_sensor(struct smu_context * smu,enum amd_pp_sensors sensor,void * data,uint32_t * size)382 static int smu_v14_0_0_read_sensor(struct smu_context *smu,
383 enum amd_pp_sensors sensor,
384 void *data, uint32_t *size)
385 {
386 int ret = 0;
387
388 if (!data || !size)
389 return -EINVAL;
390
391 switch (sensor) {
392 case AMDGPU_PP_SENSOR_GPU_LOAD:
393 ret = smu_v14_0_0_get_smu_metrics_data(smu,
394 METRICS_AVERAGE_GFXACTIVITY,
395 (uint32_t *)data);
396 *size = 4;
397 break;
398 case AMDGPU_PP_SENSOR_VCN_LOAD:
399 ret = smu_v14_0_0_get_smu_metrics_data(smu,
400 METRICS_AVERAGE_VCNACTIVITY,
401 (uint32_t *)data);
402 *size = 4;
403 break;
404 case AMDGPU_PP_SENSOR_GPU_AVG_POWER:
405 ret = smu_v14_0_0_get_smu_metrics_data(smu,
406 METRICS_AVERAGE_SOCKETPOWER,
407 (uint32_t *)data);
408 *size = 4;
409 break;
410 case AMDGPU_PP_SENSOR_GPU_INPUT_POWER:
411 ret = smu_v14_0_0_get_smu_metrics_data(smu,
412 METRICS_CURR_SOCKETPOWER,
413 (uint32_t *)data);
414 *size = 4;
415 break;
416 case AMDGPU_PP_SENSOR_EDGE_TEMP:
417 ret = smu_v14_0_0_get_smu_metrics_data(smu,
418 METRICS_TEMPERATURE_EDGE,
419 (uint32_t *)data);
420 *size = 4;
421 break;
422 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
423 ret = smu_v14_0_0_get_smu_metrics_data(smu,
424 METRICS_TEMPERATURE_HOTSPOT,
425 (uint32_t *)data);
426 *size = 4;
427 break;
428 case AMDGPU_PP_SENSOR_GFX_MCLK:
429 ret = smu_v14_0_0_get_smu_metrics_data(smu,
430 METRICS_AVERAGE_UCLK,
431 (uint32_t *)data);
432 *(uint32_t *)data *= 100;
433 *size = 4;
434 break;
435 case AMDGPU_PP_SENSOR_GFX_SCLK:
436 ret = smu_v14_0_0_get_smu_metrics_data(smu,
437 METRICS_AVERAGE_GFXCLK,
438 (uint32_t *)data);
439 *(uint32_t *)data *= 100;
440 *size = 4;
441 break;
442 case AMDGPU_PP_SENSOR_VDDGFX:
443 ret = smu_v14_0_0_get_smu_metrics_data(smu,
444 METRICS_VOLTAGE_VDDGFX,
445 (uint32_t *)data);
446 *size = 4;
447 break;
448 case AMDGPU_PP_SENSOR_VDDNB:
449 ret = smu_v14_0_0_get_smu_metrics_data(smu,
450 METRICS_VOLTAGE_VDDSOC,
451 (uint32_t *)data);
452 *size = 4;
453 break;
454 case AMDGPU_PP_SENSOR_SS_APU_SHARE:
455 ret = smu_v14_0_0_get_smu_metrics_data(smu,
456 METRICS_SS_APU_SHARE,
457 (uint32_t *)data);
458 *size = 4;
459 break;
460 case AMDGPU_PP_SENSOR_SS_DGPU_SHARE:
461 ret = smu_v14_0_0_get_smu_metrics_data(smu,
462 METRICS_SS_DGPU_SHARE,
463 (uint32_t *)data);
464 *size = 4;
465 break;
466 default:
467 ret = -EOPNOTSUPP;
468 break;
469 }
470
471 return ret;
472 }
473
smu_v14_0_0_is_dpm_running(struct smu_context * smu)474 static bool smu_v14_0_0_is_dpm_running(struct smu_context *smu)
475 {
476 int ret = 0;
477 struct smu_feature_bits feature_enabled;
478
479 ret = smu_cmn_get_enabled_mask(smu, &feature_enabled);
480
481 if (ret)
482 return false;
483
484 return smu_feature_bits_test_mask(&feature_enabled,
485 smu_v14_0_0_dpm_features.bits);
486 }
487
smu_v14_0_0_set_watermarks_table(struct smu_context * smu,struct pp_smu_wm_range_sets * clock_ranges)488 static int smu_v14_0_0_set_watermarks_table(struct smu_context *smu,
489 struct pp_smu_wm_range_sets *clock_ranges)
490 {
491 int i;
492 int ret = 0;
493 Watermarks_t *table = smu->smu_table.watermarks_table;
494
495 if (!table || !clock_ranges)
496 return -EINVAL;
497
498 if (clock_ranges->num_reader_wm_sets > NUM_WM_RANGES ||
499 clock_ranges->num_writer_wm_sets > NUM_WM_RANGES)
500 return -EINVAL;
501
502 for (i = 0; i < clock_ranges->num_reader_wm_sets; i++) {
503 table->WatermarkRow[WM_DCFCLK][i].MinClock =
504 clock_ranges->reader_wm_sets[i].min_drain_clk_mhz;
505 table->WatermarkRow[WM_DCFCLK][i].MaxClock =
506 clock_ranges->reader_wm_sets[i].max_drain_clk_mhz;
507 table->WatermarkRow[WM_DCFCLK][i].MinMclk =
508 clock_ranges->reader_wm_sets[i].min_fill_clk_mhz;
509 table->WatermarkRow[WM_DCFCLK][i].MaxMclk =
510 clock_ranges->reader_wm_sets[i].max_fill_clk_mhz;
511
512 table->WatermarkRow[WM_DCFCLK][i].WmSetting =
513 clock_ranges->reader_wm_sets[i].wm_inst;
514 }
515
516 for (i = 0; i < clock_ranges->num_writer_wm_sets; i++) {
517 table->WatermarkRow[WM_SOCCLK][i].MinClock =
518 clock_ranges->writer_wm_sets[i].min_fill_clk_mhz;
519 table->WatermarkRow[WM_SOCCLK][i].MaxClock =
520 clock_ranges->writer_wm_sets[i].max_fill_clk_mhz;
521 table->WatermarkRow[WM_SOCCLK][i].MinMclk =
522 clock_ranges->writer_wm_sets[i].min_drain_clk_mhz;
523 table->WatermarkRow[WM_SOCCLK][i].MaxMclk =
524 clock_ranges->writer_wm_sets[i].max_drain_clk_mhz;
525
526 table->WatermarkRow[WM_SOCCLK][i].WmSetting =
527 clock_ranges->writer_wm_sets[i].wm_inst;
528 }
529
530 smu->watermarks_bitmap |= WATERMARKS_EXIST;
531
532 /* pass data to smu controller */
533 if ((smu->watermarks_bitmap & WATERMARKS_EXIST) &&
534 !(smu->watermarks_bitmap & WATERMARKS_LOADED)) {
535 ret = smu_cmn_write_watermarks_table(smu);
536 if (ret) {
537 dev_err(smu->adev->dev, "Failed to update WMTABLE!");
538 return ret;
539 }
540 smu->watermarks_bitmap |= WATERMARKS_LOADED;
541 }
542
543 return 0;
544 }
545
smu_v14_0_0_get_gpu_metrics(struct smu_context * smu,void ** table)546 static ssize_t smu_v14_0_0_get_gpu_metrics(struct smu_context *smu,
547 void **table)
548 {
549 struct gpu_metrics_v3_0 *gpu_metrics =
550 (struct gpu_metrics_v3_0 *)smu_driver_table_ptr(
551 smu, SMU_DRIVER_TABLE_GPU_METRICS);
552 SmuMetrics_t metrics;
553 int ret = 0;
554
555 ret = smu_cmn_get_metrics_table(smu, &metrics, true);
556 if (ret)
557 return ret;
558
559 smu_cmn_init_soft_gpu_metrics(gpu_metrics, 3, 0);
560
561 gpu_metrics->temperature_gfx = metrics.GfxTemperature;
562 gpu_metrics->temperature_soc = metrics.SocTemperature;
563 memcpy(&gpu_metrics->temperature_core[0],
564 &metrics.CoreTemperature[0],
565 sizeof(uint16_t) * 16);
566 gpu_metrics->temperature_skin = metrics.SkinTemp;
567
568 gpu_metrics->average_gfx_activity = metrics.GfxActivity;
569 gpu_metrics->average_vcn_activity = metrics.VcnActivity;
570 memcpy(&gpu_metrics->average_ipu_activity[0],
571 &metrics.IpuBusy[0],
572 sizeof(uint16_t) * 8);
573 memcpy(&gpu_metrics->average_core_c0_activity[0],
574 &metrics.CoreC0Residency[0],
575 sizeof(uint16_t) * 16);
576 gpu_metrics->average_dram_reads = metrics.DRAMReads;
577 gpu_metrics->average_dram_writes = metrics.DRAMWrites;
578 gpu_metrics->average_ipu_reads = metrics.IpuReads;
579 gpu_metrics->average_ipu_writes = metrics.IpuWrites;
580
581 gpu_metrics->average_socket_power = metrics.SocketPower;
582 gpu_metrics->average_ipu_power = metrics.IpuPower;
583 gpu_metrics->average_apu_power = metrics.ApuPower;
584 gpu_metrics->average_gfx_power = metrics.GfxPower;
585 gpu_metrics->average_dgpu_power = metrics.dGpuPower;
586 gpu_metrics->average_all_core_power = metrics.AllCorePower;
587 gpu_metrics->average_sys_power = metrics.Psys;
588 memcpy(&gpu_metrics->average_core_power[0],
589 &metrics.CorePower[0],
590 sizeof(uint16_t) * 16);
591
592 gpu_metrics->average_gfxclk_frequency = metrics.GfxclkFrequency;
593 gpu_metrics->average_socclk_frequency = metrics.SocclkFrequency;
594 gpu_metrics->average_vpeclk_frequency = metrics.VpeclkFrequency;
595 gpu_metrics->average_fclk_frequency = metrics.FclkFrequency;
596 gpu_metrics->average_vclk_frequency = metrics.VclkFrequency;
597 gpu_metrics->average_ipuclk_frequency = metrics.IpuclkFrequency;
598 gpu_metrics->average_uclk_frequency = metrics.MemclkFrequency;
599 gpu_metrics->average_mpipu_frequency = metrics.MpipuclkFrequency;
600
601 memcpy(&gpu_metrics->current_coreclk[0],
602 &metrics.CoreFrequency[0],
603 sizeof(uint16_t) * 16);
604 gpu_metrics->current_core_maxfreq = metrics.InfrastructureCpuMaxFreq;
605 gpu_metrics->current_gfx_maxfreq = metrics.InfrastructureGfxMaxFreq;
606
607 gpu_metrics->throttle_residency_prochot = metrics.ThrottleResidency_PROCHOT;
608 gpu_metrics->throttle_residency_spl = metrics.ThrottleResidency_SPL;
609 gpu_metrics->throttle_residency_fppt = metrics.ThrottleResidency_FPPT;
610 gpu_metrics->throttle_residency_sppt = metrics.ThrottleResidency_SPPT;
611 gpu_metrics->throttle_residency_thm_core = metrics.ThrottleResidency_THM_CORE;
612 gpu_metrics->throttle_residency_thm_gfx = metrics.ThrottleResidency_THM_GFX;
613 gpu_metrics->throttle_residency_thm_soc = metrics.ThrottleResidency_THM_SOC;
614
615 gpu_metrics->time_filter_alphavalue = metrics.FilterAlphaValue;
616 gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
617
618 *table = (void *)gpu_metrics;
619
620 smu_driver_table_update_cache_time(smu, SMU_DRIVER_TABLE_GPU_METRICS);
621
622 return sizeof(struct gpu_metrics_v3_0);
623 }
624
smu_v14_0_0_mode2_reset(struct smu_context * smu)625 static int smu_v14_0_0_mode2_reset(struct smu_context *smu)
626 {
627 int ret;
628
629 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset,
630 SMU_RESET_MODE_2, NULL);
631
632 if (ret)
633 dev_err(smu->adev->dev, "Failed to mode2 reset!\n");
634
635 return ret;
636 }
637
smu_v14_0_1_get_dpm_freq_by_index(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t dpm_level,uint32_t * freq)638 static int smu_v14_0_1_get_dpm_freq_by_index(struct smu_context *smu,
639 enum smu_clk_type clk_type,
640 uint32_t dpm_level,
641 uint32_t *freq)
642 {
643 DpmClocks_t_v14_0_1 *clk_table = smu->smu_table.clocks_table;
644
645 if (!clk_table || clk_type >= SMU_CLK_COUNT)
646 return -EINVAL;
647
648 switch (clk_type) {
649 case SMU_SOCCLK:
650 if (dpm_level >= clk_table->NumSocClkLevelsEnabled)
651 return -EINVAL;
652 *freq = clk_table->SocClocks[dpm_level];
653 break;
654 case SMU_VCLK:
655 if (dpm_level >= clk_table->Vcn0ClkLevelsEnabled)
656 return -EINVAL;
657 *freq = clk_table->VClocks0[dpm_level];
658 break;
659 case SMU_DCLK:
660 if (dpm_level >= clk_table->Vcn0ClkLevelsEnabled)
661 return -EINVAL;
662 *freq = clk_table->DClocks0[dpm_level];
663 break;
664 case SMU_VCLK1:
665 if (dpm_level >= clk_table->Vcn1ClkLevelsEnabled)
666 return -EINVAL;
667 *freq = clk_table->VClocks1[dpm_level];
668 break;
669 case SMU_DCLK1:
670 if (dpm_level >= clk_table->Vcn1ClkLevelsEnabled)
671 return -EINVAL;
672 *freq = clk_table->DClocks1[dpm_level];
673 break;
674 case SMU_UCLK:
675 case SMU_MCLK:
676 if (dpm_level >= clk_table->NumMemPstatesEnabled)
677 return -EINVAL;
678 *freq = clk_table->MemPstateTable[dpm_level].MemClk;
679 break;
680 case SMU_FCLK:
681 if (dpm_level >= clk_table->NumFclkLevelsEnabled)
682 return -EINVAL;
683 *freq = clk_table->FclkClocks_Freq[dpm_level];
684 break;
685 default:
686 return -EINVAL;
687 }
688
689 return 0;
690 }
691
smu_v14_0_0_get_dpm_freq_by_index(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t dpm_level,uint32_t * freq)692 static int smu_v14_0_0_get_dpm_freq_by_index(struct smu_context *smu,
693 enum smu_clk_type clk_type,
694 uint32_t dpm_level,
695 uint32_t *freq)
696 {
697 DpmClocks_t *clk_table = smu->smu_table.clocks_table;
698
699 if (!clk_table || clk_type >= SMU_CLK_COUNT)
700 return -EINVAL;
701
702 switch (clk_type) {
703 case SMU_SOCCLK:
704 if (dpm_level >= clk_table->NumSocClkLevelsEnabled)
705 return -EINVAL;
706 *freq = clk_table->SocClocks[dpm_level];
707 break;
708 case SMU_VCLK:
709 if (dpm_level >= clk_table->VcnClkLevelsEnabled)
710 return -EINVAL;
711 *freq = clk_table->VClocks[dpm_level];
712 break;
713 case SMU_DCLK:
714 if (dpm_level >= clk_table->VcnClkLevelsEnabled)
715 return -EINVAL;
716 *freq = clk_table->DClocks[dpm_level];
717 break;
718 case SMU_UCLK:
719 case SMU_MCLK:
720 if (dpm_level >= clk_table->NumMemPstatesEnabled)
721 return -EINVAL;
722 *freq = clk_table->MemPstateTable[dpm_level].MemClk;
723 break;
724 case SMU_FCLK:
725 if (dpm_level >= clk_table->NumFclkLevelsEnabled)
726 return -EINVAL;
727 *freq = clk_table->FclkClocks_Freq[dpm_level];
728 break;
729 default:
730 return -EINVAL;
731 }
732
733 return 0;
734 }
735
smu_v14_0_common_get_dpm_freq_by_index(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t dpm_level,uint32_t * freq)736 static int smu_v14_0_common_get_dpm_freq_by_index(struct smu_context *smu,
737 enum smu_clk_type clk_type,
738 uint32_t dpm_level,
739 uint32_t *freq)
740 {
741 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 1))
742 smu_v14_0_1_get_dpm_freq_by_index(smu, clk_type, dpm_level, freq);
743 else if (clk_type != SMU_VCLK1 && clk_type != SMU_DCLK1)
744 smu_v14_0_0_get_dpm_freq_by_index(smu, clk_type, dpm_level, freq);
745
746 return 0;
747 }
748
smu_v14_0_0_clk_dpm_is_enabled(struct smu_context * smu,enum smu_clk_type clk_type)749 static bool smu_v14_0_0_clk_dpm_is_enabled(struct smu_context *smu,
750 enum smu_clk_type clk_type)
751 {
752 enum smu_feature_mask feature_id = 0;
753
754 switch (clk_type) {
755 case SMU_MCLK:
756 case SMU_UCLK:
757 case SMU_FCLK:
758 feature_id = SMU_FEATURE_DPM_FCLK_BIT;
759 break;
760 case SMU_GFXCLK:
761 case SMU_SCLK:
762 feature_id = SMU_FEATURE_DPM_GFXCLK_BIT;
763 break;
764 case SMU_SOCCLK:
765 feature_id = SMU_FEATURE_DPM_SOCCLK_BIT;
766 break;
767 case SMU_VCLK:
768 case SMU_DCLK:
769 case SMU_VCLK1:
770 case SMU_DCLK1:
771 feature_id = SMU_FEATURE_VCN_DPM_BIT;
772 break;
773 default:
774 return true;
775 }
776
777 return smu_cmn_feature_is_enabled(smu, feature_id);
778 }
779
smu_v14_0_1_get_dpm_ultimate_freq(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t * min,uint32_t * max)780 static int smu_v14_0_1_get_dpm_ultimate_freq(struct smu_context *smu,
781 enum smu_clk_type clk_type,
782 uint32_t *min,
783 uint32_t *max)
784 {
785 DpmClocks_t_v14_0_1 *clk_table = smu->smu_table.clocks_table;
786 uint32_t clock_limit;
787 uint32_t max_dpm_level, min_dpm_level;
788 int ret = 0;
789
790 if (!smu_v14_0_0_clk_dpm_is_enabled(smu, clk_type)) {
791 switch (clk_type) {
792 case SMU_MCLK:
793 case SMU_UCLK:
794 clock_limit = smu->smu_table.boot_values.uclk;
795 break;
796 case SMU_FCLK:
797 clock_limit = smu->smu_table.boot_values.fclk;
798 break;
799 case SMU_GFXCLK:
800 case SMU_SCLK:
801 clock_limit = smu->smu_table.boot_values.gfxclk;
802 break;
803 case SMU_SOCCLK:
804 clock_limit = smu->smu_table.boot_values.socclk;
805 break;
806 case SMU_VCLK:
807 case SMU_VCLK1:
808 clock_limit = smu->smu_table.boot_values.vclk;
809 break;
810 case SMU_DCLK:
811 case SMU_DCLK1:
812 clock_limit = smu->smu_table.boot_values.dclk;
813 break;
814 default:
815 clock_limit = 0;
816 break;
817 }
818
819 /* clock in Mhz unit */
820 if (min)
821 *min = clock_limit / 100;
822 if (max)
823 *max = clock_limit / 100;
824
825 return 0;
826 }
827
828 if (max) {
829 switch (clk_type) {
830 case SMU_GFXCLK:
831 case SMU_SCLK:
832 *max = clk_table->MaxGfxClk;
833 break;
834 case SMU_MCLK:
835 case SMU_UCLK:
836 max_dpm_level = 0;
837 break;
838 case SMU_FCLK:
839 max_dpm_level = clk_table->NumFclkLevelsEnabled - 1;
840 break;
841 case SMU_SOCCLK:
842 max_dpm_level = clk_table->NumSocClkLevelsEnabled - 1;
843 break;
844 case SMU_VCLK:
845 case SMU_DCLK:
846 max_dpm_level = clk_table->Vcn0ClkLevelsEnabled - 1;
847 break;
848 case SMU_VCLK1:
849 case SMU_DCLK1:
850 max_dpm_level = clk_table->Vcn1ClkLevelsEnabled - 1;
851 break;
852 default:
853 ret = -EINVAL;
854 goto failed;
855 }
856
857 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) {
858 ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, max_dpm_level, max);
859 if (ret)
860 goto failed;
861 }
862 }
863
864 if (min) {
865 switch (clk_type) {
866 case SMU_GFXCLK:
867 case SMU_SCLK:
868 *min = clk_table->MinGfxClk;
869 break;
870 case SMU_MCLK:
871 case SMU_UCLK:
872 min_dpm_level = clk_table->NumMemPstatesEnabled - 1;
873 break;
874 case SMU_FCLK:
875 min_dpm_level = 0;
876 break;
877 case SMU_SOCCLK:
878 min_dpm_level = 0;
879 break;
880 case SMU_VCLK:
881 case SMU_DCLK:
882 case SMU_VCLK1:
883 case SMU_DCLK1:
884 min_dpm_level = 0;
885 break;
886 default:
887 ret = -EINVAL;
888 goto failed;
889 }
890
891 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) {
892 ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, min_dpm_level, min);
893 if (ret)
894 goto failed;
895 }
896 }
897
898 failed:
899 return ret;
900 }
901
smu_v14_0_0_get_dpm_ultimate_freq(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t * min,uint32_t * max)902 static int smu_v14_0_0_get_dpm_ultimate_freq(struct smu_context *smu,
903 enum smu_clk_type clk_type,
904 uint32_t *min,
905 uint32_t *max)
906 {
907 DpmClocks_t *clk_table = smu->smu_table.clocks_table;
908 uint32_t clock_limit;
909 uint32_t max_dpm_level, min_dpm_level;
910 int ret = 0;
911
912 if (!smu_v14_0_0_clk_dpm_is_enabled(smu, clk_type)) {
913 switch (clk_type) {
914 case SMU_MCLK:
915 case SMU_UCLK:
916 clock_limit = smu->smu_table.boot_values.uclk;
917 break;
918 case SMU_FCLK:
919 clock_limit = smu->smu_table.boot_values.fclk;
920 break;
921 case SMU_GFXCLK:
922 case SMU_SCLK:
923 clock_limit = smu->smu_table.boot_values.gfxclk;
924 break;
925 case SMU_SOCCLK:
926 clock_limit = smu->smu_table.boot_values.socclk;
927 break;
928 case SMU_VCLK:
929 clock_limit = smu->smu_table.boot_values.vclk;
930 break;
931 case SMU_DCLK:
932 clock_limit = smu->smu_table.boot_values.dclk;
933 break;
934 default:
935 clock_limit = 0;
936 break;
937 }
938
939 /* clock in Mhz unit */
940 if (min)
941 *min = clock_limit / 100;
942 if (max)
943 *max = clock_limit / 100;
944
945 return 0;
946 }
947
948 if (max) {
949 switch (clk_type) {
950 case SMU_GFXCLK:
951 case SMU_SCLK:
952 *max = clk_table->MaxGfxClk;
953 break;
954 case SMU_MCLK:
955 case SMU_UCLK:
956 max_dpm_level = 0;
957 break;
958 case SMU_FCLK:
959 max_dpm_level = clk_table->NumFclkLevelsEnabled - 1;
960 break;
961 case SMU_SOCCLK:
962 max_dpm_level = clk_table->NumSocClkLevelsEnabled - 1;
963 break;
964 case SMU_VCLK:
965 case SMU_DCLK:
966 max_dpm_level = clk_table->VcnClkLevelsEnabled - 1;
967 break;
968 default:
969 ret = -EINVAL;
970 goto failed;
971 }
972
973 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) {
974 ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, max_dpm_level, max);
975 if (ret)
976 goto failed;
977 }
978 }
979
980 if (min) {
981 switch (clk_type) {
982 case SMU_GFXCLK:
983 case SMU_SCLK:
984 *min = clk_table->MinGfxClk;
985 break;
986 case SMU_MCLK:
987 case SMU_UCLK:
988 min_dpm_level = clk_table->NumMemPstatesEnabled - 1;
989 break;
990 case SMU_FCLK:
991 min_dpm_level = 0;
992 break;
993 case SMU_SOCCLK:
994 min_dpm_level = 0;
995 break;
996 case SMU_VCLK:
997 case SMU_DCLK:
998 min_dpm_level = 0;
999 break;
1000 default:
1001 ret = -EINVAL;
1002 goto failed;
1003 }
1004
1005 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK) {
1006 ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, min_dpm_level, min);
1007 if (ret)
1008 goto failed;
1009 }
1010 }
1011
1012 failed:
1013 return ret;
1014 }
1015
smu_v14_0_common_get_dpm_ultimate_freq(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t * min,uint32_t * max)1016 static int smu_v14_0_common_get_dpm_ultimate_freq(struct smu_context *smu,
1017 enum smu_clk_type clk_type,
1018 uint32_t *min,
1019 uint32_t *max)
1020 {
1021 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 1))
1022 smu_v14_0_1_get_dpm_ultimate_freq(smu, clk_type, min, max);
1023 else if (clk_type != SMU_VCLK1 && clk_type != SMU_DCLK1)
1024 smu_v14_0_0_get_dpm_ultimate_freq(smu, clk_type, min, max);
1025
1026 return 0;
1027 }
1028
smu_v14_0_0_get_current_clk_freq(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t * value)1029 static int smu_v14_0_0_get_current_clk_freq(struct smu_context *smu,
1030 enum smu_clk_type clk_type,
1031 uint32_t *value)
1032 {
1033 MetricsMember_t member_type;
1034
1035 switch (clk_type) {
1036 case SMU_SOCCLK:
1037 member_type = METRICS_AVERAGE_SOCCLK;
1038 break;
1039 case SMU_VCLK:
1040 member_type = METRICS_AVERAGE_VCLK;
1041 break;
1042 case SMU_VCLK1:
1043 member_type = METRICS_AVERAGE_VCLK1;
1044 break;
1045 case SMU_DCLK:
1046 member_type = METRICS_AVERAGE_DCLK;
1047 break;
1048 case SMU_DCLK1:
1049 member_type = METRICS_AVERAGE_DCLK1;
1050 break;
1051 case SMU_MCLK:
1052 member_type = METRICS_AVERAGE_UCLK;
1053 break;
1054 case SMU_FCLK:
1055 member_type = METRICS_AVERAGE_FCLK;
1056 break;
1057 case SMU_GFXCLK:
1058 case SMU_SCLK:
1059 member_type = METRICS_AVERAGE_GFXCLK;
1060 break;
1061 default:
1062 return -EINVAL;
1063 }
1064
1065 return smu_v14_0_0_get_smu_metrics_data(smu, member_type, value);
1066 }
1067
smu_v14_0_1_get_dpm_level_count(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t * count)1068 static int smu_v14_0_1_get_dpm_level_count(struct smu_context *smu,
1069 enum smu_clk_type clk_type,
1070 uint32_t *count)
1071 {
1072 DpmClocks_t_v14_0_1 *clk_table = smu->smu_table.clocks_table;
1073
1074 switch (clk_type) {
1075 case SMU_SOCCLK:
1076 *count = clk_table->NumSocClkLevelsEnabled;
1077 break;
1078 case SMU_VCLK:
1079 case SMU_DCLK:
1080 *count = clk_table->Vcn0ClkLevelsEnabled;
1081 break;
1082 case SMU_VCLK1:
1083 case SMU_DCLK1:
1084 *count = clk_table->Vcn1ClkLevelsEnabled;
1085 break;
1086 case SMU_MCLK:
1087 *count = clk_table->NumMemPstatesEnabled;
1088 break;
1089 case SMU_FCLK:
1090 *count = clk_table->NumFclkLevelsEnabled;
1091 break;
1092 default:
1093 break;
1094 }
1095
1096 return 0;
1097 }
1098
smu_v14_0_0_get_dpm_level_count(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t * count)1099 static int smu_v14_0_0_get_dpm_level_count(struct smu_context *smu,
1100 enum smu_clk_type clk_type,
1101 uint32_t *count)
1102 {
1103 DpmClocks_t *clk_table = smu->smu_table.clocks_table;
1104
1105 switch (clk_type) {
1106 case SMU_SOCCLK:
1107 *count = clk_table->NumSocClkLevelsEnabled;
1108 break;
1109 case SMU_VCLK:
1110 *count = clk_table->VcnClkLevelsEnabled;
1111 break;
1112 case SMU_DCLK:
1113 *count = clk_table->VcnClkLevelsEnabled;
1114 break;
1115 case SMU_MCLK:
1116 *count = clk_table->NumMemPstatesEnabled;
1117 break;
1118 case SMU_FCLK:
1119 *count = clk_table->NumFclkLevelsEnabled;
1120 break;
1121 default:
1122 break;
1123 }
1124
1125 return 0;
1126 }
1127
smu_v14_0_common_get_dpm_level_count(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t * count)1128 static int smu_v14_0_common_get_dpm_level_count(struct smu_context *smu,
1129 enum smu_clk_type clk_type,
1130 uint32_t *count)
1131 {
1132 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 1))
1133 smu_v14_0_1_get_dpm_level_count(smu, clk_type, count);
1134 else if (clk_type != SMU_VCLK1 && clk_type != SMU_DCLK1)
1135 smu_v14_0_0_get_dpm_level_count(smu, clk_type, count);
1136
1137 return 0;
1138 }
1139
smu_v14_0_0_emit_clk_levels(struct smu_context * smu,enum smu_clk_type clk_type,char * buf,int * offset)1140 static int smu_v14_0_0_emit_clk_levels(struct smu_context *smu,
1141 enum smu_clk_type clk_type, char *buf,
1142 int *offset)
1143 {
1144 int i, idx, ret = 0, size = *offset, start_offset = *offset;
1145 uint32_t cur_value = 0, value = 0, count = 0;
1146 uint32_t min, max;
1147
1148 switch (clk_type) {
1149 case SMU_OD_SCLK:
1150 size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
1151 size += sysfs_emit_at(buf, size, "0: %10uMhz\n",
1152 (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq);
1153 size += sysfs_emit_at(buf, size, "1: %10uMhz\n",
1154 (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq);
1155 break;
1156 case SMU_OD_RANGE:
1157 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
1158 size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n",
1159 smu->gfx_default_hard_min_freq,
1160 smu->gfx_default_soft_max_freq);
1161 break;
1162 case SMU_SOCCLK:
1163 case SMU_VCLK:
1164 case SMU_DCLK:
1165 case SMU_VCLK1:
1166 case SMU_DCLK1:
1167 case SMU_MCLK:
1168 case SMU_FCLK:
1169 ret = smu_v14_0_0_get_current_clk_freq(smu, clk_type, &cur_value);
1170 if (ret)
1171 return ret;
1172
1173 ret = smu_v14_0_common_get_dpm_level_count(smu, clk_type, &count);
1174 if (ret)
1175 return ret;
1176
1177 for (i = 0; i < count; i++) {
1178 idx = (clk_type == SMU_MCLK) ? (count - i - 1) : i;
1179 ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, idx, &value);
1180 if (ret)
1181 return ret;
1182
1183 size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i, value,
1184 cur_value == value ? "*" : "");
1185 }
1186 break;
1187 case SMU_GFXCLK:
1188 case SMU_SCLK:
1189 ret = smu_v14_0_0_get_current_clk_freq(smu, clk_type, &cur_value);
1190 if (ret)
1191 return ret;
1192 min = (smu->gfx_actual_hard_min_freq > 0) ? smu->gfx_actual_hard_min_freq : smu->gfx_default_hard_min_freq;
1193 max = (smu->gfx_actual_soft_max_freq > 0) ? smu->gfx_actual_soft_max_freq : smu->gfx_default_soft_max_freq;
1194 if (cur_value == max)
1195 i = 2;
1196 else if (cur_value == min)
1197 i = 0;
1198 else
1199 i = 1;
1200 size += sysfs_emit_at(buf, size, "0: %uMhz %s\n", min,
1201 i == 0 ? "*" : "");
1202 size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
1203 i == 1 ? cur_value : 1100, /* UMD PSTATE GFXCLK 1100 */
1204 i == 1 ? "*" : "");
1205 size += sysfs_emit_at(buf, size, "2: %uMhz %s\n", max,
1206 i == 2 ? "*" : "");
1207 break;
1208 default:
1209 break;
1210 }
1211
1212 *offset += size - start_offset;
1213
1214 return 0;
1215 }
1216
smu_v14_0_0_set_soft_freq_limited_range(struct smu_context * smu,enum smu_clk_type clk_type,u32 min,u32 max,bool __always_unused automatic)1217 static int smu_v14_0_0_set_soft_freq_limited_range(struct smu_context *smu,
1218 enum smu_clk_type clk_type,
1219 u32 min,
1220 u32 max,
1221 bool __always_unused automatic)
1222 {
1223 enum smu_message_type msg_set_min = SMU_MSG_MAX_COUNT;
1224 enum smu_message_type msg_set_max = SMU_MSG_MAX_COUNT;
1225 int ret = -EINVAL;
1226
1227 if (!smu_v14_0_0_clk_dpm_is_enabled(smu, clk_type))
1228 return -EINVAL;
1229
1230 switch (clk_type) {
1231 case SMU_GFXCLK:
1232 case SMU_SCLK:
1233 /* SoftMin lets PMFW throttle gfxclk; HardMin would override SoftMax. */
1234 msg_set_min = SMU_MSG_SetSoftMinGfxclk;
1235 msg_set_max = SMU_MSG_SetSoftMaxGfxClk;
1236 break;
1237 case SMU_FCLK:
1238 msg_set_min = SMU_MSG_SetHardMinFclkByFreq;
1239 msg_set_max = SMU_MSG_SetSoftMaxFclkByFreq;
1240 break;
1241 case SMU_SOCCLK:
1242 msg_set_min = SMU_MSG_SetHardMinSocclkByFreq;
1243 msg_set_max = SMU_MSG_SetSoftMaxSocclkByFreq;
1244 break;
1245 case SMU_VCLK:
1246 case SMU_DCLK:
1247 msg_set_min = SMU_MSG_SetHardMinVcn0;
1248 msg_set_max = SMU_MSG_SetSoftMaxVcn0;
1249 break;
1250 case SMU_VCLK1:
1251 case SMU_DCLK1:
1252 msg_set_min = SMU_MSG_SetHardMinVcn1;
1253 msg_set_max = SMU_MSG_SetSoftMaxVcn1;
1254 break;
1255 case SMU_ISPICLK:
1256 msg_set_min = SMU_MSG_SetHardMinIspiclkByFreq;
1257 break;
1258 case SMU_ISPXCLK:
1259 msg_set_min = SMU_MSG_SetHardMinIspxclkByFreq;
1260 break;
1261 default:
1262 return -EINVAL;
1263 }
1264
1265 if (min && msg_set_min != SMU_MSG_MAX_COUNT)
1266 ret = smu_cmn_send_smc_msg_with_param(smu, msg_set_min, min, NULL);
1267
1268 if (max && msg_set_max != SMU_MSG_MAX_COUNT)
1269 ret = smu_cmn_send_smc_msg_with_param(smu, msg_set_max, max, NULL);
1270
1271 return ret;
1272 }
1273
smu_v14_0_0_force_clk_levels(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t mask)1274 static int smu_v14_0_0_force_clk_levels(struct smu_context *smu,
1275 enum smu_clk_type clk_type,
1276 uint32_t mask)
1277 {
1278 uint32_t soft_min_level = 0, soft_max_level = 0;
1279 uint32_t min_freq = 0, max_freq = 0;
1280 int ret = 0;
1281
1282 soft_min_level = mask ? (ffs(mask) - 1) : 0;
1283 soft_max_level = mask ? (fls(mask) - 1) : 0;
1284
1285 switch (clk_type) {
1286 case SMU_SOCCLK:
1287 case SMU_FCLK:
1288 case SMU_VCLK:
1289 case SMU_DCLK:
1290 case SMU_VCLK1:
1291 case SMU_DCLK1:
1292 ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, soft_min_level, &min_freq);
1293 if (ret)
1294 break;
1295
1296 ret = smu_v14_0_common_get_dpm_freq_by_index(smu, clk_type, soft_max_level, &max_freq);
1297 if (ret)
1298 break;
1299
1300 ret = smu_v14_0_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq, false);
1301 break;
1302 default:
1303 ret = -EINVAL;
1304 break;
1305 }
1306
1307 return ret;
1308 }
1309
smu_v14_0_common_get_dpm_profile_freq(struct smu_context * smu,enum amd_dpm_forced_level level,enum smu_clk_type clk_type,uint32_t * min_clk,uint32_t * max_clk)1310 static int smu_v14_0_common_get_dpm_profile_freq(struct smu_context *smu,
1311 enum amd_dpm_forced_level level,
1312 enum smu_clk_type clk_type,
1313 uint32_t *min_clk,
1314 uint32_t *max_clk)
1315 {
1316 uint32_t clk_limit = 0;
1317 int ret = 0;
1318
1319 switch (clk_type) {
1320 case SMU_GFXCLK:
1321 case SMU_SCLK:
1322 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 4))
1323 clk_limit = SMU_14_0_4_UMD_PSTATE_GFXCLK;
1324 else
1325 clk_limit = SMU_14_0_0_UMD_PSTATE_GFXCLK;
1326 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
1327 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SCLK, NULL, &clk_limit);
1328 else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK)
1329 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SCLK, &clk_limit, NULL);
1330 break;
1331 case SMU_SOCCLK:
1332 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 4))
1333 clk_limit = SMU_14_0_4_UMD_PSTATE_SOCCLK;
1334 else
1335 clk_limit = SMU_14_0_0_UMD_PSTATE_SOCCLK;
1336 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
1337 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SOCCLK, NULL, &clk_limit);
1338 break;
1339 case SMU_FCLK:
1340 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 4))
1341 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL, &clk_limit);
1342 else
1343 clk_limit = SMU_14_0_0_UMD_PSTATE_FCLK;
1344 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK)
1345 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL, &clk_limit);
1346 else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK)
1347 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, &clk_limit, NULL);
1348 break;
1349 case SMU_VCLK:
1350 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_VCLK, NULL, &clk_limit);
1351 break;
1352 case SMU_VCLK1:
1353 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_VCLK1, NULL, &clk_limit);
1354 break;
1355 case SMU_DCLK:
1356 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_DCLK, NULL, &clk_limit);
1357 break;
1358 case SMU_DCLK1:
1359 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_DCLK1, NULL, &clk_limit);
1360 break;
1361 default:
1362 ret = -EINVAL;
1363 break;
1364 }
1365 *min_clk = *max_clk = clk_limit;
1366 return ret;
1367 }
1368
smu_v14_0_common_set_performance_level(struct smu_context * smu,enum amd_dpm_forced_level level)1369 static int smu_v14_0_common_set_performance_level(struct smu_context *smu,
1370 enum amd_dpm_forced_level level)
1371 {
1372 struct amdgpu_device *adev = smu->adev;
1373 uint32_t sclk_min = 0, sclk_max = 0;
1374 uint32_t fclk_min = 0, fclk_max = 0;
1375 uint32_t socclk_min = 0, socclk_max = 0;
1376 uint32_t vclk_min = 0, vclk_max = 0;
1377 uint32_t dclk_min = 0, dclk_max = 0;
1378 uint32_t vclk1_min = 0, vclk1_max = 0;
1379 uint32_t dclk1_min = 0, dclk1_max = 0;
1380 int ret = 0;
1381
1382 switch (level) {
1383 case AMD_DPM_FORCED_LEVEL_HIGH:
1384 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SCLK, NULL, &sclk_max);
1385 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, NULL, &fclk_max);
1386 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SOCCLK, NULL, &socclk_max);
1387 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_VCLK, NULL, &vclk_max);
1388 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_DCLK, NULL, &dclk_max);
1389 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_VCLK1, NULL, &vclk1_max);
1390 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_DCLK1, NULL, &dclk1_max);
1391 sclk_min = sclk_max;
1392 fclk_min = fclk_max;
1393 socclk_min = socclk_max;
1394 vclk_min = vclk_max;
1395 dclk_min = dclk_max;
1396 vclk1_min = vclk1_max;
1397 dclk1_min = dclk1_max;
1398 break;
1399 case AMD_DPM_FORCED_LEVEL_LOW:
1400 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SCLK, &sclk_min, NULL);
1401 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, &fclk_min, NULL);
1402 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SOCCLK, &socclk_min, NULL);
1403 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_VCLK, &vclk_min, NULL);
1404 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_DCLK, &dclk_min, NULL);
1405 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_VCLK1, &vclk1_min, NULL);
1406 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_DCLK1, &dclk1_min, NULL);
1407 sclk_max = sclk_min;
1408 fclk_max = fclk_min;
1409 socclk_max = socclk_min;
1410 vclk_max = vclk_min;
1411 dclk_max = dclk_min;
1412 vclk1_max = vclk1_min;
1413 dclk1_max = dclk1_min;
1414 break;
1415 case AMD_DPM_FORCED_LEVEL_AUTO:
1416 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SCLK, &sclk_min, &sclk_max);
1417 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_FCLK, &fclk_min, &fclk_max);
1418 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_SOCCLK, &socclk_min, &socclk_max);
1419 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_VCLK, &vclk_min, &vclk_max);
1420 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_DCLK, &dclk_min, &dclk_max);
1421 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_VCLK1, &vclk1_min, &vclk1_max);
1422 smu_v14_0_common_get_dpm_ultimate_freq(smu, SMU_DCLK1, &dclk1_min, &dclk1_max);
1423 break;
1424 case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
1425 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
1426 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
1427 case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
1428 smu_v14_0_common_get_dpm_profile_freq(smu, level, SMU_SCLK, &sclk_min, &sclk_max);
1429 smu_v14_0_common_get_dpm_profile_freq(smu, level, SMU_FCLK, &fclk_min, &fclk_max);
1430 smu_v14_0_common_get_dpm_profile_freq(smu, level, SMU_SOCCLK, &socclk_min, &socclk_max);
1431 smu_v14_0_common_get_dpm_profile_freq(smu, level, SMU_VCLK, &vclk_min, &vclk_max);
1432 smu_v14_0_common_get_dpm_profile_freq(smu, level, SMU_DCLK, &dclk_min, &dclk_max);
1433 smu_v14_0_common_get_dpm_profile_freq(smu, level, SMU_VCLK1, &vclk1_min, &vclk1_max);
1434 smu_v14_0_common_get_dpm_profile_freq(smu, level, SMU_DCLK1, &dclk1_min, &dclk1_max);
1435 break;
1436 case AMD_DPM_FORCED_LEVEL_MANUAL:
1437 case AMD_DPM_FORCED_LEVEL_PROFILE_EXIT:
1438 return 0;
1439 default:
1440 dev_err(adev->dev, "Invalid performance level %d\n", level);
1441 return -EINVAL;
1442 }
1443
1444 if (sclk_min && sclk_max) {
1445 ret = smu_v14_0_0_set_soft_freq_limited_range(smu,
1446 SMU_SCLK,
1447 sclk_min,
1448 sclk_max,
1449 false);
1450 if (ret)
1451 return ret;
1452
1453 smu->gfx_actual_hard_min_freq = sclk_min;
1454 smu->gfx_actual_soft_max_freq = sclk_max;
1455 }
1456
1457 if (fclk_min && fclk_max) {
1458 ret = smu_v14_0_0_set_soft_freq_limited_range(smu,
1459 SMU_FCLK,
1460 fclk_min,
1461 fclk_max,
1462 false);
1463 if (ret)
1464 return ret;
1465 }
1466
1467 if (socclk_min && socclk_max) {
1468 ret = smu_v14_0_0_set_soft_freq_limited_range(smu,
1469 SMU_SOCCLK,
1470 socclk_min,
1471 socclk_max,
1472 false);
1473 if (ret)
1474 return ret;
1475 }
1476
1477 if (vclk_min && vclk_max) {
1478 ret = smu_v14_0_0_set_soft_freq_limited_range(smu,
1479 SMU_VCLK,
1480 vclk_min,
1481 vclk_max,
1482 false);
1483 if (ret)
1484 return ret;
1485 }
1486
1487 if (vclk1_min && vclk1_max) {
1488 ret = smu_v14_0_0_set_soft_freq_limited_range(smu,
1489 SMU_VCLK1,
1490 vclk1_min,
1491 vclk1_max,
1492 false);
1493 if (ret)
1494 return ret;
1495 }
1496
1497 if (dclk_min && dclk_max) {
1498 ret = smu_v14_0_0_set_soft_freq_limited_range(smu,
1499 SMU_DCLK,
1500 dclk_min,
1501 dclk_max,
1502 false);
1503 if (ret)
1504 return ret;
1505 }
1506
1507 if (dclk1_min && dclk1_max) {
1508 ret = smu_v14_0_0_set_soft_freq_limited_range(smu,
1509 SMU_DCLK1,
1510 dclk1_min,
1511 dclk1_max,
1512 false);
1513 if (ret)
1514 return ret;
1515 }
1516
1517 return ret;
1518 }
1519
smu_v14_0_1_set_fine_grain_gfx_freq_parameters(struct smu_context * smu)1520 static int smu_v14_0_1_set_fine_grain_gfx_freq_parameters(struct smu_context *smu)
1521 {
1522 DpmClocks_t_v14_0_1 *clk_table = smu->smu_table.clocks_table;
1523
1524 smu->gfx_default_hard_min_freq = clk_table->MinGfxClk;
1525 smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk;
1526 if (smu->gfx_actual_hard_min_freq == 0)
1527 smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
1528 if (smu->gfx_actual_soft_max_freq == 0)
1529 smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
1530 return 0;
1531 }
1532
smu_v14_0_0_set_fine_grain_gfx_freq_parameters(struct smu_context * smu)1533 static int smu_v14_0_0_set_fine_grain_gfx_freq_parameters(struct smu_context *smu)
1534 {
1535 DpmClocks_t *clk_table = smu->smu_table.clocks_table;
1536
1537 smu->gfx_default_hard_min_freq = clk_table->MinGfxClk;
1538 smu->gfx_default_soft_max_freq = clk_table->MaxGfxClk;
1539 if (smu->gfx_actual_hard_min_freq == 0)
1540 smu->gfx_actual_hard_min_freq = smu->gfx_default_hard_min_freq;
1541 if (smu->gfx_actual_soft_max_freq == 0)
1542 smu->gfx_actual_soft_max_freq = smu->gfx_default_soft_max_freq;
1543
1544 return 0;
1545 }
1546
smu_v14_0_common_set_fine_grain_gfx_freq_parameters(struct smu_context * smu)1547 static int smu_v14_0_common_set_fine_grain_gfx_freq_parameters(struct smu_context *smu)
1548 {
1549 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 1))
1550 smu_v14_0_1_set_fine_grain_gfx_freq_parameters(smu);
1551 else
1552 smu_v14_0_0_set_fine_grain_gfx_freq_parameters(smu);
1553
1554 return 0;
1555 }
1556
smu_v14_0_0_set_vpe_enable(struct smu_context * smu,bool enable)1557 static int smu_v14_0_0_set_vpe_enable(struct smu_context *smu,
1558 bool enable)
1559 {
1560 return smu_cmn_send_smc_msg_with_param(smu, enable ?
1561 SMU_MSG_PowerUpVpe : SMU_MSG_PowerDownVpe,
1562 0, NULL);
1563 }
1564
smu_v14_0_0_set_isp_enable(struct smu_context * smu,bool enable)1565 static int smu_v14_0_0_set_isp_enable(struct smu_context *smu,
1566 bool enable)
1567 {
1568 return smu_cmn_send_smc_msg_with_param(smu, enable ?
1569 SMU_MSG_PowerUpIspByTile : SMU_MSG_PowerDownIspByTile,
1570 ISP_ALL_TILES_MASK, NULL);
1571 }
1572
smu_v14_0_0_set_umsch_mm_enable(struct smu_context * smu,bool enable)1573 static int smu_v14_0_0_set_umsch_mm_enable(struct smu_context *smu,
1574 bool enable)
1575 {
1576 return smu_cmn_send_smc_msg_with_param(smu, enable ?
1577 SMU_MSG_PowerUpUmsch : SMU_MSG_PowerDownUmsch,
1578 0, NULL);
1579 }
1580
smu_14_0_1_get_dpm_table(struct smu_context * smu,struct dpm_clocks * clock_table)1581 static int smu_14_0_1_get_dpm_table(struct smu_context *smu, struct dpm_clocks *clock_table)
1582 {
1583 DpmClocks_t_v14_0_1 *clk_table = smu->smu_table.clocks_table;
1584 uint8_t idx;
1585
1586 /* Only the Clock information of SOC and VPE is copied to provide VPE DPM settings for use. */
1587 for (idx = 0; idx < NUM_SOCCLK_DPM_LEVELS; idx++) {
1588 clock_table->SocClocks[idx].Freq = (idx < clk_table->NumSocClkLevelsEnabled) ? clk_table->SocClocks[idx]:0;
1589 clock_table->SocClocks[idx].Vol = 0;
1590 }
1591
1592 for (idx = 0; idx < NUM_VPE_DPM_LEVELS; idx++) {
1593 clock_table->VPEClocks[idx].Freq = (idx < clk_table->VpeClkLevelsEnabled) ? clk_table->VPEClocks[idx]:0;
1594 clock_table->VPEClocks[idx].Vol = 0;
1595 }
1596
1597 return 0;
1598 }
1599
smu_14_0_0_get_dpm_table(struct smu_context * smu,struct dpm_clocks * clock_table)1600 static int smu_14_0_0_get_dpm_table(struct smu_context *smu, struct dpm_clocks *clock_table)
1601 {
1602 DpmClocks_t *clk_table = smu->smu_table.clocks_table;
1603 uint8_t idx;
1604
1605 /* Only the Clock information of SOC and VPE is copied to provide VPE DPM settings for use. */
1606 for (idx = 0; idx < NUM_SOCCLK_DPM_LEVELS; idx++) {
1607 clock_table->SocClocks[idx].Freq = (idx < clk_table->NumSocClkLevelsEnabled) ? clk_table->SocClocks[idx]:0;
1608 clock_table->SocClocks[idx].Vol = 0;
1609 }
1610
1611 for (idx = 0; idx < NUM_VPE_DPM_LEVELS; idx++) {
1612 clock_table->VPEClocks[idx].Freq = (idx < clk_table->VpeClkLevelsEnabled) ? clk_table->VPEClocks[idx]:0;
1613 clock_table->VPEClocks[idx].Vol = 0;
1614 }
1615
1616 return 0;
1617 }
1618
smu_v14_0_common_get_dpm_table(struct smu_context * smu,struct dpm_clocks * clock_table)1619 static int smu_v14_0_common_get_dpm_table(struct smu_context *smu, struct dpm_clocks *clock_table)
1620 {
1621 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 1))
1622 smu_14_0_1_get_dpm_table(smu, clock_table);
1623 else
1624 smu_14_0_0_get_dpm_table(smu, clock_table);
1625
1626 return 0;
1627 }
1628
smu_v14_0_1_init_mall_power_gating(struct smu_context * smu,enum smu_mall_pg_config pg_config)1629 static int smu_v14_0_1_init_mall_power_gating(struct smu_context *smu, enum smu_mall_pg_config pg_config)
1630 {
1631 struct amdgpu_device *adev = smu->adev;
1632 int ret = 0;
1633
1634 if (pg_config == SMU_MALL_PG_CONFIG_PMFW_CONTROL) {
1635 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_MALLPowerController,
1636 SMU_MALL_PMFW_CONTROL, NULL);
1637 if (ret) {
1638 dev_err(adev->dev, "Init MALL PMFW CONTROL Failure\n");
1639 return ret;
1640 }
1641 } else {
1642 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_MALLPowerController,
1643 SMU_MALL_DRIVER_CONTROL, NULL);
1644 if (ret) {
1645 dev_err(adev->dev, "Init MALL Driver CONTROL Failure\n");
1646 return ret;
1647 }
1648
1649 if (pg_config == SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_ON) {
1650 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_MALLPowerState,
1651 SMU_MALL_EXIT_PG, NULL);
1652 if (ret) {
1653 dev_err(adev->dev, "EXIT MALL PG Failure\n");
1654 return ret;
1655 }
1656 } else if (pg_config == SMU_MALL_PG_CONFIG_DRIVER_CONTROL_ALWAYS_OFF) {
1657 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_MALLPowerState,
1658 SMU_MALL_ENTER_PG, NULL);
1659 if (ret) {
1660 dev_err(adev->dev, "Enter MALL PG Failure\n");
1661 return ret;
1662 }
1663 }
1664 }
1665
1666 return ret;
1667 }
1668
smu_v14_0_common_set_mall_enable(struct smu_context * smu)1669 static int smu_v14_0_common_set_mall_enable(struct smu_context *smu)
1670 {
1671 enum smu_mall_pg_config pg_config = SMU_MALL_PG_CONFIG_DEFAULT;
1672 int ret = 0;
1673
1674 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(14, 0, 1))
1675 ret = smu_v14_0_1_init_mall_power_gating(smu, pg_config);
1676
1677 return ret;
1678 }
1679
smu_v14_0_0_restore_user_od_settings(struct smu_context * smu)1680 static int smu_v14_0_0_restore_user_od_settings(struct smu_context *smu)
1681 {
1682 int ret;
1683
1684 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetHardMinGfxClk,
1685 smu->gfx_actual_hard_min_freq,
1686 NULL);
1687 if (ret) {
1688 dev_err(smu->adev->dev, "Failed to restore hard min sclk!\n");
1689 return ret;
1690 }
1691
1692 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
1693 smu->gfx_actual_soft_max_freq,
1694 NULL);
1695 if (ret) {
1696 dev_err(smu->adev->dev, "Failed to restore soft max sclk!\n");
1697 return ret;
1698 }
1699
1700 return 0;
1701 }
1702
1703 /*
1704 * Link any xHCI controller sharing the GPU's PCIe root port as a consumer
1705 * of the GPU so the GPU resumes first, avoiding an xHCI resume race.
1706 */
smu_v14_0_0_set_power_dep(struct smu_context * smu,bool enable)1707 static int smu_v14_0_0_set_power_dep(struct smu_context *smu, bool enable)
1708 {
1709 struct amdgpu_device *adev = smu->adev;
1710 struct pci_dev *gpu_pdev = adev->pdev;
1711 struct pci_dev *root_port, *usb_pdev = NULL;
1712 struct device_link *link;
1713
1714 if (!enable) {
1715 if (smu->usb_power_link) {
1716 device_link_del(smu->usb_power_link);
1717 smu->usb_power_link = NULL;
1718 }
1719 return 0;
1720 }
1721
1722 root_port = pcie_find_root_port(gpu_pdev);
1723 while ((usb_pdev = pci_get_class(PCI_CLASS_SERIAL_USB_XHCI, usb_pdev))) {
1724 struct pci_dev *usb_root;
1725
1726 usb_root = pcie_find_root_port(usb_pdev);
1727 if (usb_root != root_port)
1728 continue;
1729
1730 /* Create device link: USB (consumer) depends on GPU (supplier) */
1731 link = device_link_add(&usb_pdev->dev, &gpu_pdev->dev,
1732 DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME);
1733 if (link) {
1734 smu->usb_power_link = link;
1735 drm_info(adev_to_drm(adev), "USB controller %s D0 power state depends on %s\n",
1736 pci_name(usb_pdev), pci_name(gpu_pdev));
1737 /* Only create one link for the first USB controller found */
1738 break;
1739 }
1740 }
1741
1742 pci_dev_put(usb_pdev);
1743
1744 return 0;
1745 }
1746
1747 static const struct pptable_funcs smu_v14_0_0_ppt_funcs = {
1748 .check_fw_status = smu_v14_0_check_fw_status,
1749 .check_fw_version = smu_cmn_check_fw_version,
1750 .init_smc_tables = smu_v14_0_0_init_smc_tables,
1751 .fini_smc_tables = smu_v14_0_0_fini_smc_tables,
1752 .get_vbios_bootup_values = smu_v14_0_get_vbios_bootup_values,
1753 .system_features_control = smu_v14_0_0_system_features_control,
1754 .dpm_set_vcn_enable = smu_v14_0_set_vcn_enable,
1755 .dpm_set_jpeg_enable = smu_v14_0_set_jpeg_enable,
1756 .set_default_dpm_table = smu_v14_0_set_default_dpm_tables,
1757 .read_sensor = smu_v14_0_0_read_sensor,
1758 .is_dpm_running = smu_v14_0_0_is_dpm_running,
1759 .set_watermarks_table = smu_v14_0_0_set_watermarks_table,
1760 .get_gpu_metrics = smu_v14_0_0_get_gpu_metrics,
1761 .get_enabled_mask = smu_cmn_get_enabled_mask,
1762 .get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
1763 .set_driver_table_location = smu_v14_0_set_driver_table_location,
1764 .gfx_off_control = smu_v14_0_gfx_off_control,
1765 .mode2_reset = smu_v14_0_0_mode2_reset,
1766 .get_dpm_ultimate_freq = smu_v14_0_common_get_dpm_ultimate_freq,
1767 .set_soft_freq_limited_range = smu_v14_0_0_set_soft_freq_limited_range,
1768 .restore_user_od_settings = smu_v14_0_0_restore_user_od_settings,
1769 .od_edit_dpm_table = smu_v14_0_od_edit_dpm_table,
1770 .emit_clk_levels = smu_v14_0_0_emit_clk_levels,
1771 .force_clk_levels = smu_v14_0_0_force_clk_levels,
1772 .set_performance_level = smu_v14_0_common_set_performance_level,
1773 .set_fine_grain_gfx_freq_parameters = smu_v14_0_common_set_fine_grain_gfx_freq_parameters,
1774 .set_gfx_power_up_by_imu = smu_v14_0_set_gfx_power_up_by_imu,
1775 .dpm_set_vpe_enable = smu_v14_0_0_set_vpe_enable,
1776 .dpm_set_isp_enable = smu_v14_0_0_set_isp_enable,
1777 .dpm_set_umsch_mm_enable = smu_v14_0_0_set_umsch_mm_enable,
1778 .get_dpm_clock_table = smu_v14_0_common_get_dpm_table,
1779 .set_mall_enable = smu_v14_0_common_set_mall_enable,
1780 .set_power_dep = smu_v14_0_0_set_power_dep,
1781 };
1782
smu_v14_0_0_init_msg_ctl(struct smu_context * smu)1783 static void smu_v14_0_0_init_msg_ctl(struct smu_context *smu)
1784 {
1785 struct amdgpu_device *adev = smu->adev;
1786 struct smu_msg_ctl *ctl = &smu->msg_ctl;
1787
1788 ctl->smu = smu;
1789 mutex_init(&ctl->lock);
1790 ctl->config.msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_66);
1791 ctl->config.resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_90);
1792 ctl->config.arg_regs[0] = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_82);
1793 ctl->config.num_arg_regs = 1;
1794 ctl->ops = &smu_msg_v1_ops;
1795 ctl->default_timeout = adev->usec_timeout * 20;
1796 ctl->message_map = smu_v14_0_0_message_map;
1797 }
1798
smu_v14_0_0_set_ppt_funcs(struct smu_context * smu)1799 void smu_v14_0_0_set_ppt_funcs(struct smu_context *smu)
1800 {
1801 struct amdgpu_device *adev = smu->adev;
1802
1803 smu->ppt_funcs = &smu_v14_0_0_ppt_funcs;
1804 smu->feature_map = smu_v14_0_0_feature_mask_map;
1805 smu->table_map = smu_v14_0_0_table_map;
1806 smu->is_apu = true;
1807
1808 switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
1809 case IP_VERSION(14, 0, 0):
1810 case IP_VERSION(14, 0, 4):
1811 case IP_VERSION(14, 0, 5):
1812 smu->smc_driver_if_version = SMU14_DRIVER_IF_VERSION_SMU_V14_0_0;
1813 break;
1814 case IP_VERSION(14, 0, 1):
1815 smu->smc_driver_if_version = SMU14_DRIVER_IF_VERSION_SMU_V14_0_1;
1816 break;
1817 }
1818
1819 smu_v14_0_0_init_msg_ctl(smu);
1820 }
1821