1 /*
2 * Copyright 2021 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24 #define SWSMU_CODE_LAYER_L2
25
26 #include <linux/firmware.h>
27 #include <linux/pci.h>
28 #include <linux/i2c.h>
29 #include "amdgpu.h"
30 #include "amdgpu_smu.h"
31 #include "atomfirmware.h"
32 #include "amdgpu_atomfirmware.h"
33 #include "amdgpu_atombios.h"
34 #include "smu_v13_0.h"
35 #include "smu13_driver_if_v13_0_0.h"
36 #include "soc15_common.h"
37 #include "atom.h"
38 #include "smu_v13_0_0_ppt.h"
39 #include "smu_v13_0_0_pptable.h"
40 #include "smu_v13_0_0_ppsmc.h"
41 #include "nbio/nbio_4_3_0_offset.h"
42 #include "nbio/nbio_4_3_0_sh_mask.h"
43 #include "mp/mp_13_0_0_offset.h"
44 #include "mp/mp_13_0_0_sh_mask.h"
45
46 #include "asic_reg/mp/mp_13_0_0_sh_mask.h"
47 #include "smu_cmn.h"
48 #include "amdgpu_ras.h"
49
50 /*
51 * DO NOT use these for err/warn/info/debug messages.
52 * Use dev_err, dev_warn, dev_info and dev_dbg instead.
53 * They are more MGPU friendly.
54 */
55 #undef pr_err
56 #undef pr_warn
57 #undef pr_info
58 #undef pr_debug
59
60 #define to_amdgpu_device(x) (container_of(x, struct amdgpu_device, pm.smu_i2c))
61
62 static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu,
63 int od_feature_bit,
64 int32_t *min, int32_t *max);
65 static int smu_v13_0_0_init_ppt_limits(struct smu_context *smu);
66
67 static const struct smu_feature_bits smu_v13_0_0_dpm_features = {
68 .bits = {
69 SMU_FEATURE_BIT_INIT(FEATURE_DPM_GFXCLK_BIT),
70 SMU_FEATURE_BIT_INIT(FEATURE_DPM_UCLK_BIT),
71 SMU_FEATURE_BIT_INIT(FEATURE_DPM_LINK_BIT),
72 SMU_FEATURE_BIT_INIT(FEATURE_DPM_SOCCLK_BIT),
73 SMU_FEATURE_BIT_INIT(FEATURE_DPM_FCLK_BIT),
74 SMU_FEATURE_BIT_INIT(FEATURE_DPM_MP0CLK_BIT)
75 }
76 };
77
78 #define MP0_MP1_DATA_REGION_SIZE_COMBOPPTABLE 0x4000
79
80 #define mmMP1_SMN_C2PMSG_75 0x028b
81 #define mmMP1_SMN_C2PMSG_75_BASE_IDX 0
82
83 #define mmMP1_SMN_C2PMSG_53 0x0275
84 #define mmMP1_SMN_C2PMSG_53_BASE_IDX 0
85
86 #define mmMP1_SMN_C2PMSG_54 0x0276
87 #define mmMP1_SMN_C2PMSG_54_BASE_IDX 0
88
89 #define DEBUGSMC_MSG_Mode1Reset 2
90
91 /*
92 * SMU_v13_0_10 supports ECCTABLE since version 80.34.0,
93 * use this to check ECCTABLE feature whether support
94 */
95 #define SUPPORT_ECCTABLE_SMU_13_0_10_VERSION 0x00502200
96
97 #define PP_OD_FEATURE_GFXCLK_FMIN 0
98 #define PP_OD_FEATURE_GFXCLK_FMAX 1
99 #define PP_OD_FEATURE_UCLK_FMIN 2
100 #define PP_OD_FEATURE_UCLK_FMAX 3
101 #define PP_OD_FEATURE_GFX_VF_CURVE 4
102 #define PP_OD_FEATURE_FAN_CURVE_TEMP 5
103 #define PP_OD_FEATURE_FAN_CURVE_PWM 6
104 #define PP_OD_FEATURE_FAN_ACOUSTIC_LIMIT 7
105 #define PP_OD_FEATURE_FAN_ACOUSTIC_TARGET 8
106 #define PP_OD_FEATURE_FAN_TARGET_TEMPERATURE 9
107 #define PP_OD_FEATURE_FAN_MINIMUM_PWM 10
108 #define PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE 11
109 #define PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP 12
110
111 #define LINK_SPEED_MAX 3
112
113 static struct cmn2asic_msg_mapping smu_v13_0_0_message_map[SMU_MSG_MAX_COUNT] = {
114 MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1),
115 MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1),
116 MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 1),
117 MSG_MAP(SetAllowedFeaturesMaskLow, PPSMC_MSG_SetAllowedFeaturesMaskLow, 0),
118 MSG_MAP(SetAllowedFeaturesMaskHigh, PPSMC_MSG_SetAllowedFeaturesMaskHigh, 0),
119 MSG_MAP(EnableAllSmuFeatures, PPSMC_MSG_EnableAllSmuFeatures, 0),
120 MSG_MAP(DisableAllSmuFeatures, PPSMC_MSG_DisableAllSmuFeatures, 0),
121 MSG_MAP(EnableSmuFeaturesLow, PPSMC_MSG_EnableSmuFeaturesLow, 1),
122 MSG_MAP(EnableSmuFeaturesHigh, PPSMC_MSG_EnableSmuFeaturesHigh, 1),
123 MSG_MAP(DisableSmuFeaturesLow, PPSMC_MSG_DisableSmuFeaturesLow, 1),
124 MSG_MAP(DisableSmuFeaturesHigh, PPSMC_MSG_DisableSmuFeaturesHigh, 1),
125 MSG_MAP(GetEnabledSmuFeaturesLow, PPSMC_MSG_GetRunningSmuFeaturesLow, 1),
126 MSG_MAP(GetEnabledSmuFeaturesHigh, PPSMC_MSG_GetRunningSmuFeaturesHigh, 1),
127 MSG_MAP(SetWorkloadMask, PPSMC_MSG_SetWorkloadMask, 0),
128 MSG_MAP(SetPptLimit, PPSMC_MSG_SetPptLimit, 0),
129 MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 1),
130 MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 1),
131 MSG_MAP(SetToolsDramAddrHigh, PPSMC_MSG_SetToolsDramAddrHigh, 0),
132 MSG_MAP(SetToolsDramAddrLow, PPSMC_MSG_SetToolsDramAddrLow, 0),
133 MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 1),
134 MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 0),
135 MSG_MAP(UseDefaultPPTable, PPSMC_MSG_UseDefaultPPTable, 0),
136 MSG_MAP(RunDcBtc, PPSMC_MSG_RunDcBtc, 0),
137 MSG_MAP(EnterBaco, PPSMC_MSG_EnterBaco, 0),
138 MSG_MAP(ExitBaco, PPSMC_MSG_ExitBaco, 0),
139 MSG_MAP(SetSoftMinByFreq, PPSMC_MSG_SetSoftMinByFreq, 1),
140 MSG_MAP(SetSoftMaxByFreq, PPSMC_MSG_SetSoftMaxByFreq, 1),
141 MSG_MAP(SetHardMinByFreq, PPSMC_MSG_SetHardMinByFreq, 0),
142 MSG_MAP(SetHardMaxByFreq, PPSMC_MSG_SetHardMaxByFreq, 0),
143 MSG_MAP(GetMinDpmFreq, PPSMC_MSG_GetMinDpmFreq, 1),
144 MSG_MAP(GetMaxDpmFreq, PPSMC_MSG_GetMaxDpmFreq, 1),
145 MSG_MAP(GetDpmFreqByIndex, PPSMC_MSG_GetDpmFreqByIndex, 1),
146 MSG_MAP(PowerUpVcn, PPSMC_MSG_PowerUpVcn, 0),
147 MSG_MAP(PowerDownVcn, PPSMC_MSG_PowerDownVcn, 0),
148 MSG_MAP(PowerUpJpeg, PPSMC_MSG_PowerUpJpeg, 0),
149 MSG_MAP(PowerDownJpeg, PPSMC_MSG_PowerDownJpeg, 0),
150 MSG_MAP(GetDcModeMaxDpmFreq, PPSMC_MSG_GetDcModeMaxDpmFreq, 0),
151 MSG_MAP(OverridePcieParameters, PPSMC_MSG_OverridePcieParameters, 0),
152 MSG_MAP(DramLogSetDramAddrHigh, PPSMC_MSG_DramLogSetDramAddrHigh, 0),
153 MSG_MAP(DramLogSetDramAddrLow, PPSMC_MSG_DramLogSetDramAddrLow, 0),
154 MSG_MAP(DramLogSetDramSize, PPSMC_MSG_DramLogSetDramSize, 0),
155 MSG_MAP(AllowGfxOff, PPSMC_MSG_AllowGfxOff, 0),
156 MSG_MAP(DisallowGfxOff, PPSMC_MSG_DisallowGfxOff, 0),
157 MSG_MAP(SetMGpuFanBoostLimitRpm, PPSMC_MSG_SetMGpuFanBoostLimitRpm, 0),
158 MSG_MAP(GetPptLimit, PPSMC_MSG_GetPptLimit, 0),
159 MSG_MAP(NotifyPowerSource, PPSMC_MSG_NotifyPowerSource, 0),
160 MSG_MAP(Mode1Reset, PPSMC_MSG_Mode1Reset, 0),
161 MSG_MAP(Mode2Reset, PPSMC_MSG_Mode2Reset, 0),
162 MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 0),
163 MSG_MAP(DFCstateControl, PPSMC_MSG_SetExternalClientDfCstateAllow, 0),
164 MSG_MAP(ArmD3, PPSMC_MSG_ArmD3, 0),
165 MSG_MAP(SetNumBadMemoryPagesRetired, PPSMC_MSG_SetNumBadMemoryPagesRetired, 0),
166 MSG_MAP(SetBadMemoryPagesRetiredFlagsPerChannel,
167 PPSMC_MSG_SetBadMemoryPagesRetiredFlagsPerChannel, 0),
168 MSG_MAP(AllowGpo, PPSMC_MSG_SetGpoAllow, 0),
169 MSG_MAP(AllowIHHostInterrupt, PPSMC_MSG_AllowIHHostInterrupt, 0),
170 MSG_MAP(ReenableAcDcInterrupt, PPSMC_MSG_ReenableAcDcInterrupt, 0),
171 MSG_MAP(DALNotPresent, PPSMC_MSG_DALNotPresent, 0),
172 MSG_MAP(EnableUCLKShadow, PPSMC_MSG_EnableUCLKShadow, 0),
173 };
174
175 static struct cmn2asic_mapping smu_v13_0_0_clk_map[SMU_CLK_COUNT] = {
176 CLK_MAP(GFXCLK, PPCLK_GFXCLK),
177 CLK_MAP(SCLK, PPCLK_GFXCLK),
178 CLK_MAP(SOCCLK, PPCLK_SOCCLK),
179 CLK_MAP(FCLK, PPCLK_FCLK),
180 CLK_MAP(UCLK, PPCLK_UCLK),
181 CLK_MAP(MCLK, PPCLK_UCLK),
182 CLK_MAP(VCLK, PPCLK_VCLK_0),
183 CLK_MAP(VCLK1, PPCLK_VCLK_1),
184 CLK_MAP(DCLK, PPCLK_DCLK_0),
185 CLK_MAP(DCLK1, PPCLK_DCLK_1),
186 CLK_MAP(DCEFCLK, PPCLK_DCFCLK),
187 };
188
189 static struct cmn2asic_mapping smu_v13_0_0_feature_mask_map[SMU_FEATURE_COUNT] = {
190 FEA_MAP(FW_DATA_READ),
191 FEA_MAP(DPM_GFXCLK),
192 FEA_MAP(DPM_GFX_POWER_OPTIMIZER),
193 FEA_MAP(DPM_UCLK),
194 FEA_MAP(DPM_FCLK),
195 FEA_MAP(DPM_SOCCLK),
196 FEA_MAP(DPM_MP0CLK),
197 FEA_MAP(DPM_LINK),
198 FEA_MAP(DPM_DCN),
199 FEA_MAP(VMEMP_SCALING),
200 FEA_MAP(VDDIO_MEM_SCALING),
201 FEA_MAP(DS_GFXCLK),
202 FEA_MAP(DS_SOCCLK),
203 FEA_MAP(DS_FCLK),
204 FEA_MAP(DS_LCLK),
205 FEA_MAP(DS_DCFCLK),
206 FEA_MAP(DS_UCLK),
207 FEA_MAP(GFX_ULV),
208 FEA_MAP(FW_DSTATE),
209 FEA_MAP(GFXOFF),
210 FEA_MAP(BACO),
211 FEA_MAP(MM_DPM),
212 FEA_MAP(SOC_MPCLK_DS),
213 FEA_MAP(BACO_MPCLK_DS),
214 FEA_MAP(THROTTLERS),
215 FEA_MAP(SMARTSHIFT),
216 FEA_MAP(GTHR),
217 FEA_MAP(ACDC),
218 FEA_MAP(VR0HOT),
219 FEA_MAP(FW_CTF),
220 FEA_MAP(FAN_CONTROL),
221 FEA_MAP(GFX_DCS),
222 FEA_MAP(GFX_READ_MARGIN),
223 FEA_MAP(LED_DISPLAY),
224 FEA_MAP(GFXCLK_SPREAD_SPECTRUM),
225 FEA_MAP(OUT_OF_BAND_MONITOR),
226 FEA_MAP(OPTIMIZED_VMIN),
227 FEA_MAP(GFX_IMU),
228 FEA_MAP(BOOT_TIME_CAL),
229 FEA_MAP(GFX_PCC_DFLL),
230 FEA_MAP(SOC_CG),
231 FEA_MAP(DF_CSTATE),
232 FEA_MAP(GFX_EDC),
233 FEA_MAP(BOOT_POWER_OPT),
234 FEA_MAP(CLOCK_POWER_DOWN_BYPASS),
235 FEA_MAP(DS_VCN),
236 FEA_MAP(BACO_CG),
237 FEA_MAP(MEM_TEMP_READ),
238 FEA_MAP(ATHUB_MMHUB_PG),
239 FEA_MAP(SOC_PCC),
240 [SMU_FEATURE_DPM_VCLK_BIT] = {1, FEATURE_MM_DPM_BIT},
241 [SMU_FEATURE_DPM_DCLK_BIT] = {1, FEATURE_MM_DPM_BIT},
242 [SMU_FEATURE_PPT_BIT] = {1, FEATURE_THROTTLERS_BIT},
243 };
244
245 static struct cmn2asic_mapping smu_v13_0_0_table_map[SMU_TABLE_COUNT] = {
246 TAB_MAP(PPTABLE),
247 TAB_MAP(WATERMARKS),
248 TAB_MAP(AVFS_PSM_DEBUG),
249 TAB_MAP(PMSTATUSLOG),
250 TAB_MAP(SMU_METRICS),
251 TAB_MAP(DRIVER_SMU_CONFIG),
252 TAB_MAP(ACTIVITY_MONITOR_COEFF),
253 [SMU_TABLE_COMBO_PPTABLE] = {1, TABLE_COMBO_PPTABLE},
254 TAB_MAP(I2C_COMMANDS),
255 TAB_MAP(ECCINFO),
256 TAB_MAP(OVERDRIVE),
257 TAB_MAP(WIFIBAND),
258 };
259
260 static struct cmn2asic_mapping smu_v13_0_0_pwr_src_map[SMU_POWER_SOURCE_COUNT] = {
261 PWR_MAP(AC),
262 PWR_MAP(DC),
263 };
264
265 static struct cmn2asic_mapping smu_v13_0_0_workload_map[PP_SMC_POWER_PROFILE_COUNT] = {
266 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT, WORKLOAD_PPLIB_DEFAULT_BIT),
267 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_FULLSCREEN3D, WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT),
268 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING, WORKLOAD_PPLIB_POWER_SAVING_BIT),
269 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO, WORKLOAD_PPLIB_VIDEO_BIT),
270 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VR, WORKLOAD_PPLIB_VR_BIT),
271 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE, WORKLOAD_PPLIB_COMPUTE_BIT),
272 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT),
273 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_WINDOW3D, WORKLOAD_PPLIB_WINDOW_3D_BIT),
274 };
275
276 static const uint8_t smu_v13_0_0_throttler_map[] = {
277 [THROTTLER_PPT0_BIT] = (SMU_THROTTLER_PPT0_BIT),
278 [THROTTLER_PPT1_BIT] = (SMU_THROTTLER_PPT1_BIT),
279 [THROTTLER_PPT2_BIT] = (SMU_THROTTLER_PPT2_BIT),
280 [THROTTLER_PPT3_BIT] = (SMU_THROTTLER_PPT3_BIT),
281 [THROTTLER_TDC_GFX_BIT] = (SMU_THROTTLER_TDC_GFX_BIT),
282 [THROTTLER_TDC_SOC_BIT] = (SMU_THROTTLER_TDC_SOC_BIT),
283 [THROTTLER_TEMP_EDGE_BIT] = (SMU_THROTTLER_TEMP_EDGE_BIT),
284 [THROTTLER_TEMP_HOTSPOT_BIT] = (SMU_THROTTLER_TEMP_HOTSPOT_BIT),
285 [THROTTLER_TEMP_MEM_BIT] = (SMU_THROTTLER_TEMP_MEM_BIT),
286 [THROTTLER_TEMP_VR_GFX_BIT] = (SMU_THROTTLER_TEMP_VR_GFX_BIT),
287 [THROTTLER_TEMP_VR_SOC_BIT] = (SMU_THROTTLER_TEMP_VR_SOC_BIT),
288 [THROTTLER_TEMP_VR_MEM0_BIT] = (SMU_THROTTLER_TEMP_VR_MEM0_BIT),
289 [THROTTLER_TEMP_VR_MEM1_BIT] = (SMU_THROTTLER_TEMP_VR_MEM1_BIT),
290 [THROTTLER_TEMP_LIQUID0_BIT] = (SMU_THROTTLER_TEMP_LIQUID0_BIT),
291 [THROTTLER_TEMP_LIQUID1_BIT] = (SMU_THROTTLER_TEMP_LIQUID1_BIT),
292 [THROTTLER_GFX_APCC_PLUS_BIT] = (SMU_THROTTLER_APCC_BIT),
293 [THROTTLER_FIT_BIT] = (SMU_THROTTLER_FIT_BIT),
294 };
295
296 static int
smu_v13_0_0_init_allowed_features(struct smu_context * smu)297 smu_v13_0_0_init_allowed_features(struct smu_context *smu)
298 {
299 struct amdgpu_device *adev = smu->adev;
300
301 smu_feature_list_set_all(smu, SMU_FEATURE_LIST_ALLOWED);
302
303 if (!(adev->pm.pp_feature & PP_SCLK_DPM_MASK)) {
304 smu_feature_list_clear_bit(smu, SMU_FEATURE_LIST_ALLOWED, FEATURE_DPM_GFXCLK_BIT);
305 smu_feature_list_clear_bit(smu, SMU_FEATURE_LIST_ALLOWED, FEATURE_GFX_IMU_BIT);
306 }
307
308 if (!(adev->pg_flags & AMD_PG_SUPPORT_ATHUB) ||
309 !(adev->pg_flags & AMD_PG_SUPPORT_MMHUB))
310 smu_feature_list_clear_bit(smu, SMU_FEATURE_LIST_ALLOWED, FEATURE_ATHUB_MMHUB_PG_BIT);
311
312 if (!(adev->pm.pp_feature & PP_SOCCLK_DPM_MASK))
313 smu_feature_list_clear_bit(smu, SMU_FEATURE_LIST_ALLOWED, FEATURE_DPM_SOCCLK_BIT);
314
315 if ((smu->smc_fw_version < 0x004e3a00) ||
316 !(adev->pm.pp_feature & PP_GFXOFF_MASK))
317 smu_feature_list_clear_bit(smu, SMU_FEATURE_LIST_ALLOWED, FEATURE_GFXOFF_BIT);
318
319 if (!(adev->pm.pp_feature & PP_MCLK_DPM_MASK)) {
320 smu_feature_list_clear_bit(smu, SMU_FEATURE_LIST_ALLOWED, FEATURE_DPM_UCLK_BIT);
321 smu_feature_list_clear_bit(smu, SMU_FEATURE_LIST_ALLOWED, FEATURE_VMEMP_SCALING_BIT);
322 smu_feature_list_clear_bit(smu, SMU_FEATURE_LIST_ALLOWED, FEATURE_VDDIO_MEM_SCALING_BIT);
323 }
324
325 if (!(adev->pm.pp_feature & PP_SCLK_DEEP_SLEEP_MASK))
326 smu_feature_list_clear_bit(smu, SMU_FEATURE_LIST_ALLOWED, FEATURE_DS_GFXCLK_BIT);
327
328 if (!(adev->pm.pp_feature & PP_PCIE_DPM_MASK)) {
329 smu_feature_list_clear_bit(smu, SMU_FEATURE_LIST_ALLOWED, FEATURE_DPM_LINK_BIT);
330 smu_feature_list_clear_bit(smu, SMU_FEATURE_LIST_ALLOWED, FEATURE_DS_LCLK_BIT);
331 }
332
333 if (!(adev->pm.pp_feature & PP_ULV_MASK))
334 smu_feature_list_clear_bit(smu, SMU_FEATURE_LIST_ALLOWED, FEATURE_GFX_ULV_BIT);
335
336 return 0;
337 }
338
smu_v13_0_0_check_powerplay_table(struct smu_context * smu)339 static int smu_v13_0_0_check_powerplay_table(struct smu_context *smu)
340 {
341 struct smu_table_context *table_context = &smu->smu_table;
342 struct smu_13_0_0_powerplay_table *powerplay_table =
343 table_context->power_play_table;
344 struct smu_baco_context *smu_baco = &smu->smu_baco;
345 PPTable_t *pptable = smu->smu_table.driver_pptable;
346 const OverDriveLimits_t * const overdrive_upperlimits =
347 &pptable->SkuTable.OverDriveLimitsBasicMax;
348 const OverDriveLimits_t * const overdrive_lowerlimits =
349 &pptable->SkuTable.OverDriveLimitsMin;
350
351 if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_HARDWAREDC)
352 smu->dc_controlled_by_gpio = true;
353
354 if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_BACO) {
355 smu_baco->platform_support = true;
356
357 if (powerplay_table->platform_caps & SMU_13_0_0_PP_PLATFORM_CAP_MACO)
358 smu_baco->maco_support = true;
359 }
360
361 if (!overdrive_lowerlimits->FeatureCtrlMask ||
362 !overdrive_upperlimits->FeatureCtrlMask)
363 smu->od_enabled = false;
364
365 table_context->thermal_controller_type =
366 powerplay_table->thermal_controller_type;
367
368 /*
369 * Instead of having its own buffer space and get overdrive_table copied,
370 * smu->od_settings just points to the actual overdrive_table
371 */
372 smu->od_settings = &powerplay_table->overdrive_table;
373
374 smu->adev->pm.no_fan =
375 !(pptable->SkuTable.FeaturesToRun[0] & (1 << FEATURE_FAN_CONTROL_BIT));
376
377 return 0;
378 }
379
smu_v13_0_0_store_powerplay_table(struct smu_context * smu)380 static int smu_v13_0_0_store_powerplay_table(struct smu_context *smu)
381 {
382 struct smu_table_context *table_context = &smu->smu_table;
383 struct smu_13_0_0_powerplay_table *powerplay_table =
384 table_context->power_play_table;
385
386 memcpy(table_context->driver_pptable, &powerplay_table->smc_pptable,
387 sizeof(PPTable_t));
388
389 return 0;
390 }
391
392 #ifndef atom_smc_dpm_info_table_13_0_0
393 struct atom_smc_dpm_info_table_13_0_0 {
394 struct atom_common_table_header table_header;
395 BoardTable_t BoardTable;
396 };
397 #endif
398
smu_v13_0_0_append_powerplay_table(struct smu_context * smu)399 static int smu_v13_0_0_append_powerplay_table(struct smu_context *smu)
400 {
401 struct smu_table_context *table_context = &smu->smu_table;
402 PPTable_t *smc_pptable = table_context->driver_pptable;
403 struct atom_smc_dpm_info_table_13_0_0 *smc_dpm_table;
404 BoardTable_t *BoardTable = &smc_pptable->BoardTable;
405 int index, ret;
406
407 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
408 smc_dpm_info);
409
410 ret = amdgpu_atombios_get_data_table(smu->adev, index, NULL, NULL, NULL,
411 (uint8_t **)&smc_dpm_table);
412 if (ret)
413 return ret;
414
415 memcpy(BoardTable, &smc_dpm_table->BoardTable, sizeof(BoardTable_t));
416
417 return 0;
418 }
419
smu_v13_0_0_get_pptable_from_pmfw(struct smu_context * smu,void ** table,uint32_t * size)420 static int smu_v13_0_0_get_pptable_from_pmfw(struct smu_context *smu,
421 void **table,
422 uint32_t *size)
423 {
424 struct smu_table_context *smu_table = &smu->smu_table;
425 void *combo_pptable = smu_table->combo_pptable;
426 int ret = 0;
427
428 ret = smu_cmn_get_combo_pptable(smu);
429 if (ret)
430 return ret;
431
432 *table = combo_pptable;
433 *size = sizeof(struct smu_13_0_0_powerplay_table);
434
435 return 0;
436 }
437
smu_v13_0_0_setup_pptable(struct smu_context * smu)438 static int smu_v13_0_0_setup_pptable(struct smu_context *smu)
439 {
440 struct smu_table_context *smu_table = &smu->smu_table;
441 struct amdgpu_device *adev = smu->adev;
442 int ret = 0;
443
444 if (amdgpu_sriov_vf(smu->adev))
445 return 0;
446
447 ret = smu_v13_0_0_get_pptable_from_pmfw(smu,
448 &smu_table->power_play_table,
449 &smu_table->power_play_table_size);
450 if (ret)
451 return ret;
452
453 ret = smu_v13_0_0_store_powerplay_table(smu);
454 if (ret)
455 return ret;
456
457 /*
458 * With SCPM enabled, the operation below will be handled
459 * by PSP. Driver involvment is unnecessary and useless.
460 */
461 if (!adev->scpm_enabled) {
462 ret = smu_v13_0_0_append_powerplay_table(smu);
463 if (ret)
464 return ret;
465 }
466
467 ret = smu_v13_0_0_check_powerplay_table(smu);
468 if (ret)
469 return ret;
470
471 return smu_v13_0_0_init_ppt_limits(smu);
472 }
473
smu_v13_0_0_tables_init(struct smu_context * smu)474 static int smu_v13_0_0_tables_init(struct smu_context *smu)
475 {
476 struct smu_table_context *smu_table = &smu->smu_table;
477 struct smu_table *tables = smu_table->tables;
478 int ret;
479
480 SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t),
481 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
482 SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t),
483 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
484 SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetricsExternal_t),
485 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
486 SMU_TABLE_INIT(tables, SMU_TABLE_I2C_COMMANDS, sizeof(SwI2cRequest_t),
487 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
488 SMU_TABLE_INIT(tables, SMU_TABLE_OVERDRIVE, sizeof(OverDriveTableExternal_t),
489 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
490 SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU13_TOOL_SIZE,
491 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
492 SMU_TABLE_INIT(tables, SMU_TABLE_ACTIVITY_MONITOR_COEFF,
493 sizeof(DpmActivityMonitorCoeffIntExternal_t), PAGE_SIZE,
494 AMDGPU_GEM_DOMAIN_VRAM);
495 SMU_TABLE_INIT(tables, SMU_TABLE_COMBO_PPTABLE, MP0_MP1_DATA_REGION_SIZE_COMBOPPTABLE,
496 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
497 SMU_TABLE_INIT(tables, SMU_TABLE_ECCINFO, sizeof(EccInfoTable_t),
498 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM);
499 SMU_TABLE_INIT(tables, SMU_TABLE_WIFIBAND,
500 sizeof(WifiBandEntryTable_t), PAGE_SIZE,
501 AMDGPU_GEM_DOMAIN_VRAM);
502
503 smu_table->metrics_table = kzalloc_obj(SmuMetricsExternal_t);
504 if (!smu_table->metrics_table)
505 goto err0_out;
506 smu_table->metrics_time = 0;
507
508 ret = smu_driver_table_init(smu, SMU_DRIVER_TABLE_GPU_METRICS,
509 sizeof(struct gpu_metrics_v1_3),
510 SMU_GPU_METRICS_CACHE_INTERVAL);
511 if (ret)
512 goto err1_out;
513
514 smu_table->watermarks_table = kzalloc_obj(Watermarks_t);
515 if (!smu_table->watermarks_table)
516 goto err2_out;
517
518 smu_table->ecc_table = kzalloc(tables[SMU_TABLE_ECCINFO].size, GFP_KERNEL);
519 if (!smu_table->ecc_table)
520 goto err3_out;
521
522 return 0;
523
524 err3_out:
525 kfree(smu_table->watermarks_table);
526 err2_out:
527 smu_driver_table_fini(smu, SMU_DRIVER_TABLE_GPU_METRICS);
528 err1_out:
529 kfree(smu_table->metrics_table);
530 err0_out:
531 return -ENOMEM;
532 }
533
smu_v13_0_0_allocate_dpm_context(struct smu_context * smu)534 static int smu_v13_0_0_allocate_dpm_context(struct smu_context *smu)
535 {
536 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
537
538 smu_dpm->dpm_context = kzalloc_obj(struct smu_13_0_dpm_context);
539 if (!smu_dpm->dpm_context)
540 return -ENOMEM;
541
542 smu_dpm->dpm_context_size = sizeof(struct smu_13_0_dpm_context);
543
544 return 0;
545 }
546
smu_v13_0_0_init_smc_tables(struct smu_context * smu)547 static int smu_v13_0_0_init_smc_tables(struct smu_context *smu)
548 {
549 int ret = 0;
550
551 ret = smu_v13_0_0_tables_init(smu);
552 if (ret)
553 return ret;
554
555 ret = smu_v13_0_0_allocate_dpm_context(smu);
556 if (ret)
557 return ret;
558
559 return smu_v13_0_init_smc_tables(smu);
560 }
561
smu_v13_0_0_set_default_dpm_table(struct smu_context * smu)562 static int smu_v13_0_0_set_default_dpm_table(struct smu_context *smu)
563 {
564 struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
565 struct smu_table_context *table_context = &smu->smu_table;
566 PPTable_t *pptable = table_context->driver_pptable;
567 SkuTable_t *skutable = &pptable->SkuTable;
568 struct smu_dpm_table *dpm_table;
569 int ret = 0;
570
571 /* socclk dpm table setup */
572 dpm_table = &dpm_context->dpm_tables.soc_table;
573 dpm_table->clk_type = SMU_SOCCLK;
574 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) {
575 ret = smu_v13_0_set_single_dpm_table(smu,
576 SMU_SOCCLK,
577 dpm_table);
578 if (ret)
579 return ret;
580 } else {
581 dpm_table->count = 1;
582 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.socclk / 100;
583 dpm_table->dpm_levels[0].enabled = true;
584 }
585
586 /* gfxclk dpm table setup */
587 dpm_table = &dpm_context->dpm_tables.gfx_table;
588 dpm_table->clk_type = SMU_GFXCLK;
589 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT)) {
590 ret = smu_v13_0_set_single_dpm_table(smu,
591 SMU_GFXCLK,
592 dpm_table);
593 if (ret)
594 return ret;
595
596 /*
597 * Update the reported maximum shader clock to the value
598 * which can be guarded to be achieved on all cards. This
599 * is aligned with Window setting. And considering that value
600 * might be not the peak frequency the card can achieve, it
601 * is normal some real-time clock frequency can overtake this
602 * labelled maximum clock frequency(for example in pp_dpm_sclk
603 * sysfs output).
604 */
605 if (skutable->DriverReportedClocks.GameClockAc &&
606 (dpm_table->dpm_levels[dpm_table->count - 1].value >
607 skutable->DriverReportedClocks.GameClockAc)) {
608 dpm_table->dpm_levels[dpm_table->count - 1].value =
609 skutable->DriverReportedClocks.GameClockAc;
610 }
611 } else {
612 dpm_table->count = 1;
613 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100;
614 dpm_table->dpm_levels[0].enabled = true;
615 }
616
617 /* uclk dpm table setup */
618 dpm_table = &dpm_context->dpm_tables.uclk_table;
619 dpm_table->clk_type = SMU_UCLK;
620 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) {
621 ret = smu_v13_0_set_single_dpm_table(smu,
622 SMU_UCLK,
623 dpm_table);
624 if (ret)
625 return ret;
626 } else {
627 dpm_table->count = 1;
628 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.uclk / 100;
629 dpm_table->dpm_levels[0].enabled = true;
630 }
631
632 /* fclk dpm table setup */
633 dpm_table = &dpm_context->dpm_tables.fclk_table;
634 dpm_table->clk_type = SMU_FCLK;
635 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_FCLK_BIT)) {
636 ret = smu_v13_0_set_single_dpm_table(smu,
637 SMU_FCLK,
638 dpm_table);
639 if (ret)
640 return ret;
641 } else {
642 dpm_table->count = 1;
643 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.fclk / 100;
644 dpm_table->dpm_levels[0].enabled = true;
645 }
646
647 /* vclk dpm table setup */
648 dpm_table = &dpm_context->dpm_tables.vclk_table;
649 dpm_table->clk_type = SMU_VCLK;
650 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_VCLK_BIT)) {
651 ret = smu_v13_0_set_single_dpm_table(smu,
652 SMU_VCLK,
653 dpm_table);
654 if (ret)
655 return ret;
656 } else {
657 dpm_table->count = 1;
658 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.vclk / 100;
659 dpm_table->dpm_levels[0].enabled = true;
660 }
661
662 /* dclk dpm table setup */
663 dpm_table = &dpm_context->dpm_tables.dclk_table;
664 dpm_table->clk_type = SMU_DCLK;
665 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCLK_BIT)) {
666 ret = smu_v13_0_set_single_dpm_table(smu,
667 SMU_DCLK,
668 dpm_table);
669 if (ret)
670 return ret;
671 } else {
672 dpm_table->count = 1;
673 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dclk / 100;
674 dpm_table->dpm_levels[0].enabled = true;
675 }
676
677 /* dcefclk dpm table setup */
678 dpm_table = &dpm_context->dpm_tables.dcef_table;
679 dpm_table->clk_type = SMU_DCEFCLK;
680 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCN_BIT)) {
681 ret = smu_v13_0_set_single_dpm_table(smu,
682 SMU_DCEFCLK,
683 dpm_table);
684 if (ret)
685 return ret;
686 } else {
687 dpm_table->count = 1;
688 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100;
689 dpm_table->dpm_levels[0].enabled = true;
690 }
691
692 return 0;
693 }
694
smu_v13_0_0_is_dpm_running(struct smu_context * smu)695 static bool smu_v13_0_0_is_dpm_running(struct smu_context *smu)
696 {
697 int ret = 0;
698 struct smu_feature_bits feature_enabled;
699
700 ret = smu_cmn_get_enabled_mask(smu, &feature_enabled);
701 if (ret)
702 return false;
703
704 return smu_feature_bits_test_mask(&feature_enabled,
705 smu_v13_0_0_dpm_features.bits);
706 }
707
smu_v13_0_0_system_features_control(struct smu_context * smu,bool en)708 static int smu_v13_0_0_system_features_control(struct smu_context *smu,
709 bool en)
710 {
711 return smu_v13_0_system_features_control(smu, en);
712 }
713
smu_v13_0_get_throttler_status(SmuMetrics_t * metrics)714 static uint32_t smu_v13_0_get_throttler_status(SmuMetrics_t *metrics)
715 {
716 uint32_t throttler_status = 0;
717 int i;
718
719 for (i = 0; i < THROTTLER_COUNT; i++)
720 throttler_status |=
721 (metrics->ThrottlingPercentage[i] ? 1U << i : 0);
722
723 return throttler_status;
724 }
725
726 #define SMU_13_0_0_BUSY_THRESHOLD 15
smu_v13_0_0_get_smu_metrics_data(struct smu_context * smu,MetricsMember_t member,uint32_t * value)727 static int smu_v13_0_0_get_smu_metrics_data(struct smu_context *smu,
728 MetricsMember_t member,
729 uint32_t *value)
730 {
731 struct smu_table_context *smu_table = &smu->smu_table;
732 SmuMetrics_t *metrics =
733 &(((SmuMetricsExternal_t *)(smu_table->metrics_table))->SmuMetrics);
734 int ret = 0;
735
736 ret = smu_cmn_get_metrics_table(smu,
737 NULL,
738 false);
739 if (ret)
740 return ret;
741
742 switch (member) {
743 case METRICS_CURR_GFXCLK:
744 *value = metrics->CurrClock[PPCLK_GFXCLK];
745 break;
746 case METRICS_CURR_SOCCLK:
747 *value = metrics->CurrClock[PPCLK_SOCCLK];
748 break;
749 case METRICS_CURR_UCLK:
750 *value = metrics->CurrClock[PPCLK_UCLK];
751 break;
752 case METRICS_CURR_VCLK:
753 *value = metrics->CurrClock[PPCLK_VCLK_0];
754 break;
755 case METRICS_CURR_VCLK1:
756 *value = metrics->CurrClock[PPCLK_VCLK_1];
757 break;
758 case METRICS_CURR_DCLK:
759 *value = metrics->CurrClock[PPCLK_DCLK_0];
760 break;
761 case METRICS_CURR_DCLK1:
762 *value = metrics->CurrClock[PPCLK_DCLK_1];
763 break;
764 case METRICS_CURR_FCLK:
765 *value = metrics->CurrClock[PPCLK_FCLK];
766 break;
767 case METRICS_CURR_DCEFCLK:
768 *value = metrics->CurrClock[PPCLK_DCFCLK];
769 break;
770 case METRICS_AVERAGE_GFXCLK:
771 if (metrics->AverageGfxActivity <= SMU_13_0_0_BUSY_THRESHOLD)
772 *value = metrics->AverageGfxclkFrequencyPostDs;
773 else
774 *value = metrics->AverageGfxclkFrequencyPreDs;
775 break;
776 case METRICS_AVERAGE_FCLK:
777 if (smu_safe_u16_nn(metrics->AverageUclkActivity) <= SMU_13_0_0_BUSY_THRESHOLD)
778 *value = metrics->AverageFclkFrequencyPostDs;
779 else
780 *value = metrics->AverageFclkFrequencyPreDs;
781 break;
782 case METRICS_AVERAGE_UCLK:
783 if (smu_safe_u16_nn(metrics->AverageUclkActivity) <= SMU_13_0_0_BUSY_THRESHOLD)
784 *value = metrics->AverageMemclkFrequencyPostDs;
785 else
786 *value = metrics->AverageMemclkFrequencyPreDs;
787 break;
788 case METRICS_AVERAGE_VCLK:
789 *value = metrics->AverageVclk0Frequency;
790 break;
791 case METRICS_AVERAGE_DCLK:
792 *value = metrics->AverageDclk0Frequency;
793 break;
794 case METRICS_AVERAGE_VCLK1:
795 *value = metrics->AverageVclk1Frequency;
796 break;
797 case METRICS_AVERAGE_DCLK1:
798 *value = metrics->AverageDclk1Frequency;
799 break;
800 case METRICS_AVERAGE_GFXACTIVITY:
801 *value = metrics->AverageGfxActivity;
802 break;
803 case METRICS_AVERAGE_MEMACTIVITY:
804 *value = smu_safe_u16_nn(metrics->AverageUclkActivity);
805 break;
806 case METRICS_AVERAGE_VCNACTIVITY:
807 *value = max(metrics->Vcn0ActivityPercentage,
808 metrics->Vcn1ActivityPercentage);
809 break;
810 case METRICS_AVERAGE_SOCKETPOWER:
811 *value = metrics->AverageSocketPower * MILLIWATT_PER_WATT;
812 break;
813 case METRICS_TEMPERATURE_EDGE:
814 *value = metrics->AvgTemperature[TEMP_EDGE] *
815 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
816 break;
817 case METRICS_TEMPERATURE_HOTSPOT:
818 *value = metrics->AvgTemperature[TEMP_HOTSPOT] *
819 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
820 break;
821 case METRICS_TEMPERATURE_MEM:
822 *value = metrics->AvgTemperature[TEMP_MEM] *
823 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
824 break;
825 case METRICS_TEMPERATURE_VRGFX:
826 *value = metrics->AvgTemperature[TEMP_VR_GFX] *
827 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
828 break;
829 case METRICS_TEMPERATURE_VRSOC:
830 *value = metrics->AvgTemperature[TEMP_VR_SOC] *
831 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
832 break;
833 case METRICS_THROTTLER_STATUS:
834 *value = smu_v13_0_get_throttler_status(metrics);
835 break;
836 case METRICS_CURR_FANSPEED:
837 *value = metrics->AvgFanRpm;
838 break;
839 case METRICS_CURR_FANPWM:
840 *value = metrics->AvgFanPwm;
841 break;
842 case METRICS_VOLTAGE_VDDGFX:
843 *value = metrics->AvgVoltage[SVI_PLANE_GFX];
844 break;
845 case METRICS_PCIE_RATE:
846 *value = metrics->PcieRate;
847 break;
848 case METRICS_PCIE_WIDTH:
849 *value = metrics->PcieWidth;
850 break;
851 default:
852 *value = UINT_MAX;
853 break;
854 }
855
856 return ret;
857 }
858
smu_v13_0_0_get_dpm_ultimate_freq(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t * min,uint32_t * max)859 static int smu_v13_0_0_get_dpm_ultimate_freq(struct smu_context *smu,
860 enum smu_clk_type clk_type,
861 uint32_t *min,
862 uint32_t *max)
863 {
864 struct smu_13_0_dpm_context *dpm_context =
865 smu->smu_dpm.dpm_context;
866 struct smu_dpm_table *dpm_table;
867
868 switch (clk_type) {
869 case SMU_MCLK:
870 case SMU_UCLK:
871 /* uclk dpm table */
872 dpm_table = &dpm_context->dpm_tables.uclk_table;
873 break;
874 case SMU_GFXCLK:
875 case SMU_SCLK:
876 /* gfxclk dpm table */
877 dpm_table = &dpm_context->dpm_tables.gfx_table;
878 break;
879 case SMU_SOCCLK:
880 /* socclk dpm table */
881 dpm_table = &dpm_context->dpm_tables.soc_table;
882 break;
883 case SMU_FCLK:
884 /* fclk dpm table */
885 dpm_table = &dpm_context->dpm_tables.fclk_table;
886 break;
887 case SMU_VCLK:
888 case SMU_VCLK1:
889 /* vclk dpm table */
890 dpm_table = &dpm_context->dpm_tables.vclk_table;
891 break;
892 case SMU_DCLK:
893 case SMU_DCLK1:
894 /* dclk dpm table */
895 dpm_table = &dpm_context->dpm_tables.dclk_table;
896 break;
897 default:
898 dev_err(smu->adev->dev, "Unsupported clock type!\n");
899 return -EINVAL;
900 }
901
902 if (min)
903 *min = SMU_DPM_TABLE_MIN(dpm_table);
904 if (max)
905 *max = SMU_DPM_TABLE_MAX(dpm_table);
906
907 return 0;
908 }
909
smu_v13_0_0_read_sensor(struct smu_context * smu,enum amd_pp_sensors sensor,void * data,uint32_t * size)910 static int smu_v13_0_0_read_sensor(struct smu_context *smu,
911 enum amd_pp_sensors sensor,
912 void *data,
913 uint32_t *size)
914 {
915 struct smu_table_context *table_context = &smu->smu_table;
916 PPTable_t *smc_pptable = table_context->driver_pptable;
917 int ret = 0;
918
919 switch (sensor) {
920 case AMDGPU_PP_SENSOR_MAX_FAN_RPM:
921 *(uint16_t *)data = smc_pptable->SkuTable.FanMaximumRpm;
922 *size = 4;
923 break;
924 case AMDGPU_PP_SENSOR_MEM_LOAD:
925 ret = smu_v13_0_0_get_smu_metrics_data(smu,
926 METRICS_AVERAGE_MEMACTIVITY,
927 (uint32_t *)data);
928 *size = 4;
929 break;
930 case AMDGPU_PP_SENSOR_GPU_LOAD:
931 ret = smu_v13_0_0_get_smu_metrics_data(smu,
932 METRICS_AVERAGE_GFXACTIVITY,
933 (uint32_t *)data);
934 *size = 4;
935 break;
936 case AMDGPU_PP_SENSOR_VCN_LOAD:
937 ret = smu_v13_0_0_get_smu_metrics_data(smu,
938 METRICS_AVERAGE_VCNACTIVITY,
939 (uint32_t *)data);
940 *size = 4;
941 break;
942 case AMDGPU_PP_SENSOR_GPU_AVG_POWER:
943 ret = smu_v13_0_0_get_smu_metrics_data(smu,
944 METRICS_AVERAGE_SOCKETPOWER,
945 (uint32_t *)data);
946 *size = 4;
947 break;
948 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP:
949 ret = smu_v13_0_0_get_smu_metrics_data(smu,
950 METRICS_TEMPERATURE_HOTSPOT,
951 (uint32_t *)data);
952 *size = 4;
953 break;
954 case AMDGPU_PP_SENSOR_EDGE_TEMP:
955 ret = smu_v13_0_0_get_smu_metrics_data(smu,
956 METRICS_TEMPERATURE_EDGE,
957 (uint32_t *)data);
958 *size = 4;
959 break;
960 case AMDGPU_PP_SENSOR_MEM_TEMP:
961 ret = smu_v13_0_0_get_smu_metrics_data(smu,
962 METRICS_TEMPERATURE_MEM,
963 (uint32_t *)data);
964 *size = 4;
965 break;
966 case AMDGPU_PP_SENSOR_GFX_MCLK:
967 ret = smu_v13_0_0_get_smu_metrics_data(smu,
968 METRICS_CURR_UCLK,
969 (uint32_t *)data);
970 *(uint32_t *)data *= 100;
971 *size = 4;
972 break;
973 case AMDGPU_PP_SENSOR_GFX_SCLK:
974 ret = smu_v13_0_0_get_smu_metrics_data(smu,
975 METRICS_AVERAGE_GFXCLK,
976 (uint32_t *)data);
977 *(uint32_t *)data *= 100;
978 *size = 4;
979 break;
980 case AMDGPU_PP_SENSOR_VDDGFX:
981 ret = smu_v13_0_0_get_smu_metrics_data(smu,
982 METRICS_VOLTAGE_VDDGFX,
983 (uint32_t *)data);
984 *size = 4;
985 break;
986 case AMDGPU_PP_SENSOR_GPU_INPUT_POWER:
987 default:
988 ret = -EOPNOTSUPP;
989 break;
990 }
991
992 return ret;
993 }
994
smu_v13_0_0_get_current_clk_freq_by_table(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t * value)995 static int smu_v13_0_0_get_current_clk_freq_by_table(struct smu_context *smu,
996 enum smu_clk_type clk_type,
997 uint32_t *value)
998 {
999 MetricsMember_t member_type;
1000 int clk_id = 0;
1001
1002 clk_id = smu_cmn_to_asic_specific_index(smu,
1003 CMN2ASIC_MAPPING_CLK,
1004 clk_type);
1005 if (clk_id < 0)
1006 return -EINVAL;
1007
1008 switch (clk_id) {
1009 case PPCLK_GFXCLK:
1010 member_type = METRICS_AVERAGE_GFXCLK;
1011 break;
1012 case PPCLK_UCLK:
1013 member_type = METRICS_CURR_UCLK;
1014 break;
1015 case PPCLK_FCLK:
1016 member_type = METRICS_CURR_FCLK;
1017 break;
1018 case PPCLK_SOCCLK:
1019 member_type = METRICS_CURR_SOCCLK;
1020 break;
1021 case PPCLK_VCLK_0:
1022 member_type = METRICS_AVERAGE_VCLK;
1023 break;
1024 case PPCLK_DCLK_0:
1025 member_type = METRICS_AVERAGE_DCLK;
1026 break;
1027 case PPCLK_VCLK_1:
1028 member_type = METRICS_AVERAGE_VCLK1;
1029 break;
1030 case PPCLK_DCLK_1:
1031 member_type = METRICS_AVERAGE_DCLK1;
1032 break;
1033 case PPCLK_DCFCLK:
1034 member_type = METRICS_CURR_DCEFCLK;
1035 break;
1036 default:
1037 return -EINVAL;
1038 }
1039
1040 return smu_v13_0_0_get_smu_metrics_data(smu,
1041 member_type,
1042 value);
1043 }
1044
smu_v13_0_0_is_od_feature_supported(struct smu_context * smu,int od_feature_bit)1045 static bool smu_v13_0_0_is_od_feature_supported(struct smu_context *smu,
1046 int od_feature_bit)
1047 {
1048 PPTable_t *pptable = smu->smu_table.driver_pptable;
1049 const OverDriveLimits_t * const overdrive_upperlimits =
1050 &pptable->SkuTable.OverDriveLimitsBasicMax;
1051 int32_t min_value, max_value;
1052 bool feature_enabled;
1053
1054 switch (od_feature_bit) {
1055 case PP_OD_FEATURE_FAN_CURVE_BIT:
1056 feature_enabled = !!(overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit));
1057 if (feature_enabled) {
1058 smu_v13_0_0_get_od_setting_limits(smu, PP_OD_FEATURE_FAN_CURVE_TEMP,
1059 &min_value, &max_value);
1060 if (!min_value && !max_value) {
1061 feature_enabled = false;
1062 goto out;
1063 }
1064
1065 smu_v13_0_0_get_od_setting_limits(smu, PP_OD_FEATURE_FAN_CURVE_PWM,
1066 &min_value, &max_value);
1067 if (!min_value && !max_value) {
1068 feature_enabled = false;
1069 goto out;
1070 }
1071 }
1072 break;
1073 default:
1074 feature_enabled = !!(overdrive_upperlimits->FeatureCtrlMask & (1U << od_feature_bit));
1075 break;
1076 }
1077
1078 out:
1079 return feature_enabled;
1080 }
1081
smu_v13_0_0_get_od_setting_limits(struct smu_context * smu,int od_feature_bit,int32_t * min,int32_t * max)1082 static void smu_v13_0_0_get_od_setting_limits(struct smu_context *smu,
1083 int od_feature_bit,
1084 int32_t *min,
1085 int32_t *max)
1086 {
1087 PPTable_t *pptable = smu->smu_table.driver_pptable;
1088 const OverDriveLimits_t * const overdrive_upperlimits =
1089 &pptable->SkuTable.OverDriveLimitsBasicMax;
1090 const OverDriveLimits_t * const overdrive_lowerlimits =
1091 &pptable->SkuTable.OverDriveLimitsMin;
1092 int32_t od_min_setting, od_max_setting;
1093
1094 switch (od_feature_bit) {
1095 case PP_OD_FEATURE_GFXCLK_FMIN:
1096 od_min_setting = overdrive_lowerlimits->GfxclkFmin;
1097 od_max_setting = overdrive_upperlimits->GfxclkFmin;
1098 break;
1099 case PP_OD_FEATURE_GFXCLK_FMAX:
1100 od_min_setting = overdrive_lowerlimits->GfxclkFmax;
1101 od_max_setting = overdrive_upperlimits->GfxclkFmax;
1102 break;
1103 case PP_OD_FEATURE_UCLK_FMIN:
1104 od_min_setting = overdrive_lowerlimits->UclkFmin;
1105 od_max_setting = overdrive_upperlimits->UclkFmin;
1106 break;
1107 case PP_OD_FEATURE_UCLK_FMAX:
1108 od_min_setting = overdrive_lowerlimits->UclkFmax;
1109 od_max_setting = overdrive_upperlimits->UclkFmax;
1110 break;
1111 case PP_OD_FEATURE_GFX_VF_CURVE:
1112 od_min_setting = overdrive_lowerlimits->VoltageOffsetPerZoneBoundary;
1113 od_max_setting = overdrive_upperlimits->VoltageOffsetPerZoneBoundary;
1114 break;
1115 case PP_OD_FEATURE_FAN_CURVE_TEMP:
1116 od_min_setting = overdrive_lowerlimits->FanLinearTempPoints;
1117 od_max_setting = overdrive_upperlimits->FanLinearTempPoints;
1118 break;
1119 case PP_OD_FEATURE_FAN_CURVE_PWM:
1120 od_min_setting = overdrive_lowerlimits->FanLinearPwmPoints;
1121 od_max_setting = overdrive_upperlimits->FanLinearPwmPoints;
1122 break;
1123 case PP_OD_FEATURE_FAN_ACOUSTIC_LIMIT:
1124 od_min_setting = overdrive_lowerlimits->AcousticLimitRpmThreshold;
1125 od_max_setting = overdrive_upperlimits->AcousticLimitRpmThreshold;
1126 break;
1127 case PP_OD_FEATURE_FAN_ACOUSTIC_TARGET:
1128 od_min_setting = overdrive_lowerlimits->AcousticTargetRpmThreshold;
1129 od_max_setting = overdrive_upperlimits->AcousticTargetRpmThreshold;
1130 break;
1131 case PP_OD_FEATURE_FAN_TARGET_TEMPERATURE:
1132 od_min_setting = overdrive_lowerlimits->FanTargetTemperature;
1133 od_max_setting = overdrive_upperlimits->FanTargetTemperature;
1134 break;
1135 case PP_OD_FEATURE_FAN_MINIMUM_PWM:
1136 od_min_setting = overdrive_lowerlimits->FanMinimumPwm;
1137 od_max_setting = overdrive_upperlimits->FanMinimumPwm;
1138 break;
1139 case PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE:
1140 od_min_setting = overdrive_lowerlimits->FanZeroRpmEnable;
1141 od_max_setting = overdrive_upperlimits->FanZeroRpmEnable;
1142 break;
1143 case PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP:
1144 od_min_setting = overdrive_lowerlimits->FanZeroRpmStopTemp;
1145 od_max_setting = overdrive_upperlimits->FanZeroRpmStopTemp;
1146 break;
1147 default:
1148 od_min_setting = od_max_setting = INT_MAX;
1149 break;
1150 }
1151
1152 if (min)
1153 *min = od_min_setting;
1154 if (max)
1155 *max = od_max_setting;
1156 }
1157
smu_v13_0_0_dump_od_table(struct smu_context * smu,OverDriveTableExternal_t * od_table)1158 static void smu_v13_0_0_dump_od_table(struct smu_context *smu,
1159 OverDriveTableExternal_t *od_table)
1160 {
1161 struct amdgpu_device *adev = smu->adev;
1162
1163 dev_dbg(adev->dev, "OD: Gfxclk: (%d, %d)\n", od_table->OverDriveTable.GfxclkFmin,
1164 od_table->OverDriveTable.GfxclkFmax);
1165 dev_dbg(adev->dev, "OD: Uclk: (%d, %d)\n", od_table->OverDriveTable.UclkFmin,
1166 od_table->OverDriveTable.UclkFmax);
1167 }
1168
smu_v13_0_0_get_overdrive_table(struct smu_context * smu,OverDriveTableExternal_t * od_table)1169 static int smu_v13_0_0_get_overdrive_table(struct smu_context *smu,
1170 OverDriveTableExternal_t *od_table)
1171 {
1172 int ret = 0;
1173
1174 ret = smu_cmn_update_table(smu,
1175 SMU_TABLE_OVERDRIVE,
1176 0,
1177 (void *)od_table,
1178 false);
1179 if (ret)
1180 dev_err(smu->adev->dev, "Failed to get overdrive table!\n");
1181
1182 return ret;
1183 }
1184
smu_v13_0_0_upload_overdrive_table(struct smu_context * smu,OverDriveTableExternal_t * od_table)1185 static int smu_v13_0_0_upload_overdrive_table(struct smu_context *smu,
1186 OverDriveTableExternal_t *od_table)
1187 {
1188 int ret = 0;
1189
1190 ret = smu_cmn_update_table(smu,
1191 SMU_TABLE_OVERDRIVE,
1192 0,
1193 (void *)od_table,
1194 true);
1195 if (ret)
1196 dev_err(smu->adev->dev, "Failed to upload overdrive table!\n");
1197
1198 return ret;
1199 }
1200
smu_v13_0_0_emit_clk_levels(struct smu_context * smu,enum smu_clk_type clk_type,char * buf,int * offset)1201 static int smu_v13_0_0_emit_clk_levels(struct smu_context *smu,
1202 enum smu_clk_type clk_type, char *buf,
1203 int *offset)
1204 {
1205 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
1206 struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;
1207 OverDriveTableExternal_t *od_table =
1208 (OverDriveTableExternal_t *)smu->smu_table.overdrive_table;
1209 int i, curr_freq, size = *offset, start_offset = *offset;
1210 struct smu_dpm_table *single_dpm_table = NULL;
1211 struct smu_pcie_table *pcie_table;
1212 uint32_t gen_speed, lane_width;
1213 int32_t min_value, max_value;
1214 int ret = 0;
1215
1216 if (amdgpu_ras_intr_triggered()) {
1217 sysfs_emit_at(buf, size, "unavailable\n");
1218 return -EBUSY;
1219 }
1220
1221 switch (clk_type) {
1222 case SMU_SCLK:
1223 single_dpm_table = &(dpm_context->dpm_tables.gfx_table);
1224 break;
1225 case SMU_MCLK:
1226 single_dpm_table = &(dpm_context->dpm_tables.uclk_table);
1227 break;
1228 case SMU_SOCCLK:
1229 single_dpm_table = &(dpm_context->dpm_tables.soc_table);
1230 break;
1231 case SMU_FCLK:
1232 single_dpm_table = &(dpm_context->dpm_tables.fclk_table);
1233 break;
1234 case SMU_VCLK:
1235 case SMU_VCLK1:
1236 single_dpm_table = &(dpm_context->dpm_tables.vclk_table);
1237 break;
1238 case SMU_DCLK:
1239 case SMU_DCLK1:
1240 single_dpm_table = &(dpm_context->dpm_tables.dclk_table);
1241 break;
1242 case SMU_DCEFCLK:
1243 single_dpm_table = &(dpm_context->dpm_tables.dcef_table);
1244 break;
1245 case SMU_PCIE:
1246 ret = smu_v13_0_0_get_smu_metrics_data(smu,
1247 METRICS_PCIE_RATE,
1248 &gen_speed);
1249 if (ret)
1250 return ret;
1251
1252 ret = smu_v13_0_0_get_smu_metrics_data(smu,
1253 METRICS_PCIE_WIDTH,
1254 &lane_width);
1255 if (ret)
1256 return ret;
1257
1258 pcie_table = &(dpm_context->dpm_tables.pcie_table);
1259 return smu_cmn_print_pcie_levels(smu, pcie_table,
1260 SMU_DPM_PCIE_GEN_IDX(gen_speed),
1261 SMU_DPM_PCIE_WIDTH_IDX(lane_width),
1262 buf, offset);
1263 case SMU_OD_SCLK:
1264 if (!smu_v13_0_0_is_od_feature_supported(smu,
1265 PP_OD_FEATURE_GFXCLK_BIT))
1266 break;
1267
1268 size += sysfs_emit_at(buf, size, "OD_SCLK:\n");
1269 size += sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMhz\n",
1270 od_table->OverDriveTable.GfxclkFmin,
1271 od_table->OverDriveTable.GfxclkFmax);
1272 break;
1273
1274 case SMU_OD_MCLK:
1275 if (!smu_v13_0_0_is_od_feature_supported(smu,
1276 PP_OD_FEATURE_UCLK_BIT))
1277 break;
1278
1279 size += sysfs_emit_at(buf, size, "OD_MCLK:\n");
1280 size += sysfs_emit_at(buf, size, "0: %uMhz\n1: %uMHz\n",
1281 od_table->OverDriveTable.UclkFmin,
1282 od_table->OverDriveTable.UclkFmax);
1283 break;
1284
1285 case SMU_OD_VDDGFX_OFFSET:
1286 if (!smu_v13_0_0_is_od_feature_supported(smu,
1287 PP_OD_FEATURE_GFX_VF_CURVE_BIT))
1288 break;
1289
1290 size += sysfs_emit_at(buf, size, "OD_VDDGFX_OFFSET:\n");
1291 size += sysfs_emit_at(buf, size, "%dmV\n",
1292 od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[0]);
1293 break;
1294
1295 case SMU_OD_FAN_CURVE:
1296 if (!smu_v13_0_0_is_od_feature_supported(smu,
1297 PP_OD_FEATURE_FAN_CURVE_BIT))
1298 break;
1299
1300 size += sysfs_emit_at(buf, size, "OD_FAN_CURVE:\n");
1301 for (i = 0; i < NUM_OD_FAN_MAX_POINTS - 1; i++)
1302 size += sysfs_emit_at(buf, size, "%d: %dC %d%%\n",
1303 i,
1304 (int)od_table->OverDriveTable.FanLinearTempPoints[i],
1305 (int)od_table->OverDriveTable.FanLinearPwmPoints[i]);
1306
1307 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
1308 smu_v13_0_0_get_od_setting_limits(smu,
1309 PP_OD_FEATURE_FAN_CURVE_TEMP,
1310 &min_value,
1311 &max_value);
1312 size += sysfs_emit_at(buf, size, "FAN_CURVE(hotspot temp): %uC %uC\n",
1313 min_value, max_value);
1314
1315 smu_v13_0_0_get_od_setting_limits(smu,
1316 PP_OD_FEATURE_FAN_CURVE_PWM,
1317 &min_value,
1318 &max_value);
1319 size += sysfs_emit_at(buf, size, "FAN_CURVE(fan speed): %u%% %u%%\n",
1320 min_value, max_value);
1321
1322 break;
1323
1324 case SMU_OD_ACOUSTIC_LIMIT:
1325 if (!smu_v13_0_0_is_od_feature_supported(smu,
1326 PP_OD_FEATURE_FAN_CURVE_BIT))
1327 break;
1328
1329 size += sysfs_emit_at(buf, size, "OD_ACOUSTIC_LIMIT:\n");
1330 size += sysfs_emit_at(buf, size, "%d\n",
1331 (int)od_table->OverDriveTable.AcousticLimitRpmThreshold);
1332
1333 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
1334 smu_v13_0_0_get_od_setting_limits(smu,
1335 PP_OD_FEATURE_FAN_ACOUSTIC_LIMIT,
1336 &min_value,
1337 &max_value);
1338 size += sysfs_emit_at(buf, size, "ACOUSTIC_LIMIT: %u %u\n",
1339 min_value, max_value);
1340 break;
1341
1342 case SMU_OD_ACOUSTIC_TARGET:
1343 if (!smu_v13_0_0_is_od_feature_supported(smu,
1344 PP_OD_FEATURE_FAN_CURVE_BIT))
1345 break;
1346
1347 size += sysfs_emit_at(buf, size, "OD_ACOUSTIC_TARGET:\n");
1348 size += sysfs_emit_at(buf, size, "%d\n",
1349 (int)od_table->OverDriveTable.AcousticTargetRpmThreshold);
1350
1351 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
1352 smu_v13_0_0_get_od_setting_limits(smu,
1353 PP_OD_FEATURE_FAN_ACOUSTIC_TARGET,
1354 &min_value,
1355 &max_value);
1356 size += sysfs_emit_at(buf, size, "ACOUSTIC_TARGET: %u %u\n",
1357 min_value, max_value);
1358 break;
1359
1360 case SMU_OD_FAN_TARGET_TEMPERATURE:
1361 if (!smu_v13_0_0_is_od_feature_supported(smu,
1362 PP_OD_FEATURE_FAN_CURVE_BIT))
1363 break;
1364
1365 size += sysfs_emit_at(buf, size, "FAN_TARGET_TEMPERATURE:\n");
1366 size += sysfs_emit_at(buf, size, "%d\n",
1367 (int)od_table->OverDriveTable.FanTargetTemperature);
1368
1369 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
1370 smu_v13_0_0_get_od_setting_limits(smu,
1371 PP_OD_FEATURE_FAN_TARGET_TEMPERATURE,
1372 &min_value,
1373 &max_value);
1374 size += sysfs_emit_at(buf, size, "TARGET_TEMPERATURE: %u %u\n",
1375 min_value, max_value);
1376 break;
1377
1378 case SMU_OD_FAN_MINIMUM_PWM:
1379 if (!smu_v13_0_0_is_od_feature_supported(smu,
1380 PP_OD_FEATURE_FAN_CURVE_BIT))
1381 break;
1382
1383 size += sysfs_emit_at(buf, size, "FAN_MINIMUM_PWM:\n");
1384 size += sysfs_emit_at(buf, size, "%d\n",
1385 (int)od_table->OverDriveTable.FanMinimumPwm);
1386
1387 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
1388 smu_v13_0_0_get_od_setting_limits(smu,
1389 PP_OD_FEATURE_FAN_MINIMUM_PWM,
1390 &min_value,
1391 &max_value);
1392 size += sysfs_emit_at(buf, size, "MINIMUM_PWM: %u %u\n",
1393 min_value, max_value);
1394 break;
1395
1396 case SMU_OD_FAN_ZERO_RPM_ENABLE:
1397 if (!smu_v13_0_0_is_od_feature_supported(smu,
1398 PP_OD_FEATURE_ZERO_FAN_BIT))
1399 break;
1400
1401 size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM_ENABLE:\n");
1402 size += sysfs_emit_at(buf, size, "%d\n",
1403 (int)od_table->OverDriveTable.FanZeroRpmEnable);
1404
1405 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
1406 smu_v13_0_0_get_od_setting_limits(smu,
1407 PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE,
1408 &min_value,
1409 &max_value);
1410 size += sysfs_emit_at(buf, size, "ZERO_RPM_ENABLE: %u %u\n",
1411 min_value, max_value);
1412 break;
1413
1414 case SMU_OD_FAN_ZERO_RPM_STOP_TEMP:
1415 if (!smu_v13_0_0_is_od_feature_supported(smu,
1416 PP_OD_FEATURE_ZERO_FAN_BIT))
1417 break;
1418
1419 size += sysfs_emit_at(buf, size, "FAN_ZERO_RPM_STOP_TEMPERATURE:\n");
1420 size += sysfs_emit_at(buf, size, "%d\n",
1421 (int)od_table->OverDriveTable.FanZeroRpmStopTemp);
1422
1423 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
1424 smu_v13_0_0_get_od_setting_limits(smu,
1425 PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP,
1426 &min_value,
1427 &max_value);
1428 size += sysfs_emit_at(buf, size, "ZERO_RPM_STOP_TEMPERATURE: %u %u\n",
1429 min_value, max_value);
1430 break;
1431
1432 case SMU_OD_RANGE:
1433 if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT) &&
1434 !smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT) &&
1435 !smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT))
1436 break;
1437
1438 size += sysfs_emit_at(buf, size, "%s:\n", "OD_RANGE");
1439
1440 if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT)) {
1441 smu_v13_0_0_get_od_setting_limits(smu,
1442 PP_OD_FEATURE_GFXCLK_FMIN,
1443 &min_value,
1444 NULL);
1445 smu_v13_0_0_get_od_setting_limits(smu,
1446 PP_OD_FEATURE_GFXCLK_FMAX,
1447 NULL,
1448 &max_value);
1449 size += sysfs_emit_at(buf, size, "SCLK: %7uMhz %10uMhz\n",
1450 min_value, max_value);
1451 }
1452
1453 if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT)) {
1454 smu_v13_0_0_get_od_setting_limits(smu,
1455 PP_OD_FEATURE_UCLK_FMIN,
1456 &min_value,
1457 NULL);
1458 smu_v13_0_0_get_od_setting_limits(smu,
1459 PP_OD_FEATURE_UCLK_FMAX,
1460 NULL,
1461 &max_value);
1462 size += sysfs_emit_at(buf, size, "MCLK: %7uMhz %10uMhz\n",
1463 min_value, max_value);
1464 }
1465
1466 if (smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) {
1467 smu_v13_0_0_get_od_setting_limits(smu,
1468 PP_OD_FEATURE_GFX_VF_CURVE,
1469 &min_value,
1470 &max_value);
1471 size += sysfs_emit_at(buf, size, "VDDGFX_OFFSET: %7dmv %10dmv\n",
1472 min_value, max_value);
1473 }
1474 break;
1475
1476 default:
1477 break;
1478 }
1479
1480 if (single_dpm_table) {
1481 ret = smu_v13_0_0_get_current_clk_freq_by_table(smu, clk_type,
1482 &curr_freq);
1483 if (ret) {
1484 dev_err(smu->adev->dev,
1485 "Failed to get current clock freq!");
1486 return ret;
1487 }
1488 return smu_cmn_print_dpm_clk_levels(smu, single_dpm_table,
1489 curr_freq, buf, offset);
1490 }
1491
1492 *offset += size - start_offset;
1493
1494 return 0;
1495 }
1496
1497
smu_v13_0_0_od_restore_table_single(struct smu_context * smu,long input)1498 static int smu_v13_0_0_od_restore_table_single(struct smu_context *smu, long input)
1499 {
1500 struct smu_table_context *table_context = &smu->smu_table;
1501 OverDriveTableExternal_t *boot_overdrive_table =
1502 (OverDriveTableExternal_t *)table_context->boot_overdrive_table;
1503 OverDriveTableExternal_t *od_table =
1504 (OverDriveTableExternal_t *)table_context->overdrive_table;
1505 struct amdgpu_device *adev = smu->adev;
1506 int i;
1507
1508 switch (input) {
1509 case PP_OD_EDIT_FAN_CURVE:
1510 for (i = 0; i < NUM_OD_FAN_MAX_POINTS; i++) {
1511 od_table->OverDriveTable.FanLinearTempPoints[i] =
1512 boot_overdrive_table->OverDriveTable.FanLinearTempPoints[i];
1513 od_table->OverDriveTable.FanLinearPwmPoints[i] =
1514 boot_overdrive_table->OverDriveTable.FanLinearPwmPoints[i];
1515 }
1516 od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
1517 od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
1518 break;
1519 case PP_OD_EDIT_ACOUSTIC_LIMIT:
1520 od_table->OverDriveTable.AcousticLimitRpmThreshold =
1521 boot_overdrive_table->OverDriveTable.AcousticLimitRpmThreshold;
1522 od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
1523 od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
1524 break;
1525 case PP_OD_EDIT_ACOUSTIC_TARGET:
1526 od_table->OverDriveTable.AcousticTargetRpmThreshold =
1527 boot_overdrive_table->OverDriveTable.AcousticTargetRpmThreshold;
1528 od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
1529 od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
1530 break;
1531 case PP_OD_EDIT_FAN_TARGET_TEMPERATURE:
1532 od_table->OverDriveTable.FanTargetTemperature =
1533 boot_overdrive_table->OverDriveTable.FanTargetTemperature;
1534 od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
1535 od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
1536 break;
1537 case PP_OD_EDIT_FAN_MINIMUM_PWM:
1538 od_table->OverDriveTable.FanMinimumPwm =
1539 boot_overdrive_table->OverDriveTable.FanMinimumPwm;
1540 od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
1541 od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
1542 break;
1543 case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
1544 od_table->OverDriveTable.FanZeroRpmEnable =
1545 boot_overdrive_table->OverDriveTable.FanZeroRpmEnable;
1546 od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
1547 break;
1548 case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP:
1549 od_table->OverDriveTable.FanZeroRpmStopTemp =
1550 boot_overdrive_table->OverDriveTable.FanZeroRpmStopTemp;
1551 od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
1552 break;
1553 default:
1554 dev_info(adev->dev, "Invalid table index: %ld\n", input);
1555 return -EINVAL;
1556 }
1557
1558 return 0;
1559 }
1560
smu_v13_0_0_od_edit_dpm_table(struct smu_context * smu,enum PP_OD_DPM_TABLE_COMMAND type,long input[],uint32_t size)1561 static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
1562 enum PP_OD_DPM_TABLE_COMMAND type,
1563 long input[],
1564 uint32_t size)
1565 {
1566 struct smu_table_context *table_context = &smu->smu_table;
1567 OverDriveTableExternal_t *od_table =
1568 (OverDriveTableExternal_t *)table_context->overdrive_table;
1569 struct amdgpu_device *adev = smu->adev;
1570 uint32_t offset_of_voltageoffset;
1571 int32_t minimum, maximum;
1572 uint32_t feature_ctrlmask;
1573 int i, ret = 0;
1574
1575 switch (type) {
1576 case PP_OD_EDIT_SCLK_VDDC_TABLE:
1577 if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFXCLK_BIT)) {
1578 dev_warn(adev->dev, "GFXCLK_LIMITS setting not supported!\n");
1579 return -ENOTSUPP;
1580 }
1581
1582 for (i = 0; i < size; i += 2) {
1583 if (i + 2 > size) {
1584 dev_info(adev->dev, "invalid number of input parameters %d\n", size);
1585 return -EINVAL;
1586 }
1587
1588 switch (input[i]) {
1589 case 0:
1590 smu_v13_0_0_get_od_setting_limits(smu,
1591 PP_OD_FEATURE_GFXCLK_FMIN,
1592 &minimum,
1593 &maximum);
1594 if (input[i + 1] < minimum ||
1595 input[i + 1] > maximum) {
1596 dev_info(adev->dev, "GfxclkFmin (%ld) must be within [%u, %u]!\n",
1597 input[i + 1], minimum, maximum);
1598 return -EINVAL;
1599 }
1600
1601 od_table->OverDriveTable.GfxclkFmin = input[i + 1];
1602 od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_GFXCLK_BIT;
1603 break;
1604
1605 case 1:
1606 smu_v13_0_0_get_od_setting_limits(smu,
1607 PP_OD_FEATURE_GFXCLK_FMAX,
1608 &minimum,
1609 &maximum);
1610 if (input[i + 1] < minimum ||
1611 input[i + 1] > maximum) {
1612 dev_info(adev->dev, "GfxclkFmax (%ld) must be within [%u, %u]!\n",
1613 input[i + 1], minimum, maximum);
1614 return -EINVAL;
1615 }
1616
1617 od_table->OverDriveTable.GfxclkFmax = input[i + 1];
1618 od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_GFXCLK_BIT;
1619 break;
1620
1621 default:
1622 dev_info(adev->dev, "Invalid SCLK_VDDC_TABLE index: %ld\n", input[i]);
1623 dev_info(adev->dev, "Supported indices: [0:min,1:max]\n");
1624 return -EINVAL;
1625 }
1626 }
1627
1628 if (od_table->OverDriveTable.GfxclkFmin > od_table->OverDriveTable.GfxclkFmax) {
1629 dev_err(adev->dev,
1630 "Invalid setting: GfxclkFmin(%u) is bigger than GfxclkFmax(%u)\n",
1631 (uint32_t)od_table->OverDriveTable.GfxclkFmin,
1632 (uint32_t)od_table->OverDriveTable.GfxclkFmax);
1633 return -EINVAL;
1634 }
1635 break;
1636
1637 case PP_OD_EDIT_MCLK_VDDC_TABLE:
1638 if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_UCLK_BIT)) {
1639 dev_warn(adev->dev, "UCLK_LIMITS setting not supported!\n");
1640 return -ENOTSUPP;
1641 }
1642
1643 for (i = 0; i < size; i += 2) {
1644 if (i + 2 > size) {
1645 dev_info(adev->dev, "invalid number of input parameters %d\n", size);
1646 return -EINVAL;
1647 }
1648
1649 switch (input[i]) {
1650 case 0:
1651 smu_v13_0_0_get_od_setting_limits(smu,
1652 PP_OD_FEATURE_UCLK_FMIN,
1653 &minimum,
1654 &maximum);
1655 if (input[i + 1] < minimum ||
1656 input[i + 1] > maximum) {
1657 dev_info(adev->dev, "UclkFmin (%ld) must be within [%u, %u]!\n",
1658 input[i + 1], minimum, maximum);
1659 return -EINVAL;
1660 }
1661
1662 od_table->OverDriveTable.UclkFmin = input[i + 1];
1663 od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_UCLK_BIT;
1664 break;
1665
1666 case 1:
1667 smu_v13_0_0_get_od_setting_limits(smu,
1668 PP_OD_FEATURE_UCLK_FMAX,
1669 &minimum,
1670 &maximum);
1671 if (input[i + 1] < minimum ||
1672 input[i + 1] > maximum) {
1673 dev_info(adev->dev, "UclkFmax (%ld) must be within [%u, %u]!\n",
1674 input[i + 1], minimum, maximum);
1675 return -EINVAL;
1676 }
1677
1678 od_table->OverDriveTable.UclkFmax = input[i + 1];
1679 od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_UCLK_BIT;
1680 break;
1681
1682 default:
1683 dev_info(adev->dev, "Invalid MCLK_VDDC_TABLE index: %ld\n", input[i]);
1684 dev_info(adev->dev, "Supported indices: [0:min,1:max]\n");
1685 return -EINVAL;
1686 }
1687 }
1688
1689 if (od_table->OverDriveTable.UclkFmin > od_table->OverDriveTable.UclkFmax) {
1690 dev_err(adev->dev,
1691 "Invalid setting: UclkFmin(%u) is bigger than UclkFmax(%u)\n",
1692 (uint32_t)od_table->OverDriveTable.UclkFmin,
1693 (uint32_t)od_table->OverDriveTable.UclkFmax);
1694 return -EINVAL;
1695 }
1696 break;
1697
1698 case PP_OD_EDIT_VDDGFX_OFFSET:
1699 if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_GFX_VF_CURVE_BIT)) {
1700 dev_warn(adev->dev, "Gfx offset setting not supported!\n");
1701 return -ENOTSUPP;
1702 }
1703
1704 smu_v13_0_0_get_od_setting_limits(smu,
1705 PP_OD_FEATURE_GFX_VF_CURVE,
1706 &minimum,
1707 &maximum);
1708 if (input[0] < minimum ||
1709 input[0] > maximum) {
1710 dev_info(adev->dev, "Voltage offset (%ld) must be within [%d, %d]!\n",
1711 input[0], minimum, maximum);
1712 return -EINVAL;
1713 }
1714
1715 for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++)
1716 od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i] = input[0];
1717 od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT);
1718 break;
1719
1720 case PP_OD_EDIT_FAN_CURVE:
1721 if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) {
1722 dev_warn(adev->dev, "Fan curve setting not supported!\n");
1723 return -ENOTSUPP;
1724 }
1725
1726 if (input[0] >= NUM_OD_FAN_MAX_POINTS - 1 ||
1727 input[0] < 0)
1728 return -EINVAL;
1729
1730 smu_v13_0_0_get_od_setting_limits(smu,
1731 PP_OD_FEATURE_FAN_CURVE_TEMP,
1732 &minimum,
1733 &maximum);
1734 if (input[1] < minimum ||
1735 input[1] > maximum) {
1736 dev_info(adev->dev, "Fan curve temp setting(%ld) must be within [%d, %d]!\n",
1737 input[1], minimum, maximum);
1738 return -EINVAL;
1739 }
1740
1741 smu_v13_0_0_get_od_setting_limits(smu,
1742 PP_OD_FEATURE_FAN_CURVE_PWM,
1743 &minimum,
1744 &maximum);
1745 if (input[2] < minimum ||
1746 input[2] > maximum) {
1747 dev_info(adev->dev, "Fan curve pwm setting(%ld) must be within [%d, %d]!\n",
1748 input[2], minimum, maximum);
1749 return -EINVAL;
1750 }
1751
1752 od_table->OverDriveTable.FanLinearTempPoints[input[0]] = input[1];
1753 od_table->OverDriveTable.FanLinearPwmPoints[input[0]] = input[2];
1754 od_table->OverDriveTable.FanMode = FAN_MODE_MANUAL_LINEAR;
1755 od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
1756 break;
1757
1758 case PP_OD_EDIT_ACOUSTIC_LIMIT:
1759 if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) {
1760 dev_warn(adev->dev, "Fan curve setting not supported!\n");
1761 return -ENOTSUPP;
1762 }
1763
1764 smu_v13_0_0_get_od_setting_limits(smu,
1765 PP_OD_FEATURE_FAN_ACOUSTIC_LIMIT,
1766 &minimum,
1767 &maximum);
1768 if (input[0] < minimum ||
1769 input[0] > maximum) {
1770 dev_info(adev->dev, "acoustic limit threshold setting(%ld) must be within [%d, %d]!\n",
1771 input[0], minimum, maximum);
1772 return -EINVAL;
1773 }
1774
1775 od_table->OverDriveTable.AcousticLimitRpmThreshold = input[0];
1776 od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
1777 od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
1778 break;
1779
1780 case PP_OD_EDIT_ACOUSTIC_TARGET:
1781 if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) {
1782 dev_warn(adev->dev, "Fan curve setting not supported!\n");
1783 return -ENOTSUPP;
1784 }
1785
1786 smu_v13_0_0_get_od_setting_limits(smu,
1787 PP_OD_FEATURE_FAN_ACOUSTIC_TARGET,
1788 &minimum,
1789 &maximum);
1790 if (input[0] < minimum ||
1791 input[0] > maximum) {
1792 dev_info(adev->dev, "acoustic target threshold setting(%ld) must be within [%d, %d]!\n",
1793 input[0], minimum, maximum);
1794 return -EINVAL;
1795 }
1796
1797 od_table->OverDriveTable.AcousticTargetRpmThreshold = input[0];
1798 od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
1799 od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
1800 break;
1801
1802 case PP_OD_EDIT_FAN_TARGET_TEMPERATURE:
1803 if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) {
1804 dev_warn(adev->dev, "Fan curve setting not supported!\n");
1805 return -ENOTSUPP;
1806 }
1807
1808 smu_v13_0_0_get_od_setting_limits(smu,
1809 PP_OD_FEATURE_FAN_TARGET_TEMPERATURE,
1810 &minimum,
1811 &maximum);
1812 if (input[0] < minimum ||
1813 input[0] > maximum) {
1814 dev_info(adev->dev, "fan target temperature setting(%ld) must be within [%d, %d]!\n",
1815 input[0], minimum, maximum);
1816 return -EINVAL;
1817 }
1818
1819 od_table->OverDriveTable.FanTargetTemperature = input[0];
1820 od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
1821 od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
1822 break;
1823
1824 case PP_OD_EDIT_FAN_MINIMUM_PWM:
1825 if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_FAN_CURVE_BIT)) {
1826 dev_warn(adev->dev, "Fan curve setting not supported!\n");
1827 return -ENOTSUPP;
1828 }
1829
1830 smu_v13_0_0_get_od_setting_limits(smu,
1831 PP_OD_FEATURE_FAN_MINIMUM_PWM,
1832 &minimum,
1833 &maximum);
1834 if (input[0] < minimum ||
1835 input[0] > maximum) {
1836 dev_info(adev->dev, "fan minimum pwm setting(%ld) must be within [%d, %d]!\n",
1837 input[0], minimum, maximum);
1838 return -EINVAL;
1839 }
1840
1841 od_table->OverDriveTable.FanMinimumPwm = input[0];
1842 od_table->OverDriveTable.FanMode = FAN_MODE_AUTO;
1843 od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_FAN_CURVE_BIT);
1844 break;
1845
1846 case PP_OD_EDIT_FAN_ZERO_RPM_ENABLE:
1847 if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
1848 dev_warn(adev->dev, "Zero RPM setting not supported!\n");
1849 return -ENOTSUPP;
1850 }
1851
1852 smu_v13_0_0_get_od_setting_limits(smu,
1853 PP_OD_FEATURE_FAN_ZERO_RPM_ENABLE,
1854 &minimum,
1855 &maximum);
1856 if (input[0] < minimum ||
1857 input[0] > maximum) {
1858 dev_info(adev->dev, "zero RPM enable setting(%ld) must be within [%d, %d]!\n",
1859 input[0], minimum, maximum);
1860 return -EINVAL;
1861 }
1862
1863 od_table->OverDriveTable.FanZeroRpmEnable = input[0];
1864 od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
1865 break;
1866
1867 case PP_OD_EDIT_FAN_ZERO_RPM_STOP_TEMP:
1868 if (!smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_ZERO_FAN_BIT)) {
1869 dev_warn(adev->dev, "Zero RPM setting not supported!\n");
1870 return -ENOTSUPP;
1871 }
1872
1873 smu_v13_0_0_get_od_setting_limits(smu,
1874 PP_OD_FEATURE_FAN_ZERO_RPM_STOP_TEMP,
1875 &minimum,
1876 &maximum);
1877 if (input[0] < minimum ||
1878 input[0] > maximum) {
1879 dev_info(adev->dev, "zero RPM stop temperature setting(%ld) must be within [%d, %d]!\n",
1880 input[0], minimum, maximum);
1881 return -EINVAL;
1882 }
1883
1884 od_table->OverDriveTable.FanZeroRpmStopTemp = input[0];
1885 od_table->OverDriveTable.FeatureCtrlMask |= BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
1886 break;
1887
1888 case PP_OD_RESTORE_DEFAULT_TABLE:
1889 if (size == 1) {
1890 ret = smu_v13_0_0_od_restore_table_single(smu, input[0]);
1891 if (ret)
1892 return ret;
1893 } else {
1894 feature_ctrlmask = od_table->OverDriveTable.FeatureCtrlMask;
1895 memcpy(od_table,
1896 table_context->boot_overdrive_table,
1897 sizeof(OverDriveTableExternal_t));
1898 od_table->OverDriveTable.FeatureCtrlMask = feature_ctrlmask;
1899 }
1900 fallthrough;
1901 case PP_OD_COMMIT_DPM_TABLE:
1902 /*
1903 * The member below instructs PMFW the settings focused in
1904 * this single operation.
1905 * `uint32_t FeatureCtrlMask;`
1906 * It does not contain actual informations about user's custom
1907 * settings. Thus we do not cache it.
1908 */
1909 offset_of_voltageoffset = offsetof(OverDriveTable_t, VoltageOffsetPerZoneBoundary);
1910 if (memcmp((u8 *)od_table + offset_of_voltageoffset,
1911 table_context->user_overdrive_table + offset_of_voltageoffset,
1912 sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset)) {
1913 smu_v13_0_0_dump_od_table(smu, od_table);
1914
1915 ret = smu_v13_0_0_upload_overdrive_table(smu, od_table);
1916 if (ret) {
1917 dev_err(adev->dev, "Failed to upload overdrive table!\n");
1918 return ret;
1919 }
1920
1921 od_table->OverDriveTable.FeatureCtrlMask = 0;
1922 memcpy(table_context->user_overdrive_table + offset_of_voltageoffset,
1923 (u8 *)od_table + offset_of_voltageoffset,
1924 sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset);
1925
1926 if (!memcmp(table_context->user_overdrive_table,
1927 table_context->boot_overdrive_table,
1928 sizeof(OverDriveTableExternal_t)))
1929 smu->user_dpm_profile.user_od = false;
1930 else
1931 smu->user_dpm_profile.user_od = true;
1932 }
1933 break;
1934
1935 default:
1936 return -ENOSYS;
1937 }
1938
1939 return ret;
1940 }
1941
smu_v13_0_0_force_clk_levels(struct smu_context * smu,enum smu_clk_type clk_type,uint32_t mask)1942 static int smu_v13_0_0_force_clk_levels(struct smu_context *smu,
1943 enum smu_clk_type clk_type,
1944 uint32_t mask)
1945 {
1946 struct smu_dpm_context *smu_dpm = &smu->smu_dpm;
1947 struct smu_13_0_dpm_context *dpm_context = smu_dpm->dpm_context;
1948 struct smu_dpm_table *single_dpm_table;
1949 uint32_t soft_min_level, soft_max_level;
1950 uint32_t min_freq, max_freq;
1951 int ret = 0;
1952
1953 soft_min_level = mask ? (ffs(mask) - 1) : 0;
1954 soft_max_level = mask ? (fls(mask) - 1) : 0;
1955
1956 switch (clk_type) {
1957 case SMU_GFXCLK:
1958 case SMU_SCLK:
1959 single_dpm_table = &(dpm_context->dpm_tables.gfx_table);
1960 break;
1961 case SMU_MCLK:
1962 case SMU_UCLK:
1963 single_dpm_table = &(dpm_context->dpm_tables.uclk_table);
1964 break;
1965 case SMU_SOCCLK:
1966 single_dpm_table = &(dpm_context->dpm_tables.soc_table);
1967 break;
1968 case SMU_FCLK:
1969 single_dpm_table = &(dpm_context->dpm_tables.fclk_table);
1970 break;
1971 case SMU_VCLK:
1972 case SMU_VCLK1:
1973 single_dpm_table = &(dpm_context->dpm_tables.vclk_table);
1974 break;
1975 case SMU_DCLK:
1976 case SMU_DCLK1:
1977 single_dpm_table = &(dpm_context->dpm_tables.dclk_table);
1978 break;
1979 default:
1980 break;
1981 }
1982
1983 switch (clk_type) {
1984 case SMU_GFXCLK:
1985 case SMU_SCLK:
1986 case SMU_MCLK:
1987 case SMU_UCLK:
1988 case SMU_SOCCLK:
1989 case SMU_FCLK:
1990 case SMU_VCLK:
1991 case SMU_VCLK1:
1992 case SMU_DCLK:
1993 case SMU_DCLK1:
1994 if (single_dpm_table->flags & SMU_DPM_TABLE_FINE_GRAINED) {
1995 /* There is only 2 levels for fine grained DPM */
1996 soft_max_level = (soft_max_level >= 1 ? 1 : 0);
1997 soft_min_level = (soft_min_level >= 1 ? 1 : 0);
1998 } else {
1999 if ((soft_max_level >= single_dpm_table->count) ||
2000 (soft_min_level >= single_dpm_table->count))
2001 return -EINVAL;
2002 }
2003
2004 min_freq = single_dpm_table->dpm_levels[soft_min_level].value;
2005 max_freq = single_dpm_table->dpm_levels[soft_max_level].value;
2006
2007 ret = smu_v13_0_set_soft_freq_limited_range(smu,
2008 clk_type,
2009 min_freq,
2010 max_freq,
2011 false);
2012 break;
2013 case SMU_DCEFCLK:
2014 case SMU_PCIE:
2015 default:
2016 break;
2017 }
2018
2019 return ret;
2020 }
2021
2022 static const struct smu_temperature_range smu13_thermal_policy[] = {
2023 {-273150, 99000, 99000, -273150, 99000, 99000, -273150, 99000, 99000},
2024 { 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000, 120000},
2025 };
2026
smu_v13_0_0_get_thermal_temperature_range(struct smu_context * smu,struct smu_temperature_range * range)2027 static int smu_v13_0_0_get_thermal_temperature_range(struct smu_context *smu,
2028 struct smu_temperature_range *range)
2029 {
2030 struct smu_table_context *table_context = &smu->smu_table;
2031 struct smu_13_0_0_powerplay_table *powerplay_table =
2032 table_context->power_play_table;
2033 PPTable_t *pptable = smu->smu_table.driver_pptable;
2034
2035 if (amdgpu_sriov_vf(smu->adev))
2036 return 0;
2037
2038 if (!range)
2039 return -EINVAL;
2040
2041 memcpy(range, &smu13_thermal_policy[0], sizeof(struct smu_temperature_range));
2042
2043 range->max = pptable->SkuTable.TemperatureLimit[TEMP_EDGE] *
2044 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
2045 range->edge_emergency_max = (pptable->SkuTable.TemperatureLimit[TEMP_EDGE] + CTF_OFFSET_EDGE) *
2046 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
2047 range->hotspot_crit_max = pptable->SkuTable.TemperatureLimit[TEMP_HOTSPOT] *
2048 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
2049 range->hotspot_emergency_max = (pptable->SkuTable.TemperatureLimit[TEMP_HOTSPOT] + CTF_OFFSET_HOTSPOT) *
2050 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
2051 range->mem_crit_max = pptable->SkuTable.TemperatureLimit[TEMP_MEM] *
2052 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
2053 range->mem_emergency_max = (pptable->SkuTable.TemperatureLimit[TEMP_MEM] + CTF_OFFSET_MEM)*
2054 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES;
2055 range->software_shutdown_temp = powerplay_table->software_shutdown_temp;
2056 range->software_shutdown_temp_offset = pptable->SkuTable.FanAbnormalTempLimitOffset;
2057
2058 return 0;
2059 }
2060
smu_v13_0_0_get_gpu_metrics(struct smu_context * smu,void ** table)2061 static ssize_t smu_v13_0_0_get_gpu_metrics(struct smu_context *smu,
2062 void **table)
2063 {
2064 struct gpu_metrics_v1_3 *gpu_metrics =
2065 (struct gpu_metrics_v1_3 *)smu_driver_table_ptr(
2066 smu, SMU_DRIVER_TABLE_GPU_METRICS);
2067 SmuMetricsExternal_t metrics_ext;
2068 SmuMetrics_t *metrics = &metrics_ext.SmuMetrics;
2069 uint32_t mp1_ver = amdgpu_ip_version(smu->adev, MP1_HWIP, 0);
2070 int ret = 0;
2071
2072 ret = smu_cmn_get_metrics_table(smu,
2073 &metrics_ext,
2074 true);
2075 if (ret)
2076 return ret;
2077
2078 smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 3);
2079
2080 gpu_metrics->temperature_edge = metrics->AvgTemperature[TEMP_EDGE];
2081 gpu_metrics->temperature_hotspot = metrics->AvgTemperature[TEMP_HOTSPOT];
2082 gpu_metrics->temperature_mem = metrics->AvgTemperature[TEMP_MEM];
2083 gpu_metrics->temperature_vrgfx = metrics->AvgTemperature[TEMP_VR_GFX];
2084 gpu_metrics->temperature_vrsoc = metrics->AvgTemperature[TEMP_VR_SOC];
2085 gpu_metrics->temperature_vrmem = max(metrics->AvgTemperature[TEMP_VR_MEM0],
2086 metrics->AvgTemperature[TEMP_VR_MEM1]);
2087
2088 gpu_metrics->average_gfx_activity = metrics->AverageGfxActivity;
2089 gpu_metrics->average_umc_activity = smu_safe_u16_nn(metrics->AverageUclkActivity);
2090 gpu_metrics->average_mm_activity = max(metrics->Vcn0ActivityPercentage,
2091 metrics->Vcn1ActivityPercentage);
2092
2093 gpu_metrics->average_socket_power = metrics->AverageSocketPower;
2094
2095 if ((mp1_ver == IP_VERSION(13, 0, 0) && smu->smc_fw_version <= 0x004e1e00) ||
2096 (mp1_ver == IP_VERSION(13, 0, 10) && smu->smc_fw_version <= 0x00500800))
2097 gpu_metrics->energy_accumulator = metrics->EnergyAccumulator;
2098 else
2099 gpu_metrics->energy_accumulator = UINT_MAX;
2100
2101 if (metrics->AverageGfxActivity <= SMU_13_0_0_BUSY_THRESHOLD)
2102 gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPostDs;
2103 else
2104 gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPreDs;
2105
2106 if (smu_safe_u16_nn(metrics->AverageUclkActivity) <= SMU_13_0_0_BUSY_THRESHOLD)
2107 gpu_metrics->average_uclk_frequency = metrics->AverageMemclkFrequencyPostDs;
2108 else
2109 gpu_metrics->average_uclk_frequency = metrics->AverageMemclkFrequencyPreDs;
2110
2111 gpu_metrics->average_vclk0_frequency = metrics->AverageVclk0Frequency;
2112 gpu_metrics->average_dclk0_frequency = metrics->AverageDclk0Frequency;
2113 gpu_metrics->average_vclk1_frequency = metrics->AverageVclk1Frequency;
2114 gpu_metrics->average_dclk1_frequency = metrics->AverageDclk1Frequency;
2115
2116 gpu_metrics->current_gfxclk = gpu_metrics->average_gfxclk_frequency;
2117 gpu_metrics->current_socclk = metrics->CurrClock[PPCLK_SOCCLK];
2118 gpu_metrics->current_uclk = metrics->CurrClock[PPCLK_UCLK];
2119 gpu_metrics->current_vclk0 = metrics->CurrClock[PPCLK_VCLK_0];
2120 gpu_metrics->current_dclk0 = metrics->CurrClock[PPCLK_DCLK_0];
2121 gpu_metrics->current_vclk1 = metrics->CurrClock[PPCLK_VCLK_1];
2122 gpu_metrics->current_dclk1 = metrics->CurrClock[PPCLK_DCLK_1];
2123
2124 gpu_metrics->throttle_status =
2125 smu_v13_0_get_throttler_status(metrics);
2126 gpu_metrics->indep_throttle_status =
2127 smu_cmn_get_indep_throttler_status(gpu_metrics->throttle_status,
2128 smu_v13_0_0_throttler_map);
2129
2130 gpu_metrics->current_fan_speed = metrics->AvgFanRpm;
2131
2132 gpu_metrics->pcie_link_width = metrics->PcieWidth;
2133 if ((metrics->PcieRate - 1) > LINK_SPEED_MAX)
2134 gpu_metrics->pcie_link_speed = pcie_gen_to_speed(1);
2135 else
2136 gpu_metrics->pcie_link_speed = pcie_gen_to_speed(metrics->PcieRate);
2137
2138 gpu_metrics->system_clock_counter = ktime_get_boottime_ns();
2139
2140 gpu_metrics->voltage_gfx = metrics->AvgVoltage[SVI_PLANE_GFX];
2141 gpu_metrics->voltage_soc = metrics->AvgVoltage[SVI_PLANE_SOC];
2142 gpu_metrics->voltage_mem = metrics->AvgVoltage[SVI_PLANE_VMEMP];
2143
2144 *table = (void *)gpu_metrics;
2145
2146 smu_driver_table_update_cache_time(smu, SMU_DRIVER_TABLE_GPU_METRICS);
2147
2148 return sizeof(struct gpu_metrics_v1_3);
2149 }
2150
smu_v13_0_0_set_supported_od_feature_mask(struct smu_context * smu)2151 static void smu_v13_0_0_set_supported_od_feature_mask(struct smu_context *smu)
2152 {
2153 struct amdgpu_device *adev = smu->adev;
2154
2155 if (smu_v13_0_0_is_od_feature_supported(smu,
2156 PP_OD_FEATURE_FAN_CURVE_BIT))
2157 adev->pm.od_feature_mask |= OD_OPS_SUPPORT_FAN_CURVE_RETRIEVE |
2158 OD_OPS_SUPPORT_FAN_CURVE_SET |
2159 OD_OPS_SUPPORT_ACOUSTIC_LIMIT_THRESHOLD_RETRIEVE |
2160 OD_OPS_SUPPORT_ACOUSTIC_LIMIT_THRESHOLD_SET |
2161 OD_OPS_SUPPORT_ACOUSTIC_TARGET_THRESHOLD_RETRIEVE |
2162 OD_OPS_SUPPORT_ACOUSTIC_TARGET_THRESHOLD_SET |
2163 OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_RETRIEVE |
2164 OD_OPS_SUPPORT_FAN_TARGET_TEMPERATURE_SET |
2165 OD_OPS_SUPPORT_FAN_MINIMUM_PWM_RETRIEVE |
2166 OD_OPS_SUPPORT_FAN_MINIMUM_PWM_SET |
2167 OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_RETRIEVE |
2168 OD_OPS_SUPPORT_FAN_ZERO_RPM_ENABLE_SET |
2169 OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_RETRIEVE |
2170 OD_OPS_SUPPORT_FAN_ZERO_RPM_STOP_TEMP_SET;
2171 }
2172
smu_v13_0_0_set_default_od_settings(struct smu_context * smu)2173 static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu)
2174 {
2175 OverDriveTableExternal_t *od_table =
2176 (OverDriveTableExternal_t *)smu->smu_table.overdrive_table;
2177 OverDriveTableExternal_t *boot_od_table =
2178 (OverDriveTableExternal_t *)smu->smu_table.boot_overdrive_table;
2179 OverDriveTableExternal_t *user_od_table =
2180 (OverDriveTableExternal_t *)smu->smu_table.user_overdrive_table;
2181 OverDriveTableExternal_t user_od_table_bak;
2182 int ret = 0;
2183 int i;
2184
2185 ret = smu_v13_0_0_get_overdrive_table(smu, boot_od_table);
2186 if (ret)
2187 return ret;
2188
2189 smu_v13_0_0_dump_od_table(smu, boot_od_table);
2190
2191 memcpy(od_table,
2192 boot_od_table,
2193 sizeof(OverDriveTableExternal_t));
2194
2195 /*
2196 * For S3/S4/Runpm resume, we need to setup those overdrive tables again,
2197 * but we have to preserve user defined values in "user_od_table".
2198 */
2199 if (!smu->adev->in_suspend) {
2200 memcpy(user_od_table,
2201 boot_od_table,
2202 sizeof(OverDriveTableExternal_t));
2203 smu->user_dpm_profile.user_od = false;
2204 } else if (smu->user_dpm_profile.user_od) {
2205 memcpy(&user_od_table_bak,
2206 user_od_table,
2207 sizeof(OverDriveTableExternal_t));
2208 memcpy(user_od_table,
2209 boot_od_table,
2210 sizeof(OverDriveTableExternal_t));
2211 user_od_table->OverDriveTable.GfxclkFmin =
2212 user_od_table_bak.OverDriveTable.GfxclkFmin;
2213 user_od_table->OverDriveTable.GfxclkFmax =
2214 user_od_table_bak.OverDriveTable.GfxclkFmax;
2215 user_od_table->OverDriveTable.UclkFmin =
2216 user_od_table_bak.OverDriveTable.UclkFmin;
2217 user_od_table->OverDriveTable.UclkFmax =
2218 user_od_table_bak.OverDriveTable.UclkFmax;
2219 for (i = 0; i < PP_NUM_OD_VF_CURVE_POINTS; i++)
2220 user_od_table->OverDriveTable.VoltageOffsetPerZoneBoundary[i] =
2221 user_od_table_bak.OverDriveTable.VoltageOffsetPerZoneBoundary[i];
2222 for (i = 0; i < NUM_OD_FAN_MAX_POINTS - 1; i++) {
2223 user_od_table->OverDriveTable.FanLinearTempPoints[i] =
2224 user_od_table_bak.OverDriveTable.FanLinearTempPoints[i];
2225 user_od_table->OverDriveTable.FanLinearPwmPoints[i] =
2226 user_od_table_bak.OverDriveTable.FanLinearPwmPoints[i];
2227 }
2228 user_od_table->OverDriveTable.AcousticLimitRpmThreshold =
2229 user_od_table_bak.OverDriveTable.AcousticLimitRpmThreshold;
2230 user_od_table->OverDriveTable.AcousticTargetRpmThreshold =
2231 user_od_table_bak.OverDriveTable.AcousticTargetRpmThreshold;
2232 user_od_table->OverDriveTable.FanTargetTemperature =
2233 user_od_table_bak.OverDriveTable.FanTargetTemperature;
2234 user_od_table->OverDriveTable.FanMinimumPwm =
2235 user_od_table_bak.OverDriveTable.FanMinimumPwm;
2236 user_od_table->OverDriveTable.FanZeroRpmEnable =
2237 user_od_table_bak.OverDriveTable.FanZeroRpmEnable;
2238 user_od_table->OverDriveTable.FanZeroRpmStopTemp =
2239 user_od_table_bak.OverDriveTable.FanZeroRpmStopTemp;
2240 }
2241
2242 smu_v13_0_0_set_supported_od_feature_mask(smu);
2243
2244 return 0;
2245 }
2246
smu_v13_0_0_restore_user_od_settings(struct smu_context * smu)2247 static int smu_v13_0_0_restore_user_od_settings(struct smu_context *smu)
2248 {
2249 struct smu_table_context *table_context = &smu->smu_table;
2250 OverDriveTableExternal_t *od_table = table_context->overdrive_table;
2251 OverDriveTableExternal_t *user_od_table = table_context->user_overdrive_table;
2252 int res;
2253
2254 user_od_table->OverDriveTable.FeatureCtrlMask = BIT(PP_OD_FEATURE_GFXCLK_BIT) |
2255 BIT(PP_OD_FEATURE_UCLK_BIT) |
2256 BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT) |
2257 BIT(PP_OD_FEATURE_FAN_CURVE_BIT) |
2258 BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
2259 res = smu_v13_0_0_upload_overdrive_table(smu, user_od_table);
2260 user_od_table->OverDriveTable.FeatureCtrlMask = 0;
2261 if (res == 0)
2262 memcpy(od_table, user_od_table, sizeof(OverDriveTableExternal_t));
2263
2264 return res;
2265 }
2266
smu_v13_0_0_populate_umd_state_clk(struct smu_context * smu)2267 static int smu_v13_0_0_populate_umd_state_clk(struct smu_context *smu)
2268 {
2269 struct smu_13_0_dpm_context *dpm_context =
2270 smu->smu_dpm.dpm_context;
2271 struct smu_dpm_table *gfx_table = &dpm_context->dpm_tables.gfx_table;
2272 struct smu_dpm_table *mem_table = &dpm_context->dpm_tables.uclk_table;
2273 struct smu_dpm_table *soc_table = &dpm_context->dpm_tables.soc_table;
2274 struct smu_dpm_table *vclk_table = &dpm_context->dpm_tables.vclk_table;
2275 struct smu_dpm_table *dclk_table = &dpm_context->dpm_tables.dclk_table;
2276 struct smu_dpm_table *fclk_table = &dpm_context->dpm_tables.fclk_table;
2277 struct smu_umd_pstate_table *pstate_table =
2278 &smu->pstate_table;
2279 struct smu_table_context *table_context = &smu->smu_table;
2280 PPTable_t *pptable = table_context->driver_pptable;
2281 DriverReportedClocks_t driver_clocks =
2282 pptable->SkuTable.DriverReportedClocks;
2283
2284 pstate_table->gfxclk_pstate.min = SMU_DPM_TABLE_MIN(gfx_table);
2285 if (driver_clocks.GameClockAc &&
2286 (driver_clocks.GameClockAc < SMU_DPM_TABLE_MAX(gfx_table)))
2287 pstate_table->gfxclk_pstate.peak = driver_clocks.GameClockAc;
2288 else
2289 pstate_table->gfxclk_pstate.peak = SMU_DPM_TABLE_MAX(gfx_table);
2290
2291 pstate_table->uclk_pstate.min = SMU_DPM_TABLE_MIN(mem_table);
2292 pstate_table->uclk_pstate.peak = SMU_DPM_TABLE_MAX(mem_table);
2293
2294 pstate_table->socclk_pstate.min = SMU_DPM_TABLE_MIN(soc_table);
2295 pstate_table->socclk_pstate.peak = SMU_DPM_TABLE_MAX(soc_table);
2296
2297 pstate_table->vclk_pstate.min = SMU_DPM_TABLE_MIN(vclk_table);
2298 pstate_table->vclk_pstate.peak = SMU_DPM_TABLE_MAX(vclk_table);
2299
2300 pstate_table->dclk_pstate.min = SMU_DPM_TABLE_MIN(dclk_table);
2301 pstate_table->dclk_pstate.peak = SMU_DPM_TABLE_MAX(dclk_table);
2302
2303 pstate_table->fclk_pstate.min = SMU_DPM_TABLE_MIN(fclk_table);
2304 pstate_table->fclk_pstate.peak = SMU_DPM_TABLE_MAX(fclk_table);
2305
2306 if (driver_clocks.BaseClockAc &&
2307 driver_clocks.BaseClockAc < SMU_DPM_TABLE_MAX(gfx_table))
2308 pstate_table->gfxclk_pstate.standard = driver_clocks.BaseClockAc;
2309 else
2310 pstate_table->gfxclk_pstate.standard =
2311 SMU_DPM_TABLE_MAX(gfx_table);
2312 pstate_table->uclk_pstate.standard = SMU_DPM_TABLE_MAX(mem_table);
2313 pstate_table->socclk_pstate.standard = SMU_DPM_TABLE_MIN(soc_table);
2314 pstate_table->vclk_pstate.standard = SMU_DPM_TABLE_MIN(vclk_table);
2315 pstate_table->dclk_pstate.standard = SMU_DPM_TABLE_MIN(dclk_table);
2316 pstate_table->fclk_pstate.standard = SMU_DPM_TABLE_MIN(fclk_table);
2317
2318 return 0;
2319 }
2320
smu_v13_0_0_get_unique_id(struct smu_context * smu)2321 static void smu_v13_0_0_get_unique_id(struct smu_context *smu)
2322 {
2323 struct smu_table_context *smu_table = &smu->smu_table;
2324 SmuMetrics_t *metrics =
2325 &(((SmuMetricsExternal_t *)(smu_table->metrics_table))->SmuMetrics);
2326 struct amdgpu_device *adev = smu->adev;
2327 uint32_t upper32 = 0, lower32 = 0;
2328 int ret;
2329
2330 ret = smu_cmn_get_metrics_table(smu, NULL, false);
2331 if (ret)
2332 goto out;
2333
2334 upper32 = metrics->PublicSerialNumberUpper;
2335 lower32 = metrics->PublicSerialNumberLower;
2336
2337 out:
2338 adev->unique_id = ((uint64_t)upper32 << 32) | lower32;
2339 }
2340
smu_v13_0_0_get_fan_speed_pwm(struct smu_context * smu,uint32_t * speed)2341 static int smu_v13_0_0_get_fan_speed_pwm(struct smu_context *smu,
2342 uint32_t *speed)
2343 {
2344 int ret;
2345
2346 if (!speed)
2347 return -EINVAL;
2348
2349 ret = smu_v13_0_0_get_smu_metrics_data(smu,
2350 METRICS_CURR_FANPWM,
2351 speed);
2352 if (ret) {
2353 dev_err(smu->adev->dev, "Failed to get fan speed(PWM)!");
2354 return ret;
2355 }
2356
2357 /* Convert the PMFW output which is in percent to pwm(255) based */
2358 *speed = min(*speed * 255 / 100, (uint32_t)255);
2359
2360 return 0;
2361 }
2362
smu_v13_0_0_get_fan_speed_rpm(struct smu_context * smu,uint32_t * speed)2363 static int smu_v13_0_0_get_fan_speed_rpm(struct smu_context *smu,
2364 uint32_t *speed)
2365 {
2366 if (!speed)
2367 return -EINVAL;
2368
2369 return smu_v13_0_0_get_smu_metrics_data(smu,
2370 METRICS_CURR_FANSPEED,
2371 speed);
2372 }
2373
smu_v13_0_0_enable_mgpu_fan_boost(struct smu_context * smu)2374 static int smu_v13_0_0_enable_mgpu_fan_boost(struct smu_context *smu)
2375 {
2376 struct smu_table_context *table_context = &smu->smu_table;
2377 PPTable_t *pptable = table_context->driver_pptable;
2378 SkuTable_t *skutable = &pptable->SkuTable;
2379
2380 /*
2381 * Skip the MGpuFanBoost setting for those ASICs
2382 * which do not support it
2383 */
2384 if (skutable->MGpuAcousticLimitRpmThreshold == 0)
2385 return 0;
2386
2387 return smu_cmn_send_smc_msg_with_param(smu,
2388 SMU_MSG_SetMGpuFanBoostLimitRpm,
2389 0,
2390 NULL);
2391 }
2392
smu_v13_0_0_get_ppt_limit(struct smu_context * smu,enum smu_ppt_limit_type limit_type,uint32_t * ppt_limit)2393 static int smu_v13_0_0_get_ppt_limit(struct smu_context *smu,
2394 enum smu_ppt_limit_type limit_type,
2395 uint32_t *ppt_limit)
2396 {
2397 OverDriveTableExternal_t od_table;
2398 int ret;
2399
2400 if (limit_type != SMU_PPT_LIMIT_PPT0)
2401 return -EOPNOTSUPP;
2402
2403 ret = smu_v13_0_get_ppt_limit(smu, limit_type, ppt_limit);
2404 if (ret)
2405 return ret;
2406
2407 ret = smu_v13_0_0_get_overdrive_table(smu, &od_table);
2408 if (ret)
2409 return ret;
2410
2411 if (od_table.OverDriveTable.Ppt > 0)
2412 *ppt_limit = *ppt_limit *
2413 (100 + od_table.OverDriveTable.Ppt) / 100;
2414
2415 return 0;
2416 }
2417
smu_v13_0_0_init_ppt_limits(struct smu_context * smu)2418 static int smu_v13_0_0_init_ppt_limits(struct smu_context *smu)
2419 {
2420 struct smu_table_context *table_context = &smu->smu_table;
2421 struct smu_13_0_0_powerplay_table *powerplay_table =
2422 (struct smu_13_0_0_powerplay_table *)table_context->power_play_table;
2423 PPTable_t *pptable = table_context->driver_pptable;
2424 SkuTable_t *skutable = &pptable->SkuTable;
2425 uint32_t od_percent_upper = 0, od_percent_lower = 0;
2426 uint32_t pp_limit, msg_limit, min_limit, max_limit;
2427 int i;
2428
2429 if (powerplay_table &&
2430 smu_v13_0_0_is_od_feature_supported(smu, PP_OD_FEATURE_PPT_BIT)) {
2431 od_percent_upper = le32_to_cpu(powerplay_table->overdrive_table.max[
2432 SMU_13_0_0_ODSETTING_POWERPERCENTAGE]);
2433 od_percent_lower = le32_to_cpu(powerplay_table->overdrive_table.min[
2434 SMU_13_0_0_ODSETTING_POWERPERCENTAGE]);
2435 }
2436
2437 for (i = SMU_POWER_SOURCE_AC; i < SMU_POWER_SOURCE_COUNT; i++) {
2438 pp_limit = i == SMU_POWER_SOURCE_AC ?
2439 skutable->SocketPowerLimitAc[PPT_THROTTLER_PPT0] :
2440 skutable->SocketPowerLimitDc[PPT_THROTTLER_PPT0];
2441 msg_limit = skutable->MsgLimits.Power[PPT_THROTTLER_PPT0][i];
2442 min_limit = min(pp_limit, msg_limit);
2443 max_limit = max(pp_limit, msg_limit);
2444
2445 smu->ppt_limits.range[i][SMU_PPT_LIMIT_PPT0].default_value =
2446 pp_limit;
2447 smu->ppt_limits.range[i][SMU_PPT_LIMIT_PPT0].max =
2448 max_limit;
2449 smu->ppt_limits.range[i][SMU_PPT_LIMIT_PPT0].min =
2450 min_limit * (100 - od_percent_lower) / 100;
2451 smu->ppt_limits.range[i][SMU_PPT_LIMIT_PPT0].od_max =
2452 max_limit * (100 + od_percent_upper) / 100;
2453 smu->ppt_limits.range[i][SMU_PPT_LIMIT_PPT0].od_min =
2454 smu->ppt_limits.range[i][SMU_PPT_LIMIT_PPT0].min;
2455 }
2456
2457 smu->ppt_limits.supported_mask |= BIT(SMU_PPT_LIMIT_PPT0);
2458
2459 return 0;
2460 }
2461
smu_v13_0_0_get_power_profile_mode(struct smu_context * smu,char * buf)2462 static int smu_v13_0_0_get_power_profile_mode(struct smu_context *smu,
2463 char *buf)
2464 {
2465 DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;
2466 DpmActivityMonitorCoeffInt_t *activity_monitor =
2467 &(activity_monitor_external.DpmActivityMonitorCoeffInt);
2468 static const char *title[] = {
2469 "PROFILE_INDEX(NAME)",
2470 "CLOCK_TYPE(NAME)",
2471 "FPS",
2472 "MinActiveFreqType",
2473 "MinActiveFreq",
2474 "BoosterFreqType",
2475 "BoosterFreq",
2476 "PD_Data_limit_c",
2477 "PD_Data_error_coeff",
2478 "PD_Data_error_rate_coeff"};
2479 int16_t workload_type = 0;
2480 uint32_t i, size = 0;
2481 int result = 0;
2482
2483 if (!buf)
2484 return -EINVAL;
2485
2486 size += sysfs_emit_at(buf, size, "%16s %s %s %s %s %s %s %s %s %s\n",
2487 title[0], title[1], title[2], title[3], title[4], title[5],
2488 title[6], title[7], title[8], title[9]);
2489
2490 for (i = 0; i < PP_SMC_POWER_PROFILE_COUNT; i++) {
2491 /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */
2492 workload_type = smu_cmn_to_asic_specific_index(smu,
2493 CMN2ASIC_MAPPING_WORKLOAD,
2494 i);
2495 if (workload_type == -ENOTSUPP)
2496 continue;
2497 else if (workload_type < 0)
2498 return -EINVAL;
2499
2500 result = smu_cmn_update_table(smu,
2501 SMU_TABLE_ACTIVITY_MONITOR_COEFF,
2502 workload_type,
2503 (void *)(&activity_monitor_external),
2504 false);
2505 if (result) {
2506 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
2507 return result;
2508 }
2509
2510 size += sysfs_emit_at(buf, size, "%2d %14s%s:\n",
2511 i, amdgpu_pp_profile_name[i], (i == smu->power_profile_mode) ? "*" : " ");
2512
2513 size += sysfs_emit_at(buf, size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d\n",
2514 " ",
2515 0,
2516 "GFXCLK",
2517 activity_monitor->Gfx_FPS,
2518 activity_monitor->Gfx_MinActiveFreqType,
2519 activity_monitor->Gfx_MinActiveFreq,
2520 activity_monitor->Gfx_BoosterFreqType,
2521 activity_monitor->Gfx_BoosterFreq,
2522 activity_monitor->Gfx_PD_Data_limit_c,
2523 activity_monitor->Gfx_PD_Data_error_coeff,
2524 activity_monitor->Gfx_PD_Data_error_rate_coeff);
2525
2526 size += sysfs_emit_at(buf, size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d\n",
2527 " ",
2528 1,
2529 "FCLK",
2530 activity_monitor->Fclk_FPS,
2531 activity_monitor->Fclk_MinActiveFreqType,
2532 activity_monitor->Fclk_MinActiveFreq,
2533 activity_monitor->Fclk_BoosterFreqType,
2534 activity_monitor->Fclk_BoosterFreq,
2535 activity_monitor->Fclk_PD_Data_limit_c,
2536 activity_monitor->Fclk_PD_Data_error_coeff,
2537 activity_monitor->Fclk_PD_Data_error_rate_coeff);
2538 }
2539
2540 return size;
2541 }
2542
2543 #define SMU_13_0_0_CUSTOM_PARAMS_COUNT 9
2544 #define SMU_13_0_0_CUSTOM_PARAMS_CLOCK_COUNT 2
2545 #define SMU_13_0_0_CUSTOM_PARAMS_SIZE (SMU_13_0_0_CUSTOM_PARAMS_CLOCK_COUNT * SMU_13_0_0_CUSTOM_PARAMS_COUNT * sizeof(long))
2546
smu_v13_0_0_set_power_profile_mode_coeff(struct smu_context * smu,long * input)2547 static int smu_v13_0_0_set_power_profile_mode_coeff(struct smu_context *smu,
2548 long *input)
2549 {
2550 DpmActivityMonitorCoeffIntExternal_t activity_monitor_external;
2551 DpmActivityMonitorCoeffInt_t *activity_monitor =
2552 &(activity_monitor_external.DpmActivityMonitorCoeffInt);
2553 int ret, idx;
2554
2555 ret = smu_cmn_update_table(smu,
2556 SMU_TABLE_ACTIVITY_MONITOR_COEFF,
2557 WORKLOAD_PPLIB_CUSTOM_BIT,
2558 (void *)(&activity_monitor_external),
2559 false);
2560 if (ret) {
2561 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__);
2562 return ret;
2563 }
2564
2565 idx = 0 * SMU_13_0_0_CUSTOM_PARAMS_COUNT;
2566 if (input[idx]) {
2567 /* Gfxclk */
2568 activity_monitor->Gfx_FPS = input[idx + 1];
2569 activity_monitor->Gfx_MinActiveFreqType = input[idx + 2];
2570 activity_monitor->Gfx_MinActiveFreq = input[idx + 3];
2571 activity_monitor->Gfx_BoosterFreqType = input[idx + 4];
2572 activity_monitor->Gfx_BoosterFreq = input[idx + 5];
2573 activity_monitor->Gfx_PD_Data_limit_c = input[idx + 6];
2574 activity_monitor->Gfx_PD_Data_error_coeff = input[idx + 7];
2575 activity_monitor->Gfx_PD_Data_error_rate_coeff = input[idx + 8];
2576 }
2577 idx = 1 * SMU_13_0_0_CUSTOM_PARAMS_COUNT;
2578 if (input[idx]) {
2579 /* Fclk */
2580 activity_monitor->Fclk_FPS = input[idx + 1];
2581 activity_monitor->Fclk_MinActiveFreqType = input[idx + 2];
2582 activity_monitor->Fclk_MinActiveFreq = input[idx + 3];
2583 activity_monitor->Fclk_BoosterFreqType = input[idx + 4];
2584 activity_monitor->Fclk_BoosterFreq = input[idx + 5];
2585 activity_monitor->Fclk_PD_Data_limit_c = input[idx + 6];
2586 activity_monitor->Fclk_PD_Data_error_coeff = input[idx + 7];
2587 activity_monitor->Fclk_PD_Data_error_rate_coeff = input[idx + 8];
2588 }
2589
2590 ret = smu_cmn_update_table(smu,
2591 SMU_TABLE_ACTIVITY_MONITOR_COEFF,
2592 WORKLOAD_PPLIB_CUSTOM_BIT,
2593 (void *)(&activity_monitor_external),
2594 true);
2595 if (ret) {
2596 dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__);
2597 return ret;
2598 }
2599
2600 return ret;
2601 }
2602
smu_v13_0_0_set_power_profile_mode(struct smu_context * smu,u32 workload_mask,long * custom_params,u32 custom_params_max_idx)2603 static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu,
2604 u32 workload_mask,
2605 long *custom_params,
2606 u32 custom_params_max_idx)
2607 {
2608 u32 backend_workload_mask = 0;
2609 int workload_type, ret, idx = -1, i;
2610
2611 smu_cmn_get_backend_workload_mask(smu, workload_mask,
2612 &backend_workload_mask);
2613
2614 /* Add optimizations for SMU13.0.0/10. Reuse the power saving profile */
2615 if ((workload_mask & (1 << PP_SMC_POWER_PROFILE_COMPUTE)) &&
2616 ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) &&
2617 ((smu->adev->pm.fw_version == 0x004e6601) ||
2618 (smu->adev->pm.fw_version >= 0x004e7300))) ||
2619 (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) &&
2620 smu->adev->pm.fw_version >= 0x00504500))) {
2621 workload_type = smu_cmn_to_asic_specific_index(smu,
2622 CMN2ASIC_MAPPING_WORKLOAD,
2623 PP_SMC_POWER_PROFILE_POWERSAVING);
2624 if (workload_type >= 0)
2625 backend_workload_mask |= 1 << workload_type;
2626 }
2627
2628 if (workload_mask & (1 << PP_SMC_POWER_PROFILE_CUSTOM)) {
2629 if (!smu->custom_profile_params) {
2630 smu->custom_profile_params =
2631 kzalloc(SMU_13_0_0_CUSTOM_PARAMS_SIZE, GFP_KERNEL);
2632 if (!smu->custom_profile_params)
2633 return -ENOMEM;
2634 }
2635 if (custom_params && custom_params_max_idx) {
2636 if (!smu_cmn_custom_params_count_valid(custom_params_max_idx,
2637 SMU_13_0_0_CUSTOM_PARAMS_COUNT) ||
2638 !smu_cmn_custom_params_clock_valid(custom_params[0],
2639 SMU_13_0_0_CUSTOM_PARAMS_CLOCK_COUNT))
2640 return -EINVAL;
2641 idx = custom_params[0] * SMU_13_0_0_CUSTOM_PARAMS_COUNT;
2642 smu->custom_profile_params[idx] = 1;
2643 for (i = 1; i < custom_params_max_idx; i++)
2644 smu->custom_profile_params[idx + i] = custom_params[i];
2645 }
2646 ret = smu_v13_0_0_set_power_profile_mode_coeff(smu,
2647 smu->custom_profile_params);
2648 if (ret) {
2649 if (idx != -1)
2650 smu->custom_profile_params[idx] = 0;
2651 return ret;
2652 }
2653 } else if (smu->custom_profile_params) {
2654 memset(smu->custom_profile_params, 0, SMU_13_0_0_CUSTOM_PARAMS_SIZE);
2655 }
2656
2657 ret = smu_cmn_send_smc_msg_with_param(smu,
2658 SMU_MSG_SetWorkloadMask,
2659 backend_workload_mask,
2660 NULL);
2661 if (ret) {
2662 dev_err(smu->adev->dev, "Failed to set workload mask 0x%08x\n",
2663 workload_mask);
2664 if (idx != -1)
2665 smu->custom_profile_params[idx] = 0;
2666 return ret;
2667 }
2668
2669 return ret;
2670 }
2671
smu_v13_0_0_is_mode1_reset_supported(struct smu_context * smu)2672 static bool smu_v13_0_0_is_mode1_reset_supported(struct smu_context *smu)
2673 {
2674 struct amdgpu_device *adev = smu->adev;
2675
2676 /* SRIOV does not support SMU mode1 reset */
2677 if (amdgpu_sriov_vf(adev))
2678 return false;
2679
2680 return true;
2681 }
2682
smu_v13_0_0_i2c_xfer(struct i2c_adapter * i2c_adap,struct i2c_msg * msg,int num_msgs)2683 static int smu_v13_0_0_i2c_xfer(struct i2c_adapter *i2c_adap,
2684 struct i2c_msg *msg, int num_msgs)
2685 {
2686 struct amdgpu_smu_i2c_bus *smu_i2c = i2c_get_adapdata(i2c_adap);
2687 struct amdgpu_device *adev = smu_i2c->adev;
2688 struct smu_context *smu = adev->powerplay.pp_handle;
2689 struct smu_table_context *smu_table = &smu->smu_table;
2690 struct smu_table *table = &smu_table->driver_table;
2691 SwI2cRequest_t *req, *res = (SwI2cRequest_t *)table->cpu_addr;
2692 int i, j, r, c;
2693 u16 dir;
2694
2695 if (!adev->pm.dpm_enabled)
2696 return -EBUSY;
2697
2698 req = kzalloc_obj(*req);
2699 if (!req)
2700 return -ENOMEM;
2701
2702 req->I2CcontrollerPort = smu_i2c->port;
2703 req->I2CSpeed = I2C_SPEED_FAST_400K;
2704 req->SlaveAddress = msg[0].addr << 1; /* wants an 8-bit address */
2705 dir = msg[0].flags & I2C_M_RD;
2706
2707 for (c = i = 0; i < num_msgs; i++) {
2708 for (j = 0; j < msg[i].len; j++, c++) {
2709 SwI2cCmd_t *cmd = &req->SwI2cCmds[c];
2710
2711 if (!(msg[i].flags & I2C_M_RD)) {
2712 /* write */
2713 cmd->CmdConfig |= CMDCONFIG_READWRITE_MASK;
2714 cmd->ReadWriteData = msg[i].buf[j];
2715 }
2716
2717 if ((dir ^ msg[i].flags) & I2C_M_RD) {
2718 /* The direction changes.
2719 */
2720 dir = msg[i].flags & I2C_M_RD;
2721 cmd->CmdConfig |= CMDCONFIG_RESTART_MASK;
2722 }
2723
2724 req->NumCmds++;
2725
2726 /*
2727 * Insert STOP if we are at the last byte of either last
2728 * message for the transaction or the client explicitly
2729 * requires a STOP at this particular message.
2730 */
2731 if ((j == msg[i].len - 1) &&
2732 ((i == num_msgs - 1) || (msg[i].flags & I2C_M_STOP))) {
2733 cmd->CmdConfig &= ~CMDCONFIG_RESTART_MASK;
2734 cmd->CmdConfig |= CMDCONFIG_STOP_MASK;
2735 }
2736 }
2737 }
2738 mutex_lock(&adev->pm.mutex);
2739 r = smu_cmn_update_table(smu, SMU_TABLE_I2C_COMMANDS, 0, req, true);
2740 if (r)
2741 goto fail;
2742
2743 for (c = i = 0; i < num_msgs; i++) {
2744 if (!(msg[i].flags & I2C_M_RD)) {
2745 c += msg[i].len;
2746 continue;
2747 }
2748 for (j = 0; j < msg[i].len; j++, c++) {
2749 SwI2cCmd_t *cmd = &res->SwI2cCmds[c];
2750
2751 msg[i].buf[j] = cmd->ReadWriteData;
2752 }
2753 }
2754 r = num_msgs;
2755 fail:
2756 mutex_unlock(&adev->pm.mutex);
2757 kfree(req);
2758 return r;
2759 }
2760
smu_v13_0_0_i2c_func(struct i2c_adapter * adap)2761 static u32 smu_v13_0_0_i2c_func(struct i2c_adapter *adap)
2762 {
2763 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
2764 }
2765
2766 static const struct i2c_algorithm smu_v13_0_0_i2c_algo = {
2767 .master_xfer = smu_v13_0_0_i2c_xfer,
2768 .functionality = smu_v13_0_0_i2c_func,
2769 };
2770
2771 static const struct i2c_adapter_quirks smu_v13_0_0_i2c_control_quirks = {
2772 .flags = I2C_AQ_COMB | I2C_AQ_COMB_SAME_ADDR | I2C_AQ_NO_ZERO_LEN,
2773 .max_read_len = MAX_SW_I2C_COMMANDS,
2774 .max_write_len = MAX_SW_I2C_COMMANDS,
2775 .max_comb_1st_msg_len = 2,
2776 .max_comb_2nd_msg_len = MAX_SW_I2C_COMMANDS - 2,
2777 };
2778
smu_v13_0_0_i2c_control_init(struct smu_context * smu)2779 static int smu_v13_0_0_i2c_control_init(struct smu_context *smu)
2780 {
2781 struct amdgpu_device *adev = smu->adev;
2782 int res, i;
2783
2784 for (i = 0; i < MAX_SMU_I2C_BUSES; i++) {
2785 struct amdgpu_smu_i2c_bus *smu_i2c = &adev->pm.smu_i2c[i];
2786 struct i2c_adapter *control = &smu_i2c->adapter;
2787
2788 smu_i2c->adev = adev;
2789 smu_i2c->port = i;
2790 mutex_init(&smu_i2c->mutex);
2791 control->owner = THIS_MODULE;
2792 control->dev.parent = &adev->pdev->dev;
2793 control->algo = &smu_v13_0_0_i2c_algo;
2794 snprintf(control->name, sizeof(control->name), "AMDGPU SMU %d", i);
2795 control->quirks = &smu_v13_0_0_i2c_control_quirks;
2796 i2c_set_adapdata(control, smu_i2c);
2797
2798 res = devm_i2c_add_adapter(adev->dev, control);
2799 if (res) {
2800 DRM_ERROR("Failed to register hw i2c, err: %d\n", res);
2801 return res;
2802 }
2803 }
2804
2805 /* assign the buses used for the FRU EEPROM and RAS EEPROM */
2806 /* XXX ideally this would be something in a vbios data table */
2807 adev->pm.ras_eeprom_i2c_bus = &adev->pm.smu_i2c[1].adapter;
2808 adev->pm.fru_eeprom_i2c_bus = &adev->pm.smu_i2c[0].adapter;
2809
2810 return 0;
2811 }
2812
smu_v13_0_0_i2c_control_fini(struct smu_context * smu)2813 static void smu_v13_0_0_i2c_control_fini(struct smu_context *smu)
2814 {
2815 struct amdgpu_device *adev = smu->adev;
2816
2817 adev->pm.ras_eeprom_i2c_bus = NULL;
2818 adev->pm.fru_eeprom_i2c_bus = NULL;
2819 }
2820
smu_v13_0_0_set_mp1_state(struct smu_context * smu,enum pp_mp1_state mp1_state)2821 static int smu_v13_0_0_set_mp1_state(struct smu_context *smu,
2822 enum pp_mp1_state mp1_state)
2823 {
2824 uint32_t param;
2825 int ret;
2826
2827 switch (mp1_state) {
2828 case PP_MP1_STATE_UNLOAD:
2829 /*
2830 * NOTE: Param 0x55 comes from PMFW 80.31.0, ignored in older versions.
2831 * No PMFW version check required.
2832 */
2833 param = amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10) ?
2834 0x55 : 0x00;
2835 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PrepareMp1ForUnload,
2836 param, NULL);
2837 break;
2838 default:
2839 /* Ignore others */
2840 ret = 0;
2841 }
2842
2843 return ret;
2844 }
2845
smu_v13_0_0_set_df_cstate(struct smu_context * smu,enum pp_df_cstate state)2846 static int smu_v13_0_0_set_df_cstate(struct smu_context *smu,
2847 enum pp_df_cstate state)
2848 {
2849 return smu_cmn_send_smc_msg_with_param(smu,
2850 SMU_MSG_DFCstateControl,
2851 state,
2852 NULL);
2853 }
2854
smu_v13_0_0_set_mode1_reset_param(struct smu_context * smu,uint32_t supported_version,uint32_t * param)2855 static void smu_v13_0_0_set_mode1_reset_param(struct smu_context *smu,
2856 uint32_t supported_version,
2857 uint32_t *param)
2858 {
2859 struct amdgpu_device *adev = smu->adev;
2860
2861 if ((smu->smc_fw_version >= supported_version) &&
2862 amdgpu_ras_get_fed_status(adev))
2863 /* Set RAS fatal error reset flag */
2864 *param = 1 << 16;
2865 else
2866 *param = 0;
2867 }
2868
smu_v13_0_0_mode1_reset(struct smu_context * smu)2869 static int smu_v13_0_0_mode1_reset(struct smu_context *smu)
2870 {
2871 int ret;
2872 uint32_t param;
2873 struct amdgpu_device *adev = smu->adev;
2874
2875 switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
2876 case IP_VERSION(13, 0, 0):
2877 /* SMU 13_0_0 PMFW supports RAS fatal error reset from 78.77 */
2878 smu_v13_0_0_set_mode1_reset_param(smu, 0x004e4d00, ¶m);
2879
2880 ret = smu_cmn_send_debug_smc_msg_with_param(smu,
2881 DEBUGSMC_MSG_Mode1Reset, param);
2882
2883 break;
2884
2885 case IP_VERSION(13, 0, 10):
2886 /* SMU 13_0_10 PMFW supports RAS fatal error reset from 80.28 */
2887 smu_v13_0_0_set_mode1_reset_param(smu, 0x00501c00, ¶m);
2888
2889 ret = smu_cmn_send_debug_smc_msg_with_param(smu,
2890 DEBUGSMC_MSG_Mode1Reset, param);
2891 break;
2892
2893 default:
2894 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_Mode1Reset, NULL);
2895 break;
2896 }
2897
2898 if (!ret) {
2899 /* disable mmio access while doing mode 1 reset*/
2900 smu->adev->no_hw_access = true;
2901 /* ensure no_hw_access is globally visible before any MMIO */
2902 smp_mb();
2903 msleep(SMU13_MODE1_RESET_WAIT_TIME_IN_MS);
2904 }
2905
2906 return ret;
2907 }
2908
smu_v13_0_0_mode2_reset(struct smu_context * smu)2909 static int smu_v13_0_0_mode2_reset(struct smu_context *smu)
2910 {
2911 int ret;
2912 struct amdgpu_device *adev = smu->adev;
2913
2914 if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10))
2915 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_Mode2Reset, NULL);
2916 else
2917 return -EOPNOTSUPP;
2918
2919 return ret;
2920 }
2921
smu_v13_0_0_enable_gfx_features(struct smu_context * smu)2922 static int smu_v13_0_0_enable_gfx_features(struct smu_context *smu)
2923 {
2924 struct amdgpu_device *adev = smu->adev;
2925
2926 if (amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10))
2927 return smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_EnableAllSmuFeatures,
2928 FEATURE_PWR_GFX, NULL);
2929 else
2930 return -EOPNOTSUPP;
2931 }
2932
smu_v13_0_0_init_msg_ctl(struct smu_context * smu)2933 static void smu_v13_0_0_init_msg_ctl(struct smu_context *smu)
2934 {
2935 struct amdgpu_device *adev = smu->adev;
2936 struct smu_msg_ctl *ctl = &smu->msg_ctl;
2937
2938 smu_v13_0_init_msg_ctl(smu, smu_v13_0_0_message_map);
2939
2940 /* Set up debug mailbox registers */
2941 ctl->config.debug_param_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_53);
2942 ctl->config.debug_msg_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_75);
2943 ctl->config.debug_resp_reg = SOC15_REG_OFFSET(MP1, 0, mmMP1_SMN_C2PMSG_54);
2944 ctl->flags |= SMU_MSG_CTL_DEBUG_MAILBOX;
2945 }
2946
smu_v13_0_0_smu_send_bad_mem_page_num(struct smu_context * smu,uint32_t size)2947 static int smu_v13_0_0_smu_send_bad_mem_page_num(struct smu_context *smu,
2948 uint32_t size)
2949 {
2950 int ret = 0;
2951
2952 /* message SMU to update the bad page number on SMUBUS */
2953 ret = smu_cmn_send_smc_msg_with_param(smu,
2954 SMU_MSG_SetNumBadMemoryPagesRetired,
2955 size, NULL);
2956 if (ret)
2957 dev_err(smu->adev->dev,
2958 "[%s] failed to message SMU to update bad memory pages number\n",
2959 __func__);
2960
2961 return ret;
2962 }
2963
smu_v13_0_0_send_bad_mem_channel_flag(struct smu_context * smu,uint32_t size)2964 static int smu_v13_0_0_send_bad_mem_channel_flag(struct smu_context *smu,
2965 uint32_t size)
2966 {
2967 int ret = 0;
2968
2969 /* message SMU to update the bad channel info on SMUBUS */
2970 ret = smu_cmn_send_smc_msg_with_param(smu,
2971 SMU_MSG_SetBadMemoryPagesRetiredFlagsPerChannel,
2972 size, NULL);
2973 if (ret)
2974 dev_err(smu->adev->dev,
2975 "[%s] failed to message SMU to update bad memory pages channel info\n",
2976 __func__);
2977
2978 return ret;
2979 }
2980
smu_v13_0_0_check_ecc_table_support(struct smu_context * smu)2981 static int smu_v13_0_0_check_ecc_table_support(struct smu_context *smu)
2982 {
2983 struct amdgpu_device *adev = smu->adev;
2984 int ret = 0;
2985
2986 if ((amdgpu_ip_version(adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 10)) &&
2987 (smu->smc_fw_version >= SUPPORT_ECCTABLE_SMU_13_0_10_VERSION))
2988 return ret;
2989 else
2990 return -EOPNOTSUPP;
2991 }
2992
smu_v13_0_0_get_ecc_info(struct smu_context * smu,void * table)2993 static ssize_t smu_v13_0_0_get_ecc_info(struct smu_context *smu,
2994 void *table)
2995 {
2996 struct smu_table_context *smu_table = &smu->smu_table;
2997 struct amdgpu_device *adev = smu->adev;
2998 EccInfoTable_t *ecc_table = NULL;
2999 struct ecc_info_per_ch *ecc_info_per_channel = NULL;
3000 int i, ret = 0;
3001 struct umc_ecc_info *eccinfo = (struct umc_ecc_info *)table;
3002
3003 ret = smu_v13_0_0_check_ecc_table_support(smu);
3004 if (ret)
3005 return ret;
3006
3007 ret = smu_cmn_update_table(smu,
3008 SMU_TABLE_ECCINFO,
3009 0,
3010 smu_table->ecc_table,
3011 false);
3012 if (ret) {
3013 dev_info(adev->dev, "Failed to export SMU ecc table!\n");
3014 return ret;
3015 }
3016
3017 ecc_table = (EccInfoTable_t *)smu_table->ecc_table;
3018
3019 for (i = 0; i < ARRAY_SIZE(ecc_table->EccInfo); i++) {
3020 ecc_info_per_channel = &(eccinfo->ecc[i]);
3021 ecc_info_per_channel->ce_count_lo_chip =
3022 ecc_table->EccInfo[i].ce_count_lo_chip;
3023 ecc_info_per_channel->ce_count_hi_chip =
3024 ecc_table->EccInfo[i].ce_count_hi_chip;
3025 ecc_info_per_channel->mca_umc_status =
3026 ecc_table->EccInfo[i].mca_umc_status;
3027 ecc_info_per_channel->mca_umc_addr =
3028 ecc_table->EccInfo[i].mca_umc_addr;
3029 }
3030
3031 return ret;
3032 }
3033
smu_v13_0_0_wbrf_support_check(struct smu_context * smu)3034 static bool smu_v13_0_0_wbrf_support_check(struct smu_context *smu)
3035 {
3036 struct amdgpu_device *adev = smu->adev;
3037
3038 switch (amdgpu_ip_version(adev, MP1_HWIP, 0)) {
3039 case IP_VERSION(13, 0, 0):
3040 return smu->smc_fw_version >= 0x004e6300;
3041 case IP_VERSION(13, 0, 10):
3042 return smu->smc_fw_version >= 0x00503300;
3043 default:
3044 return false;
3045 }
3046 }
3047
smu_v13_0_0_set_ppt_limit(struct smu_context * smu,enum smu_ppt_limit_type limit_type,uint32_t limit)3048 static int smu_v13_0_0_set_ppt_limit(struct smu_context *smu,
3049 enum smu_ppt_limit_type limit_type,
3050 uint32_t limit)
3051 {
3052 PPTable_t *pptable = smu->smu_table.driver_pptable;
3053 SkuTable_t *skutable = &pptable->SkuTable;
3054 uint32_t msg_limit = skutable->MsgLimits.Power
3055 [PPT_THROTTLER_PPT0][POWER_SOURCE_AC];
3056 struct smu_table_context *table_context = &smu->smu_table;
3057 OverDriveTableExternal_t *od_table =
3058 (OverDriveTableExternal_t *)table_context->overdrive_table;
3059 OverDriveTableExternal_t current_od_table;
3060 int ret = 0;
3061
3062 if (limit_type != SMU_PPT_LIMIT_PPT0)
3063 return -EINVAL;
3064
3065 if (limit <= msg_limit) {
3066 ret = smu_v13_0_0_get_overdrive_table(smu, ¤t_od_table);
3067 if (ret)
3068 return ret;
3069
3070 if (current_od_table.OverDriveTable.Ppt) {
3071 od_table->OverDriveTable.Ppt = 0;
3072 od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_PPT_BIT;
3073
3074 ret = smu_v13_0_0_upload_overdrive_table(smu, od_table);
3075 if (ret) {
3076 dev_err(smu->adev->dev, "Failed to upload overdrive table!\n");
3077 return ret;
3078 }
3079 }
3080 return smu_v13_0_set_ppt_limit(smu, limit_type, limit);
3081 } else if (smu->od_enabled) {
3082 ret = smu_v13_0_set_ppt_limit(smu, limit_type, msg_limit);
3083 if (ret)
3084 return ret;
3085
3086 od_table->OverDriveTable.Ppt = (limit * 100) / msg_limit - 100;
3087 od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_PPT_BIT;
3088
3089 ret = smu_v13_0_0_upload_overdrive_table(smu, od_table);
3090 if (ret) {
3091 dev_err(smu->adev->dev, "Failed to upload overdrive table!\n");
3092 return ret;
3093 }
3094
3095 } else {
3096 return -EINVAL;
3097 }
3098
3099 return 0;
3100 }
3101
smu_v13_0_0_update_pcie_parameters(struct smu_context * smu,uint8_t pcie_gen_cap,uint8_t pcie_width_cap)3102 static int smu_v13_0_0_update_pcie_parameters(struct smu_context *smu,
3103 uint8_t pcie_gen_cap,
3104 uint8_t pcie_width_cap)
3105 {
3106 struct smu_13_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context;
3107 struct smu_pcie_table *pcie_table = &dpm_context->dpm_tables.pcie_table;
3108 int num_of_levels;
3109 uint32_t smu_pcie_arg;
3110 uint32_t link_level;
3111 struct smu_table_context *table_context = &smu->smu_table;
3112 PPTable_t *pptable = table_context->driver_pptable;
3113 SkuTable_t *skutable = &pptable->SkuTable;
3114 int ret = 0;
3115 int i;
3116
3117 pcie_table->lclk_levels = 0;
3118
3119 for (link_level = 0; link_level < NUM_LINK_LEVELS; link_level++) {
3120 if (!skutable->PcieGenSpeed[link_level] &&
3121 !skutable->PcieLaneCount[link_level] &&
3122 !skutable->LclkFreq[link_level])
3123 continue;
3124
3125 pcie_table->pcie_gen[pcie_table->lclk_levels] =
3126 skutable->PcieGenSpeed[link_level];
3127 pcie_table->pcie_lane[pcie_table->lclk_levels] =
3128 skutable->PcieLaneCount[link_level];
3129 pcie_table->lclk_freq[pcie_table->lclk_levels] =
3130 skutable->LclkFreq[link_level];
3131 pcie_table->lclk_levels++;
3132 }
3133
3134 num_of_levels = pcie_table->lclk_levels;
3135 if (!num_of_levels)
3136 return 0;
3137
3138 if (!(smu->adev->pm.pp_feature & PP_PCIE_DPM_MASK)) {
3139 if (pcie_table->pcie_gen[num_of_levels - 1] < pcie_gen_cap)
3140 pcie_gen_cap = pcie_table->pcie_gen[num_of_levels - 1];
3141
3142 if (pcie_table->pcie_lane[num_of_levels - 1] < pcie_width_cap)
3143 pcie_width_cap = pcie_table->pcie_lane[num_of_levels - 1];
3144
3145 /* Force all levels to use the same settings */
3146 for (i = 0; i < num_of_levels; i++) {
3147 pcie_table->pcie_gen[i] = pcie_gen_cap;
3148 pcie_table->pcie_lane[i] = pcie_width_cap;
3149 smu_pcie_arg = i << 16;
3150 smu_pcie_arg |= pcie_table->pcie_gen[i] << 8;
3151 smu_pcie_arg |= pcie_table->pcie_lane[i];
3152
3153 ret = smu_cmn_send_smc_msg_with_param(smu,
3154 SMU_MSG_OverridePcieParameters,
3155 smu_pcie_arg,
3156 NULL);
3157 if (ret)
3158 break;
3159 }
3160 } else {
3161 for (i = 0; i < num_of_levels; i++) {
3162 if (pcie_table->pcie_gen[i] > pcie_gen_cap ||
3163 pcie_table->pcie_lane[i] > pcie_width_cap) {
3164 pcie_table->pcie_gen[i] = pcie_table->pcie_gen[i] > pcie_gen_cap ?
3165 pcie_gen_cap : pcie_table->pcie_gen[i];
3166 pcie_table->pcie_lane[i] = pcie_table->pcie_lane[i] > pcie_width_cap ?
3167 pcie_width_cap : pcie_table->pcie_lane[i];
3168 smu_pcie_arg = i << 16;
3169 smu_pcie_arg |= pcie_table->pcie_gen[i] << 8;
3170 smu_pcie_arg |= pcie_table->pcie_lane[i];
3171
3172 ret = smu_cmn_send_smc_msg_with_param(smu,
3173 SMU_MSG_OverridePcieParameters,
3174 smu_pcie_arg,
3175 NULL);
3176 if (ret)
3177 break;
3178 }
3179 }
3180 }
3181
3182 return ret;
3183 }
3184
3185 static const struct pptable_funcs smu_v13_0_0_ppt_funcs = {
3186 .init_allowed_features = smu_v13_0_0_init_allowed_features,
3187 .set_default_dpm_table = smu_v13_0_0_set_default_dpm_table,
3188 .i2c_init = smu_v13_0_0_i2c_control_init,
3189 .i2c_fini = smu_v13_0_0_i2c_control_fini,
3190 .is_dpm_running = smu_v13_0_0_is_dpm_running,
3191 .init_microcode = smu_v13_0_init_microcode,
3192 .load_microcode = smu_v13_0_load_microcode,
3193 .fini_microcode = smu_v13_0_fini_microcode,
3194 .init_smc_tables = smu_v13_0_0_init_smc_tables,
3195 .fini_smc_tables = smu_v13_0_fini_smc_tables,
3196 .init_power = smu_v13_0_init_power,
3197 .fini_power = smu_v13_0_fini_power,
3198 .check_fw_status = smu_v13_0_check_fw_status,
3199 .setup_pptable = smu_v13_0_0_setup_pptable,
3200 .check_fw_version = smu_cmn_check_fw_version,
3201 .write_pptable = smu_cmn_write_pptable,
3202 .set_driver_table_location = smu_v13_0_set_driver_table_location,
3203 .system_features_control = smu_v13_0_0_system_features_control,
3204 .set_allowed_mask = smu_v13_0_set_allowed_mask,
3205 .get_enabled_mask = smu_cmn_get_enabled_mask,
3206 .dpm_set_vcn_enable = smu_v13_0_set_vcn_enable,
3207 .dpm_set_jpeg_enable = smu_v13_0_set_jpeg_enable,
3208 .get_dpm_ultimate_freq = smu_v13_0_0_get_dpm_ultimate_freq,
3209 .get_vbios_bootup_values = smu_v13_0_get_vbios_bootup_values,
3210 .read_sensor = smu_v13_0_0_read_sensor,
3211 .feature_is_enabled = smu_cmn_feature_is_enabled,
3212 .emit_clk_levels = smu_v13_0_0_emit_clk_levels,
3213 .force_clk_levels = smu_v13_0_0_force_clk_levels,
3214 .update_pcie_parameters = smu_v13_0_0_update_pcie_parameters,
3215 .get_thermal_temperature_range = smu_v13_0_0_get_thermal_temperature_range,
3216 .register_irq_handler = smu_v13_0_register_irq_handler,
3217 .enable_thermal_alert = smu_v13_0_enable_thermal_alert,
3218 .disable_thermal_alert = smu_v13_0_disable_thermal_alert,
3219 .notify_memory_pool_location = smu_v13_0_notify_memory_pool_location,
3220 .get_gpu_metrics = smu_v13_0_0_get_gpu_metrics,
3221 .set_soft_freq_limited_range = smu_v13_0_set_soft_freq_limited_range,
3222 .set_default_od_settings = smu_v13_0_0_set_default_od_settings,
3223 .restore_user_od_settings = smu_v13_0_0_restore_user_od_settings,
3224 .od_edit_dpm_table = smu_v13_0_0_od_edit_dpm_table,
3225 .init_pptable_microcode = smu_v13_0_init_pptable_microcode,
3226 .populate_umd_state_clk = smu_v13_0_0_populate_umd_state_clk,
3227 .set_performance_level = smu_v13_0_set_performance_level,
3228 .gfx_off_control = smu_v13_0_gfx_off_control,
3229 .get_unique_id = smu_v13_0_0_get_unique_id,
3230 .get_fan_speed_pwm = smu_v13_0_0_get_fan_speed_pwm,
3231 .get_fan_speed_rpm = smu_v13_0_0_get_fan_speed_rpm,
3232 .set_fan_speed_pwm = smu_v13_0_set_fan_speed_pwm,
3233 .set_fan_speed_rpm = smu_v13_0_set_fan_speed_rpm,
3234 .get_fan_control_mode = smu_v13_0_get_fan_control_mode,
3235 .set_fan_control_mode = smu_v13_0_set_fan_control_mode,
3236 .enable_mgpu_fan_boost = smu_v13_0_0_enable_mgpu_fan_boost,
3237 .get_ppt_limit = smu_v13_0_0_get_ppt_limit,
3238 .set_ppt_limit = smu_v13_0_0_set_ppt_limit,
3239 .set_power_source = smu_v13_0_set_power_source,
3240 .get_power_profile_mode = smu_v13_0_0_get_power_profile_mode,
3241 .set_power_profile_mode = smu_v13_0_0_set_power_profile_mode,
3242 .run_btc = smu_v13_0_run_btc,
3243 .get_pp_feature_mask = smu_cmn_get_pp_feature_mask,
3244 .set_pp_feature_mask = smu_cmn_set_pp_feature_mask,
3245 .set_tool_table_location = smu_v13_0_set_tool_table_location,
3246 .deep_sleep_control = smu_v13_0_deep_sleep_control,
3247 .gfx_ulv_control = smu_v13_0_gfx_ulv_control,
3248 .get_bamaco_support = smu_v13_0_get_bamaco_support,
3249 .baco_enter = smu_v13_0_baco_enter,
3250 .baco_exit = smu_v13_0_baco_exit,
3251 .mode1_reset_is_support = smu_v13_0_0_is_mode1_reset_supported,
3252 .mode1_reset = smu_v13_0_0_mode1_reset,
3253 .mode2_reset = smu_v13_0_0_mode2_reset,
3254 .enable_gfx_features = smu_v13_0_0_enable_gfx_features,
3255 .set_mp1_state = smu_v13_0_0_set_mp1_state,
3256 .set_df_cstate = smu_v13_0_0_set_df_cstate,
3257 .send_hbm_bad_pages_num = smu_v13_0_0_smu_send_bad_mem_page_num,
3258 .send_hbm_bad_channel_flag = smu_v13_0_0_send_bad_mem_channel_flag,
3259 .gpo_control = smu_v13_0_gpo_control,
3260 .get_ecc_info = smu_v13_0_0_get_ecc_info,
3261 .notify_display_change = smu_v13_0_notify_display_change,
3262 .is_asic_wbrf_supported = smu_v13_0_0_wbrf_support_check,
3263 .enable_uclk_shadow = smu_v13_0_enable_uclk_shadow,
3264 .set_wbrf_exclusion_ranges = smu_v13_0_set_wbrf_exclusion_ranges,
3265 .interrupt_work = smu_v13_0_interrupt_work,
3266 };
3267
smu_v13_0_0_set_ppt_funcs(struct smu_context * smu)3268 void smu_v13_0_0_set_ppt_funcs(struct smu_context *smu)
3269 {
3270 smu->ppt_funcs = &smu_v13_0_0_ppt_funcs;
3271 smu->clock_map = smu_v13_0_0_clk_map;
3272 smu->feature_map = smu_v13_0_0_feature_mask_map;
3273 smu->table_map = smu_v13_0_0_table_map;
3274 smu->pwr_src_map = smu_v13_0_0_pwr_src_map;
3275 smu->workload_map = smu_v13_0_0_workload_map;
3276 smu->smc_driver_if_version = SMU13_0_0_DRIVER_IF_VERSION;
3277 smu_v13_0_0_init_msg_ctl(smu);
3278
3279 if (amdgpu_ip_version(smu->adev, MP1_HWIP, 0) ==
3280 IP_VERSION(13, 0, 10) &&
3281 !amdgpu_device_has_display_hardware(smu->adev))
3282 smu->adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
3283 }
3284