xref: /linux/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_0_ppt.c (revision fab183d632628381b466a41479489541ac0e29a0)
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