diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 26 |
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) | |||
849 | done: | 869 | done: |
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 | } |