Skip to content

Commit

Permalink
i915: Enable IMR passthrough of vblank events before enabling it in p…
Browse files Browse the repository at this point in the history
…ipestat.

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>
  • Loading branch information
Eric Anholt authored and Dave Airlie committed Oct 23, 2008
1 parent 35ad68c commit 053d7f2
Showing 1 changed file with 9 additions and 1 deletion.
10 changes: 9 additions & 1 deletion drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,15 @@ int i915_enable_vblank(struct drm_device *dev, int plane)
}

spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
/* Enabling vblank events in IMR comes before PIPESTAT write, or
* there's a race where the PIPESTAT vblank bit gets set to 1, so
* the OR of enabled PIPESTAT bits goes to 1, so the PIPExEVENT in
* ISR flashes to 1, but the IIR bit doesn't get set to 1 because
* IMR masks it. It doesn't ever get set after we clear the masking
* in IMR because the ISR bit is edge, not level-triggered, on the
* OR of PIPESTAT bits.
*/
i915_enable_irq(dev_priv, interrupt);
pipestat = I915_READ(pipestat_reg);
if (IS_I965G(dev))
pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE;
Expand All @@ -615,7 +624,6 @@ int i915_enable_vblank(struct drm_device *dev, int plane)
PIPE_VBLANK_INTERRUPT_STATUS);
I915_WRITE(pipestat_reg, pipestat);
(void) I915_READ(pipestat_reg); /* Posting read */
i915_enable_irq(dev_priv, interrupt);
spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);

return 0;
Expand Down

0 comments on commit 053d7f2

Please sign in to comment.