drm/radeon/dpm: add checks against vblank time
authorAlex Deucher <alexander.deucher@amd.com>
Mon, 8 Jul 2013 15:35:06 +0000 (11:35 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 8 Jul 2013 21:40:20 +0000 (17:40 -0400)
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>
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_pm.c

index b468131..9b7025d 100644 (file)
@@ -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 */
index b163102..f374c46 100644 (file)
@@ -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;