[Intel-gfx] [PATCH 2/2] drm/i915: Assert we hold the CRTC powerwell for generating vblank interrupts

Chris Wilson chris at chris-wilson.co.uk
Fri Oct 7 19:49:53 UTC 2016


To enable the vblank itself, we need to have an RPM wakeref for the mmio
access, and whilst generating the vblank interrupts we continue to
require the rpm wakeref. The assumption is that the RPM wakeref is held
by the display powerwell held by the active pipe. As this chain was not
obvious to me chasing the drm_wait_vblank ioctl, document it with a WARN
during *_vblank_enable().

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 1e43fe30da11..4491573ea329 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2715,6 +2715,15 @@ void i915_handle_error(struct drm_i915_private *dev_priv,
 	i915_reset_and_wakeup(dev_priv);
 }
 
+static void assert_pipe_is_active(struct drm_i915_private *dev_priv,
+				  enum pipe pipe)
+{
+	struct intel_crtc *crtc =
+		to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
+
+	I915_STATE_WARN_ON(!crtc->base.state->active);
+}
+
 /* Called from drm generic code, passed 'crtc' which
  * we use as a pipe index
  */
@@ -2723,6 +2732,9 @@ static int i8xx_enable_vblank(struct drm_device *dev, unsigned int pipe)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	unsigned long irqflags;
 
+	/* vblank IRQ requires the powerwell, held awake by the CRTC */
+	assert_pipe_is_active(dev_priv, pipe);
+
 	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
 	i915_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_STATUS);
 	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
@@ -2735,6 +2747,9 @@ static int i965_enable_vblank(struct drm_device *dev, unsigned int pipe)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	unsigned long irqflags;
 
+	/* vblank IRQ requires the powerwell, held awake by the CRTC */
+	assert_pipe_is_active(dev_priv, pipe);
+
 	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
 	i915_enable_pipestat(dev_priv, pipe,
 			     PIPE_START_VBLANK_INTERRUPT_STATUS);
@@ -2750,6 +2765,9 @@ static int ironlake_enable_vblank(struct drm_device *dev, unsigned int pipe)
 	uint32_t bit = INTEL_GEN(dev) >= 7 ?
 		DE_PIPE_VBLANK_IVB(pipe) : DE_PIPE_VBLANK(pipe);
 
+	/* vblank IRQ requires the powerwell, held awake by the CRTC */
+	assert_pipe_is_active(dev_priv, pipe);
+
 	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
 	ilk_enable_display_irq(dev_priv, bit);
 	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
@@ -2762,6 +2780,9 @@ static int gen8_enable_vblank(struct drm_device *dev, unsigned int pipe)
 	struct drm_i915_private *dev_priv = to_i915(dev);
 	unsigned long irqflags;
 
+	/* vblank IRQ requires the powerwell, held awake by the CRTC */
+	assert_pipe_is_active(dev_priv, pipe);
+
 	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
 	bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_VBLANK);
 	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
-- 
2.9.3



More information about the Intel-gfx mailing list