aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2008-10-17 18:41:26 -0400
committerDave Airlie <airlied@redhat.com>2008-10-22 23:42:27 -0400
commit053d7f244a8739d96d316c77a97cd063804c8e35 (patch)
tree009b443222c13585db343f4ece1a70b0bd28aa42 /drivers/gpu/drm
parent35ad68c18148a18938ff4f40e945c9734e7d2265 (diff)
i915: Enable IMR passthrough of vblank events before enabling it in pipestat.
Otherwise, if we lost the race, the pipestat bit would be set without being reflected in IIR, and we would never clear the pipestat bit so the pipe event would never be generated again, and all vblank waits would time out. Signed-off-by: Eric Anholt <eric@anholt.net> Acked-by: Keith Packard <keithp@keithp.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 2cd853b2c562..ca55c40353a5 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -605,6 +605,15 @@ int i915_enable_vblank(struct drm_device *dev, int plane)
605 } 605 }
606 606
607 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); 607 spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
608 /* Enabling vblank events in IMR comes before PIPESTAT write, or
609 * there's a race where the PIPESTAT vblank bit gets set to 1, so
610 * the OR of enabled PIPESTAT bits goes to 1, so the PIPExEVENT in
611 * ISR flashes to 1, but the IIR bit doesn't get set to 1 because
612 * IMR masks it. It doesn't ever get set after we clear the masking
613 * in IMR because the ISR bit is edge, not level-triggered, on the
614 * OR of PIPESTAT bits.
615 */
616 i915_enable_irq(dev_priv, interrupt);
608 pipestat = I915_READ(pipestat_reg); 617 pipestat = I915_READ(pipestat_reg);
609 if (IS_I965G(dev)) 618 if (IS_I965G(dev))
610 pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE; 619 pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE;
@@ -615,7 +624,6 @@ int i915_enable_vblank(struct drm_device *dev, int plane)
615 PIPE_VBLANK_INTERRUPT_STATUS); 624 PIPE_VBLANK_INTERRUPT_STATUS);
616 I915_WRITE(pipestat_reg, pipestat); 625 I915_WRITE(pipestat_reg, pipestat);
617 (void) I915_READ(pipestat_reg); /* Posting read */ 626 (void) I915_READ(pipestat_reg); /* Posting read */
618 i915_enable_irq(dev_priv, interrupt);
619 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); 627 spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
620 628
621 return 0; 629 return 0;