Skip to content

Commit e7b4c6b

Browse files
committed
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 <jbarnes@virtuousgeek.org> Antagonized-by: Ben Widawsky <ben@bwidawsk.net> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
1 parent 901781b commit e7b4c6b

File tree

1 file changed

+37
-29
lines changed

1 file changed

+37
-29
lines changed

drivers/gpu/drm/i915/i915_irq.c

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,27 @@ static void gen6_pm_rps_work(struct work_struct *work)
430430
mutex_unlock(&dev_priv->dev->struct_mutex);
431431
}
432432

433+
static void snb_gt_irq_handler(struct drm_device *dev,
434+
struct drm_i915_private *dev_priv,
435+
u32 gt_iir)
436+
{
437+
438+
if (gt_iir & (GEN6_RENDER_USER_INTERRUPT |
439+
GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT))
440+
notify_ring(dev, &dev_priv->ring[RCS]);
441+
if (gt_iir & GEN6_BSD_USER_INTERRUPT)
442+
notify_ring(dev, &dev_priv->ring[VCS]);
443+
if (gt_iir & GEN6_BLITTER_USER_INTERRUPT)
444+
notify_ring(dev, &dev_priv->ring[BCS]);
445+
446+
if (gt_iir & (GT_GEN6_BLT_CS_ERROR_INTERRUPT |
447+
GT_GEN6_BSD_CS_ERROR_INTERRUPT |
448+
GT_RENDER_CS_ERROR_INTERRUPT)) {
449+
DRM_ERROR("GT error interrupt 0x%08x\n", gt_iir);
450+
i915_handle_error(dev, false);
451+
}
452+
}
453+
433454
static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)
434455
{
435456
struct drm_device *dev = (struct drm_device *) arg;
@@ -458,19 +479,7 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)
458479

459480
ret = IRQ_HANDLED;
460481

461-
if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY))
462-
notify_ring(dev, &dev_priv->ring[RCS]);
463-
if (gt_iir & GT_GEN6_BSD_USER_INTERRUPT)
464-
notify_ring(dev, &dev_priv->ring[VCS]);
465-
if (gt_iir & GT_GEN6_BLT_USER_INTERRUPT)
466-
notify_ring(dev, &dev_priv->ring[BCS]);
467-
468-
if (gt_iir & (GT_GEN6_BLT_CS_ERROR_INTERRUPT |
469-
GT_GEN6_BSD_CS_ERROR_INTERRUPT |
470-
GT_RENDER_CS_ERROR_INTERRUPT)) {
471-
DRM_ERROR("GT error interrupt 0x%08x\n", gt_iir);
472-
i915_handle_error(dev, false);
473-
}
482+
snb_gt_irq_handler(dev, dev_priv, gt_iir);
474483

475484
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
476485
for_each_pipe(pipe) {
@@ -618,12 +627,7 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
618627
READ_BREADCRUMB(dev_priv);
619628
}
620629

621-
if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY))
622-
notify_ring(dev, &dev_priv->ring[RCS]);
623-
if (gt_iir & GEN6_BSD_USER_INTERRUPT)
624-
notify_ring(dev, &dev_priv->ring[VCS]);
625-
if (gt_iir & GEN6_BLITTER_USER_INTERRUPT)
626-
notify_ring(dev, &dev_priv->ring[BCS]);
630+
snb_gt_irq_handler(dev, dev_priv, gt_iir);
627631

628632
if (de_iir & DE_GSE_IVB)
629633
intel_opregion_gse_intr(dev);
@@ -675,6 +679,16 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
675679
return ret;
676680
}
677681

682+
static void ilk_gt_irq_handler(struct drm_device *dev,
683+
struct drm_i915_private *dev_priv,
684+
u32 gt_iir)
685+
{
686+
if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY))
687+
notify_ring(dev, &dev_priv->ring[RCS]);
688+
if (gt_iir & GT_BSD_USER_INTERRUPT)
689+
notify_ring(dev, &dev_priv->ring[VCS]);
690+
}
691+
678692
static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
679693
{
680694
struct drm_device *dev = (struct drm_device *) arg;
@@ -683,13 +697,9 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
683697
u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir;
684698
u32 hotplug_mask;
685699
struct drm_i915_master_private *master_priv;
686-
u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT;
687700

688701
atomic_inc(&dev_priv->irq_received);
689702

690-
if (IS_GEN6(dev))
691-
bsd_usr_interrupt = GEN6_BSD_USER_INTERRUPT;
692-
693703
/* disable master interrupt before clearing iir */
694704
de_ier = I915_READ(DEIER);
695705
I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
@@ -718,12 +728,10 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
718728
READ_BREADCRUMB(dev_priv);
719729
}
720730

721-
if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY))
722-
notify_ring(dev, &dev_priv->ring[RCS]);
723-
if (gt_iir & bsd_usr_interrupt)
724-
notify_ring(dev, &dev_priv->ring[VCS]);
725-
if (gt_iir & GEN6_BLITTER_USER_INTERRUPT)
726-
notify_ring(dev, &dev_priv->ring[BCS]);
731+
if (IS_GEN5(dev))
732+
ilk_gt_irq_handler(dev, dev_priv, gt_iir);
733+
else
734+
snb_gt_irq_handler(dev, dev_priv, gt_iir);
727735

728736
if (de_iir & DE_GSE)
729737
intel_opregion_gse_intr(dev);

0 commit comments

Comments
 (0)