diff mbox series

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

Message ID 20211029032817.3747750-8-matthew.d.roper@intel.com (mailing list archive)
State New, archived
Headers show
Series i915: Initial multi-tile support | expand

Commit Message

Matt Roper Oct. 29, 2021, 3:28 a.m. UTC
From: Paulo Zanoni <paulo.r.zanoni@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@intel.com>
Cc: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 41 ++++++++++++++++++---------------
 1 file changed, 23 insertions(+), 18 deletions(-)

Comments

Andi Shyti Nov. 1, 2021, 11:33 p.m. UTC | #1
Hi Matt and Paulo,

> @@ -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;

just a nitpick, this doesn't need to be initialize and you could
also insert it inside the for_each_gt()

Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>

Thanks,
Andi

> +	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
diff mbox series

Patch

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);