[PATCH 2/5] drm/xe/rtp: Allow to OR rules
Lucas De Marchi
lucas.demarchi at intel.com
Mon Jun 17 18:25:15 UTC 2024
Some workarounds started to depend in different set of conditions where
the action should be applied if any of them match. See e.g.
commit 24d0d98af1c3 ("drm/xe/xe2lpm: Fixup Wa_14020756599"). Add
XE_RTP_MATCH_OR that allows to implement a logical OR for the rules.
Normal precedence applies:
r1, r2, OR, r3
means
(r1 AND r2) OR r3
The check is shortcut as soon as a set of conditions match.
Signed-off-by: Lucas De Marchi <lucas.demarchi at intel.com>
---
drivers/gpu/drm/xe/tests/xe_rtp_test.c | 54 ++++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_rtp.c | 20 +++++++++-
drivers/gpu/drm/xe/xe_rtp.h | 21 ++++++++++
drivers/gpu/drm/xe/xe_rtp_types.h | 1 +
4 files changed, 94 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/xe/tests/xe_rtp_test.c b/drivers/gpu/drm/xe/tests/xe_rtp_test.c
index 474a0b222ce1..bf7fee9b20cc 100644
--- a/drivers/gpu/drm/xe/tests/xe_rtp_test.c
+++ b/drivers/gpu/drm/xe/tests/xe_rtp_test.c
@@ -90,6 +90,60 @@ static const struct rtp_test_case cases[] = {
{}
},
},
+ {
+ .name = "match-or-first",
+ .expected_reg = REGULAR_REG1,
+ .expected_set_bits = REG_BIT(0),
+ .expected_clr_bits = REG_BIT(0),
+ .expected_count = 1,
+ .entries = (const struct xe_rtp_entry_sr[]) {
+ { XE_RTP_NAME("first"),
+ XE_RTP_RULES(FUNC(match_yes), OR, FUNC(match_no)),
+ XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(0)))
+ },
+ {}
+ },
+ },
+ {
+ .name = "match-or-last",
+ .expected_reg = REGULAR_REG1,
+ .expected_set_bits = REG_BIT(0),
+ .expected_clr_bits = REG_BIT(0),
+ .expected_count = 1,
+ .entries = (const struct xe_rtp_entry_sr[]) {
+ { XE_RTP_NAME("last"),
+ XE_RTP_RULES(FUNC(match_no), OR, FUNC(match_yes)),
+ XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(0)))
+ },
+ {}
+ },
+ },
+ {
+ .name = "match-or-empty",
+ .expected_reg = REGULAR_REG1,
+ .expected_set_bits = REG_BIT(0),
+ .expected_clr_bits = REG_BIT(0),
+ .expected_count = 1,
+ .entries = (const struct xe_rtp_entry_sr[]) {
+ { XE_RTP_NAME("empty-matches-ok"),
+ XE_RTP_RULES(OR, FUNC(match_no)),
+ XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(0)))
+ },
+ {}
+ },
+ },
+ {
+ .name = "match-or-none",
+ .expected_reg = REGULAR_REG1,
+ .expected_count = 0,
+ .entries = (const struct xe_rtp_entry_sr[]) {
+ { XE_RTP_NAME("none"),
+ XE_RTP_RULES(FUNC(match_no), OR, FUNC(match_no)),
+ XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(0)))
+ },
+ {}
+ },
+ },
{
.name = "no-match-no-add-multiple-rules",
.expected_reg = REGULAR_REG1,
diff --git a/drivers/gpu/drm/xe/xe_rtp.c b/drivers/gpu/drm/xe/xe_rtp.c
index eff1c9c2f5cc..66ca58fa5739 100644
--- a/drivers/gpu/drm/xe/xe_rtp.c
+++ b/drivers/gpu/drm/xe/xe_rtp.c
@@ -40,6 +40,13 @@ static bool rule_matches(const struct xe_device *xe,
for (r = rules, i = 0; i < n_rules; r = &rules[++i]) {
switch (r->match_type) {
+ case XE_RTP_MATCH_OR:
+ /*
+ * This is only reached if a complete set of required
+ * rules passed, so return success: the remaining rules
+ * do not matter
+ */
+ return true;
case XE_RTP_MATCH_PLATFORM:
match = xe->info.platform == r->platform;
break;
@@ -102,8 +109,17 @@ static bool rule_matches(const struct xe_device *xe,
match = false;
}
- if (!match)
- return false;
+ if (!match) {
+ /*
+ * Advance rules until we find XE_RTP_MATCH_OR to check
+ * if there's another set of conditions to check
+ */
+ while (i < n_rules && rules[++i].match_type != XE_RTP_MATCH_OR)
+ ;
+
+ if (i >= n_rules)
+ return false;
+ }
}
return true;
diff --git a/drivers/gpu/drm/xe/xe_rtp.h b/drivers/gpu/drm/xe/xe_rtp.h
index 337b1ef1959c..5a6b112a8be6 100644
--- a/drivers/gpu/drm/xe/xe_rtp.h
+++ b/drivers/gpu/drm/xe/xe_rtp.h
@@ -179,6 +179,27 @@ struct xe_reg_sr;
#define XE_RTP_RULE_IS_DISCRETE \
{ .match_type = XE_RTP_MATCH_DISCRETE }
+/**
+ * XE_RTP_RULE_OR - Create an OR condition for rtp rules
+ *
+ * RTP rules are AND'ed when evaluated and all of them need to match.
+ * XE_RTP_RULE_OR allows to create set of rules where any of them matching is
+ * sufficient for the action to trigger. Example:
+ *
+ * .. code-block:: c
+ *
+ * const struct xe_rtp_entry_sr entries[] = {
+ * ...
+ * { XE_RTP_NAME("test-entry"),
+ * XE_RTP_RULES(PLATFORM(DG2), OR, PLATFORM(TIGERLAKE)),
+ * ...
+ * },
+ * ...
+ * };
+ */
+#define XE_RTP_RULE_OR \
+ { .match_type = XE_RTP_MATCH_OR }
+
/**
* XE_RTP_ACTION_WR - Helper to write a value to the register, overriding all
* the bits
diff --git a/drivers/gpu/drm/xe/xe_rtp_types.h b/drivers/gpu/drm/xe/xe_rtp_types.h
index 637acc7626a4..10150bc22ccd 100644
--- a/drivers/gpu/drm/xe/xe_rtp_types.h
+++ b/drivers/gpu/drm/xe/xe_rtp_types.h
@@ -51,6 +51,7 @@ enum {
XE_RTP_MATCH_ENGINE_CLASS,
XE_RTP_MATCH_NOT_ENGINE_CLASS,
XE_RTP_MATCH_FUNC,
+ XE_RTP_MATCH_OR,
};
/** struct xe_rtp_rule - match rule for processing entry */
--
2.43.0
More information about the Intel-xe
mailing list