]> git.dujemihanovic.xyz Git - linux.git/commitdiff
drm/i915/pvc: Add register steering
authorMatt Roper <matthew.d.roper@intel.com>
Wed, 8 Jun 2022 17:07:00 +0000 (10:07 -0700)
committerMatt Roper <matthew.d.roper@intel.com>
Thu, 9 Jun 2022 14:49:30 +0000 (07:49 -0700)
Ponte Vecchio no longer has MSLICE or LNCF steering, but the bspec does
document several new types of multicast register ranges.  Fortunately,
most of the different MCR types all provide valid values at instance
(0,0) so there's no need to read fuse registers and calculate a
non-terminated instance.  We'll lump all of those range types (BSLICE,
HALFBSLICE, TILEPSMI, CC, and L3BANK) into a single category called
"INSTANCE0" to keep things simple.  We'll also perform explicit steering
for each of these multicast register types, even if the implicit
steering setup for COMPUTE/DSS ranges would have worked too; this is
based on guidance from our hardware architects who suggested that we
move away from implicit steering and start explicitly steer all MCR
register accesses on modern platforms (we'll work on transitioning
COMPUTE/DSS to explicit steering in the future).

Note that there's one additional MCR range type defined in the bspec
(SQIDI) that we don't handle here.  Those ranges use a different
steering control register that we never touch; since instance 0 is also
always a valid setting there, we can just ignore those ranges.

Finally, we'll rename the HAS_MSLICES() macro to HAS_MSLICE_STEERING().
PVC hardware still has units referred to as mslices, but there's no
register steering based on mslice for this platform.

v2:
 - Rebase on other recent changes
 - Swap two table rows to keep table sorted & easy to read.  (Harish)

Bspec: 67609
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Harish Chegondi <harish.chegondi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220608170700.4026648-1-matthew.d.roper@intel.com
drivers/gpu/drm/i915/gt/intel_gt.c
drivers/gpu/drm/i915/gt/intel_gt_types.h
drivers/gpu/drm/i915/gt/intel_workarounds.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_pci.c
drivers/gpu/drm/i915/intel_device_info.h

index ddfb98f704898d30c8756e57035bb94fe6963fbb..f33290358c518fd28e3540db07f6db2b70fe0923 100644 (file)
@@ -106,6 +106,7 @@ static const char * const intel_steering_types[] = {
        "L3BANK",
        "MSLICE",
        "LNCF",
+       "INSTANCE 0",
 };
 
 static const struct intel_mmio_range icl_l3bank_steering_table[] = {
@@ -133,6 +134,27 @@ static const struct intel_mmio_range dg2_lncf_steering_table[] = {
        {},
 };
 
+/*
+ * We have several types of MCR registers on PVC where steering to (0,0)
+ * will always provide us with a non-terminated value.  We'll stick them
+ * all in the same table for simplicity.
+ */
+static const struct intel_mmio_range pvc_instance0_steering_table[] = {
+       { 0x004000, 0x004AFF },         /* HALF-BSLICE */
+       { 0x008800, 0x00887F },         /* CC */
+       { 0x008A80, 0x008AFF },         /* TILEPSMI */
+       { 0x00B000, 0x00B0FF },         /* HALF-BSLICE */
+       { 0x00B100, 0x00B3FF },         /* L3BANK */
+       { 0x00C800, 0x00CFFF },         /* HALF-BSLICE */
+       { 0x00D800, 0x00D8FF },         /* HALF-BSLICE */
+       { 0x00DD00, 0x00DDFF },         /* BSLICE */
+       { 0x00E900, 0x00E9FF },         /* HALF-BSLICE */
+       { 0x00EC00, 0x00EEFF },         /* HALF-BSLICE */
+       { 0x00F000, 0x00FFFF },         /* HALF-BSLICE */
+       { 0x024180, 0x0241FF },         /* HALF-BSLICE */
+       {},
+};
+
 int intel_gt_init_mmio(struct intel_gt *gt)
 {
        struct drm_i915_private *i915 = gt->i915;
@@ -146,7 +168,7 @@ int intel_gt_init_mmio(struct intel_gt *gt)
         * An mslice is unavailable only if both the meml3 for the slice is
         * disabled *and* all of the DSS in the slice (quadrant) are disabled.
         */
-       if (HAS_MSLICES(i915)) {
+       if (HAS_MSLICE_STEERING(i915)) {
                gt->info.mslice_mask =
                        intel_slicemask_from_xehp_dssmask(gt->info.sseu.subslice_mask,
                                                          GEN_DSS_PER_MSLICE);
@@ -158,7 +180,9 @@ int intel_gt_init_mmio(struct intel_gt *gt)
                        drm_warn(&i915->drm, "mslice mask all zero!\n");
        }
 
-       if (IS_DG2(i915)) {
+       if (IS_PONTEVECCHIO(i915)) {
+               gt->steering_table[INSTANCE0] = pvc_instance0_steering_table;
+       } else if (IS_DG2(i915)) {
                gt->steering_table[MSLICE] = xehpsdv_mslice_steering_table;
                gt->steering_table[LNCF] = dg2_lncf_steering_table;
        } else if (IS_XEHPSDV(i915)) {
@@ -172,7 +196,11 @@ int intel_gt_init_mmio(struct intel_gt *gt)
                        GEN10_L3BANK_MASK;
                if (!gt->info.l3bank_mask) /* should be impossible! */
                        drm_warn(&i915->drm, "L3 bank mask is all zero!\n");
-       } else if (HAS_MSLICES(i915)) {
+       } else if (GRAPHICS_VER(i915) >= 11) {
+               /*
+                * We expect all modern platforms to have at least some
+                * type of steering that needs to be initialized.
+                */
                MISSING_CASE(INTEL_INFO(i915)->platform);
        }
 
@@ -888,7 +916,7 @@ static void intel_gt_get_valid_steering(struct intel_gt *gt,
                *subsliceid = __ffs(gt->info.l3bank_mask);
                break;
        case MSLICE:
-               GEM_WARN_ON(!HAS_MSLICES(gt->i915));
+               GEM_WARN_ON(!HAS_MSLICE_STEERING(gt->i915));
                *sliceid = __ffs(gt->info.mslice_mask);
                *subsliceid = 0;        /* unused */
                break;
@@ -897,10 +925,18 @@ static void intel_gt_get_valid_steering(struct intel_gt *gt,
                 * An LNCF is always present if its mslice is present, so we
                 * can safely just steer to LNCF 0 in all cases.
                 */
-               GEM_WARN_ON(!HAS_MSLICES(gt->i915));
+               GEM_WARN_ON(!HAS_MSLICE_STEERING(gt->i915));
                *sliceid = __ffs(gt->info.mslice_mask) << 1;
                *subsliceid = 0;        /* unused */
                break;
+       case INSTANCE0:
+               /*
+                * There are a lot of MCR types for which instance (0, 0)
+                * will always provide a non-terminated value.
+                */
+               *sliceid = 0;
+               *subsliceid = 0;
+               break;
        default:
                MISSING_CASE(type);
                *sliceid = 0;
@@ -1020,7 +1056,9 @@ void intel_gt_report_steering(struct drm_printer *p, struct intel_gt *gt,
                   gt->default_steering.groupid,
                   gt->default_steering.instanceid);
 
-       if (HAS_MSLICES(gt->i915)) {
+       if (IS_PONTEVECCHIO(gt->i915)) {
+               report_steering_type(p, gt, INSTANCE0, dump_table);
+       } else if (HAS_MSLICE_STEERING(gt->i915)) {
                report_steering_type(p, gt, MSLICE, dump_table);
                report_steering_type(p, gt, LNCF, dump_table);
        }
index 993f003dad1dc5a0d1b6b423444b5e468233fed0..df708802889dfc00e17863295b11bba5bf7d2e90 100644 (file)
@@ -59,6 +59,13 @@ enum intel_steering_type {
        MSLICE,
        LNCF,
 
+       /*
+        * On some platforms there are multiple types of MCR registers that
+        * will always return a non-terminated value at instance (0, 0).  We'll
+        * lump those all into a single category to keep things simple.
+        */
+       INSTANCE0,
+
        NUM_STEERING_TYPES
 };
 
index 1ee54a83e459b50427f8d3b1b1f3373caee79d27..1e982ac931dc9d59e6a7c99d0d1d5c4edb51a498 100644 (file)
@@ -1195,6 +1195,20 @@ xehp_init_mcr(struct intel_gt *gt, struct i915_wa_list *wal)
        __set_mcr_steering(wal, SF_MCR_SELECTOR, 0, 2);
 }
 
+static void
+pvc_init_mcr(struct intel_gt *gt, struct i915_wa_list *wal)
+{
+       unsigned int dss;
+
+       /*
+        * Setup implicit steering for COMPUTE and DSS ranges to the first
+        * non-fused-off DSS.  All other types of MCR registers will be
+        * explicitly steered.
+        */
+       dss = intel_sseu_find_first_xehp_dss(&gt->info.sseu, 0, 0);
+       __add_mcr_wa(gt, wal, dss / GEN_DSS_PER_CSLICE, dss % GEN_DSS_PER_CSLICE);
+}
+
 static void
 icl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
@@ -1494,6 +1508,8 @@ dg2_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 static void
 pvc_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
 {
+       pvc_init_mcr(gt, wal);
+
        /* Wa_14015795083 */
        wa_write_clr(wal, GEN7_MISCCPCTL, GEN12_DOP_CLOCK_GATE_RENDER_ENABLE);
 }
index fbea4d1ede7c85f28e431035dac134c10643c635..59cd888209fe10bc46f7b8039c4d0c6116e9f679 100644 (file)
@@ -1346,8 +1346,7 @@ IS_SUBPLATFORM(const struct drm_i915_private *i915,
 #define HAS_RUNTIME_PM(dev_priv) (INTEL_INFO(dev_priv)->has_runtime_pm)
 #define HAS_64BIT_RELOC(dev_priv) (INTEL_INFO(dev_priv)->has_64bit_reloc)
 
-#define HAS_MSLICES(dev_priv) \
-       (INTEL_INFO(dev_priv)->has_mslices)
+#define HAS_MSLICE_STEERING(dev_priv)  (INTEL_INFO(dev_priv)->has_mslice_steering)
 
 /*
  * Set this flag, when platform requires 64K GTT page sizes or larger for
index b8244f72e4329db3afa92cee70f130dd8ccf0df0..d6d875b2d3799dec9183e35a8759496cb02a9b94 100644 (file)
@@ -1021,7 +1021,7 @@ static const struct intel_device_info adl_p_info = {
        .has_llc = 1, \
        .has_logical_ring_contexts = 1, \
        .has_logical_ring_elsq = 1, \
-       .has_mslices = 1, \
+       .has_mslice_steering = 1, \
        .has_rc6 = 1, \
        .has_reset_engine = 1, \
        .has_rps = 1, \
@@ -1092,6 +1092,7 @@ static const struct intel_device_info ats_m_info = {
        .has_3d_pipeline = 0, \
        .has_guc_deprivilege = 1, \
        .has_l3_ccs_read = 1, \
+       .has_mslice_steering = 0, \
        .has_one_eu_per_fuse_bit = 1
 
 __maybe_unused
index 346f17f2dce8c1a114152a08f11fce17720cef18..08341174ee0a544e2f87affcbd4c59905c8afaf2 100644 (file)
@@ -157,7 +157,7 @@ enum intel_ppgtt_type {
        func(has_logical_ring_contexts); \
        func(has_logical_ring_elsq); \
        func(has_media_ratio_mode); \
-       func(has_mslices); \
+       func(has_mslice_steering); \
        func(has_one_eu_per_fuse_bit); \
        func(has_pooled_eu); \
        func(has_pxp); \