[Intel-gfx] [PATCH 11/16] drm/i915: manual FDI training for Ivy Bridge

Keith Packard keithp at keithp.com
Wed Apr 27 17:10:29 CEST 2011


On Tue, 26 Apr 2011 16:38:49 -0700, Jesse Barnes <jbarnes at virtuousgeek.org> wrote:
> A0 stepping chips need to use manual training, but the bits have all
> moved.  So fix things up so we can at least train FDI for VGA links.

This patch should be before the auto-train patch so that we don't have
a broken driver between them.

> 
> Signed-off-by: Jesse Barnes <jbarnes at virtuousgeek.org>
> ---
>  drivers/gpu/drm/i915/i915_reg.h      |   10 +++
>  drivers/gpu/drm/i915/intel_display.c |  129 +++++++++++++++++++++++++++++++++-
>  2 files changed, 136 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index b77bd49..03c99ed 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -3105,7 +3105,15 @@
>  #define  FDI_TX_ENHANCE_FRAME_ENABLE    (1<<18)
>  /* Ironlake: hardwired to 1 */
>  #define  FDI_TX_PLL_ENABLE              (1<<14)
> +
> +/* Ivybridge has different bits for lolz */
> +#define  FDI_LINK_TRAIN_PATTERN_1_IVB       (0<<8)
> +#define  FDI_LINK_TRAIN_PATTERN_2_IVB       (1<<8)
> +#define  FDI_LINK_TRAIN_PATTERN_IDLE_IVB    (2<<8)
> +#define  FDI_LINK_TRAIN_NONE_IVB            (3<<8)
> +
>  /* both Tx and Rx */
> +#define  FDI_LINK_TRAIN_AUTO		(1<<10)
>  #define  FDI_SCRAMBLING_ENABLE          (0<<7)
>  #define  FDI_SCRAMBLING_DISABLE         (1<<7)
>  /* Ivybridge */
> @@ -3117,6 +3125,8 @@
>  #define FDI_RX_CTL(pipe) _PIPE(pipe, _FDI_RXA_CTL, _FDI_RXB_CTL)
>  #define  FDI_RX_ENABLE          (1<<31)
>  /* train, dp width same as FDI_TX */
> +#define  FDI_FS_ERRC_ENABLE		(1<<27)
> +#define  FDI_FE_ERRC_ENABLE		(1<<26)
>  #define  FDI_DP_PORT_WIDTH_X8           (7<<19)
>  #define  FDI_8BPC                       (0<<16)
>  #define  FDI_10BPC                      (1<<16)
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index db46e4f..866abe5 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2047,8 +2047,13 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc)
>  	/* enable normal train */
>  	reg = FDI_TX_CTL(pipe);
>  	temp = I915_READ(reg);
> -	temp &= ~FDI_LINK_TRAIN_NONE;
> -	temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
> +	if (IS_GEN6(dev)) {
> +		temp &= ~FDI_LINK_TRAIN_NONE;
> +		temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
> +	} else if (IS_IVYBRIDGE(dev)) {
> +		temp &= ~FDI_LINK_TRAIN_NONE_IVB;
> +		temp |= FDI_LINK_TRAIN_NONE_IVB | FDI_TX_ENHANCE_FRAME_ENABLE;
> +	}
>  	I915_WRITE(reg, temp);
>  
>  	reg = FDI_RX_CTL(pipe);
> @@ -2065,6 +2070,11 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc)
>  	/* wait one idle pattern time */
>  	POSTING_READ(reg);
>  	udelay(1000);
> +
> +	/* IVB wants error correction enabled */
> +	if (IS_IVYBRIDGE(dev))
> +		I915_WRITE(reg, I915_READ(reg) | FDI_FS_ERRC_ENABLE |
> +			   FDI_FE_ERRC_ENABLE);
>  }
>  
>  /* The FDI link training functions for ILK/Ibexpeak. */
> @@ -2292,6 +2302,115 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
>  	DRM_DEBUG_KMS("FDI train done.\n");
>  }
>  
> +/* Manual link training for Ivy Bridge A0 parts */
> +static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
> +{
> +	struct drm_device *dev = crtc->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
> +	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +	int pipe = intel_crtc->pipe;
> +	u32 reg, temp, i;
> +
> +	/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
> +	   for train result */
> +	reg = FDI_RX_IMR(pipe);
> +	temp = I915_READ(reg);
> +	temp &= ~FDI_RX_SYMBOL_LOCK;
> +	temp &= ~FDI_RX_BIT_LOCK;
> +	I915_WRITE(reg, temp);
> +
> +	POSTING_READ(reg);
> +	udelay(150);
> +
> +	/* enable CPU FDI TX and PCH FDI RX */
> +	reg = FDI_TX_CTL(pipe);
> +	temp = I915_READ(reg);
> +	temp &= ~(7 << 19);
> +	temp |= (intel_crtc->fdi_lanes - 1) << 19;
> +	temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB);
> +	temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
> +	temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
> +	temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
> +	I915_WRITE(reg, temp | FDI_TX_ENABLE);
> +
> +	reg = FDI_RX_CTL(pipe);
> +	temp = I915_READ(reg);
> +	temp &= ~FDI_LINK_TRAIN_AUTO;
> +	temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
> +	temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
> +	I915_WRITE(reg, temp | FDI_RX_ENABLE);
> +
> +	POSTING_READ(reg);
> +	udelay(150);
> +
> +	for (i = 0; i < 4; i++ ) {
> +		reg = FDI_TX_CTL(pipe);
> +		temp = I915_READ(reg);
> +		temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
> +		temp |= snb_b_fdi_train_param[i];
> +		I915_WRITE(reg, temp);
> +
> +		POSTING_READ(reg);
> +		udelay(500);
> +
> +		reg = FDI_RX_IIR(pipe);
> +		temp = I915_READ(reg);
> +		DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
> +
> +		if (temp & FDI_RX_BIT_LOCK ||
> +		    (I915_READ(reg) & FDI_RX_BIT_LOCK)) {
> +			I915_WRITE(reg, temp | FDI_RX_BIT_LOCK);
> +			DRM_DEBUG_KMS("FDI train 1 done.\n");
> +			break;
> +		}
> +	}
> +	if (i == 4)
> +		DRM_ERROR("FDI train 1 fail!\n");
> +
> +	/* Train 2 */
> +	reg = FDI_TX_CTL(pipe);
> +	temp = I915_READ(reg);
> +	temp &= ~FDI_LINK_TRAIN_NONE_IVB;
> +	temp |= FDI_LINK_TRAIN_PATTERN_2_IVB;
> +	temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
> +	temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
> +	I915_WRITE(reg, temp);
> +
> +	reg = FDI_RX_CTL(pipe);
> +	temp = I915_READ(reg);
> +	temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
> +	temp |= FDI_LINK_TRAIN_PATTERN_2_CPT;
> +	I915_WRITE(reg, temp);
> +
> +	POSTING_READ(reg);
> +	udelay(150);
> +
> +	for (i = 0; i < 4; i++ ) {
> +		reg = FDI_TX_CTL(pipe);
> +		temp = I915_READ(reg);
> +		temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
> +		temp |= snb_b_fdi_train_param[i];
> +		I915_WRITE(reg, temp);
> +
> +		POSTING_READ(reg);
> +		udelay(500);
> +
> +		reg = FDI_RX_IIR(pipe);
> +		temp = I915_READ(reg);
> +		DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
> +
> +		if (temp & FDI_RX_SYMBOL_LOCK) {
> +			I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK);
> +			DRM_DEBUG_KMS("FDI train 2 done.\n");
> +			break;
> +		}
> +	}
> +	if (i == 4)
> +		DRM_ERROR("FDI train 2 fail!\n");
> +
> +	DRM_DEBUG_KMS("FDI train done.\n");
> +}
> +
>  /* On Ivybridge we can use auto training */
>  static void ivb_fdi_link_train(struct drm_crtc *crtc)
>  {
> @@ -7367,7 +7486,11 @@ static void intel_init_display(struct drm_device *dev)
>  			}
>  			dev_priv->display.train_fdi = gen6_fdi_link_train;
>  		} else if (IS_IVYBRIDGE(dev)) {
> -			dev_priv->display.train_fdi = ivb_fdi_link_train;
> +			/* FIXME: detect B0+ stepping and use auto training */
> +			if (0)
> +				dev_priv->display.train_fdi = ivb_fdi_link_train;
> +			else
> +				dev_priv->display.train_fdi = ivb_manual_fdi_link_train;
>  		} else
>  			dev_priv->display.update_wm = NULL;
>  	} else if (IS_PINEVIEW(dev)) {
> -- 
> 1.7.4.1
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
keith.packard at intel.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20110427/9558beca/attachment.sig>


More information about the Intel-gfx mailing list