xref: /linux/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c (revision 889600e21e3be388a6817c2a0dac0411df860751)
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, &param);
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, &param);
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, &current_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