aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-03-30 14:24:35 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-04-09 12:04:07 -0400
commite7b4c6b122443254bc7cab0f17fd67871dbe0a19 (patch)
tree65c6ac90103c61d6b853652b747427448218db71 /drivers
parent901781b997570e55af950348d7cd5cef64fb6d7c (diff)
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c66
1 files changed, 37 insertions, 29 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 8496fa55122a..6d76ee54278b 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)
430 mutex_unlock(&dev_priv->dev->struct_mutex); 430 mutex_unlock(&dev_priv->dev->struct_mutex);
431} 431}
432 432
433static 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
433static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS) 454static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)
434{ 455{
435 struct drm_device *dev = (struct drm_device *) arg; 456 struct drm_device *dev = (struct drm_device *) arg;
@@ -458,19 +479,7 @@ static irqreturn_t valleyview_irq_handler(DRM_IRQ_ARGS)
458 479
459 ret = IRQ_HANDLED; 480 ret = IRQ_HANDLED;
460 481
461 if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) 482 snb_gt_irq_handler(dev, dev_priv, gt_iir);
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 }
474 483
475 spin_lock_irqsave(&dev_priv->irq_lock, irqflags); 484 spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
476 for_each_pipe(pipe) { 485 for_each_pipe(pipe) {
@@ -618,12 +627,7 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
618 READ_BREADCRUMB(dev_priv); 627 READ_BREADCRUMB(dev_priv);
619 } 628 }
620 629
621 if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) 630 snb_gt_irq_handler(dev, dev_priv, gt_iir);
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]);
627 631
628 if (de_iir & DE_GSE_IVB) 632 if (de_iir & DE_GSE_IVB)
629 intel_opregion_gse_intr(dev); 633 intel_opregion_gse_intr(dev);
@@ -675,6 +679,16 @@ done:
675 return ret; 679 return ret;
676} 680}
677 681
682static 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
678static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) 692static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
679{ 693{
680 struct drm_device *dev = (struct drm_device *) arg; 694 struct drm_device *dev = (struct drm_device *) arg;
@@ -683,13 +697,9 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
683 u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir; 697 u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir;
684 u32 hotplug_mask; 698 u32 hotplug_mask;
685 struct drm_i915_master_private *master_priv; 699 struct drm_i915_master_private *master_priv;
686 u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT;
687 700
688 atomic_inc(&dev_priv->irq_received); 701 atomic_inc(&dev_priv->irq_received);
689 702
690 if (IS_GEN6(dev))
691 bsd_usr_interrupt = GEN6_BSD_USER_INTERRUPT;
692
693 /* disable master interrupt before clearing iir */ 703 /* disable master interrupt before clearing iir */
694 de_ier = I915_READ(DEIER); 704 de_ier = I915_READ(DEIER);
695 I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); 705 I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
@@ -718,12 +728,10 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
718 READ_BREADCRUMB(dev_priv); 728 READ_BREADCRUMB(dev_priv);
719 } 729 }
720 730
721 if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) 731 if (IS_GEN5(dev))
722 notify_ring(dev, &dev_priv->ring[RCS]); 732 ilk_gt_irq_handler(dev, dev_priv, gt_iir);
723 if (gt_iir & bsd_usr_interrupt) 733 else
724 notify_ring(dev, &dev_priv->ring[VCS]); 734 snb_gt_irq_handler(dev, dev_priv, gt_iir);
725 if (gt_iir & GEN6_BLITTER_USER_INTERRUPT)
726 notify_ring(dev, &dev_priv->ring[BCS]);
727 735
728 if (de_iir & DE_GSE) 736 if (de_iir & DE_GSE)
729 intel_opregion_gse_intr(dev); 737 intel_opregion_gse_intr(dev);