diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/si_dpm.c')
-rw-r--r-- | drivers/gpu/drm/radeon/si_dpm.c | 80 |
1 files changed, 67 insertions, 13 deletions
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c index 88699e3cd868..5be9b4e72350 100644 --- a/drivers/gpu/drm/radeon/si_dpm.c +++ b/drivers/gpu/drm/radeon/si_dpm.c | |||
@@ -1753,6 +1753,9 @@ static int si_calculate_sclk_params(struct radeon_device *rdev, | |||
1753 | u32 engine_clock, | 1753 | u32 engine_clock, |
1754 | SISLANDS_SMC_SCLK_VALUE *sclk); | 1754 | SISLANDS_SMC_SCLK_VALUE *sclk); |
1755 | 1755 | ||
1756 | extern void si_update_cg(struct radeon_device *rdev, | ||
1757 | u32 block, bool enable); | ||
1758 | |||
1756 | static struct si_power_info *si_get_pi(struct radeon_device *rdev) | 1759 | static struct si_power_info *si_get_pi(struct radeon_device *rdev) |
1757 | { | 1760 | { |
1758 | struct si_power_info *pi = rdev->pm.dpm.priv; | 1761 | struct si_power_info *pi = rdev->pm.dpm.priv; |
@@ -3663,7 +3666,7 @@ static void si_clear_vc(struct radeon_device *rdev) | |||
3663 | WREG32(CG_FTV, 0); | 3666 | WREG32(CG_FTV, 0); |
3664 | } | 3667 | } |
3665 | 3668 | ||
3666 | static u8 si_get_ddr3_mclk_frequency_ratio(u32 memory_clock) | 3669 | u8 si_get_ddr3_mclk_frequency_ratio(u32 memory_clock) |
3667 | { | 3670 | { |
3668 | u8 mc_para_index; | 3671 | u8 mc_para_index; |
3669 | 3672 | ||
@@ -3676,7 +3679,7 @@ static u8 si_get_ddr3_mclk_frequency_ratio(u32 memory_clock) | |||
3676 | return mc_para_index; | 3679 | return mc_para_index; |
3677 | } | 3680 | } |
3678 | 3681 | ||
3679 | static u8 si_get_mclk_frequency_ratio(u32 memory_clock, bool strobe_mode) | 3682 | u8 si_get_mclk_frequency_ratio(u32 memory_clock, bool strobe_mode) |
3680 | { | 3683 | { |
3681 | u8 mc_para_index; | 3684 | u8 mc_para_index; |
3682 | 3685 | ||
@@ -3758,20 +3761,21 @@ static bool si_validate_phase_shedding_tables(struct radeon_device *rdev, | |||
3758 | return true; | 3761 | return true; |
3759 | } | 3762 | } |
3760 | 3763 | ||
3761 | static void si_trim_voltage_table_to_fit_state_table(struct radeon_device *rdev, | 3764 | void si_trim_voltage_table_to_fit_state_table(struct radeon_device *rdev, |
3762 | struct atom_voltage_table *voltage_table) | 3765 | u32 max_voltage_steps, |
3766 | struct atom_voltage_table *voltage_table) | ||
3763 | { | 3767 | { |
3764 | unsigned int i, diff; | 3768 | unsigned int i, diff; |
3765 | 3769 | ||
3766 | if (voltage_table->count <= SISLANDS_MAX_NO_VREG_STEPS) | 3770 | if (voltage_table->count <= max_voltage_steps) |
3767 | return; | 3771 | return; |
3768 | 3772 | ||
3769 | diff = voltage_table->count - SISLANDS_MAX_NO_VREG_STEPS; | 3773 | diff = voltage_table->count - max_voltage_steps; |
3770 | 3774 | ||
3771 | for (i= 0; i < SISLANDS_MAX_NO_VREG_STEPS; i++) | 3775 | for (i= 0; i < max_voltage_steps; i++) |
3772 | voltage_table->entries[i] = voltage_table->entries[i + diff]; | 3776 | voltage_table->entries[i] = voltage_table->entries[i + diff]; |
3773 | 3777 | ||
3774 | voltage_table->count = SISLANDS_MAX_NO_VREG_STEPS; | 3778 | voltage_table->count = max_voltage_steps; |
3775 | } | 3779 | } |
3776 | 3780 | ||
3777 | static int si_construct_voltage_tables(struct radeon_device *rdev) | 3781 | static int si_construct_voltage_tables(struct radeon_device *rdev) |
@@ -3787,7 +3791,9 @@ static int si_construct_voltage_tables(struct radeon_device *rdev) | |||
3787 | return ret; | 3791 | return ret; |
3788 | 3792 | ||
3789 | if (eg_pi->vddc_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS) | 3793 | if (eg_pi->vddc_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS) |
3790 | si_trim_voltage_table_to_fit_state_table(rdev, &eg_pi->vddc_voltage_table); | 3794 | si_trim_voltage_table_to_fit_state_table(rdev, |
3795 | SISLANDS_MAX_NO_VREG_STEPS, | ||
3796 | &eg_pi->vddc_voltage_table); | ||
3791 | 3797 | ||
3792 | if (eg_pi->vddci_control) { | 3798 | if (eg_pi->vddci_control) { |
3793 | ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_VDDCI, | 3799 | ret = radeon_atom_get_voltage_table(rdev, VOLTAGE_TYPE_VDDCI, |
@@ -3796,7 +3802,9 @@ static int si_construct_voltage_tables(struct radeon_device *rdev) | |||
3796 | return ret; | 3802 | return ret; |
3797 | 3803 | ||
3798 | if (eg_pi->vddci_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS) | 3804 | if (eg_pi->vddci_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS) |
3799 | si_trim_voltage_table_to_fit_state_table(rdev, &eg_pi->vddci_voltage_table); | 3805 | si_trim_voltage_table_to_fit_state_table(rdev, |
3806 | SISLANDS_MAX_NO_VREG_STEPS, | ||
3807 | &eg_pi->vddci_voltage_table); | ||
3800 | } | 3808 | } |
3801 | 3809 | ||
3802 | if (pi->mvdd_control) { | 3810 | if (pi->mvdd_control) { |
@@ -3814,7 +3822,9 @@ static int si_construct_voltage_tables(struct radeon_device *rdev) | |||
3814 | } | 3822 | } |
3815 | 3823 | ||
3816 | if (si_pi->mvdd_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS) | 3824 | if (si_pi->mvdd_voltage_table.count > SISLANDS_MAX_NO_VREG_STEPS) |
3817 | si_trim_voltage_table_to_fit_state_table(rdev, &si_pi->mvdd_voltage_table); | 3825 | si_trim_voltage_table_to_fit_state_table(rdev, |
3826 | SISLANDS_MAX_NO_VREG_STEPS, | ||
3827 | &si_pi->mvdd_voltage_table); | ||
3818 | } | 3828 | } |
3819 | 3829 | ||
3820 | if (si_pi->vddc_phase_shed_control) { | 3830 | if (si_pi->vddc_phase_shed_control) { |
@@ -5752,6 +5762,13 @@ int si_dpm_enable(struct radeon_device *rdev) | |||
5752 | struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps; | 5762 | struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps; |
5753 | int ret; | 5763 | int ret; |
5754 | 5764 | ||
5765 | si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | | ||
5766 | RADEON_CG_BLOCK_MC | | ||
5767 | RADEON_CG_BLOCK_SDMA | | ||
5768 | RADEON_CG_BLOCK_BIF | | ||
5769 | RADEON_CG_BLOCK_UVD | | ||
5770 | RADEON_CG_BLOCK_HDP), false); | ||
5771 | |||
5755 | if (si_is_smc_running(rdev)) | 5772 | if (si_is_smc_running(rdev)) |
5756 | return -EINVAL; | 5773 | return -EINVAL; |
5757 | if (pi->voltage_control) | 5774 | if (pi->voltage_control) |
@@ -5871,6 +5888,13 @@ int si_dpm_enable(struct radeon_device *rdev) | |||
5871 | 5888 | ||
5872 | si_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true); | 5889 | si_enable_auto_throttle_source(rdev, RADEON_DPM_AUTO_THROTTLE_SRC_THERMAL, true); |
5873 | 5890 | ||
5891 | si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | | ||
5892 | RADEON_CG_BLOCK_MC | | ||
5893 | RADEON_CG_BLOCK_SDMA | | ||
5894 | RADEON_CG_BLOCK_BIF | | ||
5895 | RADEON_CG_BLOCK_UVD | | ||
5896 | RADEON_CG_BLOCK_HDP), true); | ||
5897 | |||
5874 | ni_update_current_ps(rdev, boot_ps); | 5898 | ni_update_current_ps(rdev, boot_ps); |
5875 | 5899 | ||
5876 | return 0; | 5900 | return 0; |
@@ -5881,6 +5905,13 @@ void si_dpm_disable(struct radeon_device *rdev) | |||
5881 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); | 5905 | struct rv7xx_power_info *pi = rv770_get_pi(rdev); |
5882 | struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps; | 5906 | struct radeon_ps *boot_ps = rdev->pm.dpm.boot_ps; |
5883 | 5907 | ||
5908 | si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | | ||
5909 | RADEON_CG_BLOCK_MC | | ||
5910 | RADEON_CG_BLOCK_SDMA | | ||
5911 | RADEON_CG_BLOCK_BIF | | ||
5912 | RADEON_CG_BLOCK_UVD | | ||
5913 | RADEON_CG_BLOCK_HDP), false); | ||
5914 | |||
5884 | if (!si_is_smc_running(rdev)) | 5915 | if (!si_is_smc_running(rdev)) |
5885 | return; | 5916 | return; |
5886 | si_disable_ulv(rdev); | 5917 | si_disable_ulv(rdev); |
@@ -5945,6 +5976,13 @@ int si_dpm_set_power_state(struct radeon_device *rdev) | |||
5945 | struct radeon_ps *old_ps = &eg_pi->current_rps; | 5976 | struct radeon_ps *old_ps = &eg_pi->current_rps; |
5946 | int ret; | 5977 | int ret; |
5947 | 5978 | ||
5979 | si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | | ||
5980 | RADEON_CG_BLOCK_MC | | ||
5981 | RADEON_CG_BLOCK_SDMA | | ||
5982 | RADEON_CG_BLOCK_BIF | | ||
5983 | RADEON_CG_BLOCK_UVD | | ||
5984 | RADEON_CG_BLOCK_HDP), false); | ||
5985 | |||
5948 | ret = si_disable_ulv(rdev); | 5986 | ret = si_disable_ulv(rdev); |
5949 | if (ret) { | 5987 | if (ret) { |
5950 | DRM_ERROR("si_disable_ulv failed\n"); | 5988 | DRM_ERROR("si_disable_ulv failed\n"); |
@@ -6043,6 +6081,13 @@ int si_dpm_set_power_state(struct radeon_device *rdev) | |||
6043 | return ret; | 6081 | return ret; |
6044 | } | 6082 | } |
6045 | 6083 | ||
6084 | si_update_cg(rdev, (RADEON_CG_BLOCK_GFX | | ||
6085 | RADEON_CG_BLOCK_MC | | ||
6086 | RADEON_CG_BLOCK_SDMA | | ||
6087 | RADEON_CG_BLOCK_BIF | | ||
6088 | RADEON_CG_BLOCK_UVD | | ||
6089 | RADEON_CG_BLOCK_HDP), true); | ||
6090 | |||
6046 | return 0; | 6091 | return 0; |
6047 | } | 6092 | } |
6048 | 6093 | ||
@@ -6232,6 +6277,7 @@ static int si_parse_power_table(struct radeon_device *rdev) | |||
6232 | rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime); | 6277 | rdev->pm.dpm.backbias_response_time = le16_to_cpu(power_info->pplib.usBackbiasTime); |
6233 | rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime); | 6278 | rdev->pm.dpm.voltage_response_time = le16_to_cpu(power_info->pplib.usVoltageTime); |
6234 | for (i = 0; i < state_array->ucNumEntries; i++) { | 6279 | for (i = 0; i < state_array->ucNumEntries; i++) { |
6280 | u8 *idx; | ||
6235 | power_state = (union pplib_power_state *)power_state_offset; | 6281 | power_state = (union pplib_power_state *)power_state_offset; |
6236 | non_clock_array_index = power_state->v2.nonClockInfoIndex; | 6282 | non_clock_array_index = power_state->v2.nonClockInfoIndex; |
6237 | non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) | 6283 | non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) |
@@ -6248,14 +6294,16 @@ static int si_parse_power_table(struct radeon_device *rdev) | |||
6248 | non_clock_info, | 6294 | non_clock_info, |
6249 | non_clock_info_array->ucEntrySize); | 6295 | non_clock_info_array->ucEntrySize); |
6250 | k = 0; | 6296 | k = 0; |
6297 | idx = (u8 *)&power_state->v2.clockInfoIndex[0]; | ||
6251 | for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { | 6298 | for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { |
6252 | clock_array_index = power_state->v2.clockInfoIndex[j]; | 6299 | clock_array_index = idx[j]; |
6253 | if (clock_array_index >= clock_info_array->ucNumEntries) | 6300 | if (clock_array_index >= clock_info_array->ucNumEntries) |
6254 | continue; | 6301 | continue; |
6255 | if (k >= SISLANDS_MAX_HARDWARE_POWERLEVELS) | 6302 | if (k >= SISLANDS_MAX_HARDWARE_POWERLEVELS) |
6256 | break; | 6303 | break; |
6257 | clock_info = (union pplib_clock_info *) | 6304 | clock_info = (union pplib_clock_info *) |
6258 | &clock_info_array->clockInfo[clock_array_index * clock_info_array->ucEntrySize]; | 6305 | ((u8 *)&clock_info_array->clockInfo[0] + |
6306 | (clock_array_index * clock_info_array->ucEntrySize)); | ||
6259 | si_parse_pplib_clock_info(rdev, | 6307 | si_parse_pplib_clock_info(rdev, |
6260 | &rdev->pm.dpm.ps[i], k, | 6308 | &rdev->pm.dpm.ps[i], k, |
6261 | clock_info); | 6309 | clock_info); |
@@ -6401,6 +6449,12 @@ int si_dpm_init(struct radeon_device *rdev) | |||
6401 | 6449 | ||
6402 | si_initialize_powertune_defaults(rdev); | 6450 | si_initialize_powertune_defaults(rdev); |
6403 | 6451 | ||
6452 | /* make sure dc limits are valid */ | ||
6453 | if ((rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.sclk == 0) || | ||
6454 | (rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc.mclk == 0)) | ||
6455 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_dc = | ||
6456 | rdev->pm.dpm.dyn_state.max_clock_voltage_on_ac; | ||
6457 | |||
6404 | return 0; | 6458 | return 0; |
6405 | } | 6459 | } |
6406 | 6460 | ||