From e7b4c6b122443254bc7cab0f17fd67871dbe0a19 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 30 Mar 2012 20:24:35 +0200 Subject: [PATCH] drm/i915: extract gt interrupt handler vlv, ivb and snb all share the gen6+ gt irq handling. 3 copies of the same stuff is a bit much, so extract it into a little helper. Now ilk has a different gt irq handling than snb, but shares the same irq handler (due to the similar display block). So also extract the ilk gt irq handling to clearly separate these two things. Nice side effect of this is that we can complete Ben Widawsky's gen6+ irq bit #define cleanup and call the render irq also with the GEN6 alias. Beforehand that code was shared with ilk, and neither option really made much sense. As a bonus this enables the error interrupt handling lifted from the vlv code on snb and ivb, too. Reviewed-by: Jesse Barnes Antagonized-by: Ben Widawsky Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 66 ++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8496fa55122..6d76ee54278 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -430,6 +430,27 @@ static void gen6_pm_rps_work(struct work_struct *work) mutex_unlock(&dev_priv->dev->struct_mutex); } +static void snb_gt_irq_handler(struct drm_device *dev, + struct drm_i915_private *dev_priv, + u32 gt_iir) +{ + + if (gt_iir & (GEN6_RENDER_USER_INTERRUPT | + GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT)) + notify_ring(dev, &dev_priv->ring[RCS]); + if (gt_iir & GEN6_BSD_USER_INTERRUPT) + notify_ring(dev, &dev_priv->ring[VCS]); + if (gt_iir & GEN6_BLITTER_USER_INTERRUPT) + notify_ring(dev, &dev_priv->ring[BCS]); + + if (gt_iir & (GT_GEN6_BLT_CS_ERROR_INTERRUPT | + GT_GEN6_BSD_CS_ERROR_INTERRUPT | + GT_RENDER_CS_ERROR_INTERRUPT)) { + DRM_ERROR("GT error interrupt 0x%08x\n", gt_iir); + i915_handle_error(dev, false); + } +} + static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; @@ -458,19 +479,7 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS) ret = IRQ_HANDLED; - if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) - notify_ring(dev, &dev_priv->ring[RCS]); - if (gt_iir & GT_GEN6_BSD_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[VCS]); - if (gt_iir & GT_GEN6_BLT_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[BCS]); - - if (gt_iir & (GT_GEN6_BLT_CS_ERROR_INTERRUPT | - GT_GEN6_BSD_CS_ERROR_INTERRUPT | - GT_RENDER_CS_ERROR_INTERRUPT)) { - DRM_ERROR("GT error interrupt 0x%08x\n", gt_iir); - i915_handle_error(dev, false); - } + snb_gt_irq_handler(dev, dev_priv, gt_iir); spin_lock_irqsave(&dev_priv->irq_lock, irqflags); for_each_pipe(pipe) { @@ -618,12 +627,7 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) READ_BREADCRUMB(dev_priv); } - if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) - notify_ring(dev, &dev_priv->ring[RCS]); - if (gt_iir & GEN6_BSD_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[VCS]); - if (gt_iir & GEN6_BLITTER_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[BCS]); + snb_gt_irq_handler(dev, dev_priv, gt_iir); if (de_iir & DE_GSE_IVB) intel_opregion_gse_intr(dev); @@ -675,6 +679,16 @@ done: return ret; } +static void ilk_gt_irq_handler(struct drm_device *dev, + struct drm_i915_private *dev_priv, + u32 gt_iir) +{ + if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) + notify_ring(dev, &dev_priv->ring[RCS]); + if (gt_iir & GT_BSD_USER_INTERRUPT) + notify_ring(dev, &dev_priv->ring[VCS]); +} + static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *) arg; @@ -683,13 +697,9 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir; u32 hotplug_mask; struct drm_i915_master_private *master_priv; - u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT; atomic_inc(&dev_priv->irq_received); - if (IS_GEN6(dev)) - bsd_usr_interrupt = GEN6_BSD_USER_INTERRUPT; - /* disable master interrupt before clearing iir */ de_ier = I915_READ(DEIER); I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); @@ -718,12 +728,10 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) READ_BREADCRUMB(dev_priv); } - if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) - notify_ring(dev, &dev_priv->ring[RCS]); - if (gt_iir & bsd_usr_interrupt) - notify_ring(dev, &dev_priv->ring[VCS]); - if (gt_iir & GEN6_BLITTER_USER_INTERRUPT) - notify_ring(dev, &dev_priv->ring[BCS]); + if (IS_GEN5(dev)) + ilk_gt_irq_handler(dev, dev_priv, gt_iir); + else + snb_gt_irq_handler(dev, dev_priv, gt_iir); if (de_iir & DE_GSE) intel_opregion_gse_intr(dev); -- 2.41.0