]> git.ipfire.org Git - thirdparty/linux.git/blame - drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_6_ppt.c
drm/amdgpu: correct smu v13.0.6 umc ras error check
[thirdparty/linux.git] / drivers / gpu / drm / amd / pm / swsmu / smu13 / smu_v13_0_6_ppt.c
CommitLineData
511a9555
LL
1/*
2 * Copyright 2021 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 "atomfirmware.h"
30#include "amdgpu_atomfirmware.h"
31#include "amdgpu_atombios.h"
32#include "smu_v13_0_6_pmfw.h"
33#include "smu13_driver_if_v13_0_6.h"
34#include "smu_v13_0_6_ppsmc.h"
35#include "soc15_common.h"
36#include "atom.h"
37#include "power_state.h"
38#include "smu_v13_0.h"
39#include "smu_v13_0_6_ppt.h"
40#include "nbio/nbio_7_4_offset.h"
41#include "nbio/nbio_7_4_sh_mask.h"
42#include "thm/thm_11_0_2_offset.h"
43#include "thm/thm_11_0_2_sh_mask.h"
44#include "amdgpu_xgmi.h"
45#include <linux/pci.h>
46#include "amdgpu_ras.h"
25396684 47#include "amdgpu_mca.h"
511a9555
LL
48#include "smu_cmn.h"
49#include "mp/mp_13_0_6_offset.h"
50#include "mp/mp_13_0_6_sh_mask.h"
bf13da6a 51#include "umc_v12_0.h"
511a9555
LL
52
53#undef MP1_Public
54#undef smnMP1_FIRMWARE_FLAGS
55
56/* TODO: Check final register offsets */
57#define MP1_Public 0x03b00000
58#define smnMP1_FIRMWARE_FLAGS 0x3010028
59/*
60 * DO NOT use these for err/warn/info/debug messages.
61 * Use dev_err, dev_warn, dev_info and dev_dbg instead.
62 * They are more MGPU friendly.
63 */
64#undef pr_err
65#undef pr_warn
66#undef pr_info
67#undef pr_debug
68
f20f3b0d
LL
69MODULE_FIRMWARE("amdgpu/smu_13_0_6.bin");
70
511a9555
LL
71#define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c))
72
73#define SMU_13_0_6_FEA_MAP(smu_feature, smu_13_0_6_feature) \
74 [smu_feature] = { 1, (smu_13_0_6_feature) }
75
76#define FEATURE_MASK(feature) (1ULL << feature)
77#define SMC_DPM_FEATURE \
78 (FEATURE_MASK(FEATURE_DATA_CALCULATION) | \
79 FEATURE_MASK(FEATURE_DPM_GFXCLK) | FEATURE_MASK(FEATURE_DPM_UCLK) | \
80 FEATURE_MASK(FEATURE_DPM_SOCCLK) | FEATURE_MASK(FEATURE_DPM_FCLK) | \
81 FEATURE_MASK(FEATURE_DPM_LCLK) | FEATURE_MASK(FEATURE_DPM_XGMI) | \
82 FEATURE_MASK(FEATURE_DPM_VCN))
83
84/* possible frequency drift (1Mhz) */
85#define EPSILON 1
86
f1d1abd6 87#define smnPCIE_ESM_CTRL 0x93D0
1d02ae4e 88#define smnPCIE_LC_LINK_WIDTH_CNTL 0x1a340288
1718e973
LL
89#define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD_MASK 0x00000070L
90#define PCIE_LC_LINK_WIDTH_CNTL__LC_LINK_WIDTH_RD__SHIFT 0x4
1d02ae4e 91#define MAX_LINK_WIDTH 6
511a9555 92
f1d1abd6
AK
93#define smnPCIE_LC_SPEED_CNTL 0x1a340290
94#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK 0xE0
95#define PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT 0x5
96#define LINK_SPEED_MAX 4
97
5a2913aa 98#define SMU_13_0_6_DSCLK_THRESHOLD 140
cad2fb19 99
25396684
YW
100#define MCA_BANK_IPID(_ip, _hwid, _type) \
101 [AMDGPU_MCA_IP_##_ip] = { .hwid = _hwid, .mcatype = _type, }
102
103enum mca_reg_idx {
104 MCA_REG_IDX_CONTROL = 0,
105 MCA_REG_IDX_STATUS = 1,
106 MCA_REG_IDX_ADDR = 2,
107 MCA_REG_IDX_MISC0 = 3,
108 MCA_REG_IDX_CONFIG = 4,
109 MCA_REG_IDX_IPID = 5,
110 MCA_REG_IDX_SYND = 6,
111 MCA_REG_IDX_COUNT = 16,
112};
113
114struct mca_bank_ipid {
115 enum amdgpu_mca_ip ip;
116 uint16_t hwid;
117 uint16_t mcatype;
118};
119
120struct mca_ras_info {
121 enum amdgpu_ras_block blkid;
122 enum amdgpu_mca_ip ip;
123 int *err_code_array;
124 int err_code_count;
125 int (*get_err_count)(const struct mca_ras_info *mca_ras, struct amdgpu_device *adev,
126 enum amdgpu_mca_error_type type, int idx, uint32_t *count);
127};
128
f20f3b0d
LL
129#define P2S_TABLE_ID_A 0x50325341
130#define P2S_TABLE_ID_X 0x50325358
131
511a9555
LL
132static const struct cmn2asic_msg_mapping smu_v13_0_6_message_map[SMU_MSG_MAX_COUNT] = {
133 MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0),
134 MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1),
135 MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 1),
ae77d2fa
YW
136 MSG_MAP(EnableAllSmuFeatures, PPSMC_MSG_EnableAllSmuFeatures, 0),
137 MSG_MAP(DisableAllSmuFeatures, PPSMC_MSG_DisableAllSmuFeatures, 0),
511a9555
LL
138 MSG_MAP(RequestI2cTransaction, PPSMC_MSG_RequestI2cTransaction, 0),
139 MSG_MAP(GetMetricsTable, PPSMC_MSG_GetMetricsTable, 1),
140 MSG_MAP(GetEnabledSmuFeaturesHigh, PPSMC_MSG_GetEnabledSmuFeaturesHigh, 1),
141 MSG_MAP(GetEnabledSmuFeaturesLow, PPSMC_MSG_GetEnabledSmuFeaturesLow, 1),
142 MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 1),
143 MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 1),
144 MSG_MAP(SetToolsDramAddrHigh, PPSMC_MSG_SetToolsDramAddrHigh, 0),
145 MSG_MAP(SetToolsDramAddrLow, PPSMC_MSG_SetToolsDramAddrLow, 0),
146 MSG_MAP(SetSoftMinByFreq, PPSMC_MSG_SetSoftMinByFreq, 0),
147 MSG_MAP(SetSoftMaxByFreq, PPSMC_MSG_SetSoftMaxByFreq, 0),
ae77d2fa
YW
148 MSG_MAP(GetMinDpmFreq, PPSMC_MSG_GetMinDpmFreq, 1),
149 MSG_MAP(GetMaxDpmFreq, PPSMC_MSG_GetMaxDpmFreq, 1),
511a9555
LL
150 MSG_MAP(GetDpmFreqByIndex, PPSMC_MSG_GetDpmFreqByIndex, 1),
151 MSG_MAP(SetPptLimit, PPSMC_MSG_SetPptLimit, 0),
152 MSG_MAP(GetPptLimit, PPSMC_MSG_GetPptLimit, 1),
153 MSG_MAP(GfxDeviceDriverReset, PPSMC_MSG_GfxDriverReset, 0),
154 MSG_MAP(DramLogSetDramAddrHigh, PPSMC_MSG_DramLogSetDramAddrHigh, 0),
155 MSG_MAP(DramLogSetDramAddrLow, PPSMC_MSG_DramLogSetDramAddrLow, 0),
156 MSG_MAP(DramLogSetDramSize, PPSMC_MSG_DramLogSetDramSize, 0),
157 MSG_MAP(GetDebugData, PPSMC_MSG_GetDebugData, 0),
158 MSG_MAP(SetNumBadHbmPagesRetired, PPSMC_MSG_SetNumBadHbmPagesRetired, 0),
159 MSG_MAP(DFCstateControl, PPSMC_MSG_DFCstateControl, 0),
160 MSG_MAP(GetGmiPwrDnHyst, PPSMC_MSG_GetGmiPwrDnHyst, 0),
161 MSG_MAP(SetGmiPwrDnHyst, PPSMC_MSG_SetGmiPwrDnHyst, 0),
162 MSG_MAP(GmiPwrDnControl, PPSMC_MSG_GmiPwrDnControl, 0),
163 MSG_MAP(EnterGfxoff, PPSMC_MSG_EnterGfxoff, 0),
164 MSG_MAP(ExitGfxoff, PPSMC_MSG_ExitGfxoff, 0),
165 MSG_MAP(EnableDeterminism, PPSMC_MSG_EnableDeterminism, 0),
166 MSG_MAP(DisableDeterminism, PPSMC_MSG_DisableDeterminism, 0),
167 MSG_MAP(GfxDriverResetRecovery, PPSMC_MSG_GfxDriverResetRecovery, 0),
ae77d2fa
YW
168 MSG_MAP(GetMinGfxclkFrequency, PPSMC_MSG_GetMinGfxDpmFreq, 1),
169 MSG_MAP(GetMaxGfxclkFrequency, PPSMC_MSG_GetMaxGfxDpmFreq, 1),
511a9555
LL
170 MSG_MAP(SetSoftMinGfxclk, PPSMC_MSG_SetSoftMinGfxClk, 0),
171 MSG_MAP(SetSoftMaxGfxClk, PPSMC_MSG_SetSoftMaxGfxClk, 0),
7214c08c 172 MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareForDriverUnload, 0),
07864911 173 MSG_MAP(GetCTFLimit, PPSMC_MSG_GetCTFLimit, 0),
df7a2808 174 MSG_MAP(GetThermalLimit, PPSMC_MSG_ReadThrottlerLimit, 0),
df38fe12 175 MSG_MAP(ClearMcaOnRead, PPSMC_MSG_ClearMcaOnRead, 0),
bcd8dc49
YW
176 MSG_MAP(QueryValidMcaCount, PPSMC_MSG_QueryValidMcaCount, 0),
177 MSG_MAP(QueryValidMcaCeCount, PPSMC_MSG_QueryValidMcaCeCount, 0),
178 MSG_MAP(McaBankDumpDW, PPSMC_MSG_McaBankDumpDW, 0),
179 MSG_MAP(McaBankCeDumpDW, PPSMC_MSG_McaBankCeDumpDW, 0),
d07f1c20 180 MSG_MAP(SelectPLPDMode, PPSMC_MSG_SelectPLPDMode, 0),
511a9555
LL
181};
182
183static const struct cmn2asic_mapping smu_v13_0_6_clk_map[SMU_CLK_COUNT] = {
184 CLK_MAP(SOCCLK, PPCLK_SOCCLK),
185 CLK_MAP(FCLK, PPCLK_FCLK),
186 CLK_MAP(UCLK, PPCLK_UCLK),
187 CLK_MAP(MCLK, PPCLK_UCLK),
188 CLK_MAP(DCLK, PPCLK_DCLK),
189 CLK_MAP(VCLK, PPCLK_VCLK),
190 CLK_MAP(LCLK, PPCLK_LCLK),
191};
192
193static const struct cmn2asic_mapping smu_v13_0_6_feature_mask_map[SMU_FEATURE_COUNT] = {
194 SMU_13_0_6_FEA_MAP(SMU_FEATURE_DATA_CALCULATIONS_BIT, FEATURE_DATA_CALCULATION),
195 SMU_13_0_6_FEA_MAP(SMU_FEATURE_DPM_GFXCLK_BIT, FEATURE_DPM_GFXCLK),
196 SMU_13_0_6_FEA_MAP(SMU_FEATURE_DPM_UCLK_BIT, FEATURE_DPM_UCLK),
197 SMU_13_0_6_FEA_MAP(SMU_FEATURE_DPM_SOCCLK_BIT, FEATURE_DPM_SOCCLK),
198 SMU_13_0_6_FEA_MAP(SMU_FEATURE_DPM_FCLK_BIT, FEATURE_DPM_FCLK),
199 SMU_13_0_6_FEA_MAP(SMU_FEATURE_DPM_LCLK_BIT, FEATURE_DPM_LCLK),
200 SMU_13_0_6_FEA_MAP(SMU_FEATURE_DPM_VCLK_BIT, FEATURE_DPM_VCN),
201 SMU_13_0_6_FEA_MAP(SMU_FEATURE_DPM_DCLK_BIT, FEATURE_DPM_VCN),
202 SMU_13_0_6_FEA_MAP(SMU_FEATURE_DPM_XGMI_BIT, FEATURE_DPM_XGMI),
203 SMU_13_0_6_FEA_MAP(SMU_FEATURE_DS_GFXCLK_BIT, FEATURE_DS_GFXCLK),
204 SMU_13_0_6_FEA_MAP(SMU_FEATURE_DS_SOCCLK_BIT, FEATURE_DS_SOCCLK),
205 SMU_13_0_6_FEA_MAP(SMU_FEATURE_DS_LCLK_BIT, FEATURE_DS_LCLK),
206 SMU_13_0_6_FEA_MAP(SMU_FEATURE_DS_FCLK_BIT, FEATURE_DS_FCLK),
207 SMU_13_0_6_FEA_MAP(SMU_FEATURE_VCN_DPM_BIT, FEATURE_DPM_VCN),
208 SMU_13_0_6_FEA_MAP(SMU_FEATURE_PPT_BIT, FEATURE_PPT),
209 SMU_13_0_6_FEA_MAP(SMU_FEATURE_TDC_BIT, FEATURE_TDC),
210 SMU_13_0_6_FEA_MAP(SMU_FEATURE_APCC_DFLL_BIT, FEATURE_APCC_DFLL),
211 SMU_13_0_6_FEA_MAP(SMU_FEATURE_MP1_CG_BIT, FEATURE_SMU_CG),
212 SMU_13_0_6_FEA_MAP(SMU_FEATURE_GFXOFF_BIT, FEATURE_GFXOFF),
213 SMU_13_0_6_FEA_MAP(SMU_FEATURE_FW_CTF_BIT, FEATURE_FW_CTF),
214 SMU_13_0_6_FEA_MAP(SMU_FEATURE_THERMAL_BIT, FEATURE_THERMAL),
215 SMU_13_0_6_FEA_MAP(SMU_FEATURE_XGMI_PER_LINK_PWR_DWN_BIT, FEATURE_XGMI_PER_LINK_PWR_DOWN),
216 SMU_13_0_6_FEA_MAP(SMU_FEATURE_DF_CSTATE_BIT, FEATURE_DF_CSTATE),
217};
218
219#define TABLE_PMSTATUSLOG 0
220#define TABLE_SMU_METRICS 1
221#define TABLE_I2C_COMMANDS 2
222#define TABLE_COUNT 3
223
224static const struct cmn2asic_mapping smu_v13_0_6_table_map[SMU_TABLE_COUNT] = {
225 TAB_MAP(PMSTATUSLOG),
226 TAB_MAP(SMU_METRICS),
227 TAB_MAP(I2C_COMMANDS),
228};
229
511a9555
LL
230static const uint8_t smu_v13_0_6_throttler_map[] = {
231 [THROTTLER_PPT_BIT] = (SMU_THROTTLER_PPT0_BIT),
93682f8a
LL
232 [THROTTLER_THERMAL_SOCKET_BIT] = (SMU_THROTTLER_TEMP_GPU_BIT),
233 [THROTTLER_THERMAL_HBM_BIT] = (SMU_THROTTLER_TEMP_MEM_BIT),
234 [THROTTLER_THERMAL_VR_BIT] = (SMU_THROTTLER_TEMP_VR_GFX_BIT),
235 [THROTTLER_PROCHOT_BIT] = (SMU_THROTTLER_PROCHOT_GFX_BIT),
511a9555
LL
236};
237
238struct PPTable_t {
239 uint32_t MaxSocketPowerLimit;
240 uint32_t MaxGfxclkFrequency;
241 uint32_t MinGfxclkFrequency;
242 uint32_t FclkFrequencyTable[4];
243 uint32_t UclkFrequencyTable[4];
244 uint32_t SocclkFrequencyTable[4];
245 uint32_t VclkFrequencyTable[4];
246 uint32_t DclkFrequencyTable[4];
247 uint32_t LclkFrequencyTable[4];
248 uint32_t MaxLclkDpmRange;
249 uint32_t MinLclkDpmRange;
5e86aa29 250 uint64_t PublicSerialNumber_AID;
511a9555
LL
251 bool Init;
252};
253
254#define SMUQ10_TO_UINT(x) ((x) >> 10)
4ea7fb33
LL
255#define SMUQ10_FRAC(x) ((x) & 0x3ff)
256#define SMUQ10_ROUND(x) ((SMUQ10_TO_UINT(x)) + ((SMUQ10_FRAC(x)) >= 0x200))
511a9555
LL
257
258struct smu_v13_0_6_dpm_map {
259 enum smu_clk_type clk_type;
260 uint32_t feature_num;
261 struct smu_13_0_dpm_table *dpm_table;
262 uint32_t *freq_table;
263};
264
f20f3b0d
LL
265static int smu_v13_0_6_init_microcode(struct smu_context *smu)
266{
267 const struct smc_firmware_header_v2_1 *v2_1;
268 const struct common_firmware_header *hdr;
269 struct amdgpu_firmware_info *ucode = NULL;
270 struct smc_soft_pptable_entry *entries;
271 struct amdgpu_device *adev = smu->adev;
272 uint32_t p2s_table_id = P2S_TABLE_ID_A;
273 int ret = 0, i, p2stable_count;
5575ce21 274 char ucode_prefix[15];
f20f3b0d
LL
275 char fw_name[30];
276
277 /* No need to load P2S tables in IOV mode */
278 if (amdgpu_sriov_vf(adev))
279 return 0;
280
281 if (!(adev->flags & AMD_IS_APU))
282 p2s_table_id = P2S_TABLE_ID_X;
283
284 amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix,
285 sizeof(ucode_prefix));
286
287 snprintf(fw_name, sizeof(fw_name), "amdgpu/%s.bin", ucode_prefix);
288
289 ret = amdgpu_ucode_request(adev, &adev->pm.fw, fw_name);
290 if (ret)
291 goto out;
292
293 hdr = (const struct common_firmware_header *)adev->pm.fw->data;
294 amdgpu_ucode_print_smc_hdr(hdr);
295
296 /* SMU v13.0.6 binary file doesn't carry pptables, instead the entries
297 * are used to carry p2s tables.
298 */
299 v2_1 = (const struct smc_firmware_header_v2_1 *)adev->pm.fw->data;
300 entries = (struct smc_soft_pptable_entry
301 *)((uint8_t *)v2_1 +
302 le32_to_cpu(v2_1->pptable_entry_offset));
303 p2stable_count = le32_to_cpu(v2_1->pptable_count);
304 for (i = 0; i < p2stable_count; i++) {
305 if (le32_to_cpu(entries[i].id) == p2s_table_id) {
306 smu->pptable_firmware.data =
307 ((uint8_t *)v2_1 +
308 le32_to_cpu(entries[i].ppt_offset_bytes));
309 smu->pptable_firmware.size =
310 le32_to_cpu(entries[i].ppt_size_bytes);
311 break;
312 }
313 }
314
315 if (smu->pptable_firmware.data && smu->pptable_firmware.size) {
316 ucode = &adev->firmware.ucode[AMDGPU_UCODE_ID_P2S_TABLE];
317 ucode->ucode_id = AMDGPU_UCODE_ID_P2S_TABLE;
318 ucode->fw = &smu->pptable_firmware;
319 adev->firmware.fw_size += ALIGN(ucode->fw->size, PAGE_SIZE);
320 }
321
322 return 0;
323out:
324 amdgpu_ucode_release(&adev->pm.fw);
325
326 return ret;
327}
328
511a9555
LL
329static int smu_v13_0_6_tables_init(struct smu_context *smu)
330{
331 struct smu_table_context *smu_table = &smu->smu_table;
332 struct smu_table *tables = smu_table->tables;
333 struct amdgpu_device *adev = smu->adev;
334
335 if (!(adev->flags & AMD_IS_APU))
336 SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU13_TOOL_SIZE,
337 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
338
339 SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(MetricsTable_t),
228ce176
RB
340 PAGE_SIZE,
341 AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT);
511a9555
LL
342
343 SMU_TABLE_INIT(tables, SMU_TABLE_I2C_COMMANDS, sizeof(SwI2cRequest_t),
228ce176
RB
344 PAGE_SIZE,
345 AMDGPU_GEM_DOMAIN_VRAM | AMDGPU_GEM_DOMAIN_GTT);
511a9555
LL
346
347 smu_table->metrics_table = kzalloc(sizeof(MetricsTable_t), GFP_KERNEL);
348 if (!smu_table->metrics_table)
349 return -ENOMEM;
350 smu_table->metrics_time = 0;
351
915414d0 352 smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_4);
511a9555
LL
353 smu_table->gpu_metrics_table =
354 kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL);
355 if (!smu_table->gpu_metrics_table) {
356 kfree(smu_table->metrics_table);
357 return -ENOMEM;
358 }
359
360 smu_table->driver_pptable =
361 kzalloc(sizeof(struct PPTable_t), GFP_KERNEL);
362 if (!smu_table->driver_pptable) {
363 kfree(smu_table->metrics_table);
364 kfree(smu_table->gpu_metrics_table);
365 return -ENOMEM;
366 }
367
368 return 0;
369}
370
371static int smu_v13_0_6_allocate_dpm_context(struct smu_context *smu)
372{
373 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
374
375 smu_dpm->dpm_context =
376 kzalloc(sizeof(struct smu_13_0_dpm_context), GFP_KERNEL);
377 if (!smu_dpm->dpm_context)
378 return -ENOMEM;
379 smu_dpm->dpm_context_size = sizeof(struct smu_13_0_dpm_context);
380
381 return 0;
382}
383
384static int smu_v13_0_6_init_smc_tables(struct smu_context *smu)
385{
386 int ret = 0;
387
388 ret = smu_v13_0_6_tables_init(smu);
389 if (ret)
390 return ret;
391
392 ret = smu_v13_0_6_allocate_dpm_context(smu);
393
394 return ret;
395}
396
397static int smu_v13_0_6_get_allowed_feature_mask(struct smu_context *smu,
398 uint32_t *feature_mask,
399 uint32_t num)
400{
401 if (num > 2)
402 return -EINVAL;
403
404 /* pptable will handle the features to enable */
405 memset(feature_mask, 0xFF, sizeof(uint32_t) * num);
406
407 return 0;
408}
409
410static int smu_v13_0_6_get_metrics_table(struct smu_context *smu,
411 void *metrics_table, bool bypass_cache)
412{
413 struct smu_table_context *smu_table = &smu->smu_table;
414 uint32_t table_size = smu_table->tables[SMU_TABLE_SMU_METRICS].size;
415 struct smu_table *table = &smu_table->driver_table;
416 int ret;
417
418 if (bypass_cache || !smu_table->metrics_time ||
419 time_after(jiffies,
420 smu_table->metrics_time + msecs_to_jiffies(1))) {
421 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetMetricsTable, NULL);
422 if (ret) {
423 dev_info(smu->adev->dev,
424 "Failed to export SMU metrics table!\n");
425 return ret;
426 }
427
428 amdgpu_asic_invalidate_hdp(smu->adev, NULL);
429 memcpy(smu_table->metrics_table, table->cpu_addr, table_size);
430
431 smu_table->metrics_time = jiffies;
432 }
433
434 if (metrics_table)
435 memcpy(metrics_table, smu_table->metrics_table, table_size);
436
437 return 0;
438}
439
440static int smu_v13_0_6_setup_driver_pptable(struct smu_context *smu)
441{
442 struct smu_table_context *smu_table = &smu->smu_table;
443 MetricsTable_t *metrics = (MetricsTable_t *)smu_table->metrics_table;
444 struct PPTable_t *pptable =
445 (struct PPTable_t *)smu_table->driver_pptable;
e01eeffc 446 int ret, i, retry = 100;
511a9555
LL
447
448 /* Store one-time values in driver PPTable */
449 if (!pptable->Init) {
b3b18685 450 while (--retry) {
e01eeffc
YW
451 ret = smu_v13_0_6_get_metrics_table(smu, NULL, true);
452 if (ret)
453 return ret;
454
455 /* Ensure that metrics have been updated */
456 if (metrics->AccumulationCounter)
457 break;
458
459 usleep_range(1000, 1100);
460 }
461
462 if (!retry)
463 return -ETIME;
511a9555
LL
464
465 pptable->MaxSocketPowerLimit =
4ea7fb33 466 SMUQ10_ROUND(metrics->MaxSocketPowerLimit);
511a9555 467 pptable->MaxGfxclkFrequency =
4ea7fb33 468 SMUQ10_ROUND(metrics->MaxGfxclkFrequency);
511a9555 469 pptable->MinGfxclkFrequency =
4ea7fb33 470 SMUQ10_ROUND(metrics->MinGfxclkFrequency);
511a9555 471
0bad3200 472 for (i = 0; i < 4; ++i) {
511a9555 473 pptable->FclkFrequencyTable[i] =
4ea7fb33 474 SMUQ10_ROUND(metrics->FclkFrequencyTable[i]);
511a9555 475 pptable->UclkFrequencyTable[i] =
4ea7fb33
LL
476 SMUQ10_ROUND(metrics->UclkFrequencyTable[i]);
477 pptable->SocclkFrequencyTable[i] = SMUQ10_ROUND(
511a9555
LL
478 metrics->SocclkFrequencyTable[i]);
479 pptable->VclkFrequencyTable[i] =
4ea7fb33 480 SMUQ10_ROUND(metrics->VclkFrequencyTable[i]);
511a9555 481 pptable->DclkFrequencyTable[i] =
4ea7fb33 482 SMUQ10_ROUND(metrics->DclkFrequencyTable[i]);
511a9555 483 pptable->LclkFrequencyTable[i] =
4ea7fb33 484 SMUQ10_ROUND(metrics->LclkFrequencyTable[i]);
511a9555
LL
485 }
486
5e86aa29
YW
487 /* use AID0 serial number by default */
488 pptable->PublicSerialNumber_AID = metrics->PublicSerialNumber_AID[0];
489
511a9555
LL
490 pptable->Init = true;
491 }
492
493 return 0;
494}
495
496static int smu_v13_0_6_get_dpm_ultimate_freq(struct smu_context *smu,
497 enum smu_clk_type clk_type,
498 uint32_t *min, uint32_t *max)
499{
500 struct smu_table_context *smu_table = &smu->smu_table;
501 struct PPTable_t *pptable =
502 (struct PPTable_t *)smu_table->driver_pptable;
503 uint32_t clock_limit = 0, param;
504 int ret = 0, clk_id = 0;
505
506 if (!smu_cmn_clk_dpm_is_enabled(smu, clk_type)) {
507 switch (clk_type) {
508 case SMU_MCLK:
509 case SMU_UCLK:
510 if (pptable->Init)
511 clock_limit = pptable->UclkFrequencyTable[0];
512 break;
513 case SMU_GFXCLK:
514 case SMU_SCLK:
515 if (pptable->Init)
516 clock_limit = pptable->MinGfxclkFrequency;
517 break;
518 case SMU_SOCCLK:
519 if (pptable->Init)
463e953e 520 clock_limit = pptable->SocclkFrequencyTable[0];
511a9555
LL
521 break;
522 case SMU_FCLK:
523 if (pptable->Init)
524 clock_limit = pptable->FclkFrequencyTable[0];
525 break;
526 case SMU_VCLK:
527 if (pptable->Init)
528 clock_limit = pptable->VclkFrequencyTable[0];
529 break;
530 case SMU_DCLK:
531 if (pptable->Init)
532 clock_limit = pptable->DclkFrequencyTable[0];
533 break;
534 default:
535 break;
536 }
537
538 if (min)
539 *min = clock_limit;
540
541 if (max)
542 *max = clock_limit;
543
544 return 0;
545 }
546
547 if (!(clk_type == SMU_GFXCLK || clk_type == SMU_SCLK)) {
548 clk_id = smu_cmn_to_asic_specific_index(
549 smu, CMN2ASIC_MAPPING_CLK, clk_type);
550 if (clk_id < 0) {
551 ret = -EINVAL;
552 goto failed;
553 }
554 param = (clk_id & 0xffff) << 16;
555 }
556
557 if (max) {
558 if (clk_type == SMU_GFXCLK || clk_type == SMU_SCLK)
559 ret = smu_cmn_send_smc_msg(
560 smu, SMU_MSG_GetMaxGfxclkFrequency, max);
561 else
562 ret = smu_cmn_send_smc_msg_with_param(
563 smu, SMU_MSG_GetMaxDpmFreq, param, max);
564 if (ret)
565 goto failed;
566 }
567
568 if (min) {
569 if (clk_type == SMU_GFXCLK || clk_type == SMU_SCLK)
570 ret = smu_cmn_send_smc_msg(
571 smu, SMU_MSG_GetMinGfxclkFrequency, min);
572 else
573 ret = smu_cmn_send_smc_msg_with_param(
574 smu, SMU_MSG_GetMinDpmFreq, param, min);
575 }
576
577failed:
578 return ret;
579}
580
581static int smu_v13_0_6_get_dpm_level_count(struct smu_context *smu,
582 enum smu_clk_type clk_type,
583 uint32_t *levels)
584{
585 int ret;
586
587 ret = smu_v13_0_get_dpm_freq_by_index(smu, clk_type, 0xff, levels);
588 if (!ret)
589 ++(*levels);
590
591 return ret;
592}
593
594static int smu_v13_0_6_set_default_dpm_table(struct smu_context *smu)
595{
596 struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
597 struct smu_table_context *smu_table = &smu->smu_table;
598 struct smu_13_0_dpm_table *dpm_table = NULL;
599 struct PPTable_t *pptable =
600 (struct PPTable_t *)smu_table->driver_pptable;
601 uint32_t gfxclkmin, gfxclkmax, levels;
0bad3200 602 int ret = 0, i, j;
511a9555
LL
603 struct smu_v13_0_6_dpm_map dpm_map[] = {
604 { SMU_SOCCLK, SMU_FEATURE_DPM_SOCCLK_BIT,
605 &dpm_context->dpm_tables.soc_table,
606 pptable->SocclkFrequencyTable },
607 { SMU_UCLK, SMU_FEATURE_DPM_UCLK_BIT,
608 &dpm_context->dpm_tables.uclk_table,
609 pptable->UclkFrequencyTable },
610 { SMU_FCLK, SMU_FEATURE_DPM_FCLK_BIT,
611 &dpm_context->dpm_tables.fclk_table,
612 pptable->FclkFrequencyTable },
613 { SMU_VCLK, SMU_FEATURE_DPM_VCLK_BIT,
614 &dpm_context->dpm_tables.vclk_table,
615 pptable->VclkFrequencyTable },
616 { SMU_DCLK, SMU_FEATURE_DPM_DCLK_BIT,
617 &dpm_context->dpm_tables.dclk_table,
618 pptable->DclkFrequencyTable },
619 };
620
621 smu_v13_0_6_setup_driver_pptable(smu);
622
623 /* gfxclk dpm table setup */
624 dpm_table = &dpm_context->dpm_tables.gfx_table;
625 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT)) {
626 /* In the case of gfxclk, only fine-grained dpm is honored.
627 * Get min/max values from FW.
628 */
629 ret = smu_v13_0_6_get_dpm_ultimate_freq(smu, SMU_GFXCLK,
630 &gfxclkmin, &gfxclkmax);
631 if (ret)
632 return ret;
633
634 dpm_table->count = 2;
635 dpm_table->dpm_levels[0].value = gfxclkmin;
636 dpm_table->dpm_levels[0].enabled = true;
637 dpm_table->dpm_levels[1].value = gfxclkmax;
638 dpm_table->dpm_levels[1].enabled = true;
639 dpm_table->min = dpm_table->dpm_levels[0].value;
640 dpm_table->max = dpm_table->dpm_levels[1].value;
641 } else {
642 dpm_table->count = 1;
643 dpm_table->dpm_levels[0].value = pptable->MinGfxclkFrequency;
644 dpm_table->dpm_levels[0].enabled = true;
645 dpm_table->min = dpm_table->dpm_levels[0].value;
646 dpm_table->max = dpm_table->dpm_levels[0].value;
647 }
648
0bad3200 649 for (j = 0; j < ARRAY_SIZE(dpm_map); j++) {
511a9555
LL
650 dpm_table = dpm_map[j].dpm_table;
651 levels = 1;
652 if (smu_cmn_feature_is_enabled(smu, dpm_map[j].feature_num)) {
653 ret = smu_v13_0_6_get_dpm_level_count(
654 smu, dpm_map[j].clk_type, &levels);
655 if (ret)
656 return ret;
657 }
658 dpm_table->count = levels;
659 for (i = 0; i < dpm_table->count; ++i) {
660 dpm_table->dpm_levels[i].value =
661 dpm_map[j].freq_table[i];
662 dpm_table->dpm_levels[i].enabled = true;
663
664 }
665 dpm_table->min = dpm_table->dpm_levels[0].value;
666 dpm_table->max = dpm_table->dpm_levels[levels - 1].value;
667
668 }
669
670 return 0;
671}
672
673static int smu_v13_0_6_setup_pptable(struct smu_context *smu)
674{
675 struct smu_table_context *table_context = &smu->smu_table;
676
677 /* TODO: PPTable is not available.
678 * 1) Find an alternate way to get 'PPTable values' here.
679 * 2) Check if there is SW CTF
680 */
681 table_context->thermal_controller_type = 0;
682
683 return 0;
684}
685
686static int smu_v13_0_6_check_fw_status(struct smu_context *smu)
687{
688 struct amdgpu_device *adev = smu->adev;
689 uint32_t mp1_fw_flags;
690
691 mp1_fw_flags =
692 RREG32_PCIE(MP1_Public | (smnMP1_FIRMWARE_FLAGS & 0xffffffff));
693
694 if ((mp1_fw_flags & MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED_MASK) >>
695 MP1_FIRMWARE_FLAGS__INTERRUPTS_ENABLED__SHIFT)
696 return 0;
697
698 return -EIO;
699}
700
701static int smu_v13_0_6_populate_umd_state_clk(struct smu_context *smu)
702{
703 struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
704 struct smu_13_0_dpm_table *gfx_table =
705 &dpm_context->dpm_tables.gfx_table;
706 struct smu_13_0_dpm_table *mem_table =
707 &dpm_context->dpm_tables.uclk_table;
708 struct smu_13_0_dpm_table *soc_table =
709 &dpm_context->dpm_tables.soc_table;
710 struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
711
712 pstate_table->gfxclk_pstate.min = gfx_table->min;
713 pstate_table->gfxclk_pstate.peak = gfx_table->max;
714 pstate_table->gfxclk_pstate.curr.min = gfx_table->min;
715 pstate_table->gfxclk_pstate.curr.max = gfx_table->max;
716
717 pstate_table->uclk_pstate.min = mem_table->min;
718 pstate_table->uclk_pstate.peak = mem_table->max;
719 pstate_table->uclk_pstate.curr.min = mem_table->min;
720 pstate_table->uclk_pstate.curr.max = mem_table->max;
721
722 pstate_table->socclk_pstate.min = soc_table->min;
723 pstate_table->socclk_pstate.peak = soc_table->max;
724 pstate_table->socclk_pstate.curr.min = soc_table->min;
725 pstate_table->socclk_pstate.curr.max = soc_table->max;
726
727 if (gfx_table->count > SMU_13_0_6_UMD_PSTATE_GFXCLK_LEVEL &&
728 mem_table->count > SMU_13_0_6_UMD_PSTATE_MCLK_LEVEL &&
729 soc_table->count > SMU_13_0_6_UMD_PSTATE_SOCCLK_LEVEL) {
730 pstate_table->gfxclk_pstate.standard =
731 gfx_table->dpm_levels[SMU_13_0_6_UMD_PSTATE_GFXCLK_LEVEL].value;
732 pstate_table->uclk_pstate.standard =
733 mem_table->dpm_levels[SMU_13_0_6_UMD_PSTATE_MCLK_LEVEL].value;
734 pstate_table->socclk_pstate.standard =
735 soc_table->dpm_levels[SMU_13_0_6_UMD_PSTATE_SOCCLK_LEVEL].value;
736 } else {
737 pstate_table->gfxclk_pstate.standard =
738 pstate_table->gfxclk_pstate.min;
739 pstate_table->uclk_pstate.standard =
740 pstate_table->uclk_pstate.min;
741 pstate_table->socclk_pstate.standard =
742 pstate_table->socclk_pstate.min;
743 }
744
745 return 0;
746}
747
748static int smu_v13_0_6_get_clk_table(struct smu_context *smu,
749 struct pp_clock_levels_with_latency *clocks,
750 struct smu_13_0_dpm_table *dpm_table)
751{
752 int i, count;
753
754 count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS :
755 dpm_table->count;
756 clocks->num_levels = count;
757
758 for (i = 0; i < count; i++) {
759 clocks->data[i].clocks_in_khz =
760 dpm_table->dpm_levels[i].value * 1000;
761 clocks->data[i].latency_in_us = 0;
762 }
763
764 return 0;
765}
766
767static int smu_v13_0_6_freqs_in_same_level(int32_t frequency1,
768 int32_t frequency2)
769{
770 return (abs(frequency1 - frequency2) <= EPSILON);
771}
772
93682f8a 773static uint32_t smu_v13_0_6_get_throttler_status(struct smu_context *smu)
511a9555 774{
93682f8a
LL
775 struct smu_power_context *smu_power = &smu->smu_power;
776 struct smu_13_0_power_context *power_context = smu_power->power_context;
511a9555
LL
777 uint32_t throttler_status = 0;
778
93682f8a
LL
779 throttler_status = atomic_read(&power_context->throttle_status);
780 dev_dbg(smu->adev->dev, "SMU Throttler status: %u", throttler_status);
511a9555
LL
781
782 return throttler_status;
783}
784
785static int smu_v13_0_6_get_smu_metrics_data(struct smu_context *smu,
786 MetricsMember_t member,
787 uint32_t *value)
788{
789 struct smu_table_context *smu_table = &smu->smu_table;
790 MetricsTable_t *metrics = (MetricsTable_t *)smu_table->metrics_table;
a1b0dafa 791 struct amdgpu_device *adev = smu->adev;
511a9555 792 int ret = 0;
a1b0dafa 793 int xcc_id;
511a9555
LL
794
795 ret = smu_v13_0_6_get_metrics_table(smu, NULL, false);
796 if (ret)
797 return ret;
798
799 /* For clocks with multiple instances, only report the first one */
800 switch (member) {
801 case METRICS_CURR_GFXCLK:
802 case METRICS_AVERAGE_GFXCLK:
710d9cae 803 if (smu->smc_fw_version >= 0x552F00) {
a1b0dafa 804 xcc_id = GET_INST(GC, 0);
4ea7fb33 805 *value = SMUQ10_ROUND(metrics->GfxclkFrequency[xcc_id]);
a1b0dafa
A
806 } else {
807 *value = 0;
808 }
511a9555
LL
809 break;
810 case METRICS_CURR_SOCCLK:
811 case METRICS_AVERAGE_SOCCLK:
4ea7fb33 812 *value = SMUQ10_ROUND(metrics->SocclkFrequency[0]);
511a9555
LL
813 break;
814 case METRICS_CURR_UCLK:
815 case METRICS_AVERAGE_UCLK:
4ea7fb33 816 *value = SMUQ10_ROUND(metrics->UclkFrequency);
511a9555
LL
817 break;
818 case METRICS_CURR_VCLK:
4ea7fb33 819 *value = SMUQ10_ROUND(metrics->VclkFrequency[0]);
511a9555
LL
820 break;
821 case METRICS_CURR_DCLK:
4ea7fb33 822 *value = SMUQ10_ROUND(metrics->DclkFrequency[0]);
511a9555
LL
823 break;
824 case METRICS_CURR_FCLK:
4ea7fb33 825 *value = SMUQ10_ROUND(metrics->FclkFrequency);
511a9555
LL
826 break;
827 case METRICS_AVERAGE_GFXACTIVITY:
4ea7fb33 828 *value = SMUQ10_ROUND(metrics->SocketGfxBusy);
511a9555
LL
829 break;
830 case METRICS_AVERAGE_MEMACTIVITY:
4ea7fb33 831 *value = SMUQ10_ROUND(metrics->DramBandwidthUtilization);
511a9555 832 break;
47f1724d 833 case METRICS_CURR_SOCKETPOWER:
4ea7fb33 834 *value = SMUQ10_ROUND(metrics->SocketPower) << 8;
511a9555 835 break;
511a9555 836 case METRICS_TEMPERATURE_HOTSPOT:
4ea7fb33 837 *value = SMUQ10_ROUND(metrics->MaxSocketTemperature) *
669f2372 838 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
511a9555
LL
839 break;
840 case METRICS_TEMPERATURE_MEM:
4ea7fb33 841 *value = SMUQ10_ROUND(metrics->MaxHbmTemperature) *
669f2372 842 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
511a9555
LL
843 break;
844 /* This is the max of all VRs and not just SOC VR.
845 * No need to define another data type for the same.
846 */
847 case METRICS_TEMPERATURE_VRSOC:
4ea7fb33 848 *value = SMUQ10_ROUND(metrics->MaxVrTemperature) *
669f2372 849 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
511a9555 850 break;
511a9555
LL
851 default:
852 *value = UINT_MAX;
853 break;
854 }
855
856 return ret;
857}
858
859static int smu_v13_0_6_get_current_clk_freq_by_table(struct smu_context *smu,
860 enum smu_clk_type clk_type,
861 uint32_t *value)
862{
863 MetricsMember_t member_type;
864
865 if (!value)
866 return -EINVAL;
867
868 switch (clk_type) {
869 case SMU_GFXCLK:
870 member_type = METRICS_CURR_GFXCLK;
871 break;
872 case SMU_UCLK:
873 member_type = METRICS_CURR_UCLK;
874 break;
875 case SMU_SOCCLK:
876 member_type = METRICS_CURR_SOCCLK;
877 break;
878 case SMU_VCLK:
879 member_type = METRICS_CURR_VCLK;
880 break;
881 case SMU_DCLK:
882 member_type = METRICS_CURR_DCLK;
883 break;
884 case SMU_FCLK:
885 member_type = METRICS_CURR_FCLK;
886 break;
887 default:
888 return -EINVAL;
889 }
890
891 return smu_v13_0_6_get_smu_metrics_data(smu, member_type, value);
892}
893
2b44d0a4 894static int smu_v13_0_6_print_clks(struct smu_context *smu, char *buf, int size,
cad2fb19
LL
895 struct smu_13_0_dpm_table *single_dpm_table,
896 uint32_t curr_clk, const char *clk_name)
897{
898 struct pp_clock_levels_with_latency clocks;
2b44d0a4 899 int i, ret, level = -1;
cad2fb19
LL
900 uint32_t clk1, clk2;
901
902 ret = smu_v13_0_6_get_clk_table(smu, &clocks, single_dpm_table);
903 if (ret) {
904 dev_err(smu->adev->dev, "Attempt to get %s clk levels failed!",
905 clk_name);
906 return ret;
907 }
908
909 if (!clocks.num_levels)
910 return -EINVAL;
911
912 if (curr_clk < SMU_13_0_6_DSCLK_THRESHOLD) {
913 size = sysfs_emit_at(buf, size, "S: %uMhz *\n", curr_clk);
914 for (i = 0; i < clocks.num_levels; i++)
915 size += sysfs_emit_at(buf, size, "%d: %uMhz\n", i,
916 clocks.data[i].clocks_in_khz /
917 1000);
918
919 } else {
920 if ((clocks.num_levels == 1) ||
921 (curr_clk < (clocks.data[0].clocks_in_khz / 1000)))
922 level = 0;
923 for (i = 0; i < clocks.num_levels; i++) {
924 clk1 = clocks.data[i].clocks_in_khz / 1000;
925
926 if (i < (clocks.num_levels - 1))
927 clk2 = clocks.data[i + 1].clocks_in_khz / 1000;
928
929 if (curr_clk >= clk1 && curr_clk < clk2) {
930 level = (curr_clk - clk1) <= (clk2 - curr_clk) ?
931 i :
932 i + 1;
933 }
934
935 size += sysfs_emit_at(buf, size, "%d: %uMhz %s\n", i,
936 clk1, (level == i) ? "*" : "");
937 }
938 }
939
940 return size;
941}
942
511a9555
LL
943static int smu_v13_0_6_print_clk_levels(struct smu_context *smu,
944 enum smu_clk_type type, char *buf)
945{
cad2fb19 946 int now, size = 0;
511a9555
LL
947 int ret = 0;
948 struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
511a9555
LL
949 struct smu_13_0_dpm_table *single_dpm_table;
950 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
951 struct smu_13_0_dpm_context *dpm_context = NULL;
511a9555
LL
952 uint32_t min_clk, max_clk;
953
954 smu_cmn_get_sysfs_buf(&buf, &size);
955
956 if (amdgpu_ras_intr_triggered()) {
957 size += sysfs_emit_at(buf, size, "unavailable\n");
958 return size;
959 }
960
961 dpm_context = smu_dpm->dpm_context;
962
963 switch (type) {
964 case SMU_OD_SCLK:
965 size += sysfs_emit_at(buf, size, "%s:\n", "GFXCLK");
966 fallthrough;
967 case SMU_SCLK:
968 ret = smu_v13_0_6_get_current_clk_freq_by_table(smu, SMU_GFXCLK,
969 &now);
970 if (ret) {
971 dev_err(smu->adev->dev,
972 "Attempt to get current gfx clk Failed!");
973 return ret;
974 }
975
511a9555
LL
976 min_clk = pstate_table->gfxclk_pstate.curr.min;
977 max_clk = pstate_table->gfxclk_pstate.curr.max;
978
608f604c
LL
979 if (now < SMU_13_0_6_DSCLK_THRESHOLD) {
980 size += sysfs_emit_at(buf, size, "S: %uMhz *\n",
981 now);
982 size += sysfs_emit_at(buf, size, "0: %uMhz\n",
983 min_clk);
984 size += sysfs_emit_at(buf, size, "1: %uMhz\n",
985 max_clk);
986
987 } else if (!smu_v13_0_6_freqs_in_same_level(now, min_clk) &&
54f9e1ca
YW
988 !smu_v13_0_6_freqs_in_same_level(now, max_clk)) {
989 size += sysfs_emit_at(buf, size, "0: %uMhz\n",
990 min_clk);
991 size += sysfs_emit_at(buf, size, "1: %uMhz *\n",
992 now);
993 size += sysfs_emit_at(buf, size, "2: %uMhz\n",
994 max_clk);
511a9555 995 } else {
54f9e1ca
YW
996 size += sysfs_emit_at(buf, size, "0: %uMhz %s\n",
997 min_clk,
998 smu_v13_0_6_freqs_in_same_level(now, min_clk) ? "*" : "");
999 size += sysfs_emit_at(buf, size, "1: %uMhz %s\n",
1000 max_clk,
1001 smu_v13_0_6_freqs_in_same_level(now, max_clk) ? "*" : "");
511a9555
LL
1002 }
1003
1004 break;
1005
1006 case SMU_OD_MCLK:
1007 size += sysfs_emit_at(buf, size, "%s:\n", "MCLK");
1008 fallthrough;
1009 case SMU_MCLK:
1010 ret = smu_v13_0_6_get_current_clk_freq_by_table(smu, SMU_UCLK,
1011 &now);
1012 if (ret) {
1013 dev_err(smu->adev->dev,
1014 "Attempt to get current mclk Failed!");
1015 return ret;
1016 }
1017
1018 single_dpm_table = &(dpm_context->dpm_tables.uclk_table);
511a9555 1019
2b44d0a4
LM
1020 return smu_v13_0_6_print_clks(smu, buf, size, single_dpm_table,
1021 now, "mclk");
511a9555
LL
1022
1023 case SMU_SOCCLK:
1024 ret = smu_v13_0_6_get_current_clk_freq_by_table(smu, SMU_SOCCLK,
1025 &now);
1026 if (ret) {
1027 dev_err(smu->adev->dev,
1028 "Attempt to get current socclk Failed!");
1029 return ret;
1030 }
1031
1032 single_dpm_table = &(dpm_context->dpm_tables.soc_table);
511a9555 1033
2b44d0a4
LM
1034 return smu_v13_0_6_print_clks(smu, buf, size, single_dpm_table,
1035 now, "socclk");
511a9555
LL
1036
1037 case SMU_FCLK:
1038 ret = smu_v13_0_6_get_current_clk_freq_by_table(smu, SMU_FCLK,
1039 &now);
1040 if (ret) {
1041 dev_err(smu->adev->dev,
1042 "Attempt to get current fclk Failed!");
1043 return ret;
1044 }
1045
1046 single_dpm_table = &(dpm_context->dpm_tables.fclk_table);
511a9555 1047
2b44d0a4
LM
1048 return smu_v13_0_6_print_clks(smu, buf, size, single_dpm_table,
1049 now, "fclk");
511a9555
LL
1050
1051 case SMU_VCLK:
1052 ret = smu_v13_0_6_get_current_clk_freq_by_table(smu, SMU_VCLK,
1053 &now);
1054 if (ret) {
1055 dev_err(smu->adev->dev,
1056 "Attempt to get current vclk Failed!");
1057 return ret;
1058 }
1059
1060 single_dpm_table = &(dpm_context->dpm_tables.vclk_table);
511a9555 1061
2b44d0a4
LM
1062 return smu_v13_0_6_print_clks(smu, buf, size, single_dpm_table,
1063 now, "vclk");
511a9555
LL
1064
1065 case SMU_DCLK:
1066 ret = smu_v13_0_6_get_current_clk_freq_by_table(smu, SMU_DCLK,
1067 &now);
1068 if (ret) {
1069 dev_err(smu->adev->dev,
1070 "Attempt to get current dclk Failed!");
1071 return ret;
1072 }
1073
1074 single_dpm_table = &(dpm_context->dpm_tables.dclk_table);
511a9555 1075
2b44d0a4
LM
1076 return smu_v13_0_6_print_clks(smu, buf, size, single_dpm_table,
1077 now, "dclk");
511a9555
LL
1078
1079 default:
1080 break;
1081 }
1082
1083 return size;
1084}
1085
1086static int smu_v13_0_6_upload_dpm_level(struct smu_context *smu, bool max,
1087 uint32_t feature_mask, uint32_t level)
1088{
1089 struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
1090 uint32_t freq;
1091 int ret = 0;
1092
1093 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT) &&
1094 (feature_mask & FEATURE_MASK(FEATURE_DPM_GFXCLK))) {
1095 freq = dpm_context->dpm_tables.gfx_table.dpm_levels[level].value;
1096 ret = smu_cmn_send_smc_msg_with_param(
1097 smu,
1098 (max ? SMU_MSG_SetSoftMaxGfxClk :
1099 SMU_MSG_SetSoftMinGfxclk),
1100 freq & 0xffff, NULL);
1101 if (ret) {
1102 dev_err(smu->adev->dev,
1103 "Failed to set soft %s gfxclk !\n",
1104 max ? "max" : "min");
1105 return ret;
1106 }
1107 }
1108
1109 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT) &&
1110 (feature_mask & FEATURE_MASK(FEATURE_DPM_UCLK))) {
1111 freq = dpm_context->dpm_tables.uclk_table.dpm_levels[level]
1112 .value;
1113 ret = smu_cmn_send_smc_msg_with_param(
1114 smu,
1115 (max ? SMU_MSG_SetSoftMaxByFreq :
1116 SMU_MSG_SetSoftMinByFreq),
1117 (PPCLK_UCLK << 16) | (freq & 0xffff), NULL);
1118 if (ret) {
1119 dev_err(smu->adev->dev,
1120 "Failed to set soft %s memclk !\n",
1121 max ? "max" : "min");
1122 return ret;
1123 }
1124 }
1125
1126 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT) &&
1127 (feature_mask & FEATURE_MASK(FEATURE_DPM_SOCCLK))) {
1128 freq = dpm_context->dpm_tables.soc_table.dpm_levels[level].value;
1129 ret = smu_cmn_send_smc_msg_with_param(
1130 smu,
1131 (max ? SMU_MSG_SetSoftMaxByFreq :
1132 SMU_MSG_SetSoftMinByFreq),
1133 (PPCLK_SOCCLK << 16) | (freq & 0xffff), NULL);
1134 if (ret) {
1135 dev_err(smu->adev->dev,
1136 "Failed to set soft %s socclk !\n",
1137 max ? "max" : "min");
1138 return ret;
1139 }
1140 }
1141
1142 return ret;
1143}
1144
1145static int smu_v13_0_6_force_clk_levels(struct smu_context *smu,
1146 enum smu_clk_type type, uint32_t mask)
1147{
1148 struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
1149 struct smu_13_0_dpm_table *single_dpm_table = NULL;
1150 uint32_t soft_min_level, soft_max_level;
1151 int ret = 0;
1152
1153 soft_min_level = mask ? (ffs(mask) - 1) : 0;
1154 soft_max_level = mask ? (fls(mask) - 1) : 0;
1155
1156 switch (type) {
1157 case SMU_SCLK:
1158 single_dpm_table = &(dpm_context->dpm_tables.gfx_table);
1159 if (soft_max_level >= single_dpm_table->count) {
1160 dev_err(smu->adev->dev,
1161 "Clock level specified %d is over max allowed %d\n",
1162 soft_max_level, single_dpm_table->count - 1);
1163 ret = -EINVAL;
1164 break;
1165 }
1166
1167 ret = smu_v13_0_6_upload_dpm_level(
1168 smu, false, FEATURE_MASK(FEATURE_DPM_GFXCLK),
1169 soft_min_level);
1170 if (ret) {
1171 dev_err(smu->adev->dev,
1172 "Failed to upload boot level to lowest!\n");
1173 break;
1174 }
1175
1176 ret = smu_v13_0_6_upload_dpm_level(
1177 smu, true, FEATURE_MASK(FEATURE_DPM_GFXCLK),
1178 soft_max_level);
1179 if (ret)
1180 dev_err(smu->adev->dev,
1181 "Failed to upload dpm max level to highest!\n");
1182
1183 break;
1184
1185 case SMU_MCLK:
1186 case SMU_SOCCLK:
1187 case SMU_FCLK:
1188 /*
1189 * Should not arrive here since smu_13_0_6 does not
1190 * support mclk/socclk/fclk softmin/softmax settings
1191 */
1192 ret = -EINVAL;
1193 break;
1194
1195 default:
1196 break;
1197 }
1198
1199 return ret;
1200}
1201
511a9555
LL
1202static int smu_v13_0_6_get_current_activity_percent(struct smu_context *smu,
1203 enum amd_pp_sensors sensor,
1204 uint32_t *value)
1205{
1206 int ret = 0;
1207
1208 if (!value)
1209 return -EINVAL;
1210
1211 switch (sensor) {
1212 case AMDGPU_PP_SENSOR_GPU_LOAD:
1213 ret = smu_v13_0_6_get_smu_metrics_data(
1214 smu, METRICS_AVERAGE_GFXACTIVITY, value);
1215 break;
1216 case AMDGPU_PP_SENSOR_MEM_LOAD:
1217 ret = smu_v13_0_6_get_smu_metrics_data(
1218 smu, METRICS_AVERAGE_MEMACTIVITY, value);
1219 break;
1220 default:
1221 dev_err(smu->adev->dev,
1222 "Invalid sensor for retrieving clock activity\n");
1223 return -EINVAL;
1224 }
1225
1226 return ret;
1227}
1228
511a9555
LL
1229static int smu_v13_0_6_thermal_get_temperature(struct smu_context *smu,
1230 enum amd_pp_sensors sensor,
1231 uint32_t *value)
1232{
1233 int ret = 0;
1234
1235 if (!value)
1236 return -EINVAL;
1237
1238 switch (sensor) {
1239 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
1240 ret = smu_v13_0_6_get_smu_metrics_data(
1241 smu, METRICS_TEMPERATURE_HOTSPOT, value);
1242 break;
511a9555
LL
1243 case AMDGPU_PP_SENSOR_MEM_TEMP:
1244 ret = smu_v13_0_6_get_smu_metrics_data(
1245 smu, METRICS_TEMPERATURE_MEM, value);
1246 break;
1247 default:
1248 dev_err(smu->adev->dev, "Invalid sensor for retrieving temp\n");
1249 return -EINVAL;
1250 }
1251
1252 return ret;
1253}
1254
1255static int smu_v13_0_6_read_sensor(struct smu_context *smu,
1256 enum amd_pp_sensors sensor, void *data,
1257 uint32_t *size)
1258{
1259 int ret = 0;
1260
1261 if (amdgpu_ras_intr_triggered())
1262 return 0;
1263
1264 if (!data || !size)
1265 return -EINVAL;
1266
1267 switch (sensor) {
1268 case AMDGPU_PP_SENSOR_MEM_LOAD:
1269 case AMDGPU_PP_SENSOR_GPU_LOAD:
1270 ret = smu_v13_0_6_get_current_activity_percent(smu, sensor,
1271 (uint32_t *)data);
1272 *size = 4;
1273 break;
47f1724d
ML
1274 case AMDGPU_PP_SENSOR_GPU_INPUT_POWER:
1275 ret = smu_v13_0_6_get_smu_metrics_data(smu,
1276 METRICS_CURR_SOCKETPOWER,
1277 (uint32_t *)data);
511a9555
LL
1278 *size = 4;
1279 break;
1280 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
511a9555
LL
1281 case AMDGPU_PP_SENSOR_MEM_TEMP:
1282 ret = smu_v13_0_6_thermal_get_temperature(smu, sensor,
1283 (uint32_t *)data);
1284 *size = 4;
1285 break;
1286 case AMDGPU_PP_SENSOR_GFX_MCLK:
1287 ret = smu_v13_0_6_get_current_clk_freq_by_table(
1288 smu, SMU_UCLK, (uint32_t *)data);
1289 /* the output clock frequency in 10K unit */
1290 *(uint32_t *)data *= 100;
1291 *size = 4;
1292 break;
1293 case AMDGPU_PP_SENSOR_GFX_SCLK:
1294 ret = smu_v13_0_6_get_current_clk_freq_by_table(
1295 smu, SMU_GFXCLK, (uint32_t *)data);
1296 *(uint32_t *)data *= 100;
1297 *size = 4;
1298 break;
1299 case AMDGPU_PP_SENSOR_VDDGFX:
1300 ret = smu_v13_0_get_gfx_vdd(smu, (uint32_t *)data);
1301 *size = 4;
1302 break;
9366c2e8 1303 case AMDGPU_PP_SENSOR_GPU_AVG_POWER:
511a9555
LL
1304 default:
1305 ret = -EOPNOTSUPP;
1306 break;
1307 }
1308
1309 return ret;
1310}
1311
1312static int smu_v13_0_6_get_power_limit(struct smu_context *smu,
19589468
MJ
1313 uint32_t *current_power_limit,
1314 uint32_t *default_power_limit,
1315 uint32_t *max_power_limit,
1316 uint32_t *min_power_limit)
511a9555 1317{
d397fa5e
RS
1318 struct smu_table_context *smu_table = &smu->smu_table;
1319 struct PPTable_t *pptable =
1320 (struct PPTable_t *)smu_table->driver_pptable;
511a9555
LL
1321 uint32_t power_limit = 0;
1322 int ret;
1323
511a9555
LL
1324 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_GetPptLimit, &power_limit);
1325
1326 if (ret) {
1327 dev_err(smu->adev->dev, "Couldn't get PPT limit");
1328 return -EINVAL;
1329 }
1330
1331 if (current_power_limit)
1332 *current_power_limit = power_limit;
1333 if (default_power_limit)
1334 *default_power_limit = power_limit;
1335
1336 if (max_power_limit) {
1337 *max_power_limit = pptable->MaxSocketPowerLimit;
1338 }
1339
19589468
MJ
1340 if (min_power_limit)
1341 *min_power_limit = 0;
511a9555
LL
1342 return 0;
1343}
1344
1345static int smu_v13_0_6_set_power_limit(struct smu_context *smu,
1346 enum smu_ppt_limit_type limit_type,
1347 uint32_t limit)
1348{
1349 return smu_v13_0_set_power_limit(smu, limit_type, limit);
1350}
1351
676915e4
A
1352static int smu_v13_0_6_irq_process(struct amdgpu_device *adev,
1353 struct amdgpu_irq_src *source,
1354 struct amdgpu_iv_entry *entry)
1355{
1356 struct smu_context *smu = adev->powerplay.pp_handle;
93682f8a
LL
1357 struct smu_power_context *smu_power = &smu->smu_power;
1358 struct smu_13_0_power_context *power_context = smu_power->power_context;
676915e4 1359 uint32_t client_id = entry->client_id;
676915e4 1360 uint32_t ctxid = entry->src_data[0];
93682f8a 1361 uint32_t src_id = entry->src_id;
676915e4
A
1362 uint32_t data;
1363
1364 if (client_id == SOC15_IH_CLIENTID_MP1) {
1365 if (src_id == IH_INTERRUPT_ID_TO_DRIVER) {
1366 /* ACK SMUToHost interrupt */
1367 data = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL);
1368 data = REG_SET_FIELD(data, MP1_SMN_IH_SW_INT_CTRL, INT_ACK, 1);
1369 WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, data);
93682f8a
LL
1370 /*
1371 * ctxid is used to distinguish different events for SMCToHost
1372 * interrupt.
1373 */
676915e4
A
1374 switch (ctxid) {
1375 case IH_INTERRUPT_CONTEXT_ID_THERMAL_THROTTLING:
1376 /*
1377 * Increment the throttle interrupt counter
1378 */
1379 atomic64_inc(&smu->throttle_int_counter);
1380
1381 if (!atomic_read(&adev->throttling_logging_enabled))
1382 return 0;
1383
93682f8a
LL
1384 /* This uses the new method which fixes the
1385 * incorrect throttling status reporting
1386 * through metrics table. For older FWs,
1387 * it will be ignored.
1388 */
1389 if (__ratelimit(&adev->throttling_logging_rs)) {
1390 atomic_set(
1391 &power_context->throttle_status,
1392 entry->src_data[1]);
676915e4 1393 schedule_work(&smu->throttling_logging_work);
93682f8a 1394 }
676915e4
A
1395
1396 break;
1397 }
1398 }
1399 }
1400
1401 return 0;
1402}
1403
87f4c2d9 1404static int smu_v13_0_6_set_irq_state(struct amdgpu_device *adev,
676915e4
A
1405 struct amdgpu_irq_src *source,
1406 unsigned tyep,
1407 enum amdgpu_interrupt_state state)
1408{
1409 uint32_t val = 0;
1410
1411 switch (state) {
1412 case AMDGPU_IRQ_STATE_DISABLE:
1413 /* For MP1 SW irqs */
1414 val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL);
1415 val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT_CTRL, INT_MASK, 1);
1416 WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, val);
1417
1418 break;
1419 case AMDGPU_IRQ_STATE_ENABLE:
1420 /* For MP1 SW irqs */
1421 val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT);
1422 val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT, ID, 0xFE);
1423 val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT, VALID, 0);
1424 WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT, val);
1425
1426 val = RREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL);
1427 val = REG_SET_FIELD(val, MP1_SMN_IH_SW_INT_CTRL, INT_MASK, 0);
1428 WREG32_SOC15(MP1, 0, regMP1_SMN_IH_SW_INT_CTRL, val);
1429
1430 break;
1431 default:
1432 break;
1433 }
1434
1435 return 0;
1436}
1437
d397fa5e 1438static const struct amdgpu_irq_src_funcs smu_v13_0_6_irq_funcs = {
676915e4
A
1439 .set = smu_v13_0_6_set_irq_state,
1440 .process = smu_v13_0_6_irq_process,
1441};
1442
87f4c2d9 1443static int smu_v13_0_6_register_irq_handler(struct smu_context *smu)
676915e4
A
1444{
1445 struct amdgpu_device *adev = smu->adev;
1446 struct amdgpu_irq_src *irq_src = &smu->irq_source;
1447 int ret = 0;
1448
1449 if (amdgpu_sriov_vf(adev))
1450 return 0;
1451
1452 irq_src->num_types = 1;
1453 irq_src->funcs = &smu_v13_0_6_irq_funcs;
1454
1455 ret = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_MP1,
1456 IH_INTERRUPT_ID_TO_DRIVER,
1457 irq_src);
1458 if (ret)
1459 return ret;
1460
1461 return ret;
1462}
1463
7214c08c
LL
1464static int smu_v13_0_6_notify_unload(struct smu_context *smu)
1465{
710d9cae 1466 if (smu->smc_fw_version <= 0x553500)
7214c08c
LL
1467 return 0;
1468
1469 dev_dbg(smu->adev->dev, "Notify PMFW about driver unload");
1470 /* Ignore return, just intimate FW that driver is not going to be there */
1471 smu_cmn_send_smc_msg(smu, SMU_MSG_PrepareMp1ForUnload, NULL);
1472
1473 return 0;
1474}
1475
df38fe12
YW
1476static int smu_v13_0_6_mca_set_debug_mode(struct smu_context *smu, bool enable)
1477{
df38fe12 1478 /* NOTE: this ClearMcaOnRead message is only supported for smu version 85.72.0 or higher */
710d9cae 1479 if (smu->smc_fw_version < 0x554800)
df38fe12
YW
1480 return 0;
1481
4dd9f540 1482 amdgpu_ras_set_mca_debug_mode(smu->adev, enable);
df38fe12
YW
1483 return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_ClearMcaOnRead,
1484 enable ? 0 : ClearMcaOnRead_UE_FLAG_MASK | ClearMcaOnRead_CE_POLL_MASK,
1485 NULL);
1486}
1487
511a9555
LL
1488static int smu_v13_0_6_system_features_control(struct smu_context *smu,
1489 bool enable)
1490{
7214c08c 1491 struct amdgpu_device *adev = smu->adev;
09a77a40 1492 int ret = 0;
7214c08c 1493
ae77d2fa
YW
1494 if (amdgpu_sriov_vf(adev))
1495 return 0;
1496
09a77a40
LM
1497 if (enable) {
1498 if (!(adev->flags & AMD_IS_APU))
1499 ret = smu_v13_0_system_features_control(smu, enable);
1500 } else {
1501 /* Notify FW that the device is no longer driver managed */
1502 smu_v13_0_6_notify_unload(smu);
7214c08c 1503 }
511a9555 1504
511a9555
LL
1505 return ret;
1506}
1507
1508static int smu_v13_0_6_set_gfx_soft_freq_limited_range(struct smu_context *smu,
1509 uint32_t min,
1510 uint32_t max)
1511{
1512 int ret;
1513
1514 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMaxGfxClk,
1515 max & 0xffff, NULL);
1516 if (ret)
1517 return ret;
1518
1519 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetSoftMinGfxclk,
1520 min & 0xffff, NULL);
1521
1522 return ret;
1523}
1524
1525static int smu_v13_0_6_set_performance_level(struct smu_context *smu,
1526 enum amd_dpm_forced_level level)
1527{
1528 struct smu_dpm_context *smu_dpm = &(smu->smu_dpm);
1529 struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;
1530 struct smu_13_0_dpm_table *gfx_table =
1531 &dpm_context->dpm_tables.gfx_table;
1532 struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
1533 int ret;
1534
1535 /* Disable determinism if switching to another mode */
1536 if ((smu_dpm->dpm_level == AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) &&
1537 (level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM)) {
1538 smu_cmn_send_smc_msg(smu, SMU_MSG_DisableDeterminism, NULL);
1539 pstate_table->gfxclk_pstate.curr.max = gfx_table->max;
1540 }
1541
1542 switch (level) {
1543 case AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM:
1544 return 0;
1545
1546 case AMD_DPM_FORCED_LEVEL_AUTO:
1547 if ((gfx_table->min == pstate_table->gfxclk_pstate.curr.min) &&
1548 (gfx_table->max == pstate_table->gfxclk_pstate.curr.max))
1549 return 0;
1550
1551 ret = smu_v13_0_6_set_gfx_soft_freq_limited_range(
1552 smu, gfx_table->min, gfx_table->max);
1553 if (ret)
1554 return ret;
1555
1556 pstate_table->gfxclk_pstate.curr.min = gfx_table->min;
1557 pstate_table->gfxclk_pstate.curr.max = gfx_table->max;
1558 return 0;
1559 case AMD_DPM_FORCED_LEVEL_MANUAL:
1560 return 0;
1561 default:
1562 break;
1563 }
1564
1565 return -EINVAL;
1566}
1567
1568static int smu_v13_0_6_set_soft_freq_limited_range(struct smu_context *smu,
1569 enum smu_clk_type clk_type,
1570 uint32_t min, uint32_t max)
1571{
1572 struct smu_dpm_context *smu_dpm = &(smu->smu_dpm);
1573 struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;
1574 struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
1575 struct amdgpu_device *adev = smu->adev;
1576 uint32_t min_clk;
1577 uint32_t max_clk;
1578 int ret = 0;
1579
1580 if (clk_type != SMU_GFXCLK && clk_type != SMU_SCLK)
1581 return -EINVAL;
1582
1583 if ((smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) &&
1584 (smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM))
1585 return -EINVAL;
1586
1587 if (smu_dpm->dpm_level == AMD_DPM_FORCED_LEVEL_MANUAL) {
1588 if (min >= max) {
1589 dev_err(smu->adev->dev,
1590 "Minimum GFX clk should be less than the maximum allowed clock\n");
1591 return -EINVAL;
1592 }
1593
1594 if ((min == pstate_table->gfxclk_pstate.curr.min) &&
1595 (max == pstate_table->gfxclk_pstate.curr.max))
1596 return 0;
1597
1598 ret = smu_v13_0_6_set_gfx_soft_freq_limited_range(smu, min, max);
1599 if (!ret) {
1600 pstate_table->gfxclk_pstate.curr.min = min;
1601 pstate_table->gfxclk_pstate.curr.max = max;
1602 }
1603
1604 return ret;
1605 }
1606
1607 if (smu_dpm->dpm_level == AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM) {
1608 if (!max || (max < dpm_context->dpm_tables.gfx_table.min) ||
1609 (max > dpm_context->dpm_tables.gfx_table.max)) {
1610 dev_warn(
1611 adev->dev,
1612 "Invalid max frequency %d MHz specified for determinism\n",
1613 max);
1614 return -EINVAL;
1615 }
1616
1617 /* Restore default min/max clocks and enable determinism */
1618 min_clk = dpm_context->dpm_tables.gfx_table.min;
1619 max_clk = dpm_context->dpm_tables.gfx_table.max;
1620 ret = smu_v13_0_6_set_gfx_soft_freq_limited_range(smu, min_clk,
1621 max_clk);
1622 if (!ret) {
1623 usleep_range(500, 1000);
1624 ret = smu_cmn_send_smc_msg_with_param(
1625 smu, SMU_MSG_EnableDeterminism, max, NULL);
1626 if (ret) {
1627 dev_err(adev->dev,
1628 "Failed to enable determinism at GFX clock %d MHz\n",
1629 max);
1630 } else {
1631 pstate_table->gfxclk_pstate.curr.min = min_clk;
1632 pstate_table->gfxclk_pstate.curr.max = max;
1633 }
1634 }
1635 }
1636
1637 return ret;
1638}
1639
1640static int smu_v13_0_6_usr_edit_dpm_table(struct smu_context *smu,
1641 enum PP_OD_DPM_TABLE_COMMAND type,
1642 long input[], uint32_t size)
1643{
1644 struct smu_dpm_context *smu_dpm = &(smu->smu_dpm);
1645 struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;
1646 struct smu_umd_pstate_table *pstate_table = &smu->pstate_table;
1647 uint32_t min_clk;
1648 uint32_t max_clk;
1649 int ret = 0;
1650
1651 /* Only allowed in manual or determinism mode */
1652 if ((smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_MANUAL) &&
1653 (smu_dpm->dpm_level != AMD_DPM_FORCED_LEVEL_PERF_DETERMINISM))
1654 return -EINVAL;
1655
1656 switch (type) {
1657 case PP_OD_EDIT_SCLK_VDDC_TABLE:
1658 if (size != 2) {
1659 dev_err(smu->adev->dev,
1660 "Input parameter number not correct\n");
1661 return -EINVAL;
1662 }
1663
1664 if (input[0] == 0) {
1665 if (input[1] < dpm_context->dpm_tables.gfx_table.min) {
1666 dev_warn(
1667 smu->adev->dev,
1668 "Minimum GFX clk (%ld) MHz specified is less than the minimum allowed (%d) MHz\n",
1669 input[1],
1670 dpm_context->dpm_tables.gfx_table.min);
1671 pstate_table->gfxclk_pstate.custom.min =
1672 pstate_table->gfxclk_pstate.curr.min;
1673 return -EINVAL;
1674 }
1675
1676 pstate_table->gfxclk_pstate.custom.min = input[1];
1677 } else if (input[0] == 1) {
1678 if (input[1] > dpm_context->dpm_tables.gfx_table.max) {
1679 dev_warn(
1680 smu->adev->dev,
1681 "Maximum GFX clk (%ld) MHz specified is greater than the maximum allowed (%d) MHz\n",
1682 input[1],
1683 dpm_context->dpm_tables.gfx_table.max);
1684 pstate_table->gfxclk_pstate.custom.max =
1685 pstate_table->gfxclk_pstate.curr.max;
1686 return -EINVAL;
1687 }
1688
1689 pstate_table->gfxclk_pstate.custom.max = input[1];
1690 } else {
1691 return -EINVAL;
1692 }
1693 break;
1694 case PP_OD_RESTORE_DEFAULT_TABLE:
1695 if (size != 0) {
1696 dev_err(smu->adev->dev,
1697 "Input parameter number not correct\n");
1698 return -EINVAL;
1699 } else {
1700 /* Use the default frequencies for manual and determinism mode */
1701 min_clk = dpm_context->dpm_tables.gfx_table.min;
1702 max_clk = dpm_context->dpm_tables.gfx_table.max;
1703
1704 return smu_v13_0_6_set_soft_freq_limited_range(
1705 smu, SMU_GFXCLK, min_clk, max_clk);
1706 }
1707 break;
1708 case PP_OD_COMMIT_DPM_TABLE:
1709 if (size != 0) {
1710 dev_err(smu->adev->dev,
1711 "Input parameter number not correct\n");
1712 return -EINVAL;
1713 } else {
1714 if (!pstate_table->gfxclk_pstate.custom.min)
1715 pstate_table->gfxclk_pstate.custom.min =
1716 pstate_table->gfxclk_pstate.curr.min;
1717
1718 if (!pstate_table->gfxclk_pstate.custom.max)
1719 pstate_table->gfxclk_pstate.custom.max =
1720 pstate_table->gfxclk_pstate.curr.max;
1721
1722 min_clk = pstate_table->gfxclk_pstate.custom.min;
1723 max_clk = pstate_table->gfxclk_pstate.custom.max;
1724
1725 return smu_v13_0_6_set_soft_freq_limited_range(
1726 smu, SMU_GFXCLK, min_clk, max_clk);
1727 }
1728 break;
1729 default:
1730 return -ENOSYS;
1731 }
1732
1733 return ret;
1734}
1735
1736static int smu_v13_0_6_get_enabled_mask(struct smu_context *smu,
1737 uint64_t *feature_mask)
1738{
511a9555
LL
1739 int ret;
1740
511a9555
LL
1741 ret = smu_cmn_get_enabled_mask(smu, feature_mask);
1742
710d9cae 1743 if (ret == -EIO && smu->smc_fw_version < 0x552F00) {
511a9555
LL
1744 *feature_mask = 0;
1745 ret = 0;
1746 }
1747
1748 return ret;
1749}
1750
1751static bool smu_v13_0_6_is_dpm_running(struct smu_context *smu)
1752{
1753 int ret;
1754 uint64_t feature_enabled;
1755
1756 ret = smu_v13_0_6_get_enabled_mask(smu, &feature_enabled);
1757
1758 if (ret)
1759 return false;
1760
1761 return !!(feature_enabled & SMC_DPM_FEATURE);
1762}
1763
1764static int smu_v13_0_6_request_i2c_xfer(struct smu_context *smu,
1765 void *table_data)
1766{
1767 struct smu_table_context *smu_table = &smu->smu_table;
1768 struct smu_table *table = &smu_table->driver_table;
1769 struct amdgpu_device *adev = smu->adev;
1770 uint32_t table_size;
1771 int ret = 0;
1772
1773 if (!table_data)
1774 return -EINVAL;
1775
1776 table_size = smu_table->tables[SMU_TABLE_I2C_COMMANDS].size;
1777
1778 memcpy(table->cpu_addr, table_data, table_size);
1779 /* Flush hdp cache */
1780 amdgpu_asic_flush_hdp(adev, NULL);
1781 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_RequestI2cTransaction,
1782 NULL);
1783
1784 return ret;
1785}
1786
1787static int smu_v13_0_6_i2c_xfer(struct i2c_adapter *i2c_adap,
1788 struct i2c_msg *msg, int num_msgs)
1789{
1790 struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(i2c_adap);
1791 struct amdgpu_device *adev = smu_i2c->adev;
1792 struct smu_context *smu = adev->powerplay.pp_handle;
1793 struct smu_table_context *smu_table = &smu->smu_table;
1794 struct smu_table *table = &smu_table->driver_table;
1795 SwI2cRequest_t *req, *res = (SwI2cRequest_t *)table->cpu_addr;
1796 int i, j, r, c;
1797 u16 dir;
1798
1799 if (!adev->pm.dpm_enabled)
1800 return -EBUSY;
1801
1802 req = kzalloc(sizeof(*req), GFP_KERNEL);
1803 if (!req)
1804 return -ENOMEM;
1805
1806 req->I2CcontrollerPort = smu_i2c->port;
1807 req->I2CSpeed = I2C_SPEED_FAST_400K;
1808 req->SlaveAddress = msg[0].addr << 1; /* wants an 8-bit address */
1809 dir = msg[0].flags & I2C_M_RD;
1810
1811 for (c = i = 0; i < num_msgs; i++) {
1812 for (j = 0; j < msg[i].len; j++, c++) {
1813 SwI2cCmd_t *cmd = &req->SwI2cCmds[c];
1814
1815 if (!(msg[i].flags & I2C_M_RD)) {
1816 /* write */
1817 cmd->CmdConfig |= CMDCONFIG_READWRITE_MASK;
1818 cmd->ReadWriteData = msg[i].buf[j];
1819 }
1820
1821 if ((dir ^ msg[i].flags) & I2C_M_RD) {
1822 /* The direction changes.
1823 */
1824 dir = msg[i].flags & I2C_M_RD;
1825 cmd->CmdConfig |= CMDCONFIG_RESTART_MASK;
1826 }
1827
1828 req->NumCmds++;
1829
1830 /*
1831 * Insert STOP if we are at the last byte of either last
1832 * message for the transaction or the client explicitly
1833 * requires a STOP at this particular message.
1834 */
1835 if ((j == msg[i].len - 1) &&
1836 ((i == num_msgs - 1) || (msg[i].flags & I2C_M_STOP))) {
1837 cmd->CmdConfig &= ~CMDCONFIG_RESTART_MASK;
1838 cmd->CmdConfig |= CMDCONFIG_STOP_MASK;
1839 }
1840 }
1841 }
1842 mutex_lock(&adev->pm.mutex);
1843 r = smu_v13_0_6_request_i2c_xfer(smu, req);
511a9555
LL
1844 if (r)
1845 goto fail;
1846
1847 for (c = i = 0; i < num_msgs; i++) {
1848 if (!(msg[i].flags & I2C_M_RD)) {
1849 c += msg[i].len;
1850 continue;
1851 }
1852 for (j = 0; j < msg[i].len; j++, c++) {
1853 SwI2cCmd_t *cmd = &res->SwI2cCmds[c];
1854
1855 msg[i].buf[j] = cmd->ReadWriteData;
1856 }
1857 }
1858 r = num_msgs;
1859fail:
d934e537 1860 mutex_unlock(&adev->pm.mutex);
511a9555
LL
1861 kfree(req);
1862 return r;
1863}
1864
1865static u32 smu_v13_0_6_i2c_func(struct i2c_adapter *adap)
1866{
1867 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
1868}
1869
1870static const struct i2c_algorithm smu_v13_0_6_i2c_algo = {
1871 .master_xfer = smu_v13_0_6_i2c_xfer,
1872 .functionality = smu_v13_0_6_i2c_func,
1873};
1874
1875static const struct i2c_adapter_quirks smu_v13_0_6_i2c_control_quirks = {
1876 .flags = I2C_AQ_COMB | I2C_AQ_COMB_SAME_ADDR | I2C_AQ_NO_ZERO_LEN,
1877 .max_read_len = MAX_SW_I2C_COMMANDS,
1878 .max_write_len = MAX_SW_I2C_COMMANDS,
1879 .max_comb_1st_msg_len = 2,
1880 .max_comb_2nd_msg_len = MAX_SW_I2C_COMMANDS - 2,
1881};
1882
1883static int smu_v13_0_6_i2c_control_init(struct smu_context *smu)
1884{
1885 struct amdgpu_device *adev = smu->adev;
1886 int res, i;
1887
1888 for (i = 0; i < MAX_SMU_I2C_BUSES; i++) {
1889 struct amdgpu_smu_i2c_bus *smu_i2c = &adev->pm.smu_i2c[i];
1890 struct i2c_adapter *control = &smu_i2c->adapter;
1891
1892 smu_i2c->adev = adev;
1893 smu_i2c->port = i;
1894 mutex_init(&smu_i2c->mutex);
1895 control->owner = THIS_MODULE;
1896 control->class = I2C_CLASS_SPD;
1897 control->dev.parent = &adev->pdev->dev;
1898 control->algo = &smu_v13_0_6_i2c_algo;
1899 snprintf(control->name, sizeof(control->name), "AMDGPU SMU %d", i);
1900 control->quirks = &smu_v13_0_6_i2c_control_quirks;
1901 i2c_set_adapdata(control, smu_i2c);
1902
1903 res = i2c_add_adapter(control);
1904 if (res) {
1905 DRM_ERROR("Failed to register hw i2c, err: %d\n", res);
1906 goto Out_err;
1907 }
1908 }
1909
1910 adev->pm.ras_eeprom_i2c_bus = &adev->pm.smu_i2c[0].adapter;
1911 adev->pm.fru_eeprom_i2c_bus = &adev->pm.smu_i2c[0].adapter;
1912
1913 return 0;
1914Out_err:
1915 for ( ; i >= 0; i--) {
1916 struct amdgpu_smu_i2c_bus *smu_i2c = &adev->pm.smu_i2c[i];
1917 struct i2c_adapter *control = &smu_i2c->adapter;
1918
1919 i2c_del_adapter(control);
1920 }
1921 return res;
1922}
1923
1924static void smu_v13_0_6_i2c_control_fini(struct smu_context *smu)
1925{
1926 struct amdgpu_device *adev = smu->adev;
1927 int i;
1928
1929 for (i = 0; i < MAX_SMU_I2C_BUSES; i++) {
1930 struct amdgpu_smu_i2c_bus *smu_i2c = &adev->pm.smu_i2c[i];
1931 struct i2c_adapter *control = &smu_i2c->adapter;
1932
1933 i2c_del_adapter(control);
1934 }
1935 adev->pm.ras_eeprom_i2c_bus = NULL;
1936 adev->pm.fru_eeprom_i2c_bus = NULL;
1937}
1938
1939static void smu_v13_0_6_get_unique_id(struct smu_context *smu)
1940{
1941 struct amdgpu_device *adev = smu->adev;
5e86aa29
YW
1942 struct smu_table_context *smu_table = &smu->smu_table;
1943 struct PPTable_t *pptable =
1944 (struct PPTable_t *)smu_table->driver_pptable;
511a9555 1945
5e86aa29 1946 adev->unique_id = pptable->PublicSerialNumber_AID;
511a9555
LL
1947}
1948
1949static bool smu_v13_0_6_is_baco_supported(struct smu_context *smu)
1950{
1951 /* smu_13_0_6 does not support baco */
1952
1953 return false;
1954}
1955
93682f8a
LL
1956static const char *const throttling_logging_label[] = {
1957 [THROTTLER_PROCHOT_BIT] = "Prochot",
1958 [THROTTLER_PPT_BIT] = "PPT",
1959 [THROTTLER_THERMAL_SOCKET_BIT] = "SOC",
1960 [THROTTLER_THERMAL_VR_BIT] = "VR",
1961 [THROTTLER_THERMAL_HBM_BIT] = "HBM"
511a9555 1962};
93682f8a 1963
511a9555
LL
1964static void smu_v13_0_6_log_thermal_throttling_event(struct smu_context *smu)
1965{
ddf1639b 1966 int throttler_idx, throttling_events = 0, buf_idx = 0;
511a9555
LL
1967 struct amdgpu_device *adev = smu->adev;
1968 uint32_t throttler_status;
1969 char log_buf[256];
1970
93682f8a
LL
1971 throttler_status = smu_v13_0_6_get_throttler_status(smu);
1972 if (!throttler_status)
511a9555
LL
1973 return;
1974
1975 memset(log_buf, 0, sizeof(log_buf));
93682f8a
LL
1976 for (throttler_idx = 0;
1977 throttler_idx < ARRAY_SIZE(throttling_logging_label);
511a9555 1978 throttler_idx++) {
93682f8a 1979 if (throttler_status & (1U << throttler_idx)) {
ddf1639b 1980 throttling_events++;
93682f8a
LL
1981 buf_idx += snprintf(
1982 log_buf + buf_idx, sizeof(log_buf) - buf_idx,
ddf1639b 1983 "%s%s", throttling_events > 1 ? " and " : "",
93682f8a 1984 throttling_logging_label[throttler_idx]);
511a9555
LL
1985 if (buf_idx >= sizeof(log_buf)) {
1986 dev_err(adev->dev, "buffer overflow!\n");
1987 log_buf[sizeof(log_buf) - 1] = '\0';
1988 break;
1989 }
1990 }
1991 }
1992
93682f8a
LL
1993 dev_warn(adev->dev,
1994 "WARN: GPU is throttled, expect performance decrease. %s.\n",
1995 log_buf);
511a9555
LL
1996 kgd2kfd_smi_event_throttle(
1997 smu->adev->kfd.dev,
1998 smu_cmn_get_indep_throttler_status(throttler_status,
1999 smu_v13_0_6_throttler_map));
2000}
2001
1718e973
LL
2002static int
2003smu_v13_0_6_get_current_pcie_link_width_level(struct smu_context *smu)
2004{
2005 struct amdgpu_device *adev = smu->adev;
2006
2007 return REG_GET_FIELD(RREG32_PCIE(smnPCIE_LC_LINK_WIDTH_CNTL),
2008 PCIE_LC_LINK_WIDTH_CNTL, LC_LINK_WIDTH_RD);
2009}
2010
511a9555
LL
2011static int smu_v13_0_6_get_current_pcie_link_speed(struct smu_context *smu)
2012{
2013 struct amdgpu_device *adev = smu->adev;
f1d1abd6 2014 uint32_t speed_level;
511a9555
LL
2015 uint32_t esm_ctrl;
2016
2017 /* TODO: confirm this on real target */
2018 esm_ctrl = RREG32_PCIE(smnPCIE_ESM_CTRL);
2019 if ((esm_ctrl >> 15) & 0x1FFFF)
2020 return (((esm_ctrl >> 8) & 0x3F) + 128);
2021
f1d1abd6
AK
2022 speed_level = (RREG32_PCIE(smnPCIE_LC_SPEED_CNTL) &
2023 PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE_MASK)
2024 >> PCIE_LC_SPEED_CNTL__LC_CURRENT_DATA_RATE__SHIFT;
2025 if (speed_level > LINK_SPEED_MAX)
2026 speed_level = 0;
2027
2028 return pcie_gen_to_speed(speed_level + 1);
511a9555
LL
2029}
2030
2031static ssize_t smu_v13_0_6_get_gpu_metrics(struct smu_context *smu, void **table)
2032{
2033 struct smu_table_context *smu_table = &smu->smu_table;
915414d0
AK
2034 struct gpu_metrics_v1_4 *gpu_metrics =
2035 (struct gpu_metrics_v1_4 *)smu_table->gpu_metrics_table;
1718e973 2036 struct amdgpu_device *adev = smu->adev;
915414d0 2037 int ret = 0, xcc_id, inst, i;
511a9555 2038 MetricsTable_t *metrics;
1d02ae4e 2039 u16 link_width_level;
1718e973 2040
511a9555
LL
2041 metrics = kzalloc(sizeof(MetricsTable_t), GFP_KERNEL);
2042 ret = smu_v13_0_6_get_metrics_table(smu, metrics, true);
828f8e31
KC
2043 if (ret) {
2044 kfree(metrics);
511a9555 2045 return ret;
828f8e31 2046 }
511a9555 2047
915414d0 2048 smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 4);
511a9555 2049
1718e973 2050 gpu_metrics->temperature_hotspot =
4ea7fb33 2051 SMUQ10_ROUND(metrics->MaxSocketTemperature);
1718e973
LL
2052 /* Individual HBM stack temperature is not reported */
2053 gpu_metrics->temperature_mem =
4ea7fb33 2054 SMUQ10_ROUND(metrics->MaxHbmTemperature);
1718e973
LL
2055 /* Reports max temperature of all voltage rails */
2056 gpu_metrics->temperature_vrsoc =
4ea7fb33 2057 SMUQ10_ROUND(metrics->MaxVrTemperature);
1718e973
LL
2058
2059 gpu_metrics->average_gfx_activity =
4ea7fb33 2060 SMUQ10_ROUND(metrics->SocketGfxBusy);
1718e973 2061 gpu_metrics->average_umc_activity =
4ea7fb33 2062 SMUQ10_ROUND(metrics->DramBandwidthUtilization);
1718e973 2063
915414d0 2064 gpu_metrics->curr_socket_power =
4ea7fb33 2065 SMUQ10_ROUND(metrics->SocketPower);
3b885ab2
LL
2066 /* Energy counter reported in 15.259uJ (2^-16) units */
2067 gpu_metrics->energy_accumulator = metrics->SocketEnergyAcc;
1718e973 2068
915414d0
AK
2069 for (i = 0; i < MAX_GFX_CLKS; i++) {
2070 xcc_id = GET_INST(GC, i);
2071 if (xcc_id >= 0)
2072 gpu_metrics->current_gfxclk[i] =
2073 SMUQ10_ROUND(metrics->GfxclkFrequency[xcc_id]);
2074
2075 if (i < MAX_CLKS) {
2076 gpu_metrics->current_socclk[i] =
2077 SMUQ10_ROUND(metrics->SocclkFrequency[i]);
2078 inst = GET_INST(VCN, i);
2079 if (inst >= 0) {
2080 gpu_metrics->current_vclk0[i] =
2081 SMUQ10_ROUND(metrics->VclkFrequency[inst]);
2082 gpu_metrics->current_dclk0[i] =
2083 SMUQ10_ROUND(metrics->DclkFrequency[inst]);
2084 }
2085 }
2086 }
1718e973 2087
915414d0 2088 gpu_metrics->current_uclk = SMUQ10_ROUND(metrics->UclkFrequency);
1718e973
LL
2089
2090 /* Throttle status is not reported through metrics now */
511a9555 2091 gpu_metrics->throttle_status = 0;
511a9555 2092
915414d0
AK
2093 /* Clock Lock Status. Each bit corresponds to each GFXCLK instance */
2094 gpu_metrics->gfxclk_lock_status = metrics->GfxLockXCDMak >> GET_INST(GC, 0);
2095
1718e973 2096 if (!(adev->flags & AMD_IS_APU)) {
1d02ae4e
AK
2097 link_width_level = smu_v13_0_6_get_current_pcie_link_width_level(smu);
2098 if (link_width_level > MAX_LINK_WIDTH)
2099 link_width_level = 0;
2100
1718e973 2101 gpu_metrics->pcie_link_width =
1d02ae4e 2102 DECODE_LANE_WIDTH(link_width_level);
1718e973
LL
2103 gpu_metrics->pcie_link_speed =
2104 smu_v13_0_6_get_current_pcie_link_speed(smu);
915414d0
AK
2105 gpu_metrics->pcie_bandwidth_acc =
2106 SMUQ10_ROUND(metrics->PcieBandwidthAcc[0]);
1718e973 2107 }
511a9555
LL
2108
2109 gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
2110
1718e973 2111 gpu_metrics->gfx_activity_acc =
4ea7fb33 2112 SMUQ10_ROUND(metrics->SocketGfxBusyAcc);
1718e973 2113 gpu_metrics->mem_activity_acc =
4ea7fb33 2114 SMUQ10_ROUND(metrics->DramBandwidthUtilizationAcc);
511a9555 2115
915414d0
AK
2116 for (i = 0; i < NUM_XGMI_LINKS; i++) {
2117 gpu_metrics->xgmi_read_data_acc[i] =
2118 SMUQ10_ROUND(metrics->XgmiReadDataSizeAcc[i]);
2119 gpu_metrics->xgmi_write_data_acc[i] =
2120 SMUQ10_ROUND(metrics->XgmiWriteDataSizeAcc[i]);
2121 }
2122
2123 gpu_metrics->xgmi_link_width = SMUQ10_ROUND(metrics->XgmiWidth);
2124 gpu_metrics->xgmi_link_speed = SMUQ10_ROUND(metrics->XgmiBitrate);
2125
1718e973 2126 gpu_metrics->firmware_timestamp = metrics->Timestamp;
511a9555
LL
2127
2128 *table = (void *)gpu_metrics;
2129 kfree(metrics);
2130
915414d0 2131 return sizeof(*gpu_metrics);
511a9555
LL
2132}
2133
2134static int smu_v13_0_6_mode2_reset(struct smu_context *smu)
2135{
511a9555
LL
2136 int ret = 0, index;
2137 struct amdgpu_device *adev = smu->adev;
2138 int timeout = 10;
2139
511a9555
LL
2140 index = smu_cmn_to_asic_specific_index(smu, CMN2ASIC_MAPPING_MSG,
2141 SMU_MSG_GfxDeviceDriverReset);
2142
2143 mutex_lock(&smu->message_lock);
8f2ccaaa 2144
511a9555
LL
2145 ret = smu_cmn_send_msg_without_waiting(smu, (uint16_t)index,
2146 SMU_RESET_MODE_2);
8f2ccaaa 2147
511a9555
LL
2148 /* This is similar to FLR, wait till max FLR timeout */
2149 msleep(100);
8f2ccaaa 2150
511a9555
LL
2151 dev_dbg(smu->adev->dev, "restore config space...\n");
2152 /* Restore the config space saved during init */
2153 amdgpu_device_load_pci_state(adev->pdev);
2154
2155 dev_dbg(smu->adev->dev, "wait for reset ack\n");
8f2ccaaa 2156 do {
511a9555
LL
2157 ret = smu_cmn_wait_for_response(smu);
2158 /* Wait a bit more time for getting ACK */
2159 if (ret == -ETIME) {
2160 --timeout;
2161 usleep_range(500, 1000);
2162 continue;
2163 }
2164
8f2ccaaa 2165 if (ret) {
511a9555 2166 dev_err(adev->dev,
8f2ccaaa 2167 "failed to send mode2 message \tparam: 0x%08x error code %d\n",
511a9555
LL
2168 SMU_RESET_MODE_2, ret);
2169 goto out;
2170 }
8f2ccaaa 2171 } while (ret == -ETIME && timeout);
511a9555 2172
511a9555
LL
2173out:
2174 mutex_unlock(&smu->message_lock);
2175
2176 return ret;
2177}
2178
07864911
AK
2179static int smu_v13_0_6_get_thermal_temperature_range(struct smu_context *smu,
2180 struct smu_temperature_range *range)
2181{
2182 struct amdgpu_device *adev = smu->adev;
df7a2808 2183 u32 aid_temp, xcd_temp, max_temp;
07864911
AK
2184 u32 ccd_temp = 0;
2185 int ret;
2186
2187 if (amdgpu_sriov_vf(smu->adev))
2188 return 0;
2189
2190 if (!range)
2191 return -EINVAL;
2192
2193 /*Check smu version, GetCtfLimit message only supported for smu version 85.69 or higher */
710d9cae 2194 if (smu->smc_fw_version < 0x554500)
07864911
AK
2195 return 0;
2196
df7a2808 2197 /* Get SOC Max operating temperature */
07864911
AK
2198 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetCTFLimit,
2199 PPSMC_AID_THM_TYPE, &aid_temp);
2200 if (ret)
2201 goto failed;
07864911
AK
2202 if (adev->flags & AMD_IS_APU) {
2203 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetCTFLimit,
2204 PPSMC_CCD_THM_TYPE, &ccd_temp);
2205 if (ret)
2206 goto failed;
2207 }
07864911
AK
2208 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetCTFLimit,
2209 PPSMC_XCD_THM_TYPE, &xcd_temp);
2210 if (ret)
2211 goto failed;
df7a2808 2212 range->hotspot_emergency_max = max3(aid_temp, xcd_temp, ccd_temp) *
d28e6d5a 2213 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
df7a2808
LL
2214
2215 /* Get HBM Max operating temperature */
07864911 2216 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetCTFLimit,
df7a2808 2217 PPSMC_HBM_THM_TYPE, &max_temp);
07864911
AK
2218 if (ret)
2219 goto failed;
df7a2808
LL
2220 range->mem_emergency_max =
2221 max_temp * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
2222
2223 /* Get SOC thermal throttle limit */
2224 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetThermalLimit,
2225 PPSMC_THROTTLING_LIMIT_TYPE_SOCKET,
2226 &max_temp);
2227 if (ret)
2228 goto failed;
2229 range->hotspot_crit_max =
2230 max_temp * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
2231
2232 /* Get HBM thermal throttle limit */
2233 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GetThermalLimit,
2234 PPSMC_THROTTLING_LIMIT_TYPE_HBM,
2235 &max_temp);
2236 if (ret)
2237 goto failed;
2238
2239 range->mem_crit_max = max_temp * SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
07864911 2240
07864911
AK
2241failed:
2242 return ret;
2243}
2244
511a9555
LL
2245static int smu_v13_0_6_mode1_reset(struct smu_context *smu)
2246{
2247 struct amdgpu_device *adev = smu->adev;
53dd920c
AK
2248 struct amdgpu_hive_info *hive = NULL;
2249 u32 hive_ras_recovery = 0;
511a9555
LL
2250 struct amdgpu_ras *ras;
2251 u32 fatal_err, param;
2252 int ret = 0;
2253
53dd920c 2254 hive = amdgpu_get_xgmi_hive(adev);
511a9555
LL
2255 ras = amdgpu_ras_get_context(adev);
2256 fatal_err = 0;
2257 param = SMU_RESET_MODE_1;
2258
53dd920c
AK
2259 if (hive) {
2260 hive_ras_recovery = atomic_read(&hive->ras_recovery);
2261 amdgpu_put_xgmi_hive(hive);
2262 }
2263
511a9555 2264 /* fatal error triggered by ras, PMFW supports the flag */
53dd920c 2265 if (ras && (atomic_read(&ras->in_recovery) || hive_ras_recovery))
511a9555
LL
2266 fatal_err = 1;
2267
2268 param |= (fatal_err << 16);
2269 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_GfxDeviceDriverReset,
2270 param, NULL);
2271
2272 if (!ret)
2273 msleep(SMU13_MODE1_RESET_WAIT_TIME_IN_MS);
2274
2275 return ret;
2276}
2277
2278static bool smu_v13_0_6_is_mode1_reset_supported(struct smu_context *smu)
2279{
c4b9dc53 2280 return true;
511a9555
LL
2281}
2282
2283static bool smu_v13_0_6_is_mode2_reset_supported(struct smu_context *smu)
2284{
2285 return true;
2286}
2287
2288static int smu_v13_0_6_smu_send_hbm_bad_page_num(struct smu_context *smu,
2289 uint32_t size)
2290{
2291 int ret = 0;
2292
2293 /* message SMU to update the bad page number on SMUBUS */
2294 ret = smu_cmn_send_smc_msg_with_param(
2295 smu, SMU_MSG_SetNumBadHbmPagesRetired, size, NULL);
2296 if (ret)
2297 dev_err(smu->adev->dev,
2298 "[%s] failed to message SMU to update HBM bad pages number\n",
2299 __func__);
2300
2301 return ret;
2302}
2303
df38fe12
YW
2304static int smu_v13_0_6_post_init(struct smu_context *smu)
2305{
2306 struct amdgpu_device *adev = smu->adev;
2307
ce43a5fa 2308 if (!amdgpu_sriov_vf(adev) && adev->ras_enabled)
df38fe12
YW
2309 return smu_v13_0_6_mca_set_debug_mode(smu, true);
2310
2311 return 0;
2312}
2313
25396684
YW
2314static int mca_smu_set_debug_mode(struct amdgpu_device *adev, bool enable)
2315{
2316 struct smu_context *smu = adev->powerplay.pp_handle;
2317
2318 return smu_v13_0_6_mca_set_debug_mode(smu, enable);
2319}
2320
2321static int smu_v13_0_6_get_valid_mca_count(struct smu_context *smu, enum amdgpu_mca_error_type type, uint32_t *count)
2322{
2323 uint32_t msg;
2324 int ret;
2325
2326 if (!count)
2327 return -EINVAL;
2328
2329 switch (type) {
2330 case AMDGPU_MCA_ERROR_TYPE_UE:
2331 msg = SMU_MSG_QueryValidMcaCount;
2332 break;
2333 case AMDGPU_MCA_ERROR_TYPE_CE:
2334 msg = SMU_MSG_QueryValidMcaCeCount;
2335 break;
2336 default:
2337 return -EINVAL;
2338 }
2339
2340 ret = smu_cmn_send_smc_msg(smu, msg, count);
2341 if (ret) {
2342 *count = 0;
2343 return ret;
2344 }
2345
2346 return 0;
2347}
2348
2349static int __smu_v13_0_6_mca_dump_bank(struct smu_context *smu, enum amdgpu_mca_error_type type,
2350 int idx, int offset, uint32_t *val)
2351{
2352 uint32_t msg, param;
2353
2354 switch (type) {
2355 case AMDGPU_MCA_ERROR_TYPE_UE:
2356 msg = SMU_MSG_McaBankDumpDW;
2357 break;
2358 case AMDGPU_MCA_ERROR_TYPE_CE:
2359 msg = SMU_MSG_McaBankCeDumpDW;
2360 break;
2361 default:
2362 return -EINVAL;
2363 }
2364
2365 param = ((idx & 0xffff) << 16) | (offset & 0xfffc);
2366
2367 return smu_cmn_send_smc_msg_with_param(smu, msg, param, val);
2368}
2369
2370static int smu_v13_0_6_mca_dump_bank(struct smu_context *smu, enum amdgpu_mca_error_type type,
2371 int idx, int offset, uint32_t *val, int count)
2372{
2373 int ret, i;
2374
2375 if (!val)
2376 return -EINVAL;
2377
2378 for (i = 0; i < count; i++) {
2379 ret = __smu_v13_0_6_mca_dump_bank(smu, type, idx, offset + (i << 2), &val[i]);
2380 if (ret)
2381 return ret;
2382 }
2383
2384 return 0;
2385}
2386
2387static const struct mca_bank_ipid smu_v13_0_6_mca_ipid_table[AMDGPU_MCA_IP_COUNT] = {
2388 MCA_BANK_IPID(UMC, 0x96, 0x0),
2389 MCA_BANK_IPID(SMU, 0x01, 0x1),
2390 MCA_BANK_IPID(MP5, 0x01, 0x2),
2391};
2392
2393static void mca_bank_entry_info_decode(struct mca_bank_entry *entry, struct mca_bank_info *info)
2394{
2395 uint64_t ipid = entry->regs[MCA_REG_IDX_IPID];
2396 uint32_t insthi;
2397
2398 /* NOTE: All MCA IPID register share the same format,
2399 * so the driver can share the MCMP1 register header file.
2400 * */
2401
2402 info->hwid = REG_GET_FIELD(ipid, MCMP1_IPIDT0, HardwareID);
2403 info->mcatype = REG_GET_FIELD(ipid, MCMP1_IPIDT0, McaType);
2404
2405 insthi = REG_GET_FIELD(ipid, MCMP1_IPIDT0, InstanceIdHi);
2406 info->aid = ((insthi >> 2) & 0x03);
2407 info->socket_id = insthi & 0x03;
2408}
2409
2410static int mca_bank_read_reg(struct amdgpu_device *adev, enum amdgpu_mca_error_type type,
2411 int idx, int reg_idx, uint64_t *val)
2412{
2413 struct smu_context *smu = adev->powerplay.pp_handle;
2414 uint32_t data[2] = {0, 0};
2415 int ret;
2416
2417 if (!val || reg_idx >= MCA_REG_IDX_COUNT)
2418 return -EINVAL;
2419
2420 ret = smu_v13_0_6_mca_dump_bank(smu, type, idx, reg_idx * 8, data, ARRAY_SIZE(data));
2421 if (ret)
2422 return ret;
2423
2424 *val = (uint64_t)data[1] << 32 | data[0];
2425
2426 dev_dbg(adev->dev, "mca read bank reg: type:%s, index: %d, reg_idx: %d, val: 0x%016llx\n",
2427 type == AMDGPU_MCA_ERROR_TYPE_UE ? "UE" : "CE", idx, reg_idx, *val);
2428
2429 return 0;
2430}
2431
2432static int mca_get_mca_entry(struct amdgpu_device *adev, enum amdgpu_mca_error_type type,
2433 int idx, struct mca_bank_entry *entry)
2434{
2435 int i, ret;
2436
2437 /* NOTE: populated all mca register by default */
2438 for (i = 0; i < ARRAY_SIZE(entry->regs); i++) {
2439 ret = mca_bank_read_reg(adev, type, idx, i, &entry->regs[i]);
2440 if (ret)
2441 return ret;
2442 }
2443
25396684
YW
2444 entry->idx = idx;
2445 entry->type = type;
2446
2447 mca_bank_entry_info_decode(entry, &entry->info);
2448
2449 return 0;
2450}
2451
2452static int mca_decode_mca_ipid(struct amdgpu_device *adev, enum amdgpu_mca_error_type type, int idx, int *ip)
2453{
2454 const struct mca_bank_ipid *ipid;
2455 uint64_t val;
2456 uint16_t hwid, mcatype;
2457 int i, ret;
2458
2459 ret = mca_bank_read_reg(adev, type, idx, MCA_REG_IDX_IPID, &val);
2460 if (ret)
2461 return ret;
2462
2463 hwid = REG_GET_FIELD(val, MCMP1_IPIDT0, HardwareID);
2464 mcatype = REG_GET_FIELD(val, MCMP1_IPIDT0, McaType);
2465
2466 if (hwid) {
2467 for (i = 0; i < ARRAY_SIZE(smu_v13_0_6_mca_ipid_table); i++) {
2468 ipid = &smu_v13_0_6_mca_ipid_table[i];
2469
2470 if (!ipid->hwid)
2471 continue;
2472
2473 if (ipid->hwid == hwid && ipid->mcatype == mcatype) {
2474 *ip = i;
2475 return 0;
2476 }
2477 }
2478 }
2479
2480 *ip = AMDGPU_MCA_IP_UNKNOW;
2481
2482 return 0;
2483}
2484
bf13da6a 2485static int mca_umc_mca_get_err_count(const struct mca_ras_info *mca_ras, struct amdgpu_device *adev,
25396684
YW
2486 enum amdgpu_mca_error_type type, int idx, uint32_t *count)
2487{
2488 uint64_t status0;
2489 int ret;
2490
2491 ret = mca_bank_read_reg(adev, type, idx, MCA_REG_IDX_STATUS, &status0);
2492 if (ret)
2493 return ret;
2494
bf13da6a 2495 if (!REG_GET_FIELD(status0, MCMP1_STATUST0, Val)) {
25396684 2496 *count = 0;
bf13da6a
YW
2497 return 0;
2498 }
2499
2500 if (type == AMDGPU_MCA_ERROR_TYPE_UE && umc_v12_0_is_uncorrectable_error(status0))
2501 *count = 1;
2502 else if (type == AMDGPU_MCA_ERROR_TYPE_CE && umc_v12_0_is_correctable_error(status0))
2503 *count = 1;
25396684
YW
2504
2505 return 0;
2506}
2507
2508static bool mca_smu_check_error_code(struct amdgpu_device *adev, const struct mca_ras_info *mca_ras,
2509 uint32_t errcode)
2510{
2511 int i;
2512
2513 if (!mca_ras->err_code_count || !mca_ras->err_code_array)
2514 return true;
2515
2516 for (i = 0; i < mca_ras->err_code_count; i++) {
2517 if (errcode == mca_ras->err_code_array[i])
2518 return true;
2519 }
2520
2521 return false;
2522}
2523
2524static int mca_mp5_mca_get_err_count(const struct mca_ras_info *mca_ras, struct amdgpu_device *adev,
2525 enum amdgpu_mca_error_type type, int idx, uint32_t *count)
2526{
2527 uint64_t status0 = 0, misc0 = 0;
2528 uint32_t errcode;
2529 int ret;
2530
2531 if (mca_ras->ip != AMDGPU_MCA_IP_MP5)
2532 return -EINVAL;
2533
2534 ret = mca_bank_read_reg(adev, type, idx, MCA_REG_IDX_STATUS, &status0);
2535 if (ret)
2536 return ret;
2537
2538 if (!REG_GET_FIELD(status0, MCMP1_STATUST0, Val)) {
2539 *count = 0;
2540 return 0;
2541 }
2542
2543 errcode = REG_GET_FIELD(status0, MCMP1_STATUST0, ErrorCode);
2544 if (!mca_smu_check_error_code(adev, mca_ras, errcode))
2545 return 0;
2546
2547 if (type == AMDGPU_MCA_ERROR_TYPE_UE &&
2548 REG_GET_FIELD(status0, MCMP1_STATUST0, UC) == 1 &&
2549 REG_GET_FIELD(status0, MCMP1_STATUST0, PCC) == 1) {
2550 if (count)
2551 *count = 1;
2552 return 0;
2553 }
2554
2555 ret = mca_bank_read_reg(adev, type, idx, MCA_REG_IDX_MISC0, &misc0);
2556 if (ret)
2557 return ret;
2558
2559 if (count)
2560 *count = REG_GET_FIELD(misc0, MCMP1_MISC0T0, ErrCnt);
2561
2562 return 0;
2563}
2564
2565static int mca_smu_mca_get_err_count(const struct mca_ras_info *mca_ras, struct amdgpu_device *adev,
2566 enum amdgpu_mca_error_type type, int idx, uint32_t *count)
2567{
2568 uint64_t status0 = 0, misc0 = 0;
2569 uint32_t errcode;
2570 int ret;
2571
2572 if (mca_ras->ip != AMDGPU_MCA_IP_SMU)
2573 return -EINVAL;
2574
2575 ret = mca_bank_read_reg(adev, type, idx, MCA_REG_IDX_STATUS, &status0);
2576 if (ret)
2577 return ret;
2578
2579 if (!REG_GET_FIELD(status0, MCMP1_STATUST0, Val)) {
2580 *count = 0;
2581 return 0;
2582 }
2583
2584 errcode = REG_GET_FIELD(status0, MCMP1_STATUST0, ErrorCode);
2585 if (!mca_smu_check_error_code(adev, mca_ras, errcode))
2586 return 0;
2587
2588 if (type == AMDGPU_MCA_ERROR_TYPE_UE &&
2589 REG_GET_FIELD(status0, MCMP1_STATUST0, UC) == 1 &&
2590 REG_GET_FIELD(status0, MCMP1_STATUST0, PCC) == 1) {
2591 if (count)
2592 *count = 1;
2593 return 0;
2594 }
2595
2596 ret = mca_bank_read_reg(adev, type, idx, MCA_REG_IDX_MISC0, &misc0);
2597 if (ret)
2598 return ret;
2599
2600 if (count)
2601 *count = REG_GET_FIELD(misc0, MCMP1_MISC0T0, ErrCnt);
2602
2603 return 0;
2604}
2605
2606static int sdma_err_codes[] = { CODE_SDMA0, CODE_SDMA1, CODE_SDMA2, CODE_SDMA3 };
2607static int mmhub_err_codes[] = {
2608 CODE_DAGB0, CODE_DAGB0 + 1, CODE_DAGB0 + 2, CODE_DAGB0 + 3, CODE_DAGB0 + 4, /* DAGB0-4 */
2609 CODE_EA0, CODE_EA0 + 1, CODE_EA0 + 2, CODE_EA0 + 3, CODE_EA0 + 4, /* MMEA0-4*/
2610 CODE_VML2, CODE_VML2_WALKER, CODE_MMCANE,
2611};
2612
2613static const struct mca_ras_info mca_ras_table[] = {
2614 {
2615 .blkid = AMDGPU_RAS_BLOCK__UMC,
2616 .ip = AMDGPU_MCA_IP_UMC,
bf13da6a 2617 .get_err_count = mca_umc_mca_get_err_count,
25396684
YW
2618 }, {
2619 .blkid = AMDGPU_RAS_BLOCK__GFX,
2620 .ip = AMDGPU_MCA_IP_MP5,
2621 .get_err_count = mca_mp5_mca_get_err_count,
2622 }, {
2623 .blkid = AMDGPU_RAS_BLOCK__SDMA,
2624 .ip = AMDGPU_MCA_IP_SMU,
2625 .err_code_array = sdma_err_codes,
2626 .err_code_count = ARRAY_SIZE(sdma_err_codes),
2627 .get_err_count = mca_smu_mca_get_err_count,
2628 }, {
2629 .blkid = AMDGPU_RAS_BLOCK__MMHUB,
2630 .ip = AMDGPU_MCA_IP_SMU,
2631 .err_code_array = mmhub_err_codes,
2632 .err_code_count = ARRAY_SIZE(mmhub_err_codes),
2633 .get_err_count = mca_smu_mca_get_err_count,
2634 },
2635};
2636
2637static const struct mca_ras_info *mca_get_mca_ras_info(struct amdgpu_device *adev, enum amdgpu_ras_block blkid)
2638{
2639 int i;
2640
2641 for (i = 0; i < ARRAY_SIZE(mca_ras_table); i++) {
2642 if (mca_ras_table[i].blkid == blkid)
2643 return &mca_ras_table[i];
2644 }
2645
2646 return NULL;
2647}
2648
2649static int mca_get_valid_mca_count(struct amdgpu_device *adev, enum amdgpu_mca_error_type type, uint32_t *count)
2650{
2651 struct smu_context *smu = adev->powerplay.pp_handle;
2652 int ret;
2653
2654 switch (type) {
2655 case AMDGPU_MCA_ERROR_TYPE_UE:
2656 case AMDGPU_MCA_ERROR_TYPE_CE:
2657 ret = smu_v13_0_6_get_valid_mca_count(smu, type, count);
2658 break;
2659 default:
2660 ret = -EINVAL;
2661 break;
2662 }
2663
2664 return ret;
2665}
2666
2667static bool mca_bank_is_valid(struct amdgpu_device *adev, const struct mca_ras_info *mca_ras,
2668 enum amdgpu_mca_error_type type, int idx)
2669{
2670 int ret, ip = AMDGPU_MCA_IP_UNKNOW;
2671
2672 ret = mca_decode_mca_ipid(adev, type, idx, &ip);
2673 if (ret)
2674 return false;
2675
2676 if (ip == AMDGPU_MCA_IP_UNKNOW)
2677 return false;
2678
2679 return ip == mca_ras->ip;
2680}
2681
2682static int mca_get_valid_mca_idx(struct amdgpu_device *adev, const struct mca_ras_info *mca_ras,
2683 enum amdgpu_mca_error_type type,
2684 uint32_t mca_cnt, int *idx_array, int idx_array_size)
2685{
2686 int i, idx_cnt = 0;
2687
2688 for (i = 0; i < mca_cnt; i++) {
2689 if (!mca_bank_is_valid(adev, mca_ras, type, i))
2690 continue;
2691
2692 if (idx_array) {
2693 if (idx_cnt < idx_array_size)
2694 idx_array[idx_cnt] = i;
2695 else
2696 return -EINVAL;
2697 }
2698
2699 idx_cnt++;
2700 }
2701
2702 return idx_cnt;
2703}
2704
2705static int __mca_smu_get_error_count(struct amdgpu_device *adev, const struct mca_ras_info *mca_ras, enum amdgpu_mca_error_type type, uint32_t *count)
2706{
2707 uint32_t result, mca_cnt, total = 0;
2708 int idx_array[16];
2709 int i, ret, idx_cnt = 0;
2710
2711 ret = mca_get_valid_mca_count(adev, type, &mca_cnt);
2712 if (ret)
2713 return ret;
2714
2715 /* if valid mca bank count is 0, the driver can return 0 directly */
2716 if (!mca_cnt) {
2717 *count = 0;
2718 return 0;
2719 }
2720
2721 if (!mca_ras->get_err_count)
2722 return -EINVAL;
2723
2724 idx_cnt = mca_get_valid_mca_idx(adev, mca_ras, type, mca_cnt, idx_array, ARRAY_SIZE(idx_array));
2725 if (idx_cnt < 0)
2726 return -EINVAL;
2727
2728 for (i = 0; i < idx_cnt; i++) {
2729 result = 0;
2730 ret = mca_ras->get_err_count(mca_ras, adev, type, idx_array[i], &result);
2731 if (ret)
2732 return ret;
2733
2734 total += result;
2735 }
2736
2737 *count = total;
2738
2739 return 0;
2740}
2741
2742static int mca_smu_get_error_count(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
2743 enum amdgpu_mca_error_type type, uint32_t *count)
2744{
2745 const struct mca_ras_info *mca_ras;
2746
2747 if (!count)
2748 return -EINVAL;
2749
2750 mca_ras = mca_get_mca_ras_info(adev, blk);
2751 if (!mca_ras)
2752 return -EOPNOTSUPP;
2753
2754 return __mca_smu_get_error_count(adev, mca_ras, type, count);
2755}
2756
2757static int __mca_smu_get_ras_mca_idx_array(struct amdgpu_device *adev, const struct mca_ras_info *mca_ras,
2758 enum amdgpu_mca_error_type type, int *idx_array, int *idx_array_size)
2759{
2760 uint32_t mca_cnt = 0;
2761 int ret, idx_cnt = 0;
2762
2763 ret = mca_get_valid_mca_count(adev, type, &mca_cnt);
2764 if (ret)
2765 return ret;
2766
2767 /* if valid mca bank count is 0, the driver can return 0 directly */
2768 if (!mca_cnt) {
2769 *idx_array_size = 0;
2770 return 0;
2771 }
2772
2773 idx_cnt = mca_get_valid_mca_idx(adev, mca_ras, type, mca_cnt, idx_array, *idx_array_size);
2774 if (idx_cnt < 0)
2775 return -EINVAL;
2776
2777 *idx_array_size = idx_cnt;
2778
2779 return 0;
2780}
2781
2782static int mca_smu_get_ras_mca_idx_array(struct amdgpu_device *adev, enum amdgpu_ras_block blk,
2783 enum amdgpu_mca_error_type type, int *idx_array, int *idx_array_size)
2784{
2785 const struct mca_ras_info *mca_ras;
2786
2787 mca_ras = mca_get_mca_ras_info(adev, blk);
2788 if (!mca_ras)
2789 return -EOPNOTSUPP;
2790
2791 return __mca_smu_get_ras_mca_idx_array(adev, mca_ras, type, idx_array, idx_array_size);
2792}
2793
2794static int mca_smu_get_mca_entry(struct amdgpu_device *adev,
2795 enum amdgpu_mca_error_type type, int idx, struct mca_bank_entry *entry)
2796{
2797 return mca_get_mca_entry(adev, type, idx, entry);
2798}
2799
2800static int mca_smu_get_valid_mca_count(struct amdgpu_device *adev,
2801 enum amdgpu_mca_error_type type, uint32_t *count)
2802{
2803 return mca_get_valid_mca_count(adev, type, count);
2804}
2805
2806static const struct amdgpu_mca_smu_funcs smu_v13_0_6_mca_smu_funcs = {
2807 .max_ue_count = 12,
2808 .max_ce_count = 12,
2809 .mca_set_debug_mode = mca_smu_set_debug_mode,
2810 .mca_get_error_count = mca_smu_get_error_count,
2811 .mca_get_mca_entry = mca_smu_get_mca_entry,
2812 .mca_get_valid_mca_count = mca_smu_get_valid_mca_count,
2813 .mca_get_ras_mca_idx_array = mca_smu_get_ras_mca_idx_array,
2814};
2815
d07f1c20
LM
2816static int smu_v13_0_6_select_xgmi_plpd_policy(struct smu_context *smu,
2817 enum pp_xgmi_plpd_mode mode)
2818{
2819 struct amdgpu_device *adev = smu->adev;
2820 int ret, param;
2821
2822 switch (mode) {
2823 case XGMI_PLPD_DEFAULT:
2824 param = PPSMC_PLPD_MODE_DEFAULT;
2825 break;
2826 case XGMI_PLPD_OPTIMIZED:
2827 param = PPSMC_PLPD_MODE_OPTIMIZED;
2828 break;
c01c8523
LM
2829 case XGMI_PLPD_DISALLOW:
2830 param = 0;
2831 break;
d07f1c20
LM
2832 default:
2833 return -EINVAL;
2834 }
2835
c01c8523
LM
2836 if (mode == XGMI_PLPD_DISALLOW)
2837 ret = smu_cmn_send_smc_msg_with_param(smu,
2838 SMU_MSG_GmiPwrDnControl,
2839 param, NULL);
2840 else
2841 /* change xgmi per-link power down policy */
2842 ret = smu_cmn_send_smc_msg_with_param(smu,
2843 SMU_MSG_SelectPLPDMode,
2844 param, NULL);
d07f1c20
LM
2845
2846 if (ret)
2847 dev_err(adev->dev,
2848 "select xgmi per-link power down policy %d failed\n",
2849 mode);
2850
2851 return ret;
2852}
2853
511a9555
LL
2854static const struct pptable_funcs smu_v13_0_6_ppt_funcs = {
2855 /* init dpm */
2856 .get_allowed_feature_mask = smu_v13_0_6_get_allowed_feature_mask,
2857 /* dpm/clk tables */
2858 .set_default_dpm_table = smu_v13_0_6_set_default_dpm_table,
2859 .populate_umd_state_clk = smu_v13_0_6_populate_umd_state_clk,
511a9555
LL
2860 .print_clk_levels = smu_v13_0_6_print_clk_levels,
2861 .force_clk_levels = smu_v13_0_6_force_clk_levels,
2862 .read_sensor = smu_v13_0_6_read_sensor,
2863 .set_performance_level = smu_v13_0_6_set_performance_level,
2864 .get_power_limit = smu_v13_0_6_get_power_limit,
2865 .is_dpm_running = smu_v13_0_6_is_dpm_running,
2866 .get_unique_id = smu_v13_0_6_get_unique_id,
f20f3b0d
LL
2867 .init_microcode = smu_v13_0_6_init_microcode,
2868 .fini_microcode = smu_v13_0_fini_microcode,
511a9555
LL
2869 .init_smc_tables = smu_v13_0_6_init_smc_tables,
2870 .fini_smc_tables = smu_v13_0_fini_smc_tables,
2871 .init_power = smu_v13_0_init_power,
2872 .fini_power = smu_v13_0_fini_power,
2873 .check_fw_status = smu_v13_0_6_check_fw_status,
2874 /* pptable related */
2875 .check_fw_version = smu_v13_0_check_fw_version,
2876 .set_driver_table_location = smu_v13_0_set_driver_table_location,
2877 .set_tool_table_location = smu_v13_0_set_tool_table_location,
2878 .notify_memory_pool_location = smu_v13_0_notify_memory_pool_location,
2879 .system_features_control = smu_v13_0_6_system_features_control,
2880 .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param,
2881 .send_smc_msg = smu_cmn_send_smc_msg,
2882 .get_enabled_mask = smu_v13_0_6_get_enabled_mask,
2883 .feature_is_enabled = smu_cmn_feature_is_enabled,
2884 .set_power_limit = smu_v13_0_6_set_power_limit,
2885 .set_xgmi_pstate = smu_v13_0_set_xgmi_pstate,
676915e4 2886 .register_irq_handler = smu_v13_0_6_register_irq_handler,
511a9555
LL
2887 .enable_thermal_alert = smu_v13_0_enable_thermal_alert,
2888 .disable_thermal_alert = smu_v13_0_disable_thermal_alert,
511a9555
LL
2889 .setup_pptable = smu_v13_0_6_setup_pptable,
2890 .baco_is_support = smu_v13_0_6_is_baco_supported,
2891 .get_dpm_ultimate_freq = smu_v13_0_6_get_dpm_ultimate_freq,
2892 .set_soft_freq_limited_range = smu_v13_0_6_set_soft_freq_limited_range,
2893 .od_edit_dpm_table = smu_v13_0_6_usr_edit_dpm_table,
d07f1c20 2894 .select_xgmi_plpd_policy = smu_v13_0_6_select_xgmi_plpd_policy,
511a9555
LL
2895 .log_thermal_throttling_event = smu_v13_0_6_log_thermal_throttling_event,
2896 .get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
511a9555 2897 .get_gpu_metrics = smu_v13_0_6_get_gpu_metrics,
07864911 2898 .get_thermal_temperature_range = smu_v13_0_6_get_thermal_temperature_range,
511a9555
LL
2899 .mode1_reset_is_support = smu_v13_0_6_is_mode1_reset_supported,
2900 .mode2_reset_is_support = smu_v13_0_6_is_mode2_reset_supported,
2901 .mode1_reset = smu_v13_0_6_mode1_reset,
2902 .mode2_reset = smu_v13_0_6_mode2_reset,
2903 .wait_for_event = smu_v13_0_wait_for_event,
2904 .i2c_init = smu_v13_0_6_i2c_control_init,
2905 .i2c_fini = smu_v13_0_6_i2c_control_fini,
2906 .send_hbm_bad_pages_num = smu_v13_0_6_smu_send_hbm_bad_page_num,
df38fe12 2907 .post_init = smu_v13_0_6_post_init,
511a9555
LL
2908};
2909
2910void smu_v13_0_6_set_ppt_funcs(struct smu_context *smu)
2911{
2912 smu->ppt_funcs = &smu_v13_0_6_ppt_funcs;
2913 smu->message_map = smu_v13_0_6_message_map;
2914 smu->clock_map = smu_v13_0_6_clk_map;
2915 smu->feature_map = smu_v13_0_6_feature_mask_map;
2916 smu->table_map = smu_v13_0_6_table_map;
9661bf68 2917 smu->smc_driver_if_version = SMU13_0_6_DRIVER_IF_VERSION;
511a9555 2918 smu_v13_0_set_smu_mailbox_registers(smu);
25396684 2919 amdgpu_mca_smu_init_funcs(smu->adev, &smu_v13_0_6_mca_smu_funcs);
511a9555 2920}