| From 227545b9a08c68778ddd89428f99c351fc9315ac Mon Sep 17 00:00:00 2001 |
| From: Kai-Heng Feng <kai.heng.feng@canonical.com> |
| Date: Fri, 30 Apr 2021 12:56:56 +0800 |
| Subject: drm/radeon/dpm: Disable sclk switching on Oland when two 4K 60Hz monitors are connected |
| |
| From: Kai-Heng Feng <kai.heng.feng@canonical.com> |
| |
| 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 | 1 + |
| drivers/gpu/drm/radeon/radeon_pm.c | 8 ++++++++ |
| drivers/gpu/drm/radeon/si_dpm.c | 3 +++ |
| 3 files changed, 12 insertions(+) |
| |
| --- a/drivers/gpu/drm/radeon/radeon.h |
| +++ b/drivers/gpu/drm/radeon/radeon.h |
| @@ -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; |
| --- a/drivers/gpu/drm/radeon/radeon_pm.c |
| +++ b/drivers/gpu/drm/radeon/radeon_pm.c |
| @@ -1747,6 +1747,7 @@ static void radeon_pm_compute_clocks_dpm |
| 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 |
| /* 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 |
| 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++; |
| } |
| } |
| } |
| --- a/drivers/gpu/drm/radeon/si_dpm.c |
| +++ b/drivers/gpu/drm/radeon/si_dpm.c |
| @@ -2982,6 +2982,9 @@ static void si_apply_state_adjust_rules( |
| (rdev->pdev->device == 0x6605)) { |
| max_sclk = 75000; |
| } |
| + |
| + if (rdev->pm.dpm.high_pixelclock_count > 1) |
| + disable_sclk_switching = true; |
| } |
| |
| if (rps->vce_active) { |