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