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 = >->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(®_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