[Intel-gfx] [PATCH] drm/i915/dp: Increase cdclk when DP audio is enabled with 4 lanes and HBR2

Dhinakaran Pandiyan dhinakaran.pandiyan at intel.com
Thu Oct 13 18:04:19 UTC 2016


According to BSpec, cdclk has to be not less than 432 MHz with DP audio
enabled, port width x4, and link rate HBR2 (5.4 GHz)

Having a lower cdclk triggers pipe underruns, which then lead to displays
continuously cycling off and on. This is essential for DP MST audio as the
link is trained at HBR2 and 4 lanes by default.

This should fix https://bugs.freedesktop.org/show_bug.cgi?id=97907

Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan at intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 47 +++++++++++++++++++++++++++++++++---
 1 file changed, 43 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index cfcb03f..6a05183 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6603,14 +6603,43 @@ static int valleyview_modeset_calc_cdclk(struct drm_atomic_state *state)
 	return 0;
 }
 
+static bool cdclk_min_for_dp_audio(struct drm_atomic_state *state)
+{
+
+	struct drm_crtc_state *crtc_state;
+	struct drm_crtc *crtc;
+	int i;
+
+	/* BSpec says "Do not use DisplayPort with CDCLK less than 432 MHz,
+	 * audio enabled, port width x4, and link rate HBR2 (5.4 GHz), or else
+	 * there may be audio corruption or screen corruption."
+	 */
+
+	for_each_crtc_in_state(state, crtc, crtc_state, i) {
+		struct intel_crtc_state *pipe_config =
+			to_intel_crtc_state(crtc_state);
+
+		return (intel_crtc_has_dp_encoder(pipe_config) &&
+			pipe_config->has_audio &&
+			pipe_config->port_clock == 540000 &&
+			pipe_config->lane_count == 4);
+	}
+
+	return false;
+}
+
 static int bxt_modeset_calc_cdclk(struct drm_atomic_state *state)
 {
 	int max_pixclk = ilk_max_pixel_rate(state);
+	int cdclk, min_cdclk = 0;
 	struct intel_atomic_state *intel_state =
 		to_intel_atomic_state(state);
 
-	intel_state->cdclk = intel_state->dev_cdclk =
-		bxt_calc_cdclk(max_pixclk);
+	if (cdclk_min_for_dp_audio(state))
+		min_cdclk = bxt_calc_cdclk(432000);
+
+	cdclk = bxt_calc_cdclk(max_pixclk);
+	intel_state->cdclk = intel_state->dev_cdclk = max(min_cdclk, cdclk);
 
 	if (!intel_state->active_crtcs)
 		intel_state->dev_cdclk = bxt_calc_cdclk(0);
@@ -10374,7 +10403,10 @@ static int broadwell_modeset_calc_cdclk(struct drm_atomic_state *state)
 	struct drm_i915_private *dev_priv = to_i915(state->dev);
 	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
 	int max_pixclk = ilk_max_pixel_rate(state);
-	int cdclk;
+	int cdclk, min_cdclk = 0;
+
+	if (cdclk_min_for_dp_audio(state))
+		min_cdclk = broadwell_calc_cdclk(432000);
 
 	/*
 	 * FIXME should also account for plane ratio
@@ -10382,6 +10414,8 @@ static int broadwell_modeset_calc_cdclk(struct drm_atomic_state *state)
 	 */
 	cdclk = broadwell_calc_cdclk(max_pixclk);
 
+	cdclk =	max(min_cdclk, cdclk);
+
 	if (cdclk > dev_priv->max_cdclk_freq) {
 		DRM_DEBUG_KMS("requested cdclk (%d kHz) exceeds max (%d kHz)\n",
 			      cdclk, dev_priv->max_cdclk_freq);
@@ -10411,7 +10445,10 @@ static int skl_modeset_calc_cdclk(struct drm_atomic_state *state)
 	struct drm_i915_private *dev_priv = to_i915(state->dev);
 	const int max_pixclk = ilk_max_pixel_rate(state);
 	int vco = intel_state->cdclk_pll_vco;
-	int cdclk;
+	int cdclk, min_cdclk = 0;
+
+	if (cdclk_min_for_dp_audio(state))
+		min_cdclk = skl_calc_cdclk(432000, vco);
 
 	/*
 	 * FIXME should also account for plane ratio
@@ -10419,6 +10456,8 @@ static int skl_modeset_calc_cdclk(struct drm_atomic_state *state)
 	 */
 	cdclk = skl_calc_cdclk(max_pixclk, vco);
 
+	cdclk = max(min_cdclk, cdclk);
+
 	/*
 	 * FIXME move the cdclk caclulation to
 	 * compute_config() so we can fail gracegully.
-- 
2.7.4



More information about the Intel-gfx mailing list