diff mbox

drm/i915: apply phase pointer override on SNB+ too

Message ID 1311961811-1813-1-git-send-email-jbarnes@virtuousgeek.org (mailing list archive)
State New, archived
Headers show

Commit Message

Jesse Barnes July 29, 2011, 5:50 p.m. UTC
These bits moved around on SNB and above.

v2: again with the git send-email fail
v3: add macros for getting per-pipe override & enable bits

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_reg.h      |    5 +++++
 drivers/gpu/drm/i915/intel_display.c |   28 +++++++++++++++++++++++++++-
 2 files changed, 32 insertions(+), 1 deletions(-)

Comments

Keith Packard July 29, 2011, 6:47 p.m. UTC | #1
On Fri, 29 Jul 2011 10:50:11 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:

> +	flags |= FDI_PHASE_SYNC_OVR(pipe);
> +	I915_WRITE(SOUTH_CHICKEN1, flags); /* once to unlock... */
> +	flags |= FDI_PHASE_SYNC_EN(pipe);
> +	I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to enable */
> +	POSTING_READ(SOUTH_CHICKEN1);
> +}

ooh, this even makes the sequence of two writes sound sensible.

Reviewed-by: Keith Packard <keithp@keithp.com>

You didn't happen to check the register values after doing this, did
you? Just to verify that all of the crazy math works, given that we
can't actually test whether this fixes anything.
Jesse Barnes July 29, 2011, 7:43 p.m. UTC | #2
On Fri, 29 Jul 2011 11:47:55 -0700
Keith Packard <keithp@keithp.com> wrote:

> On Fri, 29 Jul 2011 10:50:11 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> 
> > +	flags |= FDI_PHASE_SYNC_OVR(pipe);
> > +	I915_WRITE(SOUTH_CHICKEN1, flags); /* once to unlock... */
> > +	flags |= FDI_PHASE_SYNC_EN(pipe);
> > +	I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to enable */
> > +	POSTING_READ(SOUTH_CHICKEN1);
> > +}
> 
> ooh, this even makes the sequence of two writes sound sensible.
> 
> Reviewed-by: Keith Packard <keithp@keithp.com>
> 
> You didn't happen to check the register values after doing this, did
> you? Just to verify that all of the crazy math works, given that we
> can't actually test whether this fixes anything.
> 

Tricky.  I need to call this in the gen6 and ivb training routines
rather than the ilk one...  Bits seem to be getting set correctly with
the last patch.
diff mbox

Patch

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 00bd510..abab1f5 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3077,6 +3077,11 @@ 
 #define TRANS_CHICKEN2(pipe) _PIPE(pipe, _TRANSA_CHICKEN2, _TRANSB_CHICKEN2)
 #define   TRANS_AUTOTRAIN_GEN_STALL_DIS	(1<<31)
 
+#define SOUTH_CHICKEN1		0xc2000
+#define  FDIA_PHASE_SYNC_SHIFT_OVR	19
+#define  FDIA_PHASE_SYNC_SHIFT_EN	18
+#define FDI_PHASE_SYNC_OVR(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_OVR - ((pipe) * 2)))
+#define FDI_PHASE_SYNC_EN(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_EN - ((pipe) * 2)))
 #define SOUTH_CHICKEN2		0xc2004
 #define  DPLS_EDP_PPS_FIX_DIS	(1<<0)
 
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 8f7ed73..6f1dfc3 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2110,6 +2110,18 @@  static void intel_fdi_normal_train(struct drm_crtc *crtc)
 			   FDI_FE_ERRC_ENABLE);
 }
 
+static void cpt_phase_pointer_enable(struct drm_device *dev, int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 flags = I915_READ(SOUTH_CHICKEN1);
+
+	flags |= FDI_PHASE_SYNC_OVR(pipe);
+	I915_WRITE(SOUTH_CHICKEN1, flags); /* once to unlock... */
+	flags |= FDI_PHASE_SYNC_EN(pipe);
+	I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to enable */
+	POSTING_READ(SOUTH_CHICKEN1);
+}
+
 /* The FDI link training functions for ILK/Ibexpeak. */
 static void ironlake_fdi_link_train(struct drm_crtc *crtc)
 {
@@ -2157,7 +2169,8 @@  static void ironlake_fdi_link_train(struct drm_crtc *crtc)
 		I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR);
 		I915_WRITE(FDI_RX_CHICKEN(pipe), FDI_RX_PHASE_SYNC_POINTER_OVR |
 			   FDI_RX_PHASE_SYNC_POINTER_EN);
-	}
+	} else if (HAS_PCH_CPT(dev))
+		cpt_phase_pointer_enable(dev, pipe);
 
 	reg = FDI_RX_IIR(pipe);
 	for (tries = 0; tries < 5; tries++) {
@@ -2485,6 +2498,17 @@  static void ironlake_fdi_pll_enable(struct drm_crtc *crtc)
 	}
 }
 
+static void cpt_phase_pointer_disable(struct drm_device *dev, int pipe)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 flags = I915_READ(SOUTH_CHICKEN1);
+
+	flags &= ~(FDI_PHASE_SYNC_EN(pipe));
+	I915_WRITE(SOUTH_CHICKEN1, flags); /* once to disable... */
+	flags &= ~(FDI_PHASE_SYNC_OVR(pipe));
+	I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to lock */
+	POSTING_READ(SOUTH_CHICKEN1);
+}
 static void ironlake_fdi_disable(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
@@ -2514,6 +2538,8 @@  static void ironlake_fdi_disable(struct drm_crtc *crtc)
 		I915_WRITE(FDI_RX_CHICKEN(pipe),
 			   I915_READ(FDI_RX_CHICKEN(pipe) &
 				     ~FDI_RX_PHASE_SYNC_POINTER_EN));
+	} else if (HAS_PCH_CPT(dev)) {
+		cpt_phase_pointer_disable(dev, pipe);
 	}
 
 	/* still set train pattern 1 */