2 * Copyright 2019 Advanced Micro Devices, Inc.
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
25 #include <linux/firmware.h>
27 #include "amdgpu_smu.h"
28 #include "smu_internal.h"
29 #include "atomfirmware.h"
30 #include "amdgpu_atomfirmware.h"
31 #include "smu_v11_0.h"
32 #include "smu11_driver_if_arcturus.h"
33 #include "soc15_common.h"
35 #include "power_state.h"
36 #include "arcturus_ppt.h"
37 #include "smu_v11_0_pptable.h"
38 #include "arcturus_ppsmc.h"
39 #include "nbio/nbio_7_4_sh_mask.h"
40 #include "amdgpu_xgmi.h"
41 #include <linux/i2c.h>
42 #include <linux/pci.h>
43 #include "amdgpu_ras.h"
45 #define to_amdgpu_device(x) (container_of(x, struct amdgpu_ras, eeprom_control.eeprom_accessor))->adev
47 #define CTF_OFFSET_EDGE 5
48 #define CTF_OFFSET_HOTSPOT 5
49 #define CTF_OFFSET_HBM 5
51 #define MSG_MAP(msg, index) \
52 [SMU_MSG_##msg] = {1, (index)}
53 #define ARCTURUS_FEA_MAP(smu_feature, arcturus_feature) \
54 [smu_feature] = {1, (arcturus_feature)}
56 #define SMU_FEATURES_LOW_MASK 0x00000000FFFFFFFF
57 #define SMU_FEATURES_LOW_SHIFT 0
58 #define SMU_FEATURES_HIGH_MASK 0xFFFFFFFF00000000
59 #define SMU_FEATURES_HIGH_SHIFT 32
61 #define SMC_DPM_FEATURE ( \
62 FEATURE_DPM_PREFETCHER_MASK | \
63 FEATURE_DPM_GFXCLK_MASK | \
64 FEATURE_DPM_UCLK_MASK | \
65 FEATURE_DPM_SOCCLK_MASK | \
66 FEATURE_DPM_MP0CLK_MASK | \
67 FEATURE_DPM_FCLK_MASK | \
68 FEATURE_DPM_XGMI_MASK)
70 /* possible frequency drift (1Mhz) */
73 static struct smu_11_0_cmn2aisc_mapping arcturus_message_map
[SMU_MSG_MAX_COUNT
] = {
74 MSG_MAP(TestMessage
, PPSMC_MSG_TestMessage
),
75 MSG_MAP(GetSmuVersion
, PPSMC_MSG_GetSmuVersion
),
76 MSG_MAP(GetDriverIfVersion
, PPSMC_MSG_GetDriverIfVersion
),
77 MSG_MAP(SetAllowedFeaturesMaskLow
, PPSMC_MSG_SetAllowedFeaturesMaskLow
),
78 MSG_MAP(SetAllowedFeaturesMaskHigh
, PPSMC_MSG_SetAllowedFeaturesMaskHigh
),
79 MSG_MAP(EnableAllSmuFeatures
, PPSMC_MSG_EnableAllSmuFeatures
),
80 MSG_MAP(DisableAllSmuFeatures
, PPSMC_MSG_DisableAllSmuFeatures
),
81 MSG_MAP(EnableSmuFeaturesLow
, PPSMC_MSG_EnableSmuFeaturesLow
),
82 MSG_MAP(EnableSmuFeaturesHigh
, PPSMC_MSG_EnableSmuFeaturesHigh
),
83 MSG_MAP(DisableSmuFeaturesLow
, PPSMC_MSG_DisableSmuFeaturesLow
),
84 MSG_MAP(DisableSmuFeaturesHigh
, PPSMC_MSG_DisableSmuFeaturesHigh
),
85 MSG_MAP(GetEnabledSmuFeaturesLow
, PPSMC_MSG_GetEnabledSmuFeaturesLow
),
86 MSG_MAP(GetEnabledSmuFeaturesHigh
, PPSMC_MSG_GetEnabledSmuFeaturesHigh
),
87 MSG_MAP(SetDriverDramAddrHigh
, PPSMC_MSG_SetDriverDramAddrHigh
),
88 MSG_MAP(SetDriverDramAddrLow
, PPSMC_MSG_SetDriverDramAddrLow
),
89 MSG_MAP(SetToolsDramAddrHigh
, PPSMC_MSG_SetToolsDramAddrHigh
),
90 MSG_MAP(SetToolsDramAddrLow
, PPSMC_MSG_SetToolsDramAddrLow
),
91 MSG_MAP(TransferTableSmu2Dram
, PPSMC_MSG_TransferTableSmu2Dram
),
92 MSG_MAP(TransferTableDram2Smu
, PPSMC_MSG_TransferTableDram2Smu
),
93 MSG_MAP(UseDefaultPPTable
, PPSMC_MSG_UseDefaultPPTable
),
94 MSG_MAP(UseBackupPPTable
, PPSMC_MSG_UseBackupPPTable
),
95 MSG_MAP(SetSystemVirtualDramAddrHigh
, PPSMC_MSG_SetSystemVirtualDramAddrHigh
),
96 MSG_MAP(SetSystemVirtualDramAddrLow
, PPSMC_MSG_SetSystemVirtualDramAddrLow
),
97 MSG_MAP(EnterBaco
, PPSMC_MSG_EnterBaco
),
98 MSG_MAP(ExitBaco
, PPSMC_MSG_ExitBaco
),
99 MSG_MAP(ArmD3
, PPSMC_MSG_ArmD3
),
100 MSG_MAP(SetSoftMinByFreq
, PPSMC_MSG_SetSoftMinByFreq
),
101 MSG_MAP(SetSoftMaxByFreq
, PPSMC_MSG_SetSoftMaxByFreq
),
102 MSG_MAP(SetHardMinByFreq
, PPSMC_MSG_SetHardMinByFreq
),
103 MSG_MAP(SetHardMaxByFreq
, PPSMC_MSG_SetHardMaxByFreq
),
104 MSG_MAP(GetMinDpmFreq
, PPSMC_MSG_GetMinDpmFreq
),
105 MSG_MAP(GetMaxDpmFreq
, PPSMC_MSG_GetMaxDpmFreq
),
106 MSG_MAP(GetDpmFreqByIndex
, PPSMC_MSG_GetDpmFreqByIndex
),
107 MSG_MAP(SetWorkloadMask
, PPSMC_MSG_SetWorkloadMask
),
108 MSG_MAP(SetDfSwitchType
, PPSMC_MSG_SetDfSwitchType
),
109 MSG_MAP(GetVoltageByDpm
, PPSMC_MSG_GetVoltageByDpm
),
110 MSG_MAP(GetVoltageByDpmOverdrive
, PPSMC_MSG_GetVoltageByDpmOverdrive
),
111 MSG_MAP(SetPptLimit
, PPSMC_MSG_SetPptLimit
),
112 MSG_MAP(GetPptLimit
, PPSMC_MSG_GetPptLimit
),
113 MSG_MAP(PowerUpVcn0
, PPSMC_MSG_PowerUpVcn0
),
114 MSG_MAP(PowerDownVcn0
, PPSMC_MSG_PowerDownVcn0
),
115 MSG_MAP(PowerUpVcn1
, PPSMC_MSG_PowerUpVcn1
),
116 MSG_MAP(PowerDownVcn1
, PPSMC_MSG_PowerDownVcn1
),
117 MSG_MAP(PrepareMp1ForUnload
, PPSMC_MSG_PrepareMp1ForUnload
),
118 MSG_MAP(PrepareMp1ForReset
, PPSMC_MSG_PrepareMp1ForReset
),
119 MSG_MAP(PrepareMp1ForShutdown
, PPSMC_MSG_PrepareMp1ForShutdown
),
120 MSG_MAP(SoftReset
, PPSMC_MSG_SoftReset
),
121 MSG_MAP(RunAfllBtc
, PPSMC_MSG_RunAfllBtc
),
122 MSG_MAP(RunDcBtc
, PPSMC_MSG_RunDcBtc
),
123 MSG_MAP(DramLogSetDramAddrHigh
, PPSMC_MSG_DramLogSetDramAddrHigh
),
124 MSG_MAP(DramLogSetDramAddrLow
, PPSMC_MSG_DramLogSetDramAddrLow
),
125 MSG_MAP(DramLogSetDramSize
, PPSMC_MSG_DramLogSetDramSize
),
126 MSG_MAP(GetDebugData
, PPSMC_MSG_GetDebugData
),
127 MSG_MAP(WaflTest
, PPSMC_MSG_WaflTest
),
128 MSG_MAP(SetXgmiMode
, PPSMC_MSG_SetXgmiMode
),
129 MSG_MAP(SetMemoryChannelEnable
, PPSMC_MSG_SetMemoryChannelEnable
),
132 static struct smu_11_0_cmn2aisc_mapping arcturus_clk_map
[SMU_CLK_COUNT
] = {
133 CLK_MAP(GFXCLK
, PPCLK_GFXCLK
),
134 CLK_MAP(SCLK
, PPCLK_GFXCLK
),
135 CLK_MAP(SOCCLK
, PPCLK_SOCCLK
),
136 CLK_MAP(FCLK
, PPCLK_FCLK
),
137 CLK_MAP(UCLK
, PPCLK_UCLK
),
138 CLK_MAP(MCLK
, PPCLK_UCLK
),
139 CLK_MAP(DCLK
, PPCLK_DCLK
),
140 CLK_MAP(VCLK
, PPCLK_VCLK
),
143 static struct smu_11_0_cmn2aisc_mapping arcturus_feature_mask_map
[SMU_FEATURE_COUNT
] = {
144 FEA_MAP(DPM_PREFETCHER
),
150 ARCTURUS_FEA_MAP(SMU_FEATURE_XGMI_BIT
, FEATURE_DPM_XGMI_BIT
),
157 ARCTURUS_FEA_MAP(SMU_FEATURE_VCN_PG_BIT
, FEATURE_DPM_VCN_BIT
),
158 FEA_MAP(RSMU_SMN_CG
),
166 FEA_MAP(FAN_CONTROL
),
168 FEA_MAP(OUT_OF_BAND_MONITOR
),
169 FEA_MAP(TEMP_DEPENDENT_VMIN
),
172 static struct smu_11_0_cmn2aisc_mapping arcturus_table_map
[SMU_TABLE_COUNT
] = {
175 TAB_MAP(AVFS_PSM_DEBUG
),
176 TAB_MAP(AVFS_FUSE_OVERRIDE
),
177 TAB_MAP(PMSTATUSLOG
),
178 TAB_MAP(SMU_METRICS
),
179 TAB_MAP(DRIVER_SMU_CONFIG
),
181 TAB_MAP(I2C_COMMANDS
),
182 TAB_MAP(ACTIVITY_MONITOR_COEFF
),
185 static struct smu_11_0_cmn2aisc_mapping arcturus_pwr_src_map
[SMU_POWER_SOURCE_COUNT
] = {
190 static struct smu_11_0_cmn2aisc_mapping arcturus_workload_map
[PP_SMC_POWER_PROFILE_COUNT
] = {
191 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT
, WORKLOAD_PPLIB_DEFAULT_BIT
),
192 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING
, WORKLOAD_PPLIB_POWER_SAVING_BIT
),
193 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO
, WORKLOAD_PPLIB_VIDEO_BIT
),
194 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE
, WORKLOAD_PPLIB_COMPUTE_BIT
),
195 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM
, WORKLOAD_PPLIB_CUSTOM_BIT
),
198 static int arcturus_get_smu_msg_index(struct smu_context
*smc
, uint32_t index
)
200 struct smu_11_0_cmn2aisc_mapping mapping
;
202 if (index
>= SMU_MSG_MAX_COUNT
)
205 mapping
= arcturus_message_map
[index
];
206 if (!(mapping
.valid_mapping
))
209 return mapping
.map_to
;
212 static int arcturus_get_smu_clk_index(struct smu_context
*smc
, uint32_t index
)
214 struct smu_11_0_cmn2aisc_mapping mapping
;
216 if (index
>= SMU_CLK_COUNT
)
219 mapping
= arcturus_clk_map
[index
];
220 if (!(mapping
.valid_mapping
)) {
221 pr_warn("Unsupported SMU clk: %d\n", index
);
225 return mapping
.map_to
;
228 static int arcturus_get_smu_feature_index(struct smu_context
*smc
, uint32_t index
)
230 struct smu_11_0_cmn2aisc_mapping mapping
;
232 if (index
>= SMU_FEATURE_COUNT
)
235 mapping
= arcturus_feature_mask_map
[index
];
236 if (!(mapping
.valid_mapping
)) {
240 return mapping
.map_to
;
243 static int arcturus_get_smu_table_index(struct smu_context
*smc
, uint32_t index
)
245 struct smu_11_0_cmn2aisc_mapping mapping
;
247 if (index
>= SMU_TABLE_COUNT
)
250 mapping
= arcturus_table_map
[index
];
251 if (!(mapping
.valid_mapping
)) {
252 pr_warn("Unsupported SMU table: %d\n", index
);
256 return mapping
.map_to
;
259 static int arcturus_get_pwr_src_index(struct smu_context
*smc
, uint32_t index
)
261 struct smu_11_0_cmn2aisc_mapping mapping
;
263 if (index
>= SMU_POWER_SOURCE_COUNT
)
266 mapping
= arcturus_pwr_src_map
[index
];
267 if (!(mapping
.valid_mapping
)) {
268 pr_warn("Unsupported SMU power source: %d\n", index
);
272 return mapping
.map_to
;
276 static int arcturus_get_workload_type(struct smu_context
*smu
, enum PP_SMC_POWER_PROFILE profile
)
278 struct smu_11_0_cmn2aisc_mapping mapping
;
280 if (profile
> PP_SMC_POWER_PROFILE_CUSTOM
)
283 mapping
= arcturus_workload_map
[profile
];
284 if (!(mapping
.valid_mapping
))
287 return mapping
.map_to
;
290 static int arcturus_tables_init(struct smu_context
*smu
, struct smu_table
*tables
)
292 struct smu_table_context
*smu_table
= &smu
->smu_table
;
294 SMU_TABLE_INIT(tables
, SMU_TABLE_PPTABLE
, sizeof(PPTable_t
),
295 PAGE_SIZE
, AMDGPU_GEM_DOMAIN_VRAM
);
297 SMU_TABLE_INIT(tables
, SMU_TABLE_PMSTATUSLOG
, SMU11_TOOL_SIZE
,
298 PAGE_SIZE
, AMDGPU_GEM_DOMAIN_VRAM
);
300 SMU_TABLE_INIT(tables
, SMU_TABLE_SMU_METRICS
, sizeof(SmuMetrics_t
),
301 PAGE_SIZE
, AMDGPU_GEM_DOMAIN_VRAM
);
303 SMU_TABLE_INIT(tables
, SMU_TABLE_I2C_COMMANDS
, sizeof(SwI2cRequest_t
),
304 PAGE_SIZE
, AMDGPU_GEM_DOMAIN_VRAM
);
306 SMU_TABLE_INIT(tables
, SMU_TABLE_ACTIVITY_MONITOR_COEFF
,
307 sizeof(DpmActivityMonitorCoeffInt_t
), PAGE_SIZE
,
308 AMDGPU_GEM_DOMAIN_VRAM
);
310 smu_table
->metrics_table
= kzalloc(sizeof(SmuMetrics_t
), GFP_KERNEL
);
311 if (!smu_table
->metrics_table
)
313 smu_table
->metrics_time
= 0;
318 static int arcturus_allocate_dpm_context(struct smu_context
*smu
)
320 struct smu_dpm_context
*smu_dpm
= &smu
->smu_dpm
;
322 if (smu_dpm
->dpm_context
)
325 smu_dpm
->dpm_context
= kzalloc(sizeof(struct arcturus_dpm_table
),
327 if (!smu_dpm
->dpm_context
)
330 if (smu_dpm
->golden_dpm_context
)
333 smu_dpm
->golden_dpm_context
= kzalloc(sizeof(struct arcturus_dpm_table
),
335 if (!smu_dpm
->golden_dpm_context
)
338 smu_dpm
->dpm_context_size
= sizeof(struct arcturus_dpm_table
);
340 smu_dpm
->dpm_current_power_state
= kzalloc(sizeof(struct smu_power_state
),
342 if (!smu_dpm
->dpm_current_power_state
)
345 smu_dpm
->dpm_request_power_state
= kzalloc(sizeof(struct smu_power_state
),
347 if (!smu_dpm
->dpm_request_power_state
)
354 arcturus_get_allowed_feature_mask(struct smu_context
*smu
,
355 uint32_t *feature_mask
, uint32_t num
)
360 /* pptable will handle the features to enable */
361 memset(feature_mask
, 0xFF, sizeof(uint32_t) * num
);
367 arcturus_set_single_dpm_table(struct smu_context
*smu
,
368 struct arcturus_single_dpm_table
*single_dpm_table
,
372 uint32_t i
, num_of_levels
= 0, clk
;
374 ret
= smu_send_smc_msg_with_param(smu
,
375 SMU_MSG_GetDpmFreqByIndex
,
376 (clk_id
<< 16 | 0xFF));
378 pr_err("[%s] failed to get dpm levels!\n", __func__
);
382 smu_read_smc_arg(smu
, &num_of_levels
);
383 if (!num_of_levels
) {
384 pr_err("[%s] number of clk levels is invalid!\n", __func__
);
388 single_dpm_table
->count
= num_of_levels
;
389 for (i
= 0; i
< num_of_levels
; i
++) {
390 ret
= smu_send_smc_msg_with_param(smu
,
391 SMU_MSG_GetDpmFreqByIndex
,
394 pr_err("[%s] failed to get dpm freq by index!\n", __func__
);
397 smu_read_smc_arg(smu
, &clk
);
399 pr_err("[%s] clk value is invalid!\n", __func__
);
402 single_dpm_table
->dpm_levels
[i
].value
= clk
;
403 single_dpm_table
->dpm_levels
[i
].enabled
= true;
408 static void arcturus_init_single_dpm_state(struct arcturus_dpm_state
*dpm_state
)
410 dpm_state
->soft_min_level
= 0x0;
411 dpm_state
->soft_max_level
= 0xffff;
412 dpm_state
->hard_min_level
= 0x0;
413 dpm_state
->hard_max_level
= 0xffff;
416 static int arcturus_set_default_dpm_table(struct smu_context
*smu
)
420 struct smu_dpm_context
*smu_dpm
= &smu
->smu_dpm
;
421 struct arcturus_dpm_table
*dpm_table
= NULL
;
422 struct arcturus_single_dpm_table
*single_dpm_table
;
424 dpm_table
= smu_dpm
->dpm_context
;
427 single_dpm_table
= &(dpm_table
->soc_table
);
428 if (smu_feature_is_enabled(smu
, SMU_FEATURE_DPM_SOCCLK_BIT
)) {
429 ret
= arcturus_set_single_dpm_table(smu
, single_dpm_table
,
432 pr_err("[%s] failed to get socclk dpm levels!\n", __func__
);
436 single_dpm_table
->count
= 1;
437 single_dpm_table
->dpm_levels
[0].value
= smu
->smu_table
.boot_values
.socclk
/ 100;
439 arcturus_init_single_dpm_state(&(single_dpm_table
->dpm_state
));
442 single_dpm_table
= &(dpm_table
->gfx_table
);
443 if (smu_feature_is_enabled(smu
, SMU_FEATURE_DPM_GFXCLK_BIT
)) {
444 ret
= arcturus_set_single_dpm_table(smu
, single_dpm_table
,
447 pr_err("[SetupDefaultDpmTable] failed to get gfxclk dpm levels!");
451 single_dpm_table
->count
= 1;
452 single_dpm_table
->dpm_levels
[0].value
= smu
->smu_table
.boot_values
.gfxclk
/ 100;
454 arcturus_init_single_dpm_state(&(single_dpm_table
->dpm_state
));
457 single_dpm_table
= &(dpm_table
->mem_table
);
458 if (smu_feature_is_enabled(smu
, SMU_FEATURE_DPM_UCLK_BIT
)) {
459 ret
= arcturus_set_single_dpm_table(smu
, single_dpm_table
,
462 pr_err("[SetupDefaultDpmTable] failed to get memclk dpm levels!");
466 single_dpm_table
->count
= 1;
467 single_dpm_table
->dpm_levels
[0].value
= smu
->smu_table
.boot_values
.uclk
/ 100;
469 arcturus_init_single_dpm_state(&(single_dpm_table
->dpm_state
));
472 single_dpm_table
= &(dpm_table
->fclk_table
);
473 if (smu_feature_is_enabled(smu
, SMU_FEATURE_DPM_FCLK_BIT
)) {
474 ret
= arcturus_set_single_dpm_table(smu
, single_dpm_table
,
477 pr_err("[SetupDefaultDpmTable] failed to get fclk dpm levels!");
481 single_dpm_table
->count
= 1;
482 single_dpm_table
->dpm_levels
[0].value
= smu
->smu_table
.boot_values
.fclk
/ 100;
484 arcturus_init_single_dpm_state(&(single_dpm_table
->dpm_state
));
486 memcpy(smu_dpm
->golden_dpm_context
, dpm_table
,
487 sizeof(struct arcturus_dpm_table
));
492 static int arcturus_check_powerplay_table(struct smu_context
*smu
)
497 static int arcturus_store_powerplay_table(struct smu_context
*smu
)
499 struct smu_11_0_powerplay_table
*powerplay_table
= NULL
;
500 struct smu_table_context
*table_context
= &smu
->smu_table
;
501 struct smu_baco_context
*smu_baco
= &smu
->smu_baco
;
504 if (!table_context
->power_play_table
)
507 powerplay_table
= table_context
->power_play_table
;
509 memcpy(table_context
->driver_pptable
, &powerplay_table
->smc_pptable
,
512 table_context
->thermal_controller_type
= powerplay_table
->thermal_controller_type
;
514 mutex_lock(&smu_baco
->mutex
);
515 if (powerplay_table
->platform_caps
& SMU_11_0_PP_PLATFORM_CAP_BACO
||
516 powerplay_table
->platform_caps
& SMU_11_0_PP_PLATFORM_CAP_MACO
)
517 smu_baco
->platform_support
= true;
518 mutex_unlock(&smu_baco
->mutex
);
523 static int arcturus_append_powerplay_table(struct smu_context
*smu
)
525 struct smu_table_context
*table_context
= &smu
->smu_table
;
526 PPTable_t
*smc_pptable
= table_context
->driver_pptable
;
527 struct atom_smc_dpm_info_v4_6
*smc_dpm_table
;
530 index
= get_index_into_master_table(atom_master_list_of_data_tables_v2_1
,
533 ret
= smu_get_atom_data_table(smu
, index
, NULL
, NULL
, NULL
,
534 (uint8_t **)&smc_dpm_table
);
538 pr_info("smc_dpm_info table revision(format.content): %d.%d\n",
539 smc_dpm_table
->table_header
.format_revision
,
540 smc_dpm_table
->table_header
.content_revision
);
542 if ((smc_dpm_table
->table_header
.format_revision
== 4) &&
543 (smc_dpm_table
->table_header
.content_revision
== 6))
544 memcpy(&smc_pptable
->MaxVoltageStepGfx
,
545 &smc_dpm_table
->maxvoltagestepgfx
,
546 sizeof(*smc_dpm_table
) - offsetof(struct atom_smc_dpm_info_v4_6
, maxvoltagestepgfx
));
551 static int arcturus_run_btc(struct smu_context
*smu
)
555 ret
= smu_send_smc_msg(smu
, SMU_MSG_RunAfllBtc
);
557 pr_err("RunAfllBtc failed!\n");
561 return smu_send_smc_msg(smu
, SMU_MSG_RunDcBtc
);
564 static int arcturus_populate_umd_state_clk(struct smu_context
*smu
)
566 struct smu_dpm_context
*smu_dpm
= &smu
->smu_dpm
;
567 struct arcturus_dpm_table
*dpm_table
= NULL
;
568 struct arcturus_single_dpm_table
*gfx_table
= NULL
;
569 struct arcturus_single_dpm_table
*mem_table
= NULL
;
571 dpm_table
= smu_dpm
->dpm_context
;
572 gfx_table
= &(dpm_table
->gfx_table
);
573 mem_table
= &(dpm_table
->mem_table
);
575 smu
->pstate_sclk
= gfx_table
->dpm_levels
[0].value
;
576 smu
->pstate_mclk
= mem_table
->dpm_levels
[0].value
;
578 if (gfx_table
->count
> ARCTURUS_UMD_PSTATE_GFXCLK_LEVEL
&&
579 mem_table
->count
> ARCTURUS_UMD_PSTATE_MCLK_LEVEL
) {
580 smu
->pstate_sclk
= gfx_table
->dpm_levels
[ARCTURUS_UMD_PSTATE_GFXCLK_LEVEL
].value
;
581 smu
->pstate_mclk
= mem_table
->dpm_levels
[ARCTURUS_UMD_PSTATE_MCLK_LEVEL
].value
;
584 smu
->pstate_sclk
= smu
->pstate_sclk
* 100;
585 smu
->pstate_mclk
= smu
->pstate_mclk
* 100;
590 static int arcturus_get_clk_table(struct smu_context
*smu
,
591 struct pp_clock_levels_with_latency
*clocks
,
592 struct arcturus_single_dpm_table
*dpm_table
)
596 count
= (dpm_table
->count
> MAX_NUM_CLOCKS
) ? MAX_NUM_CLOCKS
: dpm_table
->count
;
597 clocks
->num_levels
= count
;
599 for (i
= 0; i
< count
; i
++) {
600 clocks
->data
[i
].clocks_in_khz
=
601 dpm_table
->dpm_levels
[i
].value
* 1000;
602 clocks
->data
[i
].latency_in_us
= 0;
608 static int arcturus_freqs_in_same_level(int32_t frequency1
,
611 return (abs(frequency1
- frequency2
) <= EPSILON
);
614 static int arcturus_print_clk_levels(struct smu_context
*smu
,
615 enum smu_clk_type type
, char *buf
)
617 int i
, now
, size
= 0;
619 struct pp_clock_levels_with_latency clocks
;
620 struct arcturus_single_dpm_table
*single_dpm_table
;
621 struct smu_dpm_context
*smu_dpm
= &smu
->smu_dpm
;
622 struct arcturus_dpm_table
*dpm_table
= NULL
;
624 dpm_table
= smu_dpm
->dpm_context
;
628 ret
= smu_get_current_clk_freq(smu
, SMU_GFXCLK
, &now
);
630 pr_err("Attempt to get current gfx clk Failed!");
634 single_dpm_table
= &(dpm_table
->gfx_table
);
635 ret
= arcturus_get_clk_table(smu
, &clocks
, single_dpm_table
);
637 pr_err("Attempt to get gfx clk levels Failed!");
642 * For DPM disabled case, there will be only one clock level.
643 * And it's safe to assume that is always the current clock.
645 for (i
= 0; i
< clocks
.num_levels
; i
++)
646 size
+= sprintf(buf
+ size
, "%d: %uMhz %s\n", i
,
647 clocks
.data
[i
].clocks_in_khz
/ 1000,
648 (clocks
.num_levels
== 1) ? "*" :
649 (arcturus_freqs_in_same_level(
650 clocks
.data
[i
].clocks_in_khz
/ 1000,
651 now
/ 100) ? "*" : ""));
655 ret
= smu_get_current_clk_freq(smu
, SMU_UCLK
, &now
);
657 pr_err("Attempt to get current mclk Failed!");
661 single_dpm_table
= &(dpm_table
->mem_table
);
662 ret
= arcturus_get_clk_table(smu
, &clocks
, single_dpm_table
);
664 pr_err("Attempt to get memory clk levels Failed!");
668 for (i
= 0; i
< clocks
.num_levels
; i
++)
669 size
+= sprintf(buf
+ size
, "%d: %uMhz %s\n",
670 i
, clocks
.data
[i
].clocks_in_khz
/ 1000,
671 (clocks
.num_levels
== 1) ? "*" :
672 (arcturus_freqs_in_same_level(
673 clocks
.data
[i
].clocks_in_khz
/ 1000,
674 now
/ 100) ? "*" : ""));
678 ret
= smu_get_current_clk_freq(smu
, SMU_SOCCLK
, &now
);
680 pr_err("Attempt to get current socclk Failed!");
684 single_dpm_table
= &(dpm_table
->soc_table
);
685 ret
= arcturus_get_clk_table(smu
, &clocks
, single_dpm_table
);
687 pr_err("Attempt to get socclk levels Failed!");
691 for (i
= 0; i
< clocks
.num_levels
; i
++)
692 size
+= sprintf(buf
+ size
, "%d: %uMhz %s\n",
693 i
, clocks
.data
[i
].clocks_in_khz
/ 1000,
694 (clocks
.num_levels
== 1) ? "*" :
695 (arcturus_freqs_in_same_level(
696 clocks
.data
[i
].clocks_in_khz
/ 1000,
697 now
/ 100) ? "*" : ""));
701 ret
= smu_get_current_clk_freq(smu
, SMU_FCLK
, &now
);
703 pr_err("Attempt to get current fclk Failed!");
707 single_dpm_table
= &(dpm_table
->fclk_table
);
708 ret
= arcturus_get_clk_table(smu
, &clocks
, single_dpm_table
);
710 pr_err("Attempt to get fclk levels Failed!");
714 for (i
= 0; i
< single_dpm_table
->count
; i
++)
715 size
+= sprintf(buf
+ size
, "%d: %uMhz %s\n",
716 i
, single_dpm_table
->dpm_levels
[i
].value
,
717 (clocks
.num_levels
== 1) ? "*" :
718 (arcturus_freqs_in_same_level(
719 clocks
.data
[i
].clocks_in_khz
/ 1000,
720 now
/ 100) ? "*" : ""));
730 static int arcturus_upload_dpm_level(struct smu_context
*smu
, bool max
,
731 uint32_t feature_mask
)
733 struct arcturus_single_dpm_table
*single_dpm_table
;
734 struct arcturus_dpm_table
*dpm_table
=
735 smu
->smu_dpm
.dpm_context
;
739 if (smu_feature_is_enabled(smu
, SMU_FEATURE_DPM_GFXCLK_BIT
) &&
740 (feature_mask
& FEATURE_DPM_GFXCLK_MASK
)) {
741 single_dpm_table
= &(dpm_table
->gfx_table
);
742 freq
= max
? single_dpm_table
->dpm_state
.soft_max_level
:
743 single_dpm_table
->dpm_state
.soft_min_level
;
744 ret
= smu_send_smc_msg_with_param(smu
,
745 (max
? SMU_MSG_SetSoftMaxByFreq
: SMU_MSG_SetSoftMinByFreq
),
746 (PPCLK_GFXCLK
<< 16) | (freq
& 0xffff));
748 pr_err("Failed to set soft %s gfxclk !\n",
749 max
? "max" : "min");
754 if (smu_feature_is_enabled(smu
, SMU_FEATURE_DPM_UCLK_BIT
) &&
755 (feature_mask
& FEATURE_DPM_UCLK_MASK
)) {
756 single_dpm_table
= &(dpm_table
->mem_table
);
757 freq
= max
? single_dpm_table
->dpm_state
.soft_max_level
:
758 single_dpm_table
->dpm_state
.soft_min_level
;
759 ret
= smu_send_smc_msg_with_param(smu
,
760 (max
? SMU_MSG_SetSoftMaxByFreq
: SMU_MSG_SetSoftMinByFreq
),
761 (PPCLK_UCLK
<< 16) | (freq
& 0xffff));
763 pr_err("Failed to set soft %s memclk !\n",
764 max
? "max" : "min");
769 if (smu_feature_is_enabled(smu
, SMU_FEATURE_DPM_SOCCLK_BIT
) &&
770 (feature_mask
& FEATURE_DPM_SOCCLK_MASK
)) {
771 single_dpm_table
= &(dpm_table
->soc_table
);
772 freq
= max
? single_dpm_table
->dpm_state
.soft_max_level
:
773 single_dpm_table
->dpm_state
.soft_min_level
;
774 ret
= smu_send_smc_msg_with_param(smu
,
775 (max
? SMU_MSG_SetSoftMaxByFreq
: SMU_MSG_SetSoftMinByFreq
),
776 (PPCLK_SOCCLK
<< 16) | (freq
& 0xffff));
778 pr_err("Failed to set soft %s socclk !\n",
779 max
? "max" : "min");
787 static int arcturus_force_clk_levels(struct smu_context
*smu
,
788 enum smu_clk_type type
, uint32_t mask
)
790 struct arcturus_dpm_table
*dpm_table
;
791 struct arcturus_single_dpm_table
*single_dpm_table
;
792 uint32_t soft_min_level
, soft_max_level
;
795 soft_min_level
= mask
? (ffs(mask
) - 1) : 0;
796 soft_max_level
= mask
? (fls(mask
) - 1) : 0;
798 dpm_table
= smu
->smu_dpm
.dpm_context
;
802 single_dpm_table
= &(dpm_table
->gfx_table
);
804 if (soft_max_level
>= single_dpm_table
->count
) {
805 pr_err("Clock level specified %d is over max allowed %d\n",
806 soft_max_level
, single_dpm_table
->count
- 1);
811 single_dpm_table
->dpm_state
.soft_min_level
=
812 single_dpm_table
->dpm_levels
[soft_min_level
].value
;
813 single_dpm_table
->dpm_state
.soft_max_level
=
814 single_dpm_table
->dpm_levels
[soft_max_level
].value
;
816 ret
= arcturus_upload_dpm_level(smu
, false, FEATURE_DPM_GFXCLK_MASK
);
818 pr_err("Failed to upload boot level to lowest!\n");
822 ret
= arcturus_upload_dpm_level(smu
, true, FEATURE_DPM_GFXCLK_MASK
);
824 pr_err("Failed to upload dpm max level to highest!\n");
832 * Should not arrive here since Arcturus does not
833 * support mclk/socclk/fclk softmin/softmax settings
845 static int arcturus_get_thermal_temperature_range(struct smu_context
*smu
,
846 struct smu_temperature_range
*range
)
848 PPTable_t
*pptable
= smu
->smu_table
.driver_pptable
;
853 range
->max
= pptable
->TedgeLimit
*
854 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES
;
855 range
->edge_emergency_max
= (pptable
->TedgeLimit
+ CTF_OFFSET_EDGE
) *
856 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES
;
857 range
->hotspot_crit_max
= pptable
->ThotspotLimit
*
858 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES
;
859 range
->hotspot_emergency_max
= (pptable
->ThotspotLimit
+ CTF_OFFSET_HOTSPOT
) *
860 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES
;
861 range
->mem_crit_max
= pptable
->TmemLimit
*
862 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES
;
863 range
->mem_emergency_max
= (pptable
->TmemLimit
+ CTF_OFFSET_HBM
)*
864 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES
;
869 static int arcturus_get_metrics_table(struct smu_context
*smu
,
870 SmuMetrics_t
*metrics_table
)
872 struct smu_table_context
*smu_table
= &smu
->smu_table
;
875 mutex_lock(&smu
->metrics_lock
);
876 if (!smu_table
->metrics_time
||
877 time_after(jiffies
, smu_table
->metrics_time
+ HZ
/ 1000)) {
878 ret
= smu_update_table(smu
, SMU_TABLE_SMU_METRICS
, 0,
879 (void *)smu_table
->metrics_table
, false);
881 pr_info("Failed to export SMU metrics table!\n");
882 mutex_unlock(&smu
->metrics_lock
);
885 smu_table
->metrics_time
= jiffies
;
888 memcpy(metrics_table
, smu_table
->metrics_table
, sizeof(SmuMetrics_t
));
889 mutex_unlock(&smu
->metrics_lock
);
894 static int arcturus_get_current_activity_percent(struct smu_context
*smu
,
895 enum amd_pp_sensors sensor
,
898 SmuMetrics_t metrics
;
904 ret
= arcturus_get_metrics_table(smu
, &metrics
);
909 case AMDGPU_PP_SENSOR_GPU_LOAD
:
910 *value
= metrics
.AverageGfxActivity
;
912 case AMDGPU_PP_SENSOR_MEM_LOAD
:
913 *value
= metrics
.AverageUclkActivity
;
916 pr_err("Invalid sensor for retrieving clock activity\n");
923 static int arcturus_get_gpu_power(struct smu_context
*smu
, uint32_t *value
)
925 SmuMetrics_t metrics
;
931 ret
= arcturus_get_metrics_table(smu
, &metrics
);
935 *value
= metrics
.AverageSocketPower
<< 8;
940 static int arcturus_thermal_get_temperature(struct smu_context
*smu
,
941 enum amd_pp_sensors sensor
,
944 SmuMetrics_t metrics
;
950 ret
= arcturus_get_metrics_table(smu
, &metrics
);
955 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP
:
956 *value
= metrics
.TemperatureHotspot
*
957 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES
;
959 case AMDGPU_PP_SENSOR_EDGE_TEMP
:
960 *value
= metrics
.TemperatureEdge
*
961 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES
;
963 case AMDGPU_PP_SENSOR_MEM_TEMP
:
964 *value
= metrics
.TemperatureHBM
*
965 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES
;
968 pr_err("Invalid sensor for retrieving temp\n");
975 static int arcturus_read_sensor(struct smu_context
*smu
,
976 enum amd_pp_sensors sensor
,
977 void *data
, uint32_t *size
)
979 struct smu_table_context
*table_context
= &smu
->smu_table
;
980 PPTable_t
*pptable
= table_context
->driver_pptable
;
986 mutex_lock(&smu
->sensor_lock
);
988 case AMDGPU_PP_SENSOR_MAX_FAN_RPM
:
989 *(uint32_t *)data
= pptable
->FanMaximumRpm
;
992 case AMDGPU_PP_SENSOR_MEM_LOAD
:
993 case AMDGPU_PP_SENSOR_GPU_LOAD
:
994 ret
= arcturus_get_current_activity_percent(smu
,
999 case AMDGPU_PP_SENSOR_GPU_POWER
:
1000 ret
= arcturus_get_gpu_power(smu
, (uint32_t *)data
);
1003 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP
:
1004 case AMDGPU_PP_SENSOR_EDGE_TEMP
:
1005 case AMDGPU_PP_SENSOR_MEM_TEMP
:
1006 ret
= arcturus_thermal_get_temperature(smu
, sensor
,
1011 ret
= smu_v11_0_read_sensor(smu
, sensor
, data
, size
);
1013 mutex_unlock(&smu
->sensor_lock
);
1018 static int arcturus_get_fan_speed_rpm(struct smu_context
*smu
,
1021 SmuMetrics_t metrics
;
1027 ret
= arcturus_get_metrics_table(smu
, &metrics
);
1031 *speed
= metrics
.CurrFanSpeed
;
1036 static int arcturus_get_fan_speed_percent(struct smu_context
*smu
,
1039 PPTable_t
*pptable
= smu
->smu_table
.driver_pptable
;
1040 uint32_t percent
, current_rpm
;
1046 ret
= arcturus_get_fan_speed_rpm(smu
, ¤t_rpm
);
1050 percent
= current_rpm
* 100 / pptable
->FanMaximumRpm
;
1051 *speed
= percent
> 100 ? 100 : percent
;
1056 static int arcturus_get_current_clk_freq_by_table(struct smu_context
*smu
,
1057 enum smu_clk_type clk_type
,
1060 static SmuMetrics_t metrics
;
1061 int ret
= 0, clk_id
= 0;
1066 clk_id
= smu_clk_get_index(smu
, clk_type
);
1070 ret
= arcturus_get_metrics_table(smu
, &metrics
);
1077 * CurrClock[clk_id] can provide accurate
1078 * output only when the dpm feature is enabled.
1079 * We can use Average_* for dpm disabled case.
1080 * But this is available for gfxclk/uclk/socclk.
1082 if (smu_feature_is_enabled(smu
, SMU_FEATURE_DPM_GFXCLK_BIT
))
1083 *value
= metrics
.CurrClock
[PPCLK_GFXCLK
];
1085 *value
= metrics
.AverageGfxclkFrequency
;
1088 if (smu_feature_is_enabled(smu
, SMU_FEATURE_DPM_UCLK_BIT
))
1089 *value
= metrics
.CurrClock
[PPCLK_UCLK
];
1091 *value
= metrics
.AverageUclkFrequency
;
1094 if (smu_feature_is_enabled(smu
, SMU_FEATURE_DPM_SOCCLK_BIT
))
1095 *value
= metrics
.CurrClock
[PPCLK_SOCCLK
];
1097 *value
= metrics
.AverageSocclkFrequency
;
1100 *value
= metrics
.CurrClock
[clk_id
];
1107 static uint32_t arcturus_find_lowest_dpm_level(struct arcturus_single_dpm_table
*table
)
1111 for (i
= 0; i
< table
->count
; i
++) {
1112 if (table
->dpm_levels
[i
].enabled
)
1115 if (i
>= table
->count
) {
1117 table
->dpm_levels
[i
].enabled
= true;
1123 static uint32_t arcturus_find_highest_dpm_level(struct arcturus_single_dpm_table
*table
)
1127 if (table
->count
<= 0) {
1128 pr_err("[%s] DPM Table has no entry!", __func__
);
1131 if (table
->count
> MAX_DPM_NUMBER
) {
1132 pr_err("[%s] DPM Table has too many entries!", __func__
);
1133 return MAX_DPM_NUMBER
- 1;
1136 for (i
= table
->count
- 1; i
>= 0; i
--) {
1137 if (table
->dpm_levels
[i
].enabled
)
1142 table
->dpm_levels
[i
].enabled
= true;
1150 static int arcturus_force_dpm_limit_value(struct smu_context
*smu
, bool highest
)
1152 struct arcturus_dpm_table
*dpm_table
=
1153 (struct arcturus_dpm_table
*)smu
->smu_dpm
.dpm_context
;
1154 struct amdgpu_hive_info
*hive
= amdgpu_get_xgmi_hive(smu
->adev
, 0);
1155 uint32_t soft_level
;
1160 soft_level
= arcturus_find_highest_dpm_level(&(dpm_table
->gfx_table
));
1162 soft_level
= arcturus_find_lowest_dpm_level(&(dpm_table
->gfx_table
));
1164 dpm_table
->gfx_table
.dpm_state
.soft_min_level
=
1165 dpm_table
->gfx_table
.dpm_state
.soft_max_level
=
1166 dpm_table
->gfx_table
.dpm_levels
[soft_level
].value
;
1168 ret
= arcturus_upload_dpm_level(smu
, false, FEATURE_DPM_GFXCLK_MASK
);
1170 pr_err("Failed to upload boot level to %s!\n",
1171 highest
? "highest" : "lowest");
1175 ret
= arcturus_upload_dpm_level(smu
, true, FEATURE_DPM_GFXCLK_MASK
);
1177 pr_err("Failed to upload dpm max level to %s!\n!",
1178 highest
? "highest" : "lowest");
1184 * Force XGMI Pstate to highest or lowest
1185 * TODO: revise this when xgmi dpm is functional
1187 ret
= smu_v11_0_set_xgmi_pstate(smu
, highest
? 1 : 0);
1192 static int arcturus_unforce_dpm_levels(struct smu_context
*smu
)
1194 struct arcturus_dpm_table
*dpm_table
=
1195 (struct arcturus_dpm_table
*)smu
->smu_dpm
.dpm_context
;
1196 struct amdgpu_hive_info
*hive
= amdgpu_get_xgmi_hive(smu
->adev
, 0);
1197 uint32_t soft_min_level
, soft_max_level
;
1201 soft_min_level
= arcturus_find_lowest_dpm_level(&(dpm_table
->gfx_table
));
1202 soft_max_level
= arcturus_find_highest_dpm_level(&(dpm_table
->gfx_table
));
1203 dpm_table
->gfx_table
.dpm_state
.soft_min_level
=
1204 dpm_table
->gfx_table
.dpm_levels
[soft_min_level
].value
;
1205 dpm_table
->gfx_table
.dpm_state
.soft_max_level
=
1206 dpm_table
->gfx_table
.dpm_levels
[soft_max_level
].value
;
1208 ret
= arcturus_upload_dpm_level(smu
, false, FEATURE_DPM_GFXCLK_MASK
);
1210 pr_err("Failed to upload DPM Bootup Levels!");
1214 ret
= arcturus_upload_dpm_level(smu
, true, FEATURE_DPM_GFXCLK_MASK
);
1216 pr_err("Failed to upload DPM Max Levels!");
1222 * Reset XGMI Pstate back to default
1223 * TODO: revise this when xgmi dpm is functional
1225 ret
= smu_v11_0_set_xgmi_pstate(smu
, 0);
1231 arcturus_get_profiling_clk_mask(struct smu_context
*smu
,
1232 enum amd_dpm_forced_level level
,
1233 uint32_t *sclk_mask
,
1234 uint32_t *mclk_mask
,
1237 struct arcturus_dpm_table
*dpm_table
=
1238 (struct arcturus_dpm_table
*)smu
->smu_dpm
.dpm_context
;
1239 struct arcturus_single_dpm_table
*gfx_dpm_table
;
1240 struct arcturus_single_dpm_table
*mem_dpm_table
;
1241 struct arcturus_single_dpm_table
*soc_dpm_table
;
1243 if (!smu
->smu_dpm
.dpm_context
)
1246 gfx_dpm_table
= &dpm_table
->gfx_table
;
1247 mem_dpm_table
= &dpm_table
->mem_table
;
1248 soc_dpm_table
= &dpm_table
->soc_table
;
1254 if (gfx_dpm_table
->count
> ARCTURUS_UMD_PSTATE_GFXCLK_LEVEL
&&
1255 mem_dpm_table
->count
> ARCTURUS_UMD_PSTATE_MCLK_LEVEL
&&
1256 soc_dpm_table
->count
> ARCTURUS_UMD_PSTATE_SOCCLK_LEVEL
) {
1257 *sclk_mask
= ARCTURUS_UMD_PSTATE_GFXCLK_LEVEL
;
1258 *mclk_mask
= ARCTURUS_UMD_PSTATE_MCLK_LEVEL
;
1259 *soc_mask
= ARCTURUS_UMD_PSTATE_SOCCLK_LEVEL
;
1262 if (level
== AMD_DPM_FORCED_LEVEL_PROFILE_MIN_SCLK
) {
1264 } else if (level
== AMD_DPM_FORCED_LEVEL_PROFILE_MIN_MCLK
) {
1266 } else if (level
== AMD_DPM_FORCED_LEVEL_PROFILE_PEAK
) {
1267 *sclk_mask
= gfx_dpm_table
->count
- 1;
1268 *mclk_mask
= mem_dpm_table
->count
- 1;
1269 *soc_mask
= soc_dpm_table
->count
- 1;
1275 static int arcturus_get_power_limit(struct smu_context
*smu
,
1279 PPTable_t
*pptable
= smu
->smu_table
.driver_pptable
;
1280 uint32_t asic_default_power_limit
= 0;
1284 if (!smu
->power_limit
) {
1285 if (smu_feature_is_enabled(smu
, SMU_FEATURE_PPT_BIT
)) {
1286 power_src
= smu_power_get_index(smu
, SMU_POWER_SOURCE_AC
);
1290 ret
= smu_send_smc_msg_with_param(smu
, SMU_MSG_GetPptLimit
,
1293 pr_err("[%s] get PPT limit failed!", __func__
);
1296 smu_read_smc_arg(smu
, &asic_default_power_limit
);
1298 /* the last hope to figure out the ppt limit */
1300 pr_err("Cannot get PPT limit due to pptable missing!");
1303 asic_default_power_limit
=
1304 pptable
->SocketPowerLimitAc
[PPT_THROTTLER_PPT0
];
1307 smu
->power_limit
= asic_default_power_limit
;
1311 *limit
= smu_v11_0_get_max_power_limit(smu
);
1313 *limit
= smu
->power_limit
;
1318 static int arcturus_get_power_profile_mode(struct smu_context
*smu
,
1321 struct amdgpu_device
*adev
= smu
->adev
;
1322 DpmActivityMonitorCoeffInt_t activity_monitor
;
1323 static const char *profile_name
[] = {
1331 static const char *title
[] = {
1332 "PROFILE_INDEX(NAME)",
1336 "MinActiveFreqType",
1341 "PD_Data_error_coeff",
1342 "PD_Data_error_rate_coeff"};
1343 uint32_t i
, size
= 0;
1344 int16_t workload_type
= 0;
1346 uint32_t smu_version
;
1351 result
= smu_get_smc_version(smu
, NULL
, &smu_version
);
1355 if (smu_version
>= 0x360d00 && !amdgpu_sriov_vf(adev
))
1356 size
+= sprintf(buf
+ size
, "%16s %s %s %s %s %s %s %s %s %s %s\n",
1357 title
[0], title
[1], title
[2], title
[3], title
[4], title
[5],
1358 title
[6], title
[7], title
[8], title
[9], title
[10]);
1360 size
+= sprintf(buf
+ size
, "%16s\n",
1363 for (i
= 0; i
<= PP_SMC_POWER_PROFILE_CUSTOM
; i
++) {
1365 * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT
1366 * Not all profile modes are supported on arcturus.
1368 workload_type
= smu_workload_get_type(smu
, i
);
1369 if (workload_type
< 0)
1372 if (smu_version
>= 0x360d00 && !amdgpu_sriov_vf(adev
)) {
1373 result
= smu_update_table(smu
,
1374 SMU_TABLE_ACTIVITY_MONITOR_COEFF
,
1376 (void *)(&activity_monitor
),
1379 pr_err("[%s] Failed to get activity monitor!", __func__
);
1384 size
+= sprintf(buf
+ size
, "%2d %14s%s\n",
1385 i
, profile_name
[i
], (i
== smu
->power_profile_mode
) ? "*" : " ");
1387 if (smu_version
>= 0x360d00 && !amdgpu_sriov_vf(adev
)) {
1388 size
+= sprintf(buf
+ size
, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
1392 activity_monitor
.Gfx_FPS
,
1393 activity_monitor
.Gfx_UseRlcBusy
,
1394 activity_monitor
.Gfx_MinActiveFreqType
,
1395 activity_monitor
.Gfx_MinActiveFreq
,
1396 activity_monitor
.Gfx_BoosterFreqType
,
1397 activity_monitor
.Gfx_BoosterFreq
,
1398 activity_monitor
.Gfx_PD_Data_limit_c
,
1399 activity_monitor
.Gfx_PD_Data_error_coeff
,
1400 activity_monitor
.Gfx_PD_Data_error_rate_coeff
);
1402 size
+= sprintf(buf
+ size
, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n",
1406 activity_monitor
.Mem_FPS
,
1407 activity_monitor
.Mem_UseRlcBusy
,
1408 activity_monitor
.Mem_MinActiveFreqType
,
1409 activity_monitor
.Mem_MinActiveFreq
,
1410 activity_monitor
.Mem_BoosterFreqType
,
1411 activity_monitor
.Mem_BoosterFreq
,
1412 activity_monitor
.Mem_PD_Data_limit_c
,
1413 activity_monitor
.Mem_PD_Data_error_coeff
,
1414 activity_monitor
.Mem_PD_Data_error_rate_coeff
);
1421 static int arcturus_set_power_profile_mode(struct smu_context
*smu
,
1425 DpmActivityMonitorCoeffInt_t activity_monitor
;
1426 int workload_type
= 0;
1427 uint32_t profile_mode
= input
[size
];
1429 uint32_t smu_version
;
1431 if (profile_mode
> PP_SMC_POWER_PROFILE_CUSTOM
) {
1432 pr_err("Invalid power profile mode %d\n", profile_mode
);
1436 ret
= smu_get_smc_version(smu
, NULL
, &smu_version
);
1440 if ((profile_mode
== PP_SMC_POWER_PROFILE_CUSTOM
) &&
1441 (smu_version
>=0x360d00)) {
1442 ret
= smu_update_table(smu
,
1443 SMU_TABLE_ACTIVITY_MONITOR_COEFF
,
1444 WORKLOAD_PPLIB_CUSTOM_BIT
,
1445 (void *)(&activity_monitor
),
1448 pr_err("[%s] Failed to get activity monitor!", __func__
);
1453 case 0: /* Gfxclk */
1454 activity_monitor
.Gfx_FPS
= input
[1];
1455 activity_monitor
.Gfx_UseRlcBusy
= input
[2];
1456 activity_monitor
.Gfx_MinActiveFreqType
= input
[3];
1457 activity_monitor
.Gfx_MinActiveFreq
= input
[4];
1458 activity_monitor
.Gfx_BoosterFreqType
= input
[5];
1459 activity_monitor
.Gfx_BoosterFreq
= input
[6];
1460 activity_monitor
.Gfx_PD_Data_limit_c
= input
[7];
1461 activity_monitor
.Gfx_PD_Data_error_coeff
= input
[8];
1462 activity_monitor
.Gfx_PD_Data_error_rate_coeff
= input
[9];
1465 activity_monitor
.Mem_FPS
= input
[1];
1466 activity_monitor
.Mem_UseRlcBusy
= input
[2];
1467 activity_monitor
.Mem_MinActiveFreqType
= input
[3];
1468 activity_monitor
.Mem_MinActiveFreq
= input
[4];
1469 activity_monitor
.Mem_BoosterFreqType
= input
[5];
1470 activity_monitor
.Mem_BoosterFreq
= input
[6];
1471 activity_monitor
.Mem_PD_Data_limit_c
= input
[7];
1472 activity_monitor
.Mem_PD_Data_error_coeff
= input
[8];
1473 activity_monitor
.Mem_PD_Data_error_rate_coeff
= input
[9];
1477 ret
= smu_update_table(smu
,
1478 SMU_TABLE_ACTIVITY_MONITOR_COEFF
,
1479 WORKLOAD_PPLIB_CUSTOM_BIT
,
1480 (void *)(&activity_monitor
),
1483 pr_err("[%s] Failed to set activity monitor!", __func__
);
1489 * Conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT
1490 * Not all profile modes are supported on arcturus.
1492 workload_type
= smu_workload_get_type(smu
, profile_mode
);
1493 if (workload_type
< 0) {
1494 pr_err("Unsupported power profile mode %d on arcturus\n", profile_mode
);
1498 ret
= smu_send_smc_msg_with_param(smu
,
1499 SMU_MSG_SetWorkloadMask
,
1500 1 << workload_type
);
1502 pr_err("Fail to set workload type %d\n", workload_type
);
1506 smu
->power_profile_mode
= profile_mode
;
1511 static void arcturus_dump_pptable(struct smu_context
*smu
)
1513 struct smu_table_context
*table_context
= &smu
->smu_table
;
1514 PPTable_t
*pptable
= table_context
->driver_pptable
;
1517 pr_info("Dumped PPTable:\n");
1519 pr_info("Version = 0x%08x\n", pptable
->Version
);
1521 pr_info("FeaturesToRun[0] = 0x%08x\n", pptable
->FeaturesToRun
[0]);
1522 pr_info("FeaturesToRun[1] = 0x%08x\n", pptable
->FeaturesToRun
[1]);
1524 for (i
= 0; i
< PPT_THROTTLER_COUNT
; i
++) {
1525 pr_info("SocketPowerLimitAc[%d] = %d\n", i
, pptable
->SocketPowerLimitAc
[i
]);
1526 pr_info("SocketPowerLimitAcTau[%d] = %d\n", i
, pptable
->SocketPowerLimitAcTau
[i
]);
1529 pr_info("TdcLimitSoc = %d\n", pptable
->TdcLimitSoc
);
1530 pr_info("TdcLimitSocTau = %d\n", pptable
->TdcLimitSocTau
);
1531 pr_info("TdcLimitGfx = %d\n", pptable
->TdcLimitGfx
);
1532 pr_info("TdcLimitGfxTau = %d\n", pptable
->TdcLimitGfxTau
);
1534 pr_info("TedgeLimit = %d\n", pptable
->TedgeLimit
);
1535 pr_info("ThotspotLimit = %d\n", pptable
->ThotspotLimit
);
1536 pr_info("TmemLimit = %d\n", pptable
->TmemLimit
);
1537 pr_info("Tvr_gfxLimit = %d\n", pptable
->Tvr_gfxLimit
);
1538 pr_info("Tvr_memLimit = %d\n", pptable
->Tvr_memLimit
);
1539 pr_info("Tvr_socLimit = %d\n", pptable
->Tvr_socLimit
);
1540 pr_info("FitLimit = %d\n", pptable
->FitLimit
);
1542 pr_info("PpmPowerLimit = %d\n", pptable
->PpmPowerLimit
);
1543 pr_info("PpmTemperatureThreshold = %d\n", pptable
->PpmTemperatureThreshold
);
1545 pr_info("ThrottlerControlMask = %d\n", pptable
->ThrottlerControlMask
);
1547 pr_info("UlvVoltageOffsetGfx = %d\n", pptable
->UlvVoltageOffsetGfx
);
1548 pr_info("UlvPadding = 0x%08x\n", pptable
->UlvPadding
);
1550 pr_info("UlvGfxclkBypass = %d\n", pptable
->UlvGfxclkBypass
);
1551 pr_info("Padding234[0] = 0x%02x\n", pptable
->Padding234
[0]);
1552 pr_info("Padding234[1] = 0x%02x\n", pptable
->Padding234
[1]);
1553 pr_info("Padding234[2] = 0x%02x\n", pptable
->Padding234
[2]);
1555 pr_info("MinVoltageGfx = %d\n", pptable
->MinVoltageGfx
);
1556 pr_info("MinVoltageSoc = %d\n", pptable
->MinVoltageSoc
);
1557 pr_info("MaxVoltageGfx = %d\n", pptable
->MaxVoltageGfx
);
1558 pr_info("MaxVoltageSoc = %d\n", pptable
->MaxVoltageSoc
);
1560 pr_info("LoadLineResistanceGfx = %d\n", pptable
->LoadLineResistanceGfx
);
1561 pr_info("LoadLineResistanceSoc = %d\n", pptable
->LoadLineResistanceSoc
);
1563 pr_info("[PPCLK_GFXCLK]\n"
1564 " .VoltageMode = 0x%02x\n"
1565 " .SnapToDiscrete = 0x%02x\n"
1566 " .NumDiscreteLevels = 0x%02x\n"
1567 " .padding = 0x%02x\n"
1568 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1569 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1570 " .SsFmin = 0x%04x\n"
1571 " .Padding_16 = 0x%04x\n",
1572 pptable
->DpmDescriptor
[PPCLK_GFXCLK
].VoltageMode
,
1573 pptable
->DpmDescriptor
[PPCLK_GFXCLK
].SnapToDiscrete
,
1574 pptable
->DpmDescriptor
[PPCLK_GFXCLK
].NumDiscreteLevels
,
1575 pptable
->DpmDescriptor
[PPCLK_GFXCLK
].padding
,
1576 pptable
->DpmDescriptor
[PPCLK_GFXCLK
].ConversionToAvfsClk
.m
,
1577 pptable
->DpmDescriptor
[PPCLK_GFXCLK
].ConversionToAvfsClk
.b
,
1578 pptable
->DpmDescriptor
[PPCLK_GFXCLK
].SsCurve
.a
,
1579 pptable
->DpmDescriptor
[PPCLK_GFXCLK
].SsCurve
.b
,
1580 pptable
->DpmDescriptor
[PPCLK_GFXCLK
].SsCurve
.c
,
1581 pptable
->DpmDescriptor
[PPCLK_GFXCLK
].SsFmin
,
1582 pptable
->DpmDescriptor
[PPCLK_GFXCLK
].Padding16
);
1584 pr_info("[PPCLK_VCLK]\n"
1585 " .VoltageMode = 0x%02x\n"
1586 " .SnapToDiscrete = 0x%02x\n"
1587 " .NumDiscreteLevels = 0x%02x\n"
1588 " .padding = 0x%02x\n"
1589 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1590 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1591 " .SsFmin = 0x%04x\n"
1592 " .Padding_16 = 0x%04x\n",
1593 pptable
->DpmDescriptor
[PPCLK_VCLK
].VoltageMode
,
1594 pptable
->DpmDescriptor
[PPCLK_VCLK
].SnapToDiscrete
,
1595 pptable
->DpmDescriptor
[PPCLK_VCLK
].NumDiscreteLevels
,
1596 pptable
->DpmDescriptor
[PPCLK_VCLK
].padding
,
1597 pptable
->DpmDescriptor
[PPCLK_VCLK
].ConversionToAvfsClk
.m
,
1598 pptable
->DpmDescriptor
[PPCLK_VCLK
].ConversionToAvfsClk
.b
,
1599 pptable
->DpmDescriptor
[PPCLK_VCLK
].SsCurve
.a
,
1600 pptable
->DpmDescriptor
[PPCLK_VCLK
].SsCurve
.b
,
1601 pptable
->DpmDescriptor
[PPCLK_VCLK
].SsCurve
.c
,
1602 pptable
->DpmDescriptor
[PPCLK_VCLK
].SsFmin
,
1603 pptable
->DpmDescriptor
[PPCLK_VCLK
].Padding16
);
1605 pr_info("[PPCLK_DCLK]\n"
1606 " .VoltageMode = 0x%02x\n"
1607 " .SnapToDiscrete = 0x%02x\n"
1608 " .NumDiscreteLevels = 0x%02x\n"
1609 " .padding = 0x%02x\n"
1610 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1611 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1612 " .SsFmin = 0x%04x\n"
1613 " .Padding_16 = 0x%04x\n",
1614 pptable
->DpmDescriptor
[PPCLK_DCLK
].VoltageMode
,
1615 pptable
->DpmDescriptor
[PPCLK_DCLK
].SnapToDiscrete
,
1616 pptable
->DpmDescriptor
[PPCLK_DCLK
].NumDiscreteLevels
,
1617 pptable
->DpmDescriptor
[PPCLK_DCLK
].padding
,
1618 pptable
->DpmDescriptor
[PPCLK_DCLK
].ConversionToAvfsClk
.m
,
1619 pptable
->DpmDescriptor
[PPCLK_DCLK
].ConversionToAvfsClk
.b
,
1620 pptable
->DpmDescriptor
[PPCLK_DCLK
].SsCurve
.a
,
1621 pptable
->DpmDescriptor
[PPCLK_DCLK
].SsCurve
.b
,
1622 pptable
->DpmDescriptor
[PPCLK_DCLK
].SsCurve
.c
,
1623 pptable
->DpmDescriptor
[PPCLK_DCLK
].SsFmin
,
1624 pptable
->DpmDescriptor
[PPCLK_DCLK
].Padding16
);
1626 pr_info("[PPCLK_SOCCLK]\n"
1627 " .VoltageMode = 0x%02x\n"
1628 " .SnapToDiscrete = 0x%02x\n"
1629 " .NumDiscreteLevels = 0x%02x\n"
1630 " .padding = 0x%02x\n"
1631 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1632 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1633 " .SsFmin = 0x%04x\n"
1634 " .Padding_16 = 0x%04x\n",
1635 pptable
->DpmDescriptor
[PPCLK_SOCCLK
].VoltageMode
,
1636 pptable
->DpmDescriptor
[PPCLK_SOCCLK
].SnapToDiscrete
,
1637 pptable
->DpmDescriptor
[PPCLK_SOCCLK
].NumDiscreteLevels
,
1638 pptable
->DpmDescriptor
[PPCLK_SOCCLK
].padding
,
1639 pptable
->DpmDescriptor
[PPCLK_SOCCLK
].ConversionToAvfsClk
.m
,
1640 pptable
->DpmDescriptor
[PPCLK_SOCCLK
].ConversionToAvfsClk
.b
,
1641 pptable
->DpmDescriptor
[PPCLK_SOCCLK
].SsCurve
.a
,
1642 pptable
->DpmDescriptor
[PPCLK_SOCCLK
].SsCurve
.b
,
1643 pptable
->DpmDescriptor
[PPCLK_SOCCLK
].SsCurve
.c
,
1644 pptable
->DpmDescriptor
[PPCLK_SOCCLK
].SsFmin
,
1645 pptable
->DpmDescriptor
[PPCLK_SOCCLK
].Padding16
);
1647 pr_info("[PPCLK_UCLK]\n"
1648 " .VoltageMode = 0x%02x\n"
1649 " .SnapToDiscrete = 0x%02x\n"
1650 " .NumDiscreteLevels = 0x%02x\n"
1651 " .padding = 0x%02x\n"
1652 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1653 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1654 " .SsFmin = 0x%04x\n"
1655 " .Padding_16 = 0x%04x\n",
1656 pptable
->DpmDescriptor
[PPCLK_UCLK
].VoltageMode
,
1657 pptable
->DpmDescriptor
[PPCLK_UCLK
].SnapToDiscrete
,
1658 pptable
->DpmDescriptor
[PPCLK_UCLK
].NumDiscreteLevels
,
1659 pptable
->DpmDescriptor
[PPCLK_UCLK
].padding
,
1660 pptable
->DpmDescriptor
[PPCLK_UCLK
].ConversionToAvfsClk
.m
,
1661 pptable
->DpmDescriptor
[PPCLK_UCLK
].ConversionToAvfsClk
.b
,
1662 pptable
->DpmDescriptor
[PPCLK_UCLK
].SsCurve
.a
,
1663 pptable
->DpmDescriptor
[PPCLK_UCLK
].SsCurve
.b
,
1664 pptable
->DpmDescriptor
[PPCLK_UCLK
].SsCurve
.c
,
1665 pptable
->DpmDescriptor
[PPCLK_UCLK
].SsFmin
,
1666 pptable
->DpmDescriptor
[PPCLK_UCLK
].Padding16
);
1668 pr_info("[PPCLK_FCLK]\n"
1669 " .VoltageMode = 0x%02x\n"
1670 " .SnapToDiscrete = 0x%02x\n"
1671 " .NumDiscreteLevels = 0x%02x\n"
1672 " .padding = 0x%02x\n"
1673 " .ConversionToAvfsClk{m = 0x%08x b = 0x%08x}\n"
1674 " .SsCurve {a = 0x%08x b = 0x%08x c = 0x%08x}\n"
1675 " .SsFmin = 0x%04x\n"
1676 " .Padding_16 = 0x%04x\n",
1677 pptable
->DpmDescriptor
[PPCLK_FCLK
].VoltageMode
,
1678 pptable
->DpmDescriptor
[PPCLK_FCLK
].SnapToDiscrete
,
1679 pptable
->DpmDescriptor
[PPCLK_FCLK
].NumDiscreteLevels
,
1680 pptable
->DpmDescriptor
[PPCLK_FCLK
].padding
,
1681 pptable
->DpmDescriptor
[PPCLK_FCLK
].ConversionToAvfsClk
.m
,
1682 pptable
->DpmDescriptor
[PPCLK_FCLK
].ConversionToAvfsClk
.b
,
1683 pptable
->DpmDescriptor
[PPCLK_FCLK
].SsCurve
.a
,
1684 pptable
->DpmDescriptor
[PPCLK_FCLK
].SsCurve
.b
,
1685 pptable
->DpmDescriptor
[PPCLK_FCLK
].SsCurve
.c
,
1686 pptable
->DpmDescriptor
[PPCLK_FCLK
].SsFmin
,
1687 pptable
->DpmDescriptor
[PPCLK_FCLK
].Padding16
);
1690 pr_info("FreqTableGfx\n");
1691 for (i
= 0; i
< NUM_GFXCLK_DPM_LEVELS
; i
++)
1692 pr_info(" .[%02d] = %d\n", i
, pptable
->FreqTableGfx
[i
]);
1694 pr_info("FreqTableVclk\n");
1695 for (i
= 0; i
< NUM_VCLK_DPM_LEVELS
; i
++)
1696 pr_info(" .[%02d] = %d\n", i
, pptable
->FreqTableVclk
[i
]);
1698 pr_info("FreqTableDclk\n");
1699 for (i
= 0; i
< NUM_DCLK_DPM_LEVELS
; i
++)
1700 pr_info(" .[%02d] = %d\n", i
, pptable
->FreqTableDclk
[i
]);
1702 pr_info("FreqTableSocclk\n");
1703 for (i
= 0; i
< NUM_SOCCLK_DPM_LEVELS
; i
++)
1704 pr_info(" .[%02d] = %d\n", i
, pptable
->FreqTableSocclk
[i
]);
1706 pr_info("FreqTableUclk\n");
1707 for (i
= 0; i
< NUM_UCLK_DPM_LEVELS
; i
++)
1708 pr_info(" .[%02d] = %d\n", i
, pptable
->FreqTableUclk
[i
]);
1710 pr_info("FreqTableFclk\n");
1711 for (i
= 0; i
< NUM_FCLK_DPM_LEVELS
; i
++)
1712 pr_info(" .[%02d] = %d\n", i
, pptable
->FreqTableFclk
[i
]);
1714 pr_info("Mp0clkFreq\n");
1715 for (i
= 0; i
< NUM_MP0CLK_DPM_LEVELS
; i
++)
1716 pr_info(" .[%d] = %d\n", i
, pptable
->Mp0clkFreq
[i
]);
1718 pr_info("Mp0DpmVoltage\n");
1719 for (i
= 0; i
< NUM_MP0CLK_DPM_LEVELS
; i
++)
1720 pr_info(" .[%d] = %d\n", i
, pptable
->Mp0DpmVoltage
[i
]);
1722 pr_info("GfxclkFidle = 0x%x\n", pptable
->GfxclkFidle
);
1723 pr_info("GfxclkSlewRate = 0x%x\n", pptable
->GfxclkSlewRate
);
1724 pr_info("Padding567[0] = 0x%x\n", pptable
->Padding567
[0]);
1725 pr_info("Padding567[1] = 0x%x\n", pptable
->Padding567
[1]);
1726 pr_info("Padding567[2] = 0x%x\n", pptable
->Padding567
[2]);
1727 pr_info("Padding567[3] = 0x%x\n", pptable
->Padding567
[3]);
1728 pr_info("GfxclkDsMaxFreq = %d\n", pptable
->GfxclkDsMaxFreq
);
1729 pr_info("GfxclkSource = 0x%x\n", pptable
->GfxclkSource
);
1730 pr_info("Padding456 = 0x%x\n", pptable
->Padding456
);
1732 pr_info("EnableTdpm = %d\n", pptable
->EnableTdpm
);
1733 pr_info("TdpmHighHystTemperature = %d\n", pptable
->TdpmHighHystTemperature
);
1734 pr_info("TdpmLowHystTemperature = %d\n", pptable
->TdpmLowHystTemperature
);
1735 pr_info("GfxclkFreqHighTempLimit = %d\n", pptable
->GfxclkFreqHighTempLimit
);
1737 pr_info("FanStopTemp = %d\n", pptable
->FanStopTemp
);
1738 pr_info("FanStartTemp = %d\n", pptable
->FanStartTemp
);
1740 pr_info("FanGainEdge = %d\n", pptable
->FanGainEdge
);
1741 pr_info("FanGainHotspot = %d\n", pptable
->FanGainHotspot
);
1742 pr_info("FanGainVrGfx = %d\n", pptable
->FanGainVrGfx
);
1743 pr_info("FanGainVrSoc = %d\n", pptable
->FanGainVrSoc
);
1744 pr_info("FanGainVrMem = %d\n", pptable
->FanGainVrMem
);
1745 pr_info("FanGainHbm = %d\n", pptable
->FanGainHbm
);
1747 pr_info("FanPwmMin = %d\n", pptable
->FanPwmMin
);
1748 pr_info("FanAcousticLimitRpm = %d\n", pptable
->FanAcousticLimitRpm
);
1749 pr_info("FanThrottlingRpm = %d\n", pptable
->FanThrottlingRpm
);
1750 pr_info("FanMaximumRpm = %d\n", pptable
->FanMaximumRpm
);
1751 pr_info("FanTargetTemperature = %d\n", pptable
->FanTargetTemperature
);
1752 pr_info("FanTargetGfxclk = %d\n", pptable
->FanTargetGfxclk
);
1753 pr_info("FanZeroRpmEnable = %d\n", pptable
->FanZeroRpmEnable
);
1754 pr_info("FanTachEdgePerRev = %d\n", pptable
->FanTachEdgePerRev
);
1755 pr_info("FanTempInputSelect = %d\n", pptable
->FanTempInputSelect
);
1757 pr_info("FuzzyFan_ErrorSetDelta = %d\n", pptable
->FuzzyFan_ErrorSetDelta
);
1758 pr_info("FuzzyFan_ErrorRateSetDelta = %d\n", pptable
->FuzzyFan_ErrorRateSetDelta
);
1759 pr_info("FuzzyFan_PwmSetDelta = %d\n", pptable
->FuzzyFan_PwmSetDelta
);
1760 pr_info("FuzzyFan_Reserved = %d\n", pptable
->FuzzyFan_Reserved
);
1762 pr_info("OverrideAvfsGb[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable
->OverrideAvfsGb
[AVFS_VOLTAGE_GFX
]);
1763 pr_info("OverrideAvfsGb[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable
->OverrideAvfsGb
[AVFS_VOLTAGE_SOC
]);
1764 pr_info("Padding8_Avfs[0] = %d\n", pptable
->Padding8_Avfs
[0]);
1765 pr_info("Padding8_Avfs[1] = %d\n", pptable
->Padding8_Avfs
[1]);
1767 pr_info("dBtcGbGfxPll{a = 0x%x b = 0x%x c = 0x%x}\n",
1768 pptable
->dBtcGbGfxPll
.a
,
1769 pptable
->dBtcGbGfxPll
.b
,
1770 pptable
->dBtcGbGfxPll
.c
);
1771 pr_info("dBtcGbGfxAfll{a = 0x%x b = 0x%x c = 0x%x}\n",
1772 pptable
->dBtcGbGfxAfll
.a
,
1773 pptable
->dBtcGbGfxAfll
.b
,
1774 pptable
->dBtcGbGfxAfll
.c
);
1775 pr_info("dBtcGbSoc{a = 0x%x b = 0x%x c = 0x%x}\n",
1776 pptable
->dBtcGbSoc
.a
,
1777 pptable
->dBtcGbSoc
.b
,
1778 pptable
->dBtcGbSoc
.c
);
1780 pr_info("qAgingGb[AVFS_VOLTAGE_GFX]{m = 0x%x b = 0x%x}\n",
1781 pptable
->qAgingGb
[AVFS_VOLTAGE_GFX
].m
,
1782 pptable
->qAgingGb
[AVFS_VOLTAGE_GFX
].b
);
1783 pr_info("qAgingGb[AVFS_VOLTAGE_SOC]{m = 0x%x b = 0x%x}\n",
1784 pptable
->qAgingGb
[AVFS_VOLTAGE_SOC
].m
,
1785 pptable
->qAgingGb
[AVFS_VOLTAGE_SOC
].b
);
1787 pr_info("qStaticVoltageOffset[AVFS_VOLTAGE_GFX]{a = 0x%x b = 0x%x c = 0x%x}\n",
1788 pptable
->qStaticVoltageOffset
[AVFS_VOLTAGE_GFX
].a
,
1789 pptable
->qStaticVoltageOffset
[AVFS_VOLTAGE_GFX
].b
,
1790 pptable
->qStaticVoltageOffset
[AVFS_VOLTAGE_GFX
].c
);
1791 pr_info("qStaticVoltageOffset[AVFS_VOLTAGE_SOC]{a = 0x%x b = 0x%x c = 0x%x}\n",
1792 pptable
->qStaticVoltageOffset
[AVFS_VOLTAGE_SOC
].a
,
1793 pptable
->qStaticVoltageOffset
[AVFS_VOLTAGE_SOC
].b
,
1794 pptable
->qStaticVoltageOffset
[AVFS_VOLTAGE_SOC
].c
);
1796 pr_info("DcTol[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable
->DcTol
[AVFS_VOLTAGE_GFX
]);
1797 pr_info("DcTol[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable
->DcTol
[AVFS_VOLTAGE_SOC
]);
1799 pr_info("DcBtcEnabled[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable
->DcBtcEnabled
[AVFS_VOLTAGE_GFX
]);
1800 pr_info("DcBtcEnabled[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable
->DcBtcEnabled
[AVFS_VOLTAGE_SOC
]);
1801 pr_info("Padding8_GfxBtc[0] = 0x%x\n", pptable
->Padding8_GfxBtc
[0]);
1802 pr_info("Padding8_GfxBtc[1] = 0x%x\n", pptable
->Padding8_GfxBtc
[1]);
1804 pr_info("DcBtcMin[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable
->DcBtcMin
[AVFS_VOLTAGE_GFX
]);
1805 pr_info("DcBtcMin[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable
->DcBtcMin
[AVFS_VOLTAGE_SOC
]);
1806 pr_info("DcBtcMax[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable
->DcBtcMax
[AVFS_VOLTAGE_GFX
]);
1807 pr_info("DcBtcMax[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable
->DcBtcMax
[AVFS_VOLTAGE_SOC
]);
1809 pr_info("DcBtcGb[AVFS_VOLTAGE_GFX] = 0x%x\n", pptable
->DcBtcGb
[AVFS_VOLTAGE_GFX
]);
1810 pr_info("DcBtcGb[AVFS_VOLTAGE_SOC] = 0x%x\n", pptable
->DcBtcGb
[AVFS_VOLTAGE_SOC
]);
1812 pr_info("XgmiDpmPstates\n");
1813 for (i
= 0; i
< NUM_XGMI_LEVELS
; i
++)
1814 pr_info(" .[%d] = %d\n", i
, pptable
->XgmiDpmPstates
[i
]);
1815 pr_info("XgmiDpmSpare[0] = 0x%02x\n", pptable
->XgmiDpmSpare
[0]);
1816 pr_info("XgmiDpmSpare[1] = 0x%02x\n", pptable
->XgmiDpmSpare
[1]);
1818 pr_info("VDDGFX_TVmin = %d\n", pptable
->VDDGFX_TVmin
);
1819 pr_info("VDDSOC_TVmin = %d\n", pptable
->VDDSOC_TVmin
);
1820 pr_info("VDDGFX_Vmin_HiTemp = %d\n", pptable
->VDDGFX_Vmin_HiTemp
);
1821 pr_info("VDDGFX_Vmin_LoTemp = %d\n", pptable
->VDDGFX_Vmin_LoTemp
);
1822 pr_info("VDDSOC_Vmin_HiTemp = %d\n", pptable
->VDDSOC_Vmin_HiTemp
);
1823 pr_info("VDDSOC_Vmin_LoTemp = %d\n", pptable
->VDDSOC_Vmin_LoTemp
);
1824 pr_info("VDDGFX_TVminHystersis = %d\n", pptable
->VDDGFX_TVminHystersis
);
1825 pr_info("VDDSOC_TVminHystersis = %d\n", pptable
->VDDSOC_TVminHystersis
);
1827 pr_info("DebugOverrides = 0x%x\n", pptable
->DebugOverrides
);
1828 pr_info("ReservedEquation0{a = 0x%x b = 0x%x c = 0x%x}\n",
1829 pptable
->ReservedEquation0
.a
,
1830 pptable
->ReservedEquation0
.b
,
1831 pptable
->ReservedEquation0
.c
);
1832 pr_info("ReservedEquation1{a = 0x%x b = 0x%x c = 0x%x}\n",
1833 pptable
->ReservedEquation1
.a
,
1834 pptable
->ReservedEquation1
.b
,
1835 pptable
->ReservedEquation1
.c
);
1836 pr_info("ReservedEquation2{a = 0x%x b = 0x%x c = 0x%x}\n",
1837 pptable
->ReservedEquation2
.a
,
1838 pptable
->ReservedEquation2
.b
,
1839 pptable
->ReservedEquation2
.c
);
1840 pr_info("ReservedEquation3{a = 0x%x b = 0x%x c = 0x%x}\n",
1841 pptable
->ReservedEquation3
.a
,
1842 pptable
->ReservedEquation3
.b
,
1843 pptable
->ReservedEquation3
.c
);
1845 pr_info("MinVoltageUlvGfx = %d\n", pptable
->MinVoltageUlvGfx
);
1846 pr_info("PaddingUlv = %d\n", pptable
->PaddingUlv
);
1848 pr_info("TotalPowerConfig = %d\n", pptable
->TotalPowerConfig
);
1849 pr_info("TotalPowerSpare1 = %d\n", pptable
->TotalPowerSpare1
);
1850 pr_info("TotalPowerSpare2 = %d\n", pptable
->TotalPowerSpare2
);
1852 pr_info("PccThresholdLow = %d\n", pptable
->PccThresholdLow
);
1853 pr_info("PccThresholdHigh = %d\n", pptable
->PccThresholdHigh
);
1855 pr_info("Board Parameters:\n");
1856 pr_info("MaxVoltageStepGfx = 0x%x\n", pptable
->MaxVoltageStepGfx
);
1857 pr_info("MaxVoltageStepSoc = 0x%x\n", pptable
->MaxVoltageStepSoc
);
1859 pr_info("VddGfxVrMapping = 0x%x\n", pptable
->VddGfxVrMapping
);
1860 pr_info("VddSocVrMapping = 0x%x\n", pptable
->VddSocVrMapping
);
1861 pr_info("VddMemVrMapping = 0x%x\n", pptable
->VddMemVrMapping
);
1862 pr_info("BoardVrMapping = 0x%x\n", pptable
->BoardVrMapping
);
1864 pr_info("GfxUlvPhaseSheddingMask = 0x%x\n", pptable
->GfxUlvPhaseSheddingMask
);
1865 pr_info("ExternalSensorPresent = 0x%x\n", pptable
->ExternalSensorPresent
);
1867 pr_info("GfxMaxCurrent = 0x%x\n", pptable
->GfxMaxCurrent
);
1868 pr_info("GfxOffset = 0x%x\n", pptable
->GfxOffset
);
1869 pr_info("Padding_TelemetryGfx = 0x%x\n", pptable
->Padding_TelemetryGfx
);
1871 pr_info("SocMaxCurrent = 0x%x\n", pptable
->SocMaxCurrent
);
1872 pr_info("SocOffset = 0x%x\n", pptable
->SocOffset
);
1873 pr_info("Padding_TelemetrySoc = 0x%x\n", pptable
->Padding_TelemetrySoc
);
1875 pr_info("MemMaxCurrent = 0x%x\n", pptable
->MemMaxCurrent
);
1876 pr_info("MemOffset = 0x%x\n", pptable
->MemOffset
);
1877 pr_info("Padding_TelemetryMem = 0x%x\n", pptable
->Padding_TelemetryMem
);
1879 pr_info("BoardMaxCurrent = 0x%x\n", pptable
->BoardMaxCurrent
);
1880 pr_info("BoardOffset = 0x%x\n", pptable
->BoardOffset
);
1881 pr_info("Padding_TelemetryBoardInput = 0x%x\n", pptable
->Padding_TelemetryBoardInput
);
1883 pr_info("VR0HotGpio = %d\n", pptable
->VR0HotGpio
);
1884 pr_info("VR0HotPolarity = %d\n", pptable
->VR0HotPolarity
);
1885 pr_info("VR1HotGpio = %d\n", pptable
->VR1HotGpio
);
1886 pr_info("VR1HotPolarity = %d\n", pptable
->VR1HotPolarity
);
1888 pr_info("PllGfxclkSpreadEnabled = %d\n", pptable
->PllGfxclkSpreadEnabled
);
1889 pr_info("PllGfxclkSpreadPercent = %d\n", pptable
->PllGfxclkSpreadPercent
);
1890 pr_info("PllGfxclkSpreadFreq = %d\n", pptable
->PllGfxclkSpreadFreq
);
1892 pr_info("UclkSpreadEnabled = %d\n", pptable
->UclkSpreadEnabled
);
1893 pr_info("UclkSpreadPercent = %d\n", pptable
->UclkSpreadPercent
);
1894 pr_info("UclkSpreadFreq = %d\n", pptable
->UclkSpreadFreq
);
1896 pr_info("FclkSpreadEnabled = %d\n", pptable
->FclkSpreadEnabled
);
1897 pr_info("FclkSpreadPercent = %d\n", pptable
->FclkSpreadPercent
);
1898 pr_info("FclkSpreadFreq = %d\n", pptable
->FclkSpreadFreq
);
1900 pr_info("FllGfxclkSpreadEnabled = %d\n", pptable
->FllGfxclkSpreadEnabled
);
1901 pr_info("FllGfxclkSpreadPercent = %d\n", pptable
->FllGfxclkSpreadPercent
);
1902 pr_info("FllGfxclkSpreadFreq = %d\n", pptable
->FllGfxclkSpreadFreq
);
1904 for (i
= 0; i
< NUM_I2C_CONTROLLERS
; i
++) {
1905 pr_info("I2cControllers[%d]:\n", i
);
1906 pr_info(" .Enabled = %d\n",
1907 pptable
->I2cControllers
[i
].Enabled
);
1908 pr_info(" .SlaveAddress = 0x%x\n",
1909 pptable
->I2cControllers
[i
].SlaveAddress
);
1910 pr_info(" .ControllerPort = %d\n",
1911 pptable
->I2cControllers
[i
].ControllerPort
);
1912 pr_info(" .ControllerName = %d\n",
1913 pptable
->I2cControllers
[i
].ControllerName
);
1914 pr_info(" .ThermalThrottler = %d\n",
1915 pptable
->I2cControllers
[i
].ThermalThrotter
);
1916 pr_info(" .I2cProtocol = %d\n",
1917 pptable
->I2cControllers
[i
].I2cProtocol
);
1918 pr_info(" .Speed = %d\n",
1919 pptable
->I2cControllers
[i
].Speed
);
1922 pr_info("MemoryChannelEnabled = %d\n", pptable
->MemoryChannelEnabled
);
1923 pr_info("DramBitWidth = %d\n", pptable
->DramBitWidth
);
1925 pr_info("TotalBoardPower = %d\n", pptable
->TotalBoardPower
);
1927 pr_info("XgmiLinkSpeed\n");
1928 for (i
= 0; i
< NUM_XGMI_PSTATE_LEVELS
; i
++)
1929 pr_info(" .[%d] = %d\n", i
, pptable
->XgmiLinkSpeed
[i
]);
1930 pr_info("XgmiLinkWidth\n");
1931 for (i
= 0; i
< NUM_XGMI_PSTATE_LEVELS
; i
++)
1932 pr_info(" .[%d] = %d\n", i
, pptable
->XgmiLinkWidth
[i
]);
1933 pr_info("XgmiFclkFreq\n");
1934 for (i
= 0; i
< NUM_XGMI_PSTATE_LEVELS
; i
++)
1935 pr_info(" .[%d] = %d\n", i
, pptable
->XgmiFclkFreq
[i
]);
1936 pr_info("XgmiSocVoltage\n");
1937 for (i
= 0; i
< NUM_XGMI_PSTATE_LEVELS
; i
++)
1938 pr_info(" .[%d] = %d\n", i
, pptable
->XgmiSocVoltage
[i
]);
1942 static bool arcturus_is_dpm_running(struct smu_context
*smu
)
1945 uint32_t feature_mask
[2];
1946 unsigned long feature_enabled
;
1947 ret
= smu_feature_get_enabled_mask(smu
, feature_mask
, 2);
1948 feature_enabled
= (unsigned long)((uint64_t)feature_mask
[0] |
1949 ((uint64_t)feature_mask
[1] << 32));
1950 return !!(feature_enabled
& SMC_DPM_FEATURE
);
1953 static int arcturus_dpm_set_uvd_enable(struct smu_context
*smu
, bool enable
)
1955 struct smu_power_context
*smu_power
= &smu
->smu_power
;
1956 struct smu_power_gate
*power_gate
= &smu_power
->power_gate
;
1960 if (!smu_feature_is_enabled(smu
, SMU_FEATURE_VCN_PG_BIT
)) {
1961 ret
= smu_feature_set_enabled(smu
, SMU_FEATURE_VCN_PG_BIT
, 1);
1963 pr_err("[EnableVCNDPM] failed!\n");
1967 power_gate
->vcn_gated
= false;
1969 if (smu_feature_is_enabled(smu
, SMU_FEATURE_VCN_PG_BIT
)) {
1970 ret
= smu_feature_set_enabled(smu
, SMU_FEATURE_VCN_PG_BIT
, 0);
1972 pr_err("[DisableVCNDPM] failed!\n");
1976 power_gate
->vcn_gated
= true;
1983 static void arcturus_fill_eeprom_i2c_req(SwI2cRequest_t
*req
, bool write
,
1984 uint8_t address
, uint32_t numbytes
,
1989 BUG_ON(numbytes
> MAX_SW_I2C_COMMANDS
);
1991 req
->I2CcontrollerPort
= 0;
1993 req
->SlaveAddress
= address
;
1994 req
->NumCmds
= numbytes
;
1996 for (i
= 0; i
< numbytes
; i
++) {
1997 SwI2cCmd_t
*cmd
= &req
->SwI2cCmds
[i
];
1999 /* First 2 bytes are always write for lower 2b EEPROM address */
2006 /* Add RESTART for read after address filled */
2007 cmd
->CmdConfig
|= (i
== 2 && !write
) ? CMDCONFIG_RESTART_MASK
: 0;
2009 /* Add STOP in the end */
2010 cmd
->CmdConfig
|= (i
== (numbytes
- 1)) ? CMDCONFIG_STOP_MASK
: 0;
2012 /* Fill with data regardless if read or write to simplify code */
2013 cmd
->RegisterAddr
= data
[i
];
2017 static int arcturus_i2c_eeprom_read_data(struct i2c_adapter
*control
,
2022 uint32_t i
, ret
= 0;
2024 struct amdgpu_device
*adev
= to_amdgpu_device(control
);
2025 struct smu_table_context
*smu_table
= &adev
->smu
.smu_table
;
2026 struct smu_table
*table
= &smu_table
->driver_table
;
2028 memset(&req
, 0, sizeof(req
));
2029 arcturus_fill_eeprom_i2c_req(&req
, false, address
, numbytes
, data
);
2031 mutex_lock(&adev
->smu
.mutex
);
2032 /* Now read data starting with that address */
2033 ret
= smu_update_table(&adev
->smu
, SMU_TABLE_I2C_COMMANDS
, 0, &req
,
2035 mutex_unlock(&adev
->smu
.mutex
);
2038 SwI2cRequest_t
*res
= (SwI2cRequest_t
*)table
->cpu_addr
;
2040 /* Assume SMU fills res.SwI2cCmds[i].Data with read bytes */
2041 for (i
= 0; i
< numbytes
; i
++)
2042 data
[i
] = res
->SwI2cCmds
[i
].Data
;
2044 pr_debug("arcturus_i2c_eeprom_read_data, address = %x, bytes = %d, data :",
2045 (uint16_t)address
, numbytes
);
2047 print_hex_dump(KERN_DEBUG
, "data: ", DUMP_PREFIX_NONE
,
2048 8, 1, data
, numbytes
, false);
2050 pr_err("arcturus_i2c_eeprom_read_data - error occurred :%x", ret
);
2055 static int arcturus_i2c_eeprom_write_data(struct i2c_adapter
*control
,
2062 struct amdgpu_device
*adev
= to_amdgpu_device(control
);
2064 memset(&req
, 0, sizeof(req
));
2065 arcturus_fill_eeprom_i2c_req(&req
, true, address
, numbytes
, data
);
2067 mutex_lock(&adev
->smu
.mutex
);
2068 ret
= smu_update_table(&adev
->smu
, SMU_TABLE_I2C_COMMANDS
, 0, &req
, true);
2069 mutex_unlock(&adev
->smu
.mutex
);
2072 pr_debug("arcturus_i2c_write(), address = %x, bytes = %d , data: ",
2073 (uint16_t)address
, numbytes
);
2075 print_hex_dump(KERN_DEBUG
, "data: ", DUMP_PREFIX_NONE
,
2076 8, 1, data
, numbytes
, false);
2078 * According to EEPROM spec there is a MAX of 10 ms required for
2079 * EEPROM to flush internal RX buffer after STOP was issued at the
2080 * end of write transaction. During this time the EEPROM will not be
2081 * responsive to any more commands - so wait a bit more.
2086 pr_err("arcturus_i2c_write- error occurred :%x", ret
);
2091 static int arcturus_i2c_eeprom_i2c_xfer(struct i2c_adapter
*i2c_adap
,
2092 struct i2c_msg
*msgs
, int num
)
2094 uint32_t i
, j
, ret
, data_size
, data_chunk_size
, next_eeprom_addr
= 0;
2095 uint8_t *data_ptr
, data_chunk
[MAX_SW_I2C_COMMANDS
] = { 0 };
2097 for (i
= 0; i
< num
; i
++) {
2099 * SMU interface allows at most MAX_SW_I2C_COMMANDS bytes of data at
2100 * once and hence the data needs to be spliced into chunks and sent each
2103 data_size
= msgs
[i
].len
- 2;
2104 data_chunk_size
= MAX_SW_I2C_COMMANDS
- 2;
2105 next_eeprom_addr
= (msgs
[i
].buf
[0] << 8 & 0xff00) | (msgs
[i
].buf
[1] & 0xff);
2106 data_ptr
= msgs
[i
].buf
+ 2;
2108 for (j
= 0; j
< data_size
/ data_chunk_size
; j
++) {
2109 /* Insert the EEPROM dest addess, bits 0-15 */
2110 data_chunk
[0] = ((next_eeprom_addr
>> 8) & 0xff);
2111 data_chunk
[1] = (next_eeprom_addr
& 0xff);
2113 if (msgs
[i
].flags
& I2C_M_RD
) {
2114 ret
= arcturus_i2c_eeprom_read_data(i2c_adap
,
2115 (uint8_t)msgs
[i
].addr
,
2116 data_chunk
, MAX_SW_I2C_COMMANDS
);
2118 memcpy(data_ptr
, data_chunk
+ 2, data_chunk_size
);
2121 memcpy(data_chunk
+ 2, data_ptr
, data_chunk_size
);
2123 ret
= arcturus_i2c_eeprom_write_data(i2c_adap
,
2124 (uint8_t)msgs
[i
].addr
,
2125 data_chunk
, MAX_SW_I2C_COMMANDS
);
2133 next_eeprom_addr
+= data_chunk_size
;
2134 data_ptr
+= data_chunk_size
;
2137 if (data_size
% data_chunk_size
) {
2138 data_chunk
[0] = ((next_eeprom_addr
>> 8) & 0xff);
2139 data_chunk
[1] = (next_eeprom_addr
& 0xff);
2141 if (msgs
[i
].flags
& I2C_M_RD
) {
2142 ret
= arcturus_i2c_eeprom_read_data(i2c_adap
,
2143 (uint8_t)msgs
[i
].addr
,
2144 data_chunk
, (data_size
% data_chunk_size
) + 2);
2146 memcpy(data_ptr
, data_chunk
+ 2, data_size
% data_chunk_size
);
2148 memcpy(data_chunk
+ 2, data_ptr
, data_size
% data_chunk_size
);
2150 ret
= arcturus_i2c_eeprom_write_data(i2c_adap
,
2151 (uint8_t)msgs
[i
].addr
,
2152 data_chunk
, (data_size
% data_chunk_size
) + 2);
2166 static u32
arcturus_i2c_eeprom_i2c_func(struct i2c_adapter
*adap
)
2168 return I2C_FUNC_I2C
| I2C_FUNC_SMBUS_EMUL
;
2172 static const struct i2c_algorithm arcturus_i2c_eeprom_i2c_algo
= {
2173 .master_xfer
= arcturus_i2c_eeprom_i2c_xfer
,
2174 .functionality
= arcturus_i2c_eeprom_i2c_func
,
2177 static int arcturus_i2c_eeprom_control_init(struct i2c_adapter
*control
)
2179 struct amdgpu_device
*adev
= to_amdgpu_device(control
);
2180 struct smu_context
*smu
= &adev
->smu
;
2183 if (!smu
->pm_enabled
)
2186 control
->owner
= THIS_MODULE
;
2187 control
->class = I2C_CLASS_SPD
;
2188 control
->dev
.parent
= &adev
->pdev
->dev
;
2189 control
->algo
= &arcturus_i2c_eeprom_i2c_algo
;
2190 snprintf(control
->name
, sizeof(control
->name
), "RAS EEPROM");
2192 res
= i2c_add_adapter(control
);
2194 DRM_ERROR("Failed to register hw i2c, err: %d\n", res
);
2199 static void arcturus_i2c_eeprom_control_fini(struct i2c_adapter
*control
)
2201 struct amdgpu_device
*adev
= to_amdgpu_device(control
);
2202 struct smu_context
*smu
= &adev
->smu
;
2204 if (!smu
->pm_enabled
)
2207 i2c_del_adapter(control
);
2210 static uint32_t arcturus_get_pptable_power_limit(struct smu_context
*smu
)
2212 PPTable_t
*pptable
= smu
->smu_table
.driver_pptable
;
2214 return pptable
->SocketPowerLimitAc
[PPT_THROTTLER_PPT0
];
2217 static const struct pptable_funcs arcturus_ppt_funcs
= {
2218 /* translate smu index into arcturus specific index */
2219 .get_smu_msg_index
= arcturus_get_smu_msg_index
,
2220 .get_smu_clk_index
= arcturus_get_smu_clk_index
,
2221 .get_smu_feature_index
= arcturus_get_smu_feature_index
,
2222 .get_smu_table_index
= arcturus_get_smu_table_index
,
2223 .get_smu_power_index
= arcturus_get_pwr_src_index
,
2224 .get_workload_type
= arcturus_get_workload_type
,
2225 /* internal structurs allocations */
2226 .tables_init
= arcturus_tables_init
,
2227 .alloc_dpm_context
= arcturus_allocate_dpm_context
,
2228 /* pptable related */
2229 .check_powerplay_table
= arcturus_check_powerplay_table
,
2230 .store_powerplay_table
= arcturus_store_powerplay_table
,
2231 .append_powerplay_table
= arcturus_append_powerplay_table
,
2233 .get_allowed_feature_mask
= arcturus_get_allowed_feature_mask
,
2235 .run_btc
= arcturus_run_btc
,
2236 /* dpm/clk tables */
2237 .set_default_dpm_table
= arcturus_set_default_dpm_table
,
2238 .populate_umd_state_clk
= arcturus_populate_umd_state_clk
,
2239 .get_thermal_temperature_range
= arcturus_get_thermal_temperature_range
,
2240 .get_current_clk_freq_by_table
= arcturus_get_current_clk_freq_by_table
,
2241 .print_clk_levels
= arcturus_print_clk_levels
,
2242 .force_clk_levels
= arcturus_force_clk_levels
,
2243 .read_sensor
= arcturus_read_sensor
,
2244 .get_fan_speed_percent
= arcturus_get_fan_speed_percent
,
2245 .get_fan_speed_rpm
= arcturus_get_fan_speed_rpm
,
2246 .force_dpm_limit_value
= arcturus_force_dpm_limit_value
,
2247 .unforce_dpm_levels
= arcturus_unforce_dpm_levels
,
2248 .get_profiling_clk_mask
= arcturus_get_profiling_clk_mask
,
2249 .get_power_profile_mode
= arcturus_get_power_profile_mode
,
2250 .set_power_profile_mode
= arcturus_set_power_profile_mode
,
2251 .set_performance_level
= smu_v11_0_set_performance_level
,
2252 /* debug (internal used) */
2253 .dump_pptable
= arcturus_dump_pptable
,
2254 .get_power_limit
= arcturus_get_power_limit
,
2255 .is_dpm_running
= arcturus_is_dpm_running
,
2256 .dpm_set_uvd_enable
= arcturus_dpm_set_uvd_enable
,
2257 .i2c_eeprom_init
= arcturus_i2c_eeprom_control_init
,
2258 .i2c_eeprom_fini
= arcturus_i2c_eeprom_control_fini
,
2259 .init_microcode
= smu_v11_0_init_microcode
,
2260 .load_microcode
= smu_v11_0_load_microcode
,
2261 .init_smc_tables
= smu_v11_0_init_smc_tables
,
2262 .fini_smc_tables
= smu_v11_0_fini_smc_tables
,
2263 .init_power
= smu_v11_0_init_power
,
2264 .fini_power
= smu_v11_0_fini_power
,
2265 .check_fw_status
= smu_v11_0_check_fw_status
,
2266 .setup_pptable
= smu_v11_0_setup_pptable
,
2267 .get_vbios_bootup_values
= smu_v11_0_get_vbios_bootup_values
,
2268 .get_clk_info_from_vbios
= smu_v11_0_get_clk_info_from_vbios
,
2269 .check_pptable
= smu_v11_0_check_pptable
,
2270 .parse_pptable
= smu_v11_0_parse_pptable
,
2271 .populate_smc_tables
= smu_v11_0_populate_smc_pptable
,
2272 .check_fw_version
= smu_v11_0_check_fw_version
,
2273 .write_pptable
= smu_v11_0_write_pptable
,
2274 .set_min_dcef_deep_sleep
= smu_v11_0_set_min_dcef_deep_sleep
,
2275 .set_driver_table_location
= smu_v11_0_set_driver_table_location
,
2276 .set_tool_table_location
= smu_v11_0_set_tool_table_location
,
2277 .notify_memory_pool_location
= smu_v11_0_notify_memory_pool_location
,
2278 .system_features_control
= smu_v11_0_system_features_control
,
2279 .send_smc_msg_with_param
= smu_v11_0_send_msg_with_param
,
2280 .read_smc_arg
= smu_v11_0_read_arg
,
2281 .init_display_count
= smu_v11_0_init_display_count
,
2282 .set_allowed_mask
= smu_v11_0_set_allowed_mask
,
2283 .get_enabled_mask
= smu_v11_0_get_enabled_mask
,
2284 .notify_display_change
= smu_v11_0_notify_display_change
,
2285 .set_power_limit
= smu_v11_0_set_power_limit
,
2286 .get_current_clk_freq
= smu_v11_0_get_current_clk_freq
,
2287 .init_max_sustainable_clocks
= smu_v11_0_init_max_sustainable_clocks
,
2288 .start_thermal_control
= smu_v11_0_start_thermal_control
,
2289 .stop_thermal_control
= smu_v11_0_stop_thermal_control
,
2290 .set_deep_sleep_dcefclk
= smu_v11_0_set_deep_sleep_dcefclk
,
2291 .display_clock_voltage_request
= smu_v11_0_display_clock_voltage_request
,
2292 .get_fan_control_mode
= smu_v11_0_get_fan_control_mode
,
2293 .set_fan_control_mode
= smu_v11_0_set_fan_control_mode
,
2294 .set_fan_speed_percent
= smu_v11_0_set_fan_speed_percent
,
2295 .set_fan_speed_rpm
= smu_v11_0_set_fan_speed_rpm
,
2296 .set_xgmi_pstate
= smu_v11_0_set_xgmi_pstate
,
2297 .gfx_off_control
= smu_v11_0_gfx_off_control
,
2298 .register_irq_handler
= smu_v11_0_register_irq_handler
,
2299 .set_azalia_d3_pme
= smu_v11_0_set_azalia_d3_pme
,
2300 .get_max_sustainable_clocks_by_dc
= smu_v11_0_get_max_sustainable_clocks_by_dc
,
2301 .baco_is_support
= smu_v11_0_baco_is_support
,
2302 .baco_get_state
= smu_v11_0_baco_get_state
,
2303 .baco_set_state
= smu_v11_0_baco_set_state
,
2304 .baco_enter
= smu_v11_0_baco_enter
,
2305 .baco_exit
= smu_v11_0_baco_exit
,
2306 .get_dpm_ultimate_freq
= smu_v11_0_get_dpm_ultimate_freq
,
2307 .set_soft_freq_limited_range
= smu_v11_0_set_soft_freq_limited_range
,
2308 .override_pcie_parameters
= smu_v11_0_override_pcie_parameters
,
2309 .get_pptable_power_limit
= arcturus_get_pptable_power_limit
,
2312 void arcturus_set_ppt_funcs(struct smu_context
*smu
)
2314 smu
->ppt_funcs
= &arcturus_ppt_funcs
;