[Intel-gfx] [PATCH 2/4] drm/i915: Add a hack to fix link training errors on pipe A+port B on CHV

ville.syrjala at linux.intel.com ville.syrjala at linux.intel.com
Wed Feb 11 06:59:48 PST 2015


From: Ville Syrjälä <ville.syrjala at linux.intel.com>

For some reason link training fails when port B is being driven by pipe
A, and was previously driven by port B or the common lane was previously
powered off.

After staring at some register dumps I noticed some oddness with the DCC
calibration status bits, and after some experimentation I came up with a
workaround that just involves toggling the DCC calibration bit for the
data lanes in chv_pre_enable_dp(). I also observed that doing the same
trick for pipe B resulted in a blinking display with pipe B + eDP port C.
So the I've limited the workaround to pipe A only for now, while not
caring which port is used.

Whether there are more factors in this mess is unclear. But for now
this seems to work at least on my BSW RVP.

Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h |  8 ++++++++
 drivers/gpu/drm/i915/intel_dp.c | 23 +++++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 4728dc2..7546350 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -966,6 +966,14 @@ enum skl_disp_power_wells {
 #define _VLV_PCS_DW14_CH1		0x8438
 #define	VLV_PCS_DW14(ch) _PORT(ch, _VLV_PCS_DW14_CH0, _VLV_PCS_DW14_CH1)
 
+#define _VLV_PCS_DW17_CH0		0x8244
+#define _VLV_PCS_DW17_CH1		0x8444
+#define  DPIO_TX2_DCC_CALIB_DONE	(1 << 3)
+#define  DPIO_TX1_DCC_CALIB_DONE	(1 << 2)
+#define  DPIO_TX2_DCC_CALIB_ENABLE	(1 << 1)
+#define  DPIO_TX1_DCC_CALIB_ENABLE	(1 << 0)
+#define VLV_PCS_DW17(ch) _PORT(ch, _VLV_PCS_DW17_CH0, _VLV_PCS_DW17_CH1)
+
 #define _VLV_PCS_DW23_CH0		0x825c
 #define _VLV_PCS_DW23_CH1		0x845c
 #define VLV_PCS_DW23(ch) _PORT(ch, _VLV_PCS_DW23_CH0, _VLV_PCS_DW23_CH1)
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 43129ed..2e3fb17 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2602,6 +2602,29 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder)
 		       DPIO_TX1_STAGGER_MULT(7) |
 		       DPIO_TX2_STAGGER_MULT(5));
 
+	/*
+	 * FIXME: After port B has been driven by pipe B, or
+	 * the common lane well has been powered down, trying to drive
+	 * port B with pipe A results in a link training failure. Somehow
+	 * toggling the DCC calibrate force bits before enabling the port
+	 * fixes the problem. Neither pipe B or port C seem to suffer from
+	 * this problem, however doing the toggle on pipe B seems to cause
+	 * eDP port C to blink when driven by pipe B. So we only do the
+	 * toggle for pipe A. It's untested whether pipe C + port D might
+	 * also need something like this due to lack of a suitale board.
+	 *
+	 * Not sure if this is just a symptom of some problem with the PHY
+	 * programming we do, but this seems to be a solid workaround so far.
+	 *
+	 * All of this was tested on a BSW RVP with DP on port B,
+	 * eDP on port C, and HDMI on port D.
+	 */
+	if (pipe == PIPE_A) {
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW17(ch),
+			       DPIO_TX1_DCC_CALIB_ENABLE | DPIO_TX2_DCC_CALIB_ENABLE);
+		vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW17(ch), 0);
+	}
+
 	mutex_unlock(&dev_priv->dpio_lock);
 
 	intel_enable_dp(encoder);
-- 
2.0.5



More information about the Intel-gfx mailing list