diff options
author | Lucas De Marchi <lucas.demarchi@intel.com> | 2023-01-31 04:08:37 +0300 |
---|---|---|
committer | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2023-12-20 02:27:51 +0300 |
commit | 564d64f83de9759c1faa4a64ee4aed8465281ecb (patch) | |
tree | 1222b3a1836e3d4092f7f732ee45b783dc7a8d44 /drivers/gpu | |
parent | 3319b213d7c8bdeaa001fec7b60aefa2390112d4 (diff) | |
download | linux-564d64f83de9759c1faa4a64ee4aed8465281ecb.tar.xz |
drm/xe/mcr: Add SQIDI steering for DG2
Like detailed in commit 927dfdd09d8c ("drm/i915/dg2: Add SQIDI
steering"), some registers are expected to have the selector
initialized just once and never set to anything else. For xe, the
registers with SQIDI replication type (SF and MCFG) were missing,
resulting in warnings like:
[ 410.685565] xe 0000:03:00.0: Did not find MCR register 0x8724 in any MCR steering table
While adding these registers, abstract the handling for
"dg2_gam_ranges", moving them together with SF/MCFG to a dedicated
table. This also avoids that range to be checked for platforms other
than DG2. For DG2, this is the new steering output:
# cat /sys/kernel/debug/dri/0/gt0/steering
...
IMPLICIT steering: group=0x0, instance=0x0
0x000b00 - 0x000bff
0x001000 - 0x001fff
0x004000 - 0x004aff
0x008700 - 0x0087ff
0x00c800 - 0x00cfff
0x00f000 - 0x00ffff
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/xe/xe_gt.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_gt_mcr.c | 80 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_gt_mcr.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/xe/xe_gt_types.h | 7 |
4 files changed, 59 insertions, 32 deletions
diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c index 0e0d5cadb3e7..20dbc08d3685 100644 --- a/drivers/gpu/drm/xe/xe_gt.c +++ b/drivers/gpu/drm/xe/xe_gt.c @@ -500,6 +500,7 @@ static int all_fw_domain_init(struct xe_gt *gt) if (err) goto err_hw_fence_irq; + xe_gt_mcr_set_implicit_defaults(gt); xe_reg_sr_apply_mmio(>->reg_sr, gt); err = xe_gt_clock_init(gt); @@ -633,6 +634,7 @@ static int do_gt_restart(struct xe_gt *gt) setup_private_ppat(gt); + xe_gt_mcr_set_implicit_defaults(gt); xe_reg_sr_apply_mmio(>->reg_sr, gt); err = xe_wopcm_init(>->uc.wopcm); diff --git a/drivers/gpu/drm/xe/xe_gt_mcr.c b/drivers/gpu/drm/xe/xe_gt_mcr.c index d7c89f7b56e2..bb71071c3435 100644 --- a/drivers/gpu/drm/xe/xe_gt_mcr.c +++ b/drivers/gpu/drm/xe/xe_gt_mcr.c @@ -155,15 +155,13 @@ static const struct xe_mmio_range xelpmp_oaddrm_steering_table[] = { {}, }; -/* - * DG2 GAM registers are a special case; this table is checked directly in - * xe_gt_mcr_get_nonterminated_steering and is not hooked up via - * gt->steering[]. - */ -static const struct xe_mmio_range dg2_gam_ranges[] = { - { 0x004000, 0x004AFF }, - { 0x00C800, 0x00CFFF }, - { 0x00F000, 0x00FFFF }, +static const struct xe_mmio_range dg2_implicit_steering_table[] = { + { 0x000B00, 0x000BFF }, /* SF (SQIDI replication) */ + { 0x001000, 0x001FFF }, /* SF (SQIDI replication) */ + { 0x004000, 0x004AFF }, /* GAM (MSLICE replication) */ + { 0x008700, 0x0087FF }, /* MCFG (SQIDI replication) */ + { 0x00C800, 0x00CFFF }, /* GAM (MSLICE replication) */ + { 0x00F000, 0x00FFFF }, /* GAM (MSLICE replication) */ {}, }; @@ -255,12 +253,14 @@ static const struct { [DSS] = { "DSS", init_steering_dss }, [OADDRM] = { "OADDRM", init_steering_oaddrm }, [INSTANCE0] = { "INSTANCE 0", init_steering_inst0 }, + [IMPLICIT_STEERING] = { "IMPLICIT", NULL }, }; void xe_gt_mcr_init(struct xe_gt *gt) { struct xe_device *xe = gt_to_xe(gt); + BUILD_BUG_ON(IMPLICIT_STEERING + 1 != NUM_STEERING_TYPES); BUILD_BUG_ON(ARRAY_SIZE(xe_steering_types) != NUM_STEERING_TYPES); spin_lock_init(>->mcr_lock); @@ -280,6 +280,7 @@ void xe_gt_mcr_init(struct xe_gt *gt) gt->steering[MSLICE].ranges = xehp_mslice_steering_table; gt->steering[LNCF].ranges = xehp_lncf_steering_table; gt->steering[DSS].ranges = xehp_dss_steering_table; + gt->steering[IMPLICIT_STEERING].ranges = dg2_implicit_steering_table; } else { gt->steering[L3BANK].ranges = xelp_l3bank_steering_table; gt->steering[DSS].ranges = xelp_dss_steering_table; @@ -291,6 +292,33 @@ void xe_gt_mcr_init(struct xe_gt *gt) xe_steering_types[i].init(gt); } +/** + * xe_gt_mcr_set_implicit_defaults - Initialize steer control registers + * @gt: GT structure + * + * Some register ranges don't need to have their steering control registers + * changed on each access - it's sufficient to set them once on initialization. + * This function sets those registers for each platform * + */ +void xe_gt_mcr_set_implicit_defaults(struct xe_gt *gt) +{ + struct xe_device *xe = gt_to_xe(gt); + + if (xe->info.platform == XE_DG2) { + u32 steer_val = REG_FIELD_PREP(GEN11_MCR_SLICE_MASK, 0) | + REG_FIELD_PREP(GEN11_MCR_SUBSLICE_MASK, 2); + + xe_mmio_write32(gt, MCFG_MCR_SELECTOR.reg, steer_val); + xe_mmio_write32(gt, SF_MCR_SELECTOR.reg, steer_val); + /* + * For GAM registers, all reads should be directed to instance 1 + * (unicast reads against other instances are not allowed), + * and instance 1 is already the hardware's default steering + * target, which we never change + */ + } +} + /* * xe_gt_mcr_get_nonterminated_steering - find group/instance values that * will steer a register to a non-terminated instance @@ -305,14 +333,15 @@ void xe_gt_mcr_init(struct xe_gt *gt) * steering. * * Returns true if the caller should steer to the @group/@instance values - * returned. Returns false if the caller need not perform any steering (i.e., - * the DG2 GAM range special case). + * returned. Returns false if the caller need not perform any steering */ static bool xe_gt_mcr_get_nonterminated_steering(struct xe_gt *gt, i915_mcr_reg_t reg, u8 *group, u8 *instance) { - for (int type = 0; type < NUM_STEERING_TYPES; type++) { + const struct xe_mmio_range *implicit_ranges; + + for (int type = 0; type < IMPLICIT_STEERING; type++) { if (!gt->steering[type].ranges) continue; @@ -325,27 +354,15 @@ static bool xe_gt_mcr_get_nonterminated_steering(struct xe_gt *gt, } } - /* - * All MCR registers should usually be part of one of the steering - * ranges we're tracking. However there's one special case: DG2 - * GAM registers are technically multicast registers, but are special - * in a number of ways: - * - they have their own dedicated steering control register (they - * don't share 0xFDC with other MCR classes) - * - all reads should be directed to instance 1 (unicast reads against - * other instances are not allowed), and instance 1 is already the - * the hardware's default steering target, which we never change - * - * Ultimately this means that we can just treat them as if they were - * unicast registers and all operations will work properly. - */ - for (int i = 0; dg2_gam_ranges[i].end > 0; i++) - if (xe_mmio_in_range(&dg2_gam_ranges[i], reg.reg)) - return false; + implicit_ranges = gt->steering[IMPLICIT_STEERING].ranges; + if (implicit_ranges) + for (int i = 0; implicit_ranges[i].end > 0; i++) + if (xe_mmio_in_range(&implicit_ranges[i], reg.reg)) + return false; /* - * Not found in a steering table and not a DG2 GAM register? We'll - * just steer to 0/0 as a guess and raise a warning. + * Not found in a steering table and not a register with implicit + * steering. Just steer to 0/0 as a guess and raise a warning. */ drm_WARN(>_to_xe(gt)->drm, true, "Did not find MCR register %#x in any MCR steering table\n", @@ -467,7 +484,6 @@ u32 xe_gt_mcr_unicast_read_any(struct xe_gt *gt, i915_mcr_reg_t reg) group, instance, 0); mcr_unlock(gt); } else { - /* DG2 GAM special case rules; treat as if unicast */ val = xe_mmio_read32(gt, reg.reg); } diff --git a/drivers/gpu/drm/xe/xe_gt_mcr.h b/drivers/gpu/drm/xe/xe_gt_mcr.h index 62ec6eb654a0..c31987d2177c 100644 --- a/drivers/gpu/drm/xe/xe_gt_mcr.h +++ b/drivers/gpu/drm/xe/xe_gt_mcr.h @@ -13,6 +13,8 @@ struct xe_gt; void xe_gt_mcr_init(struct xe_gt *gt); +void xe_gt_mcr_set_implicit_defaults(struct xe_gt *gt); + u32 xe_gt_mcr_unicast_read(struct xe_gt *gt, i915_mcr_reg_t reg, int group, int instance); u32 xe_gt_mcr_unicast_read_any(struct xe_gt *gt, i915_mcr_reg_t reg); diff --git a/drivers/gpu/drm/xe/xe_gt_types.h b/drivers/gpu/drm/xe/xe_gt_types.h index a40fab262ac9..b01edd3fdc4d 100644 --- a/drivers/gpu/drm/xe/xe_gt_types.h +++ b/drivers/gpu/drm/xe/xe_gt_types.h @@ -66,6 +66,13 @@ enum xe_steering_type { */ INSTANCE0, + /* + * Register ranges that don't need special steering for each register: + * it's sufficient to keep the HW-default for the selector, or only + * change it once, on GT initialization. This needs to be the last + * steering type. + */ + IMPLICIT_STEERING, NUM_STEERING_TYPES }; |