]> git.hungrycats.org Git - linux/commitdiff
drm/xe/rtp: Add FIELD_SET_FUNC RTP action
authorMatt Roper <matthew.d.roper@intel.com>
Wed, 17 Jun 2026 19:24:46 +0000 (12:24 -0700)
committerMatt Roper <matthew.d.roper@intel.com>
Wed, 17 Jun 2026 20:59:05 +0000 (13:59 -0700)
Most of our RTP programming involves programming constant values into
register fields.  However there are a few cases (e.g., RING_CMD_CCTL
programming) that rely on dynamic per-GT or per-engine checks to decide
what value will be programmed.  Add a FIELD_SET_FUNC RTP action which
will call the provided function pointer once at RTP processing time to
determine the appropriate value.

v2:
 - Tweak kerneldoc to avoid duplicating explanation from FIELD_SET.
   (Gustavo)

Reviewed-by: Gustavo Sousa <gustavo.sousa@intel.com>
Link: https://patch.msgid.link/20260617-rtp_with_dynamic_vals-v2-2-3f4cb34c2ea1@intel.com
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
drivers/gpu/drm/xe/xe_rtp.c
drivers/gpu/drm/xe/xe_rtp.h
drivers/gpu/drm/xe/xe_rtp_types.h

index 83a40e1f9528ce1db741b82e668cc98b970b905c..6a8d6ea68f25d2ee7f5dc03b3b274c3f3bba444c 100644 (file)
@@ -227,17 +227,23 @@ static bool rule_matches(const struct xe_device *xe,
 
 static void rtp_add_sr_entry(const struct xe_rtp_action *action,
                             struct xe_gt *gt,
+                            struct xe_hw_engine *hwe,
                             u32 mmio_base,
                             struct xe_reg_sr *sr)
 {
        struct xe_reg_sr_entry sr_entry = {
                .reg = action->reg,
                .clr_bits = action->clr_bits,
-               .set_bits = action->set_bits,
                .read_mask = action->read_mask,
        };
 
+       if (action->use_func)
+               sr_entry.set_bits = action->set_func(gt, hwe);
+       else
+               sr_entry.set_bits = action->set_bits;
+
        sr_entry.reg.addr += mmio_base;
+
        xe_reg_sr_add(sr, &sr_entry, gt);
 }
 
@@ -259,7 +265,7 @@ static bool rtp_process_one_sr(const struct xe_rtp_entry_sr *entry,
                else
                        mmio_base = 0;
 
-               rtp_add_sr_entry(action, gt, mmio_base, sr);
+               rtp_add_sr_entry(action, gt, hwe, mmio_base, sr);
        }
 
        return true;
index 2cc65053cd07f77315fff35c91b5eec62ee6a923..0032f68ea18737437eab7cbf06a9f43f0e69cf19 100644 (file)
@@ -322,6 +322,25 @@ struct xe_reg_sr;
          .clr_bits = (mask_bits_), .set_bits = (val_),                         \
          .read_mask = 0, ##__VA_ARGS__ }
 
+/**
+ * XE_RTP_ACTION_FIELD_SET_FUNC: Set a bit range to the value returned by a function
+ * @reg_: Register
+ * @mask_bits_: Mask of bits to be changed in the register, forming a field
+ * @func_: Function that returns value to set in the field denoted by @mask_bits_
+ * @...: Additional fields to override in the struct xe_rtp_action entry
+ *
+ * This macro works like XE_RTP_ACTION_FIELD_SET(), except that the
+ * field value is evaluated at the time the RTP table is processed.
+ *
+ * @func_ will only be called a single time, when the RTP table is being
+ * processed.  After processing, the value in the reg_sr entry is fixed and
+ * will not be re-evaluated.
+ */
+#define XE_RTP_ACTION_FIELD_SET_FUNC(reg_, mask_bits_, func_, ...)             \
+       { .reg = XE_RTP_DROP_CAST(reg_),                                        \
+         .clr_bits = mask_bits_, .set_func = func_, .use_func = 1,             \
+         .read_mask = mask_bits_, ##__VA_ARGS__ }
+
 /**
  * XE_RTP_ACTION_WHITELIST - Add register to userspace whitelist
  * @reg_: Register
index 1d7c63d0ae94c80254d5a5164c6f21b5ab246edd..b78092fa06e058d5eb71741373dd9e2f542e13c1 100644 (file)
@@ -30,8 +30,14 @@ struct xe_rtp_action {
         */
        u32 clr_bits;
 
-       /** @set_bits: bits to set when updating register */
-       u32 set_bits;
+       union {
+               /** @set_bits: bits to set when updating register */
+               u32 set_bits;
+
+               /** @set_func: function to provide bits to set when updating register */
+               u32 (*set_func)(struct xe_gt *gt,
+                               struct xe_hw_engine *hwe);
+       };
 
 #define XE_RTP_NOCHECK         .read_mask = 0
        /** @read_mask: mask for bits to consider when reading value back */
@@ -40,6 +46,13 @@ struct xe_rtp_action {
 #define XE_RTP_ACTION_FLAG_ENGINE_BASE         BIT(0)
        /** @flags: flags to apply on rule evaluation or action */
        u8 flags;
+
+       /**
+        * @use_func:
+        *   Internal flag indicating @set_func should be called instead of
+        *   using @set_bits.
+        */
+       u8 use_func:1;
 };
 
 enum {