1 /* SPDX-License-Identifier: MIT */
3 * Copyright © 2022 Intel Corporation
9 #include <linux/types.h>
10 #include <linux/xarray.h>
12 #define _XE_RTP_INCLUDE_PRIVATE_HELPERS
14 #include "xe_rtp_helpers.h"
15 #include "xe_rtp_types.h"
17 #undef _XE_RTP_INCLUDE_PRIVATE_HELPERS
20 * Register table poke infrastructure
28 * Macros to encode rules to match against platform, IP version, stepping, etc.
29 * Shouldn't be used directly - see XE_RTP_RULES()
31 #define _XE_RTP_RULE_PLATFORM(plat__) \
32 { .match_type = XE_RTP_MATCH_PLATFORM, .platform = plat__ }
34 #define _XE_RTP_RULE_SUBPLATFORM(plat__, sub__) \
35 { .match_type = XE_RTP_MATCH_SUBPLATFORM, \
36 .platform = plat__, .subplatform = sub__ }
38 #define _XE_RTP_RULE_GRAPHICS_STEP(start__, end__) \
39 { .match_type = XE_RTP_MATCH_GRAPHICS_STEP, \
40 .step_start = start__, .step_end = end__ }
42 #define _XE_RTP_RULE_MEDIA_STEP(start__, end__) \
43 { .match_type = XE_RTP_MATCH_MEDIA_STEP, \
44 .step_start = start__, .step_end = end__ }
46 #define _XE_RTP_RULE_ENGINE_CLASS(cls__) \
47 { .match_type = XE_RTP_MATCH_ENGINE_CLASS, \
48 .engine_class = (cls__) }
51 * XE_RTP_RULE_PLATFORM - Create rule matching platform
52 * @plat_: platform to match
54 * Refer to XE_RTP_RULES() for expected usage.
56 #define XE_RTP_RULE_PLATFORM(plat_) \
57 _XE_RTP_RULE_PLATFORM(XE_##plat_)
60 * XE_RTP_RULE_SUBPLATFORM - Create rule matching platform and sub-platform
61 * @plat_: platform to match
62 * @sub_: sub-platform to match
64 * Refer to XE_RTP_RULES() for expected usage.
66 #define XE_RTP_RULE_SUBPLATFORM(plat_, sub_) \
67 _XE_RTP_RULE_SUBPLATFORM(XE_##plat_, XE_SUBPLATFORM_##plat_##_##sub_)
70 * XE_RTP_RULE_GRAPHICS_STEP - Create rule matching graphics stepping
71 * @start_: First stepping matching the rule
72 * @end_: First stepping that does not match the rule
74 * Note that the range matching this rule is [ @start_, @end_ ), i.e. inclusive
75 * on the left, exclusive on the right.
77 * Refer to XE_RTP_RULES() for expected usage.
79 #define XE_RTP_RULE_GRAPHICS_STEP(start_, end_) \
80 _XE_RTP_RULE_GRAPHICS_STEP(STEP_##start_, STEP_##end_)
83 * XE_RTP_RULE_MEDIA_STEP - Create rule matching media stepping
84 * @start_: First stepping matching the rule
85 * @end_: First stepping that does not match the rule
87 * Note that the range matching this rule is [ @start_, @end_ ), i.e. inclusive
88 * on the left, exclusive on the right.
90 * Refer to XE_RTP_RULES() for expected usage.
92 #define XE_RTP_RULE_MEDIA_STEP(start_, end_) \
93 _XE_RTP_RULE_MEDIA_STEP(STEP_##start_, STEP_##end_)
96 * XE_RTP_RULE_ENGINE_CLASS - Create rule matching an engine class
97 * @cls_: Engine class to match
99 * Refer to XE_RTP_RULES() for expected usage.
101 #define XE_RTP_RULE_ENGINE_CLASS(cls_) \
102 _XE_RTP_RULE_ENGINE_CLASS(XE_ENGINE_CLASS_##cls_)
105 * XE_RTP_RULE_FUNC - Create rule using callback function for match
106 * @func__: Function to call to decide if rule matches
108 * This allows more complex checks to be performed. The ``XE_RTP``
109 * infrastructure will simply call the function @func_ passed to decide if this
110 * rule matches the device.
112 * Refer to XE_RTP_RULES() for expected usage.
114 #define XE_RTP_RULE_FUNC(func__) \
115 { .match_type = XE_RTP_MATCH_FUNC, \
116 .match_func = (func__) }
119 * XE_RTP_RULE_GRAPHICS_VERSION - Create rule matching graphics version
120 * @ver__: Graphics IP version to match
122 * Refer to XE_RTP_RULES() for expected usage.
124 #define XE_RTP_RULE_GRAPHICS_VERSION(ver__) \
125 { .match_type = XE_RTP_MATCH_GRAPHICS_VERSION, \
126 .ver_start = ver__, }
129 * XE_RTP_RULE_GRAPHICS_VERSION_RANGE - Create rule matching a range of graphics version
130 * @ver_start__: First graphics IP version to match
131 * @ver_end__: Last graphics IP version to match
133 * Note that the range matching this rule is [ @ver_start__, @ver_end__ ], i.e.
134 * inclusive on boths sides
136 * Refer to XE_RTP_RULES() for expected usage.
138 #define XE_RTP_RULE_GRAPHICS_VERSION_RANGE(ver_start__, ver_end__) \
139 { .match_type = XE_RTP_MATCH_GRAPHICS_VERSION_RANGE, \
140 .ver_start = ver_start__, .ver_end = ver_end__, }
143 * XE_RTP_RULE_MEDIA_VERSION - Create rule matching media version
144 * @ver__: Graphics IP version to match
146 * Refer to XE_RTP_RULES() for expected usage.
148 #define XE_RTP_RULE_MEDIA_VERSION(ver__) \
149 { .match_type = XE_RTP_MATCH_MEDIA_VERSION, \
150 .ver_start = ver__, }
153 * XE_RTP_RULE_MEDIA_VERSION_RANGE - Create rule matching a range of media version
154 * @ver_start__: First media IP version to match
155 * @ver_end__: Last media IP version to match
157 * Note that the range matching this rule is [ @ver_start__, @ver_end__ ], i.e.
158 * inclusive on boths sides
160 * Refer to XE_RTP_RULES() for expected usage.
162 #define XE_RTP_RULE_MEDIA_VERSION_RANGE(ver_start__, ver_end__) \
163 { .match_type = XE_RTP_MATCH_MEDIA_VERSION_RANGE, \
164 .ver_start = ver_start__, .ver_end = ver_end__, }
167 * XE_RTP_RULE_IS_INTEGRATED - Create a rule matching integrated graphics devices
169 * Refer to XE_RTP_RULES() for expected usage.
171 #define XE_RTP_RULE_IS_INTEGRATED \
172 { .match_type = XE_RTP_MATCH_INTEGRATED }
175 * XE_RTP_RULE_IS_DISCRETE - Create a rule matching discrete graphics devices
177 * Refer to XE_RTP_RULES() for expected usage.
179 #define XE_RTP_RULE_IS_DISCRETE \
180 { .match_type = XE_RTP_MATCH_DISCRETE }
183 * XE_RTP_ACTION_WR - Helper to write a value to the register, overriding all
186 * @val_: Value to set
187 * @...: Additional fields to override in the struct xe_rtp_action entry
189 * The correspondent notation in bspec is:
193 #define XE_RTP_ACTION_WR(reg_, val_, ...) \
194 { .reg = XE_RTP_DROP_CAST(reg_), \
195 .clr_bits = ~0u, .set_bits = (val_), \
196 .read_mask = (~0u), ##__VA_ARGS__ }
199 * XE_RTP_ACTION_SET - Set bits from @val_ in the register.
201 * @val_: Bits to set in the register
202 * @...: Additional fields to override in the struct xe_rtp_action entry
204 * For masked registers this translates to a single write, while for other
205 * registers it's a RMW. The correspondent bspec notation is (example for bits 2
206 * and 5, but could be any):
211 #define XE_RTP_ACTION_SET(reg_, val_, ...) \
212 { .reg = XE_RTP_DROP_CAST(reg_), \
213 .clr_bits = val_, .set_bits = val_, \
214 .read_mask = val_, ##__VA_ARGS__ }
217 * XE_RTP_ACTION_CLR: Clear bits from @val_ in the register.
219 * @val_: Bits to clear in the register
220 * @...: Additional fields to override in the struct xe_rtp_action entry
222 * For masked registers this translates to a single write, while for other
223 * registers it's a RMW. The correspondent bspec notation is (example for bits 2
224 * and 5, but could be any):
229 #define XE_RTP_ACTION_CLR(reg_, val_, ...) \
230 { .reg = XE_RTP_DROP_CAST(reg_), \
231 .clr_bits = val_, .set_bits = 0, \
232 .read_mask = val_, ##__VA_ARGS__ }
235 * XE_RTP_ACTION_FIELD_SET: Set a bit range
237 * @mask_bits_: Mask of bits to be changed in the register, forming a field
238 * @val_: Value to set in the field denoted by @mask_bits_
239 * @...: Additional fields to override in the struct xe_rtp_action entry
241 * For masked registers this translates to a single write, while for other
242 * registers it's a RMW. The correspondent bspec notation is:
244 * REGNAME[<end>:<start>] = VALUE
246 #define XE_RTP_ACTION_FIELD_SET(reg_, mask_bits_, val_, ...) \
247 { .reg = XE_RTP_DROP_CAST(reg_), \
248 .clr_bits = mask_bits_, .set_bits = val_, \
249 .read_mask = mask_bits_, ##__VA_ARGS__ }
251 #define XE_RTP_ACTION_FIELD_SET_NO_READ_MASK(reg_, mask_bits_, val_, ...) \
252 { .reg = XE_RTP_DROP_CAST(reg_), \
253 .clr_bits = (mask_bits_), .set_bits = (val_), \
254 .read_mask = 0, ##__VA_ARGS__ }
257 * XE_RTP_ACTION_WHITELIST - Add register to userspace whitelist
259 * @val_: Whitelist-specific flags to set
260 * @...: Additional fields to override in the struct xe_rtp_action entry
262 * Add a register to the whitelist, allowing userspace to modify the ster with
263 * regular user privileges.
265 #define XE_RTP_ACTION_WHITELIST(reg_, val_, ...) \
266 /* TODO fail build if ((flags) & ~(RING_FORCE_TO_NONPRIV_MASK_VALID)) */\
267 { .reg = XE_RTP_DROP_CAST(reg_), \
269 .clr_bits = RING_FORCE_TO_NONPRIV_MASK_VALID, \
273 * XE_RTP_NAME - Helper to set the name in xe_rtp_entry
274 * @s_: Name describing this rule, often a HW-specific number
276 * TODO: maybe move this behind a debug config?
278 #define XE_RTP_NAME(s_) .name = (s_)
281 * XE_RTP_ENTRY_FLAG - Helper to add multiple flags to a struct xe_rtp_entry_sr
282 * @...: Entry flags, without the ``XE_RTP_ENTRY_FLAG_`` prefix
284 * Helper to automatically add a ``XE_RTP_ENTRY_FLAG_`` prefix to the flags
285 * when defining struct xe_rtp_entry entries. Example:
289 * const struct xe_rtp_entry_sr wa_entries[] = {
291 * { XE_RTP_NAME("test-entry"),
293 * XE_RTP_ENTRY_FLAG(FOREACH_ENGINE),
299 #define XE_RTP_ENTRY_FLAG(...) \
300 .flags = (XE_RTP_PASTE_FOREACH(ENTRY_FLAG_, BITWISE_OR, (__VA_ARGS__)))
303 * XE_RTP_ACTION_FLAG - Helper to add multiple flags to a struct xe_rtp_action
304 * @...: Action flags, without the ``XE_RTP_ACTION_FLAG_`` prefix
306 * Helper to automatically add a ``XE_RTP_ACTION_FLAG_`` prefix to the flags
307 * when defining struct xe_rtp_action entries. Example:
311 * const struct xe_rtp_entry_sr wa_entries[] = {
313 * { XE_RTP_NAME("test-entry"),
315 * XE_RTP_ACTION_SET(..., XE_RTP_ACTION_FLAG(FOREACH_ENGINE)),
321 #define XE_RTP_ACTION_FLAG(...) \
322 .flags = (XE_RTP_PASTE_FOREACH(ACTION_FLAG_, BITWISE_OR, (__VA_ARGS__)))
325 * XE_RTP_RULES - Helper to set multiple rules to a struct xe_rtp_entry_sr entry
328 * At least one rule is needed and up to 4 are supported. Multiple rules are
329 * AND'ed together, i.e. all the rules must evaluate to true for the entry to
330 * be processed. See XE_RTP_MATCH_* for the possible match rules. Example:
334 * const struct xe_rtp_entry_sr wa_entries[] = {
336 * { XE_RTP_NAME("test-entry"),
337 * XE_RTP_RULES(SUBPLATFORM(DG2, G10), GRAPHICS_STEP(A0, B0)),
343 #define XE_RTP_RULES(...) \
344 .n_rules = _XE_COUNT_ARGS(__VA_ARGS__), \
345 .rules = (const struct xe_rtp_rule[]) { \
346 XE_RTP_PASTE_FOREACH(RULE_, COMMA, (__VA_ARGS__)) \
350 * XE_RTP_ACTIONS - Helper to set multiple actions to a struct xe_rtp_entry_sr
351 * @...: Actions to be taken
353 * At least one action is needed and up to 4 are supported. See XE_RTP_ACTION_*
354 * for the possible actions. Example:
358 * const struct xe_rtp_entry_sr wa_entries[] = {
360 * { XE_RTP_NAME("test-entry"),
362 * XE_RTP_ACTIONS(SET(..), SET(...), CLR(...)),
368 #define XE_RTP_ACTIONS(...) \
369 .n_actions = _XE_COUNT_ARGS(__VA_ARGS__), \
370 .actions = (const struct xe_rtp_action[]) { \
371 XE_RTP_PASTE_FOREACH(ACTION_, COMMA, (__VA_ARGS__)) \
374 #define XE_RTP_PROCESS_CTX_INITIALIZER(arg__) _Generic((arg__), \
375 struct xe_hw_engine * : (struct xe_rtp_process_ctx){ { (void *)(arg__) }, XE_RTP_PROCESS_TYPE_ENGINE }, \
376 struct xe_gt * : (struct xe_rtp_process_ctx){ { (void *)(arg__) }, XE_RTP_PROCESS_TYPE_GT })
378 void xe_rtp_process_ctx_enable_active_tracking(struct xe_rtp_process_ctx *ctx,
379 unsigned long *active_entries,
382 void xe_rtp_process_to_sr(struct xe_rtp_process_ctx *ctx,
383 const struct xe_rtp_entry_sr *entries,
384 struct xe_reg_sr *sr);
386 void xe_rtp_process(struct xe_rtp_process_ctx *ctx,
387 const struct xe_rtp_entry *entries);
389 /* Match functions to be used with XE_RTP_MATCH_FUNC */
392 * xe_rtp_match_even_instance - Match if engine instance is even
394 * @hwe: Engine instance
396 * Returns: true if engine instance is even, false otherwise
398 bool xe_rtp_match_even_instance(const struct xe_gt *gt,
399 const struct xe_hw_engine *hwe);
402 * xe_rtp_match_first_render_or_compute - Match if it's first render or compute
406 * @hwe: Engine instance
408 * Registers on the render reset domain need to have their values re-applied
409 * when any of those engines are reset. Since the engines reset together, a
410 * programming can be set to just one of them. For simplicity the first engine
411 * of either render or compute class can be chosen.
413 * Returns: true if engine id is the first to match the render reset domain,
416 bool xe_rtp_match_first_render_or_compute(const struct xe_gt *gt,
417 const struct xe_hw_engine *hwe);
420 * xe_rtp_match_first_gslice_fused_off - Match when first gslice is fused off
423 * @hwe: Engine instance
425 * Returns: true if first gslice is fused off, false otherwise.
427 bool xe_rtp_match_first_gslice_fused_off(const struct xe_gt *gt,
428 const struct xe_hw_engine *hwe);