return true;
}
+static void i9xx_clear_fifo_underrun(struct drm_device *dev, enum pipe pipe)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ u32 reg = PIPESTAT(pipe);
+ u32 pipestat = I915_READ(reg) & 0x7fff0000;
+
+ assert_spin_locked(&dev_priv->irq_lock);
+
+ I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS);
+ POSTING_READ(reg);
+}
+
static void ironlake_set_fifo_underrun_reporting(struct drm_device *dev,
enum pipe pipe, bool enable)
{
intel_crtc->cpu_fifo_underrun_disabled = !enable;
- if (IS_GEN5(dev) || IS_GEN6(dev))
+ if (enable && (INTEL_INFO(dev)->gen < 5 || IS_VALLEYVIEW(dev)))
+ i9xx_clear_fifo_underrun(dev, pipe);
+ else if (IS_GEN5(dev) || IS_GEN6(dev))
ironlake_set_fifo_underrun_reporting(dev, pipe, enable);
else if (IS_GEN7(dev))
ivybridge_set_fifo_underrun_reporting(dev, pipe, enable);
/*
* Clear the PIPE*STAT regs before the IIR
*/
- if (pipe_stats[pipe] & 0x8000ffff) {
- if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
- DRM_DEBUG_DRIVER("pipe %c underrun\n",
- pipe_name(pipe));
+ if (pipe_stats[pipe] & 0x8000ffff)
I915_WRITE(reg, pipe_stats[pipe]);
- }
}
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
i9xx_pipe_crc_irq_handler(dev, pipe);
+
+ if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS &&
+ intel_set_cpu_fifo_underrun_reporting(dev, pipe, false))
+ DRM_DEBUG_DRIVER("pipe %c underrun\n", pipe_name(pipe));
}
/* Consume port. Then clear IIR or we'll miss events */
/*
* Clear the PIPE*STAT regs before the IIR
*/
- if (pipe_stats[pipe] & 0x8000ffff) {
- if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
- DRM_DEBUG_DRIVER("pipe %c underrun\n",
- pipe_name(pipe));
+ if (pipe_stats[pipe] & 0x8000ffff)
I915_WRITE(reg, pipe_stats[pipe]);
- }
}
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
i9xx_pipe_crc_irq_handler(dev, pipe);
+
+ if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS &&
+ intel_set_cpu_fifo_underrun_reporting(dev, pipe, false))
+ DRM_DEBUG_DRIVER("pipe %c underrun\n", pipe_name(pipe));
}
iir = new_iir;
/* Clear the PIPE*STAT regs before the IIR */
if (pipe_stats[pipe] & 0x8000ffff) {
- if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
- DRM_DEBUG_DRIVER("pipe %c underrun\n",
- pipe_name(pipe));
I915_WRITE(reg, pipe_stats[pipe]);
irq_received = true;
}
if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
i9xx_pipe_crc_irq_handler(dev, pipe);
+
+ if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS &&
+ intel_set_cpu_fifo_underrun_reporting(dev, pipe, false))
+ DRM_DEBUG_DRIVER("pipe %c underrun\n", pipe_name(pipe));
}
if (blc_event || (iir & I915_ASLE_INTERRUPT))
* Clear the PIPE*STAT regs before the IIR
*/
if (pipe_stats[pipe] & 0x8000ffff) {
- if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
- DRM_DEBUG_DRIVER("pipe %c underrun\n",
- pipe_name(pipe));
I915_WRITE(reg, pipe_stats[pipe]);
irq_received = true;
}
if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
i9xx_pipe_crc_irq_handler(dev, pipe);
- }
+ if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS &&
+ intel_set_cpu_fifo_underrun_reporting(dev, pipe, false))
+ DRM_DEBUG_DRIVER("pipe %c underrun\n", pipe_name(pipe));
+ }
if (blc_event || (iir & I915_ASLE_INTERRUPT))
intel_opregion_asle_intr(dev);
intel_update_watermarks(crtc);
intel_enable_pipe(dev_priv, pipe, false, is_dsi);
+ intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
intel_enable_primary_plane(dev_priv, plane, pipe);
intel_enable_planes(crtc);
intel_crtc_update_cursor(crtc, true);
intel_update_watermarks(crtc);
intel_enable_pipe(dev_priv, pipe, false, false);
+ intel_set_cpu_fifo_underrun_reporting(dev, pipe, true);
intel_enable_primary_plane(dev_priv, plane, pipe);
intel_enable_planes(crtc);
/* The fixup needs to happen before cursor is enabled */
intel_disable_planes(crtc);
intel_disable_primary_plane(dev_priv, plane, pipe);
+ intel_set_cpu_fifo_underrun_reporting(dev, pipe, false);
intel_disable_pipe(dev_priv, pipe);
i9xx_pfit_disable(intel_crtc);