On Thu, 28 Apr 2011 15:12:55 -0700 Jesse Barnes <jbar...@virtuousgeek.org> wrote:
> Ivy Bridge supports auto-training on the CPU side, so add a separate > training function to handle it. > > Signed-off-by: Jesse Barnes <jbar...@virtuousgeek.org> > --- > drivers/gpu/drm/i915/i915_reg.h | 2 + > drivers/gpu/drm/i915/intel_display.c | 82 +++++++++++++++++++++++++++++++-- > 2 files changed, 79 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index aba3fe5..03c99ed 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -3116,6 +3116,8 @@ > #define FDI_LINK_TRAIN_AUTO (1<<10) > #define FDI_SCRAMBLING_ENABLE (0<<7) > #define FDI_SCRAMBLING_DISABLE (1<<7) > +/* Ivybridge */ > +#define FDI_AUTO_TRAIN_DONE (1<<1) > > /* FDI_RX, FDI_X is hard-wired to Transcoder_X */ > #define _FDI_RXA_CTL 0xf000c > diff --git a/drivers/gpu/drm/i915/intel_display.c > b/drivers/gpu/drm/i915/intel_display.c > index ab840a6..3396043 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -2411,6 +2411,75 @@ static void ivb_manual_fdi_link_train(struct drm_crtc > *crtc) > DRM_DEBUG_KMS("FDI train done.\n"); > } > > +/* On Ivybridge we can use auto training */ > +static void ivb_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); > + unsigned long start = jiffies_to_msecs(jiffies); > + int pipe = intel_crtc->pipe; > + u32 reg, temp, i, j; > + > + /* Can't pair IVB & Ibex Peak */ > + BUG_ON(HAS_PCH_IBX(dev)); > + > + reg = FDI_TX_CTL(pipe); > + temp = I915_READ(reg); > + temp &= ~(7 << 19); > + temp |= (intel_crtc->fdi_lanes - 1) << 19; > + temp &= ~FDI_LINK_TRAIN_NONE; > + I915_WRITE(reg, temp); > + > + /* Enable auto training on TX and RX */ > + for (i = 0; i < ARRAY_SIZE(snb_b_fdi_train_param); i++) { > + /* Try each vswing/pre-emphasis pair twice */ > + for (j = 0; j < 2; j++) { > + reg = FDI_TX_CTL(pipe); > + temp = I915_READ(reg); > + temp |= FDI_AUTO_TRAINING; > + temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK; > + temp |= snb_b_fdi_train_param[i]; > + I915_WRITE(reg, temp | FDI_TX_ENABLE); > + > + reg = FDI_RX_CTL(pipe); > + temp = I915_READ(reg); > + I915_WRITE(reg, temp | FDI_RX_ENABLE); > + POSTING_READ(reg); > + > + udelay(5); > + > + reg = FDI_TX_CTL(pipe); > + temp = I915_READ(reg); > + if ((temp & FDI_AUTO_TRAIN_DONE) || > + (I915_READ(reg) & FDI_AUTO_TRAIN_DONE)) { > + DRM_DEBUG_KMS("FDI auto train complete in %d > ms\n", > + jiffies_to_msecs(jiffies) - > start); > + goto done; > + } > + > + reg = FDI_TX_CTL(pipe); > + temp = I915_READ(reg); > + I915_WRITE(reg, temp & ~FDI_TX_ENABLE); > + > + reg = FDI_RX_CTL(pipe); > + temp = I915_READ(reg); > + I915_WRITE(reg, temp & ~FDI_RX_ENABLE); > + POSTING_READ(reg); > + udelay(31); /* wait idle time before retrying */ > + } > + } > + DRM_ERROR("FDI auto train failed\n"); > + return; > + > +done: > + reg = FDI_RX_CTL(pipe); > + temp = I915_READ(reg); > + temp |= FDI_FS_ERR_CORRECT_ENABLE | FDI_FE_ERR_CORRECT_ENABLE; > + I915_WRITE(reg, temp); > + POSTING_READ(reg); > +} > + > static void ironlake_fdi_pll_enable(struct drm_crtc *crtc) > { > struct drm_device *dev = crtc->dev; > @@ -2452,7 +2521,7 @@ static void ironlake_fdi_pll_enable(struct drm_crtc > *crtc) > } > } > > -static void ironlake_fdi_disable(struct drm_crtc *crtc) > +static void ironlake_fdi_pll_disable(struct drm_crtc *crtc) > { > struct drm_device *dev = crtc->dev; > struct drm_i915_private *dev_priv = dev->dev_private; > @@ -2674,9 +2743,9 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) > is_pch_port = intel_crtc_driving_pch(crtc); > > if (is_pch_port) > - ironlake_fdi_enable(crtc); > + ironlake_fdi_pll_enable(crtc); > else > - ironlake_fdi_disable(crtc); > + ironlake_fdi_pll_disable(crtc); > > /* Enable panel fitting for LVDS */ > if (dev_priv->pch_pf_size && > @@ -2729,7 +2798,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) > I915_WRITE(PF_CTL(pipe), 0); > I915_WRITE(PF_WIN_SZ(pipe), 0); > > - ironlake_fdi_disable(crtc); > + ironlake_fdi_pll_disable(crtc); arg, screwed up the rebase here; the fdi_pll name change needs to stay together. -- Jesse Barnes, Intel Open Source Technology Center _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx