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>
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);
}
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;
.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
*/
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 */
#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 {