intel-gfx.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/7] drm/i915: automatic FDI training support for Ivy Bridge
@ 2011-04-26 23:51 Jesse Barnes
  2011-04-26 23:51 ` [PATCH 2/7] drm/i915: manual FDI training " Jesse Barnes
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Jesse Barnes @ 2011-04-26 23:51 UTC (permalink / raw)
  To: intel-gfx

Ivy Bridge supports auto-training on the CPU side, so add a separate
training function to handle it.

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

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 8848411..b77bd49 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3108,6 +3108,8 @@
 /* both Tx and Rx */
 #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 6455e0e..db46e4f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2292,7 +2292,76 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
 	DRM_DEBUG_KMS("FDI train done.\n");
 }
 
-static void ironlake_fdi_enable(struct drm_crtc *crtc)
+/* 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;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2333,7 +2402,7 @@ static void ironlake_fdi_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;
@@ -2555,9 +2624,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 &&
@@ -2610,7 +2679,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
 	 * the connector/encoder ->prepare instead, but we don't always have
@@ -7297,6 +7366,8 @@ static void intel_init_display(struct drm_device *dev)
 				dev_priv->display.update_wm = NULL;
 			}
 			dev_priv->display.train_fdi = gen6_fdi_link_train;
+		} else if (IS_IVYBRIDGE(dev)) {
+			dev_priv->display.train_fdi = ivb_fdi_link_train;
 		} else
 			dev_priv->display.update_wm = NULL;
 	} else if (IS_PINEVIEW(dev)) {
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/7] drm/i915: manual FDI training for Ivy Bridge
  2011-04-26 23:51 [PATCH 1/7] drm/i915: automatic FDI training support for Ivy Bridge Jesse Barnes
@ 2011-04-26 23:51 ` Jesse Barnes
  2011-04-26 23:51 ` [PATCH 3/7] drm/i915: treat Ivy Bridge watermarks like Sandy Bridge Jesse Barnes
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Jesse Barnes @ 2011-04-26 23:51 UTC (permalink / raw)
  To: intel-gfx

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.

Signed-off-by: Jesse Barnes <jbarnes@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

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/7] drm/i915: treat Ivy Bridge watermarks like Sandy Bridge
  2011-04-26 23:51 [PATCH 1/7] drm/i915: automatic FDI training support for Ivy Bridge Jesse Barnes
  2011-04-26 23:51 ` [PATCH 2/7] drm/i915: manual FDI training " Jesse Barnes
@ 2011-04-26 23:51 ` Jesse Barnes
  2011-04-26 23:51 ` [PATCH 4/7] drm/i915: interrupt & vblank support for Ivy Bridge Jesse Barnes
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Jesse Barnes @ 2011-04-26 23:51 UTC (permalink / raw)
  To: intel-gfx

Not fully tested.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_display.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 866abe5..908c4d9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7229,7 +7229,7 @@ void intel_enable_clock_gating(struct drm_device *dev)
 				   _3D_CHICKEN2_WM_READ_PIPELINED);
 		}
 
-		if (IS_GEN6(dev)) {
+		if (IS_GEN6(dev) || IS_IVYBRIDGE(dev)) {
 			I915_WRITE(WM3_LP_ILK, 0);
 			I915_WRITE(WM2_LP_ILK, 0);
 			I915_WRITE(WM1_LP_ILK, 0);
@@ -7491,6 +7491,13 @@ static void intel_init_display(struct drm_device *dev)
 				dev_priv->display.train_fdi = ivb_fdi_link_train;
 			else
 				dev_priv->display.train_fdi = ivb_manual_fdi_link_train;
+			if (SNB_READ_WM0_LATENCY()) {
+				dev_priv->display.update_wm = sandybridge_update_wm;
+			} else {
+				DRM_DEBUG_KMS("Failed to read display plane latency. "
+					      "Disable CxSR\n");
+				dev_priv->display.update_wm = NULL;
+			}
 		} else
 			dev_priv->display.update_wm = NULL;
 	} else if (IS_PINEVIEW(dev)) {
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/7] drm/i915: interrupt & vblank support for Ivy Bridge
  2011-04-26 23:51 [PATCH 1/7] drm/i915: automatic FDI training support for Ivy Bridge Jesse Barnes
  2011-04-26 23:51 ` [PATCH 2/7] drm/i915: manual FDI training " Jesse Barnes
  2011-04-26 23:51 ` [PATCH 3/7] drm/i915: treat Ivy Bridge watermarks like Sandy Bridge Jesse Barnes
@ 2011-04-26 23:51 ` Jesse Barnes
  2011-04-26 23:51 ` [PATCH 5/7] drm/i915: page flip " Jesse Barnes
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Jesse Barnes @ 2011-04-26 23:51 UTC (permalink / raw)
  To: intel-gfx

Add new interrupt handling functions for Ivy Bridge.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/i915_dma.c |   12 +++-
 drivers/gpu/drm/i915/i915_drv.h |    7 ++
 drivers/gpu/drm/i915/i915_irq.c |  156 +++++++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_reg.h |   13 +++
 4 files changed, 186 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index d124f0e..8e27bc4 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1253,7 +1253,15 @@ static int i915_load_modeset_init(struct drm_device *dev)
 
 	intel_modeset_init(dev);
 
-	if (HAS_PCH_SPLIT(dev)) {
+	if (IS_IVYBRIDGE(dev)) {
+		/* Share pre & uninstall handlers with ILK/SNB */
+		dev->driver->irq_handler = ivybridge_irq_handler;
+		dev->driver->irq_preinstall = ironlake_irq_preinstall;
+		dev->driver->irq_postinstall = ivybridge_irq_postinstall;
+		dev->driver->irq_uninstall = ironlake_irq_uninstall;
+		dev->driver->enable_vblank = ivybridge_enable_vblank;
+		dev->driver->disable_vblank = ivybridge_disable_vblank;
+	} else if (HAS_PCH_SPLIT(dev)) {
 		dev->driver->irq_handler = ironlake_irq_handler;
 		dev->driver->irq_preinstall = ironlake_irq_preinstall;
 		dev->driver->irq_postinstall = ironlake_irq_postinstall;
@@ -1998,7 +2006,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
 	dev->driver->get_vblank_counter = i915_get_vblank_counter;
 	dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
-	if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev)) {
+	if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev)) {
 		dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
 		dev->driver->get_vblank_counter = gm45_get_vblank_counter;
 	}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e596c10..7be7893 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1033,6 +1033,11 @@ extern void ironlake_irq_preinstall(struct drm_device *dev);
 extern int ironlake_irq_postinstall(struct drm_device *dev);
 extern void ironlake_irq_uninstall(struct drm_device *dev);
 
+extern irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS);
+extern void ivybridge_irq_preinstall(struct drm_device *dev);
+extern int ivybridge_irq_postinstall(struct drm_device *dev);
+extern void ivybridge_irq_uninstall(struct drm_device *dev);
+
 extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
 				struct drm_file *file_priv);
 extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
@@ -1041,6 +1046,8 @@ extern int i915_enable_vblank(struct drm_device *dev, int crtc);
 extern void i915_disable_vblank(struct drm_device *dev, int crtc);
 extern int ironlake_enable_vblank(struct drm_device *dev, int crtc);
 extern void ironlake_disable_vblank(struct drm_device *dev, int crtc);
+extern int ivybridge_enable_vblank(struct drm_device *dev, int crtc);
+extern void ivybridge_disable_vblank(struct drm_device *dev, int crtc);
 extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
 extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc);
 extern int i915_vblank_swap(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index d5dcb8f..a025002 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -448,6 +448,85 @@ static void pch_irq_handler(struct drm_device *dev)
 		DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n");
 }
 
+irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
+{
+	struct drm_device *dev = (struct drm_device *) arg;
+	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+	int ret = IRQ_NONE;
+	u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir;
+	struct drm_i915_master_private *master_priv;
+
+	atomic_inc(&dev_priv->irq_received);
+
+	/* disable master interrupt before clearing iir  */
+	de_ier = I915_READ(DEIER);
+	I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
+	POSTING_READ(DEIER);
+
+	de_iir = I915_READ(DEIIR);
+	gt_iir = I915_READ(GTIIR);
+	pch_iir = I915_READ(SDEIIR);
+	pm_iir = I915_READ(GEN6_PMIIR);
+
+	if (de_iir == 0 && gt_iir == 0 && pch_iir == 0 && pm_iir == 0)
+		goto done;
+
+	ret = IRQ_HANDLED;
+
+	if (dev->primary->master) {
+		master_priv = dev->primary->master->driver_priv;
+		if (master_priv->sarea_priv)
+			master_priv->sarea_priv->last_dispatch =
+				READ_BREADCRUMB(dev_priv);
+	}
+
+	if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY))
+		notify_ring(dev, &dev_priv->ring[RCS]);
+	if (gt_iir & GT_GEN6_BSD_USER_INTERRUPT)
+		notify_ring(dev, &dev_priv->ring[VCS]);
+	if (gt_iir & GT_BLT_USER_INTERRUPT)
+		notify_ring(dev, &dev_priv->ring[BCS]);
+
+	if (de_iir & DE_GSE_IVB)
+		intel_opregion_gse_intr(dev);
+
+	if (de_iir & DE_PLANEA_FLIP_DONE_IVB) {
+		intel_prepare_page_flip(dev, 0);
+		intel_finish_page_flip_plane(dev, 0);
+	}
+
+	if (de_iir & DE_PLANEB_FLIP_DONE_IVB) {
+		intel_prepare_page_flip(dev, 1);
+		intel_finish_page_flip_plane(dev, 1);
+	}
+
+	if (de_iir & DE_PIPEA_VBLANK_IVB)
+		drm_handle_vblank(dev, 0);
+
+	if (de_iir & DE_PIPEB_VBLANK_IVB);
+		drm_handle_vblank(dev, 1);
+
+	/* check event from PCH */
+	if (de_iir & DE_PCH_EVENT_IVB) {
+		if (pch_iir & SDE_HOTPLUG_MASK_CPT)
+			queue_work(dev_priv->wq, &dev_priv->hotplug_work);
+		pch_irq_handler(dev);
+	}
+
+	gen6_pm_irq_handler(dev);
+
+	/* should clear PCH hotplug event before clear CPU irq */
+	I915_WRITE(SDEIIR, pch_iir);
+	I915_WRITE(GTIIR, gt_iir);
+	I915_WRITE(DEIIR, de_iir);
+
+done:
+	I915_WRITE(DEIER, de_ier);
+	POSTING_READ(DEIER);
+
+	return ret;
+}
+
 irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
 {
 	struct drm_device *dev = (struct drm_device *) arg;
@@ -1375,6 +1454,22 @@ int ironlake_enable_vblank(struct drm_device *dev, int pipe)
 	return 0;
 }
 
+int ivybridge_enable_vblank(struct drm_device *dev, int pipe)
+{
+	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+	unsigned long irqflags;
+
+	if (!i915_pipe_enabled(dev, pipe))
+		return -EINVAL;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+	ironlake_enable_display_irq(dev_priv, (pipe == 0) ?
+				    DE_PIPEA_VBLANK_IVB : DE_PIPEB_VBLANK_IVB);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+
+	return 0;
+}
+
 /* Called from drm generic code, passed 'crtc' which
  * we use as a pipe index
  */
@@ -1405,6 +1500,17 @@ void ironlake_disable_vblank(struct drm_device *dev, int pipe)
 	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
 }
 
+void ivybridge_disable_vblank(struct drm_device *dev, int pipe)
+{
+	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+	ironlake_disable_display_irq(dev_priv, (pipe == 0) ?
+				     DE_PIPEA_VBLANK_IVB : DE_PIPEB_VBLANK_IVB);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+}
+
 /* Set the vblank monitor pipe
  */
 int i915_vblank_pipe_set(struct drm_device *dev, void *data,
@@ -1682,6 +1788,56 @@ int ironlake_irq_postinstall(struct drm_device *dev)
 	return 0;
 }
 
+int ivybridge_irq_postinstall(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+	/* enable kind of interrupts always enabled */
+	u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE_IVB |
+		DE_PCH_EVENT_IVB | DE_PLANEA_FLIP_DONE_IVB |
+		DE_PLANEB_FLIP_DONE_IVB;
+	u32 render_irqs;
+	u32 hotplug_mask;
+
+	DRM_INIT_WAITQUEUE(&dev_priv->ring[RCS].irq_queue);
+	if (HAS_BSD(dev))
+		DRM_INIT_WAITQUEUE(&dev_priv->ring[VCS].irq_queue);
+	if (HAS_BLT(dev))
+		DRM_INIT_WAITQUEUE(&dev_priv->ring[BCS].irq_queue);
+
+	dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
+	dev_priv->irq_mask = ~display_mask;
+
+	/* should always can generate irq */
+	I915_WRITE(DEIIR, I915_READ(DEIIR));
+	I915_WRITE(DEIMR, dev_priv->irq_mask);
+	I915_WRITE(DEIER, display_mask | DE_PIPEA_VBLANK_IVB |
+		   DE_PIPEB_VBLANK_IVB);
+	POSTING_READ(DEIER);
+
+	dev_priv->gt_irq_mask = ~0;
+
+	I915_WRITE(GTIIR, I915_READ(GTIIR));
+	I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
+
+	render_irqs = GT_USER_INTERRUPT | GT_GEN6_BSD_USER_INTERRUPT |
+		GT_BLT_USER_INTERRUPT;
+	I915_WRITE(GTIER, render_irqs);
+	POSTING_READ(GTIER);
+
+	hotplug_mask = (SDE_CRT_HOTPLUG_CPT |
+			SDE_PORTB_HOTPLUG_CPT |
+			SDE_PORTC_HOTPLUG_CPT |
+			SDE_PORTD_HOTPLUG_CPT);
+	dev_priv->pch_irq_mask = ~hotplug_mask;
+
+	I915_WRITE(SDEIIR, I915_READ(SDEIIR));
+	I915_WRITE(SDEIMR, dev_priv->pch_irq_mask);
+	I915_WRITE(SDEIER, hotplug_mask);
+	POSTING_READ(SDEIER);
+
+	return 0;
+}
+
 void i915_driver_irq_preinstall(struct drm_device * dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 03c99ed..6d4e671 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2779,6 +2779,19 @@
 #define DE_PIPEA_VSYNC          (1 << 3)
 #define DE_PIPEA_FIFO_UNDERRUN  (1 << 0)
 
+/* More Ivybridge lolz */
+#define DE_ERR_DEBUG_IVB		(1<<30)
+#define DE_GSE_IVB			(1<<29)
+#define DE_PCH_EVENT_IVB		(1<<28)
+#define DE_DP_A_HOTPLUG_IVB		(1<<27)
+#define DE_AUX_CHANNEL_A_IVB		(1<<26)
+#define DE_SPRITEB_FLIP_DONE_IVB	(1<<9)
+#define DE_SPRITEA_FLIP_DONE_IVB	(1<<4)
+#define DE_PLANEB_FLIP_DONE_IVB		(1<<8)
+#define DE_PLANEA_FLIP_DONE_IVB		(1<<3)
+#define DE_PIPEB_VBLANK_IVB		(1<<5)
+#define DE_PIPEA_VBLANK_IVB		(1<<0)
+
 #define DEISR   0x44000
 #define DEIMR   0x44004
 #define DEIIR   0x44008
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/7] drm/i915: page flip support for Ivy Bridge
  2011-04-26 23:51 [PATCH 1/7] drm/i915: automatic FDI training support for Ivy Bridge Jesse Barnes
                   ` (2 preceding siblings ...)
  2011-04-26 23:51 ` [PATCH 4/7] drm/i915: interrupt & vblank support for Ivy Bridge Jesse Barnes
@ 2011-04-26 23:51 ` Jesse Barnes
  2011-04-26 23:51 ` [PATCH 6/7] drm/i915: untested DP " Jesse Barnes
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Jesse Barnes @ 2011-04-26 23:51 UTC (permalink / raw)
  To: intel-gfx

Treat Ivy Bridge like previous chips as far as flip submission is
concerned.

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

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 908c4d9..6b24947 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -6362,6 +6362,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
 		break;
 
 	case 6:
+	case 7:
 		OUT_RING(MI_DISPLAY_FLIP |
 			 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
 		OUT_RING(fb->pitch | obj->tiling_mode);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/7] drm/i915: untested DP support for Ivy Bridge
  2011-04-26 23:51 [PATCH 1/7] drm/i915: automatic FDI training support for Ivy Bridge Jesse Barnes
                   ` (3 preceding siblings ...)
  2011-04-26 23:51 ` [PATCH 5/7] drm/i915: page flip " Jesse Barnes
@ 2011-04-26 23:51 ` Jesse Barnes
  2011-04-26 23:51 ` [PATCH 7/7] drm/i915: ring " Jesse Barnes
  2011-04-27  0:06 ` [PATCH 1/7] drm/i915: automatic FDI training " Jesse Barnes
  6 siblings, 0 replies; 10+ messages in thread
From: Jesse Barnes @ 2011-04-26 23:51 UTC (permalink / raw)
  To: intel-gfx

Treat it like Sandy Bridge in a few places.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_dp.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 0daefca..1d0eccd 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -312,7 +312,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
 	else
 		aux_clock_divider = intel_hrawclk(dev) / 2;
 
-	if (IS_GEN6(dev))
+	if (IS_GEN6(dev) || IS_GEN7(dev))
 		precharge = 3;
 	else
 		precharge = 5;
@@ -1302,7 +1302,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
 	for (;;) {
 		/* Use intel_dp->train_set[0] to set the voltage and pre emphasis values */
 		uint32_t    signal_levels;
-		if (IS_GEN6(dev) && is_edp(intel_dp)) {
+		if ((IS_GEN6(dev) || IS_GEN7(dev)) && is_edp(intel_dp)) {
 			signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
 			DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
 		} else {
@@ -1376,7 +1376,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp)
 			break;
 		}
 
-		if (IS_GEN6(dev) && is_edp(intel_dp)) {
+		if ((IS_GEN6(dev) || IS_GEN7(dev)) && is_edp(intel_dp)) {
 			signal_levels = intel_gen6_edp_signal_levels(intel_dp->train_set[0]);
 			DP = (DP & ~EDP_LINK_TRAIN_VOL_EMP_MASK_SNB) | signal_levels;
 		} else {
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 7/7] drm/i915: ring support for Ivy Bridge
  2011-04-26 23:51 [PATCH 1/7] drm/i915: automatic FDI training support for Ivy Bridge Jesse Barnes
                   ` (4 preceding siblings ...)
  2011-04-26 23:51 ` [PATCH 6/7] drm/i915: untested DP " Jesse Barnes
@ 2011-04-26 23:51 ` Jesse Barnes
  2011-04-27  0:06 ` [PATCH 1/7] drm/i915: automatic FDI training " Jesse Barnes
  6 siblings, 0 replies; 10+ messages in thread
From: Jesse Barnes @ 2011-04-26 23:51 UTC (permalink / raw)
  To: intel-gfx

Use Sandy Bridge paths in a few places.

Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
---
 drivers/gpu/drm/i915/intel_ringbuffer.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index f15d80f..9bcfb9b 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -287,7 +287,7 @@ static int init_render_ring(struct intel_ring_buffer *ring)
 
 	if (INTEL_INFO(dev)->gen > 3) {
 		int mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH;
-		if (IS_GEN6(dev))
+		if (IS_GEN6(dev) || IS_GEN7(dev))
 			mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE;
 		I915_WRITE(MI_MODE, mode);
 	}
@@ -553,7 +553,7 @@ render_ring_put_irq(struct intel_ring_buffer *ring)
 void intel_ring_setup_status_page(struct intel_ring_buffer *ring)
 {
 	drm_i915_private_t *dev_priv = ring->dev->dev_private;
-	u32 mmio = IS_GEN6(ring->dev) ?
+	u32 mmio = (IS_GEN6(ring->dev) || IS_GEN7(ring->dev)) ?
 		RING_HWS_PGA_GEN6(ring->mmio_base) :
 		RING_HWS_PGA(ring->mmio_base);
 	I915_WRITE(mmio, (u32)ring->status_page.gfx_addr);
@@ -1335,7 +1335,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	struct intel_ring_buffer *ring = &dev_priv->ring[VCS];
 
-	if (IS_GEN6(dev))
+	if (IS_GEN6(dev) || IS_GEN7(dev))
 		*ring = gen6_bsd_ring;
 	else
 		*ring = bsd_ring;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/7] drm/i915: automatic FDI training support for Ivy Bridge
  2011-04-26 23:51 [PATCH 1/7] drm/i915: automatic FDI training support for Ivy Bridge Jesse Barnes
                   ` (5 preceding siblings ...)
  2011-04-26 23:51 ` [PATCH 7/7] drm/i915: ring " Jesse Barnes
@ 2011-04-27  0:06 ` Jesse Barnes
  2011-04-27  6:19   ` Chris Wilson
  6 siblings, 1 reply; 10+ messages in thread
From: Jesse Barnes @ 2011-04-27  0:06 UTC (permalink / raw)
  Cc: intel-gfx

You can ignore this set; I only sent it because I thought the others
wouldn't come through.

-- 
Jesse Barnes, Intel Open Source Technology Center

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/7] drm/i915: automatic FDI training support for Ivy Bridge
  2011-04-27  0:06 ` [PATCH 1/7] drm/i915: automatic FDI training " Jesse Barnes
@ 2011-04-27  6:19   ` Chris Wilson
  2011-04-27 20:52     ` Jesse Barnes
  0 siblings, 1 reply; 10+ messages in thread
From: Chris Wilson @ 2011-04-27  6:19 UTC (permalink / raw)
  To: Jesse Barnes; +Cc: intel-gfx

On Tue, 26 Apr 2011 17:06:01 -0700, Jesse Barnes <jbarnes@virtuousgeek.org> wrote:
> You can ignore this set; I only sent it because I thought the others
> wouldn't come through.

Before I find the others... Do they treat IS_IVYBRIDGE() vs IS_GEN7
consistently? Do they have sufficient debug and self-tests?

Can we split intel_enable_clock_gating() up into several "little"
functions that address the peculiarity of each generation individually?
-Chris

-- 
Chris Wilson, Intel Open Source Technology Centre

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/7] drm/i915: automatic FDI training support for Ivy Bridge
  2011-04-27  6:19   ` Chris Wilson
@ 2011-04-27 20:52     ` Jesse Barnes
  0 siblings, 0 replies; 10+ messages in thread
From: Jesse Barnes @ 2011-04-27 20:52 UTC (permalink / raw)
  To: Chris Wilson, intel-gfx

On 4/26/2011 11:19 PM, Chris Wilson wrote:
>  On Tue, 26 Apr 2011 17:06:01 -0700, Jesse Barnes
>  <jbarnes@virtuousgeek.org> wrote:
> > You can ignore this set; I only sent it because I thought the
> > others wouldn't come through.
>
>  Before I find the others... Do they treat IS_IVYBRIDGE() vs IS_GEN7
>  consistently? Do they have sufficient debug and self-tests?

I think so, another audit wouldn't hurt though (generally I used IS_IVB 
for display related checks ans IS_GEN7 for render related differences).

>  Can we split intel_enable_clock_gating() up into several "little"
>  functions that address the peculiarity of each generation
>  individually? -Chris

Yes, that's probably a good idea.

Jesse

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2011-04-27 20:52 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-26 23:51 [PATCH 1/7] drm/i915: automatic FDI training support for Ivy Bridge Jesse Barnes
2011-04-26 23:51 ` [PATCH 2/7] drm/i915: manual FDI training " Jesse Barnes
2011-04-26 23:51 ` [PATCH 3/7] drm/i915: treat Ivy Bridge watermarks like Sandy Bridge Jesse Barnes
2011-04-26 23:51 ` [PATCH 4/7] drm/i915: interrupt & vblank support for Ivy Bridge Jesse Barnes
2011-04-26 23:51 ` [PATCH 5/7] drm/i915: page flip " Jesse Barnes
2011-04-26 23:51 ` [PATCH 6/7] drm/i915: untested DP " Jesse Barnes
2011-04-26 23:51 ` [PATCH 7/7] drm/i915: ring " Jesse Barnes
2011-04-27  0:06 ` [PATCH 1/7] drm/i915: automatic FDI training " Jesse Barnes
2011-04-27  6:19   ` Chris Wilson
2011-04-27 20:52     ` Jesse Barnes

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).