]> git.proxmox.com Git - mirror_ubuntu-kernels.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)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 13 May 2021 14:48:21 +0000 (10:48 -0400)
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
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_pm.c
drivers/gpu/drm/radeon/si_dpm.c

index 42281fce552e6ee66221b0646cd80eedddb9ca1a..56ed5634cebef7945c289ec6c078fe2527b42db3 100644 (file)
@@ -1549,6 +1549,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 0c1950f4e146f158f00d2cc879c5bac3e07d0325..3861c0b98fcf38906ebff11c46ab062a0fba8563 100644 (file)
@@ -1767,6 +1767,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;
@@ -1776,6 +1777,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) {
@@ -1783,6 +1785,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 2c54c0d7ca5bee655c000e2f475d03db003c3758..3add39c1a6897b42dbf7f0064e5f4958ffe6496c 100644 (file)
@@ -2979,6 +2979,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) {