drm/xe/wa: Track gt/engine/lrc active workarounds
authorLucas De Marchi <lucas.demarchi@intel.com>
Fri, 26 May 2023 16:43:43 +0000 (09:43 -0700)
committerRodrigo Vivi <rodrigo.vivi@intel.com>
Tue, 19 Dec 2023 23:34:02 +0000 (18:34 -0500)
Allocate the data to track workarounds on each gt of the device,
and pass that to RTP so the active workarounds are tracked.

Even if the workarounds available until now are mostly device
or platform centric, with the different IP versions for media and
graphics starting with MTL, it's possible that some workarounds
need to be applied only on select GTs. Also, given the workaround
database is per IP block, for tracking purposes there is no need to
differentiate the workarounds per engine class. Hence the bitmask
to track active workarounds can be tracked per GT.

v2: Move the tracking from per-device to per-GT basis (Matt Roper)

Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Link: https://lore.kernel.org/r/20230526164358.86393-7-lucas.demarchi@intel.com
Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
drivers/gpu/drm/xe/xe_gt.c
drivers/gpu/drm/xe/xe_gt_types.h
drivers/gpu/drm/xe/xe_wa.c
drivers/gpu/drm/xe/xe_wa.h

index 80d42c7c7cfa9f2fdde98dc3889b733f4ae143e0..d139554316d4e08406afe72d598bc481ea3f9422 100644 (file)
@@ -315,6 +315,11 @@ int xe_gt_init_early(struct xe_gt *gt)
                return err;
 
        xe_reg_sr_init(&gt->reg_sr, "GT", gt_to_xe(gt));
+
+       err = xe_wa_init(gt);
+       if (err)
+               return err;
+
        xe_wa_process_gt(gt);
        xe_tuning_process_gt(gt);
 
index 7c47d67aa8be86e701e5ac1b65508a5dcea5780c..017ab60f2498e806748372297772493ab5681d06 100644 (file)
@@ -359,6 +359,16 @@ struct xe_gt {
         *    of a steered operation
         */
        spinlock_t mcr_lock;
+
+       /** @wa_active: keep track of active workarounds */
+       struct {
+               /** @gt: bitmap with active GT workarounds */
+               unsigned long *gt;
+               /** @engine: bitmap with active engine workarounds */
+               unsigned long *engine;
+               /** @lrc: bitmap with active LRC workarounds */
+               unsigned long *lrc;
+       } wa_active;
 };
 
 #endif
index 557e90d79f0bfbbc078413bfece20245c736b5bf..665714abc5f00a572a8cc4ef33b88b994086a96c 100644 (file)
@@ -5,6 +5,7 @@
 
 #include "xe_wa.h"
 
+#include <drm/drm_managed.h>
 #include <kunit/visibility.h>
 #include <linux/compiler_types.h>
 
@@ -581,6 +582,8 @@ void xe_wa_process_gt(struct xe_gt *gt)
 {
        struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(gt);
 
+       xe_rtp_process_ctx_enable_active_tracking(&ctx, gt->wa_active.gt,
+                                                 ARRAY_SIZE(gt_was));
        xe_rtp_process_to_sr(&ctx, gt_was, &gt->reg_sr);
 }
 EXPORT_SYMBOL_IF_KUNIT(xe_wa_process_gt);
@@ -597,6 +600,8 @@ void xe_wa_process_engine(struct xe_hw_engine *hwe)
 {
        struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
 
+       xe_rtp_process_ctx_enable_active_tracking(&ctx, hwe->gt->wa_active.engine,
+                                                 ARRAY_SIZE(engine_was));
        xe_rtp_process_to_sr(&ctx, engine_was, &hwe->reg_sr);
 }
 
@@ -612,5 +617,37 @@ void xe_wa_process_lrc(struct xe_hw_engine *hwe)
 {
        struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
 
+       xe_rtp_process_ctx_enable_active_tracking(&ctx, hwe->gt->wa_active.lrc,
+                                                 ARRAY_SIZE(lrc_was));
        xe_rtp_process_to_sr(&ctx, lrc_was, &hwe->reg_lrc);
 }
+
+/**
+ * xe_wa_init - initialize gt with workaround bookkeeping
+ * @gt: GT instance to initialize
+ *
+ * Returns 0 for success, negative error code otherwise.
+ */
+int xe_wa_init(struct xe_gt *gt)
+{
+       struct xe_device *xe = gt_to_xe(gt);
+       size_t n_lrc, n_engine, n_gt, total;
+       unsigned long *p;
+
+       n_gt = BITS_TO_LONGS(ARRAY_SIZE(gt_was));
+       n_engine = BITS_TO_LONGS(ARRAY_SIZE(engine_was));
+       n_lrc = BITS_TO_LONGS(ARRAY_SIZE(lrc_was));
+       total = n_gt + n_engine + n_lrc;
+
+       p = drmm_kzalloc(&xe->drm, sizeof(*p) * total, GFP_KERNEL);
+       if (!p)
+               return -ENOMEM;
+
+       gt->wa_active.gt = p;
+       p += n_gt;
+       gt->wa_active.engine = p;
+       p += n_engine;
+       gt->wa_active.lrc = p;
+
+       return 0;
+}
index cd2307d587950075ec51ce6499207c91fa78775c..eae05bcecc68e67b0875452e9f73c11c1bb4b4c1 100644 (file)
@@ -9,6 +9,7 @@
 struct xe_gt;
 struct xe_hw_engine;
 
+int xe_wa_init(struct xe_gt *gt);
 void xe_wa_process_gt(struct xe_gt *gt);
 void xe_wa_process_engine(struct xe_hw_engine *hwe);
 void xe_wa_process_lrc(struct xe_hw_engine *hwe);