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