[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