On Tue, 26 Apr 2011 16:38:49 -0700, Jesse Barnes <jbar...@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 <jbar...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- keith.pack...@intel.com
pgpW6vQhJQcOg.pgp
Description: PGP signature
_______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx