xref: /linux/drivers/gpu/drm/xe/xe_rtp.h (revision 3747c88428a199620ca626a196781516c6da12e6)
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_FLAG_PREFIX(x) CONCATENATE(XE_RTP_FLAG_, x) |
57 #define __ADD_XE_RTP_RULE_PREFIX(x) CONCATENATE(XE_RTP_RULE_, 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_WR - Helper to write a value to the register, overriding all the bits
200  * @reg_: Register
201  * @val_: Value to set
202  * @...: Additional fields to override in the struct xe_rtp_action entry
203  *
204  * The correspondent notation in bspec is:
205  *
206  *	REGNAME = VALUE
207  */
208 #define XE_RTP_WR(reg_, val_, ...)						\
209 	.action = { .reg = reg_, .clr_bits = ~0u, .set_bits = (val_),		\
210 		    .read_mask = (~0u), ##__VA_ARGS__ }
211 
212 /**
213  * XE_RTP_SET - Set bits from @val_ in the register.
214  * @reg_: Register
215  * @val_: Bits to set in the register
216  * @...: Additional fields to override in the struct xe_rtp_action entry
217  *
218  * For masked registers this translates to a single write, while for other
219  * registers it's a RMW. The correspondent bspec notation is (example for bits 2
220  * and 5, but could be any):
221  *
222  *	REGNAME[2] = 1
223  *	REGNAME[5] = 1
224  */
225 #define XE_RTP_SET(reg_, val_, ...)						\
226 	.action = { .reg = reg_, .clr_bits = (val_), .set_bits = (val_),	\
227 		    .read_mask = (val_), ##__VA_ARGS__ }
228 
229 /**
230  * XE_RTP_CLR: Clear bits from @val_ in the register.
231  * @reg_: Register
232  * @val_: Bits to clear in the register
233  * @...: Additional fields to override in the struct xe_rtp_action entry
234  *
235  * For masked registers this translates to a single write, while for other
236  * registers it's a RMW. The correspondent bspec notation is (example for bits 2
237  * and 5, but could be any):
238  *
239  *	REGNAME[2] = 0
240  *	REGNAME[5] = 0
241  */
242 #define XE_RTP_CLR(reg_, val_, ...)						\
243 	.action = { .reg = reg_, .clr_bits = (val_), .set_bits = 0,		\
244 		    .read_mask = (val_), ##__VA_ARGS__ }
245 
246 /**
247  * XE_RTP_FIELD_SET: Set a bit range, defined by @mask_bits_, to the value in
248  * @reg_: Register
249  * @mask_bits_: Mask of bits to be changed in the register, forming a field
250  * @val_: Value to set in the field denoted by @mask_bits_
251  * @...: Additional fields to override in the struct xe_rtp_action entry
252  *
253  * For masked registers this translates to a single write, while for other
254  * registers it's a RMW. The correspondent bspec notation is:
255  *
256  *	REGNAME[<end>:<start>] = VALUE
257  */
258 #define XE_RTP_FIELD_SET(reg_, mask_bits_, val_, ...)				\
259 	.action = { .reg = reg_, .clr_bits = (mask_bits_), .set_bits = (val_),\
260 		    .read_mask = (mask_bits_), ##__VA_ARGS__ }
261 
262 #define XE_RTP_FIELD_SET_NO_READ_MASK(reg_, mask_bits_, val_, ...)		\
263 	.action = { .reg = reg_, .clr_bits = (mask_bits_), .set_bits = (val_),\
264 		    .read_mask = 0, ##__VA_ARGS__ }
265 
266 /**
267  * XE_WHITELIST_REGISTER - Add register to userspace whitelist
268  * @reg_: Register
269  * @flags_: Whitelist-specific flags to set
270  * @...: Additional fields to override in the struct xe_rtp_action entry
271  *
272  * Add a register to the whitelist, allowing userspace to modify the ster with
273  * regular user privileges.
274  */
275 #define XE_WHITELIST_REGISTER(reg_, flags_, ...)				\
276 	/* TODO fail build if ((flags) & ~(RING_FORCE_TO_NONPRIV_MASK_VALID)) */\
277 	.action = { .reg = reg_, .set_bits = (flags_),			\
278 		    .clr_bits = RING_FORCE_TO_NONPRIV_MASK_VALID,		\
279 		    ##__VA_ARGS__ }
280 
281 /**
282  * XE_RTP_NAME - Helper to set the name in xe_rtp_entry
283  * @s_: Name describing this rule, often a HW-specific number
284  *
285  * TODO: maybe move this behind a debug config?
286  */
287 #define XE_RTP_NAME(s_)	.name = (s_)
288 
289 /**
290  * XE_RTP_FLAG - Helper to add multiple flags to a struct xe_rtp_action entry
291  * @f1_: Last part of a ``XE_RTP_FLAG_*``
292  * @...: Additional flags, defined like @f1_
293  *
294  * Helper to automatically add a ``XE_RTP_FLAG_`` prefix to @f1_ so it can be
295  * easily used to define struct xe_rtp_action entries. Example:
296  *
297  * .. code-block:: c
298  *
299  *	const struct xe_rtp_entry wa_entries[] = {
300  *		...
301  *		{ XE_RTP_NAME("test-entry"),
302  *		  XE_RTP_FLAG(FOREACH_ENGINE, MASKED_REG),
303  *		  ...
304  *		},
305  *		...
306  *	};
307  */
308 #define XE_RTP_FLAG(f1_, ...)							\
309 	.flags = (CALL_FOR_EACH(__ADD_XE_RTP_FLAG_PREFIX, f1_, ##__VA_ARGS__) 0)
310 
311 /**
312  * XE_RTP_RULES - Helper to set multiple rules to a struct xe_rtp_entry entry
313  * @r1: Last part of XE_RTP_MATCH_*
314  * @...: Additional rules, defined like @r1
315  *
316  * At least one rule is needed and up to 4 are supported. Multiple rules are
317  * AND'ed together, i.e. all the rules must evaluate to true for the entry to
318  * be processed. See XE_RTP_MATCH_* for the possible match rules. Example:
319  *
320  * .. code-block:: c
321  *
322  *	const struct xe_rtp_entry wa_entries[] = {
323  *		...
324  *		{ XE_RTP_NAME("test-entry"),
325  *		  XE_RTP_RULES(SUBPLATFORM(DG2, G10), STEP(A0, B0)),
326  *		  ...
327  *		},
328  *		...
329  *	};
330  */
331 #define XE_RTP_RULES(r1, ...)							\
332 	.n_rules = COUNT_ARGS(r1, ##__VA_ARGS__),				\
333 	.rules = (struct xe_rtp_rule[]) {					\
334 		CALL_FOR_EACH(__ADD_XE_RTP_RULE_PREFIX, r1, ##__VA_ARGS__)	\
335 	}
336 
337 void xe_rtp_process(const struct xe_rtp_entry *entries, struct xe_reg_sr *sr,
338 		    struct xe_gt *gt, struct xe_hw_engine *hwe);
339 
340 #endif
341