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