drm/xe/xe2: Add MCR register steering for primary GT
authorMatt Roper <matthew.d.roper@intel.com>
Fri, 11 Aug 2023 16:06:06 +0000 (09:06 -0700)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Thu, 21 Dec 2023 16:40:24 +0000 (11:40 -0500)
Xe2 uses the same steering control register and steering semaphore
register as MTL.  As with recent platforms, group/instance 0,0 is
sufficient to target a non-terminated instance for most classes of MCR
registers; the only types of ranges that need to consider platform
fusing to find a non-terminated instance are SLICE/DSS ranges and a new
SQIDI_PSMI type of range.

Note that the range of valid bits in XE2_NODE_ENABLE_MASK may be reduced
for some Xe2 SKUs.  However the lowest bits are always valid and only
the lowest instance is obtained via __ffs(), so there's no need to
complicate the masking with extra platform/subplatform checks.

Also note that Wa_14017387313 suggests skipping MCR lock acquisition
around GAM and GAMWKR registers to prevent MCR register accesses in an
interrupt handler from deadlocking when the steering semaphore is
already held outside the interrupt context.  At this time Xe never
issues MCR accesses from within an interrupt handler so the workaround
is not currently needed.

v2:
  - [0x008700-0x0087FF] range to extend up to 0x887F (Matt Attwood)
  - [0x00EF00-0x00F4FF] -> [0x00F000, 0xFFFF] to follow latest
    bspec version (Bala)

Bspec: 71185
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: Balasubramani Vivekanandan <balasubramani.vivekanandan@intel.com>
Reviewed-by: Matt Atwood <matthew.s.atwood@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/regs/xe_gt_regs.h
drivers/gpu/drm/xe/xe_gt_mcr.c
drivers/gpu/drm/xe/xe_gt_types.h

index c445867..33830cd 100644 (file)
 #define   EN_32B_ACCESS                                REG_BIT(30)
 
 #define        MIRROR_FUSE3                            XE_REG(0x9118)
+#define   XE2_NODE_ENABLE_MASK                 REG_GENMASK(31, 16)
 #define   L3BANK_PAIR_COUNT                    4
 #define   L3BANK_MASK                          REG_GENMASK(3, 0)
 /* on Xe_HP the same fuses indicates mslices instead of L3 banks */
index 9eb7a6a..26f69e5 100644 (file)
@@ -181,6 +181,39 @@ static const struct xe_mmio_range dg2_implicit_steering_table[] = {
        {},
 };
 
+static const struct xe_mmio_range xe2lpg_dss_steering_table[] = {
+       { 0x005200, 0x0052FF },         /* SLICE */
+       { 0x005500, 0x007FFF },         /* SLICE */
+       { 0x008140, 0x00815F },         /* SLICE (0x8140-0x814F), DSS (0x8150-0x815F) */
+       { 0x0094D0, 0x00955F },         /* SLICE (0x94D0-0x951F), DSS (0x9520-0x955F) */
+       { 0x009680, 0x0096FF },         /* DSS */
+       { 0x00D800, 0x00D87F },         /* SLICE */
+       { 0x00DC00, 0x00DCFF },         /* SLICE */
+       { 0x00DE80, 0x00E8FF },         /* DSS (0xE000-0xE0FF reserved) */
+       { 0x00E980, 0x00E9FF },         /* SLICE */
+       { 0x013000, 0x0133FF },         /* DSS (0x13000-0x131FF), SLICE (0x13200-0x133FF) */
+       {},
+};
+
+static const struct xe_mmio_range xe2lpg_sqidi_psmi_steering_table[] = {
+       { 0x000B00, 0x000BFF },
+       { 0x001000, 0x001FFF },
+       {},
+};
+
+static const struct xe_mmio_range xe2lpg_instance0_steering_table[] = {
+       { 0x004000, 0x004AFF },         /* GAM, rsvd, GAMWKR */
+       { 0x008700, 0x00887F },         /* SQIDI, MEMPIPE */
+       { 0x00B000, 0x00B3FF },         /* NODE, L3BANK */
+       { 0x00C800, 0x00CFFF },         /* GAM */
+       { 0x00D880, 0x00D8FF },         /* NODE */
+       { 0x00DD00, 0x00DDFF },         /* MEMPIPE */
+       { 0x00E900, 0x00E97F },         /* MEMPIPE */
+       { 0x00F000, 0x00FFFF },         /* GAM, GAMWKR */
+       { 0x013400, 0x0135FF },         /* MEMPIPE */
+       {},
+};
+
 static void init_steering_l3bank(struct xe_gt *gt)
 {
        if (GRAPHICS_VERx100(gt_to_xe(gt)) >= 1270) {
@@ -265,6 +298,16 @@ static void init_steering_oaddrm(struct xe_gt *gt)
        gt->steering[DSS].instance_target = 0;          /* unused */
 }
 
+static void init_steering_sqidi_psmi(struct xe_gt *gt)
+{
+       u32 mask = REG_FIELD_GET(XE2_NODE_ENABLE_MASK,
+                                xe_mmio_read32(gt, MIRROR_FUSE3));
+       u32 select = __ffs(mask);
+
+       gt->steering[SQIDI_PSMI].group_target = select >> 1;
+       gt->steering[SQIDI_PSMI].instance_target = select & 0x1;
+}
+
 static void init_steering_inst0(struct xe_gt *gt)
 {
        gt->steering[DSS].group_target = 0;             /* unused */
@@ -280,6 +323,7 @@ static const struct {
        [LNCF] =        { "LNCF",       NULL }, /* initialized by mslice init */
        [DSS] =         { "DSS",        init_steering_dss },
        [OADDRM] =      { "OADDRM",     init_steering_oaddrm },
+       [SQIDI_PSMI] =  { "SQIDI_PSMI", init_steering_sqidi_psmi },
        [INSTANCE0] =   { "INSTANCE 0", init_steering_inst0 },
        [IMPLICIT_STEERING] = { "IMPLICIT", NULL },
 };
@@ -298,7 +342,11 @@ void xe_gt_mcr_init(struct xe_gt *gt)
 
                gt->steering[OADDRM].ranges = xelpmp_oaddrm_steering_table;
        } else {
-               if (GRAPHICS_VERx100(xe) >= 1270) {
+               if (GRAPHICS_VER(xe) >= 20) {
+                       gt->steering[DSS].ranges = xe2lpg_dss_steering_table;
+                       gt->steering[SQIDI_PSMI].ranges = xe2lpg_sqidi_psmi_steering_table;
+                       gt->steering[INSTANCE0].ranges = xe2lpg_instance0_steering_table;
+               } else if (GRAPHICS_VERx100(xe) >= 1270) {
                        gt->steering[INSTANCE0].ranges = xelpg_instance0_steering_table;
                        gt->steering[L3BANK].ranges = xelpg_l3bank_steering_table;
                        gt->steering[DSS].ranges = xelpg_dss_steering_table;
index 48fd698..d4310be 100644 (file)
@@ -55,6 +55,7 @@ enum xe_steering_type {
        LNCF,
        DSS,
        OADDRM,
+       SQIDI_PSMI,
 
        /*
         * On some platforms there are multiple types of MCR registers that