[Intel-gfx] [PATCH 09/19] drm/i915: automatic FDI training support for Ivy Bridge

2011-04-28 Thread Jesse Barnes
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   (110)
 #define  FDI_SCRAMBLING_ENABLE  (07)
 #define  FDI_SCRAMBLING_DISABLE (17)
+/* Ivybridge */
+#define  FDI_AUTO_TRAIN_DONE   (11)
 
 /* 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);
 
/* This is a horrible layering violation; we should be doing this in
  

Re: [Intel-gfx] [PATCH 09/19] drm/i915: automatic FDI training support for Ivy Bridge

2011-04-28 Thread Jesse Barnes
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 (110)
  #define  FDI_SCRAMBLING_ENABLE  (07)
  #define  FDI_SCRAMBLING_DISABLE (17)
 +/* Ivybridge */
 +#define  FDI_AUTO_TRAIN_DONE (11)
  
  /* 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, 

Re: [Intel-gfx] [PATCH 09/19] drm/i915: automatic FDI training support for Ivy Bridge

2011-04-28 Thread Keith Packard
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.

Let's leave this out of the kernel until we have hardware that actually
uses it.

-- 
keith.pack...@intel.com


pgpBSTIApdDAP.pgp
Description: PGP signature
___
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx