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