xref: /linux/drivers/gpu/drm/xe/tests/xe_rtp_test.c (revision a3e50e7279996cd987001fd8a3db36e72665f8f7)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright © 2023 Intel Corporation
4  */
5 
6 #include <linux/string.h>
7 #include <linux/xarray.h>
8 
9 #include <drm/drm_drv.h>
10 #include <drm/drm_kunit_helpers.h>
11 
12 #include <kunit/static_stub.h>
13 #include <kunit/test.h>
14 
15 #include "regs/xe_gt_regs.h"
16 #include "regs/xe_reg_defs.h"
17 #include "xe_device.h"
18 #include "xe_device_types.h"
19 #include "xe_gt_mcr.h"
20 #include "xe_kunit_helpers.h"
21 #include "xe_pci_test.h"
22 #include "xe_reg_sr.h"
23 #include "xe_rtp.h"
24 
25 #define REGULAR_REG1		XE_REG(1)
26 #define REGULAR_REG2		XE_REG(2)
27 #define REGULAR_REG3		XE_REG(3)
28 #define REGULAR_REG4		XE_REG(4)
29 #define BAD_REGULAR_REG5	XE_REG(5)
30 #define MCR_REG1		XE_REG_MCR(1)
31 #define MCR_REG2		XE_REG_MCR(2)
32 #define MCR_REG3		XE_REG_MCR(3)
33 #define BAD_MCR_REG4		XE_REG_MCR(4)
34 #define MCR_REG5		XE_REG_MCR(5)
35 #define MASKED_REG1		XE_REG(1, XE_REG_OPTION_MASKED)
36 
37 #undef XE_REG_MCR
38 #define XE_REG_MCR(...)     XE_REG(__VA_ARGS__, .mcr = 1)
39 
40 struct rtp_to_sr_test_case {
41 	const char *name;
42 	struct xe_reg expected_reg;
43 	u32 expected_set_bits;
44 	u32 expected_clr_bits;
45 	unsigned long expected_count_sr_entries;
46 	unsigned int expected_sr_errors;
47 	unsigned long expected_active;
48 	const struct xe_rtp_entry_sr *entries;
49 };
50 
51 struct rtp_test_case {
52 	const char *name;
53 	unsigned long expected_active;
54 	const struct xe_rtp_entry *entries;
55 };
56 
57 static bool fake_xe_gt_mcr_check_reg(struct xe_gt *gt, struct xe_reg reg)
58 {
59 	/*
60 	 * All supported platforms in this imaginary setup will always have REG4
61 	 * as a non-MCR register and REG5 as MCR, meaning that BAD_MCR_REG4 and
62 	 * BAD_REGULAR_REG5 represent programming errors to be captured by our
63 	 * tests.
64 	 */
65 	if (reg.raw == BAD_REGULAR_REG5.raw)
66 		return true;
67 
68 	if (reg.raw == BAD_MCR_REG4.raw)
69 		return false;
70 
71 	return reg.mcr;
72 }
73 
74 static bool match_yes(const struct xe_device *xe, const struct xe_gt *gt,
75 		      const struct xe_hw_engine *hwe)
76 {
77 	return true;
78 }
79 
80 static bool match_no(const struct xe_device *xe, const struct xe_gt *gt,
81 		     const struct xe_hw_engine *hwe)
82 {
83 	return false;
84 }
85 
86 static const struct rtp_to_sr_test_case rtp_to_sr_cases[] = {
87 	{
88 		.name = "coalesce-same-reg",
89 		.expected_reg = REGULAR_REG1,
90 		.expected_set_bits = REG_BIT(0) | REG_BIT(1),
91 		.expected_clr_bits = REG_BIT(0) | REG_BIT(1),
92 		.expected_active = BIT(0) | BIT(1),
93 		.expected_count_sr_entries = 1,
94 		/* Different bits on the same register: create a single entry */
95 		.entries = (const struct xe_rtp_entry_sr[]) {
96 			{ XE_RTP_NAME("basic-1"),
97 			  XE_RTP_RULES(FUNC(match_yes)),
98 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(0)))
99 			},
100 			{ XE_RTP_NAME("basic-2"),
101 			  XE_RTP_RULES(FUNC(match_yes)),
102 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(1)))
103 			},
104 			{}
105 		},
106 	},
107 	{
108 		.name = "no-match-no-add",
109 		.expected_reg = REGULAR_REG1,
110 		.expected_set_bits = REG_BIT(0),
111 		.expected_clr_bits = REG_BIT(0),
112 		.expected_active = BIT(0),
113 		.expected_count_sr_entries = 1,
114 		/* Don't coalesce second entry since rules don't match */
115 		.entries = (const struct xe_rtp_entry_sr[]) {
116 			{ XE_RTP_NAME("basic-1"),
117 			  XE_RTP_RULES(FUNC(match_yes)),
118 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(0)))
119 			},
120 			{ XE_RTP_NAME("basic-2"),
121 			  XE_RTP_RULES(FUNC(match_no)),
122 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(1)))
123 			},
124 			{}
125 		},
126 	},
127 	{
128 		.name = "match-or",
129 		.expected_reg = REGULAR_REG1,
130 		.expected_set_bits = REG_BIT(0) | REG_BIT(1) | REG_BIT(2),
131 		.expected_clr_bits = REG_BIT(0) | REG_BIT(1) | REG_BIT(2),
132 		.expected_active = BIT(0) | BIT(1) | BIT(2),
133 		.expected_count_sr_entries = 1,
134 		.entries = (const struct xe_rtp_entry_sr[]) {
135 			{ XE_RTP_NAME("first"),
136 			  XE_RTP_RULES(FUNC(match_yes), OR, FUNC(match_no)),
137 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(0)))
138 			},
139 			{ XE_RTP_NAME("middle"),
140 			  XE_RTP_RULES(FUNC(match_no), FUNC(match_no), OR,
141 				       FUNC(match_yes), OR,
142 				       FUNC(match_no)),
143 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(1)))
144 			},
145 			{ XE_RTP_NAME("last"),
146 			  XE_RTP_RULES(FUNC(match_no), OR, FUNC(match_yes)),
147 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(2)))
148 			},
149 			{ XE_RTP_NAME("no-match"),
150 			  XE_RTP_RULES(FUNC(match_no), OR, FUNC(match_no)),
151 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(3)))
152 			},
153 			{}
154 		},
155 	},
156 	{
157 		.name = "match-or-xfail",
158 		.expected_reg = REGULAR_REG1,
159 		.expected_count_sr_entries = 0,
160 		.entries = (const struct xe_rtp_entry_sr[]) {
161 			{ XE_RTP_NAME("leading-or"),
162 			  XE_RTP_RULES(OR, FUNC(match_yes)),
163 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(0)))
164 			},
165 			{ XE_RTP_NAME("trailing-or"),
166 			  /*
167 			   * First condition is match_no, otherwise the failure
168 			   * wouldn't really trigger as RTP stops processing as
169 			   * soon as it has a matching set of rules
170 			   */
171 			  XE_RTP_RULES(FUNC(match_no), OR),
172 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(1)))
173 			},
174 			{ XE_RTP_NAME("no-or-or-yes"),
175 			  XE_RTP_RULES(FUNC(match_no), OR, OR, FUNC(match_yes)),
176 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(2)))
177 			},
178 			{}
179 		},
180 	},
181 	{
182 		.name = "no-match-no-add-multiple-rules",
183 		.expected_reg = REGULAR_REG1,
184 		.expected_set_bits = REG_BIT(0),
185 		.expected_clr_bits = REG_BIT(0),
186 		.expected_active = BIT(0),
187 		.expected_count_sr_entries = 1,
188 		/* Don't coalesce second entry due to one of the rules */
189 		.entries = (const struct xe_rtp_entry_sr[]) {
190 			{ XE_RTP_NAME("basic-1"),
191 			  XE_RTP_RULES(FUNC(match_yes)),
192 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(0)))
193 			},
194 			{ XE_RTP_NAME("basic-2"),
195 			  XE_RTP_RULES(FUNC(match_yes), FUNC(match_no)),
196 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(1)))
197 			},
198 			{}
199 		},
200 	},
201 	{
202 		.name = "two-regs-two-entries",
203 		.expected_reg = REGULAR_REG1,
204 		.expected_set_bits = REG_BIT(0),
205 		.expected_clr_bits = REG_BIT(0),
206 		.expected_active = BIT(0) | BIT(1),
207 		.expected_count_sr_entries = 2,
208 		/* Same bits on different registers are not coalesced */
209 		.entries = (const struct xe_rtp_entry_sr[]) {
210 			{ XE_RTP_NAME("basic-1"),
211 			  XE_RTP_RULES(FUNC(match_yes)),
212 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(0)))
213 			},
214 			{ XE_RTP_NAME("basic-2"),
215 			  XE_RTP_RULES(FUNC(match_yes)),
216 			  XE_RTP_ACTIONS(SET(REGULAR_REG2, REG_BIT(0)))
217 			},
218 			{}
219 		},
220 	},
221 	{
222 		.name = "clr-one-set-other",
223 		.expected_reg = REGULAR_REG1,
224 		.expected_set_bits = REG_BIT(0),
225 		.expected_clr_bits = REG_BIT(1) | REG_BIT(0),
226 		.expected_active = BIT(0) | BIT(1),
227 		.expected_count_sr_entries = 1,
228 		/* Check clr vs set actions on different bits */
229 		.entries = (const struct xe_rtp_entry_sr[]) {
230 			{ XE_RTP_NAME("basic-1"),
231 			  XE_RTP_RULES(FUNC(match_yes)),
232 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(0)))
233 			},
234 			{ XE_RTP_NAME("basic-2"),
235 			  XE_RTP_RULES(FUNC(match_yes)),
236 			  XE_RTP_ACTIONS(CLR(REGULAR_REG1, REG_BIT(1)))
237 			},
238 			{}
239 		},
240 	},
241 	{
242 #define TEMP_MASK	REG_GENMASK(10, 8)
243 #define TEMP_FIELD	REG_FIELD_PREP(TEMP_MASK, 2)
244 		.name = "set-field",
245 		.expected_reg = REGULAR_REG1,
246 		.expected_set_bits = TEMP_FIELD,
247 		.expected_clr_bits = TEMP_MASK,
248 		.expected_active = BIT(0),
249 		.expected_count_sr_entries = 1,
250 		/* Check FIELD_SET works */
251 		.entries = (const struct xe_rtp_entry_sr[]) {
252 			{ XE_RTP_NAME("basic-1"),
253 			  XE_RTP_RULES(FUNC(match_yes)),
254 			  XE_RTP_ACTIONS(FIELD_SET(REGULAR_REG1,
255 						   TEMP_MASK, TEMP_FIELD))
256 			},
257 			{}
258 		},
259 #undef TEMP_MASK
260 #undef TEMP_FIELD
261 	},
262 	{
263 		.name = "conflict-duplicate",
264 		.expected_reg = REGULAR_REG1,
265 		.expected_set_bits = REG_BIT(0),
266 		.expected_clr_bits = REG_BIT(0),
267 		.expected_active = BIT(0) | BIT(1),
268 		.expected_count_sr_entries = 1,
269 		.expected_sr_errors = 1,
270 		.entries = (const struct xe_rtp_entry_sr[]) {
271 			{ XE_RTP_NAME("basic-1"),
272 			  XE_RTP_RULES(FUNC(match_yes)),
273 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(0)))
274 			},
275 			/* drop: setting same values twice */
276 			{ XE_RTP_NAME("basic-2"),
277 			  XE_RTP_RULES(FUNC(match_yes)),
278 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(0)))
279 			},
280 			{}
281 		},
282 	},
283 	{
284 		.name = "conflict-not-disjoint",
285 		.expected_reg = REGULAR_REG1,
286 		.expected_set_bits = REG_BIT(0),
287 		.expected_clr_bits = REG_BIT(0),
288 		.expected_active = BIT(0) | BIT(1),
289 		.expected_count_sr_entries = 1,
290 		.expected_sr_errors = 1,
291 		.entries = (const struct xe_rtp_entry_sr[]) {
292 			{ XE_RTP_NAME("basic-1"),
293 			  XE_RTP_RULES(FUNC(match_yes)),
294 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(0)))
295 			},
296 			/* drop: bits are not disjoint with previous entries */
297 			{ XE_RTP_NAME("basic-2"),
298 			  XE_RTP_RULES(FUNC(match_yes)),
299 			  XE_RTP_ACTIONS(CLR(REGULAR_REG1, REG_GENMASK(1, 0)))
300 			},
301 			{}
302 		},
303 	},
304 	{
305 		.name = "conflict-reg-type",
306 		.expected_reg = REGULAR_REG1,
307 		.expected_set_bits = REG_BIT(0),
308 		.expected_clr_bits = REG_BIT(0),
309 		.expected_active = BIT(0) | BIT(1) | BIT(2),
310 		.expected_count_sr_entries = 1,
311 		.expected_sr_errors = 2,
312 		.entries = (const struct xe_rtp_entry_sr[]) {
313 			{ XE_RTP_NAME("basic-1"),
314 			  XE_RTP_RULES(FUNC(match_yes)),
315 			  XE_RTP_ACTIONS(SET(REGULAR_REG1, REG_BIT(0)))
316 			},
317 			/* drop: regular vs MCR */
318 			{ XE_RTP_NAME("basic-2"),
319 			  XE_RTP_RULES(FUNC(match_yes)),
320 			  XE_RTP_ACTIONS(SET(MCR_REG1, REG_BIT(1)))
321 			},
322 			/* drop: regular vs masked */
323 			{ XE_RTP_NAME("basic-3"),
324 			  XE_RTP_RULES(FUNC(match_yes)),
325 			  XE_RTP_ACTIONS(SET(MASKED_REG1, REG_BIT(0)))
326 			},
327 			{}
328 		},
329 	},
330 	{
331 		.name = "bad-mcr-reg-forced-to-regular",
332 		.expected_reg = REGULAR_REG4,
333 		.expected_set_bits = REG_BIT(0),
334 		.expected_clr_bits = REG_BIT(0),
335 		.expected_active = BIT(0),
336 		.expected_count_sr_entries = 1,
337 		.expected_sr_errors = 1,
338 		.entries = (const struct xe_rtp_entry_sr[]) {
339 			{ XE_RTP_NAME("bad-mcr-regular-reg"),
340 			  XE_RTP_RULES(FUNC(match_yes)),
341 			  XE_RTP_ACTIONS(SET(BAD_MCR_REG4, REG_BIT(0)))
342 			},
343 			{}
344 		},
345 	},
346 	{
347 		.name = "bad-regular-reg-forced-to-mcr",
348 		.expected_reg = MCR_REG5,
349 		.expected_set_bits = REG_BIT(0),
350 		.expected_clr_bits = REG_BIT(0),
351 		.expected_active = BIT(0),
352 		.expected_count_sr_entries = 1,
353 		.expected_sr_errors = 1,
354 		.entries = (const struct xe_rtp_entry_sr[]) {
355 			{ XE_RTP_NAME("bad-regular-reg"),
356 			  XE_RTP_RULES(FUNC(match_yes)),
357 			  XE_RTP_ACTIONS(SET(BAD_REGULAR_REG5, REG_BIT(0)))
358 			},
359 			{}
360 		},
361 	},
362 };
363 
364 static void xe_rtp_process_to_sr_tests(struct kunit *test)
365 {
366 	const struct rtp_to_sr_test_case *param = test->param_value;
367 	struct xe_device *xe = test->priv;
368 	struct xe_gt *gt = xe_device_get_root_tile(xe)->primary_gt;
369 	struct xe_reg_sr *reg_sr = &gt->reg_sr;
370 	const struct xe_reg_sr_entry *sre, *sr_entry = NULL;
371 	struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(gt);
372 	unsigned long idx, count_sr_entries = 0, count_rtp_entries = 0, active = 0;
373 
374 	xe_reg_sr_init(reg_sr, "xe_rtp_to_sr_tests", xe);
375 
376 	while (param->entries[count_rtp_entries].rules)
377 		count_rtp_entries++;
378 
379 	xe_rtp_process_ctx_enable_active_tracking(&ctx, &active, count_rtp_entries);
380 	xe_rtp_process_to_sr(&ctx, param->entries, count_rtp_entries,
381 			     reg_sr, false);
382 
383 	xa_for_each(&reg_sr->xa, idx, sre) {
384 		if (idx == param->expected_reg.addr)
385 			sr_entry = sre;
386 
387 		count_sr_entries++;
388 	}
389 
390 	KUNIT_EXPECT_EQ(test, active, param->expected_active);
391 
392 	KUNIT_EXPECT_EQ(test, count_sr_entries, param->expected_count_sr_entries);
393 	if (count_sr_entries) {
394 		KUNIT_EXPECT_EQ(test, sr_entry->clr_bits, param->expected_clr_bits);
395 		KUNIT_EXPECT_EQ(test, sr_entry->set_bits, param->expected_set_bits);
396 		KUNIT_EXPECT_EQ(test, sr_entry->reg.raw, param->expected_reg.raw);
397 	} else {
398 		KUNIT_EXPECT_NULL(test, sr_entry);
399 	}
400 
401 	KUNIT_EXPECT_EQ(test, reg_sr->errors, param->expected_sr_errors);
402 }
403 
404 /*
405  * Entries below follow the logic used with xe_wa_oob.rules:
406  * 1) Entries with empty name are OR'ed: all entries marked active since the
407  *    last entry with a name
408  * 2) There are no action associated with rules
409  */
410 static const struct rtp_test_case rtp_cases[] = {
411 	{
412 		.name = "active1",
413 		.expected_active = BIT(0),
414 		.entries = (const struct xe_rtp_entry[]) {
415 			{ XE_RTP_NAME("r1"),
416 			  XE_RTP_RULES(FUNC(match_yes)),
417 			},
418 			{}
419 		},
420 	},
421 	{
422 		.name = "active2",
423 		.expected_active = BIT(0) | BIT(1),
424 		.entries = (const struct xe_rtp_entry[]) {
425 			{ XE_RTP_NAME("r1"),
426 			  XE_RTP_RULES(FUNC(match_yes)),
427 			},
428 			{ XE_RTP_NAME("r2"),
429 			  XE_RTP_RULES(FUNC(match_yes)),
430 			},
431 			{}
432 		},
433 	},
434 	{
435 		.name = "active-inactive",
436 		.expected_active = BIT(0),
437 		.entries = (const struct xe_rtp_entry[]) {
438 			{ XE_RTP_NAME("r1"),
439 			  XE_RTP_RULES(FUNC(match_yes)),
440 			},
441 			{ XE_RTP_NAME("r2"),
442 			  XE_RTP_RULES(FUNC(match_no)),
443 			},
444 			{}
445 		},
446 	},
447 	{
448 		.name = "inactive-active",
449 		.expected_active = BIT(1),
450 		.entries = (const struct xe_rtp_entry[]) {
451 			{ XE_RTP_NAME("r1"),
452 			  XE_RTP_RULES(FUNC(match_no)),
453 			},
454 			{ XE_RTP_NAME("r2"),
455 			  XE_RTP_RULES(FUNC(match_yes)),
456 			},
457 			{}
458 		},
459 	},
460 	{
461 		.name = "inactive-1st_or_active-inactive",
462 		.expected_active = BIT(1),
463 		.entries = (const struct xe_rtp_entry[]) {
464 			{ XE_RTP_NAME("r1"),
465 			  XE_RTP_RULES(FUNC(match_no)),
466 			},
467 			{ XE_RTP_NAME("r2_or_conditions"),
468 			  XE_RTP_RULES(FUNC(match_yes), OR,
469 				       FUNC(match_no), OR,
470 				       FUNC(match_no)) },
471 			{ XE_RTP_NAME("r3"),
472 			  XE_RTP_RULES(FUNC(match_no)),
473 			},
474 			{}
475 		},
476 	},
477 	{
478 		.name = "inactive-2nd_or_active-inactive",
479 		.expected_active = BIT(1),
480 		.entries = (const struct xe_rtp_entry[]) {
481 			{ XE_RTP_NAME("r1"),
482 			  XE_RTP_RULES(FUNC(match_no)),
483 			},
484 			{ XE_RTP_NAME("r2_or_conditions"),
485 			  XE_RTP_RULES(FUNC(match_no), OR,
486 				       FUNC(match_yes), OR,
487 				       FUNC(match_no)) },
488 			{ XE_RTP_NAME("r3"),
489 			  XE_RTP_RULES(FUNC(match_no)),
490 			},
491 			{}
492 		},
493 	},
494 	{
495 		.name = "inactive-last_or_active-inactive",
496 		.expected_active = BIT(1),
497 		.entries = (const struct xe_rtp_entry[]) {
498 			{ XE_RTP_NAME("r1"),
499 			  XE_RTP_RULES(FUNC(match_no)),
500 			},
501 			{ XE_RTP_NAME("r2_or_conditions"),
502 			  XE_RTP_RULES(FUNC(match_no), OR,
503 				       FUNC(match_no), OR,
504 				       FUNC(match_yes)) },
505 			{ XE_RTP_NAME("r3"),
506 			  XE_RTP_RULES(FUNC(match_no)),
507 			},
508 			{}
509 		},
510 	},
511 	{
512 		.name = "inactive-no_or_active-inactive",
513 		.expected_active = 0,
514 		.entries = (const struct xe_rtp_entry[]) {
515 			{ XE_RTP_NAME("r1"),
516 			  XE_RTP_RULES(FUNC(match_no)),
517 			},
518 			{ XE_RTP_NAME("r2_or_conditions"),
519 			  XE_RTP_RULES(FUNC(match_no), OR,
520 				       FUNC(match_no), OR,
521 				       FUNC(match_no)) },
522 			{ XE_RTP_NAME("r3"),
523 			  XE_RTP_RULES(FUNC(match_no)),
524 			},
525 			{}
526 		},
527 	},
528 };
529 
530 static void xe_rtp_process_tests(struct kunit *test)
531 {
532 	const struct rtp_test_case *param = test->param_value;
533 	struct xe_device *xe = test->priv;
534 	struct xe_gt *gt = xe_device_get_root_tile(xe)->primary_gt;
535 	struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(gt);
536 	unsigned long count_rtp_entries = 0, active = 0;
537 
538 	while (param->entries[count_rtp_entries].rules)
539 		count_rtp_entries++;
540 
541 	xe_rtp_process_ctx_enable_active_tracking(&ctx, &active, count_rtp_entries);
542 	xe_rtp_process(&ctx, param->entries);
543 
544 	KUNIT_EXPECT_EQ(test, active, param->expected_active);
545 }
546 
547 static void rtp_to_sr_desc(const struct rtp_to_sr_test_case *t, char *desc)
548 {
549 	strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
550 }
551 
552 KUNIT_ARRAY_PARAM(rtp_to_sr, rtp_to_sr_cases, rtp_to_sr_desc);
553 
554 static void rtp_desc(const struct rtp_test_case *t, char *desc)
555 {
556 	strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
557 }
558 
559 KUNIT_ARRAY_PARAM(rtp, rtp_cases, rtp_desc);
560 
561 static int xe_rtp_test_init(struct kunit *test)
562 {
563 	struct xe_device *xe;
564 	struct device *dev;
565 	int ret;
566 
567 	dev = drm_kunit_helper_alloc_device(test);
568 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
569 
570 	xe = xe_kunit_helper_alloc_xe_device(test, dev);
571 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xe);
572 
573 	/* Initialize an empty device */
574 	test->priv = NULL;
575 	ret = xe_pci_fake_device_init(xe);
576 	KUNIT_ASSERT_EQ(test, ret, 0);
577 
578 	xe->drm.dev = dev;
579 	test->priv = xe;
580 
581 	kunit_activate_static_stub(test, xe_gt_mcr_check_reg, fake_xe_gt_mcr_check_reg);
582 
583 	return 0;
584 }
585 
586 static void xe_rtp_test_exit(struct kunit *test)
587 {
588 	struct xe_device *xe = test->priv;
589 
590 	drm_kunit_helper_free_device(test, xe->drm.dev);
591 }
592 
593 static struct kunit_case xe_rtp_tests[] = {
594 	KUNIT_CASE_PARAM(xe_rtp_process_to_sr_tests, rtp_to_sr_gen_params),
595 	KUNIT_CASE_PARAM(xe_rtp_process_tests, rtp_gen_params),
596 	{}
597 };
598 
599 static struct kunit_suite xe_rtp_test_suite = {
600 	.name = "xe_rtp",
601 	.init = xe_rtp_test_init,
602 	.exit = xe_rtp_test_exit,
603 	.test_cases = xe_rtp_tests,
604 };
605 
606 kunit_test_suite(xe_rtp_test_suite);
607