[Intel-xe] [PATCH v2 4/4] drm/xe: Fix LRC workarounds

Souza, Jose jose.souza at intel.com
Wed Sep 6 16:46:02 UTC 2023


On Tue, 2023-09-05 at 18:20 -0700, Lucas De Marchi wrote:
> Fix 2 issues when writing LRC workarounds by copying the same handling
> done when processing other RTP entries:
> 
> For masked registers, it was not correctly setting the upper 16bits.
> Differently than i915, the entry itself doesn't set the upper bits
> for masked registers: this is done when applying them. Testing on ADL-P:
> 
> Before:
> 	[drm:xe_gt_record_default_lrcs [xe]] LRC WA rcs0 save-restore MMIOs
> 	[drm:xe_gt_record_default_lrcs [xe]] REG[0x2580] = 0x00000002
> 	...
> 	[drm:xe_gt_record_default_lrcs [xe]] REG[0x7018] = 0x00002000
> 	[drm:xe_gt_record_default_lrcs [xe]] REG[0x7300] = 0x00000040
> 	[drm:xe_gt_record_default_lrcs [xe]] REG[0x7304] = 0x00000200
> 
> After:
> 	[drm:xe_gt_record_default_lrcs [xe]] LRC WA rcs0 save-restore MMIOs
> 	[drm:xe_gt_record_default_lrcs [xe]] REG[0x2580] = 0x00060002
> 	...
> 	[drm:xe_gt_record_default_lrcs [xe]] REG[0x7018] = 0x20002000
> 	[drm:xe_gt_record_default_lrcs [xe]] REG[0x7300] = 0x00400040
> 	[drm:xe_gt_record_default_lrcs [xe]] REG[0x7304] = 0x02000200

Would it be too hard to test if LRC workarounds were applied correctly?

> 
> All of these registers are masked registers, so writing to them without
> the relevant bits in the upper 16b doesn't have any effect.
> 
> Also, this adds support to regular registers; previously it was assumed
> that LRC entries would only contain masked registers. However this is
> not true. 0x6604 is not a masked register, but used in workarounds for
> e.g.  ADL-P. See commit 28cf243a341a ("drm/i915/gt: Fix context
> workarounds with non-masked regs"). In the same test with ADL-P as
> above:
> 
> Before:
> 	[drm:xe_gt_record_default_lrcs [xe]] REG[0x6604] = 0xe0000000
> After:
> 	[drm:xe_gt_record_default_lrcs [xe]] REG[0x6604] = 0xe0efef6f
> 
> As can be seen, now it will read what was in the register rather than
> completely overwrite the other bits.
> 
> Signed-off-by: Lucas De Marchi <lucas.demarchi at intel.com>
> Reviewed-by: Matt Roper <matthew.d.roper at intel.com>
> ---
>  drivers/gpu/drm/xe/xe_gt.c | 41 +++++++++++++++++++++++++++++++-------
>  1 file changed, 34 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c
> index 9e226b8a005a..678a276a25dc 100644
> --- a/drivers/gpu/drm/xe/xe_gt.c
> +++ b/drivers/gpu/drm/xe/xe_gt.c
> @@ -114,11 +114,20 @@ static int emit_nop_job(struct xe_gt *gt, struct xe_exec_queue *q)
>  	return 0;
>  }
>  
> +/*
> + * Convert back from encoded value to type-safe, only to be used when reg.mcr
> + * is true
> + */
> +static struct xe_reg_mcr to_xe_reg_mcr(const struct xe_reg reg)
> +{
> +	return (const struct xe_reg_mcr){.__reg.raw = reg.raw };
> +}
> +
>  static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q)
>  {
>  	struct xe_reg_sr *sr = &q->hwe->reg_lrc;
>  	struct xe_reg_sr_entry *entry;
> -	unsigned long reg;
> +	unsigned long idx;
>  	struct xe_sched_job *job;
>  	struct xe_bb *bb;
>  	struct dma_fence *fence;
> @@ -129,18 +138,36 @@ static int emit_wa_job(struct xe_gt *gt, struct xe_exec_queue *q)
>  	if (IS_ERR(bb))
>  		return PTR_ERR(bb);
>  
> -	xa_for_each(&sr->xa, reg, entry)
> +	xa_for_each(&sr->xa, idx, entry)
>  		++count;
>  
>  	if (count) {
>  		xe_gt_dbg(gt, "LRC WA %s save-restore batch\n", sr->name);
>  
>  		bb->cs[bb->len++] = MI_LOAD_REGISTER_IMM(count);
> -		xa_for_each(&sr->xa, reg, entry) {
> -			bb->cs[bb->len++] = reg;
> -			bb->cs[bb->len++] = entry->set_bits;
> -			xe_gt_dbg(gt, "REG[0x%lx] = 0x%08x", reg,
> -				  entry->set_bits);
> +
> +		xa_for_each(&sr->xa, idx, entry) {
> +			struct xe_reg reg = entry->reg;
> +			struct xe_reg_mcr reg_mcr = to_xe_reg_mcr(reg);
> +			u32 val;
> +
> +			/*
> +			 * Skip reading the register if it's not really needed
> +			 */
> +			if (reg.masked)
> +				val = entry->clr_bits << 16;
> +			else if (entry->clr_bits + 1)
> +				val = (reg.mcr ?
> +				       xe_gt_mcr_unicast_read_any(gt, reg_mcr) :
> +				       xe_mmio_read32(gt, reg)) & (~entry->clr_bits);
> +			else
> +				val = 0;
> +
> +			val |= entry->set_bits;
> +
> +			bb->cs[bb->len++] = reg.addr;
> +			bb->cs[bb->len++] = val;
> +			xe_gt_dbg(gt, "REG[0x%x] = 0x%08x", reg.addr, val);
>  		}
>  	}
>  



More information about the Intel-xe mailing list