Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: MIT */
2/*
3 * Copyright © 2022 Intel Corporation
4 */
5
6#ifndef _XE_RTP_
7#define _XE_RTP_
8
9#include <linux/types.h>
10#include <linux/xarray.h>
11
12#define _XE_RTP_INCLUDE_PRIVATE_HELPERS
13
14#include "xe_rtp_helpers.h"
15#include "xe_rtp_types.h"
16
17#undef _XE_RTP_INCLUDE_PRIVATE_HELPERS
18
19/*
20 * Register table poke infrastructure
21 */
22
23struct xe_hw_engine;
24struct xe_gt;
25struct xe_reg_sr;
26
27/*
28 * Macros to encode rules to match against platform, IP version, stepping, etc.
29 * Shouldn't be used directly - see XE_RTP_RULES()
30 */
31#define _XE_RTP_RULE_PLATFORM(plat__) \
32 { .match_type = XE_RTP_MATCH_PLATFORM, .platform = plat__ }
33
34#define _XE_RTP_RULE_SUBPLATFORM(plat__, sub__) \
35 { .match_type = XE_RTP_MATCH_SUBPLATFORM, \
36 .platform = plat__, .subplatform = sub__ }
37
38#define _XE_RTP_RULE_PLATFORM_STEP(start__, end__) \
39 { .match_type = XE_RTP_MATCH_PLATFORM_STEP, \
40 .step_start = start__, .step_end = end__ }
41
42#define _XE_RTP_RULE_GRAPHICS_STEP(start__, end__) \
43 { .match_type = XE_RTP_MATCH_GRAPHICS_STEP, \
44 .step_start = start__, .step_end = end__ }
45
46#define _XE_RTP_RULE_MEDIA_STEP(start__, end__) \
47 { .match_type = XE_RTP_MATCH_MEDIA_STEP, \
48 .step_start = start__, .step_end = end__ }
49
50#define _XE_RTP_RULE_ENGINE_CLASS(cls__) \
51 { .match_type = XE_RTP_MATCH_ENGINE_CLASS, \
52 .engine_class = (cls__) }
53
54/**
55 * XE_RTP_RULE_PLATFORM - Create rule matching platform
56 * @plat_: platform to match
57 *
58 * Refer to XE_RTP_RULES() for expected usage.
59 */
60#define XE_RTP_RULE_PLATFORM(plat_) \
61 _XE_RTP_RULE_PLATFORM(XE_##plat_)
62
63/**
64 * XE_RTP_RULE_SUBPLATFORM - Create rule matching platform and sub-platform
65 * @plat_: platform to match
66 * @sub_: sub-platform to match
67 *
68 * Refer to XE_RTP_RULES() for expected usage.
69 */
70#define XE_RTP_RULE_SUBPLATFORM(plat_, sub_) \
71 _XE_RTP_RULE_SUBPLATFORM(XE_##plat_, XE_SUBPLATFORM_##plat_##_##sub_)
72
73/**
74 * XE_RTP_RULE_PLATFORM_STEP - Create rule matching platform-level stepping
75 * @start_: First stepping matching the rule
76 * @end_: First stepping that does not match the rule
77 *
78 * Note that the range matching this rule is [ @start_, @end_ ), i.e. inclusive
79 * on the left, exclusive on the right.
80 *
81 * You need to make sure that proper support for reading platform-level stepping
82 * information is present for the target platform before using this rule.
83 *
84 * Refer to XE_RTP_RULES() for expected usage.
85 */
86#define XE_RTP_RULE_PLATFORM_STEP(start_, end_) \
87 _XE_RTP_RULE_PLATFORM_STEP(STEP_##start_, STEP_##end_)
88
89/**
90 * XE_RTP_RULE_GRAPHICS_STEP - Create rule matching graphics stepping
91 * @start_: First stepping matching the rule
92 * @end_: First stepping that does not match the rule
93 *
94 * Note that the range matching this rule is [ @start_, @end_ ), i.e. inclusive
95 * on the left, exclusive on the right.
96 *
97 * Refer to XE_RTP_RULES() for expected usage.
98 */
99#define XE_RTP_RULE_GRAPHICS_STEP(start_, end_) \
100 _XE_RTP_RULE_GRAPHICS_STEP(STEP_##start_, STEP_##end_)
101
102/**
103 * XE_RTP_RULE_MEDIA_STEP - Create rule matching media stepping
104 * @start_: First stepping matching the rule
105 * @end_: First stepping that does not match the rule
106 *
107 * Note that the range matching this rule is [ @start_, @end_ ), i.e. inclusive
108 * on the left, exclusive on the right.
109 *
110 * Refer to XE_RTP_RULES() for expected usage.
111 */
112#define XE_RTP_RULE_MEDIA_STEP(start_, end_) \
113 _XE_RTP_RULE_MEDIA_STEP(STEP_##start_, STEP_##end_)
114
115/**
116 * XE_RTP_RULE_ENGINE_CLASS - Create rule matching an engine class
117 * @cls_: Engine class to match
118 *
119 * Refer to XE_RTP_RULES() for expected usage.
120 */
121#define XE_RTP_RULE_ENGINE_CLASS(cls_) \
122 _XE_RTP_RULE_ENGINE_CLASS(XE_ENGINE_CLASS_##cls_)
123
124/**
125 * XE_RTP_RULE_FUNC - Create rule using callback function for match
126 * @func__: Function to call to decide if rule matches
127 *
128 * This allows more complex checks to be performed. The ``XE_RTP``
129 * infrastructure will simply call the function @func_ passed to decide if this
130 * rule matches the device.
131 *
132 * Refer to XE_RTP_RULES() for expected usage.
133 */
134#define XE_RTP_RULE_FUNC(func__) \
135 { .match_type = XE_RTP_MATCH_FUNC, \
136 .match_func = (func__) }
137
138/**
139 * XE_RTP_RULE_GRAPHICS_VERSION - Create rule matching graphics version
140 * @ver__: Graphics IP version to match
141 *
142 * Refer to XE_RTP_RULES() for expected usage.
143 */
144#define XE_RTP_RULE_GRAPHICS_VERSION(ver__) \
145 { .match_type = XE_RTP_MATCH_GRAPHICS_VERSION, \
146 .ver_start = ver__, }
147
148/**
149 * XE_RTP_RULE_GRAPHICS_VERSION_RANGE - Create rule matching a range of graphics version
150 * @ver_start__: First graphics IP version to match
151 * @ver_end__: Last graphics IP version to match
152 *
153 * Note that the range matching this rule is [ @ver_start__, @ver_end__ ], i.e.
154 * inclusive on both sides
155 *
156 * Refer to XE_RTP_RULES() for expected usage.
157 */
158#define XE_RTP_RULE_GRAPHICS_VERSION_RANGE(ver_start__, ver_end__) \
159 { .match_type = XE_RTP_MATCH_GRAPHICS_VERSION_RANGE, \
160 .ver_start = ver_start__, .ver_end = ver_end__, }
161
162/**
163 * XE_RTP_RULE_GRAPHICS_VERSION_ANY_GT - Create rule matching graphics version on any GT
164 * @ver__: Graphics IP version to match
165 *
166 * Like XE_RTP_RULE_GRAPHICS_VERSION, but it matches even if the current GT
167 * being checked is not of the graphics type. It allows to add RTP entries to
168 * another GT when the device contains a Graphics IP with that version.
169 *
170 * Refer to XE_RTP_RULES() for expected usage.
171 */
172#define XE_RTP_RULE_GRAPHICS_VERSION_ANY_GT(ver__) \
173 { .match_type = XE_RTP_MATCH_GRAPHICS_VERSION_ANY_GT, \
174 .ver_start = ver__, }
175
176/**
177 * XE_RTP_RULE_MEDIA_VERSION - Create rule matching media version
178 * @ver__: Media IP version to match
179 *
180 * Refer to XE_RTP_RULES() for expected usage.
181 */
182#define XE_RTP_RULE_MEDIA_VERSION(ver__) \
183 { .match_type = XE_RTP_MATCH_MEDIA_VERSION, \
184 .ver_start = ver__, }
185
186/**
187 * XE_RTP_RULE_MEDIA_VERSION_RANGE - Create rule matching a range of media version
188 * @ver_start__: First media IP version to match
189 * @ver_end__: Last media IP version to match
190 *
191 * Note that the range matching this rule is [ @ver_start__, @ver_end__ ], i.e.
192 * inclusive on both sides
193 *
194 * Refer to XE_RTP_RULES() for expected usage.
195 */
196#define XE_RTP_RULE_MEDIA_VERSION_RANGE(ver_start__, ver_end__) \
197 { .match_type = XE_RTP_MATCH_MEDIA_VERSION_RANGE, \
198 .ver_start = ver_start__, .ver_end = ver_end__, }
199
200/**
201 * XE_RTP_RULE_MEDIA_VERSION_ANY_GT - Create rule matching media version on any GT
202 * @ver__: Media IP version to match
203 *
204 * Like XE_RTP_RULE_MEDIA_VERSION, but it matches even if the current GT being
205 * checked is not of the media type. It allows to add RTP entries to another
206 * GT when the device contains a Media IP with that version.
207 *
208 * Refer to XE_RTP_RULES() for expected usage.
209 */
210#define XE_RTP_RULE_MEDIA_VERSION_ANY_GT(ver__) \
211 { .match_type = XE_RTP_MATCH_MEDIA_VERSION_ANY_GT, \
212 .ver_start = ver__, }
213
214/**
215 * XE_RTP_RULE_IS_INTEGRATED - Create a rule matching integrated graphics devices
216 *
217 * Refer to XE_RTP_RULES() for expected usage.
218 */
219#define XE_RTP_RULE_IS_INTEGRATED \
220 { .match_type = XE_RTP_MATCH_INTEGRATED }
221
222/**
223 * XE_RTP_RULE_IS_DISCRETE - Create a rule matching discrete graphics devices
224 *
225 * Refer to XE_RTP_RULES() for expected usage.
226 */
227#define XE_RTP_RULE_IS_DISCRETE \
228 { .match_type = XE_RTP_MATCH_DISCRETE }
229
230/**
231 * XE_RTP_RULE_OR - Create an OR condition for rtp rules
232 *
233 * RTP rules are AND'ed when evaluated and all of them need to match.
234 * XE_RTP_RULE_OR allows to create set of rules where any of them matching is
235 * sufficient for the action to trigger. Example:
236 *
237 * .. code-block:: c
238 *
239 * const struct xe_rtp_entry_sr entries[] = {
240 * ...
241 * { XE_RTP_NAME("test-entry"),
242 * XE_RTP_RULES(PLATFORM(DG2), OR, PLATFORM(TIGERLAKE)),
243 * ...
244 * },
245 * ...
246 * };
247 */
248#define XE_RTP_RULE_OR \
249 { .match_type = XE_RTP_MATCH_OR }
250
251/**
252 * XE_RTP_ACTION_WR - Helper to write a value to the register, overriding all
253 * the bits
254 * @reg_: Register
255 * @val_: Value to set
256 * @...: Additional fields to override in the struct xe_rtp_action entry
257 *
258 * The correspondent notation in bspec is:
259 *
260 * REGNAME = VALUE
261 */
262#define XE_RTP_ACTION_WR(reg_, val_, ...) \
263 { .reg = XE_RTP_DROP_CAST(reg_), \
264 .clr_bits = ~0u, .set_bits = (val_), \
265 .read_mask = (~0u), ##__VA_ARGS__ }
266
267/**
268 * XE_RTP_ACTION_SET - Set bits from @val_ in the register.
269 * @reg_: Register
270 * @val_: Bits to set in the register
271 * @...: Additional fields to override in the struct xe_rtp_action entry
272 *
273 * For masked registers this translates to a single write, while for other
274 * registers it's a RMW. The correspondent bspec notation is (example for bits 2
275 * and 5, but could be any):
276 *
277 * REGNAME[2] = 1
278 * REGNAME[5] = 1
279 */
280#define XE_RTP_ACTION_SET(reg_, val_, ...) \
281 { .reg = XE_RTP_DROP_CAST(reg_), \
282 .clr_bits = val_, .set_bits = val_, \
283 .read_mask = val_, ##__VA_ARGS__ }
284
285/**
286 * XE_RTP_ACTION_CLR: Clear bits from @val_ in the register.
287 * @reg_: Register
288 * @val_: Bits to clear in the register
289 * @...: Additional fields to override in the struct xe_rtp_action entry
290 *
291 * For masked registers this translates to a single write, while for other
292 * registers it's a RMW. The correspondent bspec notation is (example for bits 2
293 * and 5, but could be any):
294 *
295 * REGNAME[2] = 0
296 * REGNAME[5] = 0
297 */
298#define XE_RTP_ACTION_CLR(reg_, val_, ...) \
299 { .reg = XE_RTP_DROP_CAST(reg_), \
300 .clr_bits = val_, .set_bits = 0, \
301 .read_mask = val_, ##__VA_ARGS__ }
302
303/**
304 * XE_RTP_ACTION_FIELD_SET: Set a bit range
305 * @reg_: Register
306 * @mask_bits_: Mask of bits to be changed in the register, forming a field
307 * @val_: Value to set in the field denoted by @mask_bits_
308 * @...: Additional fields to override in the struct xe_rtp_action entry
309 *
310 * For masked registers this translates to a single write, while for other
311 * registers it's a RMW. The correspondent bspec notation is:
312 *
313 * REGNAME[<end>:<start>] = VALUE
314 */
315#define XE_RTP_ACTION_FIELD_SET(reg_, mask_bits_, val_, ...) \
316 { .reg = XE_RTP_DROP_CAST(reg_), \
317 .clr_bits = mask_bits_, .set_bits = val_, \
318 .read_mask = mask_bits_, ##__VA_ARGS__ }
319
320#define XE_RTP_ACTION_FIELD_SET_NO_READ_MASK(reg_, mask_bits_, val_, ...) \
321 { .reg = XE_RTP_DROP_CAST(reg_), \
322 .clr_bits = (mask_bits_), .set_bits = (val_), \
323 .read_mask = 0, ##__VA_ARGS__ }
324
325/**
326 * XE_RTP_ACTION_WHITELIST - Add register to userspace whitelist
327 * @reg_: Register
328 * @val_: Whitelist-specific flags to set
329 * @...: Additional fields to override in the struct xe_rtp_action entry
330 *
331 * Add a register to the whitelist, allowing userspace to modify the ster with
332 * regular user privileges.
333 */
334#define XE_RTP_ACTION_WHITELIST(reg_, val_, ...) \
335 /* TODO fail build if ((flags) & ~(RING_FORCE_TO_NONPRIV_MASK_VALID)) */\
336 { .reg = XE_RTP_DROP_CAST(reg_), \
337 .set_bits = val_, \
338 .clr_bits = RING_FORCE_TO_NONPRIV_MASK_VALID, \
339 ##__VA_ARGS__ }
340
341/**
342 * XE_RTP_NAME - Helper to set the name in xe_rtp_entry
343 * @s_: Name describing this rule, often a HW-specific number
344 *
345 * TODO: maybe move this behind a debug config?
346 */
347#define XE_RTP_NAME(s_) .name = (s_)
348
349/**
350 * XE_RTP_ENTRY_FLAG - Helper to add multiple flags to a struct xe_rtp_entry_sr
351 * @...: Entry flags, without the ``XE_RTP_ENTRY_FLAG_`` prefix
352 *
353 * Helper to automatically add a ``XE_RTP_ENTRY_FLAG_`` prefix to the flags
354 * when defining struct xe_rtp_entry entries. Example:
355 *
356 * .. code-block:: c
357 *
358 * const struct xe_rtp_entry_sr wa_entries[] = {
359 * ...
360 * { XE_RTP_NAME("test-entry"),
361 * ...
362 * XE_RTP_ENTRY_FLAG(FOREACH_ENGINE),
363 * ...
364 * },
365 * ...
366 * };
367 */
368#define XE_RTP_ENTRY_FLAG(...) \
369 .flags = (XE_RTP_PASTE_FOREACH(ENTRY_FLAG_, BITWISE_OR, (__VA_ARGS__)))
370
371/**
372 * XE_RTP_ACTION_FLAG - Helper to add multiple flags to a struct xe_rtp_action
373 * @...: Action flags, without the ``XE_RTP_ACTION_FLAG_`` prefix
374 *
375 * Helper to automatically add a ``XE_RTP_ACTION_FLAG_`` prefix to the flags
376 * when defining struct xe_rtp_action entries. Example:
377 *
378 * .. code-block:: c
379 *
380 * const struct xe_rtp_entry_sr wa_entries[] = {
381 * ...
382 * { XE_RTP_NAME("test-entry"),
383 * ...
384 * XE_RTP_ACTION_SET(..., XE_RTP_ACTION_FLAG(FOREACH_ENGINE)),
385 * ...
386 * },
387 * ...
388 * };
389 */
390#define XE_RTP_ACTION_FLAG(...) \
391 .flags = (XE_RTP_PASTE_FOREACH(ACTION_FLAG_, BITWISE_OR, (__VA_ARGS__)))
392
393/**
394 * XE_RTP_RULES - Helper to set multiple rules to a struct xe_rtp_entry_sr entry
395 * @...: Rules
396 *
397 * At least one rule is needed and up to 12 are supported. Multiple rules are
398 * AND'ed together, i.e. all the rules must evaluate to true for the entry to
399 * be processed. See XE_RTP_MATCH_* for the possible match rules. Example:
400 *
401 * .. code-block:: c
402 *
403 * const struct xe_rtp_entry_sr wa_entries[] = {
404 * ...
405 * { XE_RTP_NAME("test-entry"),
406 * XE_RTP_RULES(SUBPLATFORM(DG2, G10), GRAPHICS_STEP(A0, B0)),
407 * ...
408 * },
409 * ...
410 * };
411 */
412#define XE_RTP_RULES(...) \
413 .n_rules = COUNT_ARGS(__VA_ARGS__), \
414 .rules = (const struct xe_rtp_rule[]) { \
415 XE_RTP_PASTE_FOREACH(RULE_, COMMA, (__VA_ARGS__)) \
416 }
417
418/**
419 * XE_RTP_ACTIONS - Helper to set multiple actions to a struct xe_rtp_entry_sr
420 * @...: Actions to be taken
421 *
422 * At least one action is needed and up to 12 are supported. See XE_RTP_ACTION_*
423 * for the possible actions. Example:
424 *
425 * .. code-block:: c
426 *
427 * const struct xe_rtp_entry_sr wa_entries[] = {
428 * ...
429 * { XE_RTP_NAME("test-entry"),
430 * XE_RTP_RULES(...),
431 * XE_RTP_ACTIONS(SET(..), SET(...), CLR(...)),
432 * ...
433 * },
434 * ...
435 * };
436 */
437#define XE_RTP_ACTIONS(...) \
438 .n_actions = COUNT_ARGS(__VA_ARGS__), \
439 .actions = (const struct xe_rtp_action[]) { \
440 XE_RTP_PASTE_FOREACH(ACTION_, COMMA, (__VA_ARGS__)) \
441 }
442
443#define XE_RTP_PROCESS_CTX_INITIALIZER(arg__) _Generic((arg__), \
444 struct xe_hw_engine * : (struct xe_rtp_process_ctx){ { (void *)(arg__) }, XE_RTP_PROCESS_TYPE_ENGINE }, \
445 struct xe_gt * : (struct xe_rtp_process_ctx){ { (void *)(arg__) }, XE_RTP_PROCESS_TYPE_GT }, \
446 struct xe_device * : (struct xe_rtp_process_ctx){ { (void *)(arg__) }, XE_RTP_PROCESS_TYPE_DEVICE })
447
448void xe_rtp_process_ctx_enable_active_tracking(struct xe_rtp_process_ctx *ctx,
449 unsigned long *active_entries,
450 size_t n_entries);
451
452void xe_rtp_process_to_sr(struct xe_rtp_process_ctx *ctx,
453 const struct xe_rtp_entry_sr *entries,
454 size_t n_entries, struct xe_reg_sr *sr,
455 bool process_in_vf);
456
457void xe_rtp_process(struct xe_rtp_process_ctx *ctx,
458 const struct xe_rtp_entry *entries);
459
460/* Match functions to be used with XE_RTP_MATCH_FUNC */
461
462/**
463 * xe_rtp_match_even_instance - Match if engine instance is even
464 * @xe: Device structure
465 * @gt: GT structure
466 * @hwe: Engine instance
467 *
468 * Returns: true if engine instance is even, false otherwise
469 */
470bool xe_rtp_match_even_instance(const struct xe_device *xe,
471 const struct xe_gt *gt,
472 const struct xe_hw_engine *hwe);
473
474/*
475 * xe_rtp_match_first_render_or_compute - Match if it's first render or compute
476 * engine in the GT
477 *
478 * @xe: Device structure
479 * @gt: GT structure
480 * @hwe: Engine instance
481 *
482 * Registers on the render reset domain need to have their values re-applied
483 * when any of those engines are reset. Since the engines reset together, a
484 * programming can be set to just one of them. For simplicity the first engine
485 * of either render or compute class can be chosen.
486 *
487 * Returns: true if engine id is the first to match the render reset domain,
488 * false otherwise.
489 */
490bool xe_rtp_match_first_render_or_compute(const struct xe_device *xe,
491 const struct xe_gt *gt,
492 const struct xe_hw_engine *hwe);
493
494/*
495 * xe_rtp_match_not_sriov_vf - Match when not on SR-IOV VF device
496 *
497 * @xe: Device structure
498 * @gt: GT structure
499 * @hwe: Engine instance
500 *
501 * Returns: true if device is not VF, false otherwise.
502 */
503bool xe_rtp_match_not_sriov_vf(const struct xe_device *xe,
504 const struct xe_gt *gt,
505 const struct xe_hw_engine *hwe);
506
507bool xe_rtp_match_psmi_enabled(const struct xe_device *xe,
508 const struct xe_gt *gt,
509 const struct xe_hw_engine *hwe);
510
511bool xe_rtp_match_gt_has_discontiguous_dss_groups(const struct xe_device *xe,
512 const struct xe_gt *gt,
513 const struct xe_hw_engine *hwe);
514
515/**
516 * xe_rtp_match_has_flat_ccs - Match when platform has FlatCCS compression
517 * @xe: Device structure
518 * @gt: GT structure
519 * @hwe: Engine instance
520 *
521 * Returns: true if platform has FlatCCS compression, false otherwise
522 */
523bool xe_rtp_match_has_flat_ccs(const struct xe_device *xe,
524 const struct xe_gt *gt,
525 const struct xe_hw_engine *hwe);
526
527#endif