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