Since CCS automatic load balancing is disabled, we will impose a
fixed balancing policy that involves setting all the CCS engines
to work together on the same load.

Simultaneously, the user will see only 1 CCS rather than the
actual number. As of now, this change affects only DG2.

Fixes: d2eae8e98d59 ("drm/i915/dg2: Drop force_probe requirement")
Signed-off-by: Andi Shyti <andi.sh...@linux.intel.com>
Cc: Chris Wilson <chris.p.wil...@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahti...@linux.intel.com>
Cc: Matt Roper <matthew.d.ro...@intel.com>
Cc: <sta...@vger.kernel.org> # v6.2+
---
 drivers/gpu/drm/i915/gt/intel_gt.c      | 11 +++++++++++
 drivers/gpu/drm/i915/gt/intel_gt_regs.h |  2 ++
 drivers/gpu/drm/i915/i915_drv.h         | 17 +++++++++++++++++
 drivers/gpu/drm/i915/i915_query.c       |  5 +++--
 4 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/gt/intel_gt.c 
b/drivers/gpu/drm/i915/gt/intel_gt.c
index a425db5ed3a2..e19df4ef47f6 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt.c
+++ b/drivers/gpu/drm/i915/gt/intel_gt.c
@@ -168,6 +168,14 @@ static void init_unused_rings(struct intel_gt *gt)
        }
 }
 
+static void intel_gt_apply_ccs_mode(struct intel_gt *gt)
+{
+       if (!IS_DG2(gt->i915))
+               return;
+
+       intel_uncore_write(gt->uncore, XEHP_CCS_MODE, 0);
+}
+
 int intel_gt_init_hw(struct intel_gt *gt)
 {
        struct drm_i915_private *i915 = gt->i915;
@@ -195,6 +203,9 @@ int intel_gt_init_hw(struct intel_gt *gt)
 
        intel_gt_init_swizzling(gt);
 
+       /* Configure CCS mode */
+       intel_gt_apply_ccs_mode(gt);
+
        /*
         * At least 830 can leave some of the unused rings
         * "active" (ie. head != tail) after resume which
diff --git a/drivers/gpu/drm/i915/gt/intel_gt_regs.h 
b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
index cf709f6c05ae..c148113770ea 100644
--- a/drivers/gpu/drm/i915/gt/intel_gt_regs.h
+++ b/drivers/gpu/drm/i915/gt/intel_gt_regs.h
@@ -1605,6 +1605,8 @@
 #define   GEN12_VOLTAGE_MASK                   REG_GENMASK(10, 0)
 #define   GEN12_CAGF_MASK                      REG_GENMASK(19, 11)
 
+#define XEHP_CCS_MODE                          _MMIO(0x14804)
+
 #define GEN11_GT_INTR_DW(x)                    _MMIO(0x190018 + ((x) * 4))
 #define   GEN11_CSME                           (31)
 #define   GEN12_HECI_2                         (30)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e81b3b2858ac..0853ffd3cb8d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -396,6 +396,23 @@ static inline struct intel_gt *to_gt(const struct 
drm_i915_private *i915)
             (engine__); \
             (engine__) = rb_to_uabi_engine(rb_next(&(engine__)->uabi_node)))
 
+/*
+ * Exclude unavailable engines.
+ *
+ * Only the first CCS engine is utilized due to the disabling of CCS auto load
+ * balancing. As a result, all CCS engines operate collectively, functioning
+ * essentially as a single CCS engine, hence the count of active CCS engines is
+ * considered '1'.
+ * Currently, this applies to platforms with more than one CCS engine,
+ * specifically DG2.
+ */
+#define for_each_available_uabi_engine(engine__, i915__) \
+       for_each_uabi_engine(engine__, i915__) \
+               if ((IS_DG2(i915__)) && \
+                   ((engine__)->uabi_class == I915_ENGINE_CLASS_COMPUTE) && \
+                   ((engine__)->uabi_instance)) { } \
+               else
+
 #define INTEL_INFO(i915)       ((i915)->__info)
 #define RUNTIME_INFO(i915)     (&(i915)->__runtime)
 #define DRIVER_CAPS(i915)      (&(i915)->caps)
diff --git a/drivers/gpu/drm/i915/i915_query.c 
b/drivers/gpu/drm/i915/i915_query.c
index fa3e937ed3f5..2d41bda626a6 100644
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -124,6 +124,7 @@ static int query_geometry_subslices(struct drm_i915_private 
*i915,
        return fill_topology_info(sseu, query_item, 
sseu->geometry_subslice_mask);
 }
 
+
 static int
 query_engine_info(struct drm_i915_private *i915,
                  struct drm_i915_query_item *query_item)
@@ -140,7 +141,7 @@ query_engine_info(struct drm_i915_private *i915,
        if (query_item->flags)
                return -EINVAL;
 
-       for_each_uabi_engine(engine, i915)
+       for_each_available_uabi_engine(engine, i915)
                num_uabi_engines++;
 
        len = struct_size(query_ptr, engines, num_uabi_engines);
@@ -155,7 +156,7 @@ query_engine_info(struct drm_i915_private *i915,
 
        info_ptr = &query_ptr->engines[0];
 
-       for_each_uabi_engine(engine, i915) {
+       for_each_available_uabi_engine(engine, i915) {
                info.engine.engine_class = engine->uabi_class;
                info.engine.engine_instance = engine->uabi_instance;
                info.flags = I915_ENGINE_INFO_HAS_LOGICAL_INSTANCE;
-- 
2.43.0

Reply via email to