Need to expand the check to handle short circuiting
if the selected state is the same as current state.

bug:
https://bugs.freedesktop.org/show_bug.cgi?id=87796

Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
Cc: stable at vger.kernel.org
---
 drivers/gpu/drm/radeon/radeon.h    |  1 +
 drivers/gpu/drm/radeon/radeon_pm.c | 22 +++++++++++++++++-----
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 35ab65d..73a6432 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1567,6 +1567,7 @@ struct radeon_dpm {
        int                     new_active_crtc_count;
        u32                     current_active_crtcs;
        int                     current_active_crtc_count;
+       bool single_display;
        struct radeon_dpm_dynamic_state dyn_state;
        struct radeon_dpm_fan fan;
        u32 tdp_limit;
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c 
b/drivers/gpu/drm/radeon/radeon_pm.c
index 33cf410..c1ba83a 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -837,12 +837,8 @@ static void radeon_dpm_thermal_work_handler(struct 
work_struct *work)
        radeon_pm_compute_clocks(rdev);
 }

-static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device 
*rdev,
-                                                    enum radeon_pm_state_type 
dpm_state)
+static bool radeon_dpm_single_display(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;

@@ -858,6 +854,17 @@ static struct radeon_ps 
*radeon_dpm_pick_power_state(struct radeon_device *rdev,
        if (single_display && (r600_dpm_get_vrefresh(rdev) >= 120))
                single_display = false;

+       return single_display;
+}
+
+static struct radeon_ps *radeon_dpm_pick_power_state(struct radeon_device 
*rdev,
+                                                    enum radeon_pm_state_type 
dpm_state)
+{
+       int i;
+       struct radeon_ps *ps;
+       u32 ui_class;
+       bool single_display = radeon_dpm_single_display(rdev);
+
        /* certain older asics have a separare 3D performance state,
         * so try that first if the user selected performance
         */
@@ -983,6 +990,7 @@ static void radeon_dpm_change_power_state_locked(struct 
radeon_device *rdev)
        struct radeon_ps *ps;
        enum radeon_pm_state_type dpm_state;
        int ret;
+       bool single_display = radeon_dpm_single_display(rdev);

        /* if dpm init failed */
        if (!rdev->pm.dpm_enabled)
@@ -1007,6 +1015,9 @@ static void radeon_dpm_change_power_state_locked(struct 
radeon_device *rdev)
                /* vce just modifies an existing state so force a change */
                if (ps->vce_active != rdev->pm.dpm.vce_active)
                        goto force;
+               /* user has made a display change (such as timing) */
+               if (rdev->pm.dpm.single_display != single_display)
+                       goto force;
                if ((rdev->family < CHIP_BARTS) || (rdev->flags & 
RADEON_IS_IGP)) {
                        /* for pre-BTC and APUs if the num crtcs changed but 
state is the same,
                         * all we need to do is update the display 
configuration.
@@ -1069,6 +1080,7 @@ force:

        rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs;
        rdev->pm.dpm.current_active_crtc_count = 
rdev->pm.dpm.new_active_crtc_count;
+       rdev->pm.dpm.single_display = single_display;

        /* wait for the rings to drain */
        for (i = 0; i < RADEON_NUM_RINGS; i++) {
-- 
1.8.3.1

Reply via email to