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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Paulo Zanoni <paulo.r.zanoni@xxxxxxxxx>

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@xxxxxxxxx>
Cc: Lucas De Marchi <lucas.demarchi@xxxxxxxxx>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@xxxxxxxxx>
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx>
Signed-off-by: Matt Roper <matthew.d.roper@xxxxxxxxx>
---
 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




[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux