[PATCH 1/2] drm/xe/gt: Add L3 bank mask to GT topology

Matt Roper matthew.d.roper at intel.com
Tue Apr 9 22:44:07 UTC 2024


On Fri, Apr 05, 2024 at 11:59:14AM +0000, Francois Dugast wrote:
> Generate the mask of enabled L3 banks for the GT. It is stored with the
> rest of the GT topology in a consistent representation across platforms.
> For now the L3 bank mask is just printed in the log for developers to
> easily figure out the fusing characteristics of machines that they are
> trying to debug issues on. Later it can be used to replace existing code
> in the driver that requires the L3 bank count (not mask). Also the mask
> can easily be exposed to user space in a new query if needed.
> 
> Bspec: 52545, 52546, 62482
> Cc: Matt Roper <matthew.d.roper at intel.com>
> Signed-off-by: Francois Dugast <francois.dugast at intel.com>
> ---
>  drivers/gpu/drm/xe/regs/xe_gt_regs.h |   3 +
>  drivers/gpu/drm/xe/xe_gt_topology.c  | 107 +++++++++++++++++++++++++++
>  drivers/gpu/drm/xe/xe_gt_types.h     |  13 +++-
>  3 files changed, 119 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
> index 6617c86a096b..c026b9d3ca15 100644
> --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h
> +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h
> @@ -157,7 +157,10 @@
>  #define	MIRROR_FUSE3				XE_REG(0x9118)
>  #define   XE2_NODE_ENABLE_MASK			REG_GENMASK(31, 16)
>  #define   L3BANK_PAIR_COUNT			4
> +#define   XEHPC_GT_L3_MODE_MASK			REG_GENMASK(7, 4)
> +#define   XE2_GT_L3_MODE_MASK			REG_GENMASK(7, 4)
>  #define   L3BANK_MASK				REG_GENMASK(3, 0)
> +#define   XELP_GT_L3_MODE_MASK			REG_GENMASK(7, 0)
>  /* on Xe_HP the same fuses indicates mslices instead of L3 banks */
>  #define   MAX_MSLICES				4
>  #define   MEML3_EN_MASK				REG_GENMASK(3, 0)
> diff --git a/drivers/gpu/drm/xe/xe_gt_topology.c b/drivers/gpu/drm/xe/xe_gt_topology.c
> index f5773a14f3c8..de2ba412e86c 100644
> --- a/drivers/gpu/drm/xe/xe_gt_topology.c
> +++ b/drivers/gpu/drm/xe/xe_gt_topology.c
> @@ -8,6 +8,7 @@
>  #include <linux/bitmap.h>
>  
>  #include "regs/xe_gt_regs.h"
> +#include "xe_assert.h"
>  #include "xe_gt.h"
>  #include "xe_mmio.h"
>  
> @@ -59,6 +60,109 @@ load_eu_mask(struct xe_gt *gt, xe_eu_mask_t mask)
>  	bitmap_from_arr32(mask, &val, XE_MAX_EU_FUSE_BITS);
>  }
>  
> +/**
> + * replicate_by_mask - Replicate a bit pattern according to a mask
> + *
> + * It is used to compute the L3 bank masks in a generic format on
> + * various platforms where the internal representation of L3 node
> + * and masks from registers are different.
> + *
> + * @xe: device
> + * @dst: destination
> + * @pattern: pattern to replicate
> + * @mask: mask describing where to replicate the pattern
> + * @maskbits: how many bits represents each bit in the mask
> + *
> + * Example 1:
> + * ----------
> + * @pattern = 0b1111
> + *              └┬─┘
> + * @maskbits =   4 (bits)
> + * @mask = 0b0101
> + *           ││││
> + *           │││└────────────────── 0b1111 (=1×0b1111)
> + *           ││└──────────── 0b0000    │   (=0×0b1111)
> + *           │└────── 0b1111    │      │   (=1×0b1111)
> + *           └ 0b0000    │      │      │   (=0×0b1111)
> + *                │      │      │      │
> + * @dst =      0b0000 0b1111 0b0000 0b1111
> + *
> + * Example 2:
> + * ----------
> + * @pattern = 0b11111111
> + *              └┬─────┘
> + * @maskbits =   8 (bits)
> + * @mask = 0b10
> + *           ││
> + *           ││
> + *           ││
> + *           │└────────── 0b00000000 (=0×0b11111111)
> + *           └ 0b11111111      │     (=1×0b11111111)
> + *                  │          │
> + * @dst =      0b11111111 0b00000000
> + */
> +static void
> +replicate_by_mask(struct xe_device *xe, xe_l3_bank_mask_t dst,
> +		  xe_l3_bank_mask_t pattern, unsigned long mask, int maskbits)

We should probably s/maskbits/patternbits/ since that's the size
actually being passed here (example 2 above does a good job of showing
this).

We might want to put "l3" somewhere in the function name as well to make
it clear that this function is specifically intended for use on the L3
masks and can't be used on the other mask types in this file.

Aside from those, the rest of this patch seems to match the information I
can find on the L3 handling for each platform.


Matt

> +{
> +	unsigned long bit;
> +
> +	xe_assert(xe, fls(mask) <= maskbits);
> +	for_each_set_bit(bit, &mask, 32) {
> +		xe_l3_bank_mask_t shifted_pattern = {};
> +
> +		bitmap_shift_left(shifted_pattern, pattern, bit * maskbits,
> +				  XE_MAX_L3_BANK_MASK_BITS);
> +		bitmap_or(dst, dst, shifted_pattern, XE_MAX_L3_BANK_MASK_BITS);
> +	}
> +}
> +
> +static void
> +load_l3_bank_mask(struct xe_gt *gt, xe_l3_bank_mask_t l3_bank_mask)
> +{
> +	struct xe_device *xe = gt_to_xe(gt);
> +	u32 fuse3 = xe_mmio_read32(gt, MIRROR_FUSE3);
> +
> +	if (GRAPHICS_VER(xe) >= 20) {
> +		xe_l3_bank_mask_t per_node = {};
> +		u32 meml3_en = REG_FIELD_GET(XE2_NODE_ENABLE_MASK, fuse3);
> +		u32 bank_val = REG_FIELD_GET(XE2_GT_L3_MODE_MASK, fuse3);
> +
> +		bitmap_from_arr32(per_node, &bank_val, 32);
> +		replicate_by_mask(xe, l3_bank_mask, per_node, meml3_en, 4);
> +	} else if (GRAPHICS_VERx100(xe) >= 1270) {
> +		xe_l3_bank_mask_t per_node = {};
> +		xe_l3_bank_mask_t per_mask_bit = {};
> +		u32 meml3_en = REG_FIELD_GET(MEML3_EN_MASK, fuse3);
> +		u32 fuse4 = xe_mmio_read32(gt, XEHP_FUSE4);
> +		u32 bank_val = REG_FIELD_GET(GT_L3_EXC_MASK, fuse4);
> +
> +		bitmap_set_value8(per_mask_bit, 0x3, 0);
> +		replicate_by_mask(xe, per_node, per_mask_bit, bank_val, 2);
> +		replicate_by_mask(xe, l3_bank_mask, per_node, meml3_en, 4);
> +	} else if (xe->info.platform == XE_PVC) {
> +		xe_l3_bank_mask_t per_node = {};
> +		xe_l3_bank_mask_t per_mask_bit = {};
> +		u32 meml3_en = REG_FIELD_GET(MEML3_EN_MASK, fuse3);
> +		u32 bank_val = REG_FIELD_GET(XEHPC_GT_L3_MODE_MASK, fuse3);
> +
> +		bitmap_set_value8(per_mask_bit, 0xf, 0);
> +		replicate_by_mask(xe, per_node, per_mask_bit, bank_val, 4);
> +		replicate_by_mask(xe, l3_bank_mask, per_node, meml3_en, 16);
> +	} else if (xe->info.platform == XE_DG2) {
> +		xe_l3_bank_mask_t per_node = {};
> +		u32 mask = REG_FIELD_GET(MEML3_EN_MASK, fuse3);
> +
> +		bitmap_set_value8(per_node, 0xff, 0);
> +		replicate_by_mask(xe, l3_bank_mask, per_node, mask, 8);
> +	} else {
> +		/* 1:1 register bit to mask bit (inverted register bits) */
> +		u32 mask = REG_FIELD_GET(XELP_GT_L3_MODE_MASK, ~fuse3);
> +
> +		bitmap_from_arr32(l3_bank_mask, &mask, 32);
> +	}
> +}
> +
>  static void
>  get_num_dss_regs(struct xe_device *xe, int *geometry_regs, int *compute_regs)
>  {
> @@ -103,6 +207,7 @@ xe_gt_topology_init(struct xe_gt *gt)
>  		      XEHPC_GT_COMPUTE_DSS_ENABLE_EXT,
>  		      XE2_GT_COMPUTE_DSS_2);
>  	load_eu_mask(gt, gt->fuse_topo.eu_mask_per_dss);
> +	load_l3_bank_mask(gt, gt->fuse_topo.l3_bank_mask);
>  
>  	p = drm_dbg_printer(&gt_to_xe(gt)->drm, DRM_UT_DRIVER, "GT topology");
>  
> @@ -120,6 +225,8 @@ xe_gt_topology_dump(struct xe_gt *gt, struct drm_printer *p)
>  	drm_printf(p, "EU mask per DSS:     %*pb\n", XE_MAX_EU_FUSE_BITS,
>  		   gt->fuse_topo.eu_mask_per_dss);
>  
> +	drm_printf(p, "L3 bank mask:        %*pb\n", XE_MAX_L3_BANK_MASK_BITS,
> +		   gt->fuse_topo.l3_bank_mask);
>  }
>  
>  /*
> diff --git a/drivers/gpu/drm/xe/xe_gt_types.h b/drivers/gpu/drm/xe/xe_gt_types.h
> index 2143dffcaf11..e60156871026 100644
> --- a/drivers/gpu/drm/xe/xe_gt_types.h
> +++ b/drivers/gpu/drm/xe/xe_gt_types.h
> @@ -24,13 +24,15 @@ enum xe_gt_type {
>  	XE_GT_TYPE_MEDIA,
>  };
>  
> -#define XE_MAX_DSS_FUSE_REGS	3
> -#define XE_MAX_DSS_FUSE_BITS	(32 * XE_MAX_DSS_FUSE_REGS)
> -#define XE_MAX_EU_FUSE_REGS	1
> -#define XE_MAX_EU_FUSE_BITS	(32 * XE_MAX_EU_FUSE_REGS)
> +#define XE_MAX_DSS_FUSE_REGS		3
> +#define XE_MAX_DSS_FUSE_BITS		(32 * XE_MAX_DSS_FUSE_REGS)
> +#define XE_MAX_EU_FUSE_REGS		1
> +#define XE_MAX_EU_FUSE_BITS		(32 * XE_MAX_EU_FUSE_REGS)
> +#define XE_MAX_L3_BANK_MASK_BITS	64
>  
>  typedef unsigned long xe_dss_mask_t[BITS_TO_LONGS(XE_MAX_DSS_FUSE_BITS)];
>  typedef unsigned long xe_eu_mask_t[BITS_TO_LONGS(XE_MAX_EU_FUSE_BITS)];
> +typedef unsigned long xe_l3_bank_mask_t[BITS_TO_LONGS(XE_MAX_L3_BANK_MASK_BITS)];
>  
>  struct xe_mmio_range {
>  	u32 start;
> @@ -327,6 +329,9 @@ struct xe_gt {
>  
>  		/** @fuse_topo.eu_mask_per_dss: EU mask per DSS*/
>  		xe_eu_mask_t eu_mask_per_dss;
> +
> +		/** @fuse_topo.l3_bank_mask: L3 bank mask */
> +		xe_l3_bank_mask_t l3_bank_mask;
>  	} fuse_topo;
>  
>  	/** @steering: register steering for individual HW units */
> -- 
> 2.34.1
> 

-- 
Matt Roper
Graphics Software Engineer
Linux GPU Platform Enablement
Intel Corporation


More information about the Intel-xe mailing list