aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/rv6xx_dpm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/rv6xx_dpm.c')
-rw-r--r--drivers/gpu/drm/radeon/rv6xx_dpm.c41
1 files changed, 38 insertions, 3 deletions
diff --git a/drivers/gpu/drm/radeon/rv6xx_dpm.c b/drivers/gpu/drm/radeon/rv6xx_dpm.c
index 65e33f387341..363018c60412 100644
--- a/drivers/gpu/drm/radeon/rv6xx_dpm.c
+++ b/drivers/gpu/drm/radeon/rv6xx_dpm.c
@@ -819,7 +819,7 @@ static void rv6xx_program_memory_timing_parameters(struct radeon_device *rdev)
819 POWERMODE1(calculate_memory_refresh_rate(rdev, 819 POWERMODE1(calculate_memory_refresh_rate(rdev,
820 pi->hw.sclks[R600_POWER_LEVEL_MEDIUM])) | 820 pi->hw.sclks[R600_POWER_LEVEL_MEDIUM])) |
821 POWERMODE2(calculate_memory_refresh_rate(rdev, 821 POWERMODE2(calculate_memory_refresh_rate(rdev,
822 pi->hw.sclks[R600_POWER_LEVEL_MEDIUM])) | 822 pi->hw.sclks[R600_POWER_LEVEL_HIGH])) |
823 POWERMODE3(calculate_memory_refresh_rate(rdev, 823 POWERMODE3(calculate_memory_refresh_rate(rdev,
824 pi->hw.sclks[R600_POWER_LEVEL_HIGH]))); 824 pi->hw.sclks[R600_POWER_LEVEL_HIGH])));
825 WREG32(ARB_RFSH_RATE, arb_refresh_rate); 825 WREG32(ARB_RFSH_RATE, arb_refresh_rate);
@@ -1182,10 +1182,10 @@ static void rv6xx_program_display_gap(struct radeon_device *rdev)
1182 u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL); 1182 u32 tmp = RREG32(CG_DISPLAY_GAP_CNTL);
1183 1183
1184 tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK); 1184 tmp &= ~(DISP1_GAP_MCHG_MASK | DISP2_GAP_MCHG_MASK);
1185 if (RREG32(AVIVO_D1CRTC_CONTROL) & AVIVO_CRTC_EN) { 1185 if (rdev->pm.dpm.new_active_crtcs & 1) {
1186 tmp |= DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK); 1186 tmp |= DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK);
1187 tmp |= DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE); 1187 tmp |= DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
1188 } else if (RREG32(AVIVO_D2CRTC_CONTROL) & AVIVO_CRTC_EN) { 1188 } else if (rdev->pm.dpm.new_active_crtcs & 2) {
1189 tmp |= DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE); 1189 tmp |= DISP1_GAP_MCHG(R600_PM_DISPLAY_GAP_IGNORE);
1190 tmp |= DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK); 1190 tmp |= DISP2_GAP_MCHG(R600_PM_DISPLAY_GAP_VBLANK);
1191 } else { 1191 } else {
@@ -1670,6 +1670,8 @@ int rv6xx_dpm_set_power_state(struct radeon_device *rdev)
1670 struct radeon_ps *old_ps = rdev->pm.dpm.current_ps; 1670 struct radeon_ps *old_ps = rdev->pm.dpm.current_ps;
1671 int ret; 1671 int ret;
1672 1672
1673 pi->restricted_levels = 0;
1674
1673 rv6xx_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps); 1675 rv6xx_set_uvd_clock_before_set_eng_clock(rdev, new_ps, old_ps);
1674 1676
1675 rv6xx_clear_vc(rdev); 1677 rv6xx_clear_vc(rdev);
@@ -1756,6 +1758,8 @@ int rv6xx_dpm_set_power_state(struct radeon_device *rdev)
1756 1758
1757 rv6xx_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps); 1759 rv6xx_set_uvd_clock_after_set_eng_clock(rdev, new_ps, old_ps);
1758 1760
1761 rdev->pm.dpm.forced_level = RADEON_DPM_FORCED_LEVEL_AUTO;
1762
1759 return 0; 1763 return 0;
1760} 1764}
1761 1765
@@ -2085,3 +2089,34 @@ u32 rv6xx_dpm_get_mclk(struct radeon_device *rdev, bool low)
2085 else 2089 else
2086 return requested_state->high.mclk; 2090 return requested_state->high.mclk;
2087} 2091}
2092
2093int rv6xx_dpm_force_performance_level(struct radeon_device *rdev,
2094 enum radeon_dpm_forced_level level)
2095{
2096 struct rv6xx_power_info *pi = rv6xx_get_pi(rdev);
2097
2098 if (level == RADEON_DPM_FORCED_LEVEL_HIGH) {
2099 pi->restricted_levels = 3;
2100 } else if (level == RADEON_DPM_FORCED_LEVEL_LOW) {
2101 pi->restricted_levels = 2;
2102 } else {
2103 pi->restricted_levels = 0;
2104 }
2105
2106 rv6xx_clear_vc(rdev);
2107 r600_power_level_enable(rdev, R600_POWER_LEVEL_LOW, true);
2108 r600_set_at(rdev, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF);
2109 r600_wait_for_power_level(rdev, R600_POWER_LEVEL_LOW);
2110 r600_power_level_enable(rdev, R600_POWER_LEVEL_HIGH, false);
2111 r600_power_level_enable(rdev, R600_POWER_LEVEL_MEDIUM, false);
2112 rv6xx_enable_medium(rdev);
2113 rv6xx_enable_high(rdev);
2114 if (pi->restricted_levels == 3)
2115 r600_power_level_enable(rdev, R600_POWER_LEVEL_LOW, false);
2116 rv6xx_program_vc(rdev);
2117 rv6xx_program_at(rdev);
2118
2119 rdev->pm.dpm.forced_level = level;
2120
2121 return 0;
2122}