[Intel-gfx] Patch for testing irq spinning

Keith Packard keithp at keithp.com
Wed Dec 3 20:25:14 CET 2008


Here's a patch which switches from using pipestat to using iir to see
vblank interrupts. I'm wondering what this will do on machines where
people are seeing interrupts get stuck on (and then disabled by the
kernel).

If you're having any IRQ issues, please give this a try and let me know
what you discover.

From 3a395f1caab433222361a71c14d2d4d1b9557ea8 Mon Sep 17 00:00:00 2001
From: Keith Packard <keithp at keithp.com>
Date: Wed, 3 Dec 2008 11:20:20 -0800
Subject: [PATCH] drm/i915: use IIR to monitor vblank interrupts

Use the top-level interrupt registers in the irq_handler for vblank instead
of reading the pipestat registers.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 drivers/gpu/drm/i915/i915_irq.c |   42 ++++++++++++++++++--------------------
 1 files changed, 20 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index fe3d9cc..6166b15 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -45,7 +45,9 @@
 				   I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
 
 /** Interrupts that we mask and unmask at runtime. */
-#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
+#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT| \
+				   I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT| \
+				   I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
 
 /** These are all of the interrupts used by the driver */
 #define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \
@@ -71,6 +73,7 @@ i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
 	}
 }
 
+
 static inline u32
 i915_pipestat(int pipe)
 {
@@ -170,8 +173,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	u32 iir, new_iir;
 	u32 pipea_stats, pipeb_stats;
-	u32 vblank_status;
-	u32 vblank_enable;
 	int vblank = 0;
 	unsigned long irqflags;
 	int irq_received;
@@ -181,14 +182,6 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
 
 	iir = I915_READ(IIR);
 
-	if (IS_I965G(dev)) {
-		vblank_status = I915_START_VBLANK_INTERRUPT_STATUS;
-		vblank_enable = PIPE_START_VBLANK_INTERRUPT_ENABLE;
-	} else {
-		vblank_status = I915_VBLANK_INTERRUPT_STATUS;
-		vblank_enable = I915_VBLANK_INTERRUPT_ENABLE;
-	}
-
 	for (;;) {
 		irq_received = iir != 0;
 
@@ -231,12 +224,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
 			DRM_WAKEUP(&dev_priv->irq_queue);
 		}
 
-		if (pipea_stats & vblank_status) {
+		if (iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) {
 			vblank++;
 			drm_handle_vblank(dev, 0);
 		}
 
-		if (pipeb_stats & vblank_status) {
+		if (iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) {
 			vblank++;
 			drm_handle_vblank(dev, 1);
 		}
@@ -393,6 +386,14 @@ int i915_irq_wait(struct drm_device *dev, void *data,
 	return i915_wait_irq(dev, irqwait->irq_seq);
 }
 
+static int
+i915_pipe_vblank(int pipe)
+{
+	if (pipe == 1)
+		return I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
+	return I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
+}
+
 /* Called from drm generic code, passed 'crtc' which
  * we use as a pipe index
  */
@@ -401,13 +402,10 @@ int i915_enable_vblank(struct drm_device *dev, int pipe)
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	unsigned long irqflags;
 
+	DRM_ERROR("enable_vblank %d\n", pipe);
 	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
-	if (IS_I965G(dev))
-		i915_enable_pipestat(dev_priv, pipe,
-				     PIPE_START_VBLANK_INTERRUPT_ENABLE);
-	else
-		i915_enable_pipestat(dev_priv, pipe,
-				     PIPE_VBLANK_INTERRUPT_ENABLE);
+	i915_enable_irq(dev_priv, i915_pipe_vblank(pipe));
+	i915_enable_pipestat(dev_priv, pipe, I915_VBLANK_INTERRUPT_ENABLE);
 	spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
 	return 0;
 }
@@ -420,10 +418,10 @@ void i915_disable_vblank(struct drm_device *dev, int pipe)
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	unsigned long irqflags;
 
+	DRM_ERROR("disable_vblank %d\n", pipe);
 	spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
-	i915_disable_pipestat(dev_priv, pipe,
-			      PIPE_VBLANK_INTERRUPT_ENABLE |
-			      PIPE_START_VBLANK_INTERRUPT_ENABLE);
+	i915_disable_irq(dev_priv, i915_pipe_vblank(pipe));
+	i915_disable_pipestat(dev_priv, pipe, I915_VBLANK_INTERRUPT_ENABLE);
 	spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
 }
 
-- 
1.5.6.5


-- 
keith.packard at intel.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20081203/52a38ac9/attachment.sig>


More information about the Intel-gfx mailing list