[Intel-xe] [PATCH v2 05/11] drm/xe: Use vfunc to initialize PAT

Lucas De Marchi lucas.demarchi at intel.com
Wed Sep 27 03:30:34 UTC 2023


On Tue, Sep 26, 2023 at 04:17:47PM -0700, Matt Roper wrote:
>On Tue, Sep 26, 2023 at 03:36:25PM -0700, Lucas De Marchi wrote:
>> Split the PAT initialization between SW-only and HW. The _early() only
>> sets up the ops and data structure that are used later to program the
>> tables. This allows the PAT to be easily extended to other platforms.
>>
>> Reviewed-by: Matt Roper <matthew.d.roper at intel.com>
>> Signed-off-by: Lucas De Marchi <lucas.demarchi at intel.com>
>> ---
>>  drivers/gpu/drm/xe/xe_device.c       |  3 ++
>>  drivers/gpu/drm/xe/xe_device_types.h | 13 ++++++
>>  drivers/gpu/drm/xe/xe_pat.c          | 59 +++++++++++++++++++++-------
>>  drivers/gpu/drm/xe/xe_pat.h          | 11 ++++++
>>  4 files changed, 72 insertions(+), 14 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
>> index 687dc3d79a66..046b7a087451 100644
>> --- a/drivers/gpu/drm/xe/xe_device.c
>> +++ b/drivers/gpu/drm/xe/xe_device.c
>> @@ -26,6 +26,7 @@
>>  #include "xe_irq.h"
>>  #include "xe_mmio.h"
>>  #include "xe_module.h"
>> +#include "xe_pat.h"
>>  #include "xe_pcode.h"
>>  #include "xe_pm.h"
>>  #include "xe_query.h"
>> @@ -276,6 +277,8 @@ int xe_device_probe(struct xe_device *xe)
>>  	int err;
>>  	u8 id;
>>
>> +	xe_pat_init_early(xe);
>> +
>>  	xe->info.mem_region_mask = 1;
>>  	err = xe_display_init_nommio(xe);
>>  	if (err)
>> diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
>> index 32ab0fea04ee..98835ee058f5 100644
>> --- a/drivers/gpu/drm/xe/xe_device_types.h
>> +++ b/drivers/gpu/drm/xe/xe_device_types.h
>> @@ -25,6 +25,7 @@
>>  #endif
>>
>>  struct xe_ggtt;
>> +struct xe_pat_ops;
>>
>>  #define XE_BO_INVALID_OFFSET	LONG_MAX
>>
>> @@ -331,6 +332,18 @@ struct xe_device {
>>  		atomic_t ref;
>>  	} mem_access;
>>
>> +	/**
>> +	 * @pat: Encapsulate PAT related stuff
>> +	 */
>> +	struct {
>> +		/** Internal operations to abstract platforms */
>> +		const struct xe_pat_ops *ops;
>> +		/** PAT table to program in the HW */
>> +		const u32 *table;
>> +		/** Number of PAT entries */
>> +		int n_entries;
>> +	} pat;
>> +
>>  	/** @d3cold: Encapsulate d3cold related stuff */
>>  	struct {
>>  		/** capable: Indicates if root port is d3cold capable */
>> diff --git a/drivers/gpu/drm/xe/xe_pat.c b/drivers/gpu/drm/xe/xe_pat.c
>> index 71e0e047fff3..86386633e206 100644
>> --- a/drivers/gpu/drm/xe/xe_pat.c
>> +++ b/drivers/gpu/drm/xe/xe_pat.c
>> @@ -32,6 +32,11 @@
>>  #define TGL_PAT_WC				REG_FIELD_PREP(TGL_MEM_TYPE_MASK, 1)
>>  #define TGL_PAT_UC				REG_FIELD_PREP(TGL_MEM_TYPE_MASK, 0)
>>
>> +struct xe_pat_ops {
>> +	void (*program_graphics)(struct xe_gt *gt, const u32 table[], int n_entries);
>> +	void (*program_media)(struct xe_gt *gt, const u32 table[], int n_entries);
>> +};
>> +
>>  static const u32 tgl_pat_table[] = {
>>  	[0] = TGL_PAT_WB,
>>  	[1] = TGL_PAT_WC,
>> @@ -80,24 +85,37 @@ static void program_pat_mcr(struct xe_gt *gt, const u32 table[], int n_entries)
>>  	}
>>  }
>>
>> -void xe_pat_init(struct xe_gt *gt)
>> -{
>> -	struct xe_device *xe = gt_to_xe(gt);
>> +static const struct xe_pat_ops tgl_pat_ops = {
>> +	.program_graphics = program_pat,
>> +};
>> +
>> +static const struct xe_pat_ops pvc_pat_ops = {
>> +	.program_graphics = program_pat_mcr,
>> +};
>> +
>> +/*
>> + * SAMedia register offsets are adjusted by the write methods and they target
>> + * registers that are not MCR, while for normal GT they are MCR
>> + */
>> +static const struct xe_pat_ops mtl_pat_ops = {
>> +	.program_graphics = program_pat,
>> +	.program_media = program_pat_mcr,
>> +};
>>
>> +void xe_pat_init_early(struct xe_device *xe)
>> +{
>>  	if (xe->info.platform == XE_METEORLAKE) {
>> -		/*
>> -		 * SAMedia register offsets are adjusted by the write methods
>> -		 * and they target registers that are not MCR, while for normal
>> -		 * GT they are MCR
>> -		 */
>> -		if (xe_gt_is_media_type(gt))
>> -			program_pat(gt, mtl_pat_table, ARRAY_SIZE(mtl_pat_table));
>> -		else
>> -			program_pat_mcr(gt, mtl_pat_table, ARRAY_SIZE(mtl_pat_table));
>> +		xe->pat.ops = &mtl_pat_ops;
>> +		xe->pat.table = mtl_pat_table;
>> +		xe->pat.n_entries = ARRAY_SIZE(mtl_pat_table);
>>  	} else if (xe->info.platform == XE_PVC || xe->info.platform == XE_DG2) {
>> -		program_pat_mcr(gt, pvc_pat_table, ARRAY_SIZE(pvc_pat_table));
>> +		xe->pat.ops = &pvc_pat_ops;
>
>Actually, to be more consistent with the rest of the driver we should
>probably name this 'dg2_pat_ops' after the first platform that
>introduced this.

I was not very happy with the name neither, but naming it dg2 would be
inconsistent with the pvc_pat_table.... or I would need to rename that
in this same patch. But my final goal was to name it after the arch, so
renaming it here would be pointless. See patch #7.

Lucas De Marchi

>
>
>Matt
>
>> +		xe->pat.table = pvc_pat_table;
>> +		xe->pat.n_entries = ARRAY_SIZE(pvc_pat_table);
>>  	} else if (GRAPHICS_VERx100(xe) <= 1210) {
>> -		program_pat(gt, tgl_pat_table, ARRAY_SIZE(tgl_pat_table));
>> +		xe->pat.ops = &tgl_pat_ops;
>> +		xe->pat.table = tgl_pat_table;
>> +		xe->pat.n_entries = ARRAY_SIZE(tgl_pat_table);
>>  	} else {
>>  		/*
>>  		 * Going forward we expect to need new PAT settings for most
>> @@ -111,3 +129,16 @@ void xe_pat_init(struct xe_gt *gt)
>>  			GRAPHICS_VER(xe), GRAPHICS_VERx100(xe) % 100);
>>  	}
>>  }
>> +
>> +void xe_pat_init(struct xe_gt *gt)
>> +{
>> +	struct xe_device *xe = gt_to_xe(gt);
>> +
>> +	if (!xe->pat.ops)
>> +		return;
>> +
>> +	if (xe_gt_is_media_type(gt))
>> +		xe->pat.ops->program_media(gt, xe->pat.table, xe->pat.n_entries);
>> +	else
>> +		xe->pat.ops->program_graphics(gt, xe->pat.table, xe->pat.n_entries);
>> +}
>> diff --git a/drivers/gpu/drm/xe/xe_pat.h b/drivers/gpu/drm/xe/xe_pat.h
>> index 659de4008131..744318cab69b 100644
>> --- a/drivers/gpu/drm/xe/xe_pat.h
>> +++ b/drivers/gpu/drm/xe/xe_pat.h
>> @@ -7,7 +7,18 @@
>>  #define _XE_PAT_H_
>>
>>  struct xe_gt;
>> +struct xe_device;
>>
>> +/**
>> + * xe_pat_init_early - SW initialization, setting up data based on device
>> + * @xe: xe device
>> + */
>> +void xe_pat_init_early(struct xe_device *xe);
>> +
>> +/**
>> + * xe_pat_init_early - Program HW PAT table
>> + * @gt: GT structure
>> + */
>>  void xe_pat_init(struct xe_gt *gt);
>>
>>  #endif
>> --
>> 2.40.1
>>
>
>-- 
>Matt Roper
>Graphics Software Engineer
>Linux GPU Platform Enablement
>Intel Corporation


More information about the Intel-xe mailing list