aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlex Deucher <alexander.deucher@amd.com>2013-07-08 11:35:06 -0400
committerAlex Deucher <alexander.deucher@amd.com>2013-07-08 17:40:20 -0400
commit48783069350a2963e97696a3c3ed0a40cbe35210 (patch)
treef2d75ed1954a444927bd263611df0c5d42926fb2 /drivers
parentdrm/radeon/dpm: add helper to calculate vblank time (diff)
downloadlinux-dev-48783069350a2963e97696a3c3ed0a40cbe35210.tar.xz
linux-dev-48783069350a2963e97696a3c3ed0a40cbe35210.zip
drm/radeon/dpm: add checks against vblank time
If the vblank time is too short to adjust mclk, assume multiple displays (no mclk adjustments). Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/radeon/radeon.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c14
2 files changed, 13 insertions, 3 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index b4681313646c..9b7025d02cd0 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1678,6 +1678,7 @@ struct radeon_asic {
void (*print_power_state)(struct radeon_device *rdev, struct radeon_ps *ps);
void (*debugfs_print_current_performance_level)(struct radeon_device *rdev, struct seq_file *m);
int (*force_performance_level)(struct radeon_device *rdev, enum radeon_dpm_forced_level level);
+ bool (*vblank_too_short)(struct radeon_device *rdev);
} dpm;
/* pageflipping */
struct {
@@ -2446,6 +2447,7 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v);
#define radeon_dpm_print_power_state(rdev, ps) rdev->asic->dpm.print_power_state((rdev), (ps))
#define radeon_dpm_debugfs_print_current_performance_level(rdev, m) rdev->asic->dpm.debugfs_print_current_performance_level((rdev), (m))
#define radeon_dpm_force_performance_level(rdev, l) rdev->asic->dpm.force_performance_level((rdev), (l))
+#define radeon_dpm_vblank_too_short(rdev) rdev->asic->dpm.vblank_too_short((rdev))
/* Common functions */
/* AGP */
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index b163102eccd4..f374c467aaca 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -633,6 +633,14 @@ static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device *rdev,
int i;
struct radeon_ps *ps;
u32 ui_class;
+ bool single_display = (rdev->pm.dpm.new_active_crtc_count < 2) ?
+ true : false;
+
+ /* check if the vblank period is too short to adjust the mclk */
+ if (single_display && rdev->asic->dpm.vblank_too_short) {
+ if (radeon_dpm_vblank_too_short(rdev))
+ single_display = false;
+ }
/* certain older asics have a separare 3D performance state,
* so try that first if the user selected performance
@@ -653,7 +661,7 @@ restart_search:
case POWER_STATE_TYPE_BATTERY:
if (ui_class == ATOM_PPLIB_CLASSIFICATION_UI_BATTERY) {
if (ps->caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) {
- if (rdev->pm.dpm.new_active_crtc_count < 2)
+ if (single_display)
return ps;
} else
return ps;
@@ -662,7 +670,7 @@ restart_search:
case POWER_STATE_TYPE_BALANCED:
if (ui_class == ATOM_PPLIB_CLASSIFICATION_UI_BALANCED) {
if (ps->caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) {
- if (rdev->pm.dpm.new_active_crtc_count < 2)
+ if (single_display)
return ps;
} else
return ps;
@@ -671,7 +679,7 @@ restart_search:
case POWER_STATE_TYPE_PERFORMANCE:
if (ui_class == ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE) {
if (ps->caps & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) {
- if (rdev->pm.dpm.new_active_crtc_count < 2)
+ if (single_display)
return ps;
} else
return ps;