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.c83
1 files changed, 61 insertions, 22 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 2e242270e270..d447d7d508f4 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2887,21 +2887,39 @@ gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl)
2887 return ret; 2887 return ret;
2888} 2888}
2889 2889
2890static inline u32 gen8_master_intr_disable(void __iomem * const regs)
2891{
2892 raw_reg_write(regs, GEN8_MASTER_IRQ, 0);
2893
2894 /*
2895 * Now with master disabled, get a sample of level indications
2896 * for this interrupt. Indications will be cleared on related acks.
2897 * New indications can and will light up during processing,
2898 * and will generate new interrupt after enabling master.
2899 */
2900 return raw_reg_read(regs, GEN8_MASTER_IRQ);
2901}
2902
2903static inline void gen8_master_intr_enable(void __iomem * const regs)
2904{
2905 raw_reg_write(regs, GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
2906}
2907
2890static irqreturn_t gen8_irq_handler(int irq, void *arg) 2908static irqreturn_t gen8_irq_handler(int irq, void *arg)
2891{ 2909{
2892 struct drm_i915_private *dev_priv = to_i915(arg); 2910 struct drm_i915_private *dev_priv = to_i915(arg);
2911 void __iomem * const regs = dev_priv->regs;
2893 u32 master_ctl; 2912 u32 master_ctl;
2894 u32 gt_iir[4]; 2913 u32 gt_iir[4];
2895 2914
2896 if (!intel_irqs_enabled(dev_priv)) 2915 if (!intel_irqs_enabled(dev_priv))
2897 return IRQ_NONE; 2916 return IRQ_NONE;
2898 2917
2899 master_ctl = I915_READ_FW(GEN8_MASTER_IRQ); 2918 master_ctl = gen8_master_intr_disable(regs);
2900 master_ctl &= ~GEN8_MASTER_IRQ_CONTROL; 2919 if (!master_ctl) {
2901 if (!master_ctl) 2920 gen8_master_intr_enable(regs);
2902 return IRQ_NONE; 2921 return IRQ_NONE;
2903 2922 }
2904 I915_WRITE_FW(GEN8_MASTER_IRQ, 0);
2905 2923
2906 /* Find, clear, then process each source of interrupt */ 2924 /* Find, clear, then process each source of interrupt */
2907 gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir); 2925 gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir);
@@ -2913,7 +2931,7 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
2913 enable_rpm_wakeref_asserts(dev_priv); 2931 enable_rpm_wakeref_asserts(dev_priv);
2914 } 2932 }
2915 2933
2916 I915_WRITE_FW(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); 2934 gen8_master_intr_enable(regs);
2917 2935
2918 gen8_gt_irq_handler(dev_priv, master_ctl, gt_iir); 2936 gen8_gt_irq_handler(dev_priv, master_ctl, gt_iir);
2919 2937
@@ -3111,6 +3129,24 @@ gen11_gu_misc_irq_handler(struct drm_i915_private *dev_priv, const u32 iir)
3111 intel_opregion_asle_intr(dev_priv); 3129 intel_opregion_asle_intr(dev_priv);
3112} 3130}
3113 3131
3132static inline u32 gen11_master_intr_disable(void __iomem * const regs)
3133{
3134 raw_reg_write(regs, GEN11_GFX_MSTR_IRQ, 0);
3135
3136 /*
3137 * Now with master disabled, get a sample of level indications
3138 * for this interrupt. Indications will be cleared on related acks.
3139 * New indications can and will light up during processing,
3140 * and will generate new interrupt after enabling master.
3141 */
3142 return raw_reg_read(regs, GEN11_GFX_MSTR_IRQ);
3143}
3144
3145static inline void gen11_master_intr_enable(void __iomem * const regs)
3146{
3147 raw_reg_write(regs, GEN11_GFX_MSTR_IRQ, GEN11_MASTER_IRQ);
3148}
3149
3114static irqreturn_t gen11_irq_handler(int irq, void *arg) 3150static irqreturn_t gen11_irq_handler(int irq, void *arg)
3115{ 3151{
3116 struct drm_i915_private * const i915 = to_i915(arg); 3152 struct drm_i915_private * const i915 = to_i915(arg);
@@ -3121,13 +3157,11 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg)
3121 if (!intel_irqs_enabled(i915)) 3157 if (!intel_irqs_enabled(i915))
3122 return IRQ_NONE; 3158 return IRQ_NONE;
3123 3159
3124 master_ctl = raw_reg_read(regs, GEN11_GFX_MSTR_IRQ); 3160 master_ctl = gen11_master_intr_disable(regs);
3125 master_ctl &= ~GEN11_MASTER_IRQ; 3161 if (!master_ctl) {
3126 if (!master_ctl) 3162 gen11_master_intr_enable(regs);
3127 return IRQ_NONE; 3163 return IRQ_NONE;
3128 3164 }
3129 /* Disable interrupts. */
3130 raw_reg_write(regs, GEN11_GFX_MSTR_IRQ, 0);
3131 3165
3132 /* Find, clear, then process each source of interrupt. */ 3166 /* Find, clear, then process each source of interrupt. */
3133 gen11_gt_irq_handler(i915, master_ctl); 3167 gen11_gt_irq_handler(i915, master_ctl);
@@ -3147,8 +3181,7 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg)
3147 3181
3148 gu_misc_iir = gen11_gu_misc_irq_ack(i915, master_ctl); 3182 gu_misc_iir = gen11_gu_misc_irq_ack(i915, master_ctl);
3149 3183
3150 /* Acknowledge and enable interrupts. */ 3184 gen11_master_intr_enable(regs);
3151 raw_reg_write(regs, GEN11_GFX_MSTR_IRQ, GEN11_MASTER_IRQ | master_ctl);
3152 3185
3153 gen11_gu_misc_irq_handler(i915, gu_misc_iir); 3186 gen11_gu_misc_irq_handler(i915, gu_misc_iir);
3154 3187
@@ -3598,8 +3631,7 @@ static void gen8_irq_reset(struct drm_device *dev)
3598 struct drm_i915_private *dev_priv = to_i915(dev); 3631 struct drm_i915_private *dev_priv = to_i915(dev);
3599 int pipe; 3632 int pipe;
3600 3633
3601 I915_WRITE(GEN8_MASTER_IRQ, 0); 3634 gen8_master_intr_disable(dev_priv->regs);
3602 POSTING_READ(GEN8_MASTER_IRQ);
3603 3635
3604 gen8_gt_irq_reset(dev_priv); 3636 gen8_gt_irq_reset(dev_priv);
3605 3637
@@ -3641,13 +3673,15 @@ static void gen11_irq_reset(struct drm_device *dev)
3641 struct drm_i915_private *dev_priv = dev->dev_private; 3673 struct drm_i915_private *dev_priv = dev->dev_private;
3642 int pipe; 3674 int pipe;
3643 3675
3644 I915_WRITE(GEN11_GFX_MSTR_IRQ, 0); 3676 gen11_master_intr_disable(dev_priv->regs);
3645 POSTING_READ(GEN11_GFX_MSTR_IRQ);
3646 3677
3647 gen11_gt_irq_reset(dev_priv); 3678 gen11_gt_irq_reset(dev_priv);
3648 3679
3649 I915_WRITE(GEN11_DISPLAY_INT_CTL, 0); 3680 I915_WRITE(GEN11_DISPLAY_INT_CTL, 0);
3650 3681
3682 I915_WRITE(EDP_PSR_IMR, 0xffffffff);
3683 I915_WRITE(EDP_PSR_IIR, 0xffffffff);
3684
3651 for_each_pipe(dev_priv, pipe) 3685 for_each_pipe(dev_priv, pipe)
3652 if (intel_display_power_is_enabled(dev_priv, 3686 if (intel_display_power_is_enabled(dev_priv,
3653 POWER_DOMAIN_PIPE(pipe))) 3687 POWER_DOMAIN_PIPE(pipe)))
@@ -4244,8 +4278,7 @@ static int gen8_irq_postinstall(struct drm_device *dev)
4244 if (HAS_PCH_SPLIT(dev_priv)) 4278 if (HAS_PCH_SPLIT(dev_priv))
4245 ibx_irq_postinstall(dev); 4279 ibx_irq_postinstall(dev);
4246 4280
4247 I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); 4281 gen8_master_intr_enable(dev_priv->regs);
4248 POSTING_READ(GEN8_MASTER_IRQ);
4249 4282
4250 return 0; 4283 return 0;
4251} 4284}
@@ -4307,8 +4340,7 @@ static int gen11_irq_postinstall(struct drm_device *dev)
4307 4340
4308 I915_WRITE(GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE); 4341 I915_WRITE(GEN11_DISPLAY_INT_CTL, GEN11_DISPLAY_IRQ_ENABLE);
4309 4342
4310 I915_WRITE(GEN11_GFX_MSTR_IRQ, GEN11_MASTER_IRQ); 4343 gen11_master_intr_enable(dev_priv->regs);
4311 POSTING_READ(GEN11_GFX_MSTR_IRQ);
4312 4344
4313 return 0; 4345 return 0;
4314} 4346}
@@ -4834,6 +4866,13 @@ void intel_irq_init(struct drm_i915_private *dev_priv)
4834 dev_priv->display_irqs_enabled = false; 4866 dev_priv->display_irqs_enabled = false;
4835 4867
4836 dev_priv->hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD; 4868 dev_priv->hotplug.hpd_storm_threshold = HPD_STORM_DEFAULT_THRESHOLD;
4869 /* If we have MST support, we want to avoid doing short HPD IRQ storm
4870 * detection, as short HPD storms will occur as a natural part of
4871 * sideband messaging with MST.
4872 * On older platforms however, IRQ storms can occur with both long and
4873 * short pulses, as seen on some G4x systems.
4874 */
4875 dev_priv->hotplug.hpd_short_storm_enabled = !HAS_DP_MST(dev_priv);
4837 4876
4838 dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos; 4877 dev->driver->get_vblank_timestamp = drm_calc_vbltimestamp_from_scanoutpos;
4839 dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; 4878 dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;