xref: /linux/drivers/gpu/drm/amd/pm/swsmu/smu15/smu_v15_0_8_ppt.c (revision 1fc5a74b108fc90951890ec513ac81869f5eaff1)
1 /*
2  * Copyright 2025 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 #define SWSMU_CODE_LAYER_L2
25 
26 #include <linux/firmware.h>
27 #include "amdgpu.h"
28 #include "amdgpu_smu.h"
29 #include "smu_v15_0_8_pmfw.h"
30 #include "smu15_driver_if_v15_0_8.h"
31 #include "smu_v15_0_8_ppsmc.h"
32 #include "smu_v15_0_8_ppt.h"
33 #include <linux/pci.h>
34 #include "smu_cmn.h"
35 #include "mp/mp_15_0_8_offset.h"
36 #include "mp/mp_15_0_8_sh_mask.h"
37 #include "smu_v15_0.h"
38 #include "amdgpu_fru_eeprom.h"
39 
40 #undef MP1_Public
41 
42 /* address block */
43 #define MP1_Public 			0x03b00000
44 #define smnMP1_FIRMWARE_FLAGS_15_0_8 	0x3010024
45 /*
46  * DO NOT use these for err/warn/info/debug messages.
47  * Use dev_err, dev_warn, dev_info and dev_dbg instead.
48  * They are more MGPU friendly.
49  */
50 #undef pr_err
51 #undef pr_warn
52 #undef pr_info
53 #undef pr_debug
54 
55 #define SMUQ10_TO_UINT(x) ((x) >> 10)
56 #define SMUQ10_FRAC(x) ((x) & 0x3ff)
57 #define SMUQ10_ROUND(x) ((SMUQ10_TO_UINT(x)) + ((SMUQ10_FRAC(x)) >= 0x200))
58 /* Convert Q10 watts to milliwatts, preserving the fractional part */
59 #define SMUQ10_TO_MILLIWATT(x) (SMUQ10_TO_UINT(x) * MILLIWATT_PER_WATT + \
60 				((SMUQ10_FRAC(x) * MILLIWATT_PER_WATT) >> 10))
61 /* Convert Q10 degrees Celsius to millidegrees, preserving the fractional part */
62 #define SMUQ10_TO_MILLICELSIUS(x) \
63 	(SMUQ10_TO_UINT(x) * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES + \
64 	 ((SMUQ10_FRAC(x) * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES) >> 10))
65 
66 #define hbm_stack_mask_valid(umc_mask) \
67 	(((umc_mask) & 0xF) == 0xF)
68 
69 #define for_each_hbm_stack(stack_idx, umc_mask) \
70 	for ((stack_idx) = 0; (umc_mask); \
71 	     (umc_mask) >>= 4, (stack_idx)++) \
72 
73 #define NUM_JPEG_RINGS_FW	10
74 
75 #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c))
76 
77 #define SMU_15_0_8_FEA_MAP(smu_feature, smu_15_0_8_feature)                    \
78 	[smu_feature] = { 1, (smu_15_0_8_feature) }
79 
80 #define FEATURE_MASK(feature) (1ULL << feature)
81 
82 static int smu_v15_0_8_init_ppt_limits(struct smu_context *smu);
83 
84 static const struct smu_feature_bits smu_v15_0_8_dpm_features = {
85 	.bits = { SMU_FEATURE_BIT_INIT(FEATURE_ID_DATA_CALCULATION),
86 		  SMU_FEATURE_BIT_INIT(FEATURE_ID_DPM_GFXCLK),
87 		  SMU_FEATURE_BIT_INIT(FEATURE_ID_DPM_UCLK),
88 		  SMU_FEATURE_BIT_INIT(FEATURE_ID_DPM_FCLK),
89 		  SMU_FEATURE_BIT_INIT(FEATURE_ID_DPM_GL2CLK) }
90 };
91 
92 static const struct cmn2asic_msg_mapping smu_v15_0_8_message_map[SMU_MSG_MAX_COUNT] = {
93 	MSG_MAP(TestMessage,			     PPSMC_MSG_TestMessage,			0),
94 	MSG_MAP(GetSmuVersion,			     PPSMC_MSG_GetSmuVersion,			1),
95 	MSG_MAP(GfxDeviceDriverReset,		     PPSMC_MSG_GfxDriverReset,			SMU_MSG_RAS_PRI | SMU_MSG_NO_PRECHECK),
96 	MSG_MAP(GetDriverIfVersion,		     PPSMC_MSG_GetDriverIfVersion,		1),
97 	MSG_MAP(EnableAllSmuFeatures,		     PPSMC_MSG_EnableAllSmuFeatures,		0),
98 	MSG_MAP(GetMetricsVersion,		     PPSMC_MSG_GetMetricsVersion,		1),
99 	MSG_MAP(GetMetricsTable,		     PPSMC_MSG_GetMetricsTable,			1),
100 	MSG_MAP(GetEnabledSmuFeatures,	     	     PPSMC_MSG_GetEnabledSmuFeatures,		1),
101 	MSG_MAP(SetDriverDramAddr,		     PPSMC_MSG_SetDriverDramAddr,		1),
102 	MSG_MAP(SetToolsDramAddr,		     PPSMC_MSG_SetToolsDramAddr,		0),
103 	MSG_MAP(SetSoftMaxByFreq,		     PPSMC_MSG_SetSoftMaxByFreq,		1),
104 	MSG_MAP(SetPptLimit,			     PPSMC_MSG_SetPptLimit,			0),
105 	MSG_MAP(GetPptLimit,			     PPSMC_MSG_GetPptLimit,			1),
106 	MSG_MAP(DramLogSetDramAddr,		     PPSMC_MSG_DramLogSetDramAddr,		0),
107 	MSG_MAP(HeavySBR,		     	     PPSMC_MSG_HeavySBR,			0),
108 	MSG_MAP(DFCstateControl,		     PPSMC_MSG_DFCstateControl,			0),
109 	MSG_MAP(GfxDriverResetRecovery,		     PPSMC_MSG_GfxDriverResetRecovery,		0),
110 	MSG_MAP(SetSoftMinGfxclk,                    PPSMC_MSG_SetSoftMinGfxClk,                1),
111 	MSG_MAP(SetSoftMaxGfxClk,                    PPSMC_MSG_SetSoftMaxGfxClk,                1),
112 	MSG_MAP(PrepareMp1ForUnload,                 PPSMC_MSG_PrepareForDriverUnload,          0),
113 	MSG_MAP(QueryValidMcaCount,                  PPSMC_MSG_QueryValidMcaCount,              SMU_MSG_RAS_PRI),
114 	MSG_MAP(McaBankDumpDW,                       PPSMC_MSG_McaBankDumpDW,                   SMU_MSG_RAS_PRI),
115 	MSG_MAP(ClearMcaOnRead,	                     PPSMC_MSG_ClearMcaOnRead,                  0),
116 	MSG_MAP(QueryValidMcaCeCount,                PPSMC_MSG_QueryValidMcaCeCount,            SMU_MSG_RAS_PRI),
117 	MSG_MAP(McaBankCeDumpDW,                     PPSMC_MSG_McaBankCeDumpDW,                 SMU_MSG_RAS_PRI),
118 	MSG_MAP(SelectPLPDMode,                      PPSMC_MSG_SelectPLPDMode,                  0),
119 	MSG_MAP(SetThrottlingPolicy,                 PPSMC_MSG_SetThrottlingPolicy,             0),
120 	MSG_MAP(ResetSDMA,                           PPSMC_MSG_ResetSDMA,                       0),
121 	MSG_MAP(GetRASTableVersion,                  PPSMC_MSG_GetRasTableVersion,              0),
122 	MSG_MAP(SetTimestamp,                        PPSMC_MSG_SetTimestamp,                    0),
123 	MSG_MAP(GetTimestamp,                        PPSMC_MSG_GetTimestamp,                    0),
124 	MSG_MAP(GetBadPageIpid,                      PPSMC_MSG_GetBadPageIpIdLoHi,              0),
125 	MSG_MAP(EraseRasTable,                       PPSMC_MSG_EraseRasTable,                   0),
126 	MSG_MAP(GetStaticMetricsTable,               PPSMC_MSG_GetStaticMetricsTable,		1),
127 	MSG_MAP(GetSystemMetricsTable,               PPSMC_MSG_GetSystemMetricsTable,           1),
128 	MSG_MAP(GetSystemMetricsVersion,             PPSMC_MSG_GetSystemMetricsVersion,		0),
129 	MSG_MAP(ResetVCN,                            PPSMC_MSG_ResetVCN,                        0),
130 	MSG_MAP(SetFastPptLimit,                     PPSMC_MSG_SetFastPptLimit,			0),
131 	MSG_MAP(GetFastPptLimit,                     PPSMC_MSG_GetFastPptLimit,			0),
132 	MSG_MAP(SetSoftMinGl2clk,                    PPSMC_MSG_SetSoftMinGl2clk,		0),
133 	MSG_MAP(SetSoftMaxGl2clk,                    PPSMC_MSG_SetSoftMaxGl2clk,		0),
134 	MSG_MAP(SetSoftMinFclk,                      PPSMC_MSG_SetSoftMinFclk,			0),
135 	MSG_MAP(SetSoftMaxFclk,                      PPSMC_MSG_SetSoftMaxFclk,			0),
136 };
137 
138 /* TODO: Update the clk map once enum PPCLK is updated in smu15_driver_if_v15_0_8.h */
139 static struct cmn2asic_mapping smu_v15_0_8_clk_map[SMU_CLK_COUNT] = {
140 	CLK_MAP(UCLK,		PPCLK_UCLK),
141 };
142 
143 static const struct cmn2asic_mapping smu_v15_0_8_feature_mask_map[SMU_FEATURE_COUNT] = {
144 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DATA_CALCULATIONS_BIT, 		FEATURE_ID_DATA_CALCULATION),
145 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DPM_GFXCLK_BIT, 			FEATURE_ID_DPM_GFXCLK),
146 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DPM_UCLK_BIT,                    FEATURE_ID_DPM_UCLK),
147 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DPM_FCLK_BIT, 			FEATURE_ID_DPM_FCLK),
148 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DPM_GL2CLK_BIT, 			FEATURE_ID_DPM_GL2CLK),
149 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_GFXCLK_BIT, 			FEATURE_ID_DS_GFXCLK),
150 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_SOCCLK_BIT, 			FEATURE_ID_DS_SOCCLK),
151 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_LCLK_BIT, 			FEATURE_ID_DS_LCLK),
152 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_FCLK_BIT, 			FEATURE_ID_DS_FCLK),
153 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_DMABECLK_BIT, 		FEATURE_ID_DS_DMABECLK),
154 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_MPIFOECLK_BIT, 		FEATURE_ID_DS_MPIFOECLK),
155 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_MPRASCLK_BIT, 		FEATURE_ID_DS_MPRASCLK),
156 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_MPNHTCLK_BIT, 		FEATURE_ID_DS_MPNHTCLK),
157 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_FIOCLK_BIT, 			FEATURE_ID_DS_FIOCLK),
158 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_DXIOCLK_BIT, 			FEATURE_ID_DS_DXIOCLK),
159 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_GL2CLK_BIT, 			FEATURE_ID_DS_GL2CLK),
160 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_PPT_BIT, 			FEATURE_ID_PPT),
161 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_TDC_BIT, 			FEATURE_ID_TDC),
162 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_MP1_CG_BIT, 			FEATURE_ID_SMU_CG),
163 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_FW_CTF_BIT, 			FEATURE_ID_FW_CTF),
164 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_THERMAL_BIT, 			FEATURE_ID_THERMAL),
165 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_SOC_PCC_BIT, 			FEATURE_ID_SOC_PCC),
166 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_XGMI_PER_LINK_PWR_DWN_BIT,	FEATURE_ID_XGMI_PER_LINK_PWR_DOWN),
167 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_VCN_BIT,			FEATURE_ID_DS_VCN),
168 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_MP1CLK_BIT,			FEATURE_ID_DS_MP1CLK),
169 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_MPIOCLK_BIT,			FEATURE_ID_DS_MPIOCLK),
170 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_DS_MP0CLK_BIT,			FEATURE_ID_DS_MP0CLK),
171 	SMU_15_0_8_FEA_MAP(SMU_FEATURE_PIT_BIT,				FEATURE_ID_PIT),
172 };
173 
174 #define TABLE_PMSTATUSLOG             0
175 #define TABLE_SMU_METRICS             1
176 #define TABLE_I2C_COMMANDS            2
177 #define TABLE_COUNT                   3
178 
179 static const struct cmn2asic_mapping smu_v15_0_8_table_map[SMU_TABLE_COUNT] = {
180 	TAB_MAP(PMSTATUSLOG),
181 	TAB_MAP(SMU_METRICS),
182 	TAB_MAP(I2C_COMMANDS),
183 };
184 
185 static const uint8_t smu_v15_0_8_throttler_map[] = {
186 	[THROTTLER_PROCHOT_BIT] = (SMU_THROTTLER_PROCHOT_GFX_BIT),
187 	[THROTTLER_THERMAL_SOCKET_BIT] = (SMU_THROTTLER_TEMP_GPU_BIT),
188 	[THROTTLER_THERMAL_VR_BIT] = (SMU_THROTTLER_TEMP_VR_GFX_BIT),
189 	[THROTTLER_THERMAL_HBM_BIT] = (SMU_THROTTLER_TEMP_MEM_BIT),
190 };
191 
smu_v15_0_8_get_system_metrics_size(void)192 static size_t smu_v15_0_8_get_system_metrics_size(void)
193 {
194 	return sizeof(SystemMetricsTable_t);
195 }
196 
smu_v15_0_8_tables_init(struct smu_context * smu)197 static int smu_v15_0_8_tables_init(struct smu_context *smu)
198 {
199 	struct smu_v15_0_8_baseboard_temp_metrics *baseboard_temp_metrics;
200 	struct smu_v15_0_8_gpuboard_temp_metrics *gpuboard_temp_metrics;
201 	struct smu_table_context *smu_table = &smu->smu_table;
202 	int ret, gpu_metrcs_size = sizeof(MetricsTable_t);
203 	struct smu_table *tables = smu_table->tables;
204 	struct smu_v15_0_8_gpu_metrics *gpu_metrics;
205 	void *driver_pptable __free(kfree) = NULL;
206 	void *metrics_table __free(kfree) = NULL;
207 
208 	SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU15_TOOL_SIZE,
209 		       PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
210 
211 	SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS,
212 		       gpu_metrcs_size,
213 		       PAGE_SIZE,
214 		       AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT);
215 	SMU_TABLE_INIT(tables, SMU_TABLE_PMFW_SYSTEM_METRICS,
216 		       smu_v15_0_8_get_system_metrics_size(), PAGE_SIZE,
217 		       AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT);
218 
219 	metrics_table = kzalloc(gpu_metrcs_size, GFP_KERNEL);
220 	if (!metrics_table)
221 		return -ENOMEM;
222 
223 	smu_table->metrics_time = 0;
224 
225 	driver_pptable = kzalloc_obj(PPTable_t);
226 	if (!driver_pptable)
227 		return -ENOMEM;
228 
229 	ret = smu_driver_table_init(smu, SMU_DRIVER_TABLE_GPU_METRICS,
230 				    sizeof(struct smu_v15_0_8_gpu_metrics),
231 				    SMU_GPU_METRICS_CACHE_INTERVAL);
232 	if (ret)
233 		return ret;
234 
235 	gpu_metrics = (struct smu_v15_0_8_gpu_metrics *)smu_driver_table_ptr(smu,
236 		       SMU_DRIVER_TABLE_GPU_METRICS);
237 	smu_v15_0_8_gpu_metrics_init(gpu_metrics, 1, 9);
238 
239 	ret = smu_table_cache_init(smu, SMU_TABLE_PMFW_SYSTEM_METRICS,
240 				   smu_v15_0_8_get_system_metrics_size(), 5);
241 
242 	if (ret)
243 		return ret;
244 
245 	/* Initialize base board temperature metrics */
246 	ret = smu_driver_table_init(smu,
247 				    SMU_DRIVER_TABLE_BASEBOARD_TEMP_METRICS,
248 				    sizeof(*baseboard_temp_metrics), 50);
249 	if (ret)
250 		return ret;
251 	baseboard_temp_metrics = (struct smu_v15_0_8_baseboard_temp_metrics *)
252 		smu_driver_table_ptr(smu,
253 				     SMU_DRIVER_TABLE_BASEBOARD_TEMP_METRICS);
254 	smu_v15_0_8_baseboard_temp_metrics_init(baseboard_temp_metrics, 1, 1);
255 	/* Initialize GPU board temperature metrics */
256 	ret = smu_driver_table_init(smu, SMU_DRIVER_TABLE_GPUBOARD_TEMP_METRICS,
257 				    sizeof(*gpuboard_temp_metrics), 50);
258 	if (ret) {
259 		smu_table_cache_fini(smu, SMU_TABLE_PMFW_SYSTEM_METRICS);
260 		smu_driver_table_fini(smu,
261 				      SMU_DRIVER_TABLE_BASEBOARD_TEMP_METRICS);
262 		return ret;
263 	}
264 	gpuboard_temp_metrics = (struct smu_v15_0_8_gpuboard_temp_metrics *)
265 		smu_driver_table_ptr(smu,
266 				     SMU_DRIVER_TABLE_GPUBOARD_TEMP_METRICS);
267 	smu_v15_0_8_gpuboard_temp_metrics_init(gpuboard_temp_metrics, 1, 1);
268 
269 	smu_table->metrics_table = no_free_ptr(metrics_table);
270 	smu_table->driver_pptable = no_free_ptr(driver_pptable);
271 
272 	mutex_init(&smu_table->metrics_lock);
273 
274 	return 0;
275 }
276 
smu_v15_0_8_allocate_dpm_context(struct smu_context * smu)277 static int smu_v15_0_8_allocate_dpm_context(struct smu_context *smu)
278 {
279 	struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
280 
281 	smu_dpm->dpm_context =
282 		kzalloc(sizeof(struct smu_15_0_dpm_context), GFP_KERNEL);
283 	if (!smu_dpm->dpm_context)
284 		return -ENOMEM;
285 	smu_dpm->dpm_context_size = sizeof(struct smu_15_0_dpm_context);
286 
287 	smu_dpm->dpm_policies =
288 		kzalloc(sizeof(struct smu_dpm_policy_ctxt), GFP_KERNEL);
289 	if (!smu_dpm->dpm_policies) {
290 		kfree(smu_dpm->dpm_context);
291 		return -ENOMEM;
292 	}
293 
294 	return 0;
295 }
296 
smu_v15_0_8_init_smc_tables(struct smu_context * smu)297 static int smu_v15_0_8_init_smc_tables(struct smu_context *smu)
298 {
299 	int ret = 0;
300 
301 	ret = smu_v15_0_8_tables_init(smu);
302 	if (ret)
303 		return ret;
304 
305 	ret = smu_v15_0_8_allocate_dpm_context(smu);
306 
307 	return ret;
308 }
309 
smu_v15_0_8_tables_fini(struct smu_context * smu)310 static int smu_v15_0_8_tables_fini(struct smu_context *smu)
311 {
312 	struct smu_table_context *smu_table = &smu->smu_table;
313 
314 	smu_driver_table_fini(smu, SMU_DRIVER_TABLE_BASEBOARD_TEMP_METRICS);
315 	smu_driver_table_fini(smu, SMU_DRIVER_TABLE_GPUBOARD_TEMP_METRICS);
316 	smu_table_cache_fini(smu, SMU_TABLE_PMFW_SYSTEM_METRICS);
317 	mutex_destroy(&smu_table->metrics_lock);
318 
319 	return 0;
320 }
321 
smu_v15_0_8_fini_smc_tables(struct smu_context * smu)322 static int smu_v15_0_8_fini_smc_tables(struct smu_context *smu)
323 {
324 	int ret;
325 
326 	ret = smu_v15_0_8_tables_fini(smu);
327 	if (ret)
328 		return ret;
329 
330 	ret = smu_v15_0_fini_smc_tables(smu);
331 	if (ret)
332 		return ret;
333 
334 	return ret;
335 }
336 
smu_v15_0_8_init_allowed_features(struct smu_context * smu)337 static int smu_v15_0_8_init_allowed_features(struct smu_context *smu)
338 {
339 	/* pptable will handle the features to enable */
340 	smu_feature_list_set_all(smu, SMU_FEATURE_LIST_ALLOWED);
341 
342 	return 0;
343 }
344 
smu_v15_0_8_get_metrics_table_internal(struct smu_context * smu,uint32_t tmo,void * data)345 static int smu_v15_0_8_get_metrics_table_internal(struct smu_context *smu, uint32_t tmo, void *data)
346 {
347 	struct smu_table_context *smu_table = &smu->smu_table;
348 	uint32_t table_size = smu_table->tables[SMU_TABLE_SMU_METRICS].size;
349 	struct smu_table *table = &smu_table->driver_table;
350 	struct amdgpu_device *adev = smu->adev;
351 
352 	mutex_lock(&smu_table->metrics_lock);
353 
354 	if (!tmo || !smu_table->metrics_time ||
355 	    time_after(jiffies, smu_table->metrics_time + msecs_to_jiffies(tmo))) {
356 		int ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetMetricsTable, NULL);
357 		if (ret) {
358 			dev_info(adev->dev,
359 				 "Failed to export SMU metrics table!\n");
360 			mutex_unlock(&smu_table->metrics_lock);
361 			return ret;
362 		}
363 
364 		amdgpu_device_invalidate_hdp(smu->adev, NULL);
365 		ret = smu_cmn_vram_cpy(smu, smu_table->metrics_table,
366 				       table->cpu_addr, table_size);
367 		if (ret) {
368 			mutex_unlock(&smu_table->metrics_lock);
369 			return ret;
370 		}
371 
372 		smu_table->metrics_time = jiffies;
373 	}
374 
375 	if (data)
376 		memcpy(data, smu_table->metrics_table, table_size);
377 	mutex_unlock(&smu_table->metrics_lock);
378 	return 0;
379 }
380 
smu_v15_0_8_get_smu_metrics_data(struct smu_context * smu,MetricsMember_t member,uint32_t * value)381 static int smu_v15_0_8_get_smu_metrics_data(struct smu_context *smu,
382 					    MetricsMember_t member, uint32_t *value)
383 {
384 	struct smu_table_context *smu_table = &smu->smu_table;
385 	MetricsTable_t *metrics = (MetricsTable_t *)smu_table->metrics_table;
386 	struct amdgpu_device *adev = smu->adev;
387 	int ret, xcc_id;
388 
389 	ret = smu_v15_0_8_get_metrics_table_internal(smu, 10, NULL);
390 	if (ret)
391 		return ret;
392 
393 	switch (member) {
394 	case METRICS_CURR_GFXCLK:
395 	case METRICS_AVERAGE_GFXCLK:
396 			xcc_id = GET_INST(GC, 0);
397 			*value = SMUQ10_ROUND(metrics->GfxclkFrequency[xcc_id]);
398 		break;
399 	case METRICS_CURR_SOCCLK:
400 	case METRICS_AVERAGE_SOCCLK:
401 		*value = SMUQ10_ROUND(metrics->SocclkFrequency[0]);
402 		break;
403 	case METRICS_CURR_UCLK:
404 	case METRICS_AVERAGE_UCLK:
405 		*value = SMUQ10_ROUND(metrics->UclkFrequency[0]);
406 		break;
407 	case METRICS_CURR_VCLK:
408 		*value = SMUQ10_ROUND(metrics->VclkFrequency[0]);
409 		break;
410 	case METRICS_CURR_DCLK:
411 		*value = SMUQ10_ROUND(metrics->DclkFrequency[0]);
412 		break;
413 	case METRICS_CURR_FCLK:
414 		*value = SMUQ10_ROUND(metrics->FclkFrequency[0]);
415 		break;
416 	case METRICS_AVERAGE_GFXACTIVITY:
417 		*value = SMUQ10_ROUND(metrics->SocketGfxBusy);
418 		break;
419 	case METRICS_AVERAGE_MEMACTIVITY:
420 		*value = SMUQ10_ROUND(metrics->DramBandwidthUtilization);
421 		break;
422 	case METRICS_CURR_SOCKETPOWER:
423 		*value = SMUQ10_TO_MILLIWATT(metrics->SocketPower);
424 		break;
425 	case METRICS_TEMPERATURE_HOTSPOT:
426 		*value = SMUQ10_TO_MILLICELSIUS(metrics->MaxSocketTemperature);
427 		break;
428 	case METRICS_TEMPERATURE_MEM:
429 	{
430 		struct amdgpu_device *adev = smu->adev;
431 		u32 max_hbm_temp = 0;
432 
433 		/* Find max temperature across all HBM stacks */
434 		if (adev->umc.active_mask) {
435 			u64 mask = adev->umc.active_mask;
436 			int stack_idx;
437 
438 			for_each_hbm_stack(stack_idx, mask) {
439 				u32 temp;
440 
441 				if (!hbm_stack_mask_valid(mask))
442 					continue;
443 
444 				temp = metrics->HbmTemperature[stack_idx];
445 				if (temp > max_hbm_temp)
446 					max_hbm_temp = temp;
447 			}
448 		}
449 		*value = SMUQ10_TO_MILLICELSIUS(max_hbm_temp);
450 		break;
451 	}
452 	/* This is the max of all VRs and not just SOC VR.
453 	 */
454 	case METRICS_TEMPERATURE_VRSOC:
455 		*value = SMUQ10_TO_MILLICELSIUS(metrics->MaxVrTemperature);
456 		break;
457 	default:
458 		*value = UINT_MAX;
459 		break;
460 	}
461 
462 	return 0;
463 }
464 
smu_v15_0_8_get_current_clk_freq_by_table(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t * value)465 static int smu_v15_0_8_get_current_clk_freq_by_table(struct smu_context *smu,
466 						     enum smu_clk_type clk_type,
467 						     uint32_t *value)
468 {
469 	MetricsMember_t member_type;
470 
471 	if (!value)
472 		return -EINVAL;
473 
474 	switch (clk_type) {
475 	case SMU_GFXCLK:
476 	case SMU_SCLK:
477 		member_type = METRICS_CURR_GFXCLK;
478 		break;
479 	case SMU_UCLK:
480 	case SMU_MCLK:
481 		member_type = METRICS_CURR_UCLK;
482 		break;
483 	case SMU_SOCCLK:
484 		member_type = METRICS_CURR_SOCCLK;
485 		break;
486 	case SMU_VCLK:
487 		member_type = METRICS_CURR_VCLK;
488 		break;
489 	case SMU_DCLK:
490 		member_type = METRICS_CURR_DCLK;
491 		break;
492 	case SMU_FCLK:
493 		member_type = METRICS_CURR_FCLK;
494 		break;
495 	default:
496 		return -EINVAL;
497 	}
498 
499 	return smu_v15_0_8_get_smu_metrics_data(smu, member_type, value);
500 }
501 
smu_v15_0_8_get_current_activity_percent(struct smu_context * smu,enum amd_pp_sensors sensor,uint32_t * value)502 static int smu_v15_0_8_get_current_activity_percent(struct smu_context *smu,
503 						    enum amd_pp_sensors sensor,
504 						    uint32_t *value)
505 {
506 	int ret = 0;
507 
508 	if (!value)
509 		return -EINVAL;
510 
511 	switch (sensor) {
512 	case AMDGPU_PP_SENSOR_GPU_LOAD:
513 		ret = smu_v15_0_8_get_smu_metrics_data(smu,
514 						       METRICS_AVERAGE_GFXACTIVITY, value);
515 		break;
516 	case AMDGPU_PP_SENSOR_MEM_LOAD:
517 		ret = smu_v15_0_8_get_smu_metrics_data(smu,
518 						       METRICS_AVERAGE_MEMACTIVITY, value);
519 		break;
520 	default:
521 		dev_err(smu->adev->dev,
522 			"Invalid sensor for retrieving clock activity\n");
523 		return -EINVAL;
524 	}
525 
526 	return ret;
527 }
528 
smu_v15_0_8_thermal_get_temperature(struct smu_context * smu,enum amd_pp_sensors sensor,uint32_t * value)529 static int smu_v15_0_8_thermal_get_temperature(struct smu_context *smu,
530 					       enum amd_pp_sensors sensor,
531 					       uint32_t *value)
532 {
533 	int ret = 0;
534 
535 	if (!value)
536 		return -EINVAL;
537 
538 	switch (sensor) {
539 	case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
540 		ret = smu_v15_0_8_get_smu_metrics_data(smu,
541 						       METRICS_TEMPERATURE_HOTSPOT, value);
542 		break;
543 	case AMDGPU_PP_SENSOR_MEM_TEMP:
544 		ret = smu_v15_0_8_get_smu_metrics_data(smu,
545 						       METRICS_TEMPERATURE_MEM, value);
546 		break;
547 	default:
548 		dev_err(smu->adev->dev, "Invalid sensor for retrieving temp\n");
549 		return -EINVAL;
550 	}
551 
552 	return ret;
553 }
554 
smu_v15_0_8_get_system_metrics_table(struct smu_context * smu)555 static int smu_v15_0_8_get_system_metrics_table(struct smu_context *smu)
556 {
557 	struct smu_table_context *smu_table = &smu->smu_table;
558 	struct smu_table *table = &smu_table->driver_table;
559 	struct smu_table *tables = smu_table->tables;
560 	struct smu_table *sys_table;
561 	int ret;
562 
563 	sys_table = &tables[SMU_TABLE_PMFW_SYSTEM_METRICS];
564 	if (smu_table_cache_is_valid(sys_table))
565 		return 0;
566 
567 	ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetSystemMetricsTable, NULL);
568 	if (ret) {
569 		dev_info(smu->adev->dev,
570 			 "Failed to export system metrics table!\n");
571 		return ret;
572 	}
573 
574 	amdgpu_hdp_invalidate(smu->adev, NULL);
575 
576 	ret = smu_cmn_vram_cpy(smu, sys_table->cache.buffer,
577 			       table->cpu_addr,
578 			       sizeof(SystemMetricsTable_t));
579 	if (ret)
580 		return ret;
581 
582 	smu_table_cache_update_time(sys_table, jiffies);
583 
584 	return 0;
585 }
586 
smu_v15_0_8_get_npm_data(struct smu_context * smu,enum amd_pp_sensors sensor,uint32_t * value)587 static int smu_v15_0_8_get_npm_data(struct smu_context *smu,
588 				    enum amd_pp_sensors sensor,
589 				    uint32_t *value)
590 {
591 	struct smu_table_context *smu_table = &smu->smu_table;
592 	struct smu_table *tables = smu_table->tables;
593 	SystemMetricsTable_t *metrics;
594 	struct smu_table *sys_table;
595 	int ret;
596 
597 	if (sensor == AMDGPU_PP_SENSOR_MAXNODEPOWERLIMIT) {
598 		/*TBD as of now put 0 */
599 		*value = 0;
600 		return 0;
601 	}
602 
603 	ret = smu_v15_0_8_get_system_metrics_table(smu);
604 	if (ret)
605 		return ret;
606 
607 	sys_table = &tables[SMU_TABLE_PMFW_SYSTEM_METRICS];
608 	metrics = (SystemMetricsTable_t *)sys_table->cache.buffer;
609 
610 	switch (sensor) {
611 	case AMDGPU_PP_SENSOR_NODEPOWERLIMIT:
612 		*value = SMUQ10_ROUND(metrics->NodePowerLimit);
613 		break;
614 	case AMDGPU_PP_SENSOR_NODEPOWER:
615 		*value = SMUQ10_ROUND(metrics->NodePower);
616 		break;
617 	case AMDGPU_PP_SENSOR_GPPTRESIDENCY:
618 		*value = SMUQ10_ROUND(metrics->GlobalPPTResidencyAcc);
619 		break;
620 	default:
621 		return -EINVAL;
622 	}
623 
624 	return 0;
625 }
626 
smu_v15_0_8_read_sensor(struct smu_context * smu,enum amd_pp_sensors sensor,void * data,uint32_t * size)627 static int smu_v15_0_8_read_sensor(struct smu_context *smu,
628 				   enum amd_pp_sensors sensor, void *data,
629 				   uint32_t *size)
630 {
631 	struct smu_15_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
632 	int ret = 0;
633 
634 	if (amdgpu_ras_intr_triggered())
635 		return 0;
636 
637 	if (!data || !size)
638 		return -EINVAL;
639 
640 	switch (sensor) {
641 	case AMDGPU_PP_SENSOR_MEM_LOAD:
642 	case AMDGPU_PP_SENSOR_GPU_LOAD:
643 		ret = smu_v15_0_8_get_current_activity_percent(smu, sensor,
644 							       (uint32_t *)data);
645 		*size = 4;
646 		break;
647 	case AMDGPU_PP_SENSOR_GPU_INPUT_POWER:
648 		ret = smu_v15_0_8_get_smu_metrics_data(smu,
649 						       METRICS_CURR_SOCKETPOWER,
650 						       (uint32_t *)data);
651 		*size = 4;
652 		break;
653 	case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
654 	case AMDGPU_PP_SENSOR_MEM_TEMP:
655 		ret = smu_v15_0_8_thermal_get_temperature(smu, sensor,
656 							  (uint32_t *)data);
657 		*size = 4;
658 		break;
659 	case AMDGPU_PP_SENSOR_GFX_MCLK:
660 		ret = smu_v15_0_8_get_current_clk_freq_by_table(smu,
661 								SMU_UCLK, (uint32_t *)data);
662 		/* the output clock frequency in 10K unit */
663 		*(uint32_t *)data *= 100;
664 		*size = 4;
665 		break;
666 	case AMDGPU_PP_SENSOR_GFX_SCLK:
667 		ret = smu_v15_0_8_get_current_clk_freq_by_table(smu,
668 								SMU_GFXCLK, (uint32_t *)data);
669 		*(uint32_t *)data *= 100;
670 		*size = 4;
671 		break;
672 	case AMDGPU_PP_SENSOR_VDDBOARD:
673 		*(uint32_t *)data = dpm_context->board_volt;
674 		*size = 4;
675 		break;
676 	case AMDGPU_PP_SENSOR_NODEPOWERLIMIT:
677 	case AMDGPU_PP_SENSOR_NODEPOWER:
678 	case AMDGPU_PP_SENSOR_GPPTRESIDENCY:
679 	case AMDGPU_PP_SENSOR_MAXNODEPOWERLIMIT:
680 		ret = smu_v15_0_8_get_npm_data(smu, sensor, (uint32_t *)data);
681 		if (ret)
682 			return ret;
683 		*size = 4;
684 		break;
685 	case AMDGPU_PP_SENSOR_GPU_AVG_POWER:
686 	default:
687 		ret = -EOPNOTSUPP;
688 		break;
689 	}
690 
691 	return ret;
692 }
693 
smu_v15_0_8_emit_clk_levels(struct smu_context * smu,enum smu_clk_type type,char * buf,int * offset)694 static int smu_v15_0_8_emit_clk_levels(struct smu_context *smu,
695 				       enum smu_clk_type type, char *buf,
696 				       int *offset)
697 {
698 	struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
699 	struct smu_15_0_dpm_context *dpm_context;
700 	struct smu_dpm_table *single_dpm_table = NULL;
701 	struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
702 	int ret, now, size = *offset;
703 
704 	if (amdgpu_ras_intr_triggered()) {
705 		sysfs_emit_at(buf, size, "unavailable\n");
706 		return -EBUSY;
707 	}
708 
709 	dpm_context = smu_dpm->dpm_context;
710 
711 	switch (type) {
712 	case SMU_OD_SCLK:
713 		size += sysfs_emit_at(buf, size, "%s:\n", "OD_SCLK");
714 		size += sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMhz\n",
715 				      pstate_table->gfxclk_pstate.curr.min,
716 				      pstate_table->gfxclk_pstate.curr.max);
717 		break;
718 	case SMU_OD_MCLK:
719 		size += sysfs_emit_at(buf, size, "%s:\n", "OD_MCLK");
720 		size += sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMhz\n",
721 				      pstate_table->uclk_pstate.curr.min,
722 				      pstate_table->uclk_pstate.curr.max);
723 		break;
724 	case SMU_SCLK:
725 	case SMU_GFXCLK:
726 		single_dpm_table = &dpm_context->dpm_tables.gfx_table;
727 		break;
728 	case SMU_MCLK:
729 	case SMU_UCLK:
730 		single_dpm_table = &dpm_context->dpm_tables.uclk_table;
731 		break;
732 	case SMU_SOCCLK:
733 		single_dpm_table = &dpm_context->dpm_tables.soc_table;
734 		break;
735 	case SMU_FCLK:
736 		single_dpm_table = &dpm_context->dpm_tables.fclk_table;
737 		break;
738 	case SMU_VCLK:
739 		single_dpm_table = &dpm_context->dpm_tables.vclk_table;
740 		break;
741 	case SMU_DCLK:
742 		single_dpm_table = &dpm_context->dpm_tables.dclk_table;
743 		break;
744 	default:
745 		break;
746 	}
747 
748 	if (single_dpm_table) {
749 		ret = smu_v15_0_8_get_current_clk_freq_by_table(smu, type, &now);
750 		if (ret) {
751 			dev_err(smu->adev->dev,
752 				"Attempt to get current clk Failed!");
753 			return ret;
754 		}
755 		ret = smu_cmn_print_dpm_clk_levels(smu, single_dpm_table, now,
756 						   buf, offset);
757 		if (ret < 0)
758 			return ret;
759 
760 		return 0;
761 	}
762 
763 	*offset = size;
764 
765 	return 0;
766 }
767 
smu_v15_0_8_get_dpm_ultimate_freq(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t * min,uint32_t * max)768 static int smu_v15_0_8_get_dpm_ultimate_freq(struct smu_context *smu,
769 					     enum smu_clk_type clk_type,
770 					     uint32_t *min, uint32_t *max)
771 {
772 	struct smu_15_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
773 	struct smu_table_context *smu_table = &smu->smu_table;
774 	PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable;
775 	struct smu_dpm_table *dpm_table;
776 	uint32_t min_clk = 0, max_clk = 0;
777 
778 	if (!pptable->init)
779 		return -EINVAL;
780 
781 	/* Try cached DPM tables first */
782 	if (dpm_context) {
783 		switch (clk_type) {
784 		case SMU_MCLK:
785 		case SMU_UCLK:
786 			dpm_table = &dpm_context->dpm_tables.uclk_table;
787 			break;
788 		case SMU_GFXCLK:
789 		case SMU_SCLK:
790 			dpm_table = &dpm_context->dpm_tables.gfx_table;
791 			break;
792 		case SMU_SOCCLK:
793 			dpm_table = &dpm_context->dpm_tables.soc_table;
794 			break;
795 		case SMU_FCLK:
796 			dpm_table = &dpm_context->dpm_tables.fclk_table;
797 			break;
798 		case SMU_GL2CLK:
799 			dpm_table = &dpm_context->dpm_tables.gl2_table;
800 			break;
801 		case SMU_VCLK:
802 			dpm_table = &dpm_context->dpm_tables.vclk_table;
803 			break;
804 		case SMU_DCLK:
805 			dpm_table = &dpm_context->dpm_tables.dclk_table;
806 			break;
807 		default:
808 			dpm_table = NULL;
809 			break;
810 		}
811 
812 		if (dpm_table && dpm_table->count > 0) {
813 			min_clk = SMU_DPM_TABLE_MIN(dpm_table);
814 			max_clk = SMU_DPM_TABLE_MAX(dpm_table);
815 
816 			if (min_clk && max_clk) {
817 				if (min)
818 					*min = min_clk;
819 				if (max)
820 					*max = max_clk;
821 				return 0;
822 			}
823 		}
824 	}
825 
826 	/* Fall back to pptable */
827 	switch (clk_type) {
828 	case SMU_GFXCLK:
829 	case SMU_SCLK:
830 		min_clk = pptable->MinGfxclkFrequency;
831 		max_clk = pptable->MaxGfxclkFrequency;
832 		break;
833 	case SMU_FCLK:
834 		min_clk = pptable->MinFclkFrequency;
835 		max_clk = pptable->MaxFclkFrequency;
836 		break;
837 	case SMU_GL2CLK:
838 		min_clk = pptable->MinGl2clkFrequency;
839 		max_clk = pptable->MaxGl2clkFrequency;
840 		break;
841 	case SMU_MCLK:
842 	case SMU_UCLK:
843 		min_clk = pptable->UclkFrequencyTable[0];
844 		max_clk = pptable->UclkFrequencyTable[ARRAY_SIZE(pptable->UclkFrequencyTable) - 1];
845 		break;
846 	case SMU_SOCCLK:
847 		min_clk = pptable->SocclkFrequency;
848 		max_clk = pptable->SocclkFrequency;
849 		break;
850 	case SMU_VCLK:
851 		min_clk = pptable->VclkFrequency;
852 		max_clk = pptable->VclkFrequency;
853 		break;
854 	case SMU_DCLK:
855 		min_clk = pptable->DclkFrequency;
856 		max_clk = pptable->DclkFrequency;
857 		break;
858 	default:
859 		return -EINVAL;
860 	}
861 
862 	if (min)
863 		*min = min_clk;
864 	if (max)
865 		*max = max_clk;
866 
867 	return 0;
868 }
869 
smu_v15_0_8_set_dpm_table(struct smu_context * smu)870 static int smu_v15_0_8_set_dpm_table(struct smu_context *smu)
871 {
872 	struct smu_table_context *smu_table = &smu->smu_table;
873 	struct smu_15_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
874 	struct smu_dpm_table *dpm_table;
875 	PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable;
876 	int i, ret;
877 	uint32_t gfxclkmin, gfxclkmax;
878 
879 	/* gfxclk dpm table setup - fine-grained */
880 	dpm_table = &dpm_context->dpm_tables.gfx_table;
881 	dpm_table->clk_type = SMU_GFXCLK;
882 	dpm_table->flags = SMU_DPM_TABLE_FINE_GRAINED;
883 	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT)) {
884 		ret = smu_v15_0_8_get_dpm_ultimate_freq(smu, SMU_GFXCLK,
885 							&gfxclkmin, &gfxclkmax);
886 		if (ret)
887 			return ret;
888 
889 		dpm_table->count = 2;
890 		dpm_table->dpm_levels[0].value = gfxclkmin;
891 		dpm_table->dpm_levels[0].enabled = true;
892 		dpm_table->dpm_levels[1].value = gfxclkmax;
893 		dpm_table->dpm_levels[1].enabled = true;
894 	} else {
895 		dpm_table->count = 1;
896 		dpm_table->dpm_levels[0].value = pptable->MinGfxclkFrequency;
897 		dpm_table->dpm_levels[0].enabled = true;
898 	}
899 
900 	/* fclk dpm table setup - fine-grained */
901 	dpm_table = &dpm_context->dpm_tables.fclk_table;
902 	dpm_table->clk_type = SMU_FCLK;
903 	dpm_table->flags = SMU_DPM_TABLE_FINE_GRAINED;
904 	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_FCLK_BIT)) {
905 		dpm_table->count = 2;
906 		dpm_table->dpm_levels[0].value = pptable->MinFclkFrequency;
907 		dpm_table->dpm_levels[0].enabled = true;
908 		dpm_table->dpm_levels[1].value = pptable->MaxFclkFrequency;
909 		dpm_table->dpm_levels[1].enabled = true;
910 	} else {
911 		dpm_table->count = 1;
912 		dpm_table->dpm_levels[0].value = pptable->MinFclkFrequency;
913 		dpm_table->dpm_levels[0].enabled = true;
914 	}
915 
916 	/* gl2clk dpm table setup - fine-grained */
917 	dpm_table = &dpm_context->dpm_tables.gl2_table;
918 	dpm_table->flags = SMU_DPM_TABLE_FINE_GRAINED;
919 	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GL2CLK_BIT)) {
920 		dpm_table->count = 2;
921 		dpm_table->dpm_levels[0].value = pptable->MinGl2clkFrequency;
922 		dpm_table->dpm_levels[0].enabled = true;
923 		dpm_table->dpm_levels[1].value = pptable->MaxGl2clkFrequency;
924 		dpm_table->dpm_levels[1].enabled = true;
925 	} else {
926 		dpm_table->count = 1;
927 		dpm_table->dpm_levels[0].value = pptable->MinGl2clkFrequency;
928 		dpm_table->dpm_levels[0].enabled = true;
929 	}
930 
931 	/* uclk dpm table setup - discrete levels */
932 	dpm_table = &dpm_context->dpm_tables.uclk_table;
933 	dpm_table->clk_type = SMU_UCLK;
934 	dpm_table->flags = 0;
935 	if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
936 		dpm_table->count = ARRAY_SIZE(pptable->UclkFrequencyTable);
937 		for (i = 0; i < dpm_table->count; ++i) {
938 			dpm_table->dpm_levels[i].value = pptable->UclkFrequencyTable[i];
939 			dpm_table->dpm_levels[i].enabled = true;
940 		}
941 	} else {
942 		dpm_table->count = 1;
943 		dpm_table->dpm_levels[0].value = pptable->UclkFrequencyTable[0];
944 		dpm_table->dpm_levels[0].enabled = true;
945 	}
946 
947 	/* socclk dpm table setup - single boot-time value */
948 	dpm_table = &dpm_context->dpm_tables.soc_table;
949 	dpm_table->clk_type = SMU_SOCCLK;
950 	dpm_table->flags = 0;
951 	dpm_table->count = 1;
952 	dpm_table->dpm_levels[0].value = pptable->SocclkFrequency;
953 	dpm_table->dpm_levels[0].enabled = true;
954 
955 	/* vclk dpm table setup - single boot-time value */
956 	dpm_table = &dpm_context->dpm_tables.vclk_table;
957 	dpm_table->clk_type = SMU_VCLK;
958 	dpm_table->flags = 0;
959 	dpm_table->count = 1;
960 	dpm_table->dpm_levels[0].value = pptable->VclkFrequency;
961 	dpm_table->dpm_levels[0].enabled = true;
962 
963 	/* dclk dpm table setup - single boot-time value */
964 	dpm_table = &dpm_context->dpm_tables.dclk_table;
965 	dpm_table->clk_type = SMU_DCLK;
966 	dpm_table->flags = 0;
967 	dpm_table->count = 1;
968 	dpm_table->dpm_levels[0].value = pptable->DclkFrequency;
969 	dpm_table->dpm_levels[0].enabled = true;
970 
971 	return 0;
972 }
973 
smu_v15_0_8_setup_pptable(struct smu_context * smu)974 static int smu_v15_0_8_setup_pptable(struct smu_context *smu)
975 {
976 	struct smu_table_context *table_context = &smu->smu_table;
977 
978 	/* TODO: PPTable is not available.
979 	 * 1) Find an alternate way to get 'PPTable values' here.
980 	 * 2) Check if there is SW CTF
981 	 */
982 	table_context->thermal_controller_type = 0;
983 
984 	return 0;
985 }
986 
smu_v15_0_8_check_fw_status(struct smu_context * smu)987 static int smu_v15_0_8_check_fw_status(struct smu_context *smu)
988 {
989 	struct amdgpu_device *adev = smu->adev;
990 	uint32_t mp1_fw_flags;
991 
992 	mp1_fw_flags = RREG32_PCIE(MP1_Public |
993 				   (smnMP1_FIRMWARE_FLAGS_15_0_8 & 0xffffffff));
994 
995 	if ((mp1_fw_flags & MP1_CRU1_MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >>
996 	    MP1_CRU1_MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT)
997 		return 0;
998 
999 	return -EIO;
1000 }
1001 
smu_v15_0_8_get_static_metrics_table(struct smu_context * smu)1002 static int smu_v15_0_8_get_static_metrics_table(struct smu_context *smu)
1003 {
1004 	struct smu_table_context *smu_table = &smu->smu_table;
1005 	uint32_t table_size = smu_table->tables[SMU_TABLE_SMU_METRICS].size;
1006 	struct smu_table *table = &smu_table->driver_table;
1007 	int ret;
1008 
1009 	ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetStaticMetricsTable, NULL);
1010 	if (ret) {
1011 		dev_err(smu->adev->dev,
1012 			 "Failed to export static metrics table!\n");
1013 		return ret;
1014 	}
1015 
1016 	amdgpu_hdp_invalidate(smu->adev, NULL);
1017 
1018 	return smu_cmn_vram_cpy(smu, smu_table->metrics_table,
1019 				table->cpu_addr, table_size);
1020 }
1021 
smu_v15_0_8_fru_get_product_info(struct smu_context * smu,StaticMetricsTable_t * static_metrics)1022 static int smu_v15_0_8_fru_get_product_info(struct smu_context *smu,
1023 					    StaticMetricsTable_t *static_metrics)
1024 {
1025 	struct amdgpu_fru_info *fru_info;
1026 	struct amdgpu_device *adev = smu->adev;
1027 
1028 	if (!adev->fru_info) {
1029 		adev->fru_info = kzalloc_obj(*adev->fru_info);
1030 		if (!adev->fru_info)
1031 			return -ENOMEM;
1032 	}
1033 
1034 	fru_info = adev->fru_info;
1035 	strscpy(fru_info->product_number, static_metrics->ProductInfo.ModelNumber,
1036 		sizeof(fru_info->product_number));
1037 	strscpy(fru_info->product_name, static_metrics->ProductInfo.Name,
1038 		sizeof(fru_info->product_name));
1039 	strscpy(fru_info->serial, static_metrics->ProductInfo.Serial,
1040 		sizeof(fru_info->serial));
1041 	strscpy(fru_info->manufacturer_name, static_metrics->ProductInfo.ManufacturerName,
1042 		sizeof(fru_info->manufacturer_name));
1043 	strscpy(fru_info->fru_id, static_metrics->ProductInfo.FruId,
1044 		sizeof(fru_info->fru_id));
1045 
1046 	return 0;
1047 }
1048 
smu_v15_0_8_init_xgmi_data(struct smu_context * smu,StaticMetricsTable_t * static_metrics)1049 static void smu_v15_0_8_init_xgmi_data(struct smu_context *smu,
1050 				       StaticMetricsTable_t *static_metrics)
1051 {
1052 	uint16_t max_speed;
1053 	uint8_t max_width;
1054 
1055 	max_width = (uint8_t)static_metrics->MaxXgmiWidth;
1056 	max_speed = (uint16_t)static_metrics->MaxXgmiBitrate;
1057 	amgpu_xgmi_set_max_speed_width(smu->adev, max_speed, max_width);
1058 }
1059 
smu_v15_0_8_set_driver_pptable(struct smu_context * smu)1060 static int smu_v15_0_8_set_driver_pptable(struct smu_context *smu)
1061 {
1062 	struct smu_15_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
1063 	struct smu_table_context *smu_table = &smu->smu_table;
1064 	StaticMetricsTable_t *static_metrics = (StaticMetricsTable_t *)smu_table->metrics_table;
1065 	PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable;
1066 	int ret, i, n;
1067 	uint32_t table_version;
1068 
1069 	if (!pptable->init) {
1070 		ret = smu_v15_0_8_get_static_metrics_table(smu);
1071 		if (ret)
1072 			return ret;
1073 
1074 		ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetMetricsVersion,
1075 					   &table_version);
1076 		if (ret)
1077 			return ret;
1078 		smu_table->tables[SMU_TABLE_SMU_METRICS].version =
1079 			table_version;
1080 
1081 		pptable->MaxSocketPowerLimit = static_metrics->MaxSocketPowerLimit;
1082 		pptable->MaxGfxclkFrequency = static_metrics->MaxGfxclkFrequency;
1083 		pptable->MinGfxclkFrequency = static_metrics->MinGfxclkFrequency;
1084 		pptable->MaxFclkFrequency = static_metrics->MaxFclkFrequency;
1085 		pptable->MinFclkFrequency = static_metrics->MinFclkFrequency;
1086 		pptable->MaxGl2clkFrequency = static_metrics->MaxGl2clkFrequency;
1087 		pptable->MinGl2clkFrequency = static_metrics->MinGl2clkFrequency;
1088 
1089 		for (i = 0; i < ARRAY_SIZE(static_metrics->UclkFrequencyTable); ++i)
1090 			pptable->UclkFrequencyTable[i] = static_metrics->UclkFrequencyTable[i];
1091 
1092 		pptable->SocclkFrequency = static_metrics->SocclkFrequency;
1093 		pptable->LclkFrequency = static_metrics->LclkFrequency;
1094 		pptable->VclkFrequency = static_metrics->VclkFrequency;
1095 		pptable->DclkFrequency = static_metrics->DclkFrequency;
1096 
1097 		pptable->CTFLimitMID = static_metrics->CTFLimit_MID;
1098 		pptable->CTFLimitAID = static_metrics->CTFLimit_AID;
1099 		pptable->CTFLimitXCD = static_metrics->CTFLimit_XCD;
1100 		pptable->CTFLimitHBM = static_metrics->CTFLimit_HBM;
1101 		pptable->ThermalLimitMID = static_metrics->ThermalLimit_MID;
1102 		pptable->ThermalLimitAID = static_metrics->ThermalLimit_AID;
1103 		pptable->ThermalLimitXCD = static_metrics->ThermalLimit_XCD;
1104 		pptable->ThermalLimitHBM = static_metrics->ThermalLimit_HBM;
1105 
1106 		/* use MID0 serial number by default */
1107 		pptable->PublicSerialNumberMID =
1108 			static_metrics->PublicSerialNumber_MID[0];
1109 
1110 		amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_SOC,
1111 				      0, pptable->PublicSerialNumberMID);
1112 		pptable->PublicSerialNumberAID =
1113 			static_metrics->PublicSerialNumber_AID[0];
1114 		pptable->PublicSerialNumberXCD =
1115 			static_metrics->PublicSerialNumber_XCD[0];
1116 		n = ARRAY_SIZE(static_metrics->PublicSerialNumber_MID);
1117 		for (i = 0; i < n; i++) {
1118 			amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_MID, i,
1119 					      static_metrics->PublicSerialNumber_MID[i]);
1120 		}
1121 		n = ARRAY_SIZE(static_metrics->PublicSerialNumber_AID);
1122 		for (i = 0; i < n; i++) {
1123 			amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_AID, i,
1124 					      static_metrics->PublicSerialNumber_AID[i]);
1125 		}
1126 		n = ARRAY_SIZE(static_metrics->PublicSerialNumber_XCD);
1127 		for (i = 0; i < n; i++) {
1128 			amdgpu_device_set_uid(smu->adev->uid_info, AMDGPU_UID_TYPE_XCD, i,
1129 					      static_metrics->PublicSerialNumber_XCD[i]);
1130 		}
1131 
1132 		ret = smu_v15_0_8_fru_get_product_info(smu, static_metrics);
1133 		if (ret)
1134 			return ret;
1135 		pptable->PPT1Max = static_metrics->PPT1Max;
1136 		pptable->PPT1Min = static_metrics->PPT1Min;
1137 		pptable->PPT1Default = static_metrics->PPT1Default;
1138 
1139 		if (static_metrics->pldmVersion[0] != 0xFFFFFFFF)
1140 			smu->adev->firmware.pldm_version =
1141 				static_metrics->pldmVersion[0];
1142 		dpm_context->board_volt = static_metrics->InputTelemetryVoltageInmV;
1143 		smu_v15_0_8_init_xgmi_data(smu, static_metrics);
1144 		pptable->init = true;
1145 	}
1146 
1147 	return 0;
1148 }
1149 
smu_v15_0_8_set_default_dpm_table(struct smu_context * smu)1150 static int smu_v15_0_8_set_default_dpm_table(struct smu_context *smu)
1151 {
1152 	int ret;
1153 
1154 	ret = smu_v15_0_8_set_driver_pptable(smu);
1155 	if (ret)
1156 		return ret;
1157 
1158 	ret = smu_v15_0_8_set_dpm_table(smu);
1159 	if (ret)
1160 		return ret;
1161 
1162 	return smu_v15_0_8_init_ppt_limits(smu);
1163 }
1164 
smu_v15_0_8_irq_process(struct amdgpu_device * adev,struct amdgpu_irq_src * source,struct amdgpu_iv_entry * entry)1165 static int smu_v15_0_8_irq_process(struct amdgpu_device *adev,
1166 				   struct amdgpu_irq_src *source,
1167 				   struct amdgpu_iv_entry *entry)
1168 {
1169 	struct smu_context *smu = adev->powerplay.pp_handle;
1170 	struct smu_power_context *smu_power = &smu->smu_power;
1171 	struct smu_15_0_power_context *power_context = smu_power->power_context;
1172 	uint32_t client_id = entry->client_id;
1173 	uint32_t ctxid = entry->src_data[0];
1174 	uint32_t src_id = entry->src_id;
1175 	uint32_t data;
1176 
1177 	if (client_id == SOC_V1_0_IH_CLIENTID_MP1) {
1178 		if (src_id == IH_INTERRUPT_ID_TO_DRIVER) {
1179 			/* ACK SMUToHost interrupt */
1180 			data = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL);
1181 			data = REG_SET_FIELD(data, MP1_SMN_IH_SW_INT_CTRL, INT_ACK, 1);
1182 			WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, data);
1183 			/*
1184 			 * ctxid is used to distinguish different events for SMCToHost
1185 			 * interrupt.
1186 			 */
1187 			switch (ctxid) {
1188 			case IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING:
1189 				/*
1190 				 * Increment the throttle interrupt counter
1191 				 */
1192 				atomic64_inc(&smu->throttle_int_counter);
1193 
1194 				if (!atomic_read(&adev->throttling_logging_enabled))
1195 					return 0;
1196 
1197 				/* This uses the new method which fixes the
1198 				 * incorrect throttling status reporting
1199 				 * through metrics table. For older FWs,
1200 				 * it will be ignored.
1201 				 */
1202 				if (__ratelimit(&adev->throttling_logging_rs)) {
1203 					atomic_set(
1204 						&power_context->throttle_status,
1205 							entry->src_data[1]);
1206 					schedule_work(&smu->throttling_logging_work);
1207 				}
1208 				break;
1209 			default:
1210 				dev_dbg(adev->dev, "Unhandled context id %d from client:%d!\n",
1211 									ctxid, client_id);
1212 				break;
1213 			}
1214 		}
1215 	}
1216 
1217 	return 0;
1218 }
1219 
smu_v15_0_8_set_irq_state(struct amdgpu_device * adev,struct amdgpu_irq_src * source,unsigned type,enum amdgpu_interrupt_state state)1220 static int smu_v15_0_8_set_irq_state(struct amdgpu_device *adev,
1221 				     struct amdgpu_irq_src *source,
1222 				     unsigned type,
1223 				     enum amdgpu_interrupt_state state)
1224 {
1225 	uint32_t val = 0;
1226 
1227 	switch (state) {
1228 	case AMDGPU_IRQ_STATE_DISABLE:
1229 		/* For MP1 SW irqs */
1230 		val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL);
1231 		val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT_CTRL, INT_MASK, 1);
1232 		WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, val);
1233 
1234 		break;
1235 	case AMDGPU_IRQ_STATE_ENABLE:
1236 		/* For MP1 SW irqs */
1237 		val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT);
1238 		val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT, ID, 0xFE);
1239 		val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT, VALID, 0);
1240 		WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT, val);
1241 
1242 		val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL);
1243 		val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT_CTRL, INT_MASK, 0);
1244 		WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, val);
1245 
1246 		break;
1247 	default:
1248 		break;
1249 	}
1250 
1251 	return 0;
1252 }
1253 
1254 static const struct amdgpu_irq_src_funcs smu_v15_0_8_irq_funcs = {
1255 	.set = smu_v15_0_8_set_irq_state,
1256 	.process = smu_v15_0_8_irq_process,
1257 };
1258 
smu_v15_0_8_register_irq_handler(struct smu_context * smu)1259 static int smu_v15_0_8_register_irq_handler(struct smu_context *smu)
1260 {
1261 	struct amdgpu_device *adev = smu->adev;
1262 	struct amdgpu_irq_src *irq_src = &smu->irq_source;
1263 	int ret = 0;
1264 
1265 	if (amdgpu_sriov_vf(adev))
1266 		return 0;
1267 
1268 	irq_src->num_types = 1;
1269 	irq_src->funcs = &smu_v15_0_8_irq_funcs;
1270 
1271 	ret = amdgpu_irq_add_id(adev, SOC_V1_0_IH_CLIENTID_MP1,
1272 				IH_INTERRUPT_ID_TO_DRIVER,
1273 				irq_src);
1274 	if (ret)
1275 		return ret;
1276 
1277 	return ret;
1278 }
1279 
smu_v15_0_8_notify_unload(struct smu_context * smu)1280 static int smu_v15_0_8_notify_unload(struct smu_context *smu)
1281 {
1282 	if (amdgpu_in_reset(smu->adev))
1283 		return 0;
1284 
1285 	dev_dbg(smu->adev->dev, "Notify PMFW about driver unload");
1286 	/* Ignore return, just intimate FW that driver is not going to be there */
1287 	smu_cmn_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL);
1288 
1289 	return 0;
1290 }
1291 
1292 
smu_v15_0_8_system_features_control(struct smu_context * smu,bool enable)1293 static int smu_v15_0_8_system_features_control(struct smu_context *smu,
1294 					       bool enable)
1295 {
1296 	struct amdgpu_device *adev = smu->adev;
1297 	int ret = 0;
1298 
1299 	if (amdgpu_sriov_vf(adev))
1300 		return 0;
1301 
1302 	if (enable)
1303 		ret = smu_v15_0_system_features_control(smu, enable);
1304 	else
1305 		smu_v15_0_8_notify_unload(smu);
1306 
1307 	return ret;
1308 }
1309 
1310 /**
1311  * smu_v15_0_8_get_enabled_mask - Get enabled SMU features (128-bit)
1312  * @smu: SMU context
1313  * @feature_mask: feature mask structure
1314  *
1315  * SMU 15 returns all 128 feature bits in a single message via out_args[0..3].
1316  * For backward compatibility, this function returns only the first 64 bits.
1317  *
1318  * Return: 0 on success, negative errno on failure
1319  */
smu_v15_0_8_get_enabled_mask(struct smu_context * smu,struct smu_feature_bits * feature_mask)1320 static int smu_v15_0_8_get_enabled_mask(struct smu_context *smu,
1321 					struct smu_feature_bits *feature_mask)
1322 {
1323 	uint32_t out[2];
1324 	int ret;
1325 
1326 	if (!feature_mask)
1327 		return -EINVAL;
1328 
1329 	ret = smu_cmn_send_smc_msg_with_params(smu,
1330 					       SMU_MSG_GetEnabledSmuFeatures,
1331 					       NULL, 0,
1332 					       out, ARRAY_SIZE(out));
1333 
1334 	if (ret)
1335 		return ret;
1336 
1337 	smu_feature_bits_from_arr32(feature_mask, out, SMU_FEATURE_NUM_DEFAULT);
1338 
1339 	return 0;
1340 }
1341 
smu_v15_0_8_is_dpm_running(struct smu_context * smu)1342 static bool smu_v15_0_8_is_dpm_running(struct smu_context *smu)
1343 {
1344 	int ret = 0;
1345 	struct smu_feature_bits feature_enabled;
1346 
1347 	ret = smu_v15_0_8_get_enabled_mask(smu, &feature_enabled);
1348 	if (ret)
1349 		return false;
1350 
1351 	return smu_feature_bits_test_mask(&feature_enabled,
1352 					  smu_v15_0_8_dpm_features.bits);
1353 }
1354 
smu_v15_0_8_get_pm_metrics(struct smu_context * smu,void * metrics,size_t max_size)1355 static ssize_t smu_v15_0_8_get_pm_metrics(struct smu_context *smu,
1356 					  void *metrics, size_t max_size)
1357 {
1358 	struct smu_table_context *smu_table = &smu->smu_table;
1359 	struct amdgpu_pm_metrics *pm_metrics = (struct amdgpu_pm_metrics *)metrics;
1360 	uint32_t table_version = smu_table->tables[SMU_TABLE_SMU_METRICS].version;
1361 	uint32_t table_size = smu_table->tables[SMU_TABLE_SMU_METRICS].size;
1362 	uint32_t pmfw_version;
1363 	int ret;
1364 
1365 	if (!pm_metrics || !max_size)
1366 		return -EINVAL;
1367 
1368 	if (max_size < (table_size + sizeof(pm_metrics->common_header)))
1369 		return -EOVERFLOW;
1370 
1371 	/* Don't use cached metrics data */
1372 	ret = smu_v15_0_8_get_metrics_table_internal(smu, 0, pm_metrics->data);
1373 	if (ret)
1374 		return ret;
1375 
1376 	smu_cmn_get_smc_version(smu, NULL, &pmfw_version);
1377 	memset(&pm_metrics->common_header, 0, sizeof(pm_metrics->common_header));
1378 	pm_metrics->common_header.mp1_ip_discovery_version =
1379 		amdgpu_ip_version(smu->adev, MP1_HWIP, 0);
1380 	pm_metrics->common_header.pmfw_version = pmfw_version;
1381 	pm_metrics->common_header.pmmetrics_version = table_version;
1382 	pm_metrics->common_header.structure_size =
1383 		sizeof(pm_metrics->common_header) + table_size;
1384 
1385 	return pm_metrics->common_header.structure_size;
1386 }
1387 
smu_v15_0_8_mode2_reset(struct smu_context * smu)1388 static int smu_v15_0_8_mode2_reset(struct smu_context *smu)
1389 {
1390 	struct smu_msg_ctl *ctl = &smu->msg_ctl;
1391 	struct amdgpu_device *adev = smu->adev;
1392 	int timeout = 10;
1393 	int ret = 0;
1394 
1395 	mutex_lock(&ctl->lock);
1396 
1397 	ret = smu_msg_send_async_locked(ctl, SMU_MSG_GfxDeviceDriverReset,
1398 					SMU_RESET_MODE_2);
1399 
1400 	if (ret)
1401 		goto out;
1402 
1403 	/* Reset takes a bit longer, wait for 200ms. */
1404 	msleep(200);
1405 
1406 	dev_dbg(adev->dev, "wait for reset ack\n");
1407 	do {
1408 		ret = smu_msg_wait_response(ctl, 0);
1409 		/* Wait a bit more time for getting ACK */
1410 		if (ret == -ETIME) {
1411 			--timeout;
1412 			usleep_range(500, 1000);
1413 			continue;
1414 		}
1415 
1416 		if (ret)
1417 			goto out;
1418 
1419 	} while (ret == -ETIME && timeout);
1420 
1421 out:
1422 	mutex_unlock(&ctl->lock);
1423 
1424 	if (ret)
1425 		dev_err(adev->dev, "failed to send mode2 reset, error code %d",
1426 			ret);
1427 
1428 	return ret;
1429 }
1430 
smu_v15_0_8_is_temp_metrics_supported(struct smu_context * smu,enum smu_temp_metric_type type)1431 static bool smu_v15_0_8_is_temp_metrics_supported(struct smu_context *smu,
1432 						  enum smu_temp_metric_type type)
1433 {
1434 	switch (type) {
1435 	case SMU_TEMP_METRIC_BASEBOARD:
1436 		if (smu->adev->gmc.xgmi.physical_node_id == 0)
1437 			return true;
1438 		return false;
1439 	case SMU_TEMP_METRIC_GPUBOARD:
1440 		return true;
1441 	default:
1442 		return false;
1443 	}
1444 }
1445 
smu_v15_0_8_fill_baseboard_temp_metrics(struct smu_v15_0_8_baseboard_temp_metrics * baseboard_temp_metrics,const SystemMetricsTable_t * metrics)1446 static void smu_v15_0_8_fill_baseboard_temp_metrics(
1447 	struct smu_v15_0_8_baseboard_temp_metrics *baseboard_temp_metrics,
1448 	const SystemMetricsTable_t *metrics)
1449 {
1450 	baseboard_temp_metrics->accumulation_counter = metrics->AccumulationCounter;
1451 	baseboard_temp_metrics->label_version = metrics->LabelVersion;
1452 	baseboard_temp_metrics->node_id = metrics->NodeIdentifier;
1453 
1454 	baseboard_temp_metrics->system_temp_ubb_fpga =
1455 		metrics->SystemTemperatures[SYSTEM_TEMP_UBB_FPGA];
1456 	baseboard_temp_metrics->system_temp_ubb_front =
1457 		metrics->SystemTemperatures[SYSTEM_TEMP_UBB_FRONT];
1458 	baseboard_temp_metrics->system_temp_ubb_back =
1459 		metrics->SystemTemperatures[SYSTEM_TEMP_UBB_BACK];
1460 	baseboard_temp_metrics->system_temp_ubb_oam7 =
1461 		metrics->SystemTemperatures[SYSTEM_TEMP_UBB_OAM7];
1462 	baseboard_temp_metrics->system_temp_ubb_ibc =
1463 		metrics->SystemTemperatures[SYSTEM_TEMP_UBB_IBC];
1464 	baseboard_temp_metrics->system_temp_ubb_ufpga =
1465 		metrics->SystemTemperatures[SYSTEM_TEMP_UBB_UFPGA];
1466 	baseboard_temp_metrics->system_temp_ubb_oam1 =
1467 		metrics->SystemTemperatures[SYSTEM_TEMP_UBB_OAM1];
1468 	baseboard_temp_metrics->system_temp_oam_0_1_hsc =
1469 		metrics->SystemTemperatures[SYSTEM_TEMP_OAM_0_1_HSC];
1470 	baseboard_temp_metrics->system_temp_oam_2_3_hsc =
1471 		metrics->SystemTemperatures[SYSTEM_TEMP_OAM_2_3_HSC];
1472 	baseboard_temp_metrics->system_temp_oam_4_5_hsc =
1473 		metrics->SystemTemperatures[SYSTEM_TEMP_OAM_4_5_HSC];
1474 	baseboard_temp_metrics->system_temp_oam_6_7_hsc =
1475 		metrics->SystemTemperatures[SYSTEM_TEMP_OAM_6_7_HSC];
1476 	baseboard_temp_metrics->system_temp_ubb_fpga_0v72_vr =
1477 		metrics->SystemTemperatures[SYSTEM_TEMP_UBB_FPGA_0V72_VR];
1478 	baseboard_temp_metrics->system_temp_ubb_fpga_3v3_vr =
1479 		metrics->SystemTemperatures[SYSTEM_TEMP_UBB_FPGA_3V3_VR];
1480 	baseboard_temp_metrics->system_temp_retimer_0_1_2_3_1v2_vr =
1481 		metrics->SystemTemperatures[SYSTEM_TEMP_RETIMER_0_1_2_3_1V2_VR];
1482 	baseboard_temp_metrics->system_temp_retimer_4_5_6_7_1v2_vr =
1483 		metrics->SystemTemperatures[SYSTEM_TEMP_RETIMER_4_5_6_7_1V2_VR];
1484 	baseboard_temp_metrics->system_temp_retimer_0_1_0v9_vr =
1485 		metrics->SystemTemperatures[SYSTEM_TEMP_RETIMER_0_1_0V9_VR];
1486 	baseboard_temp_metrics->system_temp_retimer_4_5_0v9_vr =
1487 		metrics->SystemTemperatures[SYSTEM_TEMP_RETIMER_4_5_0V9_VR];
1488 	baseboard_temp_metrics->system_temp_retimer_2_3_0v9_vr =
1489 		metrics->SystemTemperatures[SYSTEM_TEMP_RETIMER_2_3_0V9_VR];
1490 	baseboard_temp_metrics->system_temp_retimer_6_7_0v9_vr =
1491 		metrics->SystemTemperatures[SYSTEM_TEMP_RETIMER_6_7_0V9_VR];
1492 	baseboard_temp_metrics->system_temp_oam_0_1_2_3_3v3_vr =
1493 		metrics->SystemTemperatures[SYSTEM_TEMP_OAM_0_1_2_3_3V3_VR];
1494 	baseboard_temp_metrics->system_temp_oam_4_5_6_7_3v3_vr =
1495 		metrics->SystemTemperatures[SYSTEM_TEMP_OAM_4_5_6_7_3V3_VR];
1496 	baseboard_temp_metrics->system_temp_ibc_hsc =
1497 		metrics->SystemTemperatures[SYSTEM_TEMP_IBC_HSC];
1498 	baseboard_temp_metrics->system_temp_ibc =
1499 		metrics->SystemTemperatures[SYSTEM_TEMP_IBC];
1500 }
1501 
smu_v15_0_8_fill_gpuboard_temp_metrics(struct smu_v15_0_8_gpuboard_temp_metrics * gpuboard_temp_metrics,const SystemMetricsTable_t * metrics)1502 static void smu_v15_0_8_fill_gpuboard_temp_metrics(
1503 	struct smu_v15_0_8_gpuboard_temp_metrics *gpuboard_temp_metrics,
1504 	const SystemMetricsTable_t *metrics)
1505 {
1506 	gpuboard_temp_metrics->accumulation_counter = metrics->AccumulationCounter;
1507 	gpuboard_temp_metrics->label_version = metrics->LabelVersion;
1508 	gpuboard_temp_metrics->node_id = metrics->NodeIdentifier;
1509 
1510 	gpuboard_temp_metrics->node_temp_retimer =
1511 		metrics->NodeTemperatures[NODE_TEMP_RETIMER];
1512 	gpuboard_temp_metrics->node_temp_ibc =
1513 		metrics->NodeTemperatures[NODE_TEMP_IBC_TEMP];
1514 	gpuboard_temp_metrics->node_temp_ibc_2 =
1515 		metrics->NodeTemperatures[NODE_TEMP_IBC_2_TEMP];
1516 	gpuboard_temp_metrics->node_temp_vdd18_vr =
1517 		metrics->NodeTemperatures[NODE_TEMP_VDD18_VR_TEMP];
1518 	gpuboard_temp_metrics->node_temp_04_hbm_b_vr =
1519 		metrics->NodeTemperatures[NODE_TEMP_04_HBM_B_VR_TEMP];
1520 	gpuboard_temp_metrics->node_temp_04_hbm_d_vr =
1521 		metrics->NodeTemperatures[NODE_TEMP_04_HBM_D_VR_TEMP];
1522 
1523 	gpuboard_temp_metrics->vr_temp_vddcr_socio_a =
1524 		metrics->VrTemperatures[SVI_PLANE_VDDCR_SOCIO_A_TEMP];
1525 	gpuboard_temp_metrics->vr_temp_vddcr_socio_c =
1526 		metrics->VrTemperatures[SVI_PLANE_VDDCR_SOCIO_C_TEMP];
1527 	gpuboard_temp_metrics->vr_temp_vddcr_x0 =
1528 		metrics->VrTemperatures[SVI_PLANE_VDDCR_X0_TEMP];
1529 	gpuboard_temp_metrics->vr_temp_vddcr_x1 =
1530 		metrics->VrTemperatures[SVI_PLANE_VDDCR_X1_TEMP];
1531 	gpuboard_temp_metrics->vr_temp_vddio_hbm_b =
1532 		metrics->VrTemperatures[SVI_PLANE_VDDIO_HBM_B_TEMP];
1533 	gpuboard_temp_metrics->vr_temp_vddio_hbm_d =
1534 		metrics->VrTemperatures[SVI_PLANE_VDDIO_HBM_D_TEMP];
1535 	gpuboard_temp_metrics->vr_temp_vddio_04_hbm_b =
1536 		metrics->VrTemperatures[SVI_PLANE_VDDIO_04_HBM_B_TEMP];
1537 	gpuboard_temp_metrics->vr_temp_vddio_04_hbm_d =
1538 		metrics->VrTemperatures[SVI_PLANE_VDDIO_04_HBM_D_TEMP];
1539 	gpuboard_temp_metrics->vr_temp_vddcr_hbm_b =
1540 		metrics->VrTemperatures[SVI_PLANE_VDDCR_HBM_B_TEMP];
1541 	gpuboard_temp_metrics->vr_temp_vddcr_hbm_d =
1542 		metrics->VrTemperatures[SVI_PLANE_VDDCR_HBM_D_TEMP];
1543 	gpuboard_temp_metrics->vr_temp_vddcr_075_hbm_b =
1544 		metrics->VrTemperatures[SVI_PLANE_VDDCR_075_HBM_B_TEMP];
1545 	gpuboard_temp_metrics->vr_temp_vddcr_075_hbm_d =
1546 		metrics->VrTemperatures[SVI_PLANE_VDDCR_075_HBM_D_TEMP];
1547 	gpuboard_temp_metrics->vr_temp_vddio_11_gta_a =
1548 		metrics->VrTemperatures[SVI_PLANE_VDDIO_11_GTA_A_TEMP];
1549 	gpuboard_temp_metrics->vr_temp_vddio_11_gta_c =
1550 		metrics->VrTemperatures[SVI_PLANE_VDDIO_11_GTA_C_TEMP];
1551 	gpuboard_temp_metrics->vr_temp_vddan_075_gta_a =
1552 		metrics->VrTemperatures[SVI_PLANE_VDDAN_075_GTA_A_TEMP];
1553 	gpuboard_temp_metrics->vr_temp_vddan_075_gta_c =
1554 		metrics->VrTemperatures[SVI_PLANE_VDDAN_075_GTA_C_TEMP];
1555 	gpuboard_temp_metrics->vr_temp_vddcr_075_ucie =
1556 		metrics->VrTemperatures[SVI_PLANE_VDDCR_075_UCIE_TEMP];
1557 	gpuboard_temp_metrics->vr_temp_vddio_065_ucieaa =
1558 		metrics->VrTemperatures[SVI_PLANE_VDDIO_065_UCIEAA_TEMP];
1559 	gpuboard_temp_metrics->vr_temp_vddio_065_ucieam_a =
1560 		metrics->VrTemperatures[SVI_PLANE_VDDIO_065_UCIEAM_A_TEMP];
1561 	gpuboard_temp_metrics->vr_temp_vddio_065_ucieam_c =
1562 		metrics->VrTemperatures[SVI_PLANE_VDDIO_065_UCIEAM_C_TEMP];
1563 	gpuboard_temp_metrics->vr_temp_vddan_075 =
1564 		metrics->VrTemperatures[SVI_PLANE_VDDAN_075_TEMP];
1565 }
1566 
smu_v15_0_8_get_temp_metrics(struct smu_context * smu,enum smu_temp_metric_type type,void * table)1567 static ssize_t smu_v15_0_8_get_temp_metrics(struct smu_context *smu,
1568 					    enum smu_temp_metric_type type,
1569 					    void *table)
1570 {
1571 	struct smu_v15_0_8_baseboard_temp_metrics *baseboard_temp_metrics;
1572 	struct smu_v15_0_8_gpuboard_temp_metrics *gpuboard_temp_metrics;
1573 	struct smu_table_context *smu_table = &smu->smu_table;
1574 	struct smu_table *tables = smu_table->tables;
1575 	SystemMetricsTable_t *metrics;
1576 	struct smu_table *sys_table;
1577 	int ret;
1578 
1579 	ret = smu_v15_0_8_get_system_metrics_table(smu);
1580 	if (ret)
1581 		return ret;
1582 
1583 	sys_table = &tables[SMU_TABLE_PMFW_SYSTEM_METRICS];
1584 	metrics = (SystemMetricsTable_t *)sys_table->cache.buffer;
1585 
1586 	switch (type) {
1587 	case SMU_TEMP_METRIC_GPUBOARD:
1588 		gpuboard_temp_metrics =
1589 			(struct smu_v15_0_8_gpuboard_temp_metrics *)
1590 			smu_driver_table_ptr(smu, SMU_DRIVER_TABLE_GPUBOARD_TEMP_METRICS);
1591 		smu_driver_table_update_cache_time(smu, SMU_DRIVER_TABLE_GPUBOARD_TEMP_METRICS);
1592 		smu_v15_0_8_fill_gpuboard_temp_metrics(gpuboard_temp_metrics,
1593 						       metrics);
1594 		memcpy(table, gpuboard_temp_metrics, sizeof(*gpuboard_temp_metrics));
1595 		return sizeof(*gpuboard_temp_metrics);
1596 	case SMU_TEMP_METRIC_BASEBOARD:
1597 		baseboard_temp_metrics =
1598 			(struct smu_v15_0_8_baseboard_temp_metrics *)
1599 			smu_driver_table_ptr(smu, SMU_DRIVER_TABLE_BASEBOARD_TEMP_METRICS);
1600 		smu_driver_table_update_cache_time(smu, SMU_DRIVER_TABLE_BASEBOARD_TEMP_METRICS);
1601 		smu_v15_0_8_fill_baseboard_temp_metrics(baseboard_temp_metrics,
1602 							metrics);
1603 		memcpy(table, baseboard_temp_metrics, sizeof(*baseboard_temp_metrics));
1604 		return sizeof(*baseboard_temp_metrics);
1605 	default:
1606 		return -EINVAL;
1607 	}
1608 }
1609 
smu_v15_0_8_get_xcp_metrics(struct smu_context * smu,int xcp_id,void * table)1610 static ssize_t smu_v15_0_8_get_xcp_metrics(struct smu_context *smu, int xcp_id,
1611 					   void *table)
1612 {
1613 	struct smu_table_context *smu_table = &smu->smu_table;
1614 	const u8 num_jpeg_rings = NUM_JPEG_RINGS_FW;
1615 	struct smu_v15_0_8_partition_metrics *xcp_metrics;
1616 	MetricsTable_t *metrics;
1617 	struct amdgpu_device *adev = smu->adev;
1618 	int ret, inst, i, j, k, idx;
1619 	struct amdgpu_xcp *xcp;
1620 	u32 inst_mask;
1621 
1622 	if (!table)
1623 		return sizeof(*xcp_metrics);
1624 
1625 	for_each_xcp(adev->xcp_mgr, xcp, i) {
1626 		if (xcp->id == xcp_id)
1627 			break;
1628 	}
1629 	if (i == adev->xcp_mgr->num_xcps)
1630 		return -EINVAL;
1631 
1632 	xcp_metrics = (struct smu_v15_0_8_partition_metrics *)table;
1633 	smu_v15_0_8_partition_metrics_init(xcp_metrics, 1, 1);
1634 
1635 	ret = smu_v15_0_8_get_metrics_table_internal(smu, 1, NULL);
1636 	if (ret)
1637 		return ret;
1638 
1639 	metrics = (MetricsTable_t *)smu_table->metrics_table;
1640 
1641 	amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_VCN, &inst_mask);
1642 	idx = 0;
1643 	for_each_inst(k, inst_mask) {
1644 		/* Both JPEG and VCN has same instances */
1645 		inst = GET_INST(VCN, k);
1646 		for (j = 0; j < num_jpeg_rings; ++j) {
1647 			xcp_metrics->jpeg_busy[(idx * num_jpeg_rings) + j] =
1648 				SMUQ10_ROUND(metrics->JpegBusy[(inst * num_jpeg_rings) + j]);
1649 		}
1650 		xcp_metrics->vcn_busy[idx] =
1651 			SMUQ10_ROUND(metrics->VcnBusy[inst]);
1652 
1653 		xcp_metrics->current_vclk[idx] = SMUQ10_ROUND(metrics->VclkFrequency[inst]);
1654 		xcp_metrics->current_dclk[idx] = SMUQ10_ROUND(metrics->DclkFrequency[inst]);
1655 
1656 		idx++;
1657 	}
1658 
1659 	amdgpu_xcp_get_inst_details(xcp, AMDGPU_XCP_GFX, &inst_mask);
1660 	idx = 0;
1661 	for_each_inst(k, inst_mask) {
1662 		inst = GET_INST(GC, k);
1663 		xcp_metrics->current_gfxclk[idx] =
1664 			SMUQ10_ROUND(metrics->GfxclkFrequency[inst]);
1665 
1666 		xcp_metrics->gfx_busy_inst[idx] = SMUQ10_ROUND(metrics->GfxBusy[inst]);
1667 		xcp_metrics->gfx_busy_acc[idx] = SMUQ10_ROUND(metrics->GfxBusyAcc[inst]);
1668 		xcp_metrics->gfx_below_host_limit_ppt_acc[idx] =
1669 			SMUQ10_ROUND(metrics->GfxclkBelowHostLimitPptAcc[inst]);
1670 		xcp_metrics->gfx_below_host_limit_thm_acc[idx] =
1671 			SMUQ10_ROUND(metrics->GfxclkBelowHostLimitThmAcc[inst]);
1672 		xcp_metrics->gfx_low_utilization_acc[idx] =
1673 			SMUQ10_ROUND(metrics->GfxclkLowUtilizationAcc[inst]);
1674 		xcp_metrics->gfx_below_host_limit_total_acc[idx] =
1675 			SMUQ10_ROUND(metrics->GfxclkBelowHostLimitTotalAcc[inst]);
1676 		idx++;
1677 	}
1678 
1679 	xcp_metrics->accumulation_counter = metrics->AccumulationCounter;
1680 	xcp_metrics->firmware_timestamp = metrics->Timestamp;
1681 
1682 	return sizeof(*xcp_metrics);
1683 }
1684 
smu_v15_0_8_get_gpu_metrics(struct smu_context * smu,void ** table)1685 static ssize_t smu_v15_0_8_get_gpu_metrics(struct smu_context *smu, void **table)
1686 {
1687 	struct smu_table_context *smu_table = &smu->smu_table;
1688 	struct smu_v15_0_8_gpu_metrics *gpu_metrics;
1689 	struct amdgpu_device *adev = smu->adev;
1690 	int ret = 0, xcc_id, inst, i, j, idx;
1691 	uint32_t aid_mask = adev->aid_mask;
1692 	uint32_t mid_mask = adev->aid_mask;
1693 	MetricsTable_t *metrics;
1694 
1695 	ret = smu_v15_0_8_get_metrics_table_internal(smu, 1, NULL);
1696 	if (ret)
1697 		return ret;
1698 
1699 	metrics = (MetricsTable_t *)smu_table->metrics_table;
1700 	gpu_metrics = (struct smu_v15_0_8_gpu_metrics *)smu_driver_table_ptr(smu,
1701 		       SMU_DRIVER_TABLE_GPU_METRICS);
1702 
1703 	gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
1704 
1705 	gpu_metrics->temperature_hotspot = SMUQ10_ROUND(metrics->MaxSocketTemperature);
1706 
1707 	/* Per-HBM stack temperatures */
1708 	if (adev->umc.active_mask) {
1709 		u64 mask = adev->umc.active_mask;
1710 		int out_idx = 0;
1711 		u16 max_hbm_temp = 0;
1712 		int stack_idx;
1713 
1714 		if (unlikely(hweight64(mask) / 4 > SMU_15_0_8_MAX_HBM_STACKS)) {
1715 			dev_warn(adev->dev, "Invalid umc mask %lld\n", mask);
1716 		} else  {
1717 			for_each_hbm_stack(stack_idx, mask) {
1718 				u16 temp;
1719 
1720 				if (!hbm_stack_mask_valid(mask))
1721 					continue;
1722 				temp = SMUQ10_ROUND(metrics->HbmTemperature[stack_idx]);
1723 				gpu_metrics->temperature_hbm[out_idx++] = temp;
1724 				if (temp > max_hbm_temp)
1725 					max_hbm_temp = temp;
1726 			}
1727 			gpu_metrics->temperature_mem = max_hbm_temp;
1728 		}
1729 	}
1730 
1731 	/* Reports max temperature of all voltage rails */
1732 	gpu_metrics->temperature_vrsoc = SMUQ10_ROUND(metrics->MaxVrTemperature);
1733 	/* MID, AID, XCD temperatures */
1734 	idx = 0;
1735 	for_each_inst(i, mid_mask) {
1736 		gpu_metrics->temperature_mid[idx] = SMUQ10_ROUND(metrics->MidTemperature[i]);
1737 		idx++;
1738 	}
1739 
1740 	idx = 0;
1741 	for_each_inst(i, aid_mask) {
1742 		gpu_metrics->temperature_aid[idx] = SMUQ10_ROUND(metrics->AidTemperature[i]);
1743 		idx++;
1744 	}
1745 
1746 	for (i = 0; i < NUM_XCC(adev->gfx.xcc_mask); ++i) {
1747 		xcc_id = GET_INST(GC, i);
1748 		if (xcc_id >= 0)
1749 			gpu_metrics->temperature_xcd[i] = SMUQ10_ROUND(metrics->XcdTemperature[xcc_id]);
1750 	}
1751 	/* Power */
1752 	gpu_metrics->curr_socket_power = SMUQ10_ROUND(metrics->SocketPower);
1753 
1754 	gpu_metrics->average_gfx_activity = SMUQ10_ROUND(metrics->SocketGfxBusy);
1755 	gpu_metrics->average_umc_activity = SMUQ10_ROUND(metrics->DramBandwidthUtilization);
1756 	gpu_metrics->mem_max_bandwidth = SMUQ10_ROUND(metrics->MaxDramBandwidth);
1757 
1758 	/* Energy counter reported in 15.259uJ (2^-16) units */
1759 	gpu_metrics->energy_accumulator = metrics->SocketEnergyAcc;
1760 
1761 	for (i = 0; i < NUM_XCC(adev->gfx.xcc_mask); ++i) {
1762 		xcc_id = GET_INST(GC, i);
1763 		if (xcc_id >= 0) {
1764 			gpu_metrics->current_gfxclk[i] =
1765 				SMUQ10_ROUND(metrics->GfxclkFrequency[xcc_id]);
1766 		}
1767 	}
1768 
1769 	/* Per-MID clocks */
1770 	idx = 0;
1771 	for_each_inst(i, mid_mask) {
1772 		gpu_metrics->current_socclk[idx] = SMUQ10_ROUND(metrics->SocclkFrequency[i]);
1773 		idx++;
1774 	}
1775 
1776 	/* Per-VCN clocks and busy */
1777 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1778 		inst = GET_INST(VCN, i);
1779 		if (inst >= 0) {
1780 			gpu_metrics->current_vclk0[i] = SMUQ10_ROUND(metrics->VclkFrequency[inst]);
1781 			gpu_metrics->current_dclk0[i] = SMUQ10_ROUND(metrics->DclkFrequency[inst]);
1782 			gpu_metrics->vcn_busy[i] = SMUQ10_ROUND(metrics->VcnBusy[inst]);
1783 			for (j = 0; j < NUM_JPEG_RINGS_FW; ++j)
1784 				gpu_metrics->jpeg_busy[(i * NUM_JPEG_RINGS_FW) + j] =
1785 					SMUQ10_ROUND(metrics->JpegBusy[(inst * NUM_JPEG_RINGS_FW)
1786 								       + j]);
1787 		}
1788 	}
1789 
1790 	/* Per-AID clocks */
1791 	idx = 0;
1792 	for_each_inst(i, aid_mask) {
1793 		gpu_metrics->current_uclk[idx] = SMUQ10_ROUND(metrics->UclkFrequency[i]);
1794 		idx++;
1795 	}
1796 
1797 	/* Total accumulated cycle counter */
1798 	gpu_metrics->accumulation_counter = metrics->AccumulationCounter;
1799 
1800 	/* Accumulated throttler residencies */
1801 	gpu_metrics->prochot_residency_acc = metrics->ProchotResidencyAcc;
1802 	gpu_metrics->ppt_residency_acc = metrics->PptResidencyAcc;
1803 	gpu_metrics->socket_thm_residency_acc = metrics->SocketThmResidencyAcc;
1804 	gpu_metrics->vr_thm_residency_acc = metrics->VrThmResidencyAcc;
1805 	gpu_metrics->hbm_thm_residency_acc = metrics->HbmThmResidencyAcc;
1806 
1807 	gpu_metrics->gfx_activity_acc = SMUQ10_ROUND(metrics->SocketGfxBusyAcc);
1808 	gpu_metrics->mem_activity_acc = SMUQ10_ROUND(metrics->DramBandwidthUtilizationAcc);
1809 
1810 	for (i = 0; i < NUM_XGMI_LINKS; i++) {
1811 		j = amdgpu_xgmi_get_ext_link(adev, i);
1812 		if (j < 0 || j >= NUM_XGMI_LINKS)
1813 			continue;
1814 		ret = amdgpu_get_xgmi_link_status(adev, i);
1815 		if (ret >= 0)
1816 			gpu_metrics->xgmi_link_status[j] = ret;
1817 	}
1818 
1819 	gpu_metrics->xgmi_read_data_acc = SMUQ10_ROUND(metrics->XgmiReadBandwidthAcc);
1820 	gpu_metrics->xgmi_write_data_acc = SMUQ10_ROUND(metrics->XgmiWriteBandwidthAcc);
1821 
1822 	for (i = 0; i < NUM_XCC(adev->gfx.xcc_mask); ++i) {
1823 		inst = GET_INST(GC, i);
1824 		gpu_metrics->gfx_busy_inst[i] = SMUQ10_ROUND(metrics->GfxBusy[inst]);
1825 		gpu_metrics->gfx_busy_acc[i] = SMUQ10_ROUND(metrics->GfxBusyAcc[inst]);
1826 		gpu_metrics->gfx_below_host_limit_ppt_acc[i] =
1827 			SMUQ10_ROUND(metrics->GfxclkBelowHostLimitPptAcc[inst]);
1828 		gpu_metrics->gfx_below_host_limit_thm_acc[i] =
1829 			SMUQ10_ROUND(metrics->GfxclkBelowHostLimitThmAcc[inst]);
1830 		gpu_metrics->gfx_low_utilization_acc[i] =
1831 			SMUQ10_ROUND(metrics->GfxclkLowUtilizationAcc[inst]);
1832 		gpu_metrics->gfx_below_host_limit_total_acc[i] =
1833 			SMUQ10_ROUND(metrics->GfxclkBelowHostLimitTotalAcc[inst]);
1834 	}
1835 
1836 	gpu_metrics->xgmi_link_width = metrics->XgmiWidth;
1837 	gpu_metrics->xgmi_link_speed = metrics->XgmiBitrate;
1838 
1839 	gpu_metrics->firmware_timestamp = metrics->Timestamp;
1840 
1841 	*table = gpu_metrics;
1842 
1843 	smu_driver_table_update_cache_time(smu, SMU_DRIVER_TABLE_GPU_METRICS);
1844 
1845 	return sizeof(*gpu_metrics);
1846 }
1847 
smu_v15_0_8_get_unique_id(struct smu_context * smu)1848 static void smu_v15_0_8_get_unique_id(struct smu_context *smu)
1849 {
1850 	struct amdgpu_device *adev = smu->adev;
1851 	struct smu_table_context *smu_table = &smu->smu_table;
1852 	PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable;
1853 
1854 	adev->unique_id = pptable->PublicSerialNumberMID;
1855 }
1856 
smu_v15_0_8_get_ppt_limit(struct smu_context * smu,enum smu_ppt_limit_type limit_type,uint32_t * ppt_limit)1857 static int smu_v15_0_8_get_ppt_limit(struct smu_context *smu,
1858 				     enum smu_ppt_limit_type limit_type,
1859 				     uint32_t *ppt_limit)
1860 {
1861 	int ret;
1862 
1863 	if (limit_type == SMU_PPT_LIMIT_PPT1)
1864 		ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetFastPptLimit,
1865 					       ppt_limit);
1866 	else
1867 		ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetPptLimit,
1868 					       ppt_limit);
1869 	if (ret) {
1870 		dev_err(smu->adev->dev, "Couldn't get PPT limit");
1871 		return -EINVAL;
1872 	}
1873 
1874 	return 0;
1875 }
1876 
smu_v15_0_8_init_ppt_limits(struct smu_context * smu)1877 static int smu_v15_0_8_init_ppt_limits(struct smu_context *smu)
1878 {
1879 	struct smu_table_context *smu_table = &smu->smu_table;
1880 	PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable;
1881 	int i;
1882 
1883 	for (i = SMU_POWER_SOURCE_AC; i < SMU_POWER_SOURCE_COUNT; i++) {
1884 		smu->ppt_limits.range[i][SMU_PPT_LIMIT_PPT0].default_value =
1885 			pptable->MaxSocketPowerLimit;
1886 		smu->ppt_limits.range[i][SMU_PPT_LIMIT_PPT0].max =
1887 			pptable->MaxSocketPowerLimit;
1888 		smu->ppt_limits.range[i][SMU_PPT_LIMIT_PPT0].min = 0;
1889 		smu->ppt_limits.range[i][SMU_PPT_LIMIT_PPT0].od_max =
1890 			pptable->MaxSocketPowerLimit;
1891 		smu->ppt_limits.range[i][SMU_PPT_LIMIT_PPT0].od_min = 0;
1892 	}
1893 	smu->ppt_limits.supported_mask |= BIT(SMU_PPT_LIMIT_PPT0);
1894 
1895 	if (pptable->PPT1Max) {
1896 		for (i = SMU_POWER_SOURCE_AC; i < SMU_POWER_SOURCE_COUNT; i++) {
1897 			smu->ppt_limits.range[i][SMU_PPT_LIMIT_PPT1].default_value =
1898 				pptable->PPT1Default;
1899 			smu->ppt_limits.range[i][SMU_PPT_LIMIT_PPT1].max =
1900 				pptable->PPT1Max;
1901 			smu->ppt_limits.range[i][SMU_PPT_LIMIT_PPT1].min =
1902 				pptable->PPT1Min;
1903 			smu->ppt_limits.range[i][SMU_PPT_LIMIT_PPT1].od_max =
1904 				pptable->PPT1Max;
1905 			smu->ppt_limits.range[i][SMU_PPT_LIMIT_PPT1].od_min =
1906 				pptable->PPT1Min;
1907 		}
1908 		smu->ppt_limits.supported_mask |= BIT(SMU_PPT_LIMIT_PPT1);
1909 	}
1910 
1911 	return 0;
1912 }
1913 
smu_v15_0_8_populate_umd_state_clk(struct smu_context * smu)1914 static int smu_v15_0_8_populate_umd_state_clk(struct smu_context *smu)
1915 {
1916 	struct smu_15_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
1917 	struct smu_dpm_table *gfx_table = &dpm_context->dpm_tables.gfx_table;
1918 	struct smu_dpm_table *mem_table = &dpm_context->dpm_tables.uclk_table;
1919 	struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
1920 
1921 	pstate_table->gfxclk_pstate.curr.min = SMU_DPM_TABLE_MIN(gfx_table);
1922 	pstate_table->gfxclk_pstate.curr.max = SMU_DPM_TABLE_MAX(gfx_table);
1923 
1924 	pstate_table->uclk_pstate.curr.min = SMU_DPM_TABLE_MIN(mem_table);
1925 	pstate_table->uclk_pstate.curr.max = SMU_DPM_TABLE_MAX(mem_table);
1926 	return 0;
1927 }
1928 
smu_v15_0_8_set_gfx_soft_freq_limited_range(struct smu_context * smu,uint32_t min,uint32_t max)1929 static int smu_v15_0_8_set_gfx_soft_freq_limited_range(struct smu_context *smu,
1930 						       uint32_t min,
1931 						       uint32_t max)
1932 {
1933 	int ret;
1934 
1935 	ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
1936 					      max & 0xffff, NULL);
1937 	if (ret)
1938 		return ret;
1939 
1940 	ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinGfxclk,
1941 					      min & 0xffff, NULL);
1942 
1943 	return ret;
1944 }
1945 
smu_v15_0_8_set_performance_level(struct smu_context * smu,enum amd_dpm_forced_level level)1946 static int smu_v15_0_8_set_performance_level(struct smu_context *smu,
1947 					     enum amd_dpm_forced_level level)
1948 {
1949 	struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
1950 	struct smu_15_0_dpm_context *dpm_context = smu_dpm->dpm_context;
1951 	struct smu_dpm_table *gfx_table = &dpm_context->dpm_tables.gfx_table;
1952 	struct smu_dpm_table *uclk_table = &dpm_context->dpm_tables.uclk_table;
1953 	struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
1954 	int ret = 0;
1955 
1956 	switch (level) {
1957 	case AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM:
1958 		/* Determinism not supported on SMU v15.0.8 */
1959 		ret = -EOPNOTSUPP;
1960 		break;
1961 
1962 	case AMD_DPM_FORCED_LEVEL_AUTO:
1963 		/* Restore GFXCLK to default range */
1964 		if ((SMU_DPM_TABLE_MIN(gfx_table) !=
1965 		     pstate_table->gfxclk_pstate.curr.min) ||
1966 		    (SMU_DPM_TABLE_MAX(gfx_table) !=
1967 		     pstate_table->gfxclk_pstate.curr.max)) {
1968 			ret = smu_v15_0_8_set_gfx_soft_freq_limited_range(
1969 				smu, SMU_DPM_TABLE_MIN(gfx_table),
1970 				SMU_DPM_TABLE_MAX(gfx_table));
1971 			if (ret)
1972 				goto out;
1973 
1974 			pstate_table->gfxclk_pstate.curr.min =
1975 				SMU_DPM_TABLE_MIN(gfx_table);
1976 			pstate_table->gfxclk_pstate.curr.max =
1977 				SMU_DPM_TABLE_MAX(gfx_table);
1978 		}
1979 
1980 		/* Restore UCLK to default max */
1981 		if (SMU_DPM_TABLE_MAX(uclk_table) !=
1982 		    pstate_table->uclk_pstate.curr.max) {
1983 			/* Min UCLK is not expected to be changed */
1984 			ret = smu_v15_0_set_soft_freq_limited_range(smu,
1985 								    SMU_UCLK, 0,
1986 								    SMU_DPM_TABLE_MAX(uclk_table),
1987 								    false);
1988 			if (ret)
1989 				goto out;
1990 
1991 			pstate_table->uclk_pstate.curr.max =
1992 				SMU_DPM_TABLE_MAX(uclk_table);
1993 		}
1994 
1995 		smu_cmn_reset_custom_level(smu);
1996 
1997 		break;
1998 	case AMD_DPM_FORCED_LEVEL_MANUAL:
1999 		ret = 0;
2000 		break;
2001 	default:
2002 		ret = -EOPNOTSUPP;
2003 		break;
2004 	}
2005 
2006 out:
2007 	return ret;
2008 }
2009 
smu_v15_0_8_set_soft_freq_limited_range(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t min,uint32_t max,bool automatic)2010 static int smu_v15_0_8_set_soft_freq_limited_range(struct smu_context *smu,
2011 						   enum smu_clk_type clk_type,
2012 						   uint32_t min, uint32_t max,
2013 						   bool automatic)
2014 {
2015 	struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
2016 	struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
2017 	int ret = 0;
2018 
2019 	if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK &&
2020 	    clk_type != SMU_UCLK)
2021 		return -EINVAL;
2022 
2023 	if (smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
2024 		return -EINVAL;
2025 
2026 	if (min >= max) {
2027 		dev_err(smu->adev->dev,
2028 			"Minimum clk should be less than the maximum allowed clock\n");
2029 		return -EINVAL;
2030 	}
2031 
2032 	if (clk_type == SMU_GFXCLK || clk_type == SMU_SCLK) {
2033 		if ((min == pstate_table->gfxclk_pstate.curr.min) &&
2034 		    (max == pstate_table->gfxclk_pstate.curr.max))
2035 			return 0;
2036 
2037 		ret = smu_v15_0_8_set_gfx_soft_freq_limited_range(smu, min,
2038 								  max);
2039 		if (!ret) {
2040 			pstate_table->gfxclk_pstate.curr.min = min;
2041 			pstate_table->gfxclk_pstate.curr.max = max;
2042 		}
2043 	}
2044 
2045 	if (clk_type == SMU_UCLK) {
2046 		if (max == pstate_table->uclk_pstate.curr.max)
2047 			return 0;
2048 
2049 		ret = smu_v15_0_set_soft_freq_limited_range(smu, SMU_UCLK, 0,
2050 							    max, false);
2051 		if (!ret)
2052 			pstate_table->uclk_pstate.curr.max = max;
2053 	}
2054 
2055 	return ret;
2056 }
2057 
smu_v15_0_8_od_edit_dpm_table(struct smu_context * smu,enum PP_OD_DPM_TABLE_COMMAND type,long input[],uint32_t size)2058 static int smu_v15_0_8_od_edit_dpm_table(struct smu_context *smu,
2059 					 enum PP_OD_DPM_TABLE_COMMAND type,
2060 					 long input[], uint32_t size)
2061 {
2062 	struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
2063 	struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
2064 	struct smu_15_0_dpm_context *dpm_context = smu_dpm->dpm_context;
2065 	uint32_t min_clk, max_clk;
2066 	int ret;
2067 
2068 	/* Only allowed in manual mode */
2069 	if (smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL)
2070 		return -EINVAL;
2071 
2072 	switch (type) {
2073 	case PP_OD_EDIT_SCLK_VDDC_TABLE:
2074 		if (size != 2) {
2075 			dev_err(smu->adev->dev,
2076 				"Input parameter number not correct\n");
2077 			return -EINVAL;
2078 		}
2079 		min_clk = SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.gfx_table);
2080 		max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.gfx_table);
2081 		if (input[0] == 0) {
2082 			if (input[1] < min_clk) {
2083 				dev_warn(smu->adev->dev,
2084 					 "Minimum GFX clk (%ld) MHz specified is less than the minimum allowed (%d) MHz\n",
2085 					input[1], min_clk);
2086 				pstate_table->gfxclk_pstate.custom.min =
2087 					pstate_table->gfxclk_pstate.curr.min;
2088 				return -EINVAL;
2089 			}
2090 
2091 			pstate_table->gfxclk_pstate.custom.min = input[1];
2092 		} else if (input[0] == 1) {
2093 			if (input[1] > max_clk) {
2094 				dev_warn(smu->adev->dev,
2095 					 "Maximum GFX clk (%ld) MHz specified is greater than the maximum allowed (%d) MHz\n",
2096 					input[1], max_clk);
2097 				pstate_table->gfxclk_pstate.custom.max =
2098 					pstate_table->gfxclk_pstate.curr.max;
2099 				return -EINVAL;
2100 			}
2101 
2102 			pstate_table->gfxclk_pstate.custom.max = input[1];
2103 		} else {
2104 			return -EINVAL;
2105 		}
2106 		break;
2107 	case PP_OD_EDIT_MCLK_VDDC_TABLE:
2108 		if (size != 2) {
2109 			dev_err(smu->adev->dev,
2110 				"Input parameter number not correct\n");
2111 			return -EINVAL;
2112 		}
2113 
2114 		if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
2115 			dev_warn(smu->adev->dev,
2116 				 "UCLK_LIMITS setting not supported!\n");
2117 			return -EOPNOTSUPP;
2118 		}
2119 		max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.uclk_table);
2120 		if (input[0] == 0) {
2121 			dev_info(smu->adev->dev,
2122 				 "Setting min UCLK level is not supported");
2123 			return -EINVAL;
2124 		} else if (input[0] == 1) {
2125 			if (input[1] > max_clk) {
2126 				dev_warn(smu->adev->dev,
2127 					 "Maximum UCLK (%ld) MHz specified is greater than the maximum allowed (%d) MHz\n",
2128 					input[1], max_clk);
2129 				pstate_table->uclk_pstate.custom.max =
2130 					pstate_table->uclk_pstate.curr.max;
2131 
2132 				return -EINVAL;
2133 			}
2134 
2135 			pstate_table->uclk_pstate.custom.max = input[1];
2136 		}
2137 		break;
2138 	case PP_OD_RESTORE_DEFAULT_TABLE:
2139 		if (size != 0) {
2140 			dev_err(smu->adev->dev,
2141 				"Input parameter number not correct\n");
2142 			return -EINVAL;
2143 		}
2144 
2145 		/* Use the default frequencies for manual mode */
2146 		min_clk = SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.gfx_table);
2147 		max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.gfx_table);
2148 
2149 		ret = smu_v15_0_8_set_soft_freq_limited_range(smu,
2150 							      SMU_GFXCLK,
2151 							      min_clk, max_clk,
2152 							      false);
2153 		if (ret)
2154 			return ret;
2155 
2156 		min_clk = SMU_DPM_TABLE_MIN(&dpm_context->dpm_tables.uclk_table);
2157 		max_clk = SMU_DPM_TABLE_MAX(&dpm_context->dpm_tables.uclk_table);
2158 		ret = smu_v15_0_8_set_soft_freq_limited_range(smu,
2159 							      SMU_UCLK,
2160 							      min_clk, max_clk,
2161 							      false);
2162 		if (ret)
2163 			return ret;
2164 
2165 		smu_cmn_reset_custom_level(smu);
2166 		break;
2167 	case PP_OD_COMMIT_DPM_TABLE:
2168 		if (size != 0) {
2169 			dev_err(smu->adev->dev,
2170 				"Input parameter number not correct\n");
2171 			return -EINVAL;
2172 		}
2173 
2174 		if (!pstate_table->gfxclk_pstate.custom.min)
2175 			pstate_table->gfxclk_pstate.custom.min =
2176 				pstate_table->gfxclk_pstate.curr.min;
2177 
2178 		if (!pstate_table->gfxclk_pstate.custom.max)
2179 			pstate_table->gfxclk_pstate.custom.max =
2180 				pstate_table->gfxclk_pstate.curr.max;
2181 
2182 		min_clk = pstate_table->gfxclk_pstate.custom.min;
2183 		max_clk = pstate_table->gfxclk_pstate.custom.max;
2184 
2185 		ret = smu_v15_0_8_set_soft_freq_limited_range(smu,
2186 							      SMU_GFXCLK,
2187 							      min_clk, max_clk,
2188 							      false);
2189 		if (ret)
2190 			return ret;
2191 
2192 		/* Commit UCLK custom range (only max supported) */
2193 		if (pstate_table->uclk_pstate.custom.max) {
2194 			min_clk = pstate_table->uclk_pstate.curr.min;
2195 			max_clk = pstate_table->uclk_pstate.custom.max;
2196 			ret = smu_v15_0_8_set_soft_freq_limited_range(smu,
2197 								      SMU_UCLK,
2198 								      min_clk, max_clk,
2199 								      false);
2200 			if (ret)
2201 				return ret;
2202 		}
2203 
2204 		break;
2205 	default:
2206 		return -ENOSYS;
2207 	}
2208 
2209 	return 0;
2210 }
2211 
smu_v15_0_8_get_thermal_temperature_range(struct smu_context * smu,struct smu_temperature_range * range)2212 static int smu_v15_0_8_get_thermal_temperature_range(struct smu_context *smu,
2213 						     struct smu_temperature_range *range)
2214 {
2215 	struct smu_table_context *smu_table = &smu->smu_table;
2216 	PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable;
2217 	uint32_t max_ctf, max_thm;
2218 
2219 	if (amdgpu_sriov_multi_vf_mode(smu->adev))
2220 		return 0;
2221 
2222 	if (!range)
2223 		return -EINVAL;
2224 
2225 	/* CTF (Critical Temperature Fault) limits */
2226 	max_ctf = max3(pptable->CTFLimitMID, pptable->CTFLimitXCD,
2227 		       pptable->CTFLimitAID);
2228 	range->hotspot_emergency_max = max_ctf * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
2229 
2230 	range->mem_emergency_max = pptable->CTFLimitHBM *
2231 				   SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
2232 
2233 	/* Thermal throttling limits */
2234 	max_thm = max3(pptable->ThermalLimitMID, pptable->ThermalLimitXCD,
2235 		       pptable->ThermalLimitAID);
2236 	range->hotspot_crit_max = max_thm * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
2237 
2238 	range->mem_crit_max = pptable->ThermalLimitHBM *
2239 			      SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
2240 
2241 	return 0;
2242 }
2243 
smu_v15_0_8_set_ppt_limit(struct smu_context * smu,enum smu_ppt_limit_type limit_type,uint32_t limit)2244 static int smu_v15_0_8_set_ppt_limit(struct smu_context *smu,
2245 				     enum smu_ppt_limit_type limit_type,
2246 				     uint32_t limit)
2247 {
2248 	struct smu_table_context *smu_table = &smu->smu_table;
2249 	PPTable_t *pptable = (PPTable_t *)smu_table->driver_pptable;
2250 	int ret;
2251 
2252 	if (limit_type == SMU_PPT_LIMIT_PPT1) {
2253 		if (!pptable->PPT1Max)
2254 			return -EOPNOTSUPP;
2255 
2256 		if (limit > pptable->PPT1Max || limit < pptable->PPT1Min) {
2257 			dev_err(smu->adev->dev,
2258 				"New PPT1 limit (%d) should be between min %d and max %d\n",
2259 				limit, pptable->PPT1Min, pptable->PPT1Max);
2260 			return -EINVAL;
2261 		}
2262 
2263 		ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetFastPptLimit,
2264 						      limit, NULL);
2265 		if (ret)
2266 			dev_err(smu->adev->dev, "Set fast PPT limit failed!\n");
2267 
2268 		return ret;
2269 	}
2270 
2271 	return smu_v15_0_set_ppt_limit(smu, limit_type, limit);
2272 }
2273 
smu_v15_0_8_get_throttler_status(struct smu_context * smu)2274 static uint32_t smu_v15_0_8_get_throttler_status(struct smu_context *smu)
2275 {
2276 	struct smu_power_context *smu_power = &smu->smu_power;
2277 	struct smu_15_0_power_context *power_context = smu_power->power_context;
2278 	uint32_t throttler_status = 0;
2279 
2280 	throttler_status = atomic_read(&power_context->throttle_status);
2281 	dev_dbg(smu->adev->dev, "SMU Throttler status: %u", throttler_status);
2282 
2283 	return throttler_status;
2284 }
2285 
2286 static const char *const throttling_logging_label[] = {
2287 	[THROTTLER_PROCHOT_BIT] = "Prochot",
2288 	[THROTTLER_THERMAL_SOCKET_BIT] = "SOC",
2289 	[THROTTLER_THERMAL_VR_BIT] = "VR",
2290 	[THROTTLER_THERMAL_HBM_BIT] = "HBM"
2291 };
2292 
smu_v15_0_8_log_thermal_throttling_event(struct smu_context * smu)2293 static void smu_v15_0_8_log_thermal_throttling_event(struct smu_context *smu)
2294 {
2295 	int throttler_idx, throttling_events = 0, buf_idx = 0;
2296 	struct amdgpu_device *adev = smu->adev;
2297 	uint32_t throttler_status;
2298 	char log_buf[256];
2299 
2300 	throttler_status = smu_v15_0_8_get_throttler_status(smu);
2301 	if (!throttler_status)
2302 		return;
2303 
2304 	memset(log_buf, 0, sizeof(log_buf));
2305 	for (throttler_idx = 0;
2306 	     throttler_idx < ARRAY_SIZE(throttling_logging_label);
2307 	     throttler_idx++) {
2308 		if (throttler_status & (1U << throttler_idx)) {
2309 			throttling_events++;
2310 			buf_idx += snprintf(
2311 				log_buf + buf_idx, sizeof(log_buf) - buf_idx,
2312 				"%s%s", throttling_events > 1 ? " and " : "",
2313 				throttling_logging_label[throttler_idx]);
2314 			if (buf_idx >= sizeof(log_buf)) {
2315 				dev_err(adev->dev, "buffer overflow!\n");
2316 				log_buf[sizeof(log_buf) - 1] = '\0';
2317 				break;
2318 			}
2319 		}
2320 	}
2321 
2322 	dev_warn(adev->dev,
2323 		 "WARN: GPU is throttled, expect performance decrease. %s.\n",
2324 		 log_buf);
2325 	kgd2kfd_smi_event_throttle(
2326 		smu->adev->kfd.dev,
2327 		smu_cmn_get_indep_throttler_status(throttler_status,
2328 						   smu_v15_0_8_throttler_map));
2329 }
2330 
smu_v15_0_8_enable_thermal_alert(struct smu_context * smu)2331 static int smu_v15_0_8_enable_thermal_alert(struct smu_context *smu)
2332 {
2333 	if (!smu->irq_source.num_types)
2334 		return 0;
2335 
2336 	return amdgpu_irq_get(smu->adev, &smu->irq_source, 0);
2337 }
2338 
2339 static const struct pptable_funcs smu_v15_0_8_ppt_funcs = {
2340 	.init_allowed_features = smu_v15_0_8_init_allowed_features,
2341 	.set_default_dpm_table = smu_v15_0_8_set_default_dpm_table,
2342 	.is_dpm_running = smu_v15_0_8_is_dpm_running,
2343 	.init_smc_tables = smu_v15_0_8_init_smc_tables,
2344 	.fini_smc_tables = smu_v15_0_8_fini_smc_tables,
2345 	.init_power = smu_v15_0_init_power,
2346 	.fini_power = smu_v15_0_fini_power,
2347 	.check_fw_status = smu_v15_0_8_check_fw_status,
2348 	.check_fw_version = smu_cmn_check_fw_version,
2349 	.set_driver_table_location = smu_v15_0_set_driver_table_location,
2350 	.set_tool_table_location = smu_v15_0_set_tool_table_location,
2351 	.notify_memory_pool_location = smu_v15_0_notify_memory_pool_location,
2352 	.system_features_control = smu_v15_0_8_system_features_control,
2353 	.get_enabled_mask = smu_v15_0_8_get_enabled_mask,
2354 	.feature_is_enabled = smu_cmn_feature_is_enabled,
2355 	.register_irq_handler = smu_v15_0_8_register_irq_handler,
2356 	.enable_thermal_alert = smu_v15_0_8_enable_thermal_alert,
2357 	.disable_thermal_alert = smu_v15_0_disable_thermal_alert,
2358 	.log_thermal_throttling_event = smu_v15_0_8_log_thermal_throttling_event,
2359 	.setup_pptable = smu_v15_0_8_setup_pptable,
2360 	.get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
2361 	.wait_for_event = smu_v15_0_wait_for_event,
2362 	.get_pm_metrics = smu_v15_0_8_get_pm_metrics,
2363 	.get_xcp_metrics = smu_v15_0_8_get_xcp_metrics,
2364 	.mode2_reset = smu_v15_0_8_mode2_reset,
2365 	.get_dpm_ultimate_freq = smu_v15_0_8_get_dpm_ultimate_freq,
2366 	.get_gpu_metrics = smu_v15_0_8_get_gpu_metrics,
2367 	.get_unique_id = smu_v15_0_8_get_unique_id,
2368 	.get_ppt_limit = smu_v15_0_8_get_ppt_limit,
2369 	.set_ppt_limit = smu_v15_0_8_set_ppt_limit,
2370 	.emit_clk_levels = smu_v15_0_8_emit_clk_levels,
2371 	.read_sensor = smu_v15_0_8_read_sensor,
2372 	.populate_umd_state_clk = smu_v15_0_8_populate_umd_state_clk,
2373 	.set_performance_level = smu_v15_0_8_set_performance_level,
2374 	.od_edit_dpm_table = smu_v15_0_8_od_edit_dpm_table,
2375 	.get_thermal_temperature_range = smu_v15_0_8_get_thermal_temperature_range,
2376 };
2377 
smu_v15_0_8_init_msg_ctl(struct smu_context * smu,const struct cmn2asic_msg_mapping * message_map)2378 static void smu_v15_0_8_init_msg_ctl(struct smu_context *smu,
2379 				     const struct cmn2asic_msg_mapping *message_map)
2380 {
2381 	struct amdgpu_device *adev = smu->adev;
2382 	struct smu_msg_ctl *ctl = &smu->msg_ctl;
2383 
2384 	ctl->smu = smu;
2385 	mutex_init(&ctl->lock);
2386 	ctl->config.msg_reg = SOC15_REG_OFFSET(MP1, 0, regMP1_SMN_C2PMSG_40);
2387 	ctl->config.resp_reg = SOC15_REG_OFFSET(MP1, 0, regMP1_SMN_C2PMSG_41);
2388 	ctl->config.arg_regs[0] = SOC15_REG_OFFSET(MP1, 0, regMP1_SMN_C2PMSG_42);
2389 	ctl->config.arg_regs[1] = SOC15_REG_OFFSET(MP1, 0, regMP1_SMN_C2PMSG_43);
2390 	ctl->config.arg_regs[2] = SOC15_REG_OFFSET(MP1, 0, regMP1_SMN_C2PMSG_44);
2391 	ctl->config.arg_regs[3] = SOC15_REG_OFFSET(MP1, 0, regMP1_SMN_C2PMSG_45);
2392 	ctl->config.num_arg_regs = 4;
2393 	ctl->ops = &smu_msg_v1_ops;
2394 	ctl->default_timeout = adev->usec_timeout * 20;
2395 	ctl->message_map = message_map;
2396 }
2397 
2398 static const struct smu_temp_funcs smu_v15_0_8_temp_funcs = {
2399 	.temp_metrics_is_supported = smu_v15_0_8_is_temp_metrics_supported,
2400 	.get_temp_metrics = smu_v15_0_8_get_temp_metrics,
2401 };
2402 
smu_v15_0_8_set_ppt_funcs(struct smu_context * smu)2403 void smu_v15_0_8_set_ppt_funcs(struct smu_context *smu)
2404 {
2405 	smu->ppt_funcs = &smu_v15_0_8_ppt_funcs;
2406 	smu->clock_map = smu_v15_0_8_clk_map;
2407 	smu->feature_map = smu_v15_0_8_feature_mask_map;
2408 	smu->table_map = smu_v15_0_8_table_map;
2409 	smu_v15_0_8_init_msg_ctl(smu, smu_v15_0_8_message_map);
2410 	smu->smu_temp.temp_funcs = &smu_v15_0_8_temp_funcs;
2411 	smu->smc_driver_if_version = SMU15_DRIVER_IF_VERSION_SMU_V15_0_8;
2412 }
2413