aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 2cd97d1cc920..3c7bb0410b51 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -701,7 +701,7 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
701{ 701{
702 struct drm_device *dev = (struct drm_device *) arg; 702 struct drm_device *dev = (struct drm_device *) arg;
703 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 703 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
704 u32 de_iir, gt_iir, de_ier, pm_iir; 704 u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier;
705 irqreturn_t ret = IRQ_NONE; 705 irqreturn_t ret = IRQ_NONE;
706 int i; 706 int i;
707 707
@@ -711,6 +711,15 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
711 de_ier = I915_READ(DEIER); 711 de_ier = I915_READ(DEIER);
712 I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); 712 I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
713 713
714 /* Disable south interrupts. We'll only write to SDEIIR once, so further
715 * interrupts will will be stored on its back queue, and then we'll be
716 * able to process them after we restore SDEIER (as soon as we restore
717 * it, we'll get an interrupt if SDEIIR still has something to process
718 * due to its back queue). */
719 sde_ier = I915_READ(SDEIER);
720 I915_WRITE(SDEIER, 0);
721 POSTING_READ(SDEIER);
722
714 gt_iir = I915_READ(GTIIR); 723 gt_iir = I915_READ(GTIIR);
715 if (gt_iir) { 724 if (gt_iir) {
716 snb_gt_irq_handler(dev, dev_priv, gt_iir); 725 snb_gt_irq_handler(dev, dev_priv, gt_iir);
@@ -759,6 +768,8 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
759 768
760 I915_WRITE(DEIER, de_ier); 769 I915_WRITE(DEIER, de_ier);
761 POSTING_READ(DEIER); 770 POSTING_READ(DEIER);
771 I915_WRITE(SDEIER, sde_ier);
772 POSTING_READ(SDEIER);
762 773
763 return ret; 774 return ret;
764} 775}
@@ -778,7 +789,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
778 struct drm_device *dev = (struct drm_device *) arg; 789 struct drm_device *dev = (struct drm_device *) arg;
779 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 790 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
780 int ret = IRQ_NONE; 791 int ret = IRQ_NONE;
781 u32 de_iir, gt_iir, de_ier, pm_iir; 792 u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier;
782 793
783 atomic_inc(&dev_priv->irq_received); 794 atomic_inc(&dev_priv->irq_received);
784 795
@@ -787,6 +798,15 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
787 I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); 798 I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
788 POSTING_READ(DEIER); 799 POSTING_READ(DEIER);
789 800
801 /* Disable south interrupts. We'll only write to SDEIIR once, so further
802 * interrupts will will be stored on its back queue, and then we'll be
803 * able to process them after we restore SDEIER (as soon as we restore
804 * it, we'll get an interrupt if SDEIIR still has something to process
805 * due to its back queue). */
806 sde_ier = I915_READ(SDEIER);
807 I915_WRITE(SDEIER, 0);
808 POSTING_READ(SDEIER);
809
790 de_iir = I915_READ(DEIIR); 810 de_iir = I915_READ(DEIIR);
791 gt_iir = I915_READ(GTIIR); 811 gt_iir = I915_READ(GTIIR);
792 pm_iir = I915_READ(GEN6_PMIIR); 812 pm_iir = I915_READ(GEN6_PMIIR);
@@ -849,6 +869,8 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
849done: 869done:
850 I915_WRITE(DEIER, de_ier); 870 I915_WRITE(DEIER, de_ier);
851 POSTING_READ(DEIER); 871 POSTING_READ(DEIER);
872 I915_WRITE(SDEIER, sde_ier);
873 POSTING_READ(SDEIER);
852 874
853 return ret; 875 return ret;
854} 876}