xref: /linux/drivers/gpu/drm/xe/xe_rtp.h (revision aec2f682d47c54ef434b2d440992626d80b1ebdc)
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 
23 struct xe_hw_engine;
24 struct xe_gt;
25 struct 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 
448 void xe_rtp_process_ctx_enable_active_tracking(struct xe_rtp_process_ctx *ctx,
449 					       unsigned long *active_entries,
450 					       size_t n_entries);
451 
452 void 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 
457 void 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  */
470 bool 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  */
490 bool 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  */
503 bool 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 
507 bool xe_rtp_match_psmi_enabled(const struct xe_device *xe,
508 			       const struct xe_gt *gt,
509 			       const struct xe_hw_engine *hwe);
510 
511 bool 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  */
523 bool 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
528