[PATCH v3 07/10] drm/i915/xehp: Determine which tile raised an interrupt

Matt Roper matthew.d.roper at intel.com
Fri Oct 29 03:28:14 UTC 2021


From: Paulo Zanoni <paulo.r.zanoni at intel.com>

The first step of interrupt handling is to read a tile0 register that
tells us in which tile the interrupt happened; we can then read the
usual interrupt registers from the appropriate tile.

Note that this is just the first step of handling interrupts properly on
multi-tile platforms.  Subsequent patches will convert other parts of
the interrupt handling flow.

v2:
 - Simplify init of t0_regs.  (Lucas)
 - Fix handling of display and GSE interrupts.  Although we only expect
   to receive these on tile 0, we should still process them inside the
   gt loop to ensure the proper tile's master_ctl value is used.

Cc: Stuart Summers <stuart.summers at intel.com>
Cc: Lucas De Marchi <lucas.demarchi at intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni at intel.com>
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
Signed-off-by: Matt Roper <matthew.d.roper at intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 41 ++++++++++++++++++---------------
 1 file changed, 23 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 038a9ec563c1..57a58151eaae 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2771,40 +2771,45 @@ static inline void dg1_master_intr_enable(void __iomem * const regs)
 static irqreturn_t dg1_irq_handler(int irq, void *arg)
 {
 	struct drm_i915_private * const i915 = arg;
+	void __iomem * const t0_regs = i915->gt.uncore->regs;
 	struct intel_gt *gt = &i915->gt;
-	void __iomem * const regs = gt->uncore->regs;
 	u32 master_tile_ctl, master_ctl;
-	u32 gu_misc_iir;
+	u32 gu_misc_iir = 0;
+	unsigned int i;
 
 	if (!intel_irqs_enabled(i915))
 		return IRQ_NONE;
 
-	master_tile_ctl = dg1_master_intr_disable(regs);
+	master_tile_ctl = dg1_master_intr_disable(t0_regs);
 	if (!master_tile_ctl) {
-		dg1_master_intr_enable(regs);
+		dg1_master_intr_enable(t0_regs);
 		return IRQ_NONE;
 	}
 
-	/* FIXME: we only support tile 0 for now. */
-	if (master_tile_ctl & DG1_MSTR_TILE(0)) {
+	for_each_gt(i915, i, gt) {
+		void __iomem *const regs = gt->uncore->regs;
+
+		if ((master_tile_ctl & DG1_MSTR_TILE(i)) == 0)
+			continue;
+
 		master_ctl = raw_reg_read(regs, GEN11_GFX_MSTR_IRQ);
 		raw_reg_write(regs, GEN11_GFX_MSTR_IRQ, master_ctl);
-	} else {
-		DRM_ERROR("Tile not supported: 0x%08x\n", master_tile_ctl);
-		dg1_master_intr_enable(regs);
-		return IRQ_NONE;
-	}
 
-	gen11_gt_irq_handler(gt, master_ctl);
+		gen11_gt_irq_handler(gt, master_ctl);
 
-	if (master_ctl & GEN11_DISPLAY_IRQ)
-		gen11_display_irq_handler(i915);
-
-	gu_misc_iir = gen11_gu_misc_irq_ack(gt, master_ctl);
+		/*
+		 * In practice we'll only get display and gu_misc interrupts
+		 * for the GSE on tile0, but it's still simplest to process
+		 * them inside the loop.
+		 */
+		if (master_ctl & GEN11_DISPLAY_IRQ)
+			gen11_display_irq_handler(i915);
 
-	dg1_master_intr_enable(regs);
+		gu_misc_iir = gen11_gu_misc_irq_ack(gt, master_ctl);
+		gen11_gu_misc_irq_handler(gt, gu_misc_iir);
+	}
 
-	gen11_gu_misc_irq_handler(gt, gu_misc_iir);
+	dg1_master_intr_enable(t0_regs);
 
 	pmu_irq_stats(i915, IRQ_HANDLED);
 
-- 
2.33.0



More information about the dri-devel mailing list