Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 119393
b: refs/heads/master
c: 05eff84
h: refs/heads/master
i:
  119391: f9a319e
v: v3
  • Loading branch information
Keith Packard authored and Dave Airlie committed Nov 24, 2008
1 parent e00b0d0 commit ed19629
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 20 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2678d9d6964b29ecd1975870c7a850242b29bc5c
refs/heads/master: 05eff845a28499762075d3a72e238a31f4d2407c
55 changes: 36 additions & 19 deletions trunk/drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,37 +170,54 @@ 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;
int ret = IRQ_NONE;

atomic_inc(&dev_priv->irq_received);

iir = I915_READ(IIR);

if (iir == 0)
return IRQ_NONE;
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;
}

do {
pipea_stats = 0;
pipeb_stats = 0;
for (;;) {
irq_received = iir != 0;

/* Can't rely on pipestat interrupt bit in iir as it might
* have been cleared after the pipestat interrupt was received.
* It doesn't set the bit in iir again, but it still produces
* interrupts (for non-MSI).
*/
spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
pipea_stats = I915_READ(PIPEASTAT);
pipeb_stats = I915_READ(PIPEBSTAT);
/*
* Clear the PIPE(A|B)STAT regs before the IIR
*/
if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
pipea_stats = I915_READ(PIPEASTAT);
if (pipea_stats & 0x8000ffff) {
I915_WRITE(PIPEASTAT, pipea_stats);
spin_unlock_irqrestore(&dev_priv->user_irq_lock,
irqflags);
irq_received = 1;
}

if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
pipeb_stats = I915_READ(PIPEBSTAT);
if (pipeb_stats & 0x8000ffff) {
I915_WRITE(PIPEBSTAT, pipeb_stats);
spin_unlock_irqrestore(&dev_priv->user_irq_lock,
irqflags);
irq_received = 1;
}
spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);

if (!irq_received)
break;

ret = IRQ_HANDLED;

I915_WRITE(IIR, iir);
new_iir = I915_READ(IIR); /* Flush posted writes */
Expand All @@ -214,12 +231,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
DRM_WAKEUP(&dev_priv->irq_queue);
}

if (pipea_stats & I915_VBLANK_INTERRUPT_STATUS) {
if (pipea_stats & vblank_status) {
vblank++;
drm_handle_vblank(dev, 0);
}

if (pipeb_stats & I915_VBLANK_INTERRUPT_STATUS) {
if (pipeb_stats & vblank_status) {
vblank++;
drm_handle_vblank(dev, 1);
}
Expand All @@ -244,9 +261,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
* stray interrupts.
*/
iir = new_iir;
} while (iir != 0);
}

return IRQ_HANDLED;
return ret;
}

static int i915_emit_irq(struct drm_device * dev)
Expand Down

0 comments on commit ed19629

Please sign in to comment.