[Intel-gfx] [PATCH v2 5/5] drm/i915: Use raw_reg_read()/write() in ilk+ irq handlers

Ville Syrjala ville.syrjala at linux.intel.com
Wed Jun 26 18:03:44 UTC 2019


From: Ville Syrjälä <ville.syrjala at linux.intel.com>

Optimize the irq handlers a bit by switching to the raw register
access functions.

It seems we can go fully lockless due to
WaSerializeKmdDisplayAccess, so in order to protect against that
we grab the irq_lock around the ack. I *think* that should be
sufficient as that's held whenever we otherwise massage the irq
registers. The w/a database lists this only for snb/ivb/hsw, so
maybe we don't even need it for bdw+? But I was too chicken to
leave it out.

This leads to some shrinkage:
add/remove: 1/5 grow/shrink: 3/2 up/down: 183/-1307 (-1124)
Function                                     old     new   delta
gen8_gt_irq_ack                                -     104    +104
gen8_irq_handler                             291     334     +43
gen11_irq_handler                            902     935     +33
cherryview_irq_handler                       636     639      +3
ilk_hpd_irq_ack.isra                          82       -     -82
hsw_psr_irq_ack                               91       -     -91
gen8_gt_irq_ack.isra                         104       -    -104
ibx_hpd_irq_ack.isra                         106       -    -106
cpt_irq_ack                                  117       -    -117
ironlake_irq_handler                        2973    2700    -273
gen8_de_irq_ack                             1229     695    -534
Total: Before=34132, After=33008, chg -3.29%

so we're now below the original pre-ack/handle split numbers.

Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 220 +++++++++++++++++---------------
 1 file changed, 119 insertions(+), 101 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b83c9d71d630..2ed715d4bddd 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1577,11 +1577,9 @@ gen8_cs_irq_handler(struct intel_engine_cs *engine, u32 iir)
 		tasklet_hi_schedule(&engine->execlists.tasklet);
 }
 
-static void gen8_gt_irq_ack(struct drm_i915_private *i915,
+static void gen8_gt_irq_ack(void __iomem * const regs,
 			    u32 master_ctl, u32 gt_iir[4])
 {
-	void __iomem * const regs = i915->uncore.regs;
-
 #define GEN8_GT_IRQS (GEN8_GT_RCS_IRQ | \
 		      GEN8_GT_BCS_IRQ | \
 		      GEN8_GT_VCS0_IRQ | \
@@ -2293,6 +2291,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
 	disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
 
 	do {
+		void __iomem * const regs = dev_priv->uncore.regs;
 		u32 master_ctl, iir;
 		u32 pipe_stats[I915_MAX_PIPES] = {};
 		u32 hotplug_status = 0;
@@ -2324,7 +2323,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
 		ier = I915_READ(VLV_IER);
 		I915_WRITE(VLV_IER, 0);
 
-		gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir);
+		gen8_gt_irq_ack(regs, master_ctl, gt_iir);
 
 		if (iir & I915_DISPLAY_PORT_INTERRUPT)
 			hotplug_status = i9xx_hpd_irq_ack(dev_priv);
@@ -2381,7 +2380,7 @@ struct pch_irq_regs {
 	};
 };
 
-static void ibx_hpd_irq_ack(struct drm_i915_private *dev_priv,
+static void ibx_hpd_irq_ack(void __iomem * const regs,
 			    struct hpd_irq_regs *hpd)
 {
 	/*
@@ -2390,7 +2389,7 @@ static void ibx_hpd_irq_ack(struct drm_i915_private *dev_priv,
 	 * zero. Not acking leads to "The master control interrupt lied (SDE)!"
 	 * errors.
 	 */
-	hpd->dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
+	hpd->dig_hotplug_reg = raw_reg_read(regs, PCH_PORT_HOTPLUG);
 	if (!hpd->hotplug_trigger) {
 		u32 mask = PORTA_HOTPLUG_STATUS_MASK |
 			PORTD_HOTPLUG_STATUS_MASK |
@@ -2399,7 +2398,7 @@ static void ibx_hpd_irq_ack(struct drm_i915_private *dev_priv,
 		hpd->dig_hotplug_reg &= ~mask;
 	}
 
-	I915_WRITE(PCH_PORT_HOTPLUG, hpd->dig_hotplug_reg);
+	raw_reg_write(regs, PCH_PORT_HOTPLUG, hpd->dig_hotplug_reg);
 }
 
 static void ibx_hpd_irq_handler(struct drm_i915_private *dev_priv,
@@ -2417,12 +2416,12 @@ static void ibx_hpd_irq_handler(struct drm_i915_private *dev_priv,
 	intel_hpd_irq_handler(dev_priv, pin_mask, long_mask);
 }
 
-static void ibx_irq_ack(struct drm_i915_private *dev_priv,
+static void ibx_irq_ack(void __iomem * const regs,
 			struct pch_irq_regs *pch)
 {
 	pch->hpd.hotplug_trigger = pch->iir & SDE_HOTPLUG_MASK;
 
-	ibx_hpd_irq_ack(dev_priv, &pch->hpd);
+	ibx_hpd_irq_ack(regs, &pch->hpd);
 }
 
 static void ibx_irq_handler(struct drm_i915_private *dev_priv,
@@ -2474,11 +2473,11 @@ static void ibx_irq_handler(struct drm_i915_private *dev_priv,
 		intel_pch_fifo_underrun_irq_handler(dev_priv, PIPE_B);
 }
 
-static void ivb_err_int_ack(struct drm_i915_private *dev_priv,
+static void ivb_err_int_ack(void __iomem * const regs,
 			    struct ilk_de_irq_regs *de)
 {
-	de->err_int = I915_READ(GEN7_ERR_INT);
-	I915_WRITE(GEN7_ERR_INT, de->err_int);
+	de->err_int = raw_reg_read(regs, GEN7_ERR_INT);
+	raw_reg_write(regs, GEN7_ERR_INT, de->err_int);
 }
 
 static void ivb_err_int_handler(struct drm_i915_private *dev_priv,
@@ -2503,11 +2502,11 @@ static void ivb_err_int_handler(struct drm_i915_private *dev_priv,
 	}
 }
 
-static void cpt_serr_int_ack(struct drm_i915_private *dev_priv,
+static void cpt_serr_int_ack(void __iomem * const regs,
 			     struct pch_irq_regs *pch)
 {
-	pch->serr_int = I915_READ(SERR_INT);
-	I915_WRITE(SERR_INT, pch->serr_int);
+	pch->serr_int = raw_reg_read(regs, SERR_INT);
+	raw_reg_write(regs, SERR_INT, pch->serr_int);
 }
 
 static void cpt_serr_int_handler(struct drm_i915_private *dev_priv,
@@ -2524,15 +2523,15 @@ static void cpt_serr_int_handler(struct drm_i915_private *dev_priv,
 			intel_pch_fifo_underrun_irq_handler(dev_priv, pipe);
 }
 
-static void cpt_irq_ack(struct drm_i915_private *dev_priv,
+static void cpt_irq_ack(void __iomem * const regs,
 			struct pch_irq_regs *pch)
 {
 	pch->hpd.hotplug_trigger = pch->iir & SDE_HOTPLUG_MASK_CPT;
 
-	ibx_hpd_irq_ack(dev_priv, &pch->hpd);
+	ibx_hpd_irq_ack(regs, &pch->hpd);
 
 	if (pch->iir & SDE_ERROR_CPT)
-		cpt_serr_int_ack(dev_priv, pch);
+		cpt_serr_int_ack(regs, pch);
 }
 
 static void cpt_irq_handler(struct drm_i915_private *dev_priv,
@@ -2572,20 +2571,20 @@ static void cpt_irq_handler(struct drm_i915_private *dev_priv,
 		cpt_serr_int_handler(dev_priv, pch);
 }
 
-static void icp_irq_ack(struct drm_i915_private *dev_priv,
+static void icp_irq_ack(void __iomem * const regs,
 			struct pch_irq_regs *pch)
 {
 	pch->ddi.hotplug_trigger = pch->iir & SDE_DDI_MASK_ICP;
 	pch->tc.hotplug_trigger = pch->iir & SDE_TC_MASK_ICP;
 
 	if (pch->ddi.hotplug_trigger) {
-		pch->ddi.dig_hotplug_reg = I915_READ(SHOTPLUG_CTL_DDI);
-		I915_WRITE(SHOTPLUG_CTL_DDI, pch->ddi.dig_hotplug_reg);
+		pch->ddi.dig_hotplug_reg = raw_reg_read(regs, SHOTPLUG_CTL_DDI);
+		raw_reg_write(regs, SHOTPLUG_CTL_DDI, pch->ddi.dig_hotplug_reg);
 	}
 
 	if (pch->tc.hotplug_trigger) {
-		pch->tc.dig_hotplug_reg = I915_READ(SHOTPLUG_CTL_TC);
-		I915_WRITE(SHOTPLUG_CTL_TC, pch->tc.dig_hotplug_reg);
+		pch->tc.dig_hotplug_reg = raw_reg_read(regs, SHOTPLUG_CTL_TC);
+		raw_reg_write(regs, SHOTPLUG_CTL_TC, pch->tc.dig_hotplug_reg);
 	}
 }
 
@@ -2615,7 +2614,7 @@ static void icp_irq_handler(struct drm_i915_private *dev_priv,
 		gmbus_irq_handler(dev_priv);
 }
 
-static void spt_irq_ack(struct drm_i915_private *dev_priv,
+static void spt_irq_ack(void __iomem * const regs,
 			struct pch_irq_regs *pch)
 {
 	pch->hpd.hotplug_trigger = pch->iir & SDE_HOTPLUG_MASK_SPT &
@@ -2623,13 +2622,13 @@ static void spt_irq_ack(struct drm_i915_private *dev_priv,
 	pch->hpd2.hotplug_trigger = pch->iir & SDE_PORTE_HOTPLUG_SPT;
 
 	if (pch->hpd.hotplug_trigger) {
-		pch->hpd.dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
-		I915_WRITE(PCH_PORT_HOTPLUG, pch->hpd.dig_hotplug_reg);
+		pch->hpd.dig_hotplug_reg = raw_reg_read(regs, PCH_PORT_HOTPLUG);
+		raw_reg_write(regs, PCH_PORT_HOTPLUG, pch->hpd.dig_hotplug_reg);
 	}
 
 	if (pch->hpd2.hotplug_trigger) {
-		pch->hpd2.dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG2);
-		I915_WRITE(PCH_PORT_HOTPLUG2, pch->hpd2.dig_hotplug_reg);
+		pch->hpd2.dig_hotplug_reg = raw_reg_read(regs, PCH_PORT_HOTPLUG2);
+		raw_reg_write(regs, PCH_PORT_HOTPLUG2, pch->hpd2.dig_hotplug_reg);
 	}
 }
 
@@ -2658,11 +2657,11 @@ static void spt_irq_handler(struct drm_i915_private *dev_priv,
 		gmbus_irq_handler(dev_priv);
 }
 
-static void ilk_hpd_irq_ack(struct drm_i915_private *dev_priv,
+static void ilk_hpd_irq_ack(void __iomem * const regs,
 			    struct hpd_irq_regs *hpd)
 {
-	hpd->dig_hotplug_reg = I915_READ(DIGITAL_PORT_HOTPLUG_CNTRL);
-	I915_WRITE(DIGITAL_PORT_HOTPLUG_CNTRL, hpd->dig_hotplug_reg);
+	hpd->dig_hotplug_reg = raw_reg_read(regs, DIGITAL_PORT_HOTPLUG_CNTRL);
+	raw_reg_write(regs, DIGITAL_PORT_HOTPLUG_CNTRL, hpd->dig_hotplug_reg);
 }
 
 static void ilk_hpd_irq_handler(struct drm_i915_private *dev_priv,
@@ -2678,26 +2677,27 @@ static void ilk_hpd_irq_handler(struct drm_i915_private *dev_priv,
 	intel_hpd_irq_handler(dev_priv, pin_mask, long_mask);
 }
 
-static void ilk_display_irq_ack(struct drm_i915_private *dev_priv,
+static void ilk_display_irq_ack(struct drm_i915_private *i915,
+				void __iomem * const regs,
 				struct ilk_de_irq_regs *de,
 				struct pch_irq_regs *pch)
 {
 	de->hpd.hotplug_trigger = de->iir & DE_DP_A_HOTPLUG;
 
 	if (de->hpd.hotplug_trigger)
-		ilk_hpd_irq_ack(dev_priv, &de->hpd);
+		ilk_hpd_irq_ack(regs, &de->hpd);
 
 	/* check event from PCH */
 	if (de->iir & DE_PCH_EVENT) {
-		pch->iir = I915_READ(SDEIIR);
+		pch->iir = raw_reg_read(regs, SDEIIR);
 
-		if (HAS_PCH_CPT(dev_priv))
-			cpt_irq_ack(dev_priv, pch);
+		if (HAS_PCH_CPT(i915))
+			cpt_irq_ack(regs, pch);
 		else
-			ibx_irq_ack(dev_priv, pch);
+			ibx_irq_ack(regs, pch);
 
 		/* should clear PCH hotplug event before clear CPU irq */
-		I915_WRITE(SDEIIR, pch->iir);
+		raw_reg_write(regs, SDEIIR, pch->iir);
 	}
 }
 
@@ -2743,37 +2743,38 @@ static void ilk_display_irq_handler(struct drm_i915_private *dev_priv,
 		ironlake_rps_change_irq_handler(dev_priv);
 }
 
-static void hsw_psr_irq_ack(struct drm_i915_private *dev_priv,
+static void hsw_psr_irq_ack(void __iomem * const regs,
 			    u32 *psr_iir)
 {
-	*psr_iir = I915_READ(EDP_PSR_IIR);
+	*psr_iir = raw_reg_read(regs, EDP_PSR_IIR);
 	if (*psr_iir)
-		I915_WRITE(EDP_PSR_IIR, *psr_iir);
+		raw_reg_write(regs, EDP_PSR_IIR, *psr_iir);
 }
 
-static void ivb_display_irq_ack(struct drm_i915_private *dev_priv,
+static void ivb_display_irq_ack(struct drm_i915_private *i915,
+				void __iomem * const regs,
 				struct ilk_de_irq_regs *de,
 				struct pch_irq_regs *pch)
 {
 	de->hpd.hotplug_trigger = de->iir & DE_DP_A_HOTPLUG_IVB;
 
 	if (de->hpd.hotplug_trigger)
-		ilk_hpd_irq_ack(dev_priv, &de->hpd);
+		ilk_hpd_irq_ack(regs, &de->hpd);
 
 	if (de->iir & DE_ERR_INT_IVB)
-		ivb_err_int_ack(dev_priv, de);
+		ivb_err_int_ack(regs, de);
 
 	if (de->iir & DE_EDP_PSR_INT_HSW)
-		hsw_psr_irq_ack(dev_priv, &de->psr_iir);
+		hsw_psr_irq_ack(regs, &de->psr_iir);
 
 	/* check event from PCH */
-	if (!HAS_PCH_NOP(dev_priv) && de->iir & DE_PCH_EVENT_IVB) {
-		pch->iir = I915_READ(SDEIIR);
+	if (!HAS_PCH_NOP(i915) && de->iir & DE_PCH_EVENT_IVB) {
+		pch->iir = raw_reg_read(regs, SDEIIR);
 
-		cpt_irq_ack(dev_priv, pch);
+		cpt_irq_ack(regs, pch);
 
 		/* clear PCH hotplug event before clear CPU irq */
-		I915_WRITE(SDEIIR, pch->iir);
+		raw_reg_write(regs, SDEIIR, pch->iir);
 	}
 }
 
@@ -2820,6 +2821,7 @@ static void ivb_display_irq_handler(struct drm_i915_private *dev_priv,
 static irqreturn_t ironlake_irq_handler(int irq, void *arg)
 {
 	struct drm_i915_private *dev_priv = arg;
+	void __iomem * const regs = dev_priv->uncore.regs;
 	u32 gt_iir, pm_iir = 0, de_ier, sde_ier = 0;
 	struct ilk_de_irq_regs de;
 	struct pch_irq_regs pch;
@@ -2831,9 +2833,12 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
 	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
 	disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
 
+	/* WaSerializeKmdDisplayAccess:snb,ivb,hsw */
+	spin_lock(&dev_priv->irq_lock);
+
 	/* disable master interrupt before clearing iir  */
-	de_ier = I915_READ(DEIER);
-	I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
+	de_ier = raw_reg_read(regs, DEIER);
+	raw_reg_write(regs, DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
 
 	/* Disable south interrupts. We'll only write to SDEIIR once, so further
 	 * interrupts will will be stored on its back queue, and then we'll be
@@ -2841,35 +2846,37 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
 	 * it, we'll get an interrupt if SDEIIR still has something to process
 	 * due to its back queue). */
 	if (!HAS_PCH_NOP(dev_priv)) {
-		sde_ier = I915_READ(SDEIER);
-		I915_WRITE(SDEIER, 0);
+		sde_ier = raw_reg_read(regs, SDEIER);
+		raw_reg_write(regs, SDEIER, 0);
 	}
 
 	/* Find, clear, then process each source of interrupt */
 
-	gt_iir = I915_READ(GTIIR);
-	de.iir = I915_READ(DEIIR);
+	gt_iir = raw_reg_read(regs, GTIIR);
+	de.iir = raw_reg_read(regs, DEIIR);
 	if (INTEL_GEN(dev_priv) >= 6)
-		pm_iir = I915_READ(GEN6_PMIIR);
+		pm_iir = raw_reg_read(regs, GEN6_PMIIR);
 
 	if (gt_iir)
-		I915_WRITE(GTIIR, gt_iir);
+		raw_reg_write(regs, GTIIR, gt_iir);
 
 	if (de.iir) {
 		if (INTEL_GEN(dev_priv) >= 7)
-			ivb_display_irq_ack(dev_priv, &de, &pch);
+			ivb_display_irq_ack(dev_priv, regs, &de, &pch);
 		else
-			ilk_display_irq_ack(dev_priv, &de, &pch);
+			ilk_display_irq_ack(dev_priv, regs, &de, &pch);
 
-		I915_WRITE(DEIIR, de.iir);
+		raw_reg_write(regs, DEIIR, de.iir);
 	}
 
 	if (pm_iir)
-		I915_WRITE(GEN6_PMIIR, pm_iir);
+		raw_reg_write(regs, GEN6_PMIIR, pm_iir);
 
-	I915_WRITE(DEIER, de_ier);
+	raw_reg_write(regs, DEIER, de_ier);
 	if (!HAS_PCH_NOP(dev_priv))
-		I915_WRITE(SDEIER, sde_ier);
+		raw_reg_write(regs, SDEIER, sde_ier);
+
+	spin_unlock(&dev_priv->irq_lock);
 
 	if (gt_iir) {
 		ret = IRQ_HANDLED;
@@ -2898,11 +2905,11 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg)
 	return ret;
 }
 
-static void bxt_hpd_irq_ack(struct drm_i915_private *dev_priv,
+static void bxt_hpd_irq_ack(void __iomem * const regs,
 			    struct hpd_irq_regs *hpd)
 {
-	hpd->dig_hotplug_reg = I915_READ(PCH_PORT_HOTPLUG);
-	I915_WRITE(PCH_PORT_HOTPLUG, hpd->dig_hotplug_reg);
+	hpd->dig_hotplug_reg = raw_reg_read(regs, PCH_PORT_HOTPLUG);
+	raw_reg_write(regs, PCH_PORT_HOTPLUG, hpd->dig_hotplug_reg);
 }
 
 static void bxt_hpd_irq_handler(struct drm_i915_private *dev_priv,
@@ -2928,20 +2935,20 @@ struct gen8_de_irq_regs {
 	struct hpd_irq_regs tc, tbt; /* icl+ */
 };
 
-static void gen11_hpd_irq_ack(struct drm_i915_private *dev_priv,
+static void gen11_hpd_irq_ack(void __iomem * const regs,
 			      struct gen8_de_irq_regs *de)
 {
 	de->tc.hotplug_trigger = de->hpd_iir & GEN11_DE_TC_HOTPLUG_MASK;
 	de->tbt.hotplug_trigger = de->hpd_iir & GEN11_DE_TBT_HOTPLUG_MASK;
 
 	if (de->tc.hotplug_trigger) {
-		de->tc.dig_hotplug_reg = I915_READ(GEN11_TC_HOTPLUG_CTL);
-		I915_WRITE(GEN11_TC_HOTPLUG_CTL, de->tc.dig_hotplug_reg);
+		de->tc.dig_hotplug_reg = raw_reg_read(regs, GEN11_TC_HOTPLUG_CTL);
+		raw_reg_write(regs, GEN11_TC_HOTPLUG_CTL, de->tc.dig_hotplug_reg);
 	}
 
 	if (de->tbt.hotplug_trigger) {
-		de->tbt.dig_hotplug_reg = I915_READ(GEN11_TBT_HOTPLUG_CTL);
-		I915_WRITE(GEN11_TBT_HOTPLUG_CTL, de->tbt.dig_hotplug_reg);
+		de->tbt.dig_hotplug_reg = raw_reg_read(regs, GEN11_TBT_HOTPLUG_CTL);
+		raw_reg_write(regs, GEN11_TBT_HOTPLUG_CTL, de->tbt.dig_hotplug_reg);
 	}
 }
 
@@ -2969,76 +2976,77 @@ static void gen11_hpd_irq_handler(struct drm_i915_private *dev_priv,
 }
 
 static void
-gen8_de_irq_ack(struct drm_i915_private *dev_priv, u32 master_ctl,
+gen8_de_irq_ack(struct drm_i915_private *i915,
+		void __iomem * const regs, u32 master_ctl,
 		struct gen8_de_irq_regs *de, struct pch_irq_regs *pch)
 {
 	enum pipe pipe;
 
 	if (master_ctl & GEN8_DE_MISC_IRQ) {
-		de->misc_iir = I915_READ(GEN8_DE_MISC_IIR);
+		de->misc_iir = raw_reg_read(regs, GEN8_DE_MISC_IIR);
 
 		if (de->misc_iir) {
 			if (de->misc_iir & GEN8_DE_EDP_PSR)
-				hsw_psr_irq_ack(dev_priv, &de->psr_iir);
+				hsw_psr_irq_ack(regs, &de->psr_iir);
 
-			I915_WRITE(GEN8_DE_MISC_IIR, de->misc_iir);
+			raw_reg_write(regs, GEN8_DE_MISC_IIR, de->misc_iir);
 		}
 	}
 
 	if (master_ctl & GEN11_DE_HPD_IRQ) {
-		de->hpd_iir = I915_READ(GEN11_DE_HPD_IIR);
+		de->hpd_iir = raw_reg_read(regs, GEN11_DE_HPD_IIR);
 
 		if (de->hpd_iir) {
-			gen11_hpd_irq_ack(dev_priv, de);
+			gen11_hpd_irq_ack(regs, de);
 
-			I915_WRITE(GEN11_DE_HPD_IIR, de->hpd_iir);
+			raw_reg_write(regs, GEN11_DE_HPD_IIR, de->hpd_iir);
 		}
 	}
 
 	if (master_ctl & GEN8_DE_PORT_IRQ) {
-		de->port_iir = I915_READ(GEN8_DE_PORT_IIR);
+		de->port_iir = raw_reg_read(regs, GEN8_DE_PORT_IIR);
 
 		if (de->port_iir) {
-			if (IS_GEN9_LP(dev_priv)) {
+			if (IS_GEN9_LP(i915)) {
 				de->ddi.hotplug_trigger = de->port_iir & BXT_DE_PORT_HOTPLUG_MASK;
 				if (de->ddi.hotplug_trigger)
-					bxt_hpd_irq_ack(dev_priv, &de->ddi);
-			} else if (IS_BROADWELL(dev_priv)) {
+					bxt_hpd_irq_ack(regs, &de->ddi);
+			} else if (IS_BROADWELL(i915)) {
 				de->ddi.hotplug_trigger = de->port_iir & GEN8_PORT_DP_A_HOTPLUG;
 				if (de->ddi.hotplug_trigger)
-					ilk_hpd_irq_ack(dev_priv, &de->ddi);
+					ilk_hpd_irq_ack(regs, &de->ddi);
 			}
 
-			I915_WRITE(GEN8_DE_PORT_IIR, de->port_iir);
+			raw_reg_write(regs, GEN8_DE_PORT_IIR, de->port_iir);
 		}
 	}
 
-	for_each_pipe(dev_priv, pipe) {
+	for_each_pipe(i915, pipe) {
 		if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe)))
 			continue;
 
-		de->pipe_iir[pipe] = I915_READ(GEN8_DE_PIPE_IIR(pipe));
+		de->pipe_iir[pipe] = raw_reg_read(regs, GEN8_DE_PIPE_IIR(pipe));
 		if (de->pipe_iir[pipe])
-			I915_WRITE(GEN8_DE_PIPE_IIR(pipe), de->pipe_iir[pipe]);
+			raw_reg_write(regs, GEN8_DE_PIPE_IIR(pipe), de->pipe_iir[pipe]);
 	}
 
-	if (HAS_PCH_SPLIT(dev_priv) && !HAS_PCH_NOP(dev_priv) &&
+	if (HAS_PCH_SPLIT(i915) && !HAS_PCH_NOP(i915) &&
 	    master_ctl & GEN8_DE_PCH_IRQ) {
 		/*
 		 * FIXME(BDW): Assume for now that the new interrupt handling
 		 * scheme also closed the SDE interrupt handling race we've seen
 		 * on older pch-split platforms. But this needs testing.
 		 */
-		pch->iir = I915_READ(SDEIIR);
+		pch->iir = raw_reg_read(regs, SDEIIR);
 		if (pch->iir) {
-			if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
-				icp_irq_ack(dev_priv, pch);
-			else if (INTEL_PCH_TYPE(dev_priv) >= PCH_SPT)
-				spt_irq_ack(dev_priv, pch);
+			if (INTEL_PCH_TYPE(i915) >= PCH_ICP)
+				icp_irq_ack(regs, pch);
+			else if (INTEL_PCH_TYPE(i915) >= PCH_SPT)
+				spt_irq_ack(regs, pch);
 			else
-				cpt_irq_ack(dev_priv, pch);
+				cpt_irq_ack(regs, pch);
 
-			I915_WRITE(SDEIIR, pch->iir);
+			raw_reg_write(regs, SDEIIR, pch->iir);
 		}
 	}
 }
@@ -3235,24 +3243,29 @@ static irqreturn_t gen8_irq_handler(int irq, void *arg)
 	if (!intel_irqs_enabled(dev_priv))
 		return IRQ_NONE;
 
+	spin_lock(&dev_priv->irq_lock);
+
 	master_ctl = gen8_master_intr_disable(regs);
 	if (!master_ctl) {
 		gen8_master_intr_enable(regs);
+		spin_unlock(&dev_priv->irq_lock);
 		return IRQ_NONE;
 	}
 
 	/* Find, clear, then process each source of interrupt */
-	gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir);
+	gen8_gt_irq_ack(regs, master_ctl, gt_iir);
 
 	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
 	if (master_ctl & ~GEN8_GT_IRQS) {
 		disable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
-		gen8_de_irq_ack(dev_priv, master_ctl, &de, &pch);
+		gen8_de_irq_ack(dev_priv, regs, master_ctl, &de, &pch);
 		enable_rpm_wakeref_asserts(&dev_priv->runtime_pm);
 	}
 
 	gen8_master_intr_enable(regs);
 
+	spin_unlock(&dev_priv->irq_lock);
+
 	gen8_gt_irq_handler(dev_priv, master_ctl, gt_iir);
 
 	if (master_ctl & ~GEN8_GT_IRQS) {
@@ -3390,9 +3403,9 @@ gen11_gt_irq_handler(struct drm_i915_private * const i915,
 }
 
 static u32
-gen11_gu_misc_irq_ack(struct drm_i915_private *dev_priv, const u32 master_ctl)
+gen11_gu_misc_irq_ack(void __iomem * const regs,
+		      u32 master_ctl)
 {
-	void __iomem * const regs = dev_priv->uncore.regs;
 	u32 iir;
 
 	if (!(master_ctl & GEN11_GU_MISC_IRQ))
@@ -3443,9 +3456,12 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg)
 	if (!intel_irqs_enabled(i915))
 		return IRQ_NONE;
 
+	spin_lock(&i915->irq_lock);
+
 	master_ctl = gen11_master_intr_disable(regs);
 	if (!master_ctl) {
 		gen11_master_intr_enable(regs);
+		spin_unlock(&i915->irq_lock);
 		return IRQ_NONE;
 	}
 
@@ -3461,14 +3477,16 @@ static irqreturn_t gen11_irq_handler(int irq, void *arg)
 		 * GEN11_DISPLAY_INT_CTL has same format as GEN8_MASTER_IRQ
 		 * for the display related bits.
 		 */
-		gen8_de_irq_ack(i915, disp_ctl, &de, &pch);
+		gen8_de_irq_ack(i915, regs, disp_ctl, &de, &pch);
 		enable_rpm_wakeref_asserts(&i915->runtime_pm);
 	}
 
-	gu_misc_iir = gen11_gu_misc_irq_ack(i915, master_ctl);
+	gu_misc_iir = gen11_gu_misc_irq_ack(regs, master_ctl);
 
 	gen11_master_intr_enable(regs);
 
+	spin_unlock(&i915->irq_lock);
+
 	if (master_ctl & GEN11_DISPLAY_IRQ) {
 		disable_rpm_wakeref_asserts(&i915->runtime_pm);
 		/*
-- 
2.21.0



More information about the Intel-gfx mailing list