diff mbox series

[1/1] drm/radeon/dpm: Disable sclk switching on Oland when two 4K 60Hz monitors are connected

Message ID 20210513162652.274315-2-kai.heng.feng@canonical.com
State New
Headers show
Series [1/1] drm/radeon/dpm: Disable sclk switching on Oland when two 4K 60Hz monitors are connected | expand

Commit Message

Kai-Heng Feng May 13, 2021, 4:26 p.m. UTC
BugLink: https://bugs.launchpad.net/bugs/1928361

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>
(cherry picked from commit ae30d41eb54eb0926afb82ad5ee4fd3536cce060 linux-next)
Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
---
 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(+)

Comments

Stefan Bader May 14, 2021, 7:59 a.m. UTC | #1
On 13.05.21 18:26, Kai-Heng Feng wrote:
> BugLink: https://bugs.launchpad.net/bugs/1928361
> 
> 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>
> (cherry picked from commit ae30d41eb54eb0926afb82ad5ee4fd3536cce060 linux-next)
> Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
> ---
>   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(+)
> 
> diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
> index 3effc8c71494..ea44423376c4 100644
> --- a/drivers/gpu/drm/radeon/radeon.h
> +++ b/drivers/gpu/drm/radeon/radeon.h
> @@ -1558,6 +1558,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;
> diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
> index 1995dad59dd0..2db4a8b1542d 100644
> --- a/drivers/gpu/drm/radeon/radeon_pm.c
> +++ b/drivers/gpu/drm/radeon/radeon_pm.c
> @@ -1775,6 +1775,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;
> @@ -1784,6 +1785,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) {
> @@ -1791,6 +1793,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++;
>   			}
>   		}
>   	}
> diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
> index 91bfc4762767..43b63705d073 100644
> --- a/drivers/gpu/drm/radeon/si_dpm.c
> +++ b/drivers/gpu/drm/radeon/si_dpm.c
> @@ -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) {
>
Krzysztof Kozlowski May 14, 2021, 12:07 p.m. UTC | #2
On 13/05/2021 12:26, Kai-Heng Feng wrote:
> BugLink: https://bugs.launchpad.net/bugs/1928361
> 
> 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>
> (cherry picked from commit ae30d41eb54eb0926afb82ad5ee4fd3536cce060 linux-next)
> Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
> ---
>  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(+)
> 
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com>

Best regards,
Krzysztof
diff mbox series

Patch

diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 3effc8c71494..ea44423376c4 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -1558,6 +1558,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;
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 1995dad59dd0..2db4a8b1542d 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -1775,6 +1775,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;
@@ -1784,6 +1785,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) {
@@ -1791,6 +1793,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++;
 			}
 		}
 	}
diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
index 91bfc4762767..43b63705d073 100644
--- a/drivers/gpu/drm/radeon/si_dpm.c
+++ b/drivers/gpu/drm/radeon/si_dpm.c
@@ -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) {