Commit 72906d34 authored by Lucas De Marchi's avatar Lucas De Marchi Committed by Rodrigo Vivi

drm/xe/rtp: Split rtp process initialization

The selection between hwe and gt is exposed to the outside of rtp, by
the xe_rtp_process() function. However it doesn't make seense from the
caller point of view to pass a hwe and a gt as argument since the gt
should always be the one containing the hwe.

This clarifies the interface by separating the context creation into an
initializer. The initializer then passes the correct value and there
should never be a case with hwe and gt set: when hwe is passed, the gt
is the one containing it. Internally the functions continue receiving
the argument separately.

v2: Leave the device-only context to a separate patch if they are indeed
    needed later
Reviewed-by: default avatarMatt Roper <matthew.d.roper@intel.com>
Link: https://lore.kernel.org/r/20230526164358.86393-3-lucas.demarchi@intel.comSigned-off-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
parent a9bd807e
......@@ -238,10 +238,11 @@ static void xe_rtp_process_tests(struct kunit *test)
struct xe_device *xe = test->priv;
struct xe_reg_sr *reg_sr = &xe->gt[0].reg_sr;
const struct xe_reg_sr_entry *sre, *sr_entry = NULL;
struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(&xe->gt[0]);
unsigned long idx, count = 0;
xe_reg_sr_init(reg_sr, "xe_rtp_tests", xe);
xe_rtp_process(param->entries, reg_sr, &xe->gt[0], NULL);
xe_rtp_process(&ctx, param->entries, reg_sr);
xa_for_each(&reg_sr->xa, idx, sre) {
if (idx == param->expected_reg.addr)
......
......@@ -281,6 +281,7 @@ xe_hw_engine_setup_default_lrc_state(struct xe_hw_engine *hwe)
const u8 mocs_read_idx = gt->mocs.uc_index;
u32 blit_cctl_val = REG_FIELD_PREP(BLIT_CCTL_DST_MOCS_MASK, mocs_write_idx) |
REG_FIELD_PREP(BLIT_CCTL_SRC_MOCS_MASK, mocs_read_idx);
struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
const struct xe_rtp_entry lrc_was[] = {
/*
* Some blitter commands do not have a field for MOCS, those
......@@ -299,7 +300,7 @@ xe_hw_engine_setup_default_lrc_state(struct xe_hw_engine *hwe)
{}
};
xe_rtp_process(lrc_was, &hwe->reg_lrc, gt, hwe);
xe_rtp_process(&ctx, lrc_was, &hwe->reg_lrc);
}
static void
......@@ -311,7 +312,8 @@ hw_engine_setup_default_state(struct xe_hw_engine *hwe)
const u8 mocs_read_idx = gt->mocs.uc_index;
u32 ring_cmd_cctl_val = REG_FIELD_PREP(CMD_CCTL_WRITE_OVERRIDE_MASK, mocs_write_idx) |
REG_FIELD_PREP(CMD_CCTL_READ_OVERRIDE_MASK, mocs_read_idx);
const struct xe_rtp_entry engine_was[] = {
struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
const struct xe_rtp_entry engine_entries[] = {
/*
* RING_CMD_CCTL specifies the default MOCS entry that will be
* used by the command streamer when executing commands that
......@@ -332,7 +334,7 @@ hw_engine_setup_default_state(struct xe_hw_engine *hwe)
{}
};
xe_rtp_process(engine_was, &hwe->reg_sr, gt, hwe);
xe_rtp_process(&ctx, engine_entries, &hwe->reg_sr);
}
static void hw_engine_init_early(struct xe_gt *gt, struct xe_hw_engine *hwe,
......
......@@ -63,7 +63,9 @@ static const struct xe_rtp_entry register_whitelist[] = {
*/
void xe_reg_whitelist_process_engine(struct xe_hw_engine *hwe)
{
xe_rtp_process(register_whitelist, &hwe->reg_whitelist, hwe->gt, hwe);
struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
xe_rtp_process(&ctx, register_whitelist, &hwe->reg_whitelist);
}
/**
......
......@@ -23,11 +23,11 @@
* the values to the registers that have matching rules.
*/
static bool rule_matches(struct xe_gt *gt,
static bool rule_matches(const struct xe_device *xe,
struct xe_gt *gt,
struct xe_hw_engine *hwe,
const struct xe_rtp_entry *entry)
{
const struct xe_device *xe = gt_to_xe(gt);
const struct xe_rtp_rule *r;
unsigned int i;
bool match;
......@@ -62,22 +62,27 @@ static bool rule_matches(struct xe_gt *gt,
match = xe->info.step.graphics >= r->step_start &&
xe->info.step.graphics < r->step_end;
break;
case XE_RTP_MATCH_INTEGRATED:
match = !xe->info.is_dgfx;
break;
case XE_RTP_MATCH_DISCRETE:
match = xe->info.is_dgfx;
break;
case XE_RTP_MATCH_ENGINE_CLASS:
if (drm_WARN_ON(&xe->drm, !hwe))
return false;
match = hwe->class == r->engine_class;
break;
case XE_RTP_MATCH_NOT_ENGINE_CLASS:
if (drm_WARN_ON(&xe->drm, !hwe))
return false;
match = hwe->class != r->engine_class;
break;
case XE_RTP_MATCH_FUNC:
match = r->match_func(gt, hwe);
break;
case XE_RTP_MATCH_INTEGRATED:
match = !xe->info.is_dgfx;
break;
case XE_RTP_MATCH_DISCRETE:
match = xe->info.is_dgfx;
break;
default:
XE_WARN_ON(r->match_type);
}
......@@ -105,14 +110,15 @@ static void rtp_add_sr_entry(const struct xe_rtp_action *action,
xe_reg_sr_add(sr, &sr_entry);
}
static void rtp_process_one(const struct xe_rtp_entry *entry, struct xe_gt *gt,
static void rtp_process_one(const struct xe_rtp_entry *entry,
struct xe_device *xe, struct xe_gt *gt,
struct xe_hw_engine *hwe, struct xe_reg_sr *sr)
{
const struct xe_rtp_action *action;
u32 mmio_base;
unsigned int i;
if (!rule_matches(gt, hwe, entry))
if (!rule_matches(xe, gt, hwe, entry))
return;
for (action = &entry->actions[0]; i < entry->n_actions; action++, i++) {
......@@ -126,23 +132,46 @@ static void rtp_process_one(const struct xe_rtp_entry *entry, struct xe_gt *gt,
}
}
static void rtp_get_context(struct xe_rtp_process_ctx *ctx,
struct xe_hw_engine **hwe,
struct xe_gt **gt,
struct xe_device **xe)
{
switch (ctx->type) {
case XE_RTP_PROCESS_TYPE_GT:
*hwe = NULL;
*gt = ctx->gt;
*xe = gt_to_xe(*gt);
break;
case XE_RTP_PROCESS_TYPE_ENGINE:
*hwe = ctx->hwe;
*gt = (*hwe)->gt;
*xe = gt_to_xe(*gt);
break;
};
}
/**
* xe_rtp_process - Process all rtp @entries, adding the matching ones to @sr
* @ctx: The context for processing the table, with one of device, gt or hwe
* @entries: Table with RTP definitions
* @sr: Where to add an entry to with the values for matching. This can be
* viewed as the "coalesced view" of multiple the tables. The bits for each
* register set are expected not to collide with previously added entries
* @gt: The GT to be used for matching rules
* @hwe: Engine instance to use for matching rules and as mmio base
*
* Walk the table pointed by @entries (with an empty sentinel) and add all
* entries with matching rules to @sr. If @hwe is not NULL, its mmio_base is
* used to calculate the right register offset
*/
void xe_rtp_process(const struct xe_rtp_entry *entries, struct xe_reg_sr *sr,
struct xe_gt *gt, struct xe_hw_engine *hwe)
void xe_rtp_process(struct xe_rtp_process_ctx *ctx,
const struct xe_rtp_entry *entries, struct xe_reg_sr *sr)
{
const struct xe_rtp_entry *entry;
struct xe_hw_engine *hwe = NULL;
struct xe_gt *gt = NULL;
struct xe_device *xe = NULL;
rtp_get_context(ctx, &hwe, &gt, &xe);
for (entry = entries; entry && entry->name; entry++) {
if (entry->flags & XE_RTP_ENTRY_FLAG_FOREACH_ENGINE) {
......@@ -150,9 +179,9 @@ void xe_rtp_process(const struct xe_rtp_entry *entries, struct xe_reg_sr *sr,
enum xe_hw_engine_id id;
for_each_hw_engine(each_hwe, gt, id)
rtp_process_one(entry, gt, each_hwe, sr);
rtp_process_one(entry, xe, gt, each_hwe, sr);
} else {
rtp_process_one(entry, gt, hwe, sr);
rtp_process_one(entry, xe, gt, hwe, sr);
}
}
}
......
......@@ -355,8 +355,13 @@ struct xe_reg_sr;
XE_RTP_PASTE_FOREACH(ACTION_, COMMA, (__VA_ARGS__)) \
}
void xe_rtp_process(const struct xe_rtp_entry *entries, struct xe_reg_sr *sr,
struct xe_gt *gt, struct xe_hw_engine *hwe);
#define XE_RTP_PROCESS_CTX_INITIALIZER(arg__) _Generic((arg__), \
struct xe_hw_engine *: (struct xe_rtp_process_ctx){ { (void *)(arg__) }, XE_RTP_PROCESS_TYPE_ENGINE }, \
struct xe_gt *: (struct xe_rtp_process_ctx){ { (void *)(arg__) }, XE_RTP_PROCESS_TYPE_GT })
void xe_rtp_process(struct xe_rtp_process_ctx *ctx,
const struct xe_rtp_entry *entries,
struct xe_reg_sr *sr);
/* Match functions to be used with XE_RTP_MATCH_FUNC */
......
......@@ -95,4 +95,17 @@ struct xe_rtp_entry {
u8 flags;
};
enum xe_rtp_process_type {
XE_RTP_PROCESS_TYPE_GT,
XE_RTP_PROCESS_TYPE_ENGINE,
};
struct xe_rtp_process_ctx {
union {
struct xe_gt *gt;
struct xe_hw_engine *hwe;
};
enum xe_rtp_process_type type;
};
#endif
......@@ -59,7 +59,9 @@ static const struct xe_rtp_entry lrc_tunings[] = {
void xe_tuning_process_gt(struct xe_gt *gt)
{
xe_rtp_process(gt_tunings, &gt->reg_sr, gt, NULL);
struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(gt);
xe_rtp_process(&ctx, gt_tunings, &gt->reg_sr);
}
EXPORT_SYMBOL_IF_KUNIT(xe_tuning_process_gt);
......@@ -73,5 +75,7 @@ EXPORT_SYMBOL_IF_KUNIT(xe_tuning_process_gt);
*/
void xe_tuning_process_lrc(struct xe_hw_engine *hwe)
{
xe_rtp_process(lrc_tunings, &hwe->reg_lrc, hwe->gt, hwe);
struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
xe_rtp_process(&ctx, lrc_tunings, &hwe->reg_lrc);
}
......@@ -579,7 +579,9 @@ __diag_pop();
*/
void xe_wa_process_gt(struct xe_gt *gt)
{
xe_rtp_process(gt_was, &gt->reg_sr, gt, NULL);
struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(gt);
xe_rtp_process(&ctx, gt_was, &gt->reg_sr);
}
EXPORT_SYMBOL_IF_KUNIT(xe_wa_process_gt);
......@@ -593,7 +595,9 @@ EXPORT_SYMBOL_IF_KUNIT(xe_wa_process_gt);
*/
void xe_wa_process_engine(struct xe_hw_engine *hwe)
{
xe_rtp_process(engine_was, &hwe->reg_sr, hwe->gt, hwe);
struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
xe_rtp_process(&ctx, engine_was, &hwe->reg_sr);
}
/**
......@@ -606,5 +610,7 @@ void xe_wa_process_engine(struct xe_hw_engine *hwe)
*/
void xe_wa_process_lrc(struct xe_hw_engine *hwe)
{
xe_rtp_process(lrc_was, &hwe->reg_lrc, hwe->gt, hwe);
struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
xe_rtp_process(&ctx, lrc_was, &hwe->reg_lrc);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment