]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/radeon/dpm: Disable sclk switching on Oland when two 4K 60Hz monitors are connected
authorKai-Heng Feng <kai.heng.feng@canonical.com>
Fri, 30 Apr 2021 04:56:56 +0000 (12:56 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 May 2021 08:13:11 +0000 (10:13 +0200)
commit 227545b9a08c68778ddd89428f99c351fc9315ac upstream.

Screen flickers rapidly when two 4K 60Hz monitors are in use. This issue
doesn't happen when one monitor is 4K 60Hz (pixelclock 594MHz) and
another one is 4K 30Hz (pixelclock 297MHz).

The issue is gone after setting "power_dpm_force_performance_level" to
"high". Following the indication, we found that the issue occurs when
sclk is too low.

So resolve the issue by disabling sclk switching when there are two
monitors requires high pixelclock (> 297MHz).

v2:
 - Only apply the fix to Oland.
Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/si_dpm.c

index a6d8de01194ae74722f0bee3b8bad0723d3fcae8..a813c00f109b59b6be97bcf44e532f49124a643d 100644 (file)
@@ -1559,6 +1559,7 @@ struct radeon_dpm {
        void                    *priv;
        u32                     new_active_crtcs;
        int                     new_active_crtc_count;
+       int                     high_pixelclock_count;
        u32                     current_active_crtcs;
        int                     current_active_crtc_count;
        bool single_display;
index 05c4196a8212d66515679190354d190b92c3359e..84b8d58f0718ec91ddcdb379f05d0b415df45494 100644 (file)
@@ -1747,6 +1747,7 @@ static void radeon_pm_compute_clocks_dpm(struct radeon_device *rdev)
        struct drm_device *ddev = rdev->ddev;
        struct drm_crtc *crtc;
        struct radeon_crtc *radeon_crtc;
+       struct radeon_connector *radeon_connector;
 
        if (!rdev->pm.dpm_enabled)
                return;
@@ -1756,6 +1757,7 @@ static void radeon_pm_compute_clocks_dpm(struct radeon_device *rdev)
        /* update active crtc counts */
        rdev->pm.dpm.new_active_crtcs = 0;
        rdev->pm.dpm.new_active_crtc_count = 0;
+       rdev->pm.dpm.high_pixelclock_count = 0;
        if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
                list_for_each_entry(crtc,
                                    &ddev->mode_config.crtc_list, head) {
@@ -1763,6 +1765,12 @@ static void radeon_pm_compute_clocks_dpm(struct radeon_device *rdev)
                        if (crtc->enabled) {
                                rdev->pm.dpm.new_active_crtcs |= (1 << radeon_crtc->crtc_id);
                                rdev->pm.dpm.new_active_crtc_count++;
+                               if (!radeon_crtc->connector)
+                                       continue;
+
+                               radeon_connector = to_radeon_connector(radeon_crtc->connector);
+                               if (radeon_connector->pixelclock_for_modeset > 297000)
+                                       rdev->pm.dpm.high_pixelclock_count++;
                        }
                }
        }
index d1c73e9db889aee87b6af7dddb3b99b5f86c1511..a84df439deb2f0f3dd3bace178bcf0787a38a3cf 100644 (file)
@@ -2982,6 +2982,9 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
                    (rdev->pdev->device == 0x6605)) {
                        max_sclk = 75000;
                }
+
+               if (rdev->pm.dpm.high_pixelclock_count > 1)
+                       disable_sclk_switching = true;
        }
 
        if (rps->vce_active) {