diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/ci_dpm.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/ci_dpm.c | 443 |
1 files changed, 219 insertions, 224 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c index 1f9109d3348b..e2f0e5d58d5c 100644 --- a/drivers/gpu/drm/amd/amdgpu/ci_dpm.c +++ b/drivers/gpu/drm/amd/amdgpu/ci_dpm.c @@ -50,7 +50,9 @@ #include "gmc/gmc_7_1_sh_mask.h" MODULE_FIRMWARE("radeon/bonaire_smc.bin"); +MODULE_FIRMWARE("radeon/bonaire_k_smc.bin"); MODULE_FIRMWARE("radeon/hawaii_smc.bin"); +MODULE_FIRMWARE("radeon/hawaii_k_smc.bin"); #define MC_CG_ARB_FREQ_F0 0x0a #define MC_CG_ARB_FREQ_F1 0x0b @@ -84,12 +86,14 @@ static const struct ci_pt_defaults defaults_bonaire_xt = { 0x17C, 0x172, 0x180, 0x1BC, 0x1B3, 0x1BD, 0x206, 0x200, 0x203, 0x25D, 0x25A, 0x255, 0x2C3, 0x2C5, 0x2B4 } }; +#if 0 static const struct ci_pt_defaults defaults_bonaire_pro = { 1, 0xF, 0xFD, 0x19, 5, 45, 0, 0x65062, { 0x8C, 0x23F, 0x244, 0xA6, 0x83, 0x85, 0x86, 0x86, 0x83, 0xDB, 0xDB, 0xDA, 0x67, 0x60, 0x5F }, { 0x187, 0x193, 0x193, 0x1C7, 0x1D1, 0x1D1, 0x210, 0x219, 0x219, 0x266, 0x26C, 0x26C, 0x2C9, 0x2CB, 0x2CB } }; +#endif static const struct ci_pt_defaults defaults_saturn_xt = { @@ -98,12 +102,14 @@ static const struct ci_pt_defaults defaults_saturn_xt = { 0x187, 0x187, 0x187, 0x1C7, 0x1C7, 0x1C7, 0x210, 0x210, 0x210, 0x266, 0x266, 0x266, 0x2C9, 0x2C9, 0x2C9 } }; +#if 0 static const struct ci_pt_defaults defaults_saturn_pro = { 1, 0xF, 0xFD, 0x19, 5, 55, 0, 0x30000, { 0x96, 0x21D, 0x23B, 0xA1, 0x85, 0x87, 0x83, 0x84, 0x81, 0xE6, 0xE6, 0xE6, 0x71, 0x6A, 0x6A }, { 0x193, 0x19E, 0x19E, 0x1D2, 0x1DC, 0x1DC, 0x21A, 0x223, 0x223, 0x26E, 0x27E, 0x274, 0x2CF, 0x2D2, 0x2D2 } }; +#endif static const struct ci_pt_config_reg didt_config_ci[] = { @@ -736,19 +742,19 @@ static int ci_enable_didt(struct amdgpu_device *adev, bool enable) if (pi->caps_sq_ramping || pi->caps_db_ramping || pi->caps_td_ramping || pi->caps_tcp_ramping) { - gfx_v7_0_enter_rlc_safe_mode(adev); + adev->gfx.rlc.funcs->enter_safe_mode(adev); if (enable) { ret = ci_program_pt_config_registers(adev, didt_config_ci); if (ret) { - gfx_v7_0_exit_rlc_safe_mode(adev); + adev->gfx.rlc.funcs->exit_safe_mode(adev); return ret; } } ci_do_enable_didt(adev, enable); - gfx_v7_0_exit_rlc_safe_mode(adev); + adev->gfx.rlc.funcs->exit_safe_mode(adev); } return 0; @@ -2549,19 +2555,17 @@ static int ci_get_dependency_volt_by_clk(struct amdgpu_device *adev, return 0; } -static u8 ci_get_sleep_divider_id_from_clock(struct amdgpu_device *adev, - u32 sclk, u32 min_sclk_in_sr) +static u8 ci_get_sleep_divider_id_from_clock(u32 sclk, u32 min_sclk_in_sr) { u32 i; u32 tmp; - u32 min = (min_sclk_in_sr > CISLAND_MINIMUM_ENGINE_CLOCK) ? - min_sclk_in_sr : CISLAND_MINIMUM_ENGINE_CLOCK; + u32 min = max(min_sclk_in_sr, (u32)CISLAND_MINIMUM_ENGINE_CLOCK); if (sclk < min) return 0; for (i = CISLAND_MAX_DEEPSLEEP_DIVIDER_ID; ; i--) { - tmp = sclk / (1 << i); + tmp = sclk >> i; if (tmp >= min || i == 0) break; } @@ -3032,7 +3036,7 @@ static int ci_populate_single_memory_level(struct amdgpu_device *adev, if (pi->mclk_stutter_mode_threshold && (memory_clock <= pi->mclk_stutter_mode_threshold) && - (pi->uvd_enabled == false) && + (!pi->uvd_enabled) && (RREG32(mmDPG_PIPE_STUTTER_CONTROL) & DPG_PIPE_STUTTER_CONTROL__STUTTER_ENABLE_MASK) && (adev->pm.dpm.new_active_crtc_count <= 2)) memory_level->StutterEnable = true; @@ -3358,8 +3362,7 @@ static int ci_populate_single_graphic_level(struct amdgpu_device *adev, graphic_level->PowerThrottle = 0; if (pi->caps_sclk_ds) - graphic_level->DeepSleepDivId = ci_get_sleep_divider_id_from_clock(adev, - engine_clock, + graphic_level->DeepSleepDivId = ci_get_sleep_divider_id_from_clock(engine_clock, CISLAND_MINIMUM_ENGINE_CLOCK); graphic_level->DisplayWatermark = PPSMC_DISPLAY_WATERMARK_LOW; @@ -3639,6 +3642,10 @@ static int ci_setup_default_dpm_tables(struct amdgpu_device *adev) ci_setup_default_pcie_tables(adev); + /* save a copy of the default DPM table */ + memcpy(&(pi->golden_dpm_table), &(pi->dpm_table), + sizeof(struct ci_dpm_table)); + return 0; } @@ -5757,10 +5764,18 @@ static int ci_dpm_init_microcode(struct amdgpu_device *adev) switch (adev->asic_type) { case CHIP_BONAIRE: - chip_name = "bonaire"; + if ((adev->pdev->revision == 0x80) || + (adev->pdev->revision == 0x81) || + (adev->pdev->device == 0x665f)) + chip_name = "bonaire_k"; + else + chip_name = "bonaire"; break; case CHIP_HAWAII: - chip_name = "hawaii"; + if (adev->pdev->revision == 0x80) + chip_name = "hawaii_k"; + else + chip_name = "hawaii"; break; case CHIP_KAVERI: case CHIP_KABINI: @@ -6224,6 +6239,9 @@ static int ci_dpm_sw_fini(void *handle) ci_dpm_fini(adev); mutex_unlock(&adev->pm.mutex); + release_firmware(adev->pm.fw); + adev->pm.fw = NULL; + return 0; } @@ -6309,215 +6327,6 @@ static int ci_dpm_wait_for_idle(void *handle) return 0; } -static void ci_dpm_print_status(void *handle) -{ - struct amdgpu_device *adev = (struct amdgpu_device *)handle; - - dev_info(adev->dev, "CIK DPM registers\n"); - dev_info(adev->dev, " BIOS_SCRATCH_4=0x%08X\n", - RREG32(mmBIOS_SCRATCH_4)); - dev_info(adev->dev, " MC_ARB_DRAM_TIMING=0x%08X\n", - RREG32(mmMC_ARB_DRAM_TIMING)); - dev_info(adev->dev, " MC_ARB_DRAM_TIMING2=0x%08X\n", - RREG32(mmMC_ARB_DRAM_TIMING2)); - dev_info(adev->dev, " MC_ARB_BURST_TIME=0x%08X\n", - RREG32(mmMC_ARB_BURST_TIME)); - dev_info(adev->dev, " MC_ARB_DRAM_TIMING_1=0x%08X\n", - RREG32(mmMC_ARB_DRAM_TIMING_1)); - dev_info(adev->dev, " MC_ARB_DRAM_TIMING2_1=0x%08X\n", - RREG32(mmMC_ARB_DRAM_TIMING2_1)); - dev_info(adev->dev, " MC_CG_CONFIG=0x%08X\n", - RREG32(mmMC_CG_CONFIG)); - dev_info(adev->dev, " MC_ARB_CG=0x%08X\n", - RREG32(mmMC_ARB_CG)); - dev_info(adev->dev, " DIDT_SQ_CTRL0=0x%08X\n", - RREG32_DIDT(ixDIDT_SQ_CTRL0)); - dev_info(adev->dev, " DIDT_DB_CTRL0=0x%08X\n", - RREG32_DIDT(ixDIDT_DB_CTRL0)); - dev_info(adev->dev, " DIDT_TD_CTRL0=0x%08X\n", - RREG32_DIDT(ixDIDT_TD_CTRL0)); - dev_info(adev->dev, " DIDT_TCP_CTRL0=0x%08X\n", - RREG32_DIDT(ixDIDT_TCP_CTRL0)); - dev_info(adev->dev, " CG_THERMAL_INT=0x%08X\n", - RREG32_SMC(ixCG_THERMAL_INT)); - dev_info(adev->dev, " CG_THERMAL_CTRL=0x%08X\n", - RREG32_SMC(ixCG_THERMAL_CTRL)); - dev_info(adev->dev, " GENERAL_PWRMGT=0x%08X\n", - RREG32_SMC(ixGENERAL_PWRMGT)); - dev_info(adev->dev, " MC_SEQ_CNTL_3=0x%08X\n", - RREG32(mmMC_SEQ_CNTL_3)); - dev_info(adev->dev, " LCAC_MC0_CNTL=0x%08X\n", - RREG32_SMC(ixLCAC_MC0_CNTL)); - dev_info(adev->dev, " LCAC_MC1_CNTL=0x%08X\n", - RREG32_SMC(ixLCAC_MC1_CNTL)); - dev_info(adev->dev, " LCAC_CPL_CNTL=0x%08X\n", - RREG32_SMC(ixLCAC_CPL_CNTL)); - dev_info(adev->dev, " SCLK_PWRMGT_CNTL=0x%08X\n", - RREG32_SMC(ixSCLK_PWRMGT_CNTL)); - dev_info(adev->dev, " BIF_LNCNT_RESET=0x%08X\n", - RREG32(mmBIF_LNCNT_RESET)); - dev_info(adev->dev, " FIRMWARE_FLAGS=0x%08X\n", - RREG32_SMC(ixFIRMWARE_FLAGS)); - dev_info(adev->dev, " CG_SPLL_FUNC_CNTL=0x%08X\n", - RREG32_SMC(ixCG_SPLL_FUNC_CNTL)); - dev_info(adev->dev, " CG_SPLL_FUNC_CNTL_2=0x%08X\n", - RREG32_SMC(ixCG_SPLL_FUNC_CNTL_2)); - dev_info(adev->dev, " CG_SPLL_FUNC_CNTL_3=0x%08X\n", - RREG32_SMC(ixCG_SPLL_FUNC_CNTL_3)); - dev_info(adev->dev, " CG_SPLL_FUNC_CNTL_4=0x%08X\n", - RREG32_SMC(ixCG_SPLL_FUNC_CNTL_4)); - dev_info(adev->dev, " CG_SPLL_SPREAD_SPECTRUM=0x%08X\n", - RREG32_SMC(ixCG_SPLL_SPREAD_SPECTRUM)); - dev_info(adev->dev, " CG_SPLL_SPREAD_SPECTRUM_2=0x%08X\n", - RREG32_SMC(ixCG_SPLL_SPREAD_SPECTRUM_2)); - dev_info(adev->dev, " DLL_CNTL=0x%08X\n", - RREG32(mmDLL_CNTL)); - dev_info(adev->dev, " MCLK_PWRMGT_CNTL=0x%08X\n", - RREG32(mmMCLK_PWRMGT_CNTL)); - dev_info(adev->dev, " MPLL_AD_FUNC_CNTL=0x%08X\n", - RREG32(mmMPLL_AD_FUNC_CNTL)); - dev_info(adev->dev, " MPLL_DQ_FUNC_CNTL=0x%08X\n", - RREG32(mmMPLL_DQ_FUNC_CNTL)); - dev_info(adev->dev, " MPLL_FUNC_CNTL=0x%08X\n", - RREG32(mmMPLL_FUNC_CNTL)); - dev_info(adev->dev, " MPLL_FUNC_CNTL_1=0x%08X\n", - RREG32(mmMPLL_FUNC_CNTL_1)); - dev_info(adev->dev, " MPLL_FUNC_CNTL_2=0x%08X\n", - RREG32(mmMPLL_FUNC_CNTL_2)); - dev_info(adev->dev, " MPLL_SS1=0x%08X\n", - RREG32(mmMPLL_SS1)); - dev_info(adev->dev, " MPLL_SS2=0x%08X\n", - RREG32(mmMPLL_SS2)); - dev_info(adev->dev, " CG_DISPLAY_GAP_CNTL=0x%08X\n", - RREG32_SMC(ixCG_DISPLAY_GAP_CNTL)); - dev_info(adev->dev, " CG_DISPLAY_GAP_CNTL2=0x%08X\n", - RREG32_SMC(ixCG_DISPLAY_GAP_CNTL2)); - dev_info(adev->dev, " CG_STATIC_SCREEN_PARAMETER=0x%08X\n", - RREG32_SMC(ixCG_STATIC_SCREEN_PARAMETER)); - dev_info(adev->dev, " CG_FREQ_TRAN_VOTING_0=0x%08X\n", - RREG32_SMC(ixCG_FREQ_TRAN_VOTING_0)); - dev_info(adev->dev, " CG_FREQ_TRAN_VOTING_1=0x%08X\n", - RREG32_SMC(ixCG_FREQ_TRAN_VOTING_1)); - dev_info(adev->dev, " CG_FREQ_TRAN_VOTING_2=0x%08X\n", - RREG32_SMC(ixCG_FREQ_TRAN_VOTING_2)); - dev_info(adev->dev, " CG_FREQ_TRAN_VOTING_3=0x%08X\n", - RREG32_SMC(ixCG_FREQ_TRAN_VOTING_3)); - dev_info(adev->dev, " CG_FREQ_TRAN_VOTING_4=0x%08X\n", - RREG32_SMC(ixCG_FREQ_TRAN_VOTING_4)); - dev_info(adev->dev, " CG_FREQ_TRAN_VOTING_5=0x%08X\n", - RREG32_SMC(ixCG_FREQ_TRAN_VOTING_5)); - dev_info(adev->dev, " CG_FREQ_TRAN_VOTING_6=0x%08X\n", - RREG32_SMC(ixCG_FREQ_TRAN_VOTING_6)); - dev_info(adev->dev, " CG_FREQ_TRAN_VOTING_7=0x%08X\n", - RREG32_SMC(ixCG_FREQ_TRAN_VOTING_7)); - dev_info(adev->dev, " RCU_UC_EVENTS=0x%08X\n", - RREG32_SMC(ixRCU_UC_EVENTS)); - dev_info(adev->dev, " DPM_TABLE_475=0x%08X\n", - RREG32_SMC(ixDPM_TABLE_475)); - dev_info(adev->dev, " MC_SEQ_RAS_TIMING_LP=0x%08X\n", - RREG32(mmMC_SEQ_RAS_TIMING_LP)); - dev_info(adev->dev, " MC_SEQ_RAS_TIMING=0x%08X\n", - RREG32(mmMC_SEQ_RAS_TIMING)); - dev_info(adev->dev, " MC_SEQ_CAS_TIMING_LP=0x%08X\n", - RREG32(mmMC_SEQ_CAS_TIMING_LP)); - dev_info(adev->dev, " MC_SEQ_CAS_TIMING=0x%08X\n", - RREG32(mmMC_SEQ_CAS_TIMING)); - dev_info(adev->dev, " MC_SEQ_DLL_STBY_LP=0x%08X\n", - RREG32(mmMC_SEQ_DLL_STBY_LP)); - dev_info(adev->dev, " MC_SEQ_DLL_STBY=0x%08X\n", - RREG32(mmMC_SEQ_DLL_STBY)); - dev_info(adev->dev, " MC_SEQ_G5PDX_CMD0_LP=0x%08X\n", - RREG32(mmMC_SEQ_G5PDX_CMD0_LP)); - dev_info(adev->dev, " MC_SEQ_G5PDX_CMD0=0x%08X\n", - RREG32(mmMC_SEQ_G5PDX_CMD0)); - dev_info(adev->dev, " MC_SEQ_G5PDX_CMD1_LP=0x%08X\n", - RREG32(mmMC_SEQ_G5PDX_CMD1_LP)); - dev_info(adev->dev, " MC_SEQ_G5PDX_CMD1=0x%08X\n", - RREG32(mmMC_SEQ_G5PDX_CMD1)); - dev_info(adev->dev, " MC_SEQ_G5PDX_CTRL_LP=0x%08X\n", - RREG32(mmMC_SEQ_G5PDX_CTRL_LP)); - dev_info(adev->dev, " MC_SEQ_G5PDX_CTRL=0x%08X\n", - RREG32(mmMC_SEQ_G5PDX_CTRL)); - dev_info(adev->dev, " MC_SEQ_PMG_DVS_CMD_LP=0x%08X\n", - RREG32(mmMC_SEQ_PMG_DVS_CMD_LP)); - dev_info(adev->dev, " MC_SEQ_PMG_DVS_CMD=0x%08X\n", - RREG32(mmMC_SEQ_PMG_DVS_CMD)); - dev_info(adev->dev, " MC_SEQ_PMG_DVS_CTL_LP=0x%08X\n", - RREG32(mmMC_SEQ_PMG_DVS_CTL_LP)); - dev_info(adev->dev, " MC_SEQ_PMG_DVS_CTL=0x%08X\n", - RREG32(mmMC_SEQ_PMG_DVS_CTL)); - dev_info(adev->dev, " MC_SEQ_MISC_TIMING_LP=0x%08X\n", - RREG32(mmMC_SEQ_MISC_TIMING_LP)); - dev_info(adev->dev, " MC_SEQ_MISC_TIMING=0x%08X\n", - RREG32(mmMC_SEQ_MISC_TIMING)); - dev_info(adev->dev, " MC_SEQ_MISC_TIMING2_LP=0x%08X\n", - RREG32(mmMC_SEQ_MISC_TIMING2_LP)); - dev_info(adev->dev, " MC_SEQ_MISC_TIMING2=0x%08X\n", - RREG32(mmMC_SEQ_MISC_TIMING2)); - dev_info(adev->dev, " MC_SEQ_PMG_CMD_EMRS_LP=0x%08X\n", - RREG32(mmMC_SEQ_PMG_CMD_EMRS_LP)); - dev_info(adev->dev, " MC_PMG_CMD_EMRS=0x%08X\n", - RREG32(mmMC_PMG_CMD_EMRS)); - dev_info(adev->dev, " MC_SEQ_PMG_CMD_MRS_LP=0x%08X\n", - RREG32(mmMC_SEQ_PMG_CMD_MRS_LP)); - dev_info(adev->dev, " MC_PMG_CMD_MRS=0x%08X\n", - RREG32(mmMC_PMG_CMD_MRS)); - dev_info(adev->dev, " MC_SEQ_PMG_CMD_MRS1_LP=0x%08X\n", - RREG32(mmMC_SEQ_PMG_CMD_MRS1_LP)); - dev_info(adev->dev, " MC_PMG_CMD_MRS1=0x%08X\n", - RREG32(mmMC_PMG_CMD_MRS1)); - dev_info(adev->dev, " MC_SEQ_WR_CTL_D0_LP=0x%08X\n", - RREG32(mmMC_SEQ_WR_CTL_D0_LP)); - dev_info(adev->dev, " MC_SEQ_WR_CTL_D0=0x%08X\n", - RREG32(mmMC_SEQ_WR_CTL_D0)); - dev_info(adev->dev, " MC_SEQ_WR_CTL_D1_LP=0x%08X\n", - RREG32(mmMC_SEQ_WR_CTL_D1_LP)); - dev_info(adev->dev, " MC_SEQ_WR_CTL_D1=0x%08X\n", - RREG32(mmMC_SEQ_WR_CTL_D1)); - dev_info(adev->dev, " MC_SEQ_RD_CTL_D0_LP=0x%08X\n", - RREG32(mmMC_SEQ_RD_CTL_D0_LP)); - dev_info(adev->dev, " MC_SEQ_RD_CTL_D0=0x%08X\n", - RREG32(mmMC_SEQ_RD_CTL_D0)); - dev_info(adev->dev, " MC_SEQ_RD_CTL_D1_LP=0x%08X\n", - RREG32(mmMC_SEQ_RD_CTL_D1_LP)); - dev_info(adev->dev, " MC_SEQ_RD_CTL_D1=0x%08X\n", - RREG32(mmMC_SEQ_RD_CTL_D1)); - dev_info(adev->dev, " MC_SEQ_PMG_TIMING_LP=0x%08X\n", - RREG32(mmMC_SEQ_PMG_TIMING_LP)); - dev_info(adev->dev, " MC_SEQ_PMG_TIMING=0x%08X\n", - RREG32(mmMC_SEQ_PMG_TIMING)); - dev_info(adev->dev, " MC_SEQ_PMG_CMD_MRS2_LP=0x%08X\n", - RREG32(mmMC_SEQ_PMG_CMD_MRS2_LP)); - dev_info(adev->dev, " MC_PMG_CMD_MRS2=0x%08X\n", - RREG32(mmMC_PMG_CMD_MRS2)); - dev_info(adev->dev, " MC_SEQ_WR_CTL_2_LP=0x%08X\n", - RREG32(mmMC_SEQ_WR_CTL_2_LP)); - dev_info(adev->dev, " MC_SEQ_WR_CTL_2=0x%08X\n", - RREG32(mmMC_SEQ_WR_CTL_2)); - dev_info(adev->dev, " PCIE_LC_SPEED_CNTL=0x%08X\n", - RREG32_PCIE(ixPCIE_LC_SPEED_CNTL)); - dev_info(adev->dev, " PCIE_LC_LINK_WIDTH_CNTL=0x%08X\n", - RREG32_PCIE(ixPCIE_LC_LINK_WIDTH_CNTL)); - dev_info(adev->dev, " SMC_IND_INDEX_0=0x%08X\n", - RREG32(mmSMC_IND_INDEX_0)); - dev_info(adev->dev, " SMC_IND_DATA_0=0x%08X\n", - RREG32(mmSMC_IND_DATA_0)); - dev_info(adev->dev, " SMC_IND_ACCESS_CNTL=0x%08X\n", - RREG32(mmSMC_IND_ACCESS_CNTL)); - dev_info(adev->dev, " SMC_RESP_0=0x%08X\n", - RREG32(mmSMC_RESP_0)); - dev_info(adev->dev, " SMC_MESSAGE_0=0x%08X\n", - RREG32(mmSMC_MESSAGE_0)); - dev_info(adev->dev, " SMC_SYSCON_RESET_CNTL=0x%08X\n", - RREG32_SMC(ixSMC_SYSCON_RESET_CNTL)); - dev_info(adev->dev, " SMC_SYSCON_CLOCK_CNTL_0=0x%08X\n", - RREG32_SMC(ixSMC_SYSCON_CLOCK_CNTL_0)); - dev_info(adev->dev, " SMC_SYSCON_MISC_CNTL=0x%08X\n", - RREG32_SMC(ixSMC_SYSCON_MISC_CNTL)); - dev_info(adev->dev, " SMC_PC_C=0x%08X\n", - RREG32_SMC(ixSMC_PC_C)); -} - static int ci_dpm_soft_reset(void *handle) { return 0; @@ -6572,7 +6381,7 @@ static int ci_dpm_set_interrupt_state(struct amdgpu_device *adev, } static int ci_dpm_process_interrupt(struct amdgpu_device *adev, - struct amdgpu_irq_src *source, + struct amdgpu_irq_src *source, struct amdgpu_iv_entry *entry) { bool queue_thermal = false; @@ -6613,7 +6422,188 @@ static int ci_dpm_set_powergating_state(void *handle, return 0; } +static int ci_dpm_print_clock_levels(struct amdgpu_device *adev, + enum pp_clock_type type, char *buf) +{ + struct ci_power_info *pi = ci_get_pi(adev); + struct ci_single_dpm_table *sclk_table = &pi->dpm_table.sclk_table; + struct ci_single_dpm_table *mclk_table = &pi->dpm_table.mclk_table; + struct ci_single_dpm_table *pcie_table = &pi->dpm_table.pcie_speed_table; + + int i, now, size = 0; + uint32_t clock, pcie_speed; + + switch (type) { + case PP_SCLK: + amdgpu_ci_send_msg_to_smc(adev, PPSMC_MSG_API_GetSclkFrequency); + clock = RREG32(mmSMC_MSG_ARG_0); + + for (i = 0; i < sclk_table->count; i++) { + if (clock > sclk_table->dpm_levels[i].value) + continue; + break; + } + now = i; + + for (i = 0; i < sclk_table->count; i++) + size += sprintf(buf + size, "%d: %uMhz %s\n", + i, sclk_table->dpm_levels[i].value / 100, + (i == now) ? "*" : ""); + break; + case PP_MCLK: + amdgpu_ci_send_msg_to_smc(adev, PPSMC_MSG_API_GetMclkFrequency); + clock = RREG32(mmSMC_MSG_ARG_0); + + for (i = 0; i < mclk_table->count; i++) { + if (clock > mclk_table->dpm_levels[i].value) + continue; + break; + } + now = i; + + for (i = 0; i < mclk_table->count; i++) + size += sprintf(buf + size, "%d: %uMhz %s\n", + i, mclk_table->dpm_levels[i].value / 100, + (i == now) ? "*" : ""); + break; + case PP_PCIE: + pcie_speed = ci_get_current_pcie_speed(adev); + for (i = 0; i < pcie_table->count; i++) { + if (pcie_speed != pcie_table->dpm_levels[i].value) + continue; + break; + } + now = i; + + for (i = 0; i < pcie_table->count; i++) + size += sprintf(buf + size, "%d: %s %s\n", i, + (pcie_table->dpm_levels[i].value == 0) ? "2.5GB, x1" : + (pcie_table->dpm_levels[i].value == 1) ? "5.0GB, x16" : + (pcie_table->dpm_levels[i].value == 2) ? "8.0GB, x16" : "", + (i == now) ? "*" : ""); + break; + default: + break; + } + + return size; +} + +static int ci_dpm_force_clock_level(struct amdgpu_device *adev, + enum pp_clock_type type, uint32_t mask) +{ + struct ci_power_info *pi = ci_get_pi(adev); + + if (adev->pm.dpm.forced_level + != AMDGPU_DPM_FORCED_LEVEL_MANUAL) + return -EINVAL; + + switch (type) { + case PP_SCLK: + if (!pi->sclk_dpm_key_disabled) + amdgpu_ci_send_msg_to_smc_with_parameter(adev, + PPSMC_MSG_SCLKDPM_SetEnabledMask, + pi->dpm_level_enable_mask.sclk_dpm_enable_mask & mask); + break; + + case PP_MCLK: + if (!pi->mclk_dpm_key_disabled) + amdgpu_ci_send_msg_to_smc_with_parameter(adev, + PPSMC_MSG_MCLKDPM_SetEnabledMask, + pi->dpm_level_enable_mask.mclk_dpm_enable_mask & mask); + break; + + case PP_PCIE: + { + uint32_t tmp = mask & pi->dpm_level_enable_mask.pcie_dpm_enable_mask; + uint32_t level = 0; + + while (tmp >>= 1) + level++; + + if (!pi->pcie_dpm_key_disabled) + amdgpu_ci_send_msg_to_smc_with_parameter(adev, + PPSMC_MSG_PCIeDPM_ForceLevel, + level); + break; + } + default: + break; + } + + return 0; +} + +static int ci_dpm_get_sclk_od(struct amdgpu_device *adev) +{ + struct ci_power_info *pi = ci_get_pi(adev); + struct ci_single_dpm_table *sclk_table = &(pi->dpm_table.sclk_table); + struct ci_single_dpm_table *golden_sclk_table = + &(pi->golden_dpm_table.sclk_table); + int value; + + value = (sclk_table->dpm_levels[sclk_table->count - 1].value - + golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value) * + 100 / + golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value; + + return value; +} + +static int ci_dpm_set_sclk_od(struct amdgpu_device *adev, uint32_t value) +{ + struct ci_power_info *pi = ci_get_pi(adev); + struct ci_ps *ps = ci_get_ps(adev->pm.dpm.requested_ps); + struct ci_single_dpm_table *golden_sclk_table = + &(pi->golden_dpm_table.sclk_table); + + if (value > 20) + value = 20; + + ps->performance_levels[ps->performance_level_count - 1].sclk = + golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value * + value / 100 + + golden_sclk_table->dpm_levels[golden_sclk_table->count - 1].value; + + return 0; +} + +static int ci_dpm_get_mclk_od(struct amdgpu_device *adev) +{ + struct ci_power_info *pi = ci_get_pi(adev); + struct ci_single_dpm_table *mclk_table = &(pi->dpm_table.mclk_table); + struct ci_single_dpm_table *golden_mclk_table = + &(pi->golden_dpm_table.mclk_table); + int value; + + value = (mclk_table->dpm_levels[mclk_table->count - 1].value - + golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value) * + 100 / + golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value; + + return value; +} + +static int ci_dpm_set_mclk_od(struct amdgpu_device *adev, uint32_t value) +{ + struct ci_power_info *pi = ci_get_pi(adev); + struct ci_ps *ps = ci_get_ps(adev->pm.dpm.requested_ps); + struct ci_single_dpm_table *golden_mclk_table = + &(pi->golden_dpm_table.mclk_table); + + if (value > 20) + value = 20; + + ps->performance_levels[ps->performance_level_count - 1].mclk = + golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value * + value / 100 + + golden_mclk_table->dpm_levels[golden_mclk_table->count - 1].value; + + return 0; +} + const struct amd_ip_funcs ci_dpm_ip_funcs = { + .name = "ci_dpm", .early_init = ci_dpm_early_init, .late_init = ci_dpm_late_init, .sw_init = ci_dpm_sw_init, @@ -6625,7 +6615,6 @@ const struct amd_ip_funcs ci_dpm_ip_funcs = { .is_idle = ci_dpm_is_idle, .wait_for_idle = ci_dpm_wait_for_idle, .soft_reset = ci_dpm_soft_reset, - .print_status = ci_dpm_print_status, .set_clockgating_state = ci_dpm_set_clockgating_state, .set_powergating_state = ci_dpm_set_powergating_state, }; @@ -6647,6 +6636,12 @@ static const struct amdgpu_dpm_funcs ci_dpm_funcs = { .get_fan_control_mode = &ci_dpm_get_fan_control_mode, .set_fan_speed_percent = &ci_dpm_set_fan_speed_percent, .get_fan_speed_percent = &ci_dpm_get_fan_speed_percent, + .print_clock_levels = ci_dpm_print_clock_levels, + .force_clock_level = ci_dpm_force_clock_level, + .get_sclk_od = ci_dpm_get_sclk_od, + .set_sclk_od = ci_dpm_set_sclk_od, + .get_mclk_od = ci_dpm_get_mclk_od, + .set_mclk_od = ci_dpm_set_mclk_od, }; static void ci_dpm_set_dpm_funcs(struct amdgpu_device *adev) |