aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-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;