diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2014-05-16 19:40:22 +0300 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-05-22 15:06:07 +0200 |
commit | 56b80e1f0022e34f8f92aee867aa8982889cda00 (patch) | |
tree | 0306e2ee87e1f0fd138de0df12ea55f3141fc565 /drivers/gpu/drm/i915/i915_irq.c | |
parent | e69abff0d6794311d834de0fa2f188eb24a977b9 (diff) | |
download | lwn-56b80e1f0022e34f8f92aee867aa8982889cda00.tar.gz lwn-56b80e1f0022e34f8f92aee867aa8982889cda00.zip |
drm/i915: Check for FIFO underruns at the end of modeset on gmch
FIFO underruns don't generate interrupts on gmch platforms, so
if we want to know whether a modeset triggered FIFO underruns we
need to explicitly check for them.
As a modeset on one pipe could cause underruns on other pipes,
check for underruns on all pipes.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Thomas Wood <thomas.wood@intel.com>
[danvet: Fix up merge error, kudos to Ville for noticing it.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 83ad4b43bcd6..57e86bae8f01 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -306,6 +306,34 @@ static bool cpt_can_enable_serr_int(struct drm_device *dev) return true; } +void i9xx_check_fifo_underruns(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *crtc; + unsigned long flags; + + spin_lock_irqsave(&dev_priv->irq_lock, flags); + + for_each_intel_crtc(dev, crtc) { + u32 reg = PIPESTAT(crtc->pipe); + u32 pipestat; + + if (crtc->cpu_fifo_underrun_disabled) + continue; + + pipestat = I915_READ(reg) & 0xffff0000; + if ((pipestat & PIPE_FIFO_UNDERRUN_STATUS) == 0) + continue; + + I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS); + POSTING_READ(reg); + + DRM_ERROR("pipe %c underrun\n", pipe_name(crtc->pipe)); + } + + spin_unlock_irqrestore(&dev_priv->irq_lock, flags); +} + static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev, enum pipe pipe, bool enable) { |