drm/amd/powerplay: drop redundant .set_min_dcefclk_deep_sleep API (v2)
[linux-2.6-block.git] / drivers / gpu / drm / amd / powerplay / arcturus_ppt.c
CommitLineData
6fba5906
CG
1/*
2 * Copyright 2019 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
6fba5906
CG
24#include <linux/firmware.h>
25#include "amdgpu.h"
26#include "amdgpu_smu.h"
18c1d3ce 27#include "smu_internal.h"
6fba5906
CG
28#include "atomfirmware.h"
29#include "amdgpu_atomfirmware.h"
30#include "smu_v11_0.h"
31#include "smu11_driver_if_arcturus.h"
32#include "soc15_common.h"
33#include "atom.h"
34#include "power_state.h"
35#include "arcturus_ppt.h"
a94235af 36#include "smu_v11_0_pptable.h"
6fba5906 37#include "arcturus_ppsmc.h"
49e78c82 38#include "nbio/nbio_7_4_offset.h"
6fba5906 39#include "nbio/nbio_7_4_sh_mask.h"
947c127b
LG
40#include "thm/thm_11_0_2_offset.h"
41#include "thm/thm_11_0_2_sh_mask.h"
0525f297 42#include "amdgpu_xgmi.h"
d1a84427
AG
43#include <linux/i2c.h>
44#include <linux/pci.h>
45#include "amdgpu_ras.h"
46
55084d7f
EQ
47/*
48 * DO NOT use these for err/warn/info/debug messages.
49 * Use dev_err, dev_warn, dev_info and dev_dbg instead.
50 * They are more MGPU friendly.
51 */
52#undef pr_err
53#undef pr_warn
54#undef pr_info
55#undef pr_debug
56
9015d60c 57#define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c))
6fba5906 58
a94235af
EQ
59#define CTF_OFFSET_EDGE 5
60#define CTF_OFFSET_HOTSPOT 5
61#define CTF_OFFSET_HBM 5
62
d4f3c0b3
WS
63#define MSG_MAP(msg, index, valid_in_vf) \
64 [SMU_MSG_##msg] = {1, (index), (valid_in_vf)}
55bf7e62
EQ
65#define ARCTURUS_FEA_MAP(smu_feature, arcturus_feature) \
66 [smu_feature] = {1, (arcturus_feature)}
6fba5906 67
a94235af
EQ
68#define SMU_FEATURES_LOW_MASK 0x00000000FFFFFFFF
69#define SMU_FEATURES_LOW_SHIFT 0
70#define SMU_FEATURES_HIGH_MASK 0xFFFFFFFF00000000
71#define SMU_FEATURES_HIGH_SHIFT 32
72
3f513bae
CG
73#define SMC_DPM_FEATURE ( \
74 FEATURE_DPM_PREFETCHER_MASK | \
75 FEATURE_DPM_GFXCLK_MASK | \
76 FEATURE_DPM_UCLK_MASK | \
77 FEATURE_DPM_SOCCLK_MASK | \
78 FEATURE_DPM_MP0CLK_MASK | \
79 FEATURE_DPM_FCLK_MASK | \
80 FEATURE_DPM_XGMI_MASK)
81
1f23cadb
EQ
82/* possible frequency drift (1Mhz) */
83#define EPSILON 1
84
d4f3c0b3
WS
85static struct smu_11_0_msg_mapping arcturus_message_map[SMU_MSG_MAX_COUNT] = {
86 MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 0),
87 MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1),
88 MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 1),
89 MSG_MAP(SetAllowedFeaturesMaskLow, PPSMC_MSG_SetAllowedFeaturesMaskLow, 0),
90 MSG_MAP(SetAllowedFeaturesMaskHigh, PPSMC_MSG_SetAllowedFeaturesMaskHigh, 0),
91 MSG_MAP(EnableAllSmuFeatures, PPSMC_MSG_EnableAllSmuFeatures, 0),
92 MSG_MAP(DisableAllSmuFeatures, PPSMC_MSG_DisableAllSmuFeatures, 0),
93 MSG_MAP(EnableSmuFeaturesLow, PPSMC_MSG_EnableSmuFeaturesLow, 1),
94 MSG_MAP(EnableSmuFeaturesHigh, PPSMC_MSG_EnableSmuFeaturesHigh, 1),
95 MSG_MAP(DisableSmuFeaturesLow, PPSMC_MSG_DisableSmuFeaturesLow, 0),
96 MSG_MAP(DisableSmuFeaturesHigh, PPSMC_MSG_DisableSmuFeaturesHigh, 0),
97 MSG_MAP(GetEnabledSmuFeaturesLow, PPSMC_MSG_GetEnabledSmuFeaturesLow, 0),
98 MSG_MAP(GetEnabledSmuFeaturesHigh, PPSMC_MSG_GetEnabledSmuFeaturesHigh, 0),
99 MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 1),
100 MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 1),
101 MSG_MAP(SetToolsDramAddrHigh, PPSMC_MSG_SetToolsDramAddrHigh, 0),
102 MSG_MAP(SetToolsDramAddrLow, PPSMC_MSG_SetToolsDramAddrLow, 0),
103 MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 1),
104 MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 0),
105 MSG_MAP(UseDefaultPPTable, PPSMC_MSG_UseDefaultPPTable, 0),
106 MSG_MAP(UseBackupPPTable, PPSMC_MSG_UseBackupPPTable, 0),
107 MSG_MAP(SetSystemVirtualDramAddrHigh, PPSMC_MSG_SetSystemVirtualDramAddrHigh, 0),
108 MSG_MAP(SetSystemVirtualDramAddrLow, PPSMC_MSG_SetSystemVirtualDramAddrLow, 0),
109 MSG_MAP(EnterBaco, PPSMC_MSG_EnterBaco, 0),
110 MSG_MAP(ExitBaco, PPSMC_MSG_ExitBaco, 0),
111 MSG_MAP(ArmD3, PPSMC_MSG_ArmD3, 0),
112 MSG_MAP(SetSoftMinByFreq, PPSMC_MSG_SetSoftMinByFreq, 0),
113 MSG_MAP(SetSoftMaxByFreq, PPSMC_MSG_SetSoftMaxByFreq, 0),
114 MSG_MAP(SetHardMinByFreq, PPSMC_MSG_SetHardMinByFreq, 0),
115 MSG_MAP(SetHardMaxByFreq, PPSMC_MSG_SetHardMaxByFreq, 0),
116 MSG_MAP(GetMinDpmFreq, PPSMC_MSG_GetMinDpmFreq, 0),
117 MSG_MAP(GetMaxDpmFreq, PPSMC_MSG_GetMaxDpmFreq, 0),
118 MSG_MAP(GetDpmFreqByIndex, PPSMC_MSG_GetDpmFreqByIndex, 1),
119 MSG_MAP(SetWorkloadMask, PPSMC_MSG_SetWorkloadMask, 1),
120 MSG_MAP(SetDfSwitchType, PPSMC_MSG_SetDfSwitchType, 0),
121 MSG_MAP(GetVoltageByDpm, PPSMC_MSG_GetVoltageByDpm, 0),
122 MSG_MAP(GetVoltageByDpmOverdrive, PPSMC_MSG_GetVoltageByDpmOverdrive, 0),
123 MSG_MAP(SetPptLimit, PPSMC_MSG_SetPptLimit, 0),
124 MSG_MAP(GetPptLimit, PPSMC_MSG_GetPptLimit, 1),
125 MSG_MAP(PowerUpVcn0, PPSMC_MSG_PowerUpVcn0, 0),
126 MSG_MAP(PowerDownVcn0, PPSMC_MSG_PowerDownVcn0, 0),
127 MSG_MAP(PowerUpVcn1, PPSMC_MSG_PowerUpVcn1, 0),
128 MSG_MAP(PowerDownVcn1, PPSMC_MSG_PowerDownVcn1, 0),
129 MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 0),
130 MSG_MAP(PrepareMp1ForReset, PPSMC_MSG_PrepareMp1ForReset, 0),
131 MSG_MAP(PrepareMp1ForShutdown, PPSMC_MSG_PrepareMp1ForShutdown, 0),
132 MSG_MAP(SoftReset, PPSMC_MSG_SoftReset, 0),
133 MSG_MAP(RunAfllBtc, PPSMC_MSG_RunAfllBtc, 0),
134 MSG_MAP(RunDcBtc, PPSMC_MSG_RunDcBtc, 0),
135 MSG_MAP(DramLogSetDramAddrHigh, PPSMC_MSG_DramLogSetDramAddrHigh, 0),
136 MSG_MAP(DramLogSetDramAddrLow, PPSMC_MSG_DramLogSetDramAddrLow, 0),
137 MSG_MAP(DramLogSetDramSize, PPSMC_MSG_DramLogSetDramSize, 0),
138 MSG_MAP(GetDebugData, PPSMC_MSG_GetDebugData, 0),
139 MSG_MAP(WaflTest, PPSMC_MSG_WaflTest, 0),
140 MSG_MAP(SetXgmiMode, PPSMC_MSG_SetXgmiMode, 0),
141 MSG_MAP(SetMemoryChannelEnable, PPSMC_MSG_SetMemoryChannelEnable, 0),
142 MSG_MAP(DFCstateControl, PPSMC_MSG_DFCstateControl, 0),
143 MSG_MAP(GmiPwrDnControl, PPSMC_MSG_GmiPwrDnControl, 0),
bce9ff0e
KR
144 MSG_MAP(ReadSerialNumTop32, PPSMC_MSG_ReadSerialNumTop32, 1),
145 MSG_MAP(ReadSerialNumBottom32, PPSMC_MSG_ReadSerialNumBottom32, 1),
6fba5906
CG
146};
147
a94235af
EQ
148static struct smu_11_0_cmn2aisc_mapping arcturus_clk_map[SMU_CLK_COUNT] = {
149 CLK_MAP(GFXCLK, PPCLK_GFXCLK),
150 CLK_MAP(SCLK, PPCLK_GFXCLK),
151 CLK_MAP(SOCCLK, PPCLK_SOCCLK),
152 CLK_MAP(FCLK, PPCLK_FCLK),
153 CLK_MAP(UCLK, PPCLK_UCLK),
154 CLK_MAP(MCLK, PPCLK_UCLK),
155 CLK_MAP(DCLK, PPCLK_DCLK),
156 CLK_MAP(VCLK, PPCLK_VCLK),
157};
158
159static struct smu_11_0_cmn2aisc_mapping arcturus_feature_mask_map[SMU_FEATURE_COUNT] = {
160 FEA_MAP(DPM_PREFETCHER),
161 FEA_MAP(DPM_GFXCLK),
162 FEA_MAP(DPM_UCLK),
163 FEA_MAP(DPM_SOCCLK),
55bf7e62 164 FEA_MAP(DPM_FCLK),
a94235af 165 FEA_MAP(DPM_MP0CLK),
57be797c 166 ARCTURUS_FEA_MAP(SMU_FEATURE_XGMI_BIT, FEATURE_DPM_XGMI_BIT),
a94235af
EQ
167 FEA_MAP(DS_GFXCLK),
168 FEA_MAP(DS_SOCCLK),
169 FEA_MAP(DS_LCLK),
55bf7e62 170 FEA_MAP(DS_FCLK),
a94235af
EQ
171 FEA_MAP(DS_UCLK),
172 FEA_MAP(GFX_ULV),
55bf7e62 173 ARCTURUS_FEA_MAP(SMU_FEATURE_VCN_PG_BIT, FEATURE_DPM_VCN_BIT),
a94235af 174 FEA_MAP(RSMU_SMN_CG),
57be797c 175 FEA_MAP(WAFL_CG),
a94235af
EQ
176 FEA_MAP(PPT),
177 FEA_MAP(TDC),
178 FEA_MAP(APCC_PLUS),
179 FEA_MAP(VR0HOT),
180 FEA_MAP(VR1HOT),
181 FEA_MAP(FW_CTF),
182 FEA_MAP(FAN_CONTROL),
183 FEA_MAP(THERMAL),
184 FEA_MAP(OUT_OF_BAND_MONITOR),
185 FEA_MAP(TEMP_DEPENDENT_VMIN),
186};
187
188static struct smu_11_0_cmn2aisc_mapping arcturus_table_map[SMU_TABLE_COUNT] = {
189 TAB_MAP(PPTABLE),
190 TAB_MAP(AVFS),
191 TAB_MAP(AVFS_PSM_DEBUG),
192 TAB_MAP(AVFS_FUSE_OVERRIDE),
193 TAB_MAP(PMSTATUSLOG),
194 TAB_MAP(SMU_METRICS),
195 TAB_MAP(DRIVER_SMU_CONFIG),
196 TAB_MAP(OVERDRIVE),
d1a84427 197 TAB_MAP(I2C_COMMANDS),
18d7ab98 198 TAB_MAP(ACTIVITY_MONITOR_COEFF),
a94235af
EQ
199};
200
201static struct smu_11_0_cmn2aisc_mapping arcturus_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
202 PWR_MAP(AC),
203 PWR_MAP(DC),
204};
205
206static struct smu_11_0_cmn2aisc_mapping arcturus_workload_map[PP_SMC_POWER_PROFILE_COUNT] = {
207 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT, WORKLOAD_PPLIB_DEFAULT_BIT),
208 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING, WORKLOAD_PPLIB_POWER_SAVING_BIT),
209 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO, WORKLOAD_PPLIB_VIDEO_BIT),
61696312 210 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE, WORKLOAD_PPLIB_COMPUTE_BIT),
a94235af
EQ
211 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT),
212};
213
6fba5906
CG
214static int arcturus_get_smu_msg_index(struct smu_context *smc, uint32_t index)
215{
d4f3c0b3 216 struct smu_11_0_msg_mapping mapping;
6fba5906
CG
217
218 if (index >= SMU_MSG_MAX_COUNT)
219 return -EINVAL;
220
7e01a2ec 221 mapping = arcturus_message_map[index];
790ef68a 222 if (!(mapping.valid_mapping))
6fba5906
CG
223 return -EINVAL;
224
4ea5081c
WS
225 if (amdgpu_sriov_vf(smc->adev) && !mapping.valid_in_vf)
226 return -EACCES;
227
7e01a2ec 228 return mapping.map_to;
6fba5906
CG
229}
230
a94235af
EQ
231static int arcturus_get_smu_clk_index(struct smu_context *smc, uint32_t index)
232{
233 struct smu_11_0_cmn2aisc_mapping mapping;
234
235 if (index >= SMU_CLK_COUNT)
236 return -EINVAL;
237
238 mapping = arcturus_clk_map[index];
239 if (!(mapping.valid_mapping)) {
d9811cfc 240 dev_warn(smc->adev->dev, "Unsupported SMU clk: %d\n", index);
a94235af
EQ
241 return -EINVAL;
242 }
243
244 return mapping.map_to;
245}
246
247static int arcturus_get_smu_feature_index(struct smu_context *smc, uint32_t index)
248{
249 struct smu_11_0_cmn2aisc_mapping mapping;
250
251 if (index >= SMU_FEATURE_COUNT)
252 return -EINVAL;
253
254 mapping = arcturus_feature_mask_map[index];
255 if (!(mapping.valid_mapping)) {
a94235af
EQ
256 return -EINVAL;
257 }
258
259 return mapping.map_to;
260}
261
262static int arcturus_get_smu_table_index(struct smu_context *smc, uint32_t index)
263{
264 struct smu_11_0_cmn2aisc_mapping mapping;
265
266 if (index >= SMU_TABLE_COUNT)
267 return -EINVAL;
268
269 mapping = arcturus_table_map[index];
270 if (!(mapping.valid_mapping)) {
d9811cfc 271 dev_warn(smc->adev->dev, "Unsupported SMU table: %d\n", index);
a94235af
EQ
272 return -EINVAL;
273 }
274
275 return mapping.map_to;
276}
277
278static int arcturus_get_pwr_src_index(struct smu_context *smc, uint32_t index)
279{
280 struct smu_11_0_cmn2aisc_mapping mapping;
281
282 if (index >= SMU_POWER_SOURCE_COUNT)
283 return -EINVAL;
284
285 mapping = arcturus_pwr_src_map[index];
286 if (!(mapping.valid_mapping)) {
d9811cfc 287 dev_warn(smc->adev->dev, "Unsupported SMU power source: %d\n", index);
a94235af
EQ
288 return -EINVAL;
289 }
290
291 return mapping.map_to;
292}
293
294
295static int arcturus_get_workload_type(struct smu_context *smu, enum PP_SMC_POWER_PROFILE profile)
296{
297 struct smu_11_0_cmn2aisc_mapping mapping;
298
299 if (profile > PP_SMC_POWER_PROFILE_CUSTOM)
300 return -EINVAL;
301
302 mapping = arcturus_workload_map[profile];
ebcef76b 303 if (!(mapping.valid_mapping))
a94235af 304 return -EINVAL;
a94235af
EQ
305
306 return mapping.map_to;
307}
308
309static int arcturus_tables_init(struct smu_context *smu, struct smu_table *tables)
310{
832a7062
EQ
311 struct smu_table_context *smu_table = &smu->smu_table;
312
a94235af
EQ
313 SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t),
314 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
315
316 SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU11_TOOL_SIZE,
317 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
318
319 SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_t),
320 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
321
d1a84427
AG
322 SMU_TABLE_INIT(tables, SMU_TABLE_I2C_COMMANDS, sizeof(SwI2cRequest_t),
323 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
324
18d7ab98
EQ
325 SMU_TABLE_INIT(tables, SMU_TABLE_ACTIVITY_MONITOR_COEFF,
326 sizeof(DpmActivityMonitorCoeffInt_t), PAGE_SIZE,
327 AMDGPU_GEM_DOMAIN_VRAM);
328
832a7062
EQ
329 smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_t), GFP_KERNEL);
330 if (!smu_table->metrics_table)
331 return -ENOMEM;
332 smu_table->metrics_time = 0;
333
a94235af
EQ
334 return 0;
335}
336
337static int arcturus_allocate_dpm_context(struct smu_context *smu)
338{
339 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
340
341 if (smu_dpm->dpm_context)
342 return -EINVAL;
343
344 smu_dpm->dpm_context = kzalloc(sizeof(struct arcturus_dpm_table),
345 GFP_KERNEL);
346 if (!smu_dpm->dpm_context)
347 return -ENOMEM;
348
349 if (smu_dpm->golden_dpm_context)
350 return -EINVAL;
351
352 smu_dpm->golden_dpm_context = kzalloc(sizeof(struct arcturus_dpm_table),
353 GFP_KERNEL);
354 if (!smu_dpm->golden_dpm_context)
355 return -ENOMEM;
356
357 smu_dpm->dpm_context_size = sizeof(struct arcturus_dpm_table);
358
359 smu_dpm->dpm_current_power_state = kzalloc(sizeof(struct smu_power_state),
360 GFP_KERNEL);
361 if (!smu_dpm->dpm_current_power_state)
362 return -ENOMEM;
363
364 smu_dpm->dpm_request_power_state = kzalloc(sizeof(struct smu_power_state),
365 GFP_KERNEL);
366 if (!smu_dpm->dpm_request_power_state)
367 return -ENOMEM;
368
369 return 0;
370}
371
a94235af
EQ
372static int
373arcturus_get_allowed_feature_mask(struct smu_context *smu,
374 uint32_t *feature_mask, uint32_t num)
375{
376 if (num > 2)
377 return -EINVAL;
378
59de58f8
EQ
379 /* pptable will handle the features to enable */
380 memset(feature_mask, 0xFF, sizeof(uint32_t) * num);
a94235af
EQ
381
382 return 0;
383}
384
385static int
386arcturus_set_single_dpm_table(struct smu_context *smu,
387 struct arcturus_single_dpm_table *single_dpm_table,
388 PPCLK_e clk_id)
389{
390 int ret = 0;
391 uint32_t i, num_of_levels = 0, clk;
392
393 ret = smu_send_smc_msg_with_param(smu,
394 SMU_MSG_GetDpmFreqByIndex,
1c58267c
MC
395 (clk_id << 16 | 0xFF),
396 &num_of_levels);
a94235af 397 if (ret) {
d9811cfc 398 dev_err(smu->adev->dev, "[%s] failed to get dpm levels!\n", __func__);
a94235af
EQ
399 return ret;
400 }
401
a94235af
EQ
402 single_dpm_table->count = num_of_levels;
403 for (i = 0; i < num_of_levels; i++) {
404 ret = smu_send_smc_msg_with_param(smu,
405 SMU_MSG_GetDpmFreqByIndex,
1c58267c
MC
406 (clk_id << 16 | i),
407 &clk);
a94235af 408 if (ret) {
d9811cfc 409 dev_err(smu->adev->dev, "[%s] failed to get dpm freq by index!\n", __func__);
a94235af
EQ
410 return ret;
411 }
a94235af
EQ
412 single_dpm_table->dpm_levels[i].value = clk;
413 single_dpm_table->dpm_levels[i].enabled = true;
414 }
415 return 0;
416}
417
418static void arcturus_init_single_dpm_state(struct arcturus_dpm_state *dpm_state)
419{
420 dpm_state->soft_min_level = 0x0;
421 dpm_state->soft_max_level = 0xffff;
422 dpm_state->hard_min_level = 0x0;
423 dpm_state->hard_max_level = 0xffff;
424}
425
426static int arcturus_set_default_dpm_table(struct smu_context *smu)
427{
428 int ret;
429
430 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
431 struct arcturus_dpm_table *dpm_table = NULL;
432 struct arcturus_single_dpm_table *single_dpm_table;
433
434 dpm_table = smu_dpm->dpm_context;
435
436 /* socclk */
437 single_dpm_table = &(dpm_table->soc_table);
8a856ced 438 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
a94235af
EQ
439 ret = arcturus_set_single_dpm_table(smu, single_dpm_table,
440 PPCLK_SOCCLK);
441 if (ret) {
d9811cfc 442 dev_err(smu->adev->dev, "[%s] failed to get socclk dpm levels!\n", __func__);
a94235af
EQ
443 return ret;
444 }
445 } else {
446 single_dpm_table->count = 1;
447 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.socclk / 100;
448 }
449 arcturus_init_single_dpm_state(&(single_dpm_table->dpm_state));
450
451 /* gfxclk */
452 single_dpm_table = &(dpm_table->gfx_table);
8a856ced 453 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT)) {
a94235af
EQ
454 ret = arcturus_set_single_dpm_table(smu, single_dpm_table,
455 PPCLK_GFXCLK);
456 if (ret) {
d9811cfc 457 dev_err(smu->adev->dev, "[SetupDefaultDpmTable] failed to get gfxclk dpm levels!");
a94235af
EQ
458 return ret;
459 }
460 } else {
461 single_dpm_table->count = 1;
462 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
463 }
464 arcturus_init_single_dpm_state(&(single_dpm_table->dpm_state));
465
466 /* memclk */
467 single_dpm_table = &(dpm_table->mem_table);
8a856ced 468 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
a94235af
EQ
469 ret = arcturus_set_single_dpm_table(smu, single_dpm_table,
470 PPCLK_UCLK);
471 if (ret) {
d9811cfc 472 dev_err(smu->adev->dev, "[SetupDefaultDpmTable] failed to get memclk dpm levels!");
a94235af
EQ
473 return ret;
474 }
475 } else {
476 single_dpm_table->count = 1;
477 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.uclk / 100;
478 }
479 arcturus_init_single_dpm_state(&(single_dpm_table->dpm_state));
480
481 /* fclk */
482 single_dpm_table = &(dpm_table->fclk_table);
8a856ced 483 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_FCLK_BIT)) {
a94235af
EQ
484 ret = arcturus_set_single_dpm_table(smu, single_dpm_table,
485 PPCLK_FCLK);
486 if (ret) {
d9811cfc 487 dev_err(smu->adev->dev, "[SetupDefaultDpmTable] failed to get fclk dpm levels!");
a94235af
EQ
488 return ret;
489 }
490 } else {
69174eeb
EQ
491 single_dpm_table->count = 1;
492 single_dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.fclk / 100;
a94235af
EQ
493 }
494 arcturus_init_single_dpm_state(&(single_dpm_table->dpm_state));
495
496 memcpy(smu_dpm->golden_dpm_context, dpm_table,
497 sizeof(struct arcturus_dpm_table));
498
499 return 0;
500}
501
502static int arcturus_check_powerplay_table(struct smu_context *smu)
503{
4a13b4ce
EQ
504 struct smu_table_context *table_context = &smu->smu_table;
505 struct smu_11_0_powerplay_table *powerplay_table =
506 table_context->power_play_table;
507 struct smu_baco_context *smu_baco = &smu->smu_baco;
508
509 mutex_lock(&smu_baco->mutex);
510 if (powerplay_table->platform_caps & SMU_11_0_PP_PLATFORM_CAP_BACO ||
511 powerplay_table->platform_caps & SMU_11_0_PP_PLATFORM_CAP_MACO)
512 smu_baco->platform_support = true;
513 mutex_unlock(&smu_baco->mutex);
514
515 table_context->thermal_controller_type =
516 powerplay_table->thermal_controller_type;
517
a94235af
EQ
518 return 0;
519}
520
521static int arcturus_store_powerplay_table(struct smu_context *smu)
522{
a94235af 523 struct smu_table_context *table_context = &smu->smu_table;
4a13b4ce
EQ
524 struct smu_11_0_powerplay_table *powerplay_table =
525 table_context->power_play_table;
a94235af
EQ
526
527 memcpy(table_context->driver_pptable, &powerplay_table->smc_pptable,
528 sizeof(PPTable_t));
529
4a13b4ce 530 return 0;
a94235af
EQ
531}
532
533static int arcturus_append_powerplay_table(struct smu_context *smu)
534{
535 struct smu_table_context *table_context = &smu->smu_table;
536 PPTable_t *smc_pptable = table_context->driver_pptable;
537 struct atom_smc_dpm_info_v4_6 *smc_dpm_table;
538 int index, ret;
539
540 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
541 smc_dpm_info);
542
543 ret = smu_get_atom_data_table(smu, index, NULL, NULL, NULL,
544 (uint8_t **)&smc_dpm_table);
545 if (ret)
546 return ret;
547
d9811cfc 548 dev_info(smu->adev->dev, "smc_dpm_info table revision(format.content): %d.%d\n",
a94235af
EQ
549 smc_dpm_table->table_header.format_revision,
550 smc_dpm_table->table_header.content_revision);
551
552 if ((smc_dpm_table->table_header.format_revision == 4) &&
553 (smc_dpm_table->table_header.content_revision == 6))
554 memcpy(&smc_pptable->MaxVoltageStepGfx,
555 &smc_dpm_table->maxvoltagestepgfx,
556 sizeof(*smc_dpm_table) - offsetof(struct atom_smc_dpm_info_v4_6, maxvoltagestepgfx));
557
558 return 0;
559}
560
4a13b4ce
EQ
561static int arcturus_setup_pptable(struct smu_context *smu)
562{
563 int ret = 0;
564
565 ret = smu_v11_0_setup_pptable(smu);
566 if (ret)
567 return ret;
568
569 ret = arcturus_store_powerplay_table(smu);
570 if (ret)
571 return ret;
572
573 ret = arcturus_append_powerplay_table(smu);
574 if (ret)
575 return ret;
576
577 ret = arcturus_check_powerplay_table(smu);
578 if (ret)
579 return ret;
580
581 return ret;
582}
583
04c572a0 584static int arcturus_run_btc(struct smu_context *smu)
a94235af 585{
04c572a0
EQ
586 int ret = 0;
587
1c58267c 588 ret = smu_send_smc_msg(smu, SMU_MSG_RunAfllBtc, NULL);
04c572a0 589 if (ret) {
d9811cfc 590 dev_err(smu->adev->dev, "RunAfllBtc failed!\n");
04c572a0
EQ
591 return ret;
592 }
593
1c58267c 594 return smu_send_smc_msg(smu, SMU_MSG_RunDcBtc, NULL);
a94235af
EQ
595}
596
597static int arcturus_populate_umd_state_clk(struct smu_context *smu)
598{
599 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
600 struct arcturus_dpm_table *dpm_table = NULL;
601 struct arcturus_single_dpm_table *gfx_table = NULL;
602 struct arcturus_single_dpm_table *mem_table = NULL;
603
604 dpm_table = smu_dpm->dpm_context;
605 gfx_table = &(dpm_table->gfx_table);
606 mem_table = &(dpm_table->mem_table);
607
608 smu->pstate_sclk = gfx_table->dpm_levels[0].value;
609 smu->pstate_mclk = mem_table->dpm_levels[0].value;
610
611 if (gfx_table->count > ARCTURUS_UMD_PSTATE_GFXCLK_LEVEL &&
612 mem_table->count > ARCTURUS_UMD_PSTATE_MCLK_LEVEL) {
613 smu->pstate_sclk = gfx_table->dpm_levels[ARCTURUS_UMD_PSTATE_GFXCLK_LEVEL].value;
614 smu->pstate_mclk = mem_table->dpm_levels[ARCTURUS_UMD_PSTATE_MCLK_LEVEL].value;
615 }
616
617 smu->pstate_sclk = smu->pstate_sclk * 100;
618 smu->pstate_mclk = smu->pstate_mclk * 100;
619
620 return 0;
621}
622
623static int arcturus_get_clk_table(struct smu_context *smu,
624 struct pp_clock_levels_with_latency *clocks,
625 struct arcturus_single_dpm_table *dpm_table)
626{
627 int i, count;
628
629 count = (dpm_table->count > MAX_NUM_CLOCKS) ? MAX_NUM_CLOCKS : dpm_table->count;
630 clocks->num_levels = count;
631
632 for (i = 0; i < count; i++) {
633 clocks->data[i].clocks_in_khz =
634 dpm_table->dpm_levels[i].value * 1000;
635 clocks->data[i].latency_in_us = 0;
636 }
637
638 return 0;
639}
640
1f23cadb
EQ
641static int arcturus_freqs_in_same_level(int32_t frequency1,
642 int32_t frequency2)
643{
644 return (abs(frequency1 - frequency2) <= EPSILON);
645}
646
a94235af
EQ
647static int arcturus_print_clk_levels(struct smu_context *smu,
648 enum smu_clk_type type, char *buf)
649{
650 int i, now, size = 0;
651 int ret = 0;
652 struct pp_clock_levels_with_latency clocks;
653 struct arcturus_single_dpm_table *single_dpm_table;
654 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
655 struct arcturus_dpm_table *dpm_table = NULL;
656
30c296e1
JC
657 if (amdgpu_ras_intr_triggered())
658 return snprintf(buf, PAGE_SIZE, "unavailable\n");
659
a94235af
EQ
660 dpm_table = smu_dpm->dpm_context;
661
662 switch (type) {
663 case SMU_SCLK:
664 ret = smu_get_current_clk_freq(smu, SMU_GFXCLK, &now);
665 if (ret) {
d9811cfc 666 dev_err(smu->adev->dev, "Attempt to get current gfx clk Failed!");
a94235af
EQ
667 return ret;
668 }
669
670 single_dpm_table = &(dpm_table->gfx_table);
671 ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table);
672 if (ret) {
d9811cfc 673 dev_err(smu->adev->dev, "Attempt to get gfx clk levels Failed!");
a94235af
EQ
674 return ret;
675 }
676
59e038d0
EQ
677 /*
678 * For DPM disabled case, there will be only one clock level.
679 * And it's safe to assume that is always the current clock.
680 */
a94235af
EQ
681 for (i = 0; i < clocks.num_levels; i++)
682 size += sprintf(buf + size, "%d: %uMhz %s\n", i,
683 clocks.data[i].clocks_in_khz / 1000,
59e038d0
EQ
684 (clocks.num_levels == 1) ? "*" :
685 (arcturus_freqs_in_same_level(
1f23cadb 686 clocks.data[i].clocks_in_khz / 1000,
59e038d0 687 now / 100) ? "*" : ""));
a94235af
EQ
688 break;
689
690 case SMU_MCLK:
691 ret = smu_get_current_clk_freq(smu, SMU_UCLK, &now);
692 if (ret) {
d9811cfc 693 dev_err(smu->adev->dev, "Attempt to get current mclk Failed!");
a94235af
EQ
694 return ret;
695 }
696
697 single_dpm_table = &(dpm_table->mem_table);
698 ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table);
699 if (ret) {
d9811cfc 700 dev_err(smu->adev->dev, "Attempt to get memory clk levels Failed!");
a94235af
EQ
701 return ret;
702 }
703
704 for (i = 0; i < clocks.num_levels; i++)
705 size += sprintf(buf + size, "%d: %uMhz %s\n",
706 i, clocks.data[i].clocks_in_khz / 1000,
59e038d0
EQ
707 (clocks.num_levels == 1) ? "*" :
708 (arcturus_freqs_in_same_level(
1f23cadb 709 clocks.data[i].clocks_in_khz / 1000,
59e038d0 710 now / 100) ? "*" : ""));
a94235af
EQ
711 break;
712
713 case SMU_SOCCLK:
714 ret = smu_get_current_clk_freq(smu, SMU_SOCCLK, &now);
715 if (ret) {
d9811cfc 716 dev_err(smu->adev->dev, "Attempt to get current socclk Failed!");
a94235af
EQ
717 return ret;
718 }
719
720 single_dpm_table = &(dpm_table->soc_table);
721 ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table);
722 if (ret) {
d9811cfc 723 dev_err(smu->adev->dev, "Attempt to get socclk levels Failed!");
a94235af
EQ
724 return ret;
725 }
726
727 for (i = 0; i < clocks.num_levels; i++)
728 size += sprintf(buf + size, "%d: %uMhz %s\n",
729 i, clocks.data[i].clocks_in_khz / 1000,
59e038d0
EQ
730 (clocks.num_levels == 1) ? "*" :
731 (arcturus_freqs_in_same_level(
1f23cadb 732 clocks.data[i].clocks_in_khz / 1000,
59e038d0 733 now / 100) ? "*" : ""));
a94235af
EQ
734 break;
735
736 case SMU_FCLK:
737 ret = smu_get_current_clk_freq(smu, SMU_FCLK, &now);
738 if (ret) {
d9811cfc 739 dev_err(smu->adev->dev, "Attempt to get current fclk Failed!");
a94235af
EQ
740 return ret;
741 }
742
743 single_dpm_table = &(dpm_table->fclk_table);
1f23cadb
EQ
744 ret = arcturus_get_clk_table(smu, &clocks, single_dpm_table);
745 if (ret) {
d9811cfc 746 dev_err(smu->adev->dev, "Attempt to get fclk levels Failed!");
1f23cadb
EQ
747 return ret;
748 }
749
a94235af
EQ
750 for (i = 0; i < single_dpm_table->count; i++)
751 size += sprintf(buf + size, "%d: %uMhz %s\n",
752 i, single_dpm_table->dpm_levels[i].value,
59e038d0
EQ
753 (clocks.num_levels == 1) ? "*" :
754 (arcturus_freqs_in_same_level(
1f23cadb 755 clocks.data[i].clocks_in_khz / 1000,
59e038d0 756 now / 100) ? "*" : ""));
a94235af
EQ
757 break;
758
759 default:
760 break;
761 }
762
763 return size;
764}
765
766static int arcturus_upload_dpm_level(struct smu_context *smu, bool max,
60d435b7 767 uint32_t feature_mask)
a94235af 768{
a94235af 769 struct arcturus_single_dpm_table *single_dpm_table;
60d435b7
EQ
770 struct arcturus_dpm_table *dpm_table =
771 smu->smu_dpm.dpm_context;
a94235af
EQ
772 uint32_t freq;
773 int ret = 0;
774
60d435b7 775 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT) &&
a94235af
EQ
776 (feature_mask & FEATURE_DPM_GFXCLK_MASK)) {
777 single_dpm_table = &(dpm_table->gfx_table);
778 freq = max ? single_dpm_table->dpm_state.soft_max_level :
779 single_dpm_table->dpm_state.soft_min_level;
780 ret = smu_send_smc_msg_with_param(smu,
781 (max ? SMU_MSG_SetSoftMaxByFreq : SMU_MSG_SetSoftMinByFreq),
1c58267c
MC
782 (PPCLK_GFXCLK << 16) | (freq & 0xffff),
783 NULL);
a94235af 784 if (ret) {
d9811cfc 785 dev_err(smu->adev->dev, "Failed to set soft %s gfxclk !\n",
a94235af
EQ
786 max ? "max" : "min");
787 return ret;
788 }
789 }
790
60d435b7
EQ
791 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT) &&
792 (feature_mask & FEATURE_DPM_UCLK_MASK)) {
793 single_dpm_table = &(dpm_table->mem_table);
794 freq = max ? single_dpm_table->dpm_state.soft_max_level :
795 single_dpm_table->dpm_state.soft_min_level;
796 ret = smu_send_smc_msg_with_param(smu,
797 (max ? SMU_MSG_SetSoftMaxByFreq : SMU_MSG_SetSoftMinByFreq),
1c58267c
MC
798 (PPCLK_UCLK << 16) | (freq & 0xffff),
799 NULL);
60d435b7 800 if (ret) {
d9811cfc 801 dev_err(smu->adev->dev, "Failed to set soft %s memclk !\n",
60d435b7
EQ
802 max ? "max" : "min");
803 return ret;
804 }
805 }
806
807 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT) &&
808 (feature_mask & FEATURE_DPM_SOCCLK_MASK)) {
809 single_dpm_table = &(dpm_table->soc_table);
810 freq = max ? single_dpm_table->dpm_state.soft_max_level :
811 single_dpm_table->dpm_state.soft_min_level;
812 ret = smu_send_smc_msg_with_param(smu,
813 (max ? SMU_MSG_SetSoftMaxByFreq : SMU_MSG_SetSoftMinByFreq),
1c58267c
MC
814 (PPCLK_SOCCLK << 16) | (freq & 0xffff),
815 NULL);
60d435b7 816 if (ret) {
d9811cfc 817 dev_err(smu->adev->dev, "Failed to set soft %s socclk !\n",
60d435b7
EQ
818 max ? "max" : "min");
819 return ret;
820 }
821 }
822
a94235af
EQ
823 return ret;
824}
825
826static int arcturus_force_clk_levels(struct smu_context *smu,
827 enum smu_clk_type type, uint32_t mask)
828{
829 struct arcturus_dpm_table *dpm_table;
830 struct arcturus_single_dpm_table *single_dpm_table;
831 uint32_t soft_min_level, soft_max_level;
1744fb23 832 uint32_t smu_version;
a94235af
EQ
833 int ret = 0;
834
1744fb23
EQ
835 ret = smu_get_smc_version(smu, NULL, &smu_version);
836 if (ret) {
d9811cfc 837 dev_err(smu->adev->dev, "Failed to get smu version!\n");
1744fb23
EQ
838 return ret;
839 }
840
841 if (smu_version >= 0x361200) {
d9811cfc 842 dev_err(smu->adev->dev, "Forcing clock level is not supported with "
1744fb23
EQ
843 "54.18 and onwards SMU firmwares\n");
844 return -EOPNOTSUPP;
845 }
846
a94235af
EQ
847 soft_min_level = mask ? (ffs(mask) - 1) : 0;
848 soft_max_level = mask ? (fls(mask) - 1) : 0;
849
850 dpm_table = smu->smu_dpm.dpm_context;
851
852 switch (type) {
853 case SMU_SCLK:
854 single_dpm_table = &(dpm_table->gfx_table);
855
856 if (soft_max_level >= single_dpm_table->count) {
d9811cfc 857 dev_err(smu->adev->dev, "Clock level specified %d is over max allowed %d\n",
a94235af
EQ
858 soft_max_level, single_dpm_table->count - 1);
859 ret = -EINVAL;
860 break;
861 }
862
863 single_dpm_table->dpm_state.soft_min_level =
864 single_dpm_table->dpm_levels[soft_min_level].value;
865 single_dpm_table->dpm_state.soft_max_level =
866 single_dpm_table->dpm_levels[soft_max_level].value;
867
868 ret = arcturus_upload_dpm_level(smu, false, FEATURE_DPM_GFXCLK_MASK);
869 if (ret) {
d9811cfc 870 dev_err(smu->adev->dev, "Failed to upload boot level to lowest!\n");
a94235af
EQ
871 break;
872 }
873
874 ret = arcturus_upload_dpm_level(smu, true, FEATURE_DPM_GFXCLK_MASK);
875 if (ret)
d9811cfc 876 dev_err(smu->adev->dev, "Failed to upload dpm max level to highest!\n");
a94235af
EQ
877
878 break;
879
880 case SMU_MCLK:
a94235af 881 case SMU_SOCCLK:
a94235af 882 case SMU_FCLK:
0525f297
EQ
883 /*
884 * Should not arrive here since Arcturus does not
885 * support mclk/socclk/fclk softmin/softmax settings
886 */
887 ret = -EINVAL;
a94235af
EQ
888 break;
889
890 default:
891 break;
892 }
893
a94235af
EQ
894 return ret;
895}
896
a94235af
EQ
897static int arcturus_get_thermal_temperature_range(struct smu_context *smu,
898 struct smu_temperature_range *range)
899{
a94235af
EQ
900 PPTable_t *pptable = smu->smu_table.driver_pptable;
901
902 if (!range)
903 return -EINVAL;
904
a94235af
EQ
905 range->max = pptable->TedgeLimit *
906 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
907 range->edge_emergency_max = (pptable->TedgeLimit + CTF_OFFSET_EDGE) *
908 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
909 range->hotspot_crit_max = pptable->ThotspotLimit *
910 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
911 range->hotspot_emergency_max = (pptable->ThotspotLimit + CTF_OFFSET_HOTSPOT) *
912 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
913 range->mem_crit_max = pptable->TmemLimit *
914 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
915 range->mem_emergency_max = (pptable->TmemLimit + CTF_OFFSET_HBM)*
916 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
917
a94235af
EQ
918 return 0;
919}
920
48219126
EQ
921static int arcturus_get_smu_metrics_data(struct smu_context *smu,
922 MetricsMember_t member,
923 uint32_t *value)
ba74c8bf
EQ
924{
925 struct smu_table_context *smu_table= &smu->smu_table;
48219126 926 SmuMetrics_t *metrics = (SmuMetrics_t *)smu_table->metrics_table;
ba74c8bf
EQ
927 int ret = 0;
928
59847dc8 929 mutex_lock(&smu->metrics_lock);
48219126 930
ba74c8bf 931 if (!smu_table->metrics_time ||
48219126
EQ
932 time_after(jiffies, smu_table->metrics_time + msecs_to_jiffies(1))) {
933 ret = smu_update_table(smu,
934 SMU_TABLE_SMU_METRICS,
935 0,
936 smu_table->metrics_table,
937 false);
ba74c8bf 938 if (ret) {
d9811cfc 939 dev_info(smu->adev->dev, "Failed to export SMU metrics table!\n");
59847dc8 940 mutex_unlock(&smu->metrics_lock);
ba74c8bf
EQ
941 return ret;
942 }
943 smu_table->metrics_time = jiffies;
944 }
945
48219126
EQ
946 switch (member) {
947 case METRICS_CURR_GFXCLK:
948 *value = metrics->CurrClock[PPCLK_GFXCLK];
949 break;
950 case METRICS_CURR_SOCCLK:
951 *value = metrics->CurrClock[PPCLK_SOCCLK];
952 break;
953 case METRICS_CURR_UCLK:
954 *value = metrics->CurrClock[PPCLK_UCLK];
955 break;
956 case METRICS_CURR_VCLK:
957 *value = metrics->CurrClock[PPCLK_VCLK];
958 break;
959 case METRICS_CURR_DCLK:
960 *value = metrics->CurrClock[PPCLK_DCLK];
961 break;
962 case METRICS_CURR_FCLK:
963 *value = metrics->CurrClock[PPCLK_FCLK];
964 break;
965 case METRICS_AVERAGE_GFXCLK:
966 *value = metrics->AverageGfxclkFrequency;
967 break;
968 case METRICS_AVERAGE_SOCCLK:
969 *value = metrics->AverageSocclkFrequency;
970 break;
971 case METRICS_AVERAGE_UCLK:
972 *value = metrics->AverageUclkFrequency;
973 break;
974 case METRICS_AVERAGE_VCLK:
975 *value = metrics->AverageVclkFrequency;
976 break;
977 case METRICS_AVERAGE_DCLK:
978 *value = metrics->AverageDclkFrequency;
979 break;
980 case METRICS_AVERAGE_GFXACTIVITY:
981 *value = metrics->AverageGfxActivity;
982 break;
983 case METRICS_AVERAGE_MEMACTIVITY:
984 *value = metrics->AverageUclkActivity;
985 break;
986 case METRICS_AVERAGE_VCNACTIVITY:
987 *value = metrics->VcnActivityPercentage;
988 break;
989 case METRICS_AVERAGE_SOCKETPOWER:
990 *value = metrics->AverageSocketPower << 8;
991 break;
992 case METRICS_TEMPERATURE_EDGE:
993 *value = metrics->TemperatureEdge *
994 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
995 break;
996 case METRICS_TEMPERATURE_HOTSPOT:
997 *value = metrics->TemperatureHotspot *
998 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
999 break;
1000 case METRICS_TEMPERATURE_MEM:
1001 *value = metrics->TemperatureHBM *
1002 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1003 break;
1004 case METRICS_TEMPERATURE_VRGFX:
1005 *value = metrics->TemperatureVrGfx *
1006 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1007 break;
1008 case METRICS_TEMPERATURE_VRSOC:
1009 *value = metrics->TemperatureVrSoc *
1010 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1011 break;
1012 case METRICS_TEMPERATURE_VRMEM:
1013 *value = metrics->TemperatureVrMem *
1014 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
1015 break;
1016 case METRICS_THROTTLER_STATUS:
1017 *value = metrics->ThrottlerStatus;
1018 break;
1019 case METRICS_CURR_FANSPEED:
1020 *value = metrics->CurrFanSpeed;
1021 break;
1022 default:
1023 *value = UINT_MAX;
1024 break;
1025 }
1026
59847dc8 1027 mutex_unlock(&smu->metrics_lock);
ba74c8bf
EQ
1028
1029 return ret;
1030}
1031
1032static int arcturus_get_current_activity_percent(struct smu_context *smu,
1033 enum amd_pp_sensors sensor,
1034 uint32_t *value)
1035{
ba74c8bf
EQ
1036 int ret = 0;
1037
1038 if (!value)
1039 return -EINVAL;
1040
ba74c8bf
EQ
1041 switch (sensor) {
1042 case AMDGPU_PP_SENSOR_GPU_LOAD:
48219126
EQ
1043 ret = arcturus_get_smu_metrics_data(smu,
1044 METRICS_AVERAGE_GFXACTIVITY,
1045 value);
ba74c8bf
EQ
1046 break;
1047 case AMDGPU_PP_SENSOR_MEM_LOAD:
48219126
EQ
1048 ret = arcturus_get_smu_metrics_data(smu,
1049 METRICS_AVERAGE_MEMACTIVITY,
1050 value);
ba74c8bf
EQ
1051 break;
1052 default:
d9811cfc 1053 dev_err(smu->adev->dev, "Invalid sensor for retrieving clock activity\n");
ba74c8bf
EQ
1054 return -EINVAL;
1055 }
1056
48219126 1057 return ret;
ba74c8bf
EQ
1058}
1059
1060static int arcturus_get_gpu_power(struct smu_context *smu, uint32_t *value)
1061{
ba74c8bf
EQ
1062 if (!value)
1063 return -EINVAL;
1064
48219126
EQ
1065 return arcturus_get_smu_metrics_data(smu,
1066 METRICS_AVERAGE_SOCKETPOWER,
1067 value);
ba74c8bf
EQ
1068}
1069
1070static int arcturus_thermal_get_temperature(struct smu_context *smu,
1071 enum amd_pp_sensors sensor,
1072 uint32_t *value)
1073{
ba74c8bf
EQ
1074 int ret = 0;
1075
1076 if (!value)
1077 return -EINVAL;
1078
ba74c8bf
EQ
1079 switch (sensor) {
1080 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
48219126
EQ
1081 ret = arcturus_get_smu_metrics_data(smu,
1082 METRICS_TEMPERATURE_HOTSPOT,
1083 value);
ba74c8bf
EQ
1084 break;
1085 case AMDGPU_PP_SENSOR_EDGE_TEMP:
48219126
EQ
1086 ret = arcturus_get_smu_metrics_data(smu,
1087 METRICS_TEMPERATURE_EDGE,
1088 value);
ba74c8bf
EQ
1089 break;
1090 case AMDGPU_PP_SENSOR_MEM_TEMP:
48219126
EQ
1091 ret = arcturus_get_smu_metrics_data(smu,
1092 METRICS_TEMPERATURE_MEM,
1093 value);
ba74c8bf
EQ
1094 break;
1095 default:
d9811cfc 1096 dev_err(smu->adev->dev, "Invalid sensor for retrieving temp\n");
ba74c8bf
EQ
1097 return -EINVAL;
1098 }
1099
48219126 1100 return ret;
ba74c8bf
EQ
1101}
1102
1103static int arcturus_read_sensor(struct smu_context *smu,
1104 enum amd_pp_sensors sensor,
1105 void *data, uint32_t *size)
1106{
1107 struct smu_table_context *table_context = &smu->smu_table;
1108 PPTable_t *pptable = table_context->driver_pptable;
1109 int ret = 0;
1110
30c296e1
JC
1111 if (amdgpu_ras_intr_triggered())
1112 return 0;
1113
97442140
KW
1114 if (!data || !size)
1115 return -EINVAL;
1116
95f71bfa 1117 mutex_lock(&smu->sensor_lock);
ba74c8bf
EQ
1118 switch (sensor) {
1119 case AMDGPU_PP_SENSOR_MAX_FAN_RPM:
1120 *(uint32_t *)data = pptable->FanMaximumRpm;
1121 *size = 4;
1122 break;
1123 case AMDGPU_PP_SENSOR_MEM_LOAD:
1124 case AMDGPU_PP_SENSOR_GPU_LOAD:
1125 ret = arcturus_get_current_activity_percent(smu,
1126 sensor,
1127 (uint32_t *)data);
1128 *size = 4;
1129 break;
1130 case AMDGPU_PP_SENSOR_GPU_POWER:
1131 ret = arcturus_get_gpu_power(smu, (uint32_t *)data);
1132 *size = 4;
1133 break;
1134 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
1135 case AMDGPU_PP_SENSOR_EDGE_TEMP:
1136 case AMDGPU_PP_SENSOR_MEM_TEMP:
1137 ret = arcturus_thermal_get_temperature(smu, sensor,
1138 (uint32_t *)data);
1139 *size = 4;
1140 break;
1141 default:
6c45e480 1142 ret = smu_v11_0_read_sensor(smu, sensor, data, size);
ba74c8bf 1143 }
95f71bfa 1144 mutex_unlock(&smu->sensor_lock);
ba74c8bf
EQ
1145
1146 return ret;
1147}
1148
d427cf8f
EQ
1149static int arcturus_get_fan_speed_rpm(struct smu_context *smu,
1150 uint32_t *speed)
1151{
d427cf8f
EQ
1152 if (!speed)
1153 return -EINVAL;
1154
48219126
EQ
1155 return arcturus_get_smu_metrics_data(smu,
1156 METRICS_CURR_FANSPEED,
1157 speed);
d427cf8f
EQ
1158}
1159
1160static int arcturus_get_fan_speed_percent(struct smu_context *smu,
1161 uint32_t *speed)
1162{
1163 PPTable_t *pptable = smu->smu_table.driver_pptable;
1164 uint32_t percent, current_rpm;
1165 int ret = 0;
1166
1167 if (!speed)
1168 return -EINVAL;
1169
1170 ret = arcturus_get_fan_speed_rpm(smu, &current_rpm);
1171 if (ret)
1172 return ret;
1173
1174 percent = current_rpm * 100 / pptable->FanMaximumRpm;
1175 *speed = percent > 100 ? 100 : percent;
1176
1177 return ret;
1178}
1179
631807f0
EQ
1180static int arcturus_get_current_clk_freq_by_table(struct smu_context *smu,
1181 enum smu_clk_type clk_type,
1182 uint32_t *value)
1183{
48219126
EQ
1184 MetricsMember_t member_type;
1185 int clk_id = 0;
631807f0
EQ
1186
1187 if (!value)
1188 return -EINVAL;
1189
1190 clk_id = smu_clk_get_index(smu, clk_type);
1191 if (clk_id < 0)
1192 return -EINVAL;
1193
4bf76e60
EQ
1194 switch (clk_id) {
1195 case PPCLK_GFXCLK:
1196 /*
1197 * CurrClock[clk_id] can provide accurate
1198 * output only when the dpm feature is enabled.
1199 * We can use Average_* for dpm disabled case.
48219126 1200 * But this is available for gfxclk/uclk/socclk/vclk/dclk.
4bf76e60
EQ
1201 */
1202 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT))
48219126 1203 member_type = METRICS_CURR_GFXCLK;
4bf76e60 1204 else
48219126 1205 member_type = METRICS_AVERAGE_GFXCLK;
4bf76e60
EQ
1206 break;
1207 case PPCLK_UCLK:
1208 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT))
48219126 1209 member_type = METRICS_CURR_UCLK;
4bf76e60 1210 else
48219126 1211 member_type = METRICS_AVERAGE_UCLK;
4bf76e60
EQ
1212 break;
1213 case PPCLK_SOCCLK:
1214 if (smu_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT))
48219126 1215 member_type = METRICS_CURR_SOCCLK;
4bf76e60 1216 else
48219126 1217 member_type = METRICS_AVERAGE_SOCCLK;
4bf76e60 1218 break;
48219126
EQ
1219 case PPCLK_VCLK:
1220 if (smu_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT))
1221 member_type = METRICS_CURR_VCLK;
1222 else
1223 member_type = METRICS_AVERAGE_VCLK;
1224 break;
1225 case PPCLK_DCLK:
1226 if (smu_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT))
1227 member_type = METRICS_CURR_DCLK;
1228 else
1229 member_type = METRICS_AVERAGE_DCLK;
4bf76e60 1230 break;
48219126
EQ
1231 case PPCLK_FCLK:
1232 member_type = METRICS_CURR_FCLK;
1233 break;
1234 default:
1235 return -EINVAL;
4bf76e60 1236 }
631807f0 1237
48219126
EQ
1238 return arcturus_get_smu_metrics_data(smu,
1239 member_type,
1240 value);
631807f0
EQ
1241}
1242
60d435b7
EQ
1243static uint32_t arcturus_find_lowest_dpm_level(struct arcturus_single_dpm_table *table)
1244{
1245 uint32_t i;
1246
1247 for (i = 0; i < table->count; i++) {
1248 if (table->dpm_levels[i].enabled)
1249 break;
1250 }
1251 if (i >= table->count) {
1252 i = 0;
1253 table->dpm_levels[i].enabled = true;
1254 }
1255
1256 return i;
1257}
1258
d9811cfc
EQ
1259static uint32_t arcturus_find_highest_dpm_level(struct smu_context *smu,
1260 struct arcturus_single_dpm_table *table)
60d435b7
EQ
1261{
1262 int i = 0;
1263
1264 if (table->count <= 0) {
d9811cfc 1265 dev_err(smu->adev->dev, "[%s] DPM Table has no entry!", __func__);
60d435b7
EQ
1266 return 0;
1267 }
1268 if (table->count > MAX_DPM_NUMBER) {
d9811cfc 1269 dev_err(smu->adev->dev, "[%s] DPM Table has too many entries!", __func__);
60d435b7
EQ
1270 return MAX_DPM_NUMBER - 1;
1271 }
1272
1273 for (i = table->count - 1; i >= 0; i--) {
1274 if (table->dpm_levels[i].enabled)
1275 break;
1276 }
1277 if (i < 0) {
1278 i = 0;
1279 table->dpm_levels[i].enabled = true;
1280 }
1281
1282 return i;
1283}
1284
1285
1286
1287static int arcturus_force_dpm_limit_value(struct smu_context *smu, bool highest)
1288{
1289 struct arcturus_dpm_table *dpm_table =
1290 (struct arcturus_dpm_table *)smu->smu_dpm.dpm_context;
0525f297 1291 struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(smu->adev, 0);
60d435b7
EQ
1292 uint32_t soft_level;
1293 int ret = 0;
1294
1295 /* gfxclk */
1296 if (highest)
d9811cfc 1297 soft_level = arcturus_find_highest_dpm_level(smu, &(dpm_table->gfx_table));
60d435b7
EQ
1298 else
1299 soft_level = arcturus_find_lowest_dpm_level(&(dpm_table->gfx_table));
1300
1301 dpm_table->gfx_table.dpm_state.soft_min_level =
1302 dpm_table->gfx_table.dpm_state.soft_max_level =
1303 dpm_table->gfx_table.dpm_levels[soft_level].value;
1304
0525f297 1305 ret = arcturus_upload_dpm_level(smu, false, FEATURE_DPM_GFXCLK_MASK);
60d435b7 1306 if (ret) {
d9811cfc 1307 dev_err(smu->adev->dev, "Failed to upload boot level to %s!\n",
60d435b7
EQ
1308 highest ? "highest" : "lowest");
1309 return ret;
1310 }
1311
0525f297 1312 ret = arcturus_upload_dpm_level(smu, true, FEATURE_DPM_GFXCLK_MASK);
60d435b7 1313 if (ret) {
d9811cfc 1314 dev_err(smu->adev->dev, "Failed to upload dpm max level to %s!\n!",
60d435b7
EQ
1315 highest ? "highest" : "lowest");
1316 return ret;
1317 }
1318
0525f297
EQ
1319 if (hive)
1320 /*
1321 * Force XGMI Pstate to highest or lowest
1322 * TODO: revise this when xgmi dpm is functional
1323 */
1324 ret = smu_v11_0_set_xgmi_pstate(smu, highest ? 1 : 0);
1325
60d435b7
EQ
1326 return ret;
1327}
1328
1329static int arcturus_unforce_dpm_levels(struct smu_context *smu)
1330{
1331 struct arcturus_dpm_table *dpm_table =
1332 (struct arcturus_dpm_table *)smu->smu_dpm.dpm_context;
0525f297 1333 struct amdgpu_hive_info *hive = amdgpu_get_xgmi_hive(smu->adev, 0);
60d435b7
EQ
1334 uint32_t soft_min_level, soft_max_level;
1335 int ret = 0;
1336
1337 /* gfxclk */
1338 soft_min_level = arcturus_find_lowest_dpm_level(&(dpm_table->gfx_table));
d9811cfc 1339 soft_max_level = arcturus_find_highest_dpm_level(smu, &(dpm_table->gfx_table));
60d435b7
EQ
1340 dpm_table->gfx_table.dpm_state.soft_min_level =
1341 dpm_table->gfx_table.dpm_levels[soft_min_level].value;
1342 dpm_table->gfx_table.dpm_state.soft_max_level =
1343 dpm_table->gfx_table.dpm_levels[soft_max_level].value;
1344
0525f297 1345 ret = arcturus_upload_dpm_level(smu, false, FEATURE_DPM_GFXCLK_MASK);
60d435b7 1346 if (ret) {
d9811cfc 1347 dev_err(smu->adev->dev, "Failed to upload DPM Bootup Levels!");
60d435b7
EQ
1348 return ret;
1349 }
1350
0525f297 1351 ret = arcturus_upload_dpm_level(smu, true, FEATURE_DPM_GFXCLK_MASK);
60d435b7 1352 if (ret) {
d9811cfc 1353 dev_err(smu->adev->dev, "Failed to upload DPM Max Levels!");
60d435b7
EQ
1354 return ret;
1355 }
1356
0525f297
EQ
1357 if (hive)
1358 /*
1359 * Reset XGMI Pstate back to default
1360 * TODO: revise this when xgmi dpm is functional
1361 */
1362 ret = smu_v11_0_set_xgmi_pstate(smu, 0);
1363
60d435b7
EQ
1364 return ret;
1365}
1366
1367static int
1368arcturus_get_profiling_clk_mask(struct smu_context *smu,
1369 enum amd_dpm_forced_level level,
1370 uint32_t *sclk_mask,
1371 uint32_t *mclk_mask,
1372 uint32_t *soc_mask)
1373{
1374 struct arcturus_dpm_table *dpm_table =
1375 (struct arcturus_dpm_table *)smu->smu_dpm.dpm_context;
1376 struct arcturus_single_dpm_table *gfx_dpm_table;
1377 struct arcturus_single_dpm_table *mem_dpm_table;
1378 struct arcturus_single_dpm_table *soc_dpm_table;
1379
1380 if (!smu->smu_dpm.dpm_context)
1381 return -EINVAL;
1382
1383 gfx_dpm_table = &dpm_table->gfx_table;
1384 mem_dpm_table = &dpm_table->mem_table;
1385 soc_dpm_table = &dpm_table->soc_table;
1386
1387 *sclk_mask = 0;
1388 *mclk_mask = 0;
1389 *soc_mask = 0;
1390
1391 if (gfx_dpm_table->count > ARCTURUS_UMD_PSTATE_GFXCLK_LEVEL &&
1392 mem_dpm_table->count > ARCTURUS_UMD_PSTATE_MCLK_LEVEL &&
1393 soc_dpm_table->count > ARCTURUS_UMD_PSTATE_SOCCLK_LEVEL) {
1394 *sclk_mask = ARCTURUS_UMD_PSTATE_GFXCLK_LEVEL;
1395 *mclk_mask = ARCTURUS_UMD_PSTATE_MCLK_LEVEL;
1396 *soc_mask = ARCTURUS_UMD_PSTATE_SOCCLK_LEVEL;
1397 }
1398
1399 if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK) {
1400 *sclk_mask = 0;
1401 } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK) {
1402 *mclk_mask = 0;
1403 } else if (level == AMD_DPM_FORCED_LEVEL_PROFILE_PEAK) {
1404 *sclk_mask = gfx_dpm_table->count - 1;
1405 *mclk_mask = mem_dpm_table->count - 1;
1406 *soc_mask = soc_dpm_table->count - 1;
1407 }
1408
1409 return 0;
1410}
1411
a141b4e3 1412static int arcturus_get_power_limit(struct smu_context *smu)
b4af964e 1413{
1e239fdd
EQ
1414 struct smu_11_0_powerplay_table *powerplay_table =
1415 (struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table;
b4af964e 1416 PPTable_t *pptable = smu->smu_table.driver_pptable;
1e239fdd
EQ
1417 uint32_t power_limit, od_percent;
1418
1419 if (smu_v11_0_get_current_power_limit(smu, &power_limit)) {
1420 /* the last hope to figure out the ppt limit */
1421 if (!pptable) {
1422 dev_err(smu->adev->dev, "Cannot get PPT limit due to pptable missing!");
1423 return -EINVAL;
b4af964e 1424 }
1e239fdd
EQ
1425 power_limit =
1426 pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0];
1427 }
1428 smu->current_power_limit = power_limit;
b4af964e 1429
1e239fdd
EQ
1430 if (smu->od_enabled) {
1431 od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]);
1432
1433 dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit);
1434
1435 power_limit *= (100 + od_percent);
1436 power_limit /= 100;
b4af964e 1437 }
1e239fdd 1438 smu->max_power_limit = power_limit;
b4af964e 1439
b4af964e
EQ
1440 return 0;
1441}
1442
7aa3f675
EQ
1443static int arcturus_get_power_profile_mode(struct smu_context *smu,
1444 char *buf)
1445{
18d7ab98 1446 DpmActivityMonitorCoeffInt_t activity_monitor;
7aa3f675
EQ
1447 static const char *profile_name[] = {
1448 "BOOTUP_DEFAULT",
1449 "3D_FULL_SCREEN",
1450 "POWER_SAVING",
1451 "VIDEO",
1452 "VR",
1453 "COMPUTE",
1454 "CUSTOM"};
80c5a807 1455 static const char *title[] = {
18d7ab98
EQ
1456 "PROFILE_INDEX(NAME)",
1457 "CLOCK_TYPE(NAME)",
1458 "FPS",
1459 "UseRlcBusy",
1460 "MinActiveFreqType",
1461 "MinActiveFreq",
1462 "BoosterFreqType",
1463 "BoosterFreq",
1464 "PD_Data_limit_c",
1465 "PD_Data_error_coeff",
1466 "PD_Data_error_rate_coeff"};
7aa3f675
EQ
1467 uint32_t i, size = 0;
1468 int16_t workload_type = 0;
18d7ab98
EQ
1469 int result = 0;
1470 uint32_t smu_version;
7aa3f675 1471
18d7ab98 1472 if (!buf)
7aa3f675
EQ
1473 return -EINVAL;
1474
18d7ab98
EQ
1475 result = smu_get_smc_version(smu, NULL, &smu_version);
1476 if (result)
1477 return result;
1478
41fb666d 1479 if (smu_version >= 0x360d00)
18d7ab98
EQ
1480 size += sprintf(buf + size, "%16s %s %s %s %s %s %s %s %s %s %s\n",
1481 title[0], title[1], title[2], title[3], title[4], title[5],
1482 title[6], title[7], title[8], title[9], title[10]);
1483 else
1484 size += sprintf(buf + size, "%16s\n",
80c5a807
AD
1485 title[0]);
1486
7aa3f675
EQ
1487 for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) {
1488 /*
1489 * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT
1490 * Not all profile modes are supported on arcturus.
1491 */
1492 workload_type = smu_workload_get_type(smu, i);
1493 if (workload_type < 0)
1494 continue;
1495
41fb666d 1496 if (smu_version >= 0x360d00) {
18d7ab98
EQ
1497 result = smu_update_table(smu,
1498 SMU_TABLE_ACTIVITY_MONITOR_COEFF,
1499 workload_type,
1500 (void *)(&activity_monitor),
1501 false);
1502 if (result) {
d9811cfc 1503 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
18d7ab98
EQ
1504 return result;
1505 }
1506 }
1507
7aa3f675
EQ
1508 size += sprintf(buf + size, "%2d %14s%s\n",
1509 i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " ");
18d7ab98 1510
41fb666d 1511 if (smu_version >= 0x360d00) {
18d7ab98
EQ
1512 size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
1513 " ",
1514 0,
1515 "GFXCLK",
1516 activity_monitor.Gfx_FPS,
1517 activity_monitor.Gfx_UseRlcBusy,
1518 activity_monitor.Gfx_MinActiveFreqType,
1519 activity_monitor.Gfx_MinActiveFreq,
1520 activity_monitor.Gfx_BoosterFreqType,
1521 activity_monitor.Gfx_BoosterFreq,
1522 activity_monitor.Gfx_PD_Data_limit_c,
1523 activity_monitor.Gfx_PD_Data_error_coeff,
1524 activity_monitor.Gfx_PD_Data_error_rate_coeff);
1525
1526 size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
1527 " ",
1528 1,
1529 "UCLK",
1530 activity_monitor.Mem_FPS,
1531 activity_monitor.Mem_UseRlcBusy,
1532 activity_monitor.Mem_MinActiveFreqType,
1533 activity_monitor.Mem_MinActiveFreq,
1534 activity_monitor.Mem_BoosterFreqType,
1535 activity_monitor.Mem_BoosterFreq,
1536 activity_monitor.Mem_PD_Data_limit_c,
1537 activity_monitor.Mem_PD_Data_error_coeff,
1538 activity_monitor.Mem_PD_Data_error_rate_coeff);
1539 }
7aa3f675
EQ
1540 }
1541
1542 return size;
1543}
1544
1545static int arcturus_set_power_profile_mode(struct smu_context *smu,
1546 long *input,
1547 uint32_t size)
1548{
18d7ab98 1549 DpmActivityMonitorCoeffInt_t activity_monitor;
7aa3f675
EQ
1550 int workload_type = 0;
1551 uint32_t profile_mode = input[size];
1552 int ret = 0;
18d7ab98 1553 uint32_t smu_version;
7aa3f675
EQ
1554
1555 if (profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) {
d9811cfc 1556 dev_err(smu->adev->dev, "Invalid power profile mode %d\n", profile_mode);
7aa3f675
EQ
1557 return -EINVAL;
1558 }
1559
18d7ab98
EQ
1560 ret = smu_get_smc_version(smu, NULL, &smu_version);
1561 if (ret)
1562 return ret;
1563
1564 if ((profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) &&
1565 (smu_version >=0x360d00)) {
1566 ret = smu_update_table(smu,
1567 SMU_TABLE_ACTIVITY_MONITOR_COEFF,
1568 WORKLOAD_PPLIB_CUSTOM_BIT,
1569 (void *)(&activity_monitor),
1570 false);
1571 if (ret) {
d9811cfc 1572 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
18d7ab98
EQ
1573 return ret;
1574 }
1575
1576 switch (input[0]) {
1577 case 0: /* Gfxclk */
1578 activity_monitor.Gfx_FPS = input[1];
1579 activity_monitor.Gfx_UseRlcBusy = input[2];
1580 activity_monitor.Gfx_MinActiveFreqType = input[3];
1581 activity_monitor.Gfx_MinActiveFreq = input[4];
1582 activity_monitor.Gfx_BoosterFreqType = input[5];
1583 activity_monitor.Gfx_BoosterFreq = input[6];
1584 activity_monitor.Gfx_PD_Data_limit_c = input[7];
1585 activity_monitor.Gfx_PD_Data_error_coeff = input[8];
1586 activity_monitor.Gfx_PD_Data_error_rate_coeff = input[9];
1587 break;
1588 case 1: /* Uclk */
1589 activity_monitor.Mem_FPS = input[1];
1590 activity_monitor.Mem_UseRlcBusy = input[2];
1591 activity_monitor.Mem_MinActiveFreqType = input[3];
1592 activity_monitor.Mem_MinActiveFreq = input[4];
1593 activity_monitor.Mem_BoosterFreqType = input[5];
1594 activity_monitor.Mem_BoosterFreq = input[6];
1595 activity_monitor.Mem_PD_Data_limit_c = input[7];
1596 activity_monitor.Mem_PD_Data_error_coeff = input[8];
1597 activity_monitor.Mem_PD_Data_error_rate_coeff = input[9];
1598 break;
1599 }
1600
1601 ret = smu_update_table(smu,
1602 SMU_TABLE_ACTIVITY_MONITOR_COEFF,
1603 WORKLOAD_PPLIB_CUSTOM_BIT,
1604 (void *)(&activity_monitor),
1605 true);
1606 if (ret) {
d9811cfc 1607 dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);
18d7ab98
EQ
1608 return ret;
1609 }
1610 }
1611
7aa3f675
EQ
1612 /*
1613 * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT
1614 * Not all profile modes are supported on arcturus.
1615 */
1616 workload_type = smu_workload_get_type(smu, profile_mode);
1617 if (workload_type < 0) {
d9811cfc 1618 dev_err(smu->adev->dev, "Unsupported power profile mode %d on arcturus\n", profile_mode);
7aa3f675
EQ
1619 return -EINVAL;
1620 }
1621
1622 ret = smu_send_smc_msg_with_param(smu,
1623 SMU_MSG_SetWorkloadMask,
1c58267c
MC
1624 1 << workload_type,
1625 NULL);
7aa3f675 1626 if (ret) {
d9811cfc 1627 dev_err(smu->adev->dev, "Fail to set workload type %d\n", workload_type);
7aa3f675
EQ
1628 return ret;
1629 }
1630
1631 smu->power_profile_mode = profile_mode;
1632
1633 return 0;
1634}
1635
1744fb23
EQ
1636static int arcturus_set_performance_level(struct smu_context *smu,
1637 enum amd_dpm_forced_level level)
1638{
1639 uint32_t smu_version;
1640 int ret;
1641
1642 ret = smu_get_smc_version(smu, NULL, &smu_version);
1643 if (ret) {
d9811cfc 1644 dev_err(smu->adev->dev, "Failed to get smu version!\n");
1744fb23
EQ
1645 return ret;
1646 }
1647
1648 switch (level) {
1649 case AMD_DPM_FORCED_LEVEL_HIGH:
1650 case AMD_DPM_FORCED_LEVEL_LOW:
1651 case AMD_DPM_FORCED_LEVEL_PROFILE_STANDARD:
1652 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK:
1653 case AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK:
1654 case AMD_DPM_FORCED_LEVEL_PROFILE_PEAK:
1655 if (smu_version >= 0x361200) {
d9811cfc 1656 dev_err(smu->adev->dev, "Forcing clock level is not supported with "
1744fb23
EQ
1657 "54.18 and onwards SMU firmwares\n");
1658 return -EOPNOTSUPP;
1659 }
1660 break;
1661 default:
1662 break;
1663 }
1664
1665 return smu_v11_0_set_performance_level(smu, level);
1666}
1667
a94235af
EQ
1668static void arcturus_dump_pptable(struct smu_context *smu)
1669{
1670 struct smu_table_context *table_context = &smu->smu_table;
1671 PPTable_t *pptable = table_context->driver_pptable;
1672 int i;
1673
d9811cfc 1674 dev_info(smu->adev->dev, "Dumped PPTable:\n");
a94235af 1675
d9811cfc 1676 dev_info(smu->adev->dev, "Version = 0x%08x\n", pptable->Version);
a94235af 1677
d9811cfc
EQ
1678 dev_info(smu->adev->dev, "FeaturesToRun[0] = 0x%08x\n", pptable->FeaturesToRun[0]);
1679 dev_info(smu->adev->dev, "FeaturesToRun[1] = 0x%08x\n", pptable->FeaturesToRun[1]);
a94235af
EQ
1680
1681 for (i = 0; i < PPT_THROTTLER_COUNT; i++) {
d9811cfc
EQ
1682 dev_info(smu->adev->dev, "SocketPowerLimitAc[%d] = %d\n", i, pptable->SocketPowerLimitAc[i]);
1683 dev_info(smu->adev->dev, "SocketPowerLimitAcTau[%d] = %d\n", i, pptable->SocketPowerLimitAcTau[i]);
a94235af
EQ
1684 }
1685
d9811cfc
EQ
1686 dev_info(smu->adev->dev, "TdcLimitSoc = %d\n", pptable->TdcLimitSoc);
1687 dev_info(smu->adev->dev, "TdcLimitSocTau = %d\n", pptable->TdcLimitSocTau);
1688 dev_info(smu->adev->dev, "TdcLimitGfx = %d\n", pptable->TdcLimitGfx);
1689 dev_info(smu->adev->dev, "TdcLimitGfxTau = %d\n", pptable->TdcLimitGfxTau);
a94235af 1690
d9811cfc
EQ
1691 dev_info(smu->adev->dev, "TedgeLimit = %d\n", pptable->TedgeLimit);
1692 dev_info(smu->adev->dev, "ThotspotLimit = %d\n", pptable->ThotspotLimit);
1693 dev_info(smu->adev->dev, "TmemLimit = %d\n", pptable->TmemLimit);
1694 dev_info(smu->adev->dev, "Tvr_gfxLimit = %d\n", pptable->Tvr_gfxLimit);
1695 dev_info(smu->adev->dev, "Tvr_memLimit = %d\n", pptable->Tvr_memLimit);
1696 dev_info(smu->adev->dev, "Tvr_socLimit = %d\n", pptable->Tvr_socLimit);
1697 dev_info(smu->adev->dev, "FitLimit = %d\n", pptable->FitLimit);
a94235af 1698
d9811cfc
EQ
1699 dev_info(smu->adev->dev, "PpmPowerLimit = %d\n", pptable->PpmPowerLimit);
1700 dev_info(smu->adev->dev, "PpmTemperatureThreshold = %d\n", pptable->PpmTemperatureThreshold);
a94235af 1701
d9811cfc 1702 dev_info(smu->adev->dev, "ThrottlerControlMask = %d\n", pptable->ThrottlerControlMask);
a94235af 1703
d9811cfc
EQ
1704 dev_info(smu->adev->dev, "UlvVoltageOffsetGfx = %d\n", pptable->UlvVoltageOffsetGfx);
1705 dev_info(smu->adev->dev, "UlvPadding = 0x%08x\n", pptable->UlvPadding);
a94235af 1706
d9811cfc
EQ
1707 dev_info(smu->adev->dev, "UlvGfxclkBypass = %d\n", pptable->UlvGfxclkBypass);
1708 dev_info(smu->adev->dev, "Padding234[0] = 0x%02x\n", pptable->Padding234[0]);
1709 dev_info(smu->adev->dev, "Padding234[1] = 0x%02x\n", pptable->Padding234[1]);
1710 dev_info(smu->adev->dev, "Padding234[2] = 0x%02x\n", pptable->Padding234[2]);
a94235af 1711
d9811cfc
EQ
1712 dev_info(smu->adev->dev, "MinVoltageGfx = %d\n", pptable->MinVoltageGfx);
1713 dev_info(smu->adev->dev, "MinVoltageSoc = %d\n", pptable->MinVoltageSoc);
1714 dev_info(smu->adev->dev, "MaxVoltageGfx = %d\n", pptable->MaxVoltageGfx);
1715 dev_info(smu->adev->dev, "MaxVoltageSoc = %d\n", pptable->MaxVoltageSoc);
a94235af 1716
d9811cfc
EQ
1717 dev_info(smu->adev->dev, "LoadLineResistanceGfx = %d\n", pptable->LoadLineResistanceGfx);
1718 dev_info(smu->adev->dev, "LoadLineResistanceSoc = %d\n", pptable->LoadLineResistanceSoc);
a94235af 1719
d9811cfc 1720 dev_info(smu->adev->dev, "[PPCLK_GFXCLK]\n"
a94235af
EQ
1721 " .VoltageMode = 0x%02x\n"
1722 " .SnapToDiscrete = 0x%02x\n"
1723 " .NumDiscreteLevels = 0x%02x\n"
1724 " .padding = 0x%02x\n"
1725 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1726 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1727 " .SsFmin = 0x%04x\n"
1728 " .Padding_16 = 0x%04x\n",
1729 pptable->DpmDescriptor[PPCLK_GFXCLK].VoltageMode,
1730 pptable->DpmDescriptor[PPCLK_GFXCLK].SnapToDiscrete,
1731 pptable->DpmDescriptor[PPCLK_GFXCLK].NumDiscreteLevels,
1732 pptable->DpmDescriptor[PPCLK_GFXCLK].padding,
1733 pptable->DpmDescriptor[PPCLK_GFXCLK].ConversionToAvfsClk.m,
1734 pptable->DpmDescriptor[PPCLK_GFXCLK].ConversionToAvfsClk.b,
1735 pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.a,
1736 pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.b,
1737 pptable->DpmDescriptor[PPCLK_GFXCLK].SsCurve.c,
1738 pptable->DpmDescriptor[PPCLK_GFXCLK].SsFmin,
1739 pptable->DpmDescriptor[PPCLK_GFXCLK].Padding16);
1740
d9811cfc 1741 dev_info(smu->adev->dev, "[PPCLK_VCLK]\n"
a94235af
EQ
1742 " .VoltageMode = 0x%02x\n"
1743 " .SnapToDiscrete = 0x%02x\n"
1744 " .NumDiscreteLevels = 0x%02x\n"
1745 " .padding = 0x%02x\n"
1746 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1747 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1748 " .SsFmin = 0x%04x\n"
1749 " .Padding_16 = 0x%04x\n",
1750 pptable->DpmDescriptor[PPCLK_VCLK].VoltageMode,
1751 pptable->DpmDescriptor[PPCLK_VCLK].SnapToDiscrete,
1752 pptable->DpmDescriptor[PPCLK_VCLK].NumDiscreteLevels,
1753 pptable->DpmDescriptor[PPCLK_VCLK].padding,
1754 pptable->DpmDescriptor[PPCLK_VCLK].ConversionToAvfsClk.m,
1755 pptable->DpmDescriptor[PPCLK_VCLK].ConversionToAvfsClk.b,
1756 pptable->DpmDescriptor[PPCLK_VCLK].SsCurve.a,
1757 pptable->DpmDescriptor[PPCLK_VCLK].SsCurve.b,
1758 pptable->DpmDescriptor[PPCLK_VCLK].SsCurve.c,
1759 pptable->DpmDescriptor[PPCLK_VCLK].SsFmin,
1760 pptable->DpmDescriptor[PPCLK_VCLK].Padding16);
1761
d9811cfc 1762 dev_info(smu->adev->dev, "[PPCLK_DCLK]\n"
a94235af
EQ
1763 " .VoltageMode = 0x%02x\n"
1764 " .SnapToDiscrete = 0x%02x\n"
1765 " .NumDiscreteLevels = 0x%02x\n"
1766 " .padding = 0x%02x\n"
1767 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1768 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1769 " .SsFmin = 0x%04x\n"
1770 " .Padding_16 = 0x%04x\n",
1771 pptable->DpmDescriptor[PPCLK_DCLK].VoltageMode,
1772 pptable->DpmDescriptor[PPCLK_DCLK].SnapToDiscrete,
1773 pptable->DpmDescriptor[PPCLK_DCLK].NumDiscreteLevels,
1774 pptable->DpmDescriptor[PPCLK_DCLK].padding,
1775 pptable->DpmDescriptor[PPCLK_DCLK].ConversionToAvfsClk.m,
1776 pptable->DpmDescriptor[PPCLK_DCLK].ConversionToAvfsClk.b,
1777 pptable->DpmDescriptor[PPCLK_DCLK].SsCurve.a,
1778 pptable->DpmDescriptor[PPCLK_DCLK].SsCurve.b,
1779 pptable->DpmDescriptor[PPCLK_DCLK].SsCurve.c,
1780 pptable->DpmDescriptor[PPCLK_DCLK].SsFmin,
1781 pptable->DpmDescriptor[PPCLK_DCLK].Padding16);
1782
d9811cfc 1783 dev_info(smu->adev->dev, "[PPCLK_SOCCLK]\n"
a94235af
EQ
1784 " .VoltageMode = 0x%02x\n"
1785 " .SnapToDiscrete = 0x%02x\n"
1786 " .NumDiscreteLevels = 0x%02x\n"
1787 " .padding = 0x%02x\n"
1788 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1789 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1790 " .SsFmin = 0x%04x\n"
1791 " .Padding_16 = 0x%04x\n",
1792 pptable->DpmDescriptor[PPCLK_SOCCLK].VoltageMode,
1793 pptable->DpmDescriptor[PPCLK_SOCCLK].SnapToDiscrete,
1794 pptable->DpmDescriptor[PPCLK_SOCCLK].NumDiscreteLevels,
1795 pptable->DpmDescriptor[PPCLK_SOCCLK].padding,
1796 pptable->DpmDescriptor[PPCLK_SOCCLK].ConversionToAvfsClk.m,
1797 pptable->DpmDescriptor[PPCLK_SOCCLK].ConversionToAvfsClk.b,
1798 pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.a,
1799 pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.b,
1800 pptable->DpmDescriptor[PPCLK_SOCCLK].SsCurve.c,
1801 pptable->DpmDescriptor[PPCLK_SOCCLK].SsFmin,
1802 pptable->DpmDescriptor[PPCLK_SOCCLK].Padding16);
1803
d9811cfc 1804 dev_info(smu->adev->dev, "[PPCLK_UCLK]\n"
a94235af
EQ
1805 " .VoltageMode = 0x%02x\n"
1806 " .SnapToDiscrete = 0x%02x\n"
1807 " .NumDiscreteLevels = 0x%02x\n"
1808 " .padding = 0x%02x\n"
1809 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1810 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1811 " .SsFmin = 0x%04x\n"
1812 " .Padding_16 = 0x%04x\n",
1813 pptable->DpmDescriptor[PPCLK_UCLK].VoltageMode,
1814 pptable->DpmDescriptor[PPCLK_UCLK].SnapToDiscrete,
1815 pptable->DpmDescriptor[PPCLK_UCLK].NumDiscreteLevels,
1816 pptable->DpmDescriptor[PPCLK_UCLK].padding,
1817 pptable->DpmDescriptor[PPCLK_UCLK].ConversionToAvfsClk.m,
1818 pptable->DpmDescriptor[PPCLK_UCLK].ConversionToAvfsClk.b,
1819 pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.a,
1820 pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.b,
1821 pptable->DpmDescriptor[PPCLK_UCLK].SsCurve.c,
1822 pptable->DpmDescriptor[PPCLK_UCLK].SsFmin,
1823 pptable->DpmDescriptor[PPCLK_UCLK].Padding16);
1824
d9811cfc 1825 dev_info(smu->adev->dev, "[PPCLK_FCLK]\n"
a94235af
EQ
1826 " .VoltageMode = 0x%02x\n"
1827 " .SnapToDiscrete = 0x%02x\n"
1828 " .NumDiscreteLevels = 0x%02x\n"
1829 " .padding = 0x%02x\n"
1830 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1831 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1832 " .SsFmin = 0x%04x\n"
1833 " .Padding_16 = 0x%04x\n",
1834 pptable->DpmDescriptor[PPCLK_FCLK].VoltageMode,
1835 pptable->DpmDescriptor[PPCLK_FCLK].SnapToDiscrete,
1836 pptable->DpmDescriptor[PPCLK_FCLK].NumDiscreteLevels,
1837 pptable->DpmDescriptor[PPCLK_FCLK].padding,
1838 pptable->DpmDescriptor[PPCLK_FCLK].ConversionToAvfsClk.m,
1839 pptable->DpmDescriptor[PPCLK_FCLK].ConversionToAvfsClk.b,
1840 pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.a,
1841 pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.b,
1842 pptable->DpmDescriptor[PPCLK_FCLK].SsCurve.c,
1843 pptable->DpmDescriptor[PPCLK_FCLK].SsFmin,
1844 pptable->DpmDescriptor[PPCLK_FCLK].Padding16);
1845
1846
d9811cfc 1847 dev_info(smu->adev->dev, "FreqTableGfx\n");
a94235af 1848 for (i = 0; i < NUM_GFXCLK_DPM_LEVELS; i++)
d9811cfc 1849 dev_info(smu->adev->dev, " .[%02d] = %d\n", i, pptable->FreqTableGfx[i]);
a94235af 1850
d9811cfc 1851 dev_info(smu->adev->dev, "FreqTableVclk\n");
a94235af 1852 for (i = 0; i < NUM_VCLK_DPM_LEVELS; i++)
d9811cfc 1853 dev_info(smu->adev->dev, " .[%02d] = %d\n", i, pptable->FreqTableVclk[i]);
a94235af 1854
d9811cfc 1855 dev_info(smu->adev->dev, "FreqTableDclk\n");
a94235af 1856 for (i = 0; i < NUM_DCLK_DPM_LEVELS; i++)
d9811cfc 1857 dev_info(smu->adev->dev, " .[%02d] = %d\n", i, pptable->FreqTableDclk[i]);
a94235af 1858
d9811cfc 1859 dev_info(smu->adev->dev, "FreqTableSocclk\n");
a94235af 1860 for (i = 0; i < NUM_SOCCLK_DPM_LEVELS; i++)
d9811cfc 1861 dev_info(smu->adev->dev, " .[%02d] = %d\n", i, pptable->FreqTableSocclk[i]);
a94235af 1862
d9811cfc 1863 dev_info(smu->adev->dev, "FreqTableUclk\n");
a94235af 1864 for (i = 0; i < NUM_UCLK_DPM_LEVELS; i++)
d9811cfc 1865 dev_info(smu->adev->dev, " .[%02d] = %d\n", i, pptable->FreqTableUclk[i]);
a94235af 1866
d9811cfc 1867 dev_info(smu->adev->dev, "FreqTableFclk\n");
a94235af 1868 for (i = 0; i < NUM_FCLK_DPM_LEVELS; i++)
d9811cfc 1869 dev_info(smu->adev->dev, " .[%02d] = %d\n", i, pptable->FreqTableFclk[i]);
a94235af 1870
d9811cfc 1871 dev_info(smu->adev->dev, "Mp0clkFreq\n");
a94235af 1872 for (i = 0; i < NUM_MP0CLK_DPM_LEVELS; i++)
d9811cfc 1873 dev_info(smu->adev->dev, " .[%d] = %d\n", i, pptable->Mp0clkFreq[i]);
a94235af 1874
d9811cfc 1875 dev_info(smu->adev->dev, "Mp0DpmVoltage\n");
a94235af 1876 for (i = 0; i < NUM_MP0CLK_DPM_LEVELS; i++)
d9811cfc
EQ
1877 dev_info(smu->adev->dev, " .[%d] = %d\n", i, pptable->Mp0DpmVoltage[i]);
1878
1879 dev_info(smu->adev->dev, "GfxclkFidle = 0x%x\n", pptable->GfxclkFidle);
1880 dev_info(smu->adev->dev, "GfxclkSlewRate = 0x%x\n", pptable->GfxclkSlewRate);
1881 dev_info(smu->adev->dev, "Padding567[0] = 0x%x\n", pptable->Padding567[0]);
1882 dev_info(smu->adev->dev, "Padding567[1] = 0x%x\n", pptable->Padding567[1]);
1883 dev_info(smu->adev->dev, "Padding567[2] = 0x%x\n", pptable->Padding567[2]);
1884 dev_info(smu->adev->dev, "Padding567[3] = 0x%x\n", pptable->Padding567[3]);
1885 dev_info(smu->adev->dev, "GfxclkDsMaxFreq = %d\n", pptable->GfxclkDsMaxFreq);
1886 dev_info(smu->adev->dev, "GfxclkSource = 0x%x\n", pptable->GfxclkSource);
1887 dev_info(smu->adev->dev, "Padding456 = 0x%x\n", pptable->Padding456);
1888
1889 dev_info(smu->adev->dev, "EnableTdpm = %d\n", pptable->EnableTdpm);
1890 dev_info(smu->adev->dev, "TdpmHighHystTemperature = %d\n", pptable->TdpmHighHystTemperature);
1891 dev_info(smu->adev->dev, "TdpmLowHystTemperature = %d\n", pptable->TdpmLowHystTemperature);
1892 dev_info(smu->adev->dev, "GfxclkFreqHighTempLimit = %d\n", pptable->GfxclkFreqHighTempLimit);
1893
1894 dev_info(smu->adev->dev, "FanStopTemp = %d\n", pptable->FanStopTemp);
1895 dev_info(smu->adev->dev, "FanStartTemp = %d\n", pptable->FanStartTemp);
1896
1897 dev_info(smu->adev->dev, "FanGainEdge = %d\n", pptable->FanGainEdge);
1898 dev_info(smu->adev->dev, "FanGainHotspot = %d\n", pptable->FanGainHotspot);
1899 dev_info(smu->adev->dev, "FanGainVrGfx = %d\n", pptable->FanGainVrGfx);
1900 dev_info(smu->adev->dev, "FanGainVrSoc = %d\n", pptable->FanGainVrSoc);
1901 dev_info(smu->adev->dev, "FanGainVrMem = %d\n", pptable->FanGainVrMem);
1902 dev_info(smu->adev->dev, "FanGainHbm = %d\n", pptable->FanGainHbm);
1903
1904 dev_info(smu->adev->dev, "FanPwmMin = %d\n", pptable->FanPwmMin);
1905 dev_info(smu->adev->dev, "FanAcousticLimitRpm = %d\n", pptable->FanAcousticLimitRpm);
1906 dev_info(smu->adev->dev, "FanThrottlingRpm = %d\n", pptable->FanThrottlingRpm);
1907 dev_info(smu->adev->dev, "FanMaximumRpm = %d\n", pptable->FanMaximumRpm);
1908 dev_info(smu->adev->dev, "FanTargetTemperature = %d\n", pptable->FanTargetTemperature);
1909 dev_info(smu->adev->dev, "FanTargetGfxclk = %d\n", pptable->FanTargetGfxclk);
1910 dev_info(smu->adev->dev, "FanZeroRpmEnable = %d\n", pptable->FanZeroRpmEnable);
1911 dev_info(smu->adev->dev, "FanTachEdgePerRev = %d\n", pptable->FanTachEdgePerRev);
1912 dev_info(smu->adev->dev, "FanTempInputSelect = %d\n", pptable->FanTempInputSelect);
1913
1914 dev_info(smu->adev->dev, "FuzzyFan_ErrorSetDelta = %d\n", pptable->FuzzyFan_ErrorSetDelta);
1915 dev_info(smu->adev->dev, "FuzzyFan_ErrorRateSetDelta = %d\n", pptable->FuzzyFan_ErrorRateSetDelta);
1916 dev_info(smu->adev->dev, "FuzzyFan_PwmSetDelta = %d\n", pptable->FuzzyFan_PwmSetDelta);
1917 dev_info(smu->adev->dev, "FuzzyFan_Reserved = %d\n", pptable->FuzzyFan_Reserved);
1918
1919 dev_info(smu->adev->dev, "OverrideAvfsGb[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->OverrideAvfsGb[AVFS_VOLTAGE_GFX]);
1920 dev_info(smu->adev->dev, "OverrideAvfsGb[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->OverrideAvfsGb[AVFS_VOLTAGE_SOC]);
1921 dev_info(smu->adev->dev, "Padding8_Avfs[0] = %d\n", pptable->Padding8_Avfs[0]);
1922 dev_info(smu->adev->dev, "Padding8_Avfs[1] = %d\n", pptable->Padding8_Avfs[1]);
1923
1924 dev_info(smu->adev->dev, "dBtcGbGfxPll{a = 0x%x b = 0x%x c = 0x%x}\n",
a94235af
EQ
1925 pptable->dBtcGbGfxPll.a,
1926 pptable->dBtcGbGfxPll.b,
1927 pptable->dBtcGbGfxPll.c);
d9811cfc 1928 dev_info(smu->adev->dev, "dBtcGbGfxAfll{a = 0x%x b = 0x%x c = 0x%x}\n",
a94235af
EQ
1929 pptable->dBtcGbGfxAfll.a,
1930 pptable->dBtcGbGfxAfll.b,
1931 pptable->dBtcGbGfxAfll.c);
d9811cfc 1932 dev_info(smu->adev->dev, "dBtcGbSoc{a = 0x%x b = 0x%x c = 0x%x}\n",
a94235af
EQ
1933 pptable->dBtcGbSoc.a,
1934 pptable->dBtcGbSoc.b,
1935 pptable->dBtcGbSoc.c);
1936
d9811cfc 1937 dev_info(smu->adev->dev, "qAgingGb[AVFS_VOLTAGE_GFX]{m = 0x%x b = 0x%x}\n",
a94235af
EQ
1938 pptable->qAgingGb[AVFS_VOLTAGE_GFX].m,
1939 pptable->qAgingGb[AVFS_VOLTAGE_GFX].b);
d9811cfc 1940 dev_info(smu->adev->dev, "qAgingGb[AVFS_VOLTAGE_SOC]{m = 0x%x b = 0x%x}\n",
a94235af
EQ
1941 pptable->qAgingGb[AVFS_VOLTAGE_SOC].m,
1942 pptable->qAgingGb[AVFS_VOLTAGE_SOC].b);
1943
d9811cfc 1944 dev_info(smu->adev->dev, "qStaticVoltageOffset[AVFS_VOLTAGE_GFX]{a = 0x%x b = 0x%x c = 0x%x}\n",
a94235af
EQ
1945 pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].a,
1946 pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].b,
1947 pptable->qStaticVoltageOffset[AVFS_VOLTAGE_GFX].c);
d9811cfc 1948 dev_info(smu->adev->dev, "qStaticVoltageOffset[AVFS_VOLTAGE_SOC]{a = 0x%x b = 0x%x c = 0x%x}\n",
a94235af
EQ
1949 pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].a,
1950 pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].b,
1951 pptable->qStaticVoltageOffset[AVFS_VOLTAGE_SOC].c);
1952
d9811cfc
EQ
1953 dev_info(smu->adev->dev, "DcTol[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcTol[AVFS_VOLTAGE_GFX]);
1954 dev_info(smu->adev->dev, "DcTol[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcTol[AVFS_VOLTAGE_SOC]);
a94235af 1955
d9811cfc
EQ
1956 dev_info(smu->adev->dev, "DcBtcEnabled[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcEnabled[AVFS_VOLTAGE_GFX]);
1957 dev_info(smu->adev->dev, "DcBtcEnabled[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcEnabled[AVFS_VOLTAGE_SOC]);
1958 dev_info(smu->adev->dev, "Padding8_GfxBtc[0] = 0x%x\n", pptable->Padding8_GfxBtc[0]);
1959 dev_info(smu->adev->dev, "Padding8_GfxBtc[1] = 0x%x\n", pptable->Padding8_GfxBtc[1]);
a94235af 1960
d9811cfc
EQ
1961 dev_info(smu->adev->dev, "DcBtcMin[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcMin[AVFS_VOLTAGE_GFX]);
1962 dev_info(smu->adev->dev, "DcBtcMin[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcMin[AVFS_VOLTAGE_SOC]);
1963 dev_info(smu->adev->dev, "DcBtcMax[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcMax[AVFS_VOLTAGE_GFX]);
1964 dev_info(smu->adev->dev, "DcBtcMax[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcMax[AVFS_VOLTAGE_SOC]);
a94235af 1965
d9811cfc
EQ
1966 dev_info(smu->adev->dev, "DcBtcGb[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable->DcBtcGb[AVFS_VOLTAGE_GFX]);
1967 dev_info(smu->adev->dev, "DcBtcGb[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable->DcBtcGb[AVFS_VOLTAGE_SOC]);
a94235af 1968
d9811cfc 1969 dev_info(smu->adev->dev, "XgmiDpmPstates\n");
a94235af 1970 for (i = 0; i < NUM_XGMI_LEVELS; i++)
d9811cfc
EQ
1971 dev_info(smu->adev->dev, " .[%d] = %d\n", i, pptable->XgmiDpmPstates[i]);
1972 dev_info(smu->adev->dev, "XgmiDpmSpare[0] = 0x%02x\n", pptable->XgmiDpmSpare[0]);
1973 dev_info(smu->adev->dev, "XgmiDpmSpare[1] = 0x%02x\n", pptable->XgmiDpmSpare[1]);
1974
1975 dev_info(smu->adev->dev, "VDDGFX_TVmin = %d\n", pptable->VDDGFX_TVmin);
1976 dev_info(smu->adev->dev, "VDDSOC_TVmin = %d\n", pptable->VDDSOC_TVmin);
1977 dev_info(smu->adev->dev, "VDDGFX_Vmin_HiTemp = %d\n", pptable->VDDGFX_Vmin_HiTemp);
1978 dev_info(smu->adev->dev, "VDDGFX_Vmin_LoTemp = %d\n", pptable->VDDGFX_Vmin_LoTemp);
1979 dev_info(smu->adev->dev, "VDDSOC_Vmin_HiTemp = %d\n", pptable->VDDSOC_Vmin_HiTemp);
1980 dev_info(smu->adev->dev, "VDDSOC_Vmin_LoTemp = %d\n", pptable->VDDSOC_Vmin_LoTemp);
1981 dev_info(smu->adev->dev, "VDDGFX_TVminHystersis = %d\n", pptable->VDDGFX_TVminHystersis);
1982 dev_info(smu->adev->dev, "VDDSOC_TVminHystersis = %d\n", pptable->VDDSOC_TVminHystersis);
1983
1984 dev_info(smu->adev->dev, "DebugOverrides = 0x%x\n", pptable->DebugOverrides);
1985 dev_info(smu->adev->dev, "ReservedEquation0{a = 0x%x b = 0x%x c = 0x%x}\n",
a94235af
EQ
1986 pptable->ReservedEquation0.a,
1987 pptable->ReservedEquation0.b,
1988 pptable->ReservedEquation0.c);
d9811cfc 1989 dev_info(smu->adev->dev, "ReservedEquation1{a = 0x%x b = 0x%x c = 0x%x}\n",
a94235af
EQ
1990 pptable->ReservedEquation1.a,
1991 pptable->ReservedEquation1.b,
1992 pptable->ReservedEquation1.c);
d9811cfc 1993 dev_info(smu->adev->dev, "ReservedEquation2{a = 0x%x b = 0x%x c = 0x%x}\n",
a94235af
EQ
1994 pptable->ReservedEquation2.a,
1995 pptable->ReservedEquation2.b,
1996 pptable->ReservedEquation2.c);
d9811cfc 1997 dev_info(smu->adev->dev, "ReservedEquation3{a = 0x%x b = 0x%x c = 0x%x}\n",
a94235af
EQ
1998 pptable->ReservedEquation3.a,
1999 pptable->ReservedEquation3.b,
2000 pptable->ReservedEquation3.c);
2001
d9811cfc
EQ
2002 dev_info(smu->adev->dev, "MinVoltageUlvGfx = %d\n", pptable->MinVoltageUlvGfx);
2003 dev_info(smu->adev->dev, "PaddingUlv = %d\n", pptable->PaddingUlv);
a94235af 2004
d9811cfc
EQ
2005 dev_info(smu->adev->dev, "TotalPowerConfig = %d\n", pptable->TotalPowerConfig);
2006 dev_info(smu->adev->dev, "TotalPowerSpare1 = %d\n", pptable->TotalPowerSpare1);
2007 dev_info(smu->adev->dev, "TotalPowerSpare2 = %d\n", pptable->TotalPowerSpare2);
a94235af 2008
d9811cfc
EQ
2009 dev_info(smu->adev->dev, "PccThresholdLow = %d\n", pptable->PccThresholdLow);
2010 dev_info(smu->adev->dev, "PccThresholdHigh = %d\n", pptable->PccThresholdHigh);
a94235af 2011
d9811cfc
EQ
2012 dev_info(smu->adev->dev, "Board Parameters:\n");
2013 dev_info(smu->adev->dev, "MaxVoltageStepGfx = 0x%x\n", pptable->MaxVoltageStepGfx);
2014 dev_info(smu->adev->dev, "MaxVoltageStepSoc = 0x%x\n", pptable->MaxVoltageStepSoc);
a94235af 2015
d9811cfc
EQ
2016 dev_info(smu->adev->dev, "VddGfxVrMapping = 0x%x\n", pptable->VddGfxVrMapping);
2017 dev_info(smu->adev->dev, "VddSocVrMapping = 0x%x\n", pptable->VddSocVrMapping);
2018 dev_info(smu->adev->dev, "VddMemVrMapping = 0x%x\n", pptable->VddMemVrMapping);
2019 dev_info(smu->adev->dev, "BoardVrMapping = 0x%x\n", pptable->BoardVrMapping);
a94235af 2020
d9811cfc
EQ
2021 dev_info(smu->adev->dev, "GfxUlvPhaseSheddingMask = 0x%x\n", pptable->GfxUlvPhaseSheddingMask);
2022 dev_info(smu->adev->dev, "ExternalSensorPresent = 0x%x\n", pptable->ExternalSensorPresent);
a94235af 2023
d9811cfc
EQ
2024 dev_info(smu->adev->dev, "GfxMaxCurrent = 0x%x\n", pptable->GfxMaxCurrent);
2025 dev_info(smu->adev->dev, "GfxOffset = 0x%x\n", pptable->GfxOffset);
2026 dev_info(smu->adev->dev, "Padding_TelemetryGfx = 0x%x\n", pptable->Padding_TelemetryGfx);
a94235af 2027
d9811cfc
EQ
2028 dev_info(smu->adev->dev, "SocMaxCurrent = 0x%x\n", pptable->SocMaxCurrent);
2029 dev_info(smu->adev->dev, "SocOffset = 0x%x\n", pptable->SocOffset);
2030 dev_info(smu->adev->dev, "Padding_TelemetrySoc = 0x%x\n", pptable->Padding_TelemetrySoc);
a94235af 2031
d9811cfc
EQ
2032 dev_info(smu->adev->dev, "MemMaxCurrent = 0x%x\n", pptable->MemMaxCurrent);
2033 dev_info(smu->adev->dev, "MemOffset = 0x%x\n", pptable->MemOffset);
2034 dev_info(smu->adev->dev, "Padding_TelemetryMem = 0x%x\n", pptable->Padding_TelemetryMem);
a94235af 2035
d9811cfc
EQ
2036 dev_info(smu->adev->dev, "BoardMaxCurrent = 0x%x\n", pptable->BoardMaxCurrent);
2037 dev_info(smu->adev->dev, "BoardOffset = 0x%x\n", pptable->BoardOffset);
2038 dev_info(smu->adev->dev, "Padding_TelemetryBoardInput = 0x%x\n", pptable->Padding_TelemetryBoardInput);
a94235af 2039
d9811cfc
EQ
2040 dev_info(smu->adev->dev, "VR0HotGpio = %d\n", pptable->VR0HotGpio);
2041 dev_info(smu->adev->dev, "VR0HotPolarity = %d\n", pptable->VR0HotPolarity);
2042 dev_info(smu->adev->dev, "VR1HotGpio = %d\n", pptable->VR1HotGpio);
2043 dev_info(smu->adev->dev, "VR1HotPolarity = %d\n", pptable->VR1HotPolarity);
a94235af 2044
d9811cfc
EQ
2045 dev_info(smu->adev->dev, "PllGfxclkSpreadEnabled = %d\n", pptable->PllGfxclkSpreadEnabled);
2046 dev_info(smu->adev->dev, "PllGfxclkSpreadPercent = %d\n", pptable->PllGfxclkSpreadPercent);
2047 dev_info(smu->adev->dev, "PllGfxclkSpreadFreq = %d\n", pptable->PllGfxclkSpreadFreq);
a94235af 2048
d9811cfc
EQ
2049 dev_info(smu->adev->dev, "UclkSpreadEnabled = %d\n", pptable->UclkSpreadEnabled);
2050 dev_info(smu->adev->dev, "UclkSpreadPercent = %d\n", pptable->UclkSpreadPercent);
2051 dev_info(smu->adev->dev, "UclkSpreadFreq = %d\n", pptable->UclkSpreadFreq);
a94235af 2052
d9811cfc
EQ
2053 dev_info(smu->adev->dev, "FclkSpreadEnabled = %d\n", pptable->FclkSpreadEnabled);
2054 dev_info(smu->adev->dev, "FclkSpreadPercent = %d\n", pptable->FclkSpreadPercent);
2055 dev_info(smu->adev->dev, "FclkSpreadFreq = %d\n", pptable->FclkSpreadFreq);
a94235af 2056
d9811cfc
EQ
2057 dev_info(smu->adev->dev, "FllGfxclkSpreadEnabled = %d\n", pptable->FllGfxclkSpreadEnabled);
2058 dev_info(smu->adev->dev, "FllGfxclkSpreadPercent = %d\n", pptable->FllGfxclkSpreadPercent);
2059 dev_info(smu->adev->dev, "FllGfxclkSpreadFreq = %d\n", pptable->FllGfxclkSpreadFreq);
a94235af
EQ
2060
2061 for (i = 0; i < NUM_I2C_CONTROLLERS; i++) {
d9811cfc
EQ
2062 dev_info(smu->adev->dev, "I2cControllers[%d]:\n", i);
2063 dev_info(smu->adev->dev, " .Enabled = %d\n",
a94235af 2064 pptable->I2cControllers[i].Enabled);
d9811cfc 2065 dev_info(smu->adev->dev, " .SlaveAddress = 0x%x\n",
a94235af 2066 pptable->I2cControllers[i].SlaveAddress);
d9811cfc 2067 dev_info(smu->adev->dev, " .ControllerPort = %d\n",
a94235af 2068 pptable->I2cControllers[i].ControllerPort);
d9811cfc 2069 dev_info(smu->adev->dev, " .ControllerName = %d\n",
a94235af 2070 pptable->I2cControllers[i].ControllerName);
d9811cfc 2071 dev_info(smu->adev->dev, " .ThermalThrottler = %d\n",
a94235af 2072 pptable->I2cControllers[i].ThermalThrotter);
d9811cfc 2073 dev_info(smu->adev->dev, " .I2cProtocol = %d\n",
a94235af 2074 pptable->I2cControllers[i].I2cProtocol);
d9811cfc 2075 dev_info(smu->adev->dev, " .Speed = %d\n",
a94235af
EQ
2076 pptable->I2cControllers[i].Speed);
2077 }
2078
d9811cfc
EQ
2079 dev_info(smu->adev->dev, "MemoryChannelEnabled = %d\n", pptable->MemoryChannelEnabled);
2080 dev_info(smu->adev->dev, "DramBitWidth = %d\n", pptable->DramBitWidth);
a94235af 2081
d9811cfc 2082 dev_info(smu->adev->dev, "TotalBoardPower = %d\n", pptable->TotalBoardPower);
a94235af 2083
d9811cfc 2084 dev_info(smu->adev->dev, "XgmiLinkSpeed\n");
a94235af 2085 for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
d9811cfc
EQ
2086 dev_info(smu->adev->dev, " .[%d] = %d\n", i, pptable->XgmiLinkSpeed[i]);
2087 dev_info(smu->adev->dev, "XgmiLinkWidth\n");
a94235af 2088 for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
d9811cfc
EQ
2089 dev_info(smu->adev->dev, " .[%d] = %d\n", i, pptable->XgmiLinkWidth[i]);
2090 dev_info(smu->adev->dev, "XgmiFclkFreq\n");
a94235af 2091 for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
d9811cfc
EQ
2092 dev_info(smu->adev->dev, " .[%d] = %d\n", i, pptable->XgmiFclkFreq[i]);
2093 dev_info(smu->adev->dev, "XgmiSocVoltage\n");
a94235af 2094 for (i = 0; i < NUM_XGMI_PSTATE_LEVELS; i++)
d9811cfc 2095 dev_info(smu->adev->dev, " .[%d] = %d\n", i, pptable->XgmiSocVoltage[i]);
a94235af
EQ
2096
2097}
2098
3f513bae
CG
2099static bool arcturus_is_dpm_running(struct smu_context *smu)
2100{
2101 int ret = 0;
2102 uint32_t feature_mask[2];
2103 unsigned long feature_enabled;
2104 ret = smu_feature_get_enabled_mask(smu, feature_mask, 2);
2105 feature_enabled = (unsigned long)((uint64_t)feature_mask[0] |
2106 ((uint64_t)feature_mask[1] << 32));
2107 return !!(feature_enabled & SMC_DPM_FEATURE);
2108}
2109
f6b4b4a1 2110static int arcturus_dpm_set_vcn_enable(struct smu_context *smu, bool enable)
5bcc9240
EQ
2111{
2112 struct smu_power_context *smu_power = &smu->smu_power;
2113 struct smu_power_gate *power_gate = &smu_power->power_gate;
2114 int ret = 0;
2115
2116 if (enable) {
2117 if (!smu_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
2118 ret = smu_feature_set_enabled(smu, SMU_FEATURE_VCN_PG_BIT, 1);
2119 if (ret) {
d9811cfc 2120 dev_err(smu->adev->dev, "[EnableVCNDPM] failed!\n");
5bcc9240
EQ
2121 return ret;
2122 }
2123 }
2124 power_gate->vcn_gated = false;
2125 } else {
2126 if (smu_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) {
2127 ret = smu_feature_set_enabled(smu, SMU_FEATURE_VCN_PG_BIT, 0);
2128 if (ret) {
d9811cfc 2129 dev_err(smu->adev->dev, "[DisableVCNDPM] failed!\n");
5bcc9240
EQ
2130 return ret;
2131 }
2132 }
2133 power_gate->vcn_gated = true;
2134 }
2135
2136 return ret;
2137}
2138
d1a84427
AG
2139
2140static void arcturus_fill_eeprom_i2c_req(SwI2cRequest_t *req, bool write,
2141 uint8_t address, uint32_t numbytes,
2142 uint8_t *data)
2143{
2144 int i;
2145
2146 BUG_ON(numbytes > MAX_SW_I2C_COMMANDS);
2147
2148 req->I2CcontrollerPort = 0;
2149 req->I2CSpeed = 2;
2150 req->SlaveAddress = address;
2151 req->NumCmds = numbytes;
2152
2153 for (i = 0; i < numbytes; i++) {
2154 SwI2cCmd_t *cmd = &req->SwI2cCmds[i];
2155
2156 /* First 2 bytes are always write for lower 2b EEPROM address */
2157 if (i < 2)
2158 cmd->Cmd = 1;
2159 else
2160 cmd->Cmd = write;
2161
2162
2163 /* Add RESTART for read after address filled */
2164 cmd->CmdConfig |= (i == 2 && !write) ? CMDCONFIG_RESTART_MASK : 0;
2165
2166 /* Add STOP in the end */
2167 cmd->CmdConfig |= (i == (numbytes - 1)) ? CMDCONFIG_STOP_MASK : 0;
2168
2169 /* Fill with data regardless if read or write to simplify code */
2170 cmd->RegisterAddr = data[i];
2171 }
2172}
2173
2174static int arcturus_i2c_eeprom_read_data(struct i2c_adapter *control,
2175 uint8_t address,
2176 uint8_t *data,
2177 uint32_t numbytes)
2178{
2179 uint32_t i, ret = 0;
2180 SwI2cRequest_t req;
2181 struct amdgpu_device *adev = to_amdgpu_device(control);
2182 struct smu_table_context *smu_table = &adev->smu.smu_table;
ce0d0ec3 2183 struct smu_table *table = &smu_table->driver_table;
d1a84427
AG
2184
2185 memset(&req, 0, sizeof(req));
2186 arcturus_fill_eeprom_i2c_req(&req, false, address, numbytes, data);
2187
2188 mutex_lock(&adev->smu.mutex);
2189 /* Now read data starting with that address */
2190 ret = smu_update_table(&adev->smu, SMU_TABLE_I2C_COMMANDS, 0, &req,
2191 true);
2192 mutex_unlock(&adev->smu.mutex);
2193
2194 if (!ret) {
2195 SwI2cRequest_t *res = (SwI2cRequest_t *)table->cpu_addr;
2196
2197 /* Assume SMU fills res.SwI2cCmds[i].Data with read bytes */
2198 for (i = 0; i < numbytes; i++)
2199 data[i] = res->SwI2cCmds[i].Data;
2200
d9811cfc 2201 dev_dbg(adev->dev, "arcturus_i2c_eeprom_read_data, address = %x, bytes = %d, data :",
d1a84427
AG
2202 (uint16_t)address, numbytes);
2203
2204 print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE,
2205 8, 1, data, numbytes, false);
2206 } else
d9811cfc 2207 dev_err(adev->dev, "arcturus_i2c_eeprom_read_data - error occurred :%x", ret);
d1a84427
AG
2208
2209 return ret;
2210}
2211
2212static int arcturus_i2c_eeprom_write_data(struct i2c_adapter *control,
2213 uint8_t address,
2214 uint8_t *data,
2215 uint32_t numbytes)
2216{
2217 uint32_t ret;
2218 SwI2cRequest_t req;
2219 struct amdgpu_device *adev = to_amdgpu_device(control);
2220
2221 memset(&req, 0, sizeof(req));
2222 arcturus_fill_eeprom_i2c_req(&req, true, address, numbytes, data);
2223
2224 mutex_lock(&adev->smu.mutex);
2225 ret = smu_update_table(&adev->smu, SMU_TABLE_I2C_COMMANDS, 0, &req, true);
2226 mutex_unlock(&adev->smu.mutex);
2227
2228 if (!ret) {
d9811cfc 2229 dev_dbg(adev->dev, "arcturus_i2c_write(), address = %x, bytes = %d , data: ",
d1a84427
AG
2230 (uint16_t)address, numbytes);
2231
2232 print_hex_dump(KERN_DEBUG, "data: ", DUMP_PREFIX_NONE,
2233 8, 1, data, numbytes, false);
2234 /*
2235 * According to EEPROM spec there is a MAX of 10 ms required for
2236 * EEPROM to flush internal RX buffer after STOP was issued at the
2237 * end of write transaction. During this time the EEPROM will not be
2238 * responsive to any more commands - so wait a bit more.
2239 */
2240 msleep(10);
2241
2242 } else
d9811cfc 2243 dev_err(adev->dev, "arcturus_i2c_write- error occurred :%x", ret);
d1a84427
AG
2244
2245 return ret;
2246}
2247
2248static int arcturus_i2c_eeprom_i2c_xfer(struct i2c_adapter *i2c_adap,
2249 struct i2c_msg *msgs, int num)
2250{
2251 uint32_t i, j, ret, data_size, data_chunk_size, next_eeprom_addr = 0;
2252 uint8_t *data_ptr, data_chunk[MAX_SW_I2C_COMMANDS] = { 0 };
2253
2254 for (i = 0; i < num; i++) {
2255 /*
2256 * SMU interface allows at most MAX_SW_I2C_COMMANDS bytes of data at
2257 * once and hence the data needs to be spliced into chunks and sent each
2258 * chunk separately
2259 */
2260 data_size = msgs[i].len - 2;
2261 data_chunk_size = MAX_SW_I2C_COMMANDS - 2;
2262 next_eeprom_addr = (msgs[i].buf[0] << 8 & 0xff00) | (msgs[i].buf[1] & 0xff);
2263 data_ptr = msgs[i].buf + 2;
2264
2265 for (j = 0; j < data_size / data_chunk_size; j++) {
2266 /* Insert the EEPROM dest addess, bits 0-15 */
2267 data_chunk[0] = ((next_eeprom_addr >> 8) & 0xff);
2268 data_chunk[1] = (next_eeprom_addr & 0xff);
2269
2270 if (msgs[i].flags & I2C_M_RD) {
2271 ret = arcturus_i2c_eeprom_read_data(i2c_adap,
2272 (uint8_t)msgs[i].addr,
2273 data_chunk, MAX_SW_I2C_COMMANDS);
2274
2275 memcpy(data_ptr, data_chunk + 2, data_chunk_size);
2276 } else {
2277
2278 memcpy(data_chunk + 2, data_ptr, data_chunk_size);
2279
2280 ret = arcturus_i2c_eeprom_write_data(i2c_adap,
2281 (uint8_t)msgs[i].addr,
2282 data_chunk, MAX_SW_I2C_COMMANDS);
2283 }
2284
2285 if (ret) {
2286 num = -EIO;
2287 goto fail;
2288 }
2289
2290 next_eeprom_addr += data_chunk_size;
2291 data_ptr += data_chunk_size;
2292 }
2293
2294 if (data_size % data_chunk_size) {
2295 data_chunk[0] = ((next_eeprom_addr >> 8) & 0xff);
2296 data_chunk[1] = (next_eeprom_addr & 0xff);
2297
2298 if (msgs[i].flags & I2C_M_RD) {
2299 ret = arcturus_i2c_eeprom_read_data(i2c_adap,
2300 (uint8_t)msgs[i].addr,
2301 data_chunk, (data_size % data_chunk_size) + 2);
2302
2303 memcpy(data_ptr, data_chunk + 2, data_size % data_chunk_size);
2304 } else {
2305 memcpy(data_chunk + 2, data_ptr, data_size % data_chunk_size);
2306
2307 ret = arcturus_i2c_eeprom_write_data(i2c_adap,
2308 (uint8_t)msgs[i].addr,
2309 data_chunk, (data_size % data_chunk_size) + 2);
2310 }
2311
2312 if (ret) {
2313 num = -EIO;
2314 goto fail;
2315 }
2316 }
2317 }
2318
2319fail:
2320 return num;
2321}
2322
2323static u32 arcturus_i2c_eeprom_i2c_func(struct i2c_adapter *adap)
2324{
2325 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
2326}
2327
2328
2329static const struct i2c_algorithm arcturus_i2c_eeprom_i2c_algo = {
2330 .master_xfer = arcturus_i2c_eeprom_i2c_xfer,
2331 .functionality = arcturus_i2c_eeprom_i2c_func,
2332};
2333
2cdc9c20
WS
2334static bool arcturus_i2c_adapter_is_added(struct i2c_adapter *control)
2335{
2336 struct amdgpu_device *adev = to_amdgpu_device(control);
2337
2338 return control->dev.parent == &adev->pdev->dev;
2339}
2340
b64919a2 2341static int arcturus_i2c_eeprom_control_init(struct i2c_adapter *control)
d1a84427
AG
2342{
2343 struct amdgpu_device *adev = to_amdgpu_device(control);
2344 int res;
2345
2cdc9c20
WS
2346 /* smu_i2c_eeprom_init may be called twice in sriov */
2347 if (arcturus_i2c_adapter_is_added(control))
2348 return 0;
2349
d1a84427
AG
2350 control->owner = THIS_MODULE;
2351 control->class = I2C_CLASS_SPD;
2352 control->dev.parent = &adev->pdev->dev;
2353 control->algo = &arcturus_i2c_eeprom_i2c_algo;
9015d60c 2354 snprintf(control->name, sizeof(control->name), "AMDGPU EEPROM");
d1a84427
AG
2355
2356 res = i2c_add_adapter(control);
2357 if (res)
2358 DRM_ERROR("Failed to register hw i2c, err: %d\n", res);
2359
2360 return res;
2361}
2362
b64919a2 2363static void arcturus_i2c_eeprom_control_fini(struct i2c_adapter *control)
d1a84427 2364{
2cdc9c20
WS
2365 if (!arcturus_i2c_adapter_is_added(control))
2366 return;
2367
d1a84427
AG
2368 i2c_del_adapter(control);
2369}
2370
81a16241
KR
2371static void arcturus_get_unique_id(struct smu_context *smu)
2372{
2373 struct amdgpu_device *adev = smu->adev;
2374 uint32_t top32, bottom32, smu_version, size;
2375 char sn[16];
2376 uint64_t id;
2377
2378 if (smu_get_smc_version(smu, NULL, &smu_version)) {
d9811cfc 2379 dev_warn(adev->dev, "Failed to get smu version, cannot get unique_id or serial_number\n");
81a16241
KR
2380 return;
2381 }
2382
2383 /* PPSMC_MSG_ReadSerial* is supported by 54.23.0 and onwards */
2384 if (smu_version < 0x361700) {
d9811cfc 2385 dev_warn(adev->dev, "ReadSerial is only supported by PMFW 54.23.0 and onwards\n");
81a16241
KR
2386 return;
2387 }
2388
2389 /* Get the SN to turn into a Unique ID */
2390 smu_send_smc_msg(smu, SMU_MSG_ReadSerialNumTop32, &top32);
2391 smu_send_smc_msg(smu, SMU_MSG_ReadSerialNumBottom32, &bottom32);
2392
2393 id = ((uint64_t)bottom32 << 32) | top32;
2394 adev->unique_id = id;
2395 /* For Arcturus-and-later, unique_id == serial_number, so convert it to a
2396 * 16-digit HEX string for convenience and backwards-compatibility
2397 */
2398 size = sprintf(sn, "%llx", id);
2399 memcpy(adev->serial, &sn, size);
2400}
2401
49e78c82
EQ
2402static bool arcturus_is_baco_supported(struct smu_context *smu)
2403{
2404 struct amdgpu_device *adev = smu->adev;
2405 uint32_t val;
2406
feb000fd 2407 if (!smu_v11_0_baco_is_support(smu) || amdgpu_sriov_vf(adev))
49e78c82
EQ
2408 return false;
2409
2410 val = RREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP0);
2411 return (val & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK) ? true : false;
2412}
2413
7af8bc50
HZ
2414static int arcturus_set_df_cstate(struct smu_context *smu,
2415 enum pp_df_cstate state)
2416{
2417 uint32_t smu_version;
2418 int ret;
2419
2420 ret = smu_get_smc_version(smu, NULL, &smu_version);
2421 if (ret) {
d9811cfc 2422 dev_err(smu->adev->dev, "Failed to get smu version!\n");
7af8bc50
HZ
2423 return ret;
2424 }
2425
2426 /* PPSMC_MSG_DFCstateControl is supported by 54.15.0 and onwards */
2427 if (smu_version < 0x360F00) {
d9811cfc 2428 dev_err(smu->adev->dev, "DFCstateControl is only supported by PMFW 54.15.0 and onwards\n");
7af8bc50
HZ
2429 return -EINVAL;
2430 }
2431
1c58267c 2432 return smu_send_smc_msg_with_param(smu, SMU_MSG_DFCstateControl, state, NULL);
7af8bc50
HZ
2433}
2434
ab9c2112
JC
2435static int arcturus_allow_xgmi_power_down(struct smu_context *smu, bool en)
2436{
2437 uint32_t smu_version;
2438 int ret;
2439
2440 ret = smu_get_smc_version(smu, NULL, &smu_version);
2441 if (ret) {
d9811cfc 2442 dev_err(smu->adev->dev, "Failed to get smu version!\n");
ab9c2112
JC
2443 return ret;
2444 }
2445
b7f0656a
JC
2446 /* PPSMC_MSG_GmiPwrDnControl is supported by 54.23.0 and onwards */
2447 if (smu_version < 0x00361700) {
d9811cfc 2448 dev_err(smu->adev->dev, "XGMI power down control is only supported by PMFW 54.23.0 and onwards\n");
ab9c2112
JC
2449 return -EINVAL;
2450 }
2451
2452 if (en)
2453 return smu_send_smc_msg_with_param(smu,
2454 SMU_MSG_GmiPwrDnControl,
2455 1,
2456 NULL);
2457
2458 return smu_send_smc_msg_with_param(smu,
2459 SMU_MSG_GmiPwrDnControl,
2460 0,
2461 NULL);
2462}
2463
8c0bba64
EQ
2464static const struct throttling_logging_label {
2465 uint32_t feature_mask;
2466 const char *label;
2467} logging_label[] = {
2468 {(1U << THROTTLER_TEMP_HOTSPOT_BIT), "GPU"},
2469 {(1U << THROTTLER_TEMP_MEM_BIT), "HBM"},
2470 {(1U << THROTTLER_TEMP_VR_GFX_BIT), "VR of GFX rail"},
2471 {(1U << THROTTLER_TEMP_VR_MEM_BIT), "VR of HBM rail"},
2472 {(1U << THROTTLER_TEMP_VR_SOC_BIT), "VR of SOC rail"},
2473 {(1U << THROTTLER_VRHOT0_BIT), "VR0 HOT"},
2474 {(1U << THROTTLER_VRHOT1_BIT), "VR1 HOT"},
2475};
2476static void arcturus_log_thermal_throttling_event(struct smu_context *smu)
2477{
2478 int throttler_idx, throtting_events = 0, buf_idx = 0;
2479 struct amdgpu_device *adev = smu->adev;
48219126 2480 uint32_t throttler_status;
8c0bba64
EQ
2481 char log_buf[256];
2482
48219126
EQ
2483 arcturus_get_smu_metrics_data(smu,
2484 METRICS_THROTTLER_STATUS,
2485 &throttler_status);
8c0bba64
EQ
2486
2487 memset(log_buf, 0, sizeof(log_buf));
2488 for (throttler_idx = 0; throttler_idx < ARRAY_SIZE(logging_label);
2489 throttler_idx++) {
48219126 2490 if (throttler_status & logging_label[throttler_idx].feature_mask) {
8c0bba64
EQ
2491 throtting_events++;
2492 buf_idx += snprintf(log_buf + buf_idx,
2493 sizeof(log_buf) - buf_idx,
2494 "%s%s",
2495 throtting_events > 1 ? " and " : "",
2496 logging_label[throttler_idx].label);
2497 if (buf_idx >= sizeof(log_buf)) {
d9811cfc 2498 dev_err(adev->dev, "buffer overflow!\n");
8c0bba64
EQ
2499 log_buf[sizeof(log_buf) - 1] = '\0';
2500 break;
2501 }
2502 }
2503 }
2504
2505 dev_warn(adev->dev, "WARN: GPU thermal throttling temperature reached, expect performance decrease. %s.\n",
2506 log_buf);
2507}
2508
947c127b
LG
2509static int arcturus_set_thermal_range(struct smu_context *smu,
2510 struct smu_temperature_range range)
2511{
2512 struct amdgpu_device *adev = smu->adev;
2513 int low = SMU_THERMAL_MINIMUM_ALERT_TEMP;
2514 int high = SMU_THERMAL_MAXIMUM_ALERT_TEMP;
2515 uint32_t val;
2516 struct smu_table_context *table_context = &smu->smu_table;
2517 struct smu_11_0_powerplay_table *powerplay_table = table_context->power_play_table;
2518
2519 low = max(SMU_THERMAL_MINIMUM_ALERT_TEMP,
2520 range.min / SMU_TEMPERATURE_UNITS_PER_CENTIGRADES);
2521 high = min((uint16_t)SMU_THERMAL_MAXIMUM_ALERT_TEMP, powerplay_table->software_shutdown_temp);
2522
2523 if (low > high)
2524 return -EINVAL;
2525
2526 val = RREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL);
2527 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, MAX_IH_CREDIT, 5);
2528 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_IH_HW_ENA, 1);
2529 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTH_MASK, 0);
2530 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, THERM_INTL_MASK, 0);
2531 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTH, (high & 0xff));
2532 val = REG_SET_FIELD(val, THM_THERMAL_INT_CTRL, DIG_THERM_INTL, (low & 0xff));
2533 val = val & (~THM_THERMAL_INT_CTRL__THERM_TRIGGER_MASK_MASK);
2534
2535 WREG32_SOC15(THM, 0, mmTHM_THERMAL_INT_CTRL, val);
2536
2537 return 0;
2538}
2539
6fba5906 2540static const struct pptable_funcs arcturus_ppt_funcs = {
a94235af 2541 /* translate smu index into arcturus specific index */
6fba5906 2542 .get_smu_msg_index = arcturus_get_smu_msg_index,
a94235af
EQ
2543 .get_smu_clk_index = arcturus_get_smu_clk_index,
2544 .get_smu_feature_index = arcturus_get_smu_feature_index,
2545 .get_smu_table_index = arcturus_get_smu_table_index,
2546 .get_smu_power_index= arcturus_get_pwr_src_index,
2547 .get_workload_type = arcturus_get_workload_type,
2548 /* internal structurs allocations */
2549 .tables_init = arcturus_tables_init,
2550 .alloc_dpm_context = arcturus_allocate_dpm_context,
a94235af
EQ
2551 /* init dpm */
2552 .get_allowed_feature_mask = arcturus_get_allowed_feature_mask,
2553 /* btc */
04c572a0 2554 .run_btc = arcturus_run_btc,
a94235af
EQ
2555 /* dpm/clk tables */
2556 .set_default_dpm_table = arcturus_set_default_dpm_table,
2557 .populate_umd_state_clk = arcturus_populate_umd_state_clk,
2558 .get_thermal_temperature_range = arcturus_get_thermal_temperature_range,
631807f0 2559 .get_current_clk_freq_by_table = arcturus_get_current_clk_freq_by_table,
a94235af
EQ
2560 .print_clk_levels = arcturus_print_clk_levels,
2561 .force_clk_levels = arcturus_force_clk_levels,
ba74c8bf 2562 .read_sensor = arcturus_read_sensor,
d427cf8f
EQ
2563 .get_fan_speed_percent = arcturus_get_fan_speed_percent,
2564 .get_fan_speed_rpm = arcturus_get_fan_speed_rpm,
60d435b7
EQ
2565 .force_dpm_limit_value = arcturus_force_dpm_limit_value,
2566 .unforce_dpm_levels = arcturus_unforce_dpm_levels,
2567 .get_profiling_clk_mask = arcturus_get_profiling_clk_mask,
7aa3f675
EQ
2568 .get_power_profile_mode = arcturus_get_power_profile_mode,
2569 .set_power_profile_mode = arcturus_set_power_profile_mode,
1744fb23 2570 .set_performance_level = arcturus_set_performance_level,
a94235af
EQ
2571 /* debug (internal used) */
2572 .dump_pptable = arcturus_dump_pptable,
b4af964e 2573 .get_power_limit = arcturus_get_power_limit,
3f513bae 2574 .is_dpm_running = arcturus_is_dpm_running,
f6b4b4a1 2575 .dpm_set_vcn_enable = arcturus_dpm_set_vcn_enable,
d1a84427
AG
2576 .i2c_eeprom_init = arcturus_i2c_eeprom_control_init,
2577 .i2c_eeprom_fini = arcturus_i2c_eeprom_control_fini,
81a16241 2578 .get_unique_id = arcturus_get_unique_id,
6c45e480
EQ
2579 .init_microcode = smu_v11_0_init_microcode,
2580 .load_microcode = smu_v11_0_load_microcode,
6f47116e 2581 .fini_microcode = smu_v11_0_fini_microcode,
6c45e480
EQ
2582 .init_smc_tables = smu_v11_0_init_smc_tables,
2583 .fini_smc_tables = smu_v11_0_fini_smc_tables,
2584 .init_power = smu_v11_0_init_power,
2585 .fini_power = smu_v11_0_fini_power,
2586 .check_fw_status = smu_v11_0_check_fw_status,
4a13b4ce
EQ
2587 /* pptable related */
2588 .setup_pptable = arcturus_setup_pptable,
6c45e480 2589 .get_vbios_bootup_values = smu_v11_0_get_vbios_bootup_values,
6c45e480
EQ
2590 .populate_smc_tables = smu_v11_0_populate_smc_pptable,
2591 .check_fw_version = smu_v11_0_check_fw_version,
2592 .write_pptable = smu_v11_0_write_pptable,
ce0d0ec3 2593 .set_driver_table_location = smu_v11_0_set_driver_table_location,
6c45e480
EQ
2594 .set_tool_table_location = smu_v11_0_set_tool_table_location,
2595 .notify_memory_pool_location = smu_v11_0_notify_memory_pool_location,
2596 .system_features_control = smu_v11_0_system_features_control,
6c45e480 2597 .send_smc_msg_with_param = smu_v11_0_send_msg_with_param,
31157341 2598 .init_display_count = NULL,
6c45e480
EQ
2599 .set_allowed_mask = smu_v11_0_set_allowed_mask,
2600 .get_enabled_mask = smu_v11_0_get_enabled_mask,
31157341 2601 .notify_display_change = NULL,
6c45e480
EQ
2602 .set_power_limit = smu_v11_0_set_power_limit,
2603 .get_current_clk_freq = smu_v11_0_get_current_clk_freq,
2604 .init_max_sustainable_clocks = smu_v11_0_init_max_sustainable_clocks,
22f1e0e8
EQ
2605 .enable_thermal_alert = smu_v11_0_enable_thermal_alert,
2606 .disable_thermal_alert = smu_v11_0_disable_thermal_alert,
ce63d8f8 2607 .set_min_dcef_deep_sleep = NULL,
6c45e480
EQ
2608 .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request,
2609 .get_fan_control_mode = smu_v11_0_get_fan_control_mode,
2610 .set_fan_control_mode = smu_v11_0_set_fan_control_mode,
2611 .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent,
2612 .set_fan_speed_rpm = smu_v11_0_set_fan_speed_rpm,
2613 .set_xgmi_pstate = smu_v11_0_set_xgmi_pstate,
2614 .gfx_off_control = smu_v11_0_gfx_off_control,
2615 .register_irq_handler = smu_v11_0_register_irq_handler,
2616 .set_azalia_d3_pme = smu_v11_0_set_azalia_d3_pme,
2617 .get_max_sustainable_clocks_by_dc = smu_v11_0_get_max_sustainable_clocks_by_dc,
49e78c82 2618 .baco_is_support= arcturus_is_baco_supported,
6c45e480
EQ
2619 .baco_get_state = smu_v11_0_baco_get_state,
2620 .baco_set_state = smu_v11_0_baco_set_state,
11520f27
AD
2621 .baco_enter = smu_v11_0_baco_enter,
2622 .baco_exit = smu_v11_0_baco_exit,
6c45e480
EQ
2623 .get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq,
2624 .set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range,
31157341 2625 .override_pcie_parameters = NULL,
7af8bc50 2626 .set_df_cstate = arcturus_set_df_cstate,
ab9c2112 2627 .allow_xgmi_power_down = arcturus_allow_xgmi_power_down,
8c0bba64 2628 .log_thermal_throttling_event = arcturus_log_thermal_throttling_event,
947c127b 2629 .set_thermal_range = arcturus_set_thermal_range,
6fba5906
CG
2630};
2631
2632void arcturus_set_ppt_funcs(struct smu_context *smu)
2633{
2634 smu->ppt_funcs = &arcturus_ppt_funcs;
6fba5906 2635}