1 /* 2 * Copyright 2019 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 */ 23 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 "soc15_common.h" 35 #include "smu_v11_0.h" 36 #include "smu11_driver_if_navi10.h" 37 #include "atom.h" 38 #include "navi10_ppt.h" 39 #include "smu_v11_0_pptable.h" 40 #include "smu_v11_0_ppsmc.h" 41 #include "nbio/nbio_2_3_offset.h" 42 #include "nbio/nbio_2_3_sh_mask.h" 43 #include "thm/thm_11_0_2_offset.h" 44 #include "thm/thm_11_0_2_sh_mask.h" 45 46 #include "asic_reg/mp/mp_11_0_sh_mask.h" 47 #include "smu_cmn.h" 48 #include "smu_11_0_cdr_table.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_PREFETCHER_BIT) | \ 65 FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT) | \ 66 FEATURE_MASK(FEATURE_DPM_GFX_PACE_BIT) | \ 67 FEATURE_MASK(FEATURE_DPM_UCLK_BIT) | \ 68 FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT) | \ 69 FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT) | \ 70 FEATURE_MASK(FEATURE_DPM_LINK_BIT) | \ 71 FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT)) 72 73 #define SMU_11_0_GFX_BUSY_THRESHOLD 15 74 75 static struct cmn2asic_msg_mapping navi10_message_map[SMU_MSG_MAX_COUNT] = { 76 MSG_MAP(TestMessage, PPSMC_MSG_TestMessage, 1), 77 MSG_MAP(GetSmuVersion, PPSMC_MSG_GetSmuVersion, 1), 78 MSG_MAP(GetDriverIfVersion, PPSMC_MSG_GetDriverIfVersion, 1), 79 MSG_MAP(SetAllowedFeaturesMaskLow, PPSMC_MSG_SetAllowedFeaturesMaskLow, 0), 80 MSG_MAP(SetAllowedFeaturesMaskHigh, PPSMC_MSG_SetAllowedFeaturesMaskHigh, 0), 81 MSG_MAP(EnableAllSmuFeatures, PPSMC_MSG_EnableAllSmuFeatures, 0), 82 MSG_MAP(DisableAllSmuFeatures, PPSMC_MSG_DisableAllSmuFeatures, 0), 83 MSG_MAP(EnableSmuFeaturesLow, PPSMC_MSG_EnableSmuFeaturesLow, 1), 84 MSG_MAP(EnableSmuFeaturesHigh, PPSMC_MSG_EnableSmuFeaturesHigh, 1), 85 MSG_MAP(DisableSmuFeaturesLow, PPSMC_MSG_DisableSmuFeaturesLow, 1), 86 MSG_MAP(DisableSmuFeaturesHigh, PPSMC_MSG_DisableSmuFeaturesHigh, 1), 87 MSG_MAP(GetEnabledSmuFeaturesLow, PPSMC_MSG_GetEnabledSmuFeaturesLow, 1), 88 MSG_MAP(GetEnabledSmuFeaturesHigh, PPSMC_MSG_GetEnabledSmuFeaturesHigh, 1), 89 MSG_MAP(SetWorkloadMask, PPSMC_MSG_SetWorkloadMask, 1), 90 MSG_MAP(SetPptLimit, PPSMC_MSG_SetPptLimit, 0), 91 MSG_MAP(SetDriverDramAddrHigh, PPSMC_MSG_SetDriverDramAddrHigh, 0), 92 MSG_MAP(SetDriverDramAddrLow, PPSMC_MSG_SetDriverDramAddrLow, 0), 93 MSG_MAP(SetToolsDramAddrHigh, PPSMC_MSG_SetToolsDramAddrHigh, 0), 94 MSG_MAP(SetToolsDramAddrLow, PPSMC_MSG_SetToolsDramAddrLow, 0), 95 MSG_MAP(TransferTableSmu2Dram, PPSMC_MSG_TransferTableSmu2Dram, 0), 96 MSG_MAP(TransferTableDram2Smu, PPSMC_MSG_TransferTableDram2Smu, 0), 97 MSG_MAP(UseDefaultPPTable, PPSMC_MSG_UseDefaultPPTable, 0), 98 MSG_MAP(UseBackupPPTable, PPSMC_MSG_UseBackupPPTable, 0), 99 MSG_MAP(RunBtc, PPSMC_MSG_RunBtc, 0), 100 MSG_MAP(EnterBaco, PPSMC_MSG_EnterBaco, 0), 101 MSG_MAP(SetSoftMinByFreq, PPSMC_MSG_SetSoftMinByFreq, 0), 102 MSG_MAP(SetSoftMaxByFreq, PPSMC_MSG_SetSoftMaxByFreq, 0), 103 MSG_MAP(SetHardMinByFreq, PPSMC_MSG_SetHardMinByFreq, 1), 104 MSG_MAP(SetHardMaxByFreq, PPSMC_MSG_SetHardMaxByFreq, 0), 105 MSG_MAP(GetMinDpmFreq, PPSMC_MSG_GetMinDpmFreq, 1), 106 MSG_MAP(GetMaxDpmFreq, PPSMC_MSG_GetMaxDpmFreq, 1), 107 MSG_MAP(GetDpmFreqByIndex, PPSMC_MSG_GetDpmFreqByIndex, 1), 108 MSG_MAP(SetMemoryChannelConfig, PPSMC_MSG_SetMemoryChannelConfig, 0), 109 MSG_MAP(SetGeminiMode, PPSMC_MSG_SetGeminiMode, 0), 110 MSG_MAP(SetGeminiApertureHigh, PPSMC_MSG_SetGeminiApertureHigh, 0), 111 MSG_MAP(SetGeminiApertureLow, PPSMC_MSG_SetGeminiApertureLow, 0), 112 MSG_MAP(OverridePcieParameters, PPSMC_MSG_OverridePcieParameters, 0), 113 MSG_MAP(SetMinDeepSleepDcefclk, PPSMC_MSG_SetMinDeepSleepDcefclk, 0), 114 MSG_MAP(ReenableAcDcInterrupt, PPSMC_MSG_ReenableAcDcInterrupt, 0), 115 MSG_MAP(NotifyPowerSource, PPSMC_MSG_NotifyPowerSource, 0), 116 MSG_MAP(SetUclkFastSwitch, PPSMC_MSG_SetUclkFastSwitch, 0), 117 MSG_MAP(SetVideoFps, PPSMC_MSG_SetVideoFps, 0), 118 MSG_MAP(PrepareMp1ForUnload, PPSMC_MSG_PrepareMp1ForUnload, 1), 119 MSG_MAP(DramLogSetDramAddrHigh, PPSMC_MSG_DramLogSetDramAddrHigh, 0), 120 MSG_MAP(DramLogSetDramAddrLow, PPSMC_MSG_DramLogSetDramAddrLow, 0), 121 MSG_MAP(DramLogSetDramSize, PPSMC_MSG_DramLogSetDramSize, 0), 122 MSG_MAP(ConfigureGfxDidt, PPSMC_MSG_ConfigureGfxDidt, 0), 123 MSG_MAP(NumOfDisplays, PPSMC_MSG_NumOfDisplays, 0), 124 MSG_MAP(SetSystemVirtualDramAddrHigh, PPSMC_MSG_SetSystemVirtualDramAddrHigh, 0), 125 MSG_MAP(SetSystemVirtualDramAddrLow, PPSMC_MSG_SetSystemVirtualDramAddrLow, 0), 126 MSG_MAP(AllowGfxOff, PPSMC_MSG_AllowGfxOff, 0), 127 MSG_MAP(DisallowGfxOff, PPSMC_MSG_DisallowGfxOff, 0), 128 MSG_MAP(GetPptLimit, PPSMC_MSG_GetPptLimit, 0), 129 MSG_MAP(GetDcModeMaxDpmFreq, PPSMC_MSG_GetDcModeMaxDpmFreq, 1), 130 MSG_MAP(GetDebugData, PPSMC_MSG_GetDebugData, 0), 131 MSG_MAP(ExitBaco, PPSMC_MSG_ExitBaco, 0), 132 MSG_MAP(PrepareMp1ForReset, PPSMC_MSG_PrepareMp1ForReset, 0), 133 MSG_MAP(PrepareMp1ForShutdown, PPSMC_MSG_PrepareMp1ForShutdown, 0), 134 MSG_MAP(PowerUpVcn, PPSMC_MSG_PowerUpVcn, 0), 135 MSG_MAP(PowerDownVcn, PPSMC_MSG_PowerDownVcn, 0), 136 MSG_MAP(PowerUpJpeg, PPSMC_MSG_PowerUpJpeg, 0), 137 MSG_MAP(PowerDownJpeg, PPSMC_MSG_PowerDownJpeg, 0), 138 MSG_MAP(BacoAudioD3PME, PPSMC_MSG_BacoAudioD3PME, 0), 139 MSG_MAP(ArmD3, PPSMC_MSG_ArmD3, 0), 140 MSG_MAP(DAL_DISABLE_DUMMY_PSTATE_CHANGE,PPSMC_MSG_DALDisableDummyPstateChange, 0), 141 MSG_MAP(DAL_ENABLE_DUMMY_PSTATE_CHANGE, PPSMC_MSG_DALEnableDummyPstateChange, 0), 142 MSG_MAP(GetVoltageByDpm, PPSMC_MSG_GetVoltageByDpm, 0), 143 MSG_MAP(GetVoltageByDpmOverdrive, PPSMC_MSG_GetVoltageByDpmOverdrive, 0), 144 MSG_MAP(SetMGpuFanBoostLimitRpm, PPSMC_MSG_SetMGpuFanBoostLimitRpm, 0), 145 MSG_MAP(SET_DRIVER_DUMMY_TABLE_DRAM_ADDR_HIGH, PPSMC_MSG_SetDriverDummyTableDramAddrHigh, 0), 146 MSG_MAP(SET_DRIVER_DUMMY_TABLE_DRAM_ADDR_LOW, PPSMC_MSG_SetDriverDummyTableDramAddrLow, 0), 147 MSG_MAP(GET_UMC_FW_WA, PPSMC_MSG_GetUMCFWWA, 0), 148 }; 149 150 static struct cmn2asic_mapping navi10_clk_map[SMU_CLK_COUNT] = { 151 CLK_MAP(GFXCLK, PPCLK_GFXCLK), 152 CLK_MAP(SCLK, PPCLK_GFXCLK), 153 CLK_MAP(SOCCLK, PPCLK_SOCCLK), 154 CLK_MAP(FCLK, PPCLK_SOCCLK), 155 CLK_MAP(UCLK, PPCLK_UCLK), 156 CLK_MAP(MCLK, PPCLK_UCLK), 157 CLK_MAP(DCLK, PPCLK_DCLK), 158 CLK_MAP(VCLK, PPCLK_VCLK), 159 CLK_MAP(DCEFCLK, PPCLK_DCEFCLK), 160 CLK_MAP(DISPCLK, PPCLK_DISPCLK), 161 CLK_MAP(PIXCLK, PPCLK_PIXCLK), 162 CLK_MAP(PHYCLK, PPCLK_PHYCLK), 163 }; 164 165 static struct cmn2asic_mapping navi10_feature_mask_map[SMU_FEATURE_COUNT] = { 166 FEA_MAP(DPM_PREFETCHER), 167 FEA_MAP(DPM_GFXCLK), 168 FEA_MAP(DPM_GFX_PACE), 169 FEA_MAP(DPM_UCLK), 170 FEA_MAP(DPM_SOCCLK), 171 FEA_MAP(DPM_MP0CLK), 172 FEA_MAP(DPM_LINK), 173 FEA_MAP(DPM_DCEFCLK), 174 FEA_MAP(MEM_VDDCI_SCALING), 175 FEA_MAP(MEM_MVDD_SCALING), 176 FEA_MAP(DS_GFXCLK), 177 FEA_MAP(DS_SOCCLK), 178 FEA_MAP(DS_LCLK), 179 FEA_MAP(DS_DCEFCLK), 180 FEA_MAP(DS_UCLK), 181 FEA_MAP(GFX_ULV), 182 FEA_MAP(FW_DSTATE), 183 FEA_MAP(GFXOFF), 184 FEA_MAP(BACO), 185 FEA_MAP(VCN_PG), 186 FEA_MAP(JPEG_PG), 187 FEA_MAP(USB_PG), 188 FEA_MAP(RSMU_SMN_CG), 189 FEA_MAP(PPT), 190 FEA_MAP(TDC), 191 FEA_MAP(GFX_EDC), 192 FEA_MAP(APCC_PLUS), 193 FEA_MAP(GTHR), 194 FEA_MAP(ACDC), 195 FEA_MAP(VR0HOT), 196 FEA_MAP(VR1HOT), 197 FEA_MAP(FW_CTF), 198 FEA_MAP(FAN_CONTROL), 199 FEA_MAP(THERMAL), 200 FEA_MAP(GFX_DCS), 201 FEA_MAP(RM), 202 FEA_MAP(LED_DISPLAY), 203 FEA_MAP(GFX_SS), 204 FEA_MAP(OUT_OF_BAND_MONITOR), 205 FEA_MAP(TEMP_DEPENDENT_VMIN), 206 FEA_MAP(MMHUB_PG), 207 FEA_MAP(ATHUB_PG), 208 FEA_MAP(APCC_DFLL), 209 }; 210 211 static struct cmn2asic_mapping navi10_table_map[SMU_TABLE_COUNT] = { 212 TAB_MAP(PPTABLE), 213 TAB_MAP(WATERMARKS), 214 TAB_MAP(AVFS), 215 TAB_MAP(AVFS_PSM_DEBUG), 216 TAB_MAP(AVFS_FUSE_OVERRIDE), 217 TAB_MAP(PMSTATUSLOG), 218 TAB_MAP(SMU_METRICS), 219 TAB_MAP(DRIVER_SMU_CONFIG), 220 TAB_MAP(ACTIVITY_MONITOR_COEFF), 221 TAB_MAP(OVERDRIVE), 222 TAB_MAP(I2C_COMMANDS), 223 TAB_MAP(PACE), 224 }; 225 226 static struct cmn2asic_mapping navi10_pwr_src_map[SMU_POWER_SOURCE_COUNT] = { 227 PWR_MAP(AC), 228 PWR_MAP(DC), 229 }; 230 231 static struct cmn2asic_mapping navi10_workload_map[PP_SMC_POWER_PROFILE_COUNT] = { 232 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_BOOTUP_DEFAULT, WORKLOAD_PPLIB_DEFAULT_BIT), 233 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_FULLSCREEN3D, WORKLOAD_PPLIB_FULL_SCREEN_3D_BIT), 234 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_POWERSAVING, WORKLOAD_PPLIB_POWER_SAVING_BIT), 235 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VIDEO, WORKLOAD_PPLIB_VIDEO_BIT), 236 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_VR, WORKLOAD_PPLIB_VR_BIT), 237 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_COMPUTE, WORKLOAD_PPLIB_COMPUTE_BIT), 238 WORKLOAD_MAP(PP_SMC_POWER_PROFILE_CUSTOM, WORKLOAD_PPLIB_CUSTOM_BIT), 239 }; 240 241 static bool is_asic_secure(struct smu_context *smu) 242 { 243 struct amdgpu_device *adev = smu->adev; 244 bool is_secure = true; 245 uint32_t mp0_fw_intf; 246 247 mp0_fw_intf = RREG32_PCIE(MP0_Public | 248 (smnMP0_FW_INTF & 0xffffffff)); 249 250 if (!(mp0_fw_intf & (1 << 19))) 251 is_secure = false; 252 253 return is_secure; 254 } 255 256 static int 257 navi10_get_allowed_feature_mask(struct smu_context *smu, 258 uint32_t *feature_mask, uint32_t num) 259 { 260 struct amdgpu_device *adev = smu->adev; 261 262 if (num > 2) 263 return -EINVAL; 264 265 memset(feature_mask, 0, sizeof(uint32_t) * num); 266 267 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_PREFETCHER_BIT) 268 | FEATURE_MASK(FEATURE_DPM_MP0CLK_BIT) 269 | FEATURE_MASK(FEATURE_RSMU_SMN_CG_BIT) 270 | FEATURE_MASK(FEATURE_DS_SOCCLK_BIT) 271 | FEATURE_MASK(FEATURE_PPT_BIT) 272 | FEATURE_MASK(FEATURE_TDC_BIT) 273 | FEATURE_MASK(FEATURE_GFX_EDC_BIT) 274 | FEATURE_MASK(FEATURE_APCC_PLUS_BIT) 275 | FEATURE_MASK(FEATURE_VR0HOT_BIT) 276 | FEATURE_MASK(FEATURE_FAN_CONTROL_BIT) 277 | FEATURE_MASK(FEATURE_THERMAL_BIT) 278 | FEATURE_MASK(FEATURE_LED_DISPLAY_BIT) 279 | FEATURE_MASK(FEATURE_DS_LCLK_BIT) 280 | FEATURE_MASK(FEATURE_DS_DCEFCLK_BIT) 281 | FEATURE_MASK(FEATURE_FW_DSTATE_BIT) 282 | FEATURE_MASK(FEATURE_BACO_BIT) 283 | FEATURE_MASK(FEATURE_GFX_SS_BIT) 284 | FEATURE_MASK(FEATURE_APCC_DFLL_BIT) 285 | FEATURE_MASK(FEATURE_FW_CTF_BIT) 286 | FEATURE_MASK(FEATURE_OUT_OF_BAND_MONITOR_BIT); 287 288 if (adev->pm.pp_feature & PP_SCLK_DPM_MASK) 289 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_GFXCLK_BIT); 290 291 if (adev->pm.pp_feature & PP_PCIE_DPM_MASK) 292 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_LINK_BIT); 293 294 if (adev->pm.pp_feature & PP_DCEFCLK_DPM_MASK) 295 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_DCEFCLK_BIT); 296 297 if (adev->pm.pp_feature & PP_ULV_MASK) 298 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFX_ULV_BIT); 299 300 if (adev->pm.pp_feature & PP_SCLK_DEEP_SLEEP_MASK) 301 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DS_GFXCLK_BIT); 302 303 if (adev->pm.pp_feature & PP_GFXOFF_MASK) 304 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_GFXOFF_BIT); 305 306 if (smu->adev->pg_flags & AMD_PG_SUPPORT_MMHUB) 307 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_MMHUB_PG_BIT); 308 309 if (smu->adev->pg_flags & AMD_PG_SUPPORT_ATHUB) 310 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_ATHUB_PG_BIT); 311 312 if (smu->adev->pg_flags & AMD_PG_SUPPORT_VCN) 313 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_VCN_PG_BIT); 314 315 if (smu->adev->pg_flags & AMD_PG_SUPPORT_JPEG) 316 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_JPEG_PG_BIT); 317 318 if (smu->dc_controlled_by_gpio) 319 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_ACDC_BIT); 320 321 if (adev->pm.pp_feature & PP_SOCCLK_DPM_MASK) 322 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_SOCCLK_BIT); 323 324 /* DPM UCLK enablement should be skipped for navi10 A0 secure board */ 325 if (!(is_asic_secure(smu) && 326 (adev->asic_type == CHIP_NAVI10) && 327 (adev->rev_id == 0)) && 328 (adev->pm.pp_feature & PP_MCLK_DPM_MASK)) 329 *(uint64_t *)feature_mask |= FEATURE_MASK(FEATURE_DPM_UCLK_BIT) 330 | FEATURE_MASK(FEATURE_MEM_VDDCI_SCALING_BIT) 331 | FEATURE_MASK(FEATURE_MEM_MVDD_SCALING_BIT); 332 333 /* DS SOCCLK enablement should be skipped for navi10 A0 secure board */ 334 if (is_asic_secure(smu) && 335 (adev->asic_type == CHIP_NAVI10) && 336 (adev->rev_id == 0)) 337 *(uint64_t *)feature_mask &= 338 ~FEATURE_MASK(FEATURE_DS_SOCCLK_BIT); 339 340 return 0; 341 } 342 343 static int navi10_check_powerplay_table(struct smu_context *smu) 344 { 345 struct smu_table_context *table_context = &smu->smu_table; 346 struct smu_11_0_powerplay_table *powerplay_table = 347 table_context->power_play_table; 348 struct smu_baco_context *smu_baco = &smu->smu_baco; 349 350 if (powerplay_table->platform_caps & SMU_11_0_PP_PLATFORM_CAP_HARDWAREDC) 351 smu->dc_controlled_by_gpio = true; 352 353 if (powerplay_table->platform_caps & SMU_11_0_PP_PLATFORM_CAP_BACO || 354 powerplay_table->platform_caps & SMU_11_0_PP_PLATFORM_CAP_MACO) 355 smu_baco->platform_support = true; 356 357 table_context->thermal_controller_type = 358 powerplay_table->thermal_controller_type; 359 360 /* 361 * Instead of having its own buffer space and get overdrive_table copied, 362 * smu->od_settings just points to the actual overdrive_table 363 */ 364 smu->od_settings = &powerplay_table->overdrive_table; 365 366 return 0; 367 } 368 369 static int navi10_append_powerplay_table(struct smu_context *smu) 370 { 371 struct amdgpu_device *adev = smu->adev; 372 struct smu_table_context *table_context = &smu->smu_table; 373 PPTable_t *smc_pptable = table_context->driver_pptable; 374 struct atom_smc_dpm_info_v4_5 *smc_dpm_table; 375 struct atom_smc_dpm_info_v4_7 *smc_dpm_table_v4_7; 376 int index, ret; 377 378 index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, 379 smc_dpm_info); 380 381 ret = amdgpu_atombios_get_data_table(adev, index, NULL, NULL, NULL, 382 (uint8_t **)&smc_dpm_table); 383 if (ret) 384 return ret; 385 386 dev_info(adev->dev, "smc_dpm_info table revision(format.content): %d.%d\n", 387 smc_dpm_table->table_header.format_revision, 388 smc_dpm_table->table_header.content_revision); 389 390 if (smc_dpm_table->table_header.format_revision != 4) { 391 dev_err(adev->dev, "smc_dpm_info table format revision is not 4!\n"); 392 return -EINVAL; 393 } 394 395 switch (smc_dpm_table->table_header.content_revision) { 396 case 5: /* nv10 and nv14 */ 397 memcpy(smc_pptable->I2cControllers, smc_dpm_table->I2cControllers, 398 sizeof(*smc_dpm_table) - sizeof(smc_dpm_table->table_header)); 399 break; 400 case 7: /* nv12 */ 401 ret = amdgpu_atombios_get_data_table(adev, index, NULL, NULL, NULL, 402 (uint8_t **)&smc_dpm_table_v4_7); 403 if (ret) 404 return ret; 405 memcpy(smc_pptable->I2cControllers, smc_dpm_table_v4_7->I2cControllers, 406 sizeof(*smc_dpm_table_v4_7) - sizeof(smc_dpm_table_v4_7->table_header)); 407 break; 408 default: 409 dev_err(smu->adev->dev, "smc_dpm_info with unsupported content revision %d!\n", 410 smc_dpm_table->table_header.content_revision); 411 return -EINVAL; 412 } 413 414 if (adev->pm.pp_feature & PP_GFXOFF_MASK) { 415 /* TODO: remove it once SMU fw fix it */ 416 smc_pptable->DebugOverrides |= DPM_OVERRIDE_DISABLE_DFLL_PLL_SHUTDOWN; 417 } 418 419 return 0; 420 } 421 422 static int navi10_store_powerplay_table(struct smu_context *smu) 423 { 424 struct smu_table_context *table_context = &smu->smu_table; 425 struct smu_11_0_powerplay_table *powerplay_table = 426 table_context->power_play_table; 427 428 memcpy(table_context->driver_pptable, &powerplay_table->smc_pptable, 429 sizeof(PPTable_t)); 430 431 return 0; 432 } 433 434 static int navi10_setup_pptable(struct smu_context *smu) 435 { 436 int ret = 0; 437 438 ret = smu_v11_0_setup_pptable(smu); 439 if (ret) 440 return ret; 441 442 ret = navi10_store_powerplay_table(smu); 443 if (ret) 444 return ret; 445 446 ret = navi10_append_powerplay_table(smu); 447 if (ret) 448 return ret; 449 450 ret = navi10_check_powerplay_table(smu); 451 if (ret) 452 return ret; 453 454 return ret; 455 } 456 457 static int navi10_tables_init(struct smu_context *smu) 458 { 459 struct smu_table_context *smu_table = &smu->smu_table; 460 struct smu_table *tables = smu_table->tables; 461 462 SMU_TABLE_INIT(tables, SMU_TABLE_PPTABLE, sizeof(PPTable_t), 463 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 464 SMU_TABLE_INIT(tables, SMU_TABLE_WATERMARKS, sizeof(Watermarks_t), 465 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 466 SMU_TABLE_INIT(tables, SMU_TABLE_SMU_METRICS, sizeof(SmuMetrics_NV1X_t), 467 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 468 SMU_TABLE_INIT(tables, SMU_TABLE_I2C_COMMANDS, sizeof(SwI2cRequest_t), 469 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 470 SMU_TABLE_INIT(tables, SMU_TABLE_OVERDRIVE, sizeof(OverDriveTable_t), 471 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 472 SMU_TABLE_INIT(tables, SMU_TABLE_PMSTATUSLOG, SMU11_TOOL_SIZE, 473 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM); 474 SMU_TABLE_INIT(tables, SMU_TABLE_ACTIVITY_MONITOR_COEFF, 475 sizeof(DpmActivityMonitorCoeffInt_t), PAGE_SIZE, 476 AMDGPU_GEM_DOMAIN_VRAM); 477 478 smu_table->metrics_table = kzalloc(sizeof(SmuMetrics_NV1X_t), 479 GFP_KERNEL); 480 if (!smu_table->metrics_table) 481 goto err0_out; 482 smu_table->metrics_time = 0; 483 484 smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v1_1); 485 smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL); 486 if (!smu_table->gpu_metrics_table) 487 goto err1_out; 488 489 smu_table->watermarks_table = kzalloc(sizeof(Watermarks_t), GFP_KERNEL); 490 if (!smu_table->watermarks_table) 491 goto err2_out; 492 493 return 0; 494 495 err2_out: 496 kfree(smu_table->gpu_metrics_table); 497 err1_out: 498 kfree(smu_table->metrics_table); 499 err0_out: 500 return -ENOMEM; 501 } 502 503 static int navi10_get_legacy_smu_metrics_data(struct smu_context *smu, 504 MetricsMember_t member, 505 uint32_t *value) 506 { 507 struct smu_table_context *smu_table= &smu->smu_table; 508 SmuMetrics_legacy_t *metrics = 509 (SmuMetrics_legacy_t *)smu_table->metrics_table; 510 int ret = 0; 511 512 mutex_lock(&smu->metrics_lock); 513 514 ret = smu_cmn_get_metrics_table_locked(smu, 515 NULL, 516 false); 517 if (ret) { 518 mutex_unlock(&smu->metrics_lock); 519 return ret; 520 } 521 522 switch (member) { 523 case METRICS_CURR_GFXCLK: 524 *value = metrics->CurrClock[PPCLK_GFXCLK]; 525 break; 526 case METRICS_CURR_SOCCLK: 527 *value = metrics->CurrClock[PPCLK_SOCCLK]; 528 break; 529 case METRICS_CURR_UCLK: 530 *value = metrics->CurrClock[PPCLK_UCLK]; 531 break; 532 case METRICS_CURR_VCLK: 533 *value = metrics->CurrClock[PPCLK_VCLK]; 534 break; 535 case METRICS_CURR_DCLK: 536 *value = metrics->CurrClock[PPCLK_DCLK]; 537 break; 538 case METRICS_CURR_DCEFCLK: 539 *value = metrics->CurrClock[PPCLK_DCEFCLK]; 540 break; 541 case METRICS_AVERAGE_GFXCLK: 542 *value = metrics->AverageGfxclkFrequency; 543 break; 544 case METRICS_AVERAGE_SOCCLK: 545 *value = metrics->AverageSocclkFrequency; 546 break; 547 case METRICS_AVERAGE_UCLK: 548 *value = metrics->AverageUclkFrequency; 549 break; 550 case METRICS_AVERAGE_GFXACTIVITY: 551 *value = metrics->AverageGfxActivity; 552 break; 553 case METRICS_AVERAGE_MEMACTIVITY: 554 *value = metrics->AverageUclkActivity; 555 break; 556 case METRICS_AVERAGE_SOCKETPOWER: 557 *value = metrics->AverageSocketPower << 8; 558 break; 559 case METRICS_TEMPERATURE_EDGE: 560 *value = metrics->TemperatureEdge * 561 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 562 break; 563 case METRICS_TEMPERATURE_HOTSPOT: 564 *value = metrics->TemperatureHotspot * 565 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 566 break; 567 case METRICS_TEMPERATURE_MEM: 568 *value = metrics->TemperatureMem * 569 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 570 break; 571 case METRICS_TEMPERATURE_VRGFX: 572 *value = metrics->TemperatureVrGfx * 573 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 574 break; 575 case METRICS_TEMPERATURE_VRSOC: 576 *value = metrics->TemperatureVrSoc * 577 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 578 break; 579 case METRICS_THROTTLER_STATUS: 580 *value = metrics->ThrottlerStatus; 581 break; 582 case METRICS_CURR_FANSPEED: 583 *value = metrics->CurrFanSpeed; 584 break; 585 default: 586 *value = UINT_MAX; 587 break; 588 } 589 590 mutex_unlock(&smu->metrics_lock); 591 592 return ret; 593 } 594 595 static int navi10_get_smu_metrics_data(struct smu_context *smu, 596 MetricsMember_t member, 597 uint32_t *value) 598 { 599 struct smu_table_context *smu_table= &smu->smu_table; 600 SmuMetrics_t *metrics = 601 (SmuMetrics_t *)smu_table->metrics_table; 602 int ret = 0; 603 604 mutex_lock(&smu->metrics_lock); 605 606 ret = smu_cmn_get_metrics_table_locked(smu, 607 NULL, 608 false); 609 if (ret) { 610 mutex_unlock(&smu->metrics_lock); 611 return ret; 612 } 613 614 switch (member) { 615 case METRICS_CURR_GFXCLK: 616 *value = metrics->CurrClock[PPCLK_GFXCLK]; 617 break; 618 case METRICS_CURR_SOCCLK: 619 *value = metrics->CurrClock[PPCLK_SOCCLK]; 620 break; 621 case METRICS_CURR_UCLK: 622 *value = metrics->CurrClock[PPCLK_UCLK]; 623 break; 624 case METRICS_CURR_VCLK: 625 *value = metrics->CurrClock[PPCLK_VCLK]; 626 break; 627 case METRICS_CURR_DCLK: 628 *value = metrics->CurrClock[PPCLK_DCLK]; 629 break; 630 case METRICS_CURR_DCEFCLK: 631 *value = metrics->CurrClock[PPCLK_DCEFCLK]; 632 break; 633 case METRICS_AVERAGE_GFXCLK: 634 if (metrics->AverageGfxActivity > SMU_11_0_GFX_BUSY_THRESHOLD) 635 *value = metrics->AverageGfxclkFrequencyPreDs; 636 else 637 *value = metrics->AverageGfxclkFrequencyPostDs; 638 break; 639 case METRICS_AVERAGE_SOCCLK: 640 *value = metrics->AverageSocclkFrequency; 641 break; 642 case METRICS_AVERAGE_UCLK: 643 *value = metrics->AverageUclkFrequencyPostDs; 644 break; 645 case METRICS_AVERAGE_GFXACTIVITY: 646 *value = metrics->AverageGfxActivity; 647 break; 648 case METRICS_AVERAGE_MEMACTIVITY: 649 *value = metrics->AverageUclkActivity; 650 break; 651 case METRICS_AVERAGE_SOCKETPOWER: 652 *value = metrics->AverageSocketPower << 8; 653 break; 654 case METRICS_TEMPERATURE_EDGE: 655 *value = metrics->TemperatureEdge * 656 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 657 break; 658 case METRICS_TEMPERATURE_HOTSPOT: 659 *value = metrics->TemperatureHotspot * 660 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 661 break; 662 case METRICS_TEMPERATURE_MEM: 663 *value = metrics->TemperatureMem * 664 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 665 break; 666 case METRICS_TEMPERATURE_VRGFX: 667 *value = metrics->TemperatureVrGfx * 668 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 669 break; 670 case METRICS_TEMPERATURE_VRSOC: 671 *value = metrics->TemperatureVrSoc * 672 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 673 break; 674 case METRICS_THROTTLER_STATUS: 675 *value = metrics->ThrottlerStatus; 676 break; 677 case METRICS_CURR_FANSPEED: 678 *value = metrics->CurrFanSpeed; 679 break; 680 default: 681 *value = UINT_MAX; 682 break; 683 } 684 685 mutex_unlock(&smu->metrics_lock); 686 687 return ret; 688 } 689 690 static int navi12_get_legacy_smu_metrics_data(struct smu_context *smu, 691 MetricsMember_t member, 692 uint32_t *value) 693 { 694 struct smu_table_context *smu_table= &smu->smu_table; 695 SmuMetrics_NV12_legacy_t *metrics = 696 (SmuMetrics_NV12_legacy_t *)smu_table->metrics_table; 697 int ret = 0; 698 699 mutex_lock(&smu->metrics_lock); 700 701 ret = smu_cmn_get_metrics_table_locked(smu, 702 NULL, 703 false); 704 if (ret) { 705 mutex_unlock(&smu->metrics_lock); 706 return ret; 707 } 708 709 switch (member) { 710 case METRICS_CURR_GFXCLK: 711 *value = metrics->CurrClock[PPCLK_GFXCLK]; 712 break; 713 case METRICS_CURR_SOCCLK: 714 *value = metrics->CurrClock[PPCLK_SOCCLK]; 715 break; 716 case METRICS_CURR_UCLK: 717 *value = metrics->CurrClock[PPCLK_UCLK]; 718 break; 719 case METRICS_CURR_VCLK: 720 *value = metrics->CurrClock[PPCLK_VCLK]; 721 break; 722 case METRICS_CURR_DCLK: 723 *value = metrics->CurrClock[PPCLK_DCLK]; 724 break; 725 case METRICS_CURR_DCEFCLK: 726 *value = metrics->CurrClock[PPCLK_DCEFCLK]; 727 break; 728 case METRICS_AVERAGE_GFXCLK: 729 *value = metrics->AverageGfxclkFrequency; 730 break; 731 case METRICS_AVERAGE_SOCCLK: 732 *value = metrics->AverageSocclkFrequency; 733 break; 734 case METRICS_AVERAGE_UCLK: 735 *value = metrics->AverageUclkFrequency; 736 break; 737 case METRICS_AVERAGE_GFXACTIVITY: 738 *value = metrics->AverageGfxActivity; 739 break; 740 case METRICS_AVERAGE_MEMACTIVITY: 741 *value = metrics->AverageUclkActivity; 742 break; 743 case METRICS_AVERAGE_SOCKETPOWER: 744 *value = metrics->AverageSocketPower << 8; 745 break; 746 case METRICS_TEMPERATURE_EDGE: 747 *value = metrics->TemperatureEdge * 748 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 749 break; 750 case METRICS_TEMPERATURE_HOTSPOT: 751 *value = metrics->TemperatureHotspot * 752 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 753 break; 754 case METRICS_TEMPERATURE_MEM: 755 *value = metrics->TemperatureMem * 756 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 757 break; 758 case METRICS_TEMPERATURE_VRGFX: 759 *value = metrics->TemperatureVrGfx * 760 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 761 break; 762 case METRICS_TEMPERATURE_VRSOC: 763 *value = metrics->TemperatureVrSoc * 764 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 765 break; 766 case METRICS_THROTTLER_STATUS: 767 *value = metrics->ThrottlerStatus; 768 break; 769 case METRICS_CURR_FANSPEED: 770 *value = metrics->CurrFanSpeed; 771 break; 772 default: 773 *value = UINT_MAX; 774 break; 775 } 776 777 mutex_unlock(&smu->metrics_lock); 778 779 return ret; 780 } 781 782 static int navi12_get_smu_metrics_data(struct smu_context *smu, 783 MetricsMember_t member, 784 uint32_t *value) 785 { 786 struct smu_table_context *smu_table= &smu->smu_table; 787 SmuMetrics_NV12_t *metrics = 788 (SmuMetrics_NV12_t *)smu_table->metrics_table; 789 int ret = 0; 790 791 mutex_lock(&smu->metrics_lock); 792 793 ret = smu_cmn_get_metrics_table_locked(smu, 794 NULL, 795 false); 796 if (ret) { 797 mutex_unlock(&smu->metrics_lock); 798 return ret; 799 } 800 801 switch (member) { 802 case METRICS_CURR_GFXCLK: 803 *value = metrics->CurrClock[PPCLK_GFXCLK]; 804 break; 805 case METRICS_CURR_SOCCLK: 806 *value = metrics->CurrClock[PPCLK_SOCCLK]; 807 break; 808 case METRICS_CURR_UCLK: 809 *value = metrics->CurrClock[PPCLK_UCLK]; 810 break; 811 case METRICS_CURR_VCLK: 812 *value = metrics->CurrClock[PPCLK_VCLK]; 813 break; 814 case METRICS_CURR_DCLK: 815 *value = metrics->CurrClock[PPCLK_DCLK]; 816 break; 817 case METRICS_CURR_DCEFCLK: 818 *value = metrics->CurrClock[PPCLK_DCEFCLK]; 819 break; 820 case METRICS_AVERAGE_GFXCLK: 821 if (metrics->AverageGfxActivity > SMU_11_0_GFX_BUSY_THRESHOLD) 822 *value = metrics->AverageGfxclkFrequencyPreDs; 823 else 824 *value = metrics->AverageGfxclkFrequencyPostDs; 825 break; 826 case METRICS_AVERAGE_SOCCLK: 827 *value = metrics->AverageSocclkFrequency; 828 break; 829 case METRICS_AVERAGE_UCLK: 830 *value = metrics->AverageUclkFrequencyPostDs; 831 break; 832 case METRICS_AVERAGE_GFXACTIVITY: 833 *value = metrics->AverageGfxActivity; 834 break; 835 case METRICS_AVERAGE_MEMACTIVITY: 836 *value = metrics->AverageUclkActivity; 837 break; 838 case METRICS_AVERAGE_SOCKETPOWER: 839 *value = metrics->AverageSocketPower << 8; 840 break; 841 case METRICS_TEMPERATURE_EDGE: 842 *value = metrics->TemperatureEdge * 843 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 844 break; 845 case METRICS_TEMPERATURE_HOTSPOT: 846 *value = metrics->TemperatureHotspot * 847 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 848 break; 849 case METRICS_TEMPERATURE_MEM: 850 *value = metrics->TemperatureMem * 851 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 852 break; 853 case METRICS_TEMPERATURE_VRGFX: 854 *value = metrics->TemperatureVrGfx * 855 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 856 break; 857 case METRICS_TEMPERATURE_VRSOC: 858 *value = metrics->TemperatureVrSoc * 859 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 860 break; 861 case METRICS_THROTTLER_STATUS: 862 *value = metrics->ThrottlerStatus; 863 break; 864 case METRICS_CURR_FANSPEED: 865 *value = metrics->CurrFanSpeed; 866 break; 867 default: 868 *value = UINT_MAX; 869 break; 870 } 871 872 mutex_unlock(&smu->metrics_lock); 873 874 return ret; 875 } 876 877 static int navi1x_get_smu_metrics_data(struct smu_context *smu, 878 MetricsMember_t member, 879 uint32_t *value) 880 { 881 struct amdgpu_device *adev = smu->adev; 882 uint32_t smu_version; 883 int ret = 0; 884 885 ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); 886 if (ret) { 887 dev_err(adev->dev, "Failed to get smu version!\n"); 888 return ret; 889 } 890 891 switch (adev->asic_type) { 892 case CHIP_NAVI12: 893 if (smu_version > 0x00341C00) 894 ret = navi12_get_smu_metrics_data(smu, member, value); 895 else 896 ret = navi12_get_legacy_smu_metrics_data(smu, member, value); 897 break; 898 case CHIP_NAVI10: 899 case CHIP_NAVI14: 900 default: 901 if (((adev->asic_type == CHIP_NAVI14) && smu_version > 0x00351F00) || 902 ((adev->asic_type == CHIP_NAVI10) && smu_version > 0x002A3B00)) 903 ret = navi10_get_smu_metrics_data(smu, member, value); 904 else 905 ret = navi10_get_legacy_smu_metrics_data(smu, member, value); 906 break; 907 } 908 909 return ret; 910 } 911 912 static int navi10_allocate_dpm_context(struct smu_context *smu) 913 { 914 struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 915 916 smu_dpm->dpm_context = kzalloc(sizeof(struct smu_11_0_dpm_context), 917 GFP_KERNEL); 918 if (!smu_dpm->dpm_context) 919 return -ENOMEM; 920 921 smu_dpm->dpm_context_size = sizeof(struct smu_11_0_dpm_context); 922 923 return 0; 924 } 925 926 static int navi10_init_smc_tables(struct smu_context *smu) 927 { 928 int ret = 0; 929 930 ret = navi10_tables_init(smu); 931 if (ret) 932 return ret; 933 934 ret = navi10_allocate_dpm_context(smu); 935 if (ret) 936 return ret; 937 938 return smu_v11_0_init_smc_tables(smu); 939 } 940 941 static int navi10_set_default_dpm_table(struct smu_context *smu) 942 { 943 struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; 944 PPTable_t *driver_ppt = smu->smu_table.driver_pptable; 945 struct smu_11_0_dpm_table *dpm_table; 946 int ret = 0; 947 948 /* socclk dpm table setup */ 949 dpm_table = &dpm_context->dpm_tables.soc_table; 950 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) { 951 ret = smu_v11_0_set_single_dpm_table(smu, 952 SMU_SOCCLK, 953 dpm_table); 954 if (ret) 955 return ret; 956 dpm_table->is_fine_grained = 957 !driver_ppt->DpmDescriptor[PPCLK_SOCCLK].SnapToDiscrete; 958 } else { 959 dpm_table->count = 1; 960 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.socclk / 100; 961 dpm_table->dpm_levels[0].enabled = true; 962 dpm_table->min = dpm_table->dpm_levels[0].value; 963 dpm_table->max = dpm_table->dpm_levels[0].value; 964 } 965 966 /* gfxclk dpm table setup */ 967 dpm_table = &dpm_context->dpm_tables.gfx_table; 968 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_GFXCLK_BIT)) { 969 ret = smu_v11_0_set_single_dpm_table(smu, 970 SMU_GFXCLK, 971 dpm_table); 972 if (ret) 973 return ret; 974 dpm_table->is_fine_grained = 975 !driver_ppt->DpmDescriptor[PPCLK_GFXCLK].SnapToDiscrete; 976 } else { 977 dpm_table->count = 1; 978 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.gfxclk / 100; 979 dpm_table->dpm_levels[0].enabled = true; 980 dpm_table->min = dpm_table->dpm_levels[0].value; 981 dpm_table->max = dpm_table->dpm_levels[0].value; 982 } 983 984 /* uclk dpm table setup */ 985 dpm_table = &dpm_context->dpm_tables.uclk_table; 986 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) { 987 ret = smu_v11_0_set_single_dpm_table(smu, 988 SMU_UCLK, 989 dpm_table); 990 if (ret) 991 return ret; 992 dpm_table->is_fine_grained = 993 !driver_ppt->DpmDescriptor[PPCLK_UCLK].SnapToDiscrete; 994 } else { 995 dpm_table->count = 1; 996 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.uclk / 100; 997 dpm_table->dpm_levels[0].enabled = true; 998 dpm_table->min = dpm_table->dpm_levels[0].value; 999 dpm_table->max = dpm_table->dpm_levels[0].value; 1000 } 1001 1002 /* vclk dpm table setup */ 1003 dpm_table = &dpm_context->dpm_tables.vclk_table; 1004 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) { 1005 ret = smu_v11_0_set_single_dpm_table(smu, 1006 SMU_VCLK, 1007 dpm_table); 1008 if (ret) 1009 return ret; 1010 dpm_table->is_fine_grained = 1011 !driver_ppt->DpmDescriptor[PPCLK_VCLK].SnapToDiscrete; 1012 } else { 1013 dpm_table->count = 1; 1014 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.vclk / 100; 1015 dpm_table->dpm_levels[0].enabled = true; 1016 dpm_table->min = dpm_table->dpm_levels[0].value; 1017 dpm_table->max = dpm_table->dpm_levels[0].value; 1018 } 1019 1020 /* dclk dpm table setup */ 1021 dpm_table = &dpm_context->dpm_tables.dclk_table; 1022 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) { 1023 ret = smu_v11_0_set_single_dpm_table(smu, 1024 SMU_DCLK, 1025 dpm_table); 1026 if (ret) 1027 return ret; 1028 dpm_table->is_fine_grained = 1029 !driver_ppt->DpmDescriptor[PPCLK_DCLK].SnapToDiscrete; 1030 } else { 1031 dpm_table->count = 1; 1032 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dclk / 100; 1033 dpm_table->dpm_levels[0].enabled = true; 1034 dpm_table->min = dpm_table->dpm_levels[0].value; 1035 dpm_table->max = dpm_table->dpm_levels[0].value; 1036 } 1037 1038 /* dcefclk dpm table setup */ 1039 dpm_table = &dpm_context->dpm_tables.dcef_table; 1040 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) { 1041 ret = smu_v11_0_set_single_dpm_table(smu, 1042 SMU_DCEFCLK, 1043 dpm_table); 1044 if (ret) 1045 return ret; 1046 dpm_table->is_fine_grained = 1047 !driver_ppt->DpmDescriptor[PPCLK_DCEFCLK].SnapToDiscrete; 1048 } else { 1049 dpm_table->count = 1; 1050 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100; 1051 dpm_table->dpm_levels[0].enabled = true; 1052 dpm_table->min = dpm_table->dpm_levels[0].value; 1053 dpm_table->max = dpm_table->dpm_levels[0].value; 1054 } 1055 1056 /* pixelclk dpm table setup */ 1057 dpm_table = &dpm_context->dpm_tables.pixel_table; 1058 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) { 1059 ret = smu_v11_0_set_single_dpm_table(smu, 1060 SMU_PIXCLK, 1061 dpm_table); 1062 if (ret) 1063 return ret; 1064 dpm_table->is_fine_grained = 1065 !driver_ppt->DpmDescriptor[PPCLK_PIXCLK].SnapToDiscrete; 1066 } else { 1067 dpm_table->count = 1; 1068 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100; 1069 dpm_table->dpm_levels[0].enabled = true; 1070 dpm_table->min = dpm_table->dpm_levels[0].value; 1071 dpm_table->max = dpm_table->dpm_levels[0].value; 1072 } 1073 1074 /* displayclk dpm table setup */ 1075 dpm_table = &dpm_context->dpm_tables.display_table; 1076 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) { 1077 ret = smu_v11_0_set_single_dpm_table(smu, 1078 SMU_DISPCLK, 1079 dpm_table); 1080 if (ret) 1081 return ret; 1082 dpm_table->is_fine_grained = 1083 !driver_ppt->DpmDescriptor[PPCLK_DISPCLK].SnapToDiscrete; 1084 } else { 1085 dpm_table->count = 1; 1086 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100; 1087 dpm_table->dpm_levels[0].enabled = true; 1088 dpm_table->min = dpm_table->dpm_levels[0].value; 1089 dpm_table->max = dpm_table->dpm_levels[0].value; 1090 } 1091 1092 /* phyclk dpm table setup */ 1093 dpm_table = &dpm_context->dpm_tables.phy_table; 1094 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) { 1095 ret = smu_v11_0_set_single_dpm_table(smu, 1096 SMU_PHYCLK, 1097 dpm_table); 1098 if (ret) 1099 return ret; 1100 dpm_table->is_fine_grained = 1101 !driver_ppt->DpmDescriptor[PPCLK_PHYCLK].SnapToDiscrete; 1102 } else { 1103 dpm_table->count = 1; 1104 dpm_table->dpm_levels[0].value = smu->smu_table.boot_values.dcefclk / 100; 1105 dpm_table->dpm_levels[0].enabled = true; 1106 dpm_table->min = dpm_table->dpm_levels[0].value; 1107 dpm_table->max = dpm_table->dpm_levels[0].value; 1108 } 1109 1110 return 0; 1111 } 1112 1113 static int navi10_dpm_set_vcn_enable(struct smu_context *smu, bool enable) 1114 { 1115 int ret = 0; 1116 1117 if (enable) { 1118 /* vcn dpm on is a prerequisite for vcn power gate messages */ 1119 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) { 1120 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_PowerUpVcn, 1, NULL); 1121 if (ret) 1122 return ret; 1123 } 1124 } else { 1125 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_VCN_PG_BIT)) { 1126 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownVcn, NULL); 1127 if (ret) 1128 return ret; 1129 } 1130 } 1131 1132 return ret; 1133 } 1134 1135 static int navi10_dpm_set_jpeg_enable(struct smu_context *smu, bool enable) 1136 { 1137 int ret = 0; 1138 1139 if (enable) { 1140 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) { 1141 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerUpJpeg, NULL); 1142 if (ret) 1143 return ret; 1144 } 1145 } else { 1146 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_JPEG_PG_BIT)) { 1147 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_PowerDownJpeg, NULL); 1148 if (ret) 1149 return ret; 1150 } 1151 } 1152 1153 return ret; 1154 } 1155 1156 static int navi10_get_current_clk_freq_by_table(struct smu_context *smu, 1157 enum smu_clk_type clk_type, 1158 uint32_t *value) 1159 { 1160 MetricsMember_t member_type; 1161 int clk_id = 0; 1162 1163 clk_id = smu_cmn_to_asic_specific_index(smu, 1164 CMN2ASIC_MAPPING_CLK, 1165 clk_type); 1166 if (clk_id < 0) 1167 return clk_id; 1168 1169 switch (clk_id) { 1170 case PPCLK_GFXCLK: 1171 member_type = METRICS_CURR_GFXCLK; 1172 break; 1173 case PPCLK_UCLK: 1174 member_type = METRICS_CURR_UCLK; 1175 break; 1176 case PPCLK_SOCCLK: 1177 member_type = METRICS_CURR_SOCCLK; 1178 break; 1179 case PPCLK_VCLK: 1180 member_type = METRICS_CURR_VCLK; 1181 break; 1182 case PPCLK_DCLK: 1183 member_type = METRICS_CURR_DCLK; 1184 break; 1185 case PPCLK_DCEFCLK: 1186 member_type = METRICS_CURR_DCEFCLK; 1187 break; 1188 default: 1189 return -EINVAL; 1190 } 1191 1192 return navi1x_get_smu_metrics_data(smu, 1193 member_type, 1194 value); 1195 } 1196 1197 static bool navi10_is_support_fine_grained_dpm(struct smu_context *smu, enum smu_clk_type clk_type) 1198 { 1199 PPTable_t *pptable = smu->smu_table.driver_pptable; 1200 DpmDescriptor_t *dpm_desc = NULL; 1201 uint32_t clk_index = 0; 1202 1203 clk_index = smu_cmn_to_asic_specific_index(smu, 1204 CMN2ASIC_MAPPING_CLK, 1205 clk_type); 1206 dpm_desc = &pptable->DpmDescriptor[clk_index]; 1207 1208 /* 0 - Fine grained DPM, 1 - Discrete DPM */ 1209 return dpm_desc->SnapToDiscrete == 0; 1210 } 1211 1212 static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_table *od_table, enum SMU_11_0_ODFEATURE_CAP cap) 1213 { 1214 return od_table->cap[cap]; 1215 } 1216 1217 static void navi10_od_setting_get_range(struct smu_11_0_overdrive_table *od_table, 1218 enum SMU_11_0_ODSETTING_ID setting, 1219 uint32_t *min, uint32_t *max) 1220 { 1221 if (min) 1222 *min = od_table->min[setting]; 1223 if (max) 1224 *max = od_table->max[setting]; 1225 } 1226 1227 static int navi10_print_clk_levels(struct smu_context *smu, 1228 enum smu_clk_type clk_type, char *buf) 1229 { 1230 uint16_t *curve_settings; 1231 int i, size = 0, ret = 0; 1232 uint32_t cur_value = 0, value = 0, count = 0; 1233 uint32_t freq_values[3] = {0}; 1234 uint32_t mark_index = 0; 1235 struct smu_table_context *table_context = &smu->smu_table; 1236 uint32_t gen_speed, lane_width; 1237 struct smu_dpm_context *smu_dpm = &smu->smu_dpm; 1238 struct smu_11_0_dpm_context *dpm_context = smu_dpm->dpm_context; 1239 PPTable_t *pptable = (PPTable_t *)table_context->driver_pptable; 1240 OverDriveTable_t *od_table = 1241 (OverDriveTable_t *)table_context->overdrive_table; 1242 struct smu_11_0_overdrive_table *od_settings = smu->od_settings; 1243 uint32_t min_value, max_value; 1244 1245 switch (clk_type) { 1246 case SMU_GFXCLK: 1247 case SMU_SCLK: 1248 case SMU_SOCCLK: 1249 case SMU_MCLK: 1250 case SMU_UCLK: 1251 case SMU_FCLK: 1252 case SMU_DCEFCLK: 1253 ret = navi10_get_current_clk_freq_by_table(smu, clk_type, &cur_value); 1254 if (ret) 1255 return size; 1256 1257 ret = smu_v11_0_get_dpm_level_count(smu, clk_type, &count); 1258 if (ret) 1259 return size; 1260 1261 if (!navi10_is_support_fine_grained_dpm(smu, clk_type)) { 1262 for (i = 0; i < count; i++) { 1263 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &value); 1264 if (ret) 1265 return size; 1266 1267 size += sprintf(buf + size, "%d: %uMhz %s\n", i, value, 1268 cur_value == value ? "*" : ""); 1269 } 1270 } else { 1271 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, 0, &freq_values[0]); 1272 if (ret) 1273 return size; 1274 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, count - 1, &freq_values[2]); 1275 if (ret) 1276 return size; 1277 1278 freq_values[1] = cur_value; 1279 mark_index = cur_value == freq_values[0] ? 0 : 1280 cur_value == freq_values[2] ? 2 : 1; 1281 if (mark_index != 1) 1282 freq_values[1] = (freq_values[0] + freq_values[2]) / 2; 1283 1284 for (i = 0; i < 3; i++) { 1285 size += sprintf(buf + size, "%d: %uMhz %s\n", i, freq_values[i], 1286 i == mark_index ? "*" : ""); 1287 } 1288 1289 } 1290 break; 1291 case SMU_PCIE: 1292 gen_speed = smu_v11_0_get_current_pcie_link_speed_level(smu); 1293 lane_width = smu_v11_0_get_current_pcie_link_width_level(smu); 1294 for (i = 0; i < NUM_LINK_LEVELS; i++) 1295 size += sprintf(buf + size, "%d: %s %s %dMhz %s\n", i, 1296 (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 0) ? "2.5GT/s," : 1297 (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 1) ? "5.0GT/s," : 1298 (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 2) ? "8.0GT/s," : 1299 (dpm_context->dpm_tables.pcie_table.pcie_gen[i] == 3) ? "16.0GT/s," : "", 1300 (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 1) ? "x1" : 1301 (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 2) ? "x2" : 1302 (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 3) ? "x4" : 1303 (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 4) ? "x8" : 1304 (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 5) ? "x12" : 1305 (dpm_context->dpm_tables.pcie_table.pcie_lane[i] == 6) ? "x16" : "", 1306 pptable->LclkFreq[i], 1307 (gen_speed == dpm_context->dpm_tables.pcie_table.pcie_gen[i]) && 1308 (lane_width == dpm_context->dpm_tables.pcie_table.pcie_lane[i]) ? 1309 "*" : ""); 1310 break; 1311 case SMU_OD_SCLK: 1312 if (!smu->od_enabled || !od_table || !od_settings) 1313 break; 1314 if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_LIMITS)) 1315 break; 1316 size += sprintf(buf + size, "OD_SCLK:\n"); 1317 size += sprintf(buf + size, "0: %uMhz\n1: %uMhz\n", od_table->GfxclkFmin, od_table->GfxclkFmax); 1318 break; 1319 case SMU_OD_MCLK: 1320 if (!smu->od_enabled || !od_table || !od_settings) 1321 break; 1322 if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_UCLK_MAX)) 1323 break; 1324 size += sprintf(buf + size, "OD_MCLK:\n"); 1325 size += sprintf(buf + size, "1: %uMHz\n", od_table->UclkFmax); 1326 break; 1327 case SMU_OD_VDDC_CURVE: 1328 if (!smu->od_enabled || !od_table || !od_settings) 1329 break; 1330 if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_CURVE)) 1331 break; 1332 size += sprintf(buf + size, "OD_VDDC_CURVE:\n"); 1333 for (i = 0; i < 3; i++) { 1334 switch (i) { 1335 case 0: 1336 curve_settings = &od_table->GfxclkFreq1; 1337 break; 1338 case 1: 1339 curve_settings = &od_table->GfxclkFreq2; 1340 break; 1341 case 2: 1342 curve_settings = &od_table->GfxclkFreq3; 1343 break; 1344 default: 1345 break; 1346 } 1347 size += sprintf(buf + size, "%d: %uMHz %umV\n", i, curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE); 1348 } 1349 break; 1350 case SMU_OD_RANGE: 1351 if (!smu->od_enabled || !od_table || !od_settings) 1352 break; 1353 size = sprintf(buf, "%s:\n", "OD_RANGE"); 1354 1355 if (navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_LIMITS)) { 1356 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_GFXCLKFMIN, 1357 &min_value, NULL); 1358 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_GFXCLKFMAX, 1359 NULL, &max_value); 1360 size += sprintf(buf + size, "SCLK: %7uMhz %10uMhz\n", 1361 min_value, max_value); 1362 } 1363 1364 if (navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_UCLK_MAX)) { 1365 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_UCLKFMAX, 1366 &min_value, &max_value); 1367 size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n", 1368 min_value, max_value); 1369 } 1370 1371 if (navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_CURVE)) { 1372 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1, 1373 &min_value, &max_value); 1374 size += sprintf(buf + size, "VDDC_CURVE_SCLK[0]: %7uMhz %10uMhz\n", 1375 min_value, max_value); 1376 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1, 1377 &min_value, &max_value); 1378 size += sprintf(buf + size, "VDDC_CURVE_VOLT[0]: %7dmV %11dmV\n", 1379 min_value, max_value); 1380 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2, 1381 &min_value, &max_value); 1382 size += sprintf(buf + size, "VDDC_CURVE_SCLK[1]: %7uMhz %10uMhz\n", 1383 min_value, max_value); 1384 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2, 1385 &min_value, &max_value); 1386 size += sprintf(buf + size, "VDDC_CURVE_VOLT[1]: %7dmV %11dmV\n", 1387 min_value, max_value); 1388 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3, 1389 &min_value, &max_value); 1390 size += sprintf(buf + size, "VDDC_CURVE_SCLK[2]: %7uMhz %10uMhz\n", 1391 min_value, max_value); 1392 navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3, 1393 &min_value, &max_value); 1394 size += sprintf(buf + size, "VDDC_CURVE_VOLT[2]: %7dmV %11dmV\n", 1395 min_value, max_value); 1396 } 1397 1398 break; 1399 default: 1400 break; 1401 } 1402 1403 return size; 1404 } 1405 1406 static int navi10_force_clk_levels(struct smu_context *smu, 1407 enum smu_clk_type clk_type, uint32_t mask) 1408 { 1409 1410 int ret = 0, size = 0; 1411 uint32_t soft_min_level = 0, soft_max_level = 0, min_freq = 0, max_freq = 0; 1412 1413 soft_min_level = mask ? (ffs(mask) - 1) : 0; 1414 soft_max_level = mask ? (fls(mask) - 1) : 0; 1415 1416 switch (clk_type) { 1417 case SMU_GFXCLK: 1418 case SMU_SCLK: 1419 case SMU_SOCCLK: 1420 case SMU_MCLK: 1421 case SMU_UCLK: 1422 case SMU_DCEFCLK: 1423 case SMU_FCLK: 1424 /* There is only 2 levels for fine grained DPM */ 1425 if (navi10_is_support_fine_grained_dpm(smu, clk_type)) { 1426 soft_max_level = (soft_max_level >= 1 ? 1 : 0); 1427 soft_min_level = (soft_min_level >= 1 ? 1 : 0); 1428 } 1429 1430 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, soft_min_level, &min_freq); 1431 if (ret) 1432 return size; 1433 1434 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, soft_max_level, &max_freq); 1435 if (ret) 1436 return size; 1437 1438 ret = smu_v11_0_set_soft_freq_limited_range(smu, clk_type, min_freq, max_freq); 1439 if (ret) 1440 return size; 1441 break; 1442 default: 1443 break; 1444 } 1445 1446 return size; 1447 } 1448 1449 static int navi10_populate_umd_state_clk(struct smu_context *smu) 1450 { 1451 struct smu_11_0_dpm_context *dpm_context = 1452 smu->smu_dpm.dpm_context; 1453 struct smu_11_0_dpm_table *gfx_table = 1454 &dpm_context->dpm_tables.gfx_table; 1455 struct smu_11_0_dpm_table *mem_table = 1456 &dpm_context->dpm_tables.uclk_table; 1457 struct smu_11_0_dpm_table *soc_table = 1458 &dpm_context->dpm_tables.soc_table; 1459 struct smu_umd_pstate_table *pstate_table = 1460 &smu->pstate_table; 1461 struct amdgpu_device *adev = smu->adev; 1462 uint32_t sclk_freq; 1463 1464 pstate_table->gfxclk_pstate.min = gfx_table->min; 1465 switch (adev->asic_type) { 1466 case CHIP_NAVI10: 1467 switch (adev->pdev->revision) { 1468 case 0xf0: /* XTX */ 1469 case 0xc0: 1470 sclk_freq = NAVI10_PEAK_SCLK_XTX; 1471 break; 1472 case 0xf1: /* XT */ 1473 case 0xc1: 1474 sclk_freq = NAVI10_PEAK_SCLK_XT; 1475 break; 1476 default: /* XL */ 1477 sclk_freq = NAVI10_PEAK_SCLK_XL; 1478 break; 1479 } 1480 break; 1481 case CHIP_NAVI14: 1482 switch (adev->pdev->revision) { 1483 case 0xc7: /* XT */ 1484 case 0xf4: 1485 sclk_freq = NAVI14_UMD_PSTATE_PEAK_XT_GFXCLK; 1486 break; 1487 case 0xc1: /* XTM */ 1488 case 0xf2: 1489 sclk_freq = NAVI14_UMD_PSTATE_PEAK_XTM_GFXCLK; 1490 break; 1491 case 0xc3: /* XLM */ 1492 case 0xf3: 1493 sclk_freq = NAVI14_UMD_PSTATE_PEAK_XLM_GFXCLK; 1494 break; 1495 case 0xc5: /* XTX */ 1496 case 0xf6: 1497 sclk_freq = NAVI14_UMD_PSTATE_PEAK_XLM_GFXCLK; 1498 break; 1499 default: /* XL */ 1500 sclk_freq = NAVI14_UMD_PSTATE_PEAK_XL_GFXCLK; 1501 break; 1502 } 1503 break; 1504 case CHIP_NAVI12: 1505 sclk_freq = NAVI12_UMD_PSTATE_PEAK_GFXCLK; 1506 break; 1507 default: 1508 sclk_freq = gfx_table->dpm_levels[gfx_table->count - 1].value; 1509 break; 1510 } 1511 pstate_table->gfxclk_pstate.peak = sclk_freq; 1512 1513 pstate_table->uclk_pstate.min = mem_table->min; 1514 pstate_table->uclk_pstate.peak = mem_table->max; 1515 1516 pstate_table->socclk_pstate.min = soc_table->min; 1517 pstate_table->socclk_pstate.peak = soc_table->max; 1518 1519 if (gfx_table->max > NAVI10_UMD_PSTATE_PROFILING_GFXCLK && 1520 mem_table->max > NAVI10_UMD_PSTATE_PROFILING_MEMCLK && 1521 soc_table->max > NAVI10_UMD_PSTATE_PROFILING_SOCCLK) { 1522 pstate_table->gfxclk_pstate.standard = 1523 NAVI10_UMD_PSTATE_PROFILING_GFXCLK; 1524 pstate_table->uclk_pstate.standard = 1525 NAVI10_UMD_PSTATE_PROFILING_MEMCLK; 1526 pstate_table->socclk_pstate.standard = 1527 NAVI10_UMD_PSTATE_PROFILING_SOCCLK; 1528 } else { 1529 pstate_table->gfxclk_pstate.standard = 1530 pstate_table->gfxclk_pstate.min; 1531 pstate_table->uclk_pstate.standard = 1532 pstate_table->uclk_pstate.min; 1533 pstate_table->socclk_pstate.standard = 1534 pstate_table->socclk_pstate.min; 1535 } 1536 1537 return 0; 1538 } 1539 1540 static int navi10_get_clock_by_type_with_latency(struct smu_context *smu, 1541 enum smu_clk_type clk_type, 1542 struct pp_clock_levels_with_latency *clocks) 1543 { 1544 int ret = 0, i = 0; 1545 uint32_t level_count = 0, freq = 0; 1546 1547 switch (clk_type) { 1548 case SMU_GFXCLK: 1549 case SMU_DCEFCLK: 1550 case SMU_SOCCLK: 1551 case SMU_MCLK: 1552 case SMU_UCLK: 1553 ret = smu_v11_0_get_dpm_level_count(smu, clk_type, &level_count); 1554 if (ret) 1555 return ret; 1556 1557 level_count = min(level_count, (uint32_t)MAX_NUM_CLOCKS); 1558 clocks->num_levels = level_count; 1559 1560 for (i = 0; i < level_count; i++) { 1561 ret = smu_v11_0_get_dpm_freq_by_index(smu, clk_type, i, &freq); 1562 if (ret) 1563 return ret; 1564 1565 clocks->data[i].clocks_in_khz = freq * 1000; 1566 clocks->data[i].latency_in_us = 0; 1567 } 1568 break; 1569 default: 1570 break; 1571 } 1572 1573 return ret; 1574 } 1575 1576 static int navi10_pre_display_config_changed(struct smu_context *smu) 1577 { 1578 int ret = 0; 1579 uint32_t max_freq = 0; 1580 1581 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_NumOfDisplays, 0, NULL); 1582 if (ret) 1583 return ret; 1584 1585 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) { 1586 ret = smu_v11_0_get_dpm_ultimate_freq(smu, SMU_UCLK, NULL, &max_freq); 1587 if (ret) 1588 return ret; 1589 ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, 0, max_freq); 1590 if (ret) 1591 return ret; 1592 } 1593 1594 return ret; 1595 } 1596 1597 static int navi10_display_config_changed(struct smu_context *smu) 1598 { 1599 int ret = 0; 1600 1601 if ((smu->watermarks_bitmap & WATERMARKS_EXIST) && 1602 smu_cmn_feature_is_supported(smu, SMU_FEATURE_DPM_DCEFCLK_BIT) && 1603 smu_cmn_feature_is_supported(smu, SMU_FEATURE_DPM_SOCCLK_BIT)) { 1604 ret = smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_NumOfDisplays, 1605 smu->display_config->num_display, 1606 NULL); 1607 if (ret) 1608 return ret; 1609 } 1610 1611 return ret; 1612 } 1613 1614 static bool navi10_is_dpm_running(struct smu_context *smu) 1615 { 1616 int ret = 0; 1617 uint32_t feature_mask[2]; 1618 uint64_t feature_enabled; 1619 1620 ret = smu_cmn_get_enabled_mask(smu, feature_mask, 2); 1621 if (ret) 1622 return false; 1623 1624 feature_enabled = (uint64_t)feature_mask[1] << 32 | feature_mask[0]; 1625 1626 return !!(feature_enabled & SMC_DPM_FEATURE); 1627 } 1628 1629 static int navi10_get_fan_speed_percent(struct smu_context *smu, 1630 uint32_t *speed) 1631 { 1632 int ret; 1633 u32 rpm; 1634 1635 if (!speed) 1636 return -EINVAL; 1637 1638 switch (smu_v11_0_get_fan_control_mode(smu)) { 1639 case AMD_FAN_CTRL_AUTO: 1640 ret = navi1x_get_smu_metrics_data(smu, 1641 METRICS_CURR_FANSPEED, 1642 &rpm); 1643 if (!ret && smu->fan_max_rpm) 1644 *speed = rpm * 100 / smu->fan_max_rpm; 1645 return ret; 1646 default: 1647 *speed = smu->user_dpm_profile.fan_speed_percent; 1648 return 0; 1649 } 1650 } 1651 1652 static int navi10_get_fan_parameters(struct smu_context *smu) 1653 { 1654 PPTable_t *pptable = smu->smu_table.driver_pptable; 1655 1656 smu->fan_max_rpm = pptable->FanMaximumRpm; 1657 1658 return 0; 1659 } 1660 1661 static int navi10_get_power_profile_mode(struct smu_context *smu, char *buf) 1662 { 1663 DpmActivityMonitorCoeffInt_t activity_monitor; 1664 uint32_t i, size = 0; 1665 int16_t workload_type = 0; 1666 static const char *profile_name[] = { 1667 "BOOTUP_DEFAULT", 1668 "3D_FULL_SCREEN", 1669 "POWER_SAVING", 1670 "VIDEO", 1671 "VR", 1672 "COMPUTE", 1673 "CUSTOM"}; 1674 static const char *title[] = { 1675 "PROFILE_INDEX(NAME)", 1676 "CLOCK_TYPE(NAME)", 1677 "FPS", 1678 "MinFreqType", 1679 "MinActiveFreqType", 1680 "MinActiveFreq", 1681 "BoosterFreqType", 1682 "BoosterFreq", 1683 "PD_Data_limit_c", 1684 "PD_Data_error_coeff", 1685 "PD_Data_error_rate_coeff"}; 1686 int result = 0; 1687 1688 if (!buf) 1689 return -EINVAL; 1690 1691 size += sprintf(buf + size, "%16s %s %s %s %s %s %s %s %s %s %s\n", 1692 title[0], title[1], title[2], title[3], title[4], title[5], 1693 title[6], title[7], title[8], title[9], title[10]); 1694 1695 for (i = 0; i <= PP_SMC_POWER_PROFILE_CUSTOM; i++) { 1696 /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ 1697 workload_type = smu_cmn_to_asic_specific_index(smu, 1698 CMN2ASIC_MAPPING_WORKLOAD, 1699 i); 1700 if (workload_type < 0) 1701 return -EINVAL; 1702 1703 result = smu_cmn_update_table(smu, 1704 SMU_TABLE_ACTIVITY_MONITOR_COEFF, workload_type, 1705 (void *)(&activity_monitor), false); 1706 if (result) { 1707 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__); 1708 return result; 1709 } 1710 1711 size += sprintf(buf + size, "%2d %14s%s:\n", 1712 i, profile_name[i], (i == smu->power_profile_mode) ? "*" : " "); 1713 1714 size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n", 1715 " ", 1716 0, 1717 "GFXCLK", 1718 activity_monitor.Gfx_FPS, 1719 activity_monitor.Gfx_MinFreqStep, 1720 activity_monitor.Gfx_MinActiveFreqType, 1721 activity_monitor.Gfx_MinActiveFreq, 1722 activity_monitor.Gfx_BoosterFreqType, 1723 activity_monitor.Gfx_BoosterFreq, 1724 activity_monitor.Gfx_PD_Data_limit_c, 1725 activity_monitor.Gfx_PD_Data_error_coeff, 1726 activity_monitor.Gfx_PD_Data_error_rate_coeff); 1727 1728 size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n", 1729 " ", 1730 1, 1731 "SOCCLK", 1732 activity_monitor.Soc_FPS, 1733 activity_monitor.Soc_MinFreqStep, 1734 activity_monitor.Soc_MinActiveFreqType, 1735 activity_monitor.Soc_MinActiveFreq, 1736 activity_monitor.Soc_BoosterFreqType, 1737 activity_monitor.Soc_BoosterFreq, 1738 activity_monitor.Soc_PD_Data_limit_c, 1739 activity_monitor.Soc_PD_Data_error_coeff, 1740 activity_monitor.Soc_PD_Data_error_rate_coeff); 1741 1742 size += sprintf(buf + size, "%19s %d(%13s) %7d %7d %7d %7d %7d %7d %7d %7d %7d\n", 1743 " ", 1744 2, 1745 "MEMLK", 1746 activity_monitor.Mem_FPS, 1747 activity_monitor.Mem_MinFreqStep, 1748 activity_monitor.Mem_MinActiveFreqType, 1749 activity_monitor.Mem_MinActiveFreq, 1750 activity_monitor.Mem_BoosterFreqType, 1751 activity_monitor.Mem_BoosterFreq, 1752 activity_monitor.Mem_PD_Data_limit_c, 1753 activity_monitor.Mem_PD_Data_error_coeff, 1754 activity_monitor.Mem_PD_Data_error_rate_coeff); 1755 } 1756 1757 return size; 1758 } 1759 1760 static int navi10_set_power_profile_mode(struct smu_context *smu, long *input, uint32_t size) 1761 { 1762 DpmActivityMonitorCoeffInt_t activity_monitor; 1763 int workload_type, ret = 0; 1764 1765 smu->power_profile_mode = input[size]; 1766 1767 if (smu->power_profile_mode > PP_SMC_POWER_PROFILE_CUSTOM) { 1768 dev_err(smu->adev->dev, "Invalid power profile mode %d\n", smu->power_profile_mode); 1769 return -EINVAL; 1770 } 1771 1772 if (smu->power_profile_mode == PP_SMC_POWER_PROFILE_CUSTOM) { 1773 1774 ret = smu_cmn_update_table(smu, 1775 SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, 1776 (void *)(&activity_monitor), false); 1777 if (ret) { 1778 dev_err(smu->adev->dev, "[%s] Failed to get activity monitor!", __func__); 1779 return ret; 1780 } 1781 1782 switch (input[0]) { 1783 case 0: /* Gfxclk */ 1784 activity_monitor.Gfx_FPS = input[1]; 1785 activity_monitor.Gfx_MinFreqStep = input[2]; 1786 activity_monitor.Gfx_MinActiveFreqType = input[3]; 1787 activity_monitor.Gfx_MinActiveFreq = input[4]; 1788 activity_monitor.Gfx_BoosterFreqType = input[5]; 1789 activity_monitor.Gfx_BoosterFreq = input[6]; 1790 activity_monitor.Gfx_PD_Data_limit_c = input[7]; 1791 activity_monitor.Gfx_PD_Data_error_coeff = input[8]; 1792 activity_monitor.Gfx_PD_Data_error_rate_coeff = input[9]; 1793 break; 1794 case 1: /* Socclk */ 1795 activity_monitor.Soc_FPS = input[1]; 1796 activity_monitor.Soc_MinFreqStep = input[2]; 1797 activity_monitor.Soc_MinActiveFreqType = input[3]; 1798 activity_monitor.Soc_MinActiveFreq = input[4]; 1799 activity_monitor.Soc_BoosterFreqType = input[5]; 1800 activity_monitor.Soc_BoosterFreq = input[6]; 1801 activity_monitor.Soc_PD_Data_limit_c = input[7]; 1802 activity_monitor.Soc_PD_Data_error_coeff = input[8]; 1803 activity_monitor.Soc_PD_Data_error_rate_coeff = input[9]; 1804 break; 1805 case 2: /* Memlk */ 1806 activity_monitor.Mem_FPS = input[1]; 1807 activity_monitor.Mem_MinFreqStep = input[2]; 1808 activity_monitor.Mem_MinActiveFreqType = input[3]; 1809 activity_monitor.Mem_MinActiveFreq = input[4]; 1810 activity_monitor.Mem_BoosterFreqType = input[5]; 1811 activity_monitor.Mem_BoosterFreq = input[6]; 1812 activity_monitor.Mem_PD_Data_limit_c = input[7]; 1813 activity_monitor.Mem_PD_Data_error_coeff = input[8]; 1814 activity_monitor.Mem_PD_Data_error_rate_coeff = input[9]; 1815 break; 1816 } 1817 1818 ret = smu_cmn_update_table(smu, 1819 SMU_TABLE_ACTIVITY_MONITOR_COEFF, WORKLOAD_PPLIB_CUSTOM_BIT, 1820 (void *)(&activity_monitor), true); 1821 if (ret) { 1822 dev_err(smu->adev->dev, "[%s] Failed to set activity monitor!", __func__); 1823 return ret; 1824 } 1825 } 1826 1827 /* conv PP_SMC_POWER_PROFILE* to WORKLOAD_PPLIB_*_BIT */ 1828 workload_type = smu_cmn_to_asic_specific_index(smu, 1829 CMN2ASIC_MAPPING_WORKLOAD, 1830 smu->power_profile_mode); 1831 if (workload_type < 0) 1832 return -EINVAL; 1833 smu_cmn_send_smc_msg_with_param(smu, SMU_MSG_SetWorkloadMask, 1834 1 << workload_type, NULL); 1835 1836 return ret; 1837 } 1838 1839 static int navi10_notify_smc_display_config(struct smu_context *smu) 1840 { 1841 struct smu_clocks min_clocks = {0}; 1842 struct pp_display_clock_request clock_req; 1843 int ret = 0; 1844 1845 min_clocks.dcef_clock = smu->display_config->min_dcef_set_clk; 1846 min_clocks.dcef_clock_in_sr = smu->display_config->min_dcef_deep_sleep_set_clk; 1847 min_clocks.memory_clock = smu->display_config->min_mem_set_clock; 1848 1849 if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DPM_DCEFCLK_BIT)) { 1850 clock_req.clock_type = amd_pp_dcef_clock; 1851 clock_req.clock_freq_in_khz = min_clocks.dcef_clock * 10; 1852 1853 ret = smu_v11_0_display_clock_voltage_request(smu, &clock_req); 1854 if (!ret) { 1855 if (smu_cmn_feature_is_supported(smu, SMU_FEATURE_DS_DCEFCLK_BIT)) { 1856 ret = smu_cmn_send_smc_msg_with_param(smu, 1857 SMU_MSG_SetMinDeepSleepDcefclk, 1858 min_clocks.dcef_clock_in_sr/100, 1859 NULL); 1860 if (ret) { 1861 dev_err(smu->adev->dev, "Attempt to set divider for DCEFCLK Failed!"); 1862 return ret; 1863 } 1864 } 1865 } else { 1866 dev_info(smu->adev->dev, "Attempt to set Hard Min for DCEFCLK Failed!"); 1867 } 1868 } 1869 1870 if (smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) { 1871 ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, min_clocks.memory_clock/100, 0); 1872 if (ret) { 1873 dev_err(smu->adev->dev, "[%s] Set hard min uclk failed!", __func__); 1874 return ret; 1875 } 1876 } 1877 1878 return 0; 1879 } 1880 1881 static int navi10_set_watermarks_table(struct smu_context *smu, 1882 struct pp_smu_wm_range_sets *clock_ranges) 1883 { 1884 Watermarks_t *table = smu->smu_table.watermarks_table; 1885 int ret = 0; 1886 int i; 1887 1888 if (clock_ranges) { 1889 if (clock_ranges->num_reader_wm_sets > NUM_WM_RANGES || 1890 clock_ranges->num_writer_wm_sets > NUM_WM_RANGES) 1891 return -EINVAL; 1892 1893 for (i = 0; i < clock_ranges->num_reader_wm_sets; i++) { 1894 table->WatermarkRow[WM_DCEFCLK][i].MinClock = 1895 clock_ranges->reader_wm_sets[i].min_drain_clk_mhz; 1896 table->WatermarkRow[WM_DCEFCLK][i].MaxClock = 1897 clock_ranges->reader_wm_sets[i].max_drain_clk_mhz; 1898 table->WatermarkRow[WM_DCEFCLK][i].MinUclk = 1899 clock_ranges->reader_wm_sets[i].min_fill_clk_mhz; 1900 table->WatermarkRow[WM_DCEFCLK][i].MaxUclk = 1901 clock_ranges->reader_wm_sets[i].max_fill_clk_mhz; 1902 1903 table->WatermarkRow[WM_DCEFCLK][i].WmSetting = 1904 clock_ranges->reader_wm_sets[i].wm_inst; 1905 } 1906 1907 for (i = 0; i < clock_ranges->num_writer_wm_sets; i++) { 1908 table->WatermarkRow[WM_SOCCLK][i].MinClock = 1909 clock_ranges->writer_wm_sets[i].min_fill_clk_mhz; 1910 table->WatermarkRow[WM_SOCCLK][i].MaxClock = 1911 clock_ranges->writer_wm_sets[i].max_fill_clk_mhz; 1912 table->WatermarkRow[WM_SOCCLK][i].MinUclk = 1913 clock_ranges->writer_wm_sets[i].min_drain_clk_mhz; 1914 table->WatermarkRow[WM_SOCCLK][i].MaxUclk = 1915 clock_ranges->writer_wm_sets[i].max_drain_clk_mhz; 1916 1917 table->WatermarkRow[WM_SOCCLK][i].WmSetting = 1918 clock_ranges->writer_wm_sets[i].wm_inst; 1919 } 1920 1921 smu->watermarks_bitmap |= WATERMARKS_EXIST; 1922 } 1923 1924 /* pass data to smu controller */ 1925 if ((smu->watermarks_bitmap & WATERMARKS_EXIST) && 1926 !(smu->watermarks_bitmap & WATERMARKS_LOADED)) { 1927 ret = smu_cmn_write_watermarks_table(smu); 1928 if (ret) { 1929 dev_err(smu->adev->dev, "Failed to update WMTABLE!"); 1930 return ret; 1931 } 1932 smu->watermarks_bitmap |= WATERMARKS_LOADED; 1933 } 1934 1935 return 0; 1936 } 1937 1938 static int navi10_read_sensor(struct smu_context *smu, 1939 enum amd_pp_sensors sensor, 1940 void *data, uint32_t *size) 1941 { 1942 int ret = 0; 1943 struct smu_table_context *table_context = &smu->smu_table; 1944 PPTable_t *pptable = table_context->driver_pptable; 1945 1946 if(!data || !size) 1947 return -EINVAL; 1948 1949 mutex_lock(&smu->sensor_lock); 1950 switch (sensor) { 1951 case AMDGPU_PP_SENSOR_MAX_FAN_RPM: 1952 *(uint32_t *)data = pptable->FanMaximumRpm; 1953 *size = 4; 1954 break; 1955 case AMDGPU_PP_SENSOR_MEM_LOAD: 1956 ret = navi1x_get_smu_metrics_data(smu, 1957 METRICS_AVERAGE_MEMACTIVITY, 1958 (uint32_t *)data); 1959 *size = 4; 1960 break; 1961 case AMDGPU_PP_SENSOR_GPU_LOAD: 1962 ret = navi1x_get_smu_metrics_data(smu, 1963 METRICS_AVERAGE_GFXACTIVITY, 1964 (uint32_t *)data); 1965 *size = 4; 1966 break; 1967 case AMDGPU_PP_SENSOR_GPU_POWER: 1968 ret = navi1x_get_smu_metrics_data(smu, 1969 METRICS_AVERAGE_SOCKETPOWER, 1970 (uint32_t *)data); 1971 *size = 4; 1972 break; 1973 case AMDGPU_PP_SENSOR_HOTSPOT_TEMP: 1974 ret = navi1x_get_smu_metrics_data(smu, 1975 METRICS_TEMPERATURE_HOTSPOT, 1976 (uint32_t *)data); 1977 *size = 4; 1978 break; 1979 case AMDGPU_PP_SENSOR_EDGE_TEMP: 1980 ret = navi1x_get_smu_metrics_data(smu, 1981 METRICS_TEMPERATURE_EDGE, 1982 (uint32_t *)data); 1983 *size = 4; 1984 break; 1985 case AMDGPU_PP_SENSOR_MEM_TEMP: 1986 ret = navi1x_get_smu_metrics_data(smu, 1987 METRICS_TEMPERATURE_MEM, 1988 (uint32_t *)data); 1989 *size = 4; 1990 break; 1991 case AMDGPU_PP_SENSOR_GFX_MCLK: 1992 ret = navi10_get_current_clk_freq_by_table(smu, SMU_UCLK, (uint32_t *)data); 1993 *(uint32_t *)data *= 100; 1994 *size = 4; 1995 break; 1996 case AMDGPU_PP_SENSOR_GFX_SCLK: 1997 ret = navi1x_get_smu_metrics_data(smu, METRICS_AVERAGE_GFXCLK, (uint32_t *)data); 1998 *(uint32_t *)data *= 100; 1999 *size = 4; 2000 break; 2001 case AMDGPU_PP_SENSOR_VDDGFX: 2002 ret = smu_v11_0_get_gfx_vdd(smu, (uint32_t *)data); 2003 *size = 4; 2004 break; 2005 default: 2006 ret = -EOPNOTSUPP; 2007 break; 2008 } 2009 mutex_unlock(&smu->sensor_lock); 2010 2011 return ret; 2012 } 2013 2014 static int navi10_get_uclk_dpm_states(struct smu_context *smu, uint32_t *clocks_in_khz, uint32_t *num_states) 2015 { 2016 uint32_t num_discrete_levels = 0; 2017 uint16_t *dpm_levels = NULL; 2018 uint16_t i = 0; 2019 struct smu_table_context *table_context = &smu->smu_table; 2020 PPTable_t *driver_ppt = NULL; 2021 2022 if (!clocks_in_khz || !num_states || !table_context->driver_pptable) 2023 return -EINVAL; 2024 2025 driver_ppt = table_context->driver_pptable; 2026 num_discrete_levels = driver_ppt->DpmDescriptor[PPCLK_UCLK].NumDiscreteLevels; 2027 dpm_levels = driver_ppt->FreqTableUclk; 2028 2029 if (num_discrete_levels == 0 || dpm_levels == NULL) 2030 return -EINVAL; 2031 2032 *num_states = num_discrete_levels; 2033 for (i = 0; i < num_discrete_levels; i++) { 2034 /* convert to khz */ 2035 *clocks_in_khz = (*dpm_levels) * 1000; 2036 clocks_in_khz++; 2037 dpm_levels++; 2038 } 2039 2040 return 0; 2041 } 2042 2043 static int navi10_get_thermal_temperature_range(struct smu_context *smu, 2044 struct smu_temperature_range *range) 2045 { 2046 struct smu_table_context *table_context = &smu->smu_table; 2047 struct smu_11_0_powerplay_table *powerplay_table = 2048 table_context->power_play_table; 2049 PPTable_t *pptable = smu->smu_table.driver_pptable; 2050 2051 if (!range) 2052 return -EINVAL; 2053 2054 memcpy(range, &smu11_thermal_policy[0], sizeof(struct smu_temperature_range)); 2055 2056 range->max = pptable->TedgeLimit * 2057 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 2058 range->edge_emergency_max = (pptable->TedgeLimit + CTF_OFFSET_EDGE) * 2059 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 2060 range->hotspot_crit_max = pptable->ThotspotLimit * 2061 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 2062 range->hotspot_emergency_max = (pptable->ThotspotLimit + CTF_OFFSET_HOTSPOT) * 2063 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 2064 range->mem_crit_max = pptable->TmemLimit * 2065 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 2066 range->mem_emergency_max = (pptable->TmemLimit + CTF_OFFSET_MEM)* 2067 SMU_TEMPERATURE_UNITS_PER_CENTIGRADES; 2068 range->software_shutdown_temp = powerplay_table->software_shutdown_temp; 2069 2070 return 0; 2071 } 2072 2073 static int navi10_display_disable_memory_clock_switch(struct smu_context *smu, 2074 bool disable_memory_clock_switch) 2075 { 2076 int ret = 0; 2077 struct smu_11_0_max_sustainable_clocks *max_sustainable_clocks = 2078 (struct smu_11_0_max_sustainable_clocks *) 2079 smu->smu_table.max_sustainable_clocks; 2080 uint32_t min_memory_clock = smu->hard_min_uclk_req_from_dal; 2081 uint32_t max_memory_clock = max_sustainable_clocks->uclock; 2082 2083 if(smu->disable_uclk_switch == disable_memory_clock_switch) 2084 return 0; 2085 2086 if(disable_memory_clock_switch) 2087 ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, max_memory_clock, 0); 2088 else 2089 ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, min_memory_clock, 0); 2090 2091 if(!ret) 2092 smu->disable_uclk_switch = disable_memory_clock_switch; 2093 2094 return ret; 2095 } 2096 2097 static int navi10_get_power_limit(struct smu_context *smu) 2098 { 2099 struct smu_11_0_powerplay_table *powerplay_table = 2100 (struct smu_11_0_powerplay_table *)smu->smu_table.power_play_table; 2101 struct smu_11_0_overdrive_table *od_settings = smu->od_settings; 2102 PPTable_t *pptable = smu->smu_table.driver_pptable; 2103 uint32_t power_limit, od_percent; 2104 2105 if (smu_v11_0_get_current_power_limit(smu, &power_limit)) { 2106 /* the last hope to figure out the ppt limit */ 2107 if (!pptable) { 2108 dev_err(smu->adev->dev, "Cannot get PPT limit due to pptable missing!"); 2109 return -EINVAL; 2110 } 2111 power_limit = 2112 pptable->SocketPowerLimitAc[PPT_THROTTLER_PPT0]; 2113 } 2114 smu->current_power_limit = power_limit; 2115 2116 if (smu->od_enabled && 2117 navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_POWER_LIMIT)) { 2118 od_percent = le32_to_cpu(powerplay_table->overdrive_table.max[SMU_11_0_ODSETTING_POWERPERCENTAGE]); 2119 2120 dev_dbg(smu->adev->dev, "ODSETTING_POWERPERCENTAGE: %d (default: %d)\n", od_percent, power_limit); 2121 2122 power_limit *= (100 + od_percent); 2123 power_limit /= 100; 2124 } 2125 smu->max_power_limit = power_limit; 2126 2127 return 0; 2128 } 2129 2130 static int navi10_update_pcie_parameters(struct smu_context *smu, 2131 uint32_t pcie_gen_cap, 2132 uint32_t pcie_width_cap) 2133 { 2134 struct smu_11_0_dpm_context *dpm_context = smu->smu_dpm.dpm_context; 2135 PPTable_t *pptable = smu->smu_table.driver_pptable; 2136 uint32_t smu_pcie_arg; 2137 int ret, i; 2138 2139 /* lclk dpm table setup */ 2140 for (i = 0; i < MAX_PCIE_CONF; i++) { 2141 dpm_context->dpm_tables.pcie_table.pcie_gen[i] = pptable->PcieGenSpeed[i]; 2142 dpm_context->dpm_tables.pcie_table.pcie_lane[i] = pptable->PcieLaneCount[i]; 2143 } 2144 2145 for (i = 0; i < NUM_LINK_LEVELS; i++) { 2146 smu_pcie_arg = (i << 16) | 2147 ((pptable->PcieGenSpeed[i] <= pcie_gen_cap) ? (pptable->PcieGenSpeed[i] << 8) : 2148 (pcie_gen_cap << 8)) | ((pptable->PcieLaneCount[i] <= pcie_width_cap) ? 2149 pptable->PcieLaneCount[i] : pcie_width_cap); 2150 ret = smu_cmn_send_smc_msg_with_param(smu, 2151 SMU_MSG_OverridePcieParameters, 2152 smu_pcie_arg, 2153 NULL); 2154 2155 if (ret) 2156 return ret; 2157 2158 if (pptable->PcieGenSpeed[i] > pcie_gen_cap) 2159 dpm_context->dpm_tables.pcie_table.pcie_gen[i] = pcie_gen_cap; 2160 if (pptable->PcieLaneCount[i] > pcie_width_cap) 2161 dpm_context->dpm_tables.pcie_table.pcie_lane[i] = pcie_width_cap; 2162 } 2163 2164 return 0; 2165 } 2166 2167 static inline void navi10_dump_od_table(struct smu_context *smu, 2168 OverDriveTable_t *od_table) 2169 { 2170 dev_dbg(smu->adev->dev, "OD: Gfxclk: (%d, %d)\n", od_table->GfxclkFmin, od_table->GfxclkFmax); 2171 dev_dbg(smu->adev->dev, "OD: Gfx1: (%d, %d)\n", od_table->GfxclkFreq1, od_table->GfxclkVolt1); 2172 dev_dbg(smu->adev->dev, "OD: Gfx2: (%d, %d)\n", od_table->GfxclkFreq2, od_table->GfxclkVolt2); 2173 dev_dbg(smu->adev->dev, "OD: Gfx3: (%d, %d)\n", od_table->GfxclkFreq3, od_table->GfxclkVolt3); 2174 dev_dbg(smu->adev->dev, "OD: UclkFmax: %d\n", od_table->UclkFmax); 2175 dev_dbg(smu->adev->dev, "OD: OverDrivePct: %d\n", od_table->OverDrivePct); 2176 } 2177 2178 static int navi10_od_setting_check_range(struct smu_context *smu, 2179 struct smu_11_0_overdrive_table *od_table, 2180 enum SMU_11_0_ODSETTING_ID setting, 2181 uint32_t value) 2182 { 2183 if (value < od_table->min[setting]) { 2184 dev_warn(smu->adev->dev, "OD setting (%d, %d) is less than the minimum allowed (%d)\n", setting, value, od_table->min[setting]); 2185 return -EINVAL; 2186 } 2187 if (value > od_table->max[setting]) { 2188 dev_warn(smu->adev->dev, "OD setting (%d, %d) is greater than the maximum allowed (%d)\n", setting, value, od_table->max[setting]); 2189 return -EINVAL; 2190 } 2191 return 0; 2192 } 2193 2194 static int navi10_overdrive_get_gfx_clk_base_voltage(struct smu_context *smu, 2195 uint16_t *voltage, 2196 uint32_t freq) 2197 { 2198 uint32_t param = (freq & 0xFFFF) | (PPCLK_GFXCLK << 16); 2199 uint32_t value = 0; 2200 int ret; 2201 2202 ret = smu_cmn_send_smc_msg_with_param(smu, 2203 SMU_MSG_GetVoltageByDpm, 2204 param, 2205 &value); 2206 if (ret) { 2207 dev_err(smu->adev->dev, "[GetBaseVoltage] failed to get GFXCLK AVFS voltage from SMU!"); 2208 return ret; 2209 } 2210 2211 *voltage = (uint16_t)value; 2212 2213 return 0; 2214 } 2215 2216 static bool navi10_is_baco_supported(struct smu_context *smu) 2217 { 2218 struct amdgpu_device *adev = smu->adev; 2219 uint32_t val; 2220 2221 if (amdgpu_sriov_vf(adev) || (!smu_v11_0_baco_is_support(smu))) 2222 return false; 2223 2224 val = RREG32_SOC15(NBIO, 0, mmRCC_BIF_STRAP0); 2225 return (val & RCC_BIF_STRAP0__STRAP_PX_CAPABLE_MASK) ? true : false; 2226 } 2227 2228 static int navi10_set_default_od_settings(struct smu_context *smu) 2229 { 2230 OverDriveTable_t *od_table = 2231 (OverDriveTable_t *)smu->smu_table.overdrive_table; 2232 OverDriveTable_t *boot_od_table = 2233 (OverDriveTable_t *)smu->smu_table.boot_overdrive_table; 2234 int ret = 0; 2235 2236 ret = smu_cmn_update_table(smu, SMU_TABLE_OVERDRIVE, 0, (void *)od_table, false); 2237 if (ret) { 2238 dev_err(smu->adev->dev, "Failed to get overdrive table!\n"); 2239 return ret; 2240 } 2241 2242 if (!od_table->GfxclkVolt1) { 2243 ret = navi10_overdrive_get_gfx_clk_base_voltage(smu, 2244 &od_table->GfxclkVolt1, 2245 od_table->GfxclkFreq1); 2246 if (ret) 2247 return ret; 2248 } 2249 2250 if (!od_table->GfxclkVolt2) { 2251 ret = navi10_overdrive_get_gfx_clk_base_voltage(smu, 2252 &od_table->GfxclkVolt2, 2253 od_table->GfxclkFreq2); 2254 if (ret) 2255 return ret; 2256 } 2257 2258 if (!od_table->GfxclkVolt3) { 2259 ret = navi10_overdrive_get_gfx_clk_base_voltage(smu, 2260 &od_table->GfxclkVolt3, 2261 od_table->GfxclkFreq3); 2262 if (ret) 2263 return ret; 2264 } 2265 2266 memcpy(boot_od_table, od_table, sizeof(OverDriveTable_t)); 2267 2268 navi10_dump_od_table(smu, od_table); 2269 2270 return 0; 2271 } 2272 2273 static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABLE_COMMAND type, long input[], uint32_t size) { 2274 int i; 2275 int ret = 0; 2276 struct smu_table_context *table_context = &smu->smu_table; 2277 OverDriveTable_t *od_table; 2278 struct smu_11_0_overdrive_table *od_settings; 2279 enum SMU_11_0_ODSETTING_ID freq_setting, voltage_setting; 2280 uint16_t *freq_ptr, *voltage_ptr; 2281 od_table = (OverDriveTable_t *)table_context->overdrive_table; 2282 2283 if (!smu->od_enabled) { 2284 dev_warn(smu->adev->dev, "OverDrive is not enabled!\n"); 2285 return -EINVAL; 2286 } 2287 2288 if (!smu->od_settings) { 2289 dev_err(smu->adev->dev, "OD board limits are not set!\n"); 2290 return -ENOENT; 2291 } 2292 2293 od_settings = smu->od_settings; 2294 2295 switch (type) { 2296 case PP_OD_EDIT_SCLK_VDDC_TABLE: 2297 if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_LIMITS)) { 2298 dev_warn(smu->adev->dev, "GFXCLK_LIMITS not supported!\n"); 2299 return -ENOTSUPP; 2300 } 2301 if (!table_context->overdrive_table) { 2302 dev_err(smu->adev->dev, "Overdrive is not initialized\n"); 2303 return -EINVAL; 2304 } 2305 for (i = 0; i < size; i += 2) { 2306 if (i + 2 > size) { 2307 dev_info(smu->adev->dev, "invalid number of input parameters %d\n", size); 2308 return -EINVAL; 2309 } 2310 switch (input[i]) { 2311 case 0: 2312 freq_setting = SMU_11_0_ODSETTING_GFXCLKFMIN; 2313 freq_ptr = &od_table->GfxclkFmin; 2314 if (input[i + 1] > od_table->GfxclkFmax) { 2315 dev_info(smu->adev->dev, "GfxclkFmin (%ld) must be <= GfxclkFmax (%u)!\n", 2316 input[i + 1], 2317 od_table->GfxclkFmin); 2318 return -EINVAL; 2319 } 2320 break; 2321 case 1: 2322 freq_setting = SMU_11_0_ODSETTING_GFXCLKFMAX; 2323 freq_ptr = &od_table->GfxclkFmax; 2324 if (input[i + 1] < od_table->GfxclkFmin) { 2325 dev_info(smu->adev->dev, "GfxclkFmax (%ld) must be >= GfxclkFmin (%u)!\n", 2326 input[i + 1], 2327 od_table->GfxclkFmax); 2328 return -EINVAL; 2329 } 2330 break; 2331 default: 2332 dev_info(smu->adev->dev, "Invalid SCLK_VDDC_TABLE index: %ld\n", input[i]); 2333 dev_info(smu->adev->dev, "Supported indices: [0:min,1:max]\n"); 2334 return -EINVAL; 2335 } 2336 ret = navi10_od_setting_check_range(smu, od_settings, freq_setting, input[i + 1]); 2337 if (ret) 2338 return ret; 2339 *freq_ptr = input[i + 1]; 2340 } 2341 break; 2342 case PP_OD_EDIT_MCLK_VDDC_TABLE: 2343 if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_UCLK_MAX)) { 2344 dev_warn(smu->adev->dev, "UCLK_MAX not supported!\n"); 2345 return -ENOTSUPP; 2346 } 2347 if (size < 2) { 2348 dev_info(smu->adev->dev, "invalid number of parameters: %d\n", size); 2349 return -EINVAL; 2350 } 2351 if (input[0] != 1) { 2352 dev_info(smu->adev->dev, "Invalid MCLK_VDDC_TABLE index: %ld\n", input[0]); 2353 dev_info(smu->adev->dev, "Supported indices: [1:max]\n"); 2354 return -EINVAL; 2355 } 2356 ret = navi10_od_setting_check_range(smu, od_settings, SMU_11_0_ODSETTING_UCLKFMAX, input[1]); 2357 if (ret) 2358 return ret; 2359 od_table->UclkFmax = input[1]; 2360 break; 2361 case PP_OD_RESTORE_DEFAULT_TABLE: 2362 if (!(table_context->overdrive_table && table_context->boot_overdrive_table)) { 2363 dev_err(smu->adev->dev, "Overdrive table was not initialized!\n"); 2364 return -EINVAL; 2365 } 2366 memcpy(table_context->overdrive_table, table_context->boot_overdrive_table, sizeof(OverDriveTable_t)); 2367 break; 2368 case PP_OD_COMMIT_DPM_TABLE: 2369 navi10_dump_od_table(smu, od_table); 2370 ret = smu_cmn_update_table(smu, SMU_TABLE_OVERDRIVE, 0, (void *)od_table, true); 2371 if (ret) { 2372 dev_err(smu->adev->dev, "Failed to import overdrive table!\n"); 2373 return ret; 2374 } 2375 break; 2376 case PP_OD_EDIT_VDDC_CURVE: 2377 if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODCAP_GFXCLK_CURVE)) { 2378 dev_warn(smu->adev->dev, "GFXCLK_CURVE not supported!\n"); 2379 return -ENOTSUPP; 2380 } 2381 if (size < 3) { 2382 dev_info(smu->adev->dev, "invalid number of parameters: %d\n", size); 2383 return -EINVAL; 2384 } 2385 if (!od_table) { 2386 dev_info(smu->adev->dev, "Overdrive is not initialized\n"); 2387 return -EINVAL; 2388 } 2389 2390 switch (input[0]) { 2391 case 0: 2392 freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1; 2393 voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1; 2394 freq_ptr = &od_table->GfxclkFreq1; 2395 voltage_ptr = &od_table->GfxclkVolt1; 2396 break; 2397 case 1: 2398 freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2; 2399 voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2; 2400 freq_ptr = &od_table->GfxclkFreq2; 2401 voltage_ptr = &od_table->GfxclkVolt2; 2402 break; 2403 case 2: 2404 freq_setting = SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3; 2405 voltage_setting = SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3; 2406 freq_ptr = &od_table->GfxclkFreq3; 2407 voltage_ptr = &od_table->GfxclkVolt3; 2408 break; 2409 default: 2410 dev_info(smu->adev->dev, "Invalid VDDC_CURVE index: %ld\n", input[0]); 2411 dev_info(smu->adev->dev, "Supported indices: [0, 1, 2]\n"); 2412 return -EINVAL; 2413 } 2414 ret = navi10_od_setting_check_range(smu, od_settings, freq_setting, input[1]); 2415 if (ret) 2416 return ret; 2417 // Allow setting zero to disable the OverDrive VDDC curve 2418 if (input[2] != 0) { 2419 ret = navi10_od_setting_check_range(smu, od_settings, voltage_setting, input[2]); 2420 if (ret) 2421 return ret; 2422 *freq_ptr = input[1]; 2423 *voltage_ptr = ((uint16_t)input[2]) * NAVI10_VOLTAGE_SCALE; 2424 dev_dbg(smu->adev->dev, "OD: set curve %ld: (%d, %d)\n", input[0], *freq_ptr, *voltage_ptr); 2425 } else { 2426 // If setting 0, disable all voltage curve settings 2427 od_table->GfxclkVolt1 = 0; 2428 od_table->GfxclkVolt2 = 0; 2429 od_table->GfxclkVolt3 = 0; 2430 } 2431 navi10_dump_od_table(smu, od_table); 2432 break; 2433 default: 2434 return -ENOSYS; 2435 } 2436 return ret; 2437 } 2438 2439 static int navi10_run_btc(struct smu_context *smu) 2440 { 2441 int ret = 0; 2442 2443 ret = smu_cmn_send_smc_msg(smu, SMU_MSG_RunBtc, NULL); 2444 if (ret) 2445 dev_err(smu->adev->dev, "RunBtc failed!\n"); 2446 2447 return ret; 2448 } 2449 2450 static bool navi10_need_umc_cdr_workaround(struct smu_context *smu) 2451 { 2452 struct amdgpu_device *adev = smu->adev; 2453 2454 if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) 2455 return false; 2456 2457 if (adev->asic_type == CHIP_NAVI10 || 2458 adev->asic_type == CHIP_NAVI14) 2459 return true; 2460 2461 return false; 2462 } 2463 2464 static int navi10_umc_hybrid_cdr_workaround(struct smu_context *smu) 2465 { 2466 uint32_t uclk_count, uclk_min, uclk_max; 2467 int ret = 0; 2468 2469 /* This workaround can be applied only with uclk dpm enabled */ 2470 if (!smu_cmn_feature_is_enabled(smu, SMU_FEATURE_DPM_UCLK_BIT)) 2471 return 0; 2472 2473 ret = smu_v11_0_get_dpm_level_count(smu, SMU_UCLK, &uclk_count); 2474 if (ret) 2475 return ret; 2476 2477 ret = smu_v11_0_get_dpm_freq_by_index(smu, SMU_UCLK, (uint16_t)(uclk_count - 1), &uclk_max); 2478 if (ret) 2479 return ret; 2480 2481 /* 2482 * The NAVI10_UMC_HYBRID_CDR_WORKAROUND_UCLK_THRESHOLD is 750Mhz. 2483 * This workaround is needed only when the max uclk frequency 2484 * not greater than that. 2485 */ 2486 if (uclk_max > 0x2EE) 2487 return 0; 2488 2489 ret = smu_v11_0_get_dpm_freq_by_index(smu, SMU_UCLK, (uint16_t)0, &uclk_min); 2490 if (ret) 2491 return ret; 2492 2493 /* Force UCLK out of the highest DPM */ 2494 ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, 0, uclk_min); 2495 if (ret) 2496 return ret; 2497 2498 /* Revert the UCLK Hardmax */ 2499 ret = smu_v11_0_set_hard_freq_limited_range(smu, SMU_UCLK, 0, uclk_max); 2500 if (ret) 2501 return ret; 2502 2503 /* 2504 * In this case, SMU already disabled dummy pstate during enablement 2505 * of UCLK DPM, we have to re-enabled it. 2506 */ 2507 return smu_cmn_send_smc_msg(smu, SMU_MSG_DAL_ENABLE_DUMMY_PSTATE_CHANGE, NULL); 2508 } 2509 2510 static int navi10_set_dummy_pstates_table_location(struct smu_context *smu) 2511 { 2512 struct smu_table_context *smu_table = &smu->smu_table; 2513 struct smu_table *dummy_read_table = 2514 &smu_table->dummy_read_1_table; 2515 char *dummy_table = dummy_read_table->cpu_addr; 2516 int ret = 0; 2517 uint32_t i; 2518 2519 for (i = 0; i < 0x40000; i += 0x1000 * 2) { 2520 memcpy(dummy_table, &NoDbiPrbs7[0], 0x1000); 2521 dummy_table += 0x1000; 2522 memcpy(dummy_table, &DbiPrbs7[0], 0x1000); 2523 dummy_table += 0x1000; 2524 } 2525 2526 amdgpu_asic_flush_hdp(smu->adev, NULL); 2527 2528 ret = smu_cmn_send_smc_msg_with_param(smu, 2529 SMU_MSG_SET_DRIVER_DUMMY_TABLE_DRAM_ADDR_HIGH, 2530 upper_32_bits(dummy_read_table->mc_address), 2531 NULL); 2532 if (ret) 2533 return ret; 2534 2535 return smu_cmn_send_smc_msg_with_param(smu, 2536 SMU_MSG_SET_DRIVER_DUMMY_TABLE_DRAM_ADDR_LOW, 2537 lower_32_bits(dummy_read_table->mc_address), 2538 NULL); 2539 } 2540 2541 static int navi10_run_umc_cdr_workaround(struct smu_context *smu) 2542 { 2543 struct amdgpu_device *adev = smu->adev; 2544 uint8_t umc_fw_greater_than_v136 = false; 2545 uint8_t umc_fw_disable_cdr = false; 2546 uint32_t pmfw_version; 2547 uint32_t param; 2548 int ret = 0; 2549 2550 if (!navi10_need_umc_cdr_workaround(smu)) 2551 return 0; 2552 2553 ret = smu_cmn_get_smc_version(smu, NULL, &pmfw_version); 2554 if (ret) { 2555 dev_err(adev->dev, "Failed to get smu version!\n"); 2556 return ret; 2557 } 2558 2559 /* 2560 * The messages below are only supported by Navi10 42.53.0 and later 2561 * PMFWs and Navi14 53.29.0 and later PMFWs. 2562 * - PPSMC_MSG_SetDriverDummyTableDramAddrHigh 2563 * - PPSMC_MSG_SetDriverDummyTableDramAddrLow 2564 * - PPSMC_MSG_GetUMCFWWA 2565 */ 2566 if (((adev->asic_type == CHIP_NAVI10) && (pmfw_version >= 0x2a3500)) || 2567 ((adev->asic_type == CHIP_NAVI14) && (pmfw_version >= 0x351D00))) { 2568 ret = smu_cmn_send_smc_msg_with_param(smu, 2569 SMU_MSG_GET_UMC_FW_WA, 2570 0, 2571 ¶m); 2572 if (ret) 2573 return ret; 2574 2575 /* First bit indicates if the UMC f/w is above v137 */ 2576 umc_fw_greater_than_v136 = param & 0x1; 2577 2578 /* Second bit indicates if hybrid-cdr is disabled */ 2579 umc_fw_disable_cdr = param & 0x2; 2580 2581 /* w/a only allowed if UMC f/w is <= 136 */ 2582 if (umc_fw_greater_than_v136) 2583 return 0; 2584 2585 if (umc_fw_disable_cdr) { 2586 if (adev->asic_type == CHIP_NAVI10) 2587 return navi10_umc_hybrid_cdr_workaround(smu); 2588 } else { 2589 return navi10_set_dummy_pstates_table_location(smu); 2590 } 2591 } else { 2592 if (adev->asic_type == CHIP_NAVI10) 2593 return navi10_umc_hybrid_cdr_workaround(smu); 2594 } 2595 2596 return 0; 2597 } 2598 2599 static ssize_t navi10_get_legacy_gpu_metrics(struct smu_context *smu, 2600 void **table) 2601 { 2602 struct smu_table_context *smu_table = &smu->smu_table; 2603 struct gpu_metrics_v1_1 *gpu_metrics = 2604 (struct gpu_metrics_v1_1 *)smu_table->gpu_metrics_table; 2605 SmuMetrics_legacy_t metrics; 2606 int ret = 0; 2607 2608 mutex_lock(&smu->metrics_lock); 2609 2610 ret = smu_cmn_get_metrics_table_locked(smu, 2611 NULL, 2612 true); 2613 if (ret) { 2614 mutex_unlock(&smu->metrics_lock); 2615 return ret; 2616 } 2617 2618 memcpy(&metrics, smu_table->metrics_table, sizeof(SmuMetrics_legacy_t)); 2619 2620 mutex_unlock(&smu->metrics_lock); 2621 2622 smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 1); 2623 2624 gpu_metrics->temperature_edge = metrics.TemperatureEdge; 2625 gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot; 2626 gpu_metrics->temperature_mem = metrics.TemperatureMem; 2627 gpu_metrics->temperature_vrgfx = metrics.TemperatureVrGfx; 2628 gpu_metrics->temperature_vrsoc = metrics.TemperatureVrSoc; 2629 gpu_metrics->temperature_vrmem = metrics.TemperatureVrMem0; 2630 2631 gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity; 2632 gpu_metrics->average_umc_activity = metrics.AverageUclkActivity; 2633 2634 gpu_metrics->average_socket_power = metrics.AverageSocketPower; 2635 2636 gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequency; 2637 gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency; 2638 gpu_metrics->average_uclk_frequency = metrics.AverageUclkFrequency; 2639 2640 gpu_metrics->current_gfxclk = metrics.CurrClock[PPCLK_GFXCLK]; 2641 gpu_metrics->current_socclk = metrics.CurrClock[PPCLK_SOCCLK]; 2642 gpu_metrics->current_uclk = metrics.CurrClock[PPCLK_UCLK]; 2643 gpu_metrics->current_vclk0 = metrics.CurrClock[PPCLK_VCLK]; 2644 gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK]; 2645 2646 gpu_metrics->throttle_status = metrics.ThrottlerStatus; 2647 2648 gpu_metrics->current_fan_speed = metrics.CurrFanSpeed; 2649 2650 gpu_metrics->pcie_link_width = 2651 smu_v11_0_get_current_pcie_link_width(smu); 2652 gpu_metrics->pcie_link_speed = 2653 smu_v11_0_get_current_pcie_link_speed(smu); 2654 2655 gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); 2656 2657 *table = (void *)gpu_metrics; 2658 2659 return sizeof(struct gpu_metrics_v1_1); 2660 } 2661 2662 static ssize_t navi10_get_gpu_metrics(struct smu_context *smu, 2663 void **table) 2664 { 2665 struct smu_table_context *smu_table = &smu->smu_table; 2666 struct gpu_metrics_v1_1 *gpu_metrics = 2667 (struct gpu_metrics_v1_1 *)smu_table->gpu_metrics_table; 2668 SmuMetrics_t metrics; 2669 int ret = 0; 2670 2671 mutex_lock(&smu->metrics_lock); 2672 2673 ret = smu_cmn_get_metrics_table_locked(smu, 2674 NULL, 2675 true); 2676 if (ret) { 2677 mutex_unlock(&smu->metrics_lock); 2678 return ret; 2679 } 2680 2681 memcpy(&metrics, smu_table->metrics_table, sizeof(SmuMetrics_t)); 2682 2683 mutex_unlock(&smu->metrics_lock); 2684 2685 smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 1); 2686 2687 gpu_metrics->temperature_edge = metrics.TemperatureEdge; 2688 gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot; 2689 gpu_metrics->temperature_mem = metrics.TemperatureMem; 2690 gpu_metrics->temperature_vrgfx = metrics.TemperatureVrGfx; 2691 gpu_metrics->temperature_vrsoc = metrics.TemperatureVrSoc; 2692 gpu_metrics->temperature_vrmem = metrics.TemperatureVrMem0; 2693 2694 gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity; 2695 gpu_metrics->average_umc_activity = metrics.AverageUclkActivity; 2696 2697 gpu_metrics->average_socket_power = metrics.AverageSocketPower; 2698 2699 if (metrics.AverageGfxActivity > SMU_11_0_GFX_BUSY_THRESHOLD) 2700 gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequencyPreDs; 2701 else 2702 gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequencyPostDs; 2703 2704 gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency; 2705 gpu_metrics->average_uclk_frequency = metrics.AverageUclkFrequencyPostDs; 2706 2707 gpu_metrics->current_gfxclk = metrics.CurrClock[PPCLK_GFXCLK]; 2708 gpu_metrics->current_socclk = metrics.CurrClock[PPCLK_SOCCLK]; 2709 gpu_metrics->current_uclk = metrics.CurrClock[PPCLK_UCLK]; 2710 gpu_metrics->current_vclk0 = metrics.CurrClock[PPCLK_VCLK]; 2711 gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK]; 2712 2713 gpu_metrics->throttle_status = metrics.ThrottlerStatus; 2714 2715 gpu_metrics->current_fan_speed = metrics.CurrFanSpeed; 2716 2717 gpu_metrics->pcie_link_width = metrics.PcieWidth; 2718 gpu_metrics->pcie_link_speed = link_speed[metrics.PcieRate]; 2719 2720 gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); 2721 2722 *table = (void *)gpu_metrics; 2723 2724 return sizeof(struct gpu_metrics_v1_1); 2725 } 2726 2727 static ssize_t navi12_get_legacy_gpu_metrics(struct smu_context *smu, 2728 void **table) 2729 { 2730 struct smu_table_context *smu_table = &smu->smu_table; 2731 struct gpu_metrics_v1_1 *gpu_metrics = 2732 (struct gpu_metrics_v1_1 *)smu_table->gpu_metrics_table; 2733 SmuMetrics_NV12_legacy_t metrics; 2734 int ret = 0; 2735 2736 mutex_lock(&smu->metrics_lock); 2737 2738 ret = smu_cmn_get_metrics_table_locked(smu, 2739 NULL, 2740 true); 2741 if (ret) { 2742 mutex_unlock(&smu->metrics_lock); 2743 return ret; 2744 } 2745 2746 memcpy(&metrics, smu_table->metrics_table, sizeof(SmuMetrics_NV12_legacy_t)); 2747 2748 mutex_unlock(&smu->metrics_lock); 2749 2750 smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 1); 2751 2752 gpu_metrics->temperature_edge = metrics.TemperatureEdge; 2753 gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot; 2754 gpu_metrics->temperature_mem = metrics.TemperatureMem; 2755 gpu_metrics->temperature_vrgfx = metrics.TemperatureVrGfx; 2756 gpu_metrics->temperature_vrsoc = metrics.TemperatureVrSoc; 2757 gpu_metrics->temperature_vrmem = metrics.TemperatureVrMem0; 2758 2759 gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity; 2760 gpu_metrics->average_umc_activity = metrics.AverageUclkActivity; 2761 2762 gpu_metrics->average_socket_power = metrics.AverageSocketPower; 2763 2764 gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequency; 2765 gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency; 2766 gpu_metrics->average_uclk_frequency = metrics.AverageUclkFrequency; 2767 2768 gpu_metrics->energy_accumulator = metrics.EnergyAccumulator; 2769 gpu_metrics->average_vclk0_frequency = metrics.AverageVclkFrequency; 2770 gpu_metrics->average_dclk0_frequency = metrics.AverageDclkFrequency; 2771 gpu_metrics->average_mm_activity = metrics.VcnActivityPercentage; 2772 2773 gpu_metrics->current_gfxclk = metrics.CurrClock[PPCLK_GFXCLK]; 2774 gpu_metrics->current_socclk = metrics.CurrClock[PPCLK_SOCCLK]; 2775 gpu_metrics->current_uclk = metrics.CurrClock[PPCLK_UCLK]; 2776 gpu_metrics->current_vclk0 = metrics.CurrClock[PPCLK_VCLK]; 2777 gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK]; 2778 2779 gpu_metrics->throttle_status = metrics.ThrottlerStatus; 2780 2781 gpu_metrics->current_fan_speed = metrics.CurrFanSpeed; 2782 2783 gpu_metrics->pcie_link_width = 2784 smu_v11_0_get_current_pcie_link_width(smu); 2785 gpu_metrics->pcie_link_speed = 2786 smu_v11_0_get_current_pcie_link_speed(smu); 2787 2788 gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); 2789 2790 *table = (void *)gpu_metrics; 2791 2792 return sizeof(struct gpu_metrics_v1_1); 2793 } 2794 2795 static ssize_t navi12_get_gpu_metrics(struct smu_context *smu, 2796 void **table) 2797 { 2798 struct smu_table_context *smu_table = &smu->smu_table; 2799 struct gpu_metrics_v1_1 *gpu_metrics = 2800 (struct gpu_metrics_v1_1 *)smu_table->gpu_metrics_table; 2801 SmuMetrics_NV12_t metrics; 2802 int ret = 0; 2803 2804 mutex_lock(&smu->metrics_lock); 2805 2806 ret = smu_cmn_get_metrics_table_locked(smu, 2807 NULL, 2808 true); 2809 if (ret) { 2810 mutex_unlock(&smu->metrics_lock); 2811 return ret; 2812 } 2813 2814 memcpy(&metrics, smu_table->metrics_table, sizeof(SmuMetrics_NV12_t)); 2815 2816 mutex_unlock(&smu->metrics_lock); 2817 2818 smu_cmn_init_soft_gpu_metrics(gpu_metrics, 1, 1); 2819 2820 gpu_metrics->temperature_edge = metrics.TemperatureEdge; 2821 gpu_metrics->temperature_hotspot = metrics.TemperatureHotspot; 2822 gpu_metrics->temperature_mem = metrics.TemperatureMem; 2823 gpu_metrics->temperature_vrgfx = metrics.TemperatureVrGfx; 2824 gpu_metrics->temperature_vrsoc = metrics.TemperatureVrSoc; 2825 gpu_metrics->temperature_vrmem = metrics.TemperatureVrMem0; 2826 2827 gpu_metrics->average_gfx_activity = metrics.AverageGfxActivity; 2828 gpu_metrics->average_umc_activity = metrics.AverageUclkActivity; 2829 2830 gpu_metrics->average_socket_power = metrics.AverageSocketPower; 2831 2832 if (metrics.AverageGfxActivity > SMU_11_0_GFX_BUSY_THRESHOLD) 2833 gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequencyPreDs; 2834 else 2835 gpu_metrics->average_gfxclk_frequency = metrics.AverageGfxclkFrequencyPostDs; 2836 2837 gpu_metrics->average_socclk_frequency = metrics.AverageSocclkFrequency; 2838 gpu_metrics->average_uclk_frequency = metrics.AverageUclkFrequencyPostDs; 2839 2840 gpu_metrics->energy_accumulator = metrics.EnergyAccumulator; 2841 gpu_metrics->average_vclk0_frequency = metrics.AverageVclkFrequency; 2842 gpu_metrics->average_dclk0_frequency = metrics.AverageDclkFrequency; 2843 gpu_metrics->average_mm_activity = metrics.VcnActivityPercentage; 2844 2845 gpu_metrics->current_gfxclk = metrics.CurrClock[PPCLK_GFXCLK]; 2846 gpu_metrics->current_socclk = metrics.CurrClock[PPCLK_SOCCLK]; 2847 gpu_metrics->current_uclk = metrics.CurrClock[PPCLK_UCLK]; 2848 gpu_metrics->current_vclk0 = metrics.CurrClock[PPCLK_VCLK]; 2849 gpu_metrics->current_dclk0 = metrics.CurrClock[PPCLK_DCLK]; 2850 2851 gpu_metrics->throttle_status = metrics.ThrottlerStatus; 2852 2853 gpu_metrics->current_fan_speed = metrics.CurrFanSpeed; 2854 2855 gpu_metrics->pcie_link_width = metrics.PcieWidth; 2856 gpu_metrics->pcie_link_speed = link_speed[metrics.PcieRate]; 2857 2858 gpu_metrics->system_clock_counter = ktime_get_boottime_ns(); 2859 2860 *table = (void *)gpu_metrics; 2861 2862 return sizeof(struct gpu_metrics_v1_1); 2863 } 2864 2865 static ssize_t navi1x_get_gpu_metrics(struct smu_context *smu, 2866 void **table) 2867 { 2868 struct amdgpu_device *adev = smu->adev; 2869 uint32_t smu_version; 2870 int ret = 0; 2871 2872 ret = smu_cmn_get_smc_version(smu, NULL, &smu_version); 2873 if (ret) { 2874 dev_err(adev->dev, "Failed to get smu version!\n"); 2875 return ret; 2876 } 2877 2878 switch (adev->asic_type) { 2879 case CHIP_NAVI12: 2880 if (smu_version > 0x00341C00) 2881 ret = navi12_get_gpu_metrics(smu, table); 2882 else 2883 ret = navi12_get_legacy_gpu_metrics(smu, table); 2884 break; 2885 case CHIP_NAVI10: 2886 case CHIP_NAVI14: 2887 default: 2888 if (((adev->asic_type == CHIP_NAVI14) && smu_version > 0x00351F00) || 2889 ((adev->asic_type == CHIP_NAVI10) && smu_version > 0x002A3B00)) 2890 ret = navi10_get_gpu_metrics(smu, table); 2891 else 2892 ret =navi10_get_legacy_gpu_metrics(smu, table); 2893 break; 2894 } 2895 2896 return ret; 2897 } 2898 2899 static int navi10_enable_mgpu_fan_boost(struct smu_context *smu) 2900 { 2901 struct amdgpu_device *adev = smu->adev; 2902 uint32_t param = 0; 2903 2904 /* Navi12 does not support this */ 2905 if (adev->asic_type == CHIP_NAVI12) 2906 return 0; 2907 2908 /* Workaround for WS SKU */ 2909 if (adev->pdev->device == 0x7312 && 2910 adev->pdev->revision == 0) 2911 param = 0xD188; 2912 2913 return smu_cmn_send_smc_msg_with_param(smu, 2914 SMU_MSG_SetMGpuFanBoostLimitRpm, 2915 param, 2916 NULL); 2917 } 2918 2919 static int navi10_post_smu_init(struct smu_context *smu) 2920 { 2921 struct amdgpu_device *adev = smu->adev; 2922 int ret = 0; 2923 2924 if (amdgpu_sriov_vf(adev)) 2925 return 0; 2926 2927 ret = navi10_run_umc_cdr_workaround(smu); 2928 if (ret) { 2929 dev_err(adev->dev, "Failed to apply umc cdr workaround!\n"); 2930 return ret; 2931 } 2932 2933 if (!smu->dc_controlled_by_gpio) { 2934 /* 2935 * For Navi1X, manually switch it to AC mode as PMFW 2936 * may boot it with DC mode. 2937 */ 2938 ret = smu_v11_0_set_power_source(smu, 2939 adev->pm.ac_power ? 2940 SMU_POWER_SOURCE_AC : 2941 SMU_POWER_SOURCE_DC); 2942 if (ret) { 2943 dev_err(adev->dev, "Failed to switch to %s mode!\n", 2944 adev->pm.ac_power ? "AC" : "DC"); 2945 return ret; 2946 } 2947 } 2948 2949 return ret; 2950 } 2951 2952 static const struct pptable_funcs navi10_ppt_funcs = { 2953 .get_allowed_feature_mask = navi10_get_allowed_feature_mask, 2954 .set_default_dpm_table = navi10_set_default_dpm_table, 2955 .dpm_set_vcn_enable = navi10_dpm_set_vcn_enable, 2956 .dpm_set_jpeg_enable = navi10_dpm_set_jpeg_enable, 2957 .print_clk_levels = navi10_print_clk_levels, 2958 .force_clk_levels = navi10_force_clk_levels, 2959 .populate_umd_state_clk = navi10_populate_umd_state_clk, 2960 .get_clock_by_type_with_latency = navi10_get_clock_by_type_with_latency, 2961 .pre_display_config_changed = navi10_pre_display_config_changed, 2962 .display_config_changed = navi10_display_config_changed, 2963 .notify_smc_display_config = navi10_notify_smc_display_config, 2964 .is_dpm_running = navi10_is_dpm_running, 2965 .get_fan_speed_percent = navi10_get_fan_speed_percent, 2966 .get_power_profile_mode = navi10_get_power_profile_mode, 2967 .set_power_profile_mode = navi10_set_power_profile_mode, 2968 .set_watermarks_table = navi10_set_watermarks_table, 2969 .read_sensor = navi10_read_sensor, 2970 .get_uclk_dpm_states = navi10_get_uclk_dpm_states, 2971 .set_performance_level = smu_v11_0_set_performance_level, 2972 .get_thermal_temperature_range = navi10_get_thermal_temperature_range, 2973 .display_disable_memory_clock_switch = navi10_display_disable_memory_clock_switch, 2974 .get_power_limit = navi10_get_power_limit, 2975 .update_pcie_parameters = navi10_update_pcie_parameters, 2976 .init_microcode = smu_v11_0_init_microcode, 2977 .load_microcode = smu_v11_0_load_microcode, 2978 .fini_microcode = smu_v11_0_fini_microcode, 2979 .init_smc_tables = navi10_init_smc_tables, 2980 .fini_smc_tables = smu_v11_0_fini_smc_tables, 2981 .init_power = smu_v11_0_init_power, 2982 .fini_power = smu_v11_0_fini_power, 2983 .check_fw_status = smu_v11_0_check_fw_status, 2984 .setup_pptable = navi10_setup_pptable, 2985 .get_vbios_bootup_values = smu_v11_0_get_vbios_bootup_values, 2986 .check_fw_version = smu_v11_0_check_fw_version, 2987 .write_pptable = smu_cmn_write_pptable, 2988 .set_driver_table_location = smu_v11_0_set_driver_table_location, 2989 .set_tool_table_location = smu_v11_0_set_tool_table_location, 2990 .notify_memory_pool_location = smu_v11_0_notify_memory_pool_location, 2991 .system_features_control = smu_v11_0_system_features_control, 2992 .send_smc_msg_with_param = smu_cmn_send_smc_msg_with_param, 2993 .send_smc_msg = smu_cmn_send_smc_msg, 2994 .init_display_count = smu_v11_0_init_display_count, 2995 .set_allowed_mask = smu_v11_0_set_allowed_mask, 2996 .get_enabled_mask = smu_cmn_get_enabled_mask, 2997 .feature_is_enabled = smu_cmn_feature_is_enabled, 2998 .disable_all_features_with_exception = smu_cmn_disable_all_features_with_exception, 2999 .notify_display_change = smu_v11_0_notify_display_change, 3000 .set_power_limit = smu_v11_0_set_power_limit, 3001 .init_max_sustainable_clocks = smu_v11_0_init_max_sustainable_clocks, 3002 .enable_thermal_alert = smu_v11_0_enable_thermal_alert, 3003 .disable_thermal_alert = smu_v11_0_disable_thermal_alert, 3004 .set_min_dcef_deep_sleep = smu_v11_0_set_min_deep_sleep_dcefclk, 3005 .display_clock_voltage_request = smu_v11_0_display_clock_voltage_request, 3006 .get_fan_control_mode = smu_v11_0_get_fan_control_mode, 3007 .set_fan_control_mode = smu_v11_0_set_fan_control_mode, 3008 .set_fan_speed_percent = smu_v11_0_set_fan_speed_percent, 3009 .set_xgmi_pstate = smu_v11_0_set_xgmi_pstate, 3010 .gfx_off_control = smu_v11_0_gfx_off_control, 3011 .register_irq_handler = smu_v11_0_register_irq_handler, 3012 .set_azalia_d3_pme = smu_v11_0_set_azalia_d3_pme, 3013 .get_max_sustainable_clocks_by_dc = smu_v11_0_get_max_sustainable_clocks_by_dc, 3014 .baco_is_support= navi10_is_baco_supported, 3015 .baco_get_state = smu_v11_0_baco_get_state, 3016 .baco_set_state = smu_v11_0_baco_set_state, 3017 .baco_enter = smu_v11_0_baco_enter, 3018 .baco_exit = smu_v11_0_baco_exit, 3019 .get_dpm_ultimate_freq = smu_v11_0_get_dpm_ultimate_freq, 3020 .set_soft_freq_limited_range = smu_v11_0_set_soft_freq_limited_range, 3021 .set_default_od_settings = navi10_set_default_od_settings, 3022 .od_edit_dpm_table = navi10_od_edit_dpm_table, 3023 .run_btc = navi10_run_btc, 3024 .set_power_source = smu_v11_0_set_power_source, 3025 .get_pp_feature_mask = smu_cmn_get_pp_feature_mask, 3026 .set_pp_feature_mask = smu_cmn_set_pp_feature_mask, 3027 .get_gpu_metrics = navi1x_get_gpu_metrics, 3028 .enable_mgpu_fan_boost = navi10_enable_mgpu_fan_boost, 3029 .gfx_ulv_control = smu_v11_0_gfx_ulv_control, 3030 .deep_sleep_control = smu_v11_0_deep_sleep_control, 3031 .get_fan_parameters = navi10_get_fan_parameters, 3032 .post_init = navi10_post_smu_init, 3033 .interrupt_work = smu_v11_0_interrupt_work, 3034 }; 3035 3036 void navi10_set_ppt_funcs(struct smu_context *smu) 3037 { 3038 smu->ppt_funcs = &navi10_ppt_funcs; 3039 smu->message_map = navi10_message_map; 3040 smu->clock_map = navi10_clk_map; 3041 smu->feature_map = navi10_feature_mask_map; 3042 smu->table_map = navi10_table_map; 3043 smu->pwr_src_map = navi10_pwr_src_map; 3044 smu->workload_map = navi10_workload_map; 3045 } 3046