xref: /linux/drivers/gpu/drm/xe/xe_rtp.h (revision 844c0700a675a5e30644c867ae7b30cb680d176d)
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/xarray.h>
10 #include <linux/types.h>
11 
12 #include "xe_rtp_types.h"
13 
14 #include "i915_reg_defs.h"
15 
16 /*
17  * Register table poke infrastructure
18  */
19 
20 struct xe_hw_engine;
21 struct xe_gt;
22 struct xe_reg_sr;
23 
24 /*
25  * Helper macros - not to be used outside this header.
26  */
27 /* This counts to 12. Any more, it will return 13th argument. */
28 #define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n
29 #define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
30 
31 #define __CONCAT(a, b) a ## b
32 #define CONCATENATE(a, b) __CONCAT(a, b)
33 
34 #define __CALL_FOR_EACH_1(MACRO_, x, ...) MACRO_(x)
35 #define __CALL_FOR_EACH_2(MACRO_, x, ...)					\
36 	MACRO_(x) __CALL_FOR_EACH_1(MACRO_, ##__VA_ARGS__)
37 #define __CALL_FOR_EACH_3(MACRO_, x, ...)					\
38 	MACRO_(x) __CALL_FOR_EACH_2(MACRO_, ##__VA_ARGS__)
39 #define __CALL_FOR_EACH_4(MACRO_, x, ...)					\
40 	MACRO_(x) __CALL_FOR_EACH_3(MACRO_, ##__VA_ARGS__)
41 
42 #define _CALL_FOR_EACH(NARGS_, MACRO_, x, ...)					\
43 	CONCATENATE(__CALL_FOR_EACH_, NARGS_)(MACRO_, x, ##__VA_ARGS__)
44 #define CALL_FOR_EACH(MACRO_, x, ...)						\
45 	_CALL_FOR_EACH(COUNT_ARGS(x, ##__VA_ARGS__), MACRO_, x, ##__VA_ARGS__)
46 
47 #define _XE_RTP_REG(x_)	(x_), XE_RTP_REG_REGULAR
48 #define _XE_RTP_MCR_REG(x_) (x_), XE_RTP_REG_MCR
49 
50 /*
51  * Helper macros for concatenating prefix - do not use them directly outside
52  * this header
53  */
54 #define __ADD_XE_RTP_ENTRY_FLAG_PREFIX(x) CONCATENATE(XE_RTP_ENTRY_FLAG_, x) |
55 #define __ADD_XE_RTP_ACTION_FLAG_PREFIX(x) CONCATENATE(XE_RTP_ACTION_FLAG_, x) |
56 #define __ADD_XE_RTP_RULE_PREFIX(x) CONCATENATE(XE_RTP_RULE_, x) ,
57 #define __ADD_XE_RTP_ACTION_PREFIX(x) CONCATENATE(XE_RTP_ACTION_, x) ,
58 
59 /*
60  * Macros to encode rules to match against platform, IP version, stepping, etc.
61  * Shouldn't be used directly - see XE_RTP_RULES()
62  */
63 
64 #define _XE_RTP_RULE_PLATFORM(plat__)						\
65 	{ .match_type = XE_RTP_MATCH_PLATFORM, .platform = plat__ }
66 
67 #define _XE_RTP_RULE_SUBPLATFORM(plat__, sub__)					\
68 	{ .match_type = XE_RTP_MATCH_SUBPLATFORM,				\
69 	  .platform = plat__, .subplatform = sub__ }
70 
71 #define _XE_RTP_RULE_STEP(start__, end__)					\
72 	{ .match_type = XE_RTP_MATCH_STEP,					\
73 	  .step_start = start__, .step_end = end__ }
74 
75 #define _XE_RTP_RULE_ENGINE_CLASS(cls__)					\
76 	{ .match_type = XE_RTP_MATCH_ENGINE_CLASS,				\
77 	  .engine_class = (cls__) }
78 
79 /**
80  * XE_RTP_RULE_PLATFORM - Create rule matching platform
81  * @plat_: platform to match
82  *
83  * Refer to XE_RTP_RULES() for expected usage.
84  */
85 #define XE_RTP_RULE_PLATFORM(plat_)						\
86 	_XE_RTP_RULE_PLATFORM(XE_##plat_)
87 
88 /**
89  * XE_RTP_RULE_SUBPLATFORM - Create rule matching platform and sub-platform
90  * @plat_: platform to match
91  * @sub_: sub-platform to match
92  *
93  * Refer to XE_RTP_RULES() for expected usage.
94  */
95 #define XE_RTP_RULE_SUBPLATFORM(plat_, sub_)					\
96 	_XE_RTP_RULE_SUBPLATFORM(XE_##plat_, XE_SUBPLATFORM_##plat_##_##sub_)
97 
98 /**
99  * XE_RTP_RULE_STEP - Create rule matching platform stepping
100  * @start_: First stepping matching the rule
101  * @end_: First stepping that does not match the rule
102  *
103  * Note that the range matching this rule [ @start_, @end_ ), i.e. inclusive on
104  * the left, exclusive on the right.
105  *
106  * Refer to XE_RTP_RULES() for expected usage.
107  */
108 #define XE_RTP_RULE_STEP(start_, end_)						\
109 	_XE_RTP_RULE_STEP(STEP_##start_, STEP_##end_)
110 
111 /**
112  * XE_RTP_RULE_ENGINE_CLASS - Create rule matching an engine class
113  * @cls_: Engine class to match
114  *
115  * Refer to XE_RTP_RULES() for expected usage.
116  */
117 #define XE_RTP_RULE_ENGINE_CLASS(cls_)						\
118 	_XE_RTP_RULE_ENGINE_CLASS(XE_ENGINE_CLASS_##cls_)
119 
120 /**
121  * XE_RTP_RULE_FUNC - Create rule using callback function for match
122  * @func__: Function to call to decide if rule matches
123  *
124  * This allows more complex checks to be performed. The ``XE_RTP``
125  * infrastructure will simply call the function @func_ passed to decide if this
126  * rule matches the device.
127  *
128  * Refer to XE_RTP_RULES() for expected usage.
129  */
130 #define XE_RTP_RULE_FUNC(func__)						\
131 	{ .match_type = XE_RTP_MATCH_FUNC,					\
132 	  .match_func = (func__) }
133 
134 /**
135  * XE_RTP_RULE_GRAPHICS_VERSION - Create rule matching graphics version
136  * @ver__: Graphics IP version to match
137  *
138  * Refer to XE_RTP_RULES() for expected usage.
139  */
140 #define XE_RTP_RULE_GRAPHICS_VERSION(ver__)					\
141 	{ .match_type = XE_RTP_MATCH_GRAPHICS_VERSION,				\
142 	  .ver_start = ver__, }
143 
144 /**
145  * XE_RTP_RULE_GRAPHICS_VERSION_RANGE - Create rule matching a range of graphics version
146  * @ver_start__: First graphics IP version to match
147  * @ver_end__: Last graphics IP version to match
148  *
149  * Note that the range matching this rule is [ @ver_start__, @ver_end__ ], i.e.
150  * inclusive on boths sides
151  *
152  * Refer to XE_RTP_RULES() for expected usage.
153  */
154 #define XE_RTP_RULE_GRAPHICS_VERSION_RANGE(ver_start__, ver_end__)		\
155 	{ .match_type = XE_RTP_MATCH_GRAPHICS_VERSION_RANGE,			\
156 	  .ver_start = ver_start__, .ver_end = ver_end__, }
157 
158 /**
159  * XE_RTP_RULE_MEDIA_VERSION - Create rule matching media version
160  * @ver__: Graphics IP version to match
161  *
162  * Refer to XE_RTP_RULES() for expected usage.
163  */
164 #define XE_RTP_RULE_MEDIA_VERSION(ver__)					\
165 	{ .match_type = XE_RTP_MATCH_MEDIA_VERSION,				\
166 	  .ver_start = ver__, }
167 
168 /**
169  * XE_RTP_RULE_MEDIA_VERSION_RANGE - Create rule matching a range of media version
170  * @ver_start__: First media IP version to match
171  * @ver_end__: Last media IP version to match
172  *
173  * Note that the range matching this rule is [ @ver_start__, @ver_end__ ], i.e.
174  * inclusive on boths sides
175  *
176  * Refer to XE_RTP_RULES() for expected usage.
177  */
178 #define XE_RTP_RULE_MEDIA_VERSION_RANGE(ver_start__, ver_end__)			\
179 	{ .match_type = XE_RTP_MATCH_MEDIA_VERSION_RANGE,			\
180 	  .ver_start = ver_start__, .ver_end = ver_end__, }
181 
182 /**
183  * XE_RTP_RULE_IS_INTEGRATED - Create a rule matching integrated graphics devices
184  *
185  * Refer to XE_RTP_RULES() for expected usage.
186  */
187 #define XE_RTP_RULE_IS_INTEGRATED						\
188 	{ .match_type = XE_RTP_MATCH_INTEGRATED }
189 
190 /**
191  * XE_RTP_RULE_IS_DISCRETE - Create a rule matching discrete graphics devices
192  *
193  * Refer to XE_RTP_RULES() for expected usage.
194  */
195 #define XE_RTP_RULE_IS_DISCRETE							\
196 	{ .match_type = XE_RTP_MATCH_DISCRETE }
197 
198 /**
199  * XE_RTP_ACTION_WR - Helper to write a value to the register, overriding all
200  *                    the bits
201  * @reg_: Register
202  * @reg_type_: Register type - automatically expanded by MCR_REG/_MMIO
203  * @val_: Value to set
204  * @...: Additional fields to override in the struct xe_rtp_action entry
205  *
206  * The correspondent notation in bspec is:
207  *
208  *	REGNAME = VALUE
209  */
210 #define XE_RTP_ACTION_WR(reg_, reg_type_, val_, ...)				\
211 	{ .reg = (reg_), .reg_type = (reg_type_),				\
212 	  .clr_bits = ~0u, .set_bits = (val_),					\
213 	  .read_mask = (~0u), ##__VA_ARGS__ }
214 
215 /**
216  * XE_RTP_ACTION_SET - Set bits from @val_ in the register.
217  * @reg_: Register
218  * @reg_type_: Register type - automatically expanded by MCR_REG/_MMIO
219  * @val_: Bits to set in the register
220  * @...: Additional fields to override in the struct xe_rtp_action entry
221  *
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):
225  *
226  *	REGNAME[2] = 1
227  *	REGNAME[5] = 1
228  */
229 #define XE_RTP_ACTION_SET(reg_, reg_type_, val_, ...)				\
230 	{ .reg = (reg_), .reg_type = (reg_type_),				\
231 	  .clr_bits = (val_), .set_bits = (val_),				\
232 	  .read_mask = (val_), ##__VA_ARGS__ }
233 
234 /**
235  * XE_RTP_ACTION_CLR: Clear bits from @val_ in the register.
236  * @reg_: Register
237  * @reg_type_: Register type - automatically expanded by MCR_REG/_MMIO
238  * @val_: Bits to clear in the register
239  * @...: Additional fields to override in the struct xe_rtp_action entry
240  *
241  * For masked registers this translates to a single write, while for other
242  * registers it's a RMW. The correspondent bspec notation is (example for bits 2
243  * and 5, but could be any):
244  *
245  *	REGNAME[2] = 0
246  *	REGNAME[5] = 0
247  */
248 #define XE_RTP_ACTION_CLR(reg_, reg_type_, val_, ...)				\
249 	{ .reg = (reg_), .reg_type = (reg_type_),				\
250 	  .clr_bits = (val_), .set_bits = 0,					\
251 	  .read_mask = (val_), ##__VA_ARGS__ }
252 
253 /**
254  * XE_RTP_ACTION_FIELD_SET: Set a bit range
255  * @reg_: Register
256  * @reg_type_: Register type - automatically expanded by MCR_REG/_MMIO
257  * @mask_bits_: Mask of bits to be changed in the register, forming a field
258  * @val_: Value to set in the field denoted by @mask_bits_
259  * @...: Additional fields to override in the struct xe_rtp_action entry
260  *
261  * For masked registers this translates to a single write, while for other
262  * registers it's a RMW. The correspondent bspec notation is:
263  *
264  *	REGNAME[<end>:<start>] = VALUE
265  */
266 #define XE_RTP_ACTION_FIELD_SET(reg_, reg_type_, mask_bits_, val_, ...)		\
267 	{ .reg = (reg_), .reg_type = (reg_type_),				\
268 	  .clr_bits = (mask_bits_), .set_bits = (val_),				\
269 	  .read_mask = (mask_bits_), ##__VA_ARGS__ }
270 
271 #define XE_RTP_ACTION_FIELD_SET_NO_READ_MASK(reg_, reg_type_, mask_bits_, val_, ...)	\
272 	{ .reg = (reg_), .reg_type = (reg_type_),				\
273 	  .clr_bits = (mask_bits_), .set_bits = (val_),				\
274 	  .read_mask = 0, ##__VA_ARGS__ }
275 
276 /**
277  * XE_RTP_ACTION_WHITELIST - Add register to userspace whitelist
278  * @reg_: Register
279  * @reg_type_: Register type - automatically expanded by MCR_REG/_MMIO
280  * @val_: Whitelist-specific flags to set
281  * @...: Additional fields to override in the struct xe_rtp_action entry
282  *
283  * Add a register to the whitelist, allowing userspace to modify the ster with
284  * regular user privileges.
285  */
286 #define XE_RTP_ACTION_WHITELIST(reg_, reg_type_, val_, ...)			\
287 	/* TODO fail build if ((flags) & ~(RING_FORCE_TO_NONPRIV_MASK_VALID)) */\
288 	{ .reg = (reg_), .reg_type = (reg_type_), .set_bits = (val_),		\
289 	  .clr_bits = RING_FORCE_TO_NONPRIV_MASK_VALID,				\
290 	  ##__VA_ARGS__ }
291 
292 /**
293  * XE_RTP_NAME - Helper to set the name in xe_rtp_entry
294  * @s_: Name describing this rule, often a HW-specific number
295  *
296  * TODO: maybe move this behind a debug config?
297  */
298 #define XE_RTP_NAME(s_)	.name = (s_)
299 
300 /**
301  * XE_RTP_ENTRY_FLAG - Helper to add multiple flags to a struct xe_rtp_entry
302  * @f1_: Last part of a ``XE_RTP_ENTRY_FLAG_*``
303  * @...: Additional flags, defined like @f1_
304  *
305  * Helper to automatically add a ``XE_RTP_ENTRY_FLAG_`` prefix to @f1_ so it can
306  * be easily used to define struct xe_rtp_action entries. Example:
307  *
308  * .. code-block:: c
309  *
310  *	const struct xe_rtp_entry wa_entries[] = {
311  *		...
312  *		{ XE_RTP_NAME("test-entry"),
313  *		  ...
314  *		  XE_RTP_ENTRY_FLAG(FOREACH_ENGINE),
315  *		  ...
316  *		},
317  *		...
318  *	};
319  */
320 #define XE_RTP_ENTRY_FLAG(f1_, ...)						\
321 	.flags = (CALL_FOR_EACH(__ADD_XE_RTP_ENTRY_FLAG_PREFIX, f1_, ##__VA_ARGS__) 0)
322 
323 /**
324  * XE_RTP_ACTION_FLAG - Helper to add multiple flags to a struct xe_rtp_action
325  * @f1_: Last part of a ``XE_RTP_ENTRY_*``
326  * @...: Additional flags, defined like @f1_
327  *
328  * Helper to automatically add a ``XE_RTP_ACTION_FLAG_`` prefix to @f1_ so it
329  * can be easily used to define struct xe_rtp_action entries. Example:
330  *
331  * .. code-block:: c
332  *
333  *	const struct xe_rtp_entry wa_entries[] = {
334  *		...
335  *		{ XE_RTP_NAME("test-entry"),
336  *		  ...
337  *		  XE_RTP_ACTION_SET(..., XE_RTP_ACTION_FLAG(FOREACH_ENGINE)),
338  *		  ...
339  *		},
340  *		...
341  *	};
342  */
343 #define XE_RTP_ACTION_FLAG(f1_, ...)						\
344 	.flags = (CALL_FOR_EACH(__ADD_XE_RTP_ACTION_FLAG_PREFIX, f1_, ##__VA_ARGS__) 0)
345 
346 /**
347  * XE_RTP_RULES - Helper to set multiple rules to a struct xe_rtp_entry entry
348  * @r1: Last part of XE_RTP_MATCH_*
349  * @...: Additional rules, defined like @r1
350  *
351  * At least one rule is needed and up to 4 are supported. Multiple rules are
352  * AND'ed together, i.e. all the rules must evaluate to true for the entry to
353  * be processed. See XE_RTP_MATCH_* for the possible match rules. Example:
354  *
355  * .. code-block:: c
356  *
357  *	const struct xe_rtp_entry wa_entries[] = {
358  *		...
359  *		{ XE_RTP_NAME("test-entry"),
360  *		  XE_RTP_RULES(SUBPLATFORM(DG2, G10), STEP(A0, B0)),
361  *		  ...
362  *		},
363  *		...
364  *	};
365  */
366 #define XE_RTP_RULES(r1, ...)							\
367 	.n_rules = COUNT_ARGS(r1, ##__VA_ARGS__),				\
368 	.rules = (struct xe_rtp_rule[]) {					\
369 		CALL_FOR_EACH(__ADD_XE_RTP_RULE_PREFIX, r1, ##__VA_ARGS__)	\
370 	}
371 
372 /**
373  * XE_RTP_ACTIONS - Helper to set multiple actions to a struct xe_rtp_entry
374  * @a1: Action to take. Last part of XE_RTP_ACTION_*
375  * @...: Additional rules, defined like @r1
376  *
377  * At least one rule is needed and up to 4 are supported. Multiple rules are
378  * AND'ed together, i.e. all the rules must evaluate to true for the entry to
379  * be processed. See XE_RTP_MATCH_* for the possible match rules. Example:
380  *
381  * .. code-block:: c
382  *
383  *	const struct xe_rtp_entry wa_entries[] = {
384  *		...
385  *		{ XE_RTP_NAME("test-entry"),
386  *		  XE_RTP_RULES(...),
387  *		  XE_RTP_ACTIONS(SET(..), SET(...), CLR(...)),
388  *		  ...
389  *		},
390  *		...
391  *	};
392  */
393 #define XE_RTP_ACTIONS(a1, ...)							\
394 	.n_actions = COUNT_ARGS(a1, ##__VA_ARGS__),				\
395 	.actions = (struct xe_rtp_action[]) {					\
396 		CALL_FOR_EACH(__ADD_XE_RTP_ACTION_PREFIX, a1, ##__VA_ARGS__)	\
397 	}
398 
399 void xe_rtp_process(const struct xe_rtp_entry *entries, struct xe_reg_sr *sr,
400 		    struct xe_gt *gt, struct xe_hw_engine *hwe);
401 
402 #endif
403