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 <[EMAIL PROTECTED]>
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 <[EMAIL PROTECTED]>
---
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
--
[EMAIL PROTECTED]
signature.asc
Description: This is a digitally signed message part
------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/
-- _______________________________________________ Dri-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/dri-devel
