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_GRAPHICS_STEP(start__, end__)				\
39	{ .match_type = XE_RTP_MATCH_GRAPHICS_STEP,				\
40	  .step_start = start__, .step_end = end__ }
41
42#define _XE_RTP_RULE_MEDIA_STEP(start__, end__)					\
43	{ .match_type = XE_RTP_MATCH_MEDIA_STEP,				\
44	  .step_start = start__, .step_end = end__ }
45
46#define _XE_RTP_RULE_ENGINE_CLASS(cls__)					\
47	{ .match_type = XE_RTP_MATCH_ENGINE_CLASS,				\
48	  .engine_class = (cls__) }
49
50/**
51 * XE_RTP_RULE_PLATFORM - Create rule matching platform
52 * @plat_: platform to match
53 *
54 * Refer to XE_RTP_RULES() for expected usage.
55 */
56#define XE_RTP_RULE_PLATFORM(plat_)						\
57	_XE_RTP_RULE_PLATFORM(XE_##plat_)
58
59/**
60 * XE_RTP_RULE_SUBPLATFORM - Create rule matching platform and sub-platform
61 * @plat_: platform to match
62 * @sub_: sub-platform to match
63 *
64 * Refer to XE_RTP_RULES() for expected usage.
65 */
66#define XE_RTP_RULE_SUBPLATFORM(plat_, sub_)					\
67	_XE_RTP_RULE_SUBPLATFORM(XE_##plat_, XE_SUBPLATFORM_##plat_##_##sub_)
68
69/**
70 * XE_RTP_RULE_GRAPHICS_STEP - Create rule matching graphics stepping
71 * @start_: First stepping matching the rule
72 * @end_: First stepping that does not match the rule
73 *
74 * Note that the range matching this rule is [ @start_, @end_ ), i.e. inclusive
75 * on the left, exclusive on the right.
76 *
77 * Refer to XE_RTP_RULES() for expected usage.
78 */
79#define XE_RTP_RULE_GRAPHICS_STEP(start_, end_)					\
80	_XE_RTP_RULE_GRAPHICS_STEP(STEP_##start_, STEP_##end_)
81
82/**
83 * XE_RTP_RULE_MEDIA_STEP - Create rule matching media stepping
84 * @start_: First stepping matching the rule
85 * @end_: First stepping that does not match the rule
86 *
87 * Note that the range matching this rule is [ @start_, @end_ ), i.e. inclusive
88 * on the left, exclusive on the right.
89 *
90 * Refer to XE_RTP_RULES() for expected usage.
91 */
92#define XE_RTP_RULE_MEDIA_STEP(start_, end_)					\
93	_XE_RTP_RULE_MEDIA_STEP(STEP_##start_, STEP_##end_)
94
95/**
96 * XE_RTP_RULE_ENGINE_CLASS - Create rule matching an engine class
97 * @cls_: Engine class to match
98 *
99 * Refer to XE_RTP_RULES() for expected usage.
100 */
101#define XE_RTP_RULE_ENGINE_CLASS(cls_)						\
102	_XE_RTP_RULE_ENGINE_CLASS(XE_ENGINE_CLASS_##cls_)
103
104/**
105 * XE_RTP_RULE_FUNC - Create rule using callback function for match
106 * @func__: Function to call to decide if rule matches
107 *
108 * This allows more complex checks to be performed. The ``XE_RTP``
109 * infrastructure will simply call the function @func_ passed to decide if this
110 * rule matches the device.
111 *
112 * Refer to XE_RTP_RULES() for expected usage.
113 */
114#define XE_RTP_RULE_FUNC(func__)						\
115	{ .match_type = XE_RTP_MATCH_FUNC,					\
116	  .match_func = (func__) }
117
118/**
119 * XE_RTP_RULE_GRAPHICS_VERSION - Create rule matching graphics version
120 * @ver__: Graphics IP version to match
121 *
122 * Refer to XE_RTP_RULES() for expected usage.
123 */
124#define XE_RTP_RULE_GRAPHICS_VERSION(ver__)					\
125	{ .match_type = XE_RTP_MATCH_GRAPHICS_VERSION,				\
126	  .ver_start = ver__, }
127
128/**
129 * XE_RTP_RULE_GRAPHICS_VERSION_RANGE - Create rule matching a range of graphics version
130 * @ver_start__: First graphics IP version to match
131 * @ver_end__: Last graphics IP version to match
132 *
133 * Note that the range matching this rule is [ @ver_start__, @ver_end__ ], i.e.
134 * inclusive on boths sides
135 *
136 * Refer to XE_RTP_RULES() for expected usage.
137 */
138#define XE_RTP_RULE_GRAPHICS_VERSION_RANGE(ver_start__, ver_end__)		\
139	{ .match_type = XE_RTP_MATCH_GRAPHICS_VERSION_RANGE,			\
140	  .ver_start = ver_start__, .ver_end = ver_end__, }
141
142/**
143 * XE_RTP_RULE_MEDIA_VERSION - Create rule matching media version
144 * @ver__: Graphics IP version to match
145 *
146 * Refer to XE_RTP_RULES() for expected usage.
147 */
148#define XE_RTP_RULE_MEDIA_VERSION(ver__)					\
149	{ .match_type = XE_RTP_MATCH_MEDIA_VERSION,				\
150	  .ver_start = ver__, }
151
152/**
153 * XE_RTP_RULE_MEDIA_VERSION_RANGE - Create rule matching a range of media version
154 * @ver_start__: First media IP version to match
155 * @ver_end__: Last media IP version to match
156 *
157 * Note that the range matching this rule is [ @ver_start__, @ver_end__ ], i.e.
158 * inclusive on boths sides
159 *
160 * Refer to XE_RTP_RULES() for expected usage.
161 */
162#define XE_RTP_RULE_MEDIA_VERSION_RANGE(ver_start__, ver_end__)			\
163	{ .match_type = XE_RTP_MATCH_MEDIA_VERSION_RANGE,			\
164	  .ver_start = ver_start__, .ver_end = ver_end__, }
165
166/**
167 * XE_RTP_RULE_IS_INTEGRATED - Create a rule matching integrated graphics devices
168 *
169 * Refer to XE_RTP_RULES() for expected usage.
170 */
171#define XE_RTP_RULE_IS_INTEGRATED						\
172	{ .match_type = XE_RTP_MATCH_INTEGRATED }
173
174/**
175 * XE_RTP_RULE_IS_DISCRETE - Create a rule matching discrete graphics devices
176 *
177 * Refer to XE_RTP_RULES() for expected usage.
178 */
179#define XE_RTP_RULE_IS_DISCRETE							\
180	{ .match_type = XE_RTP_MATCH_DISCRETE }
181
182/**
183 * XE_RTP_ACTION_WR - Helper to write a value to the register, overriding all
184 *                    the bits
185 * @reg_: Register
186 * @val_: Value to set
187 * @...: Additional fields to override in the struct xe_rtp_action entry
188 *
189 * The correspondent notation in bspec is:
190 *
191 *	REGNAME = VALUE
192 */
193#define XE_RTP_ACTION_WR(reg_, val_, ...)					\
194	{ .reg = XE_RTP_DROP_CAST(reg_),					\
195	  .clr_bits = ~0u, .set_bits = (val_),					\
196	  .read_mask = (~0u), ##__VA_ARGS__ }
197
198/**
199 * XE_RTP_ACTION_SET - Set bits from @val_ in the register.
200 * @reg_: Register
201 * @val_: Bits to set in the register
202 * @...: Additional fields to override in the struct xe_rtp_action entry
203 *
204 * For masked registers this translates to a single write, while for other
205 * registers it's a RMW. The correspondent bspec notation is (example for bits 2
206 * and 5, but could be any):
207 *
208 *	REGNAME[2] = 1
209 *	REGNAME[5] = 1
210 */
211#define XE_RTP_ACTION_SET(reg_, val_, ...)					\
212	{ .reg = XE_RTP_DROP_CAST(reg_),					\
213	  .clr_bits = val_, .set_bits = val_,					\
214	  .read_mask = val_, ##__VA_ARGS__ }
215
216/**
217 * XE_RTP_ACTION_CLR: Clear bits from @val_ in the register.
218 * @reg_: Register
219 * @val_: Bits to clear 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] = 0
227 *	REGNAME[5] = 0
228 */
229#define XE_RTP_ACTION_CLR(reg_, val_, ...)					\
230	{ .reg = XE_RTP_DROP_CAST(reg_),					\
231	  .clr_bits = val_, .set_bits = 0,					\
232	  .read_mask = val_, ##__VA_ARGS__ }
233
234/**
235 * XE_RTP_ACTION_FIELD_SET: Set a bit range
236 * @reg_: Register
237 * @mask_bits_: Mask of bits to be changed in the register, forming a field
238 * @val_: Value to set in the field denoted by @mask_bits_
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:
243 *
244 *	REGNAME[<end>:<start>] = VALUE
245 */
246#define XE_RTP_ACTION_FIELD_SET(reg_, mask_bits_, val_, ...)			\
247	{ .reg = XE_RTP_DROP_CAST(reg_),					\
248	  .clr_bits = mask_bits_, .set_bits = val_,				\
249	  .read_mask = mask_bits_, ##__VA_ARGS__ }
250
251#define XE_RTP_ACTION_FIELD_SET_NO_READ_MASK(reg_, mask_bits_, val_, ...)	\
252	{ .reg = XE_RTP_DROP_CAST(reg_),					\
253	  .clr_bits = (mask_bits_), .set_bits = (val_),				\
254	  .read_mask = 0, ##__VA_ARGS__ }
255
256/**
257 * XE_RTP_ACTION_WHITELIST - Add register to userspace whitelist
258 * @reg_: Register
259 * @val_: Whitelist-specific flags to set
260 * @...: Additional fields to override in the struct xe_rtp_action entry
261 *
262 * Add a register to the whitelist, allowing userspace to modify the ster with
263 * regular user privileges.
264 */
265#define XE_RTP_ACTION_WHITELIST(reg_, val_, ...)				\
266	/* TODO fail build if ((flags) & ~(RING_FORCE_TO_NONPRIV_MASK_VALID)) */\
267	{ .reg = XE_RTP_DROP_CAST(reg_),					\
268	  .set_bits = val_,							\
269	  .clr_bits = RING_FORCE_TO_NONPRIV_MASK_VALID,				\
270	  ##__VA_ARGS__ }
271
272/**
273 * XE_RTP_NAME - Helper to set the name in xe_rtp_entry
274 * @s_: Name describing this rule, often a HW-specific number
275 *
276 * TODO: maybe move this behind a debug config?
277 */
278#define XE_RTP_NAME(s_)	.name = (s_)
279
280/**
281 * XE_RTP_ENTRY_FLAG - Helper to add multiple flags to a struct xe_rtp_entry_sr
282 * @...: Entry flags, without the ``XE_RTP_ENTRY_FLAG_`` prefix
283 *
284 * Helper to automatically add a ``XE_RTP_ENTRY_FLAG_`` prefix to the flags
285 * when defining struct xe_rtp_entry entries. Example:
286 *
287 * .. code-block:: c
288 *
289 *	const struct xe_rtp_entry_sr wa_entries[] = {
290 *		...
291 *		{ XE_RTP_NAME("test-entry"),
292 *		  ...
293 *		  XE_RTP_ENTRY_FLAG(FOREACH_ENGINE),
294 *		  ...
295 *		},
296 *		...
297 *	};
298 */
299#define XE_RTP_ENTRY_FLAG(...)							\
300	.flags = (XE_RTP_PASTE_FOREACH(ENTRY_FLAG_, BITWISE_OR, (__VA_ARGS__)))
301
302/**
303 * XE_RTP_ACTION_FLAG - Helper to add multiple flags to a struct xe_rtp_action
304 * @...: Action flags, without the ``XE_RTP_ACTION_FLAG_`` prefix
305 *
306 * Helper to automatically add a ``XE_RTP_ACTION_FLAG_`` prefix to the flags
307 * when defining struct xe_rtp_action entries. Example:
308 *
309 * .. code-block:: c
310 *
311 *	const struct xe_rtp_entry_sr wa_entries[] = {
312 *		...
313 *		{ XE_RTP_NAME("test-entry"),
314 *		  ...
315 *		  XE_RTP_ACTION_SET(..., XE_RTP_ACTION_FLAG(FOREACH_ENGINE)),
316 *		  ...
317 *		},
318 *		...
319 *	};
320 */
321#define XE_RTP_ACTION_FLAG(...)							\
322	.flags = (XE_RTP_PASTE_FOREACH(ACTION_FLAG_, BITWISE_OR, (__VA_ARGS__)))
323
324/**
325 * XE_RTP_RULES - Helper to set multiple rules to a struct xe_rtp_entry_sr entry
326 * @...: Rules
327 *
328 * At least one rule is needed and up to 4 are supported. Multiple rules are
329 * AND'ed together, i.e. all the rules must evaluate to true for the entry to
330 * be processed. See XE_RTP_MATCH_* for the possible match rules. Example:
331 *
332 * .. code-block:: c
333 *
334 *	const struct xe_rtp_entry_sr wa_entries[] = {
335 *		...
336 *		{ XE_RTP_NAME("test-entry"),
337 *		  XE_RTP_RULES(SUBPLATFORM(DG2, G10), GRAPHICS_STEP(A0, B0)),
338 *		  ...
339 *		},
340 *		...
341 *	};
342 */
343#define XE_RTP_RULES(...)							\
344	.n_rules = _XE_COUNT_ARGS(__VA_ARGS__),					\
345	.rules = (const struct xe_rtp_rule[]) {					\
346		XE_RTP_PASTE_FOREACH(RULE_, COMMA, (__VA_ARGS__))	\
347	}
348
349/**
350 * XE_RTP_ACTIONS - Helper to set multiple actions to a struct xe_rtp_entry_sr
351 * @...: Actions to be taken
352 *
353 * At least one action is needed and up to 4 are supported. See XE_RTP_ACTION_*
354 * for the possible actions. Example:
355 *
356 * .. code-block:: c
357 *
358 *	const struct xe_rtp_entry_sr wa_entries[] = {
359 *		...
360 *		{ XE_RTP_NAME("test-entry"),
361 *		  XE_RTP_RULES(...),
362 *		  XE_RTP_ACTIONS(SET(..), SET(...), CLR(...)),
363 *		  ...
364 *		},
365 *		...
366 *	};
367 */
368#define XE_RTP_ACTIONS(...)							\
369	.n_actions = _XE_COUNT_ARGS(__VA_ARGS__),				\
370	.actions = (const struct xe_rtp_action[]) {				\
371		XE_RTP_PASTE_FOREACH(ACTION_, COMMA, (__VA_ARGS__))	\
372	}
373
374#define XE_RTP_PROCESS_CTX_INITIALIZER(arg__) _Generic((arg__),							\
375	struct xe_hw_engine * :	(struct xe_rtp_process_ctx){ { (void *)(arg__) }, XE_RTP_PROCESS_TYPE_ENGINE },	\
376	struct xe_gt * :	(struct xe_rtp_process_ctx){ { (void *)(arg__) }, XE_RTP_PROCESS_TYPE_GT })
377
378void xe_rtp_process_ctx_enable_active_tracking(struct xe_rtp_process_ctx *ctx,
379					       unsigned long *active_entries,
380					       size_t n_entries);
381
382void xe_rtp_process_to_sr(struct xe_rtp_process_ctx *ctx,
383			  const struct xe_rtp_entry_sr *entries,
384			  struct xe_reg_sr *sr);
385
386void xe_rtp_process(struct xe_rtp_process_ctx *ctx,
387		    const struct xe_rtp_entry *entries);
388
389/* Match functions to be used with XE_RTP_MATCH_FUNC */
390
391/**
392 * xe_rtp_match_even_instance - Match if engine instance is even
393 * @gt: GT structure
394 * @hwe: Engine instance
395 *
396 * Returns: true if engine instance is even, false otherwise
397 */
398bool xe_rtp_match_even_instance(const struct xe_gt *gt,
399				const struct xe_hw_engine *hwe);
400
401/*
402 * xe_rtp_match_first_render_or_compute - Match if it's first render or compute
403 * engine in the GT
404 *
405 * @gt: GT structure
406 * @hwe: Engine instance
407 *
408 * Registers on the render reset domain need to have their values re-applied
409 * when any of those engines are reset. Since the engines reset together, a
410 * programming can be set to just one of them. For simplicity the first engine
411 * of either render or compute class can be chosen.
412 *
413 * Returns: true if engine id is the first to match the render reset domain,
414 * false otherwise.
415 */
416bool xe_rtp_match_first_render_or_compute(const struct xe_gt *gt,
417					  const struct xe_hw_engine *hwe);
418
419/*
420 * xe_rtp_match_first_gslice_fused_off - Match when first gslice is fused off
421 *
422 * @gt: GT structure
423 * @hwe: Engine instance
424 *
425 * Returns: true if first gslice is fused off, false otherwise.
426 */
427bool xe_rtp_match_first_gslice_fused_off(const struct xe_gt *gt,
428					 const struct xe_hw_engine *hwe);
429
430#endif
431