1 // SPDX-License-Identifier: GPL-2.0+ 2 3 #include <kunit/test.h> 4 5 #include "../vkms_config.h" 6 7 MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); 8 9 static size_t vkms_config_get_num_planes(struct vkms_config *config) 10 { 11 struct vkms_config_plane *plane_cfg; 12 size_t count = 0; 13 14 vkms_config_for_each_plane(config, plane_cfg) 15 count++; 16 17 return count; 18 } 19 20 static size_t vkms_config_get_num_encoders(struct vkms_config *config) 21 { 22 struct vkms_config_encoder *encoder_cfg; 23 size_t count = 0; 24 25 vkms_config_for_each_encoder(config, encoder_cfg) 26 count++; 27 28 return count; 29 } 30 31 static size_t vkms_config_get_num_connectors(struct vkms_config *config) 32 { 33 struct vkms_config_connector *connector_cfg; 34 size_t count = 0; 35 36 vkms_config_for_each_connector(config, connector_cfg) 37 count++; 38 39 return count; 40 } 41 42 static struct vkms_config_plane *get_first_plane(struct vkms_config *config) 43 { 44 struct vkms_config_plane *plane_cfg; 45 46 vkms_config_for_each_plane(config, plane_cfg) 47 return plane_cfg; 48 49 return NULL; 50 } 51 52 static struct vkms_config_crtc *get_first_crtc(struct vkms_config *config) 53 { 54 struct vkms_config_crtc *crtc_cfg; 55 56 vkms_config_for_each_crtc(config, crtc_cfg) 57 return crtc_cfg; 58 59 return NULL; 60 } 61 62 static struct vkms_config_encoder *get_first_encoder(struct vkms_config *config) 63 { 64 struct vkms_config_encoder *encoder_cfg; 65 66 vkms_config_for_each_encoder(config, encoder_cfg) 67 return encoder_cfg; 68 69 return NULL; 70 } 71 72 static struct vkms_config_connector *get_first_connector(struct vkms_config *config) 73 { 74 struct vkms_config_connector *connector_cfg; 75 76 vkms_config_for_each_connector(config, connector_cfg) 77 return connector_cfg; 78 79 return NULL; 80 } 81 82 struct default_config_case { 83 bool enable_cursor; 84 bool enable_writeback; 85 bool enable_overlay; 86 }; 87 88 static void vkms_config_test_empty_config(struct kunit *test) 89 { 90 struct vkms_config *config; 91 const char *dev_name = "test"; 92 93 config = vkms_config_create(dev_name); 94 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 95 96 /* The dev_name string and the config have different lifetimes */ 97 dev_name = NULL; 98 KUNIT_EXPECT_STREQ(test, vkms_config_get_device_name(config), "test"); 99 100 KUNIT_EXPECT_EQ(test, vkms_config_get_num_planes(config), 0); 101 KUNIT_EXPECT_EQ(test, vkms_config_get_num_crtcs(config), 0); 102 KUNIT_EXPECT_EQ(test, vkms_config_get_num_encoders(config), 0); 103 KUNIT_EXPECT_EQ(test, vkms_config_get_num_connectors(config), 0); 104 105 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 106 107 vkms_config_destroy(config); 108 } 109 110 static struct default_config_case default_config_cases[] = { 111 { false, false, false }, 112 { true, false, false }, 113 { true, true, false }, 114 { true, false, true }, 115 { false, true, false }, 116 { false, true, true }, 117 { false, false, true }, 118 { true, true, true }, 119 }; 120 121 KUNIT_ARRAY_PARAM(default_config, default_config_cases, NULL); 122 123 static void vkms_config_test_default_config(struct kunit *test) 124 { 125 const struct default_config_case *params = test->param_value; 126 struct vkms_config *config; 127 struct vkms_config_plane *plane_cfg; 128 struct vkms_config_crtc *crtc_cfg; 129 int n_primaries = 0; 130 int n_cursors = 0; 131 int n_overlays = 0; 132 133 config = vkms_config_default_create(params->enable_cursor, 134 params->enable_writeback, 135 params->enable_overlay); 136 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 137 138 /* Planes */ 139 vkms_config_for_each_plane(config, plane_cfg) { 140 switch (vkms_config_plane_get_type(plane_cfg)) { 141 case DRM_PLANE_TYPE_PRIMARY: 142 n_primaries++; 143 break; 144 case DRM_PLANE_TYPE_CURSOR: 145 n_cursors++; 146 break; 147 case DRM_PLANE_TYPE_OVERLAY: 148 n_overlays++; 149 break; 150 default: 151 KUNIT_FAIL_AND_ABORT(test, "Unknown plane type"); 152 } 153 } 154 KUNIT_EXPECT_EQ(test, n_primaries, 1); 155 KUNIT_EXPECT_EQ(test, n_cursors, params->enable_cursor ? 1 : 0); 156 KUNIT_EXPECT_EQ(test, n_overlays, params->enable_overlay ? 8 : 0); 157 158 /* CRTCs */ 159 KUNIT_EXPECT_EQ(test, vkms_config_get_num_crtcs(config), 1); 160 161 crtc_cfg = get_first_crtc(config); 162 KUNIT_EXPECT_EQ(test, vkms_config_crtc_get_writeback(crtc_cfg), 163 params->enable_writeback); 164 165 vkms_config_for_each_plane(config, plane_cfg) { 166 struct vkms_config_crtc *possible_crtc; 167 int n_possible_crtcs = 0; 168 unsigned long idx = 0; 169 170 vkms_config_plane_for_each_possible_crtc(plane_cfg, idx, possible_crtc) { 171 KUNIT_EXPECT_PTR_EQ(test, crtc_cfg, possible_crtc); 172 n_possible_crtcs++; 173 } 174 KUNIT_EXPECT_EQ(test, n_possible_crtcs, 1); 175 } 176 177 /* Encoders */ 178 KUNIT_EXPECT_EQ(test, vkms_config_get_num_encoders(config), 1); 179 180 /* Connectors */ 181 KUNIT_EXPECT_EQ(test, vkms_config_get_num_connectors(config), 1); 182 183 KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); 184 185 vkms_config_destroy(config); 186 } 187 188 static void vkms_config_test_get_planes(struct kunit *test) 189 { 190 struct vkms_config *config; 191 struct vkms_config_plane *plane_cfg; 192 struct vkms_config_plane *plane_cfg1, *plane_cfg2; 193 int n_planes = 0; 194 195 config = vkms_config_create("test"); 196 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 197 198 vkms_config_for_each_plane(config, plane_cfg) 199 n_planes++; 200 KUNIT_ASSERT_EQ(test, n_planes, 0); 201 202 plane_cfg1 = vkms_config_create_plane(config); 203 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg1); 204 vkms_config_for_each_plane(config, plane_cfg) { 205 n_planes++; 206 if (plane_cfg != plane_cfg1) 207 KUNIT_FAIL(test, "Unexpected plane"); 208 } 209 KUNIT_ASSERT_EQ(test, n_planes, 1); 210 n_planes = 0; 211 212 plane_cfg2 = vkms_config_create_plane(config); 213 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg2); 214 vkms_config_for_each_plane(config, plane_cfg) { 215 n_planes++; 216 if (plane_cfg != plane_cfg1 && plane_cfg != plane_cfg2) 217 KUNIT_FAIL(test, "Unexpected plane"); 218 } 219 KUNIT_ASSERT_EQ(test, n_planes, 2); 220 n_planes = 0; 221 222 vkms_config_destroy_plane(plane_cfg1); 223 vkms_config_for_each_plane(config, plane_cfg) { 224 n_planes++; 225 if (plane_cfg != plane_cfg2) 226 KUNIT_FAIL(test, "Unexpected plane"); 227 } 228 KUNIT_ASSERT_EQ(test, n_planes, 1); 229 230 vkms_config_destroy(config); 231 } 232 233 static void vkms_config_test_get_crtcs(struct kunit *test) 234 { 235 struct vkms_config *config; 236 struct vkms_config_crtc *crtc_cfg; 237 struct vkms_config_crtc *crtc_cfg1, *crtc_cfg2; 238 239 config = vkms_config_create("test"); 240 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 241 242 KUNIT_ASSERT_EQ(test, vkms_config_get_num_crtcs(config), 0); 243 vkms_config_for_each_crtc(config, crtc_cfg) 244 KUNIT_FAIL(test, "Unexpected CRTC"); 245 246 crtc_cfg1 = vkms_config_create_crtc(config); 247 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg1); 248 KUNIT_ASSERT_EQ(test, vkms_config_get_num_crtcs(config), 1); 249 vkms_config_for_each_crtc(config, crtc_cfg) { 250 if (crtc_cfg != crtc_cfg1) 251 KUNIT_FAIL(test, "Unexpected CRTC"); 252 } 253 254 crtc_cfg2 = vkms_config_create_crtc(config); 255 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg2); 256 KUNIT_ASSERT_EQ(test, vkms_config_get_num_crtcs(config), 2); 257 vkms_config_for_each_crtc(config, crtc_cfg) { 258 if (crtc_cfg != crtc_cfg1 && crtc_cfg != crtc_cfg2) 259 KUNIT_FAIL(test, "Unexpected CRTC"); 260 } 261 262 vkms_config_destroy_crtc(config, crtc_cfg2); 263 KUNIT_ASSERT_EQ(test, vkms_config_get_num_crtcs(config), 1); 264 vkms_config_for_each_crtc(config, crtc_cfg) { 265 if (crtc_cfg != crtc_cfg1) 266 KUNIT_FAIL(test, "Unexpected CRTC"); 267 } 268 269 vkms_config_destroy(config); 270 } 271 272 static void vkms_config_test_get_encoders(struct kunit *test) 273 { 274 struct vkms_config *config; 275 struct vkms_config_encoder *encoder_cfg; 276 struct vkms_config_encoder *encoder_cfg1, *encoder_cfg2; 277 int n_encoders = 0; 278 279 config = vkms_config_create("test"); 280 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 281 282 vkms_config_for_each_encoder(config, encoder_cfg) 283 n_encoders++; 284 KUNIT_ASSERT_EQ(test, n_encoders, 0); 285 286 encoder_cfg1 = vkms_config_create_encoder(config); 287 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg1); 288 vkms_config_for_each_encoder(config, encoder_cfg) { 289 n_encoders++; 290 if (encoder_cfg != encoder_cfg1) 291 KUNIT_FAIL(test, "Unexpected encoder"); 292 } 293 KUNIT_ASSERT_EQ(test, n_encoders, 1); 294 n_encoders = 0; 295 296 encoder_cfg2 = vkms_config_create_encoder(config); 297 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg2); 298 vkms_config_for_each_encoder(config, encoder_cfg) { 299 n_encoders++; 300 if (encoder_cfg != encoder_cfg1 && encoder_cfg != encoder_cfg2) 301 KUNIT_FAIL(test, "Unexpected encoder"); 302 } 303 KUNIT_ASSERT_EQ(test, n_encoders, 2); 304 n_encoders = 0; 305 306 vkms_config_destroy_encoder(config, encoder_cfg2); 307 vkms_config_for_each_encoder(config, encoder_cfg) { 308 n_encoders++; 309 if (encoder_cfg != encoder_cfg1) 310 KUNIT_FAIL(test, "Unexpected encoder"); 311 } 312 KUNIT_ASSERT_EQ(test, n_encoders, 1); 313 n_encoders = 0; 314 315 vkms_config_destroy(config); 316 } 317 318 static void vkms_config_test_get_connectors(struct kunit *test) 319 { 320 struct vkms_config *config; 321 struct vkms_config_connector *connector_cfg; 322 struct vkms_config_connector *connector_cfg1, *connector_cfg2; 323 int n_connectors = 0; 324 325 config = vkms_config_create("test"); 326 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 327 328 vkms_config_for_each_connector(config, connector_cfg) 329 n_connectors++; 330 KUNIT_ASSERT_EQ(test, n_connectors, 0); 331 332 connector_cfg1 = vkms_config_create_connector(config); 333 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector_cfg1); 334 vkms_config_for_each_connector(config, connector_cfg) { 335 n_connectors++; 336 if (connector_cfg != connector_cfg1) 337 KUNIT_FAIL(test, "Unexpected connector"); 338 } 339 KUNIT_ASSERT_EQ(test, n_connectors, 1); 340 n_connectors = 0; 341 342 connector_cfg2 = vkms_config_create_connector(config); 343 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector_cfg2); 344 vkms_config_for_each_connector(config, connector_cfg) { 345 n_connectors++; 346 if (connector_cfg != connector_cfg1 && 347 connector_cfg != connector_cfg2) 348 KUNIT_FAIL(test, "Unexpected connector"); 349 } 350 KUNIT_ASSERT_EQ(test, n_connectors, 2); 351 n_connectors = 0; 352 353 vkms_config_destroy_connector(connector_cfg2); 354 vkms_config_for_each_connector(config, connector_cfg) { 355 n_connectors++; 356 if (connector_cfg != connector_cfg1) 357 KUNIT_FAIL(test, "Unexpected connector"); 358 } 359 KUNIT_ASSERT_EQ(test, n_connectors, 1); 360 n_connectors = 0; 361 362 vkms_config_destroy(config); 363 } 364 365 static void vkms_config_test_invalid_plane_number(struct kunit *test) 366 { 367 struct vkms_config *config; 368 struct vkms_config_plane *plane_cfg; 369 int n; 370 371 config = vkms_config_default_create(false, false, false); 372 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 373 374 /* Invalid: No planes */ 375 plane_cfg = get_first_plane(config); 376 vkms_config_destroy_plane(plane_cfg); 377 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 378 379 /* Invalid: Too many planes */ 380 for (n = 0; n <= 32; n++) 381 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vkms_config_create_plane(config)); 382 383 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 384 385 vkms_config_destroy(config); 386 } 387 388 static void vkms_config_test_valid_plane_type(struct kunit *test) 389 { 390 struct vkms_config *config; 391 struct vkms_config_plane *plane_cfg; 392 struct vkms_config_crtc *crtc_cfg; 393 struct vkms_config_encoder *encoder_cfg; 394 int err; 395 396 config = vkms_config_default_create(false, false, false); 397 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 398 399 plane_cfg = get_first_plane(config); 400 vkms_config_destroy_plane(plane_cfg); 401 402 crtc_cfg = get_first_crtc(config); 403 404 /* Invalid: No primary plane */ 405 plane_cfg = vkms_config_create_plane(config); 406 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg); 407 vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_OVERLAY); 408 err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); 409 KUNIT_EXPECT_EQ(test, err, 0); 410 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 411 412 /* Invalid: Multiple primary planes */ 413 plane_cfg = vkms_config_create_plane(config); 414 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg); 415 vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); 416 err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); 417 KUNIT_EXPECT_EQ(test, err, 0); 418 419 plane_cfg = vkms_config_create_plane(config); 420 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg); 421 vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); 422 err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); 423 KUNIT_EXPECT_EQ(test, err, 0); 424 425 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 426 427 /* Valid: One primary plane */ 428 vkms_config_destroy_plane(plane_cfg); 429 KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); 430 431 /* Invalid: Multiple cursor planes */ 432 plane_cfg = vkms_config_create_plane(config); 433 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg); 434 vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); 435 err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); 436 KUNIT_EXPECT_EQ(test, err, 0); 437 438 plane_cfg = vkms_config_create_plane(config); 439 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg); 440 vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_CURSOR); 441 err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); 442 KUNIT_EXPECT_EQ(test, err, 0); 443 444 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 445 446 /* Valid: One primary and one cursor plane */ 447 vkms_config_destroy_plane(plane_cfg); 448 KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); 449 450 /* Invalid: Second CRTC without primary plane */ 451 crtc_cfg = vkms_config_create_crtc(config); 452 encoder_cfg = vkms_config_create_encoder(config); 453 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg); 454 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg); 455 456 err = vkms_config_encoder_attach_crtc(encoder_cfg, crtc_cfg); 457 KUNIT_EXPECT_EQ(test, err, 0); 458 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 459 460 /* Valid: Second CRTC with a primary plane */ 461 plane_cfg = vkms_config_create_plane(config); 462 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg); 463 vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); 464 err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg); 465 KUNIT_EXPECT_EQ(test, err, 0); 466 KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); 467 468 vkms_config_destroy(config); 469 } 470 471 static void vkms_config_test_valid_plane_possible_crtcs(struct kunit *test) 472 { 473 struct vkms_config *config; 474 struct vkms_config_plane *plane_cfg; 475 struct vkms_config_crtc *crtc_cfg; 476 477 config = vkms_config_default_create(false, false, false); 478 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 479 480 plane_cfg = get_first_plane(config); 481 crtc_cfg = get_first_crtc(config); 482 483 /* Invalid: Primary plane without a possible CRTC */ 484 vkms_config_plane_detach_crtc(plane_cfg, crtc_cfg); 485 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 486 487 vkms_config_destroy(config); 488 } 489 490 static void vkms_config_test_invalid_crtc_number(struct kunit *test) 491 { 492 struct vkms_config *config; 493 struct vkms_config_crtc *crtc_cfg; 494 int n; 495 496 config = vkms_config_default_create(false, false, false); 497 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 498 499 /* Invalid: No CRTCs */ 500 crtc_cfg = get_first_crtc(config); 501 vkms_config_destroy_crtc(config, crtc_cfg); 502 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 503 504 /* Invalid: Too many CRTCs */ 505 for (n = 0; n <= 32; n++) 506 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vkms_config_create_crtc(config)); 507 508 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 509 510 vkms_config_destroy(config); 511 } 512 513 static void vkms_config_test_invalid_encoder_number(struct kunit *test) 514 { 515 struct vkms_config *config; 516 struct vkms_config_encoder *encoder_cfg; 517 int n; 518 519 config = vkms_config_default_create(false, false, false); 520 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 521 522 /* Invalid: No encoders */ 523 encoder_cfg = get_first_encoder(config); 524 vkms_config_destroy_encoder(config, encoder_cfg); 525 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 526 527 /* Invalid: Too many encoders */ 528 for (n = 0; n <= 32; n++) 529 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vkms_config_create_encoder(config)); 530 531 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 532 533 vkms_config_destroy(config); 534 } 535 536 static void vkms_config_test_valid_encoder_possible_crtcs(struct kunit *test) 537 { 538 struct vkms_config *config; 539 struct vkms_config_plane *plane_cfg; 540 struct vkms_config_crtc *crtc_cfg1, *crtc_cfg2; 541 struct vkms_config_encoder *encoder_cfg; 542 int err; 543 544 config = vkms_config_default_create(false, false, false); 545 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 546 547 crtc_cfg1 = get_first_crtc(config); 548 549 /* Invalid: Encoder without a possible CRTC */ 550 encoder_cfg = vkms_config_create_encoder(config); 551 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg); 552 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 553 554 /* Valid: Second CRTC with shared encoder */ 555 crtc_cfg2 = vkms_config_create_crtc(config); 556 plane_cfg = vkms_config_create_plane(config); 557 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg2); 558 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg); 559 560 vkms_config_plane_set_type(plane_cfg, DRM_PLANE_TYPE_PRIMARY); 561 err = vkms_config_plane_attach_crtc(plane_cfg, crtc_cfg2); 562 KUNIT_EXPECT_EQ(test, err, 0); 563 564 err = vkms_config_encoder_attach_crtc(encoder_cfg, crtc_cfg1); 565 KUNIT_EXPECT_EQ(test, err, 0); 566 567 err = vkms_config_encoder_attach_crtc(encoder_cfg, crtc_cfg2); 568 KUNIT_EXPECT_EQ(test, err, 0); 569 570 KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); 571 572 /* Invalid: Second CRTC without encoders */ 573 vkms_config_encoder_detach_crtc(encoder_cfg, crtc_cfg2); 574 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 575 576 /* Valid: First CRTC with 2 possible encoder */ 577 vkms_config_destroy_plane(plane_cfg); 578 vkms_config_destroy_crtc(config, crtc_cfg2); 579 KUNIT_EXPECT_TRUE(test, vkms_config_is_valid(config)); 580 581 vkms_config_destroy(config); 582 } 583 584 static void vkms_config_test_invalid_connector_number(struct kunit *test) 585 { 586 struct vkms_config *config; 587 struct vkms_config_connector *connector_cfg; 588 int n; 589 590 config = vkms_config_default_create(false, false, false); 591 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 592 593 /* Invalid: No connectors */ 594 connector_cfg = get_first_connector(config); 595 vkms_config_destroy_connector(connector_cfg); 596 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 597 598 /* Invalid: Too many connectors */ 599 for (n = 0; n <= 32; n++) 600 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vkms_config_create_connector(config)); 601 602 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 603 604 vkms_config_destroy(config); 605 } 606 607 static void vkms_config_test_valid_connector_possible_encoders(struct kunit *test) 608 { 609 struct vkms_config *config; 610 struct vkms_config_encoder *encoder_cfg; 611 struct vkms_config_connector *connector_cfg; 612 613 config = vkms_config_default_create(false, false, false); 614 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 615 616 encoder_cfg = get_first_encoder(config); 617 connector_cfg = get_first_connector(config); 618 619 /* Invalid: Connector without a possible encoder */ 620 vkms_config_connector_detach_encoder(connector_cfg, encoder_cfg); 621 KUNIT_EXPECT_FALSE(test, vkms_config_is_valid(config)); 622 623 vkms_config_destroy(config); 624 } 625 626 static void vkms_config_test_attach_different_configs(struct kunit *test) 627 { 628 struct vkms_config *config1, *config2; 629 struct vkms_config_plane *plane_cfg1, *plane_cfg2; 630 struct vkms_config_crtc *crtc_cfg1, *crtc_cfg2; 631 struct vkms_config_encoder *encoder_cfg1, *encoder_cfg2; 632 struct vkms_config_connector *connector_cfg1, *connector_cfg2; 633 int err; 634 635 config1 = vkms_config_create("test1"); 636 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config1); 637 638 config2 = vkms_config_create("test2"); 639 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config2); 640 641 plane_cfg1 = vkms_config_create_plane(config1); 642 crtc_cfg1 = vkms_config_create_crtc(config1); 643 encoder_cfg1 = vkms_config_create_encoder(config1); 644 connector_cfg1 = vkms_config_create_connector(config1); 645 646 plane_cfg2 = vkms_config_create_plane(config2); 647 crtc_cfg2 = vkms_config_create_crtc(config2); 648 encoder_cfg2 = vkms_config_create_encoder(config2); 649 connector_cfg2 = vkms_config_create_connector(config2); 650 651 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg1); 652 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg2); 653 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg1); 654 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg2); 655 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg1); 656 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg2); 657 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector_cfg1); 658 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector_cfg2); 659 660 err = vkms_config_plane_attach_crtc(plane_cfg1, crtc_cfg2); 661 KUNIT_EXPECT_NE(test, err, 0); 662 err = vkms_config_plane_attach_crtc(plane_cfg2, crtc_cfg1); 663 KUNIT_EXPECT_NE(test, err, 0); 664 665 err = vkms_config_encoder_attach_crtc(encoder_cfg1, crtc_cfg2); 666 KUNIT_EXPECT_NE(test, err, 0); 667 err = vkms_config_encoder_attach_crtc(encoder_cfg2, crtc_cfg1); 668 KUNIT_EXPECT_NE(test, err, 0); 669 670 err = vkms_config_connector_attach_encoder(connector_cfg1, encoder_cfg2); 671 KUNIT_EXPECT_NE(test, err, 0); 672 err = vkms_config_connector_attach_encoder(connector_cfg2, encoder_cfg1); 673 KUNIT_EXPECT_NE(test, err, 0); 674 675 vkms_config_destroy(config1); 676 vkms_config_destroy(config2); 677 } 678 679 static void vkms_config_test_plane_attach_crtc(struct kunit *test) 680 { 681 struct vkms_config *config; 682 struct vkms_config_plane *overlay_cfg; 683 struct vkms_config_plane *primary_cfg; 684 struct vkms_config_plane *cursor_cfg; 685 struct vkms_config_crtc *crtc_cfg; 686 int err; 687 688 config = vkms_config_create("test"); 689 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 690 691 overlay_cfg = vkms_config_create_plane(config); 692 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, overlay_cfg); 693 vkms_config_plane_set_type(overlay_cfg, DRM_PLANE_TYPE_OVERLAY); 694 695 primary_cfg = vkms_config_create_plane(config); 696 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, primary_cfg); 697 vkms_config_plane_set_type(primary_cfg, DRM_PLANE_TYPE_PRIMARY); 698 699 cursor_cfg = vkms_config_create_plane(config); 700 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cursor_cfg); 701 vkms_config_plane_set_type(cursor_cfg, DRM_PLANE_TYPE_CURSOR); 702 703 crtc_cfg = vkms_config_create_crtc(config); 704 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg); 705 706 /* No primary or cursor planes */ 707 KUNIT_EXPECT_NULL(test, vkms_config_crtc_primary_plane(config, crtc_cfg)); 708 KUNIT_EXPECT_NULL(test, vkms_config_crtc_cursor_plane(config, crtc_cfg)); 709 710 /* Overlay plane, but no primary or cursor planes */ 711 err = vkms_config_plane_attach_crtc(overlay_cfg, crtc_cfg); 712 KUNIT_EXPECT_EQ(test, err, 0); 713 KUNIT_EXPECT_NULL(test, vkms_config_crtc_primary_plane(config, crtc_cfg)); 714 KUNIT_EXPECT_NULL(test, vkms_config_crtc_cursor_plane(config, crtc_cfg)); 715 716 /* Primary plane, attaching it twice must fail */ 717 err = vkms_config_plane_attach_crtc(primary_cfg, crtc_cfg); 718 KUNIT_EXPECT_EQ(test, err, 0); 719 err = vkms_config_plane_attach_crtc(primary_cfg, crtc_cfg); 720 KUNIT_EXPECT_NE(test, err, 0); 721 KUNIT_EXPECT_PTR_EQ(test, 722 vkms_config_crtc_primary_plane(config, crtc_cfg), 723 primary_cfg); 724 KUNIT_EXPECT_NULL(test, vkms_config_crtc_cursor_plane(config, crtc_cfg)); 725 726 /* Primary and cursor planes */ 727 err = vkms_config_plane_attach_crtc(cursor_cfg, crtc_cfg); 728 KUNIT_EXPECT_EQ(test, err, 0); 729 KUNIT_EXPECT_PTR_EQ(test, 730 vkms_config_crtc_primary_plane(config, crtc_cfg), 731 primary_cfg); 732 KUNIT_EXPECT_PTR_EQ(test, 733 vkms_config_crtc_cursor_plane(config, crtc_cfg), 734 cursor_cfg); 735 736 /* Detach primary and destroy cursor plane */ 737 vkms_config_plane_detach_crtc(overlay_cfg, crtc_cfg); 738 vkms_config_plane_detach_crtc(primary_cfg, crtc_cfg); 739 vkms_config_destroy_plane(cursor_cfg); 740 KUNIT_EXPECT_NULL(test, vkms_config_crtc_primary_plane(config, crtc_cfg)); 741 KUNIT_EXPECT_NULL(test, vkms_config_crtc_cursor_plane(config, crtc_cfg)); 742 743 vkms_config_destroy(config); 744 } 745 746 static void vkms_config_test_plane_get_possible_crtcs(struct kunit *test) 747 { 748 struct vkms_config *config; 749 struct vkms_config_plane *plane_cfg1, *plane_cfg2; 750 struct vkms_config_crtc *crtc_cfg1, *crtc_cfg2; 751 struct vkms_config_crtc *possible_crtc; 752 unsigned long idx = 0; 753 int n_crtcs = 0; 754 int err; 755 756 config = vkms_config_create("test"); 757 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 758 759 plane_cfg1 = vkms_config_create_plane(config); 760 plane_cfg2 = vkms_config_create_plane(config); 761 crtc_cfg1 = vkms_config_create_crtc(config); 762 crtc_cfg2 = vkms_config_create_crtc(config); 763 764 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg1); 765 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_cfg2); 766 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg1); 767 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg2); 768 769 /* No possible CRTCs */ 770 vkms_config_plane_for_each_possible_crtc(plane_cfg1, idx, possible_crtc) 771 KUNIT_FAIL(test, "Unexpected possible CRTC"); 772 773 vkms_config_plane_for_each_possible_crtc(plane_cfg2, idx, possible_crtc) 774 KUNIT_FAIL(test, "Unexpected possible CRTC"); 775 776 /* Plane 1 attached to CRTC 1 and 2 */ 777 err = vkms_config_plane_attach_crtc(plane_cfg1, crtc_cfg1); 778 KUNIT_EXPECT_EQ(test, err, 0); 779 err = vkms_config_plane_attach_crtc(plane_cfg1, crtc_cfg2); 780 KUNIT_EXPECT_EQ(test, err, 0); 781 782 vkms_config_plane_for_each_possible_crtc(plane_cfg1, idx, possible_crtc) { 783 n_crtcs++; 784 if (possible_crtc != crtc_cfg1 && possible_crtc != crtc_cfg2) 785 KUNIT_FAIL(test, "Unexpected possible CRTC"); 786 } 787 KUNIT_ASSERT_EQ(test, n_crtcs, 2); 788 n_crtcs = 0; 789 790 vkms_config_plane_for_each_possible_crtc(plane_cfg2, idx, possible_crtc) 791 KUNIT_FAIL(test, "Unexpected possible CRTC"); 792 793 /* Plane 1 attached to CRTC 1 and plane 2 to CRTC 2 */ 794 vkms_config_plane_detach_crtc(plane_cfg1, crtc_cfg2); 795 vkms_config_plane_for_each_possible_crtc(plane_cfg1, idx, possible_crtc) { 796 n_crtcs++; 797 if (possible_crtc != crtc_cfg1) 798 KUNIT_FAIL(test, "Unexpected possible CRTC"); 799 } 800 KUNIT_ASSERT_EQ(test, n_crtcs, 1); 801 n_crtcs = 0; 802 803 err = vkms_config_plane_attach_crtc(plane_cfg2, crtc_cfg2); 804 KUNIT_EXPECT_EQ(test, err, 0); 805 vkms_config_plane_for_each_possible_crtc(plane_cfg2, idx, possible_crtc) { 806 n_crtcs++; 807 if (possible_crtc != crtc_cfg2) 808 KUNIT_FAIL(test, "Unexpected possible CRTC"); 809 } 810 KUNIT_ASSERT_EQ(test, n_crtcs, 1); 811 812 vkms_config_destroy(config); 813 } 814 815 static void vkms_config_test_encoder_get_possible_crtcs(struct kunit *test) 816 { 817 struct vkms_config *config; 818 struct vkms_config_encoder *encoder_cfg1, *encoder_cfg2; 819 struct vkms_config_crtc *crtc_cfg1, *crtc_cfg2; 820 struct vkms_config_crtc *possible_crtc; 821 unsigned long idx = 0; 822 int n_crtcs = 0; 823 int err; 824 825 config = vkms_config_create("test"); 826 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 827 828 encoder_cfg1 = vkms_config_create_encoder(config); 829 encoder_cfg2 = vkms_config_create_encoder(config); 830 crtc_cfg1 = vkms_config_create_crtc(config); 831 crtc_cfg2 = vkms_config_create_crtc(config); 832 833 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg1); 834 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg2); 835 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg1); 836 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_cfg2); 837 838 /* No possible CRTCs */ 839 vkms_config_encoder_for_each_possible_crtc(encoder_cfg1, idx, possible_crtc) 840 KUNIT_FAIL(test, "Unexpected possible CRTC"); 841 842 vkms_config_encoder_for_each_possible_crtc(encoder_cfg2, idx, possible_crtc) 843 KUNIT_FAIL(test, "Unexpected possible CRTC"); 844 845 /* Encoder 1 attached to CRTC 1 and 2 */ 846 err = vkms_config_encoder_attach_crtc(encoder_cfg1, crtc_cfg1); 847 KUNIT_EXPECT_EQ(test, err, 0); 848 err = vkms_config_encoder_attach_crtc(encoder_cfg1, crtc_cfg2); 849 KUNIT_EXPECT_EQ(test, err, 0); 850 851 vkms_config_encoder_for_each_possible_crtc(encoder_cfg1, idx, possible_crtc) { 852 n_crtcs++; 853 if (possible_crtc != crtc_cfg1 && possible_crtc != crtc_cfg2) 854 KUNIT_FAIL(test, "Unexpected possible CRTC"); 855 } 856 KUNIT_ASSERT_EQ(test, n_crtcs, 2); 857 n_crtcs = 0; 858 859 vkms_config_encoder_for_each_possible_crtc(encoder_cfg2, idx, possible_crtc) 860 KUNIT_FAIL(test, "Unexpected possible CRTC"); 861 862 /* Encoder 1 attached to CRTC 1 and encoder 2 to CRTC 2 */ 863 vkms_config_encoder_detach_crtc(encoder_cfg1, crtc_cfg2); 864 vkms_config_encoder_for_each_possible_crtc(encoder_cfg1, idx, possible_crtc) { 865 n_crtcs++; 866 if (possible_crtc != crtc_cfg1) 867 KUNIT_FAIL(test, "Unexpected possible CRTC"); 868 } 869 KUNIT_ASSERT_EQ(test, n_crtcs, 1); 870 n_crtcs = 0; 871 872 err = vkms_config_encoder_attach_crtc(encoder_cfg2, crtc_cfg2); 873 KUNIT_EXPECT_EQ(test, err, 0); 874 vkms_config_encoder_for_each_possible_crtc(encoder_cfg2, idx, possible_crtc) { 875 n_crtcs++; 876 if (possible_crtc != crtc_cfg2) 877 KUNIT_FAIL(test, "Unexpected possible CRTC"); 878 } 879 KUNIT_ASSERT_EQ(test, n_crtcs, 1); 880 881 vkms_config_destroy(config); 882 } 883 884 static void vkms_config_test_connector_get_possible_encoders(struct kunit *test) 885 { 886 struct vkms_config *config; 887 struct vkms_config_connector *connector_cfg1, *connector_cfg2; 888 struct vkms_config_encoder *encoder_cfg1, *encoder_cfg2; 889 struct vkms_config_encoder *possible_encoder; 890 unsigned long idx = 0; 891 int n_encoders = 0; 892 int err; 893 894 config = vkms_config_create("test"); 895 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, config); 896 897 connector_cfg1 = vkms_config_create_connector(config); 898 connector_cfg2 = vkms_config_create_connector(config); 899 encoder_cfg1 = vkms_config_create_encoder(config); 900 encoder_cfg2 = vkms_config_create_encoder(config); 901 902 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector_cfg1); 903 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, connector_cfg2); 904 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg1); 905 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder_cfg2); 906 907 /* No possible encoders */ 908 vkms_config_connector_for_each_possible_encoder(connector_cfg1, idx, 909 possible_encoder) 910 KUNIT_FAIL(test, "Unexpected possible encoder"); 911 912 vkms_config_connector_for_each_possible_encoder(connector_cfg2, idx, 913 possible_encoder) 914 KUNIT_FAIL(test, "Unexpected possible encoder"); 915 916 /* Connector 1 attached to encoders 1 and 2 */ 917 err = vkms_config_connector_attach_encoder(connector_cfg1, encoder_cfg1); 918 KUNIT_EXPECT_EQ(test, err, 0); 919 err = vkms_config_connector_attach_encoder(connector_cfg1, encoder_cfg2); 920 KUNIT_EXPECT_EQ(test, err, 0); 921 922 vkms_config_connector_for_each_possible_encoder(connector_cfg1, idx, 923 possible_encoder) { 924 n_encoders++; 925 if (possible_encoder != encoder_cfg1 && 926 possible_encoder != encoder_cfg2) 927 KUNIT_FAIL(test, "Unexpected possible encoder"); 928 } 929 KUNIT_ASSERT_EQ(test, n_encoders, 2); 930 n_encoders = 0; 931 932 vkms_config_connector_for_each_possible_encoder(connector_cfg2, idx, 933 possible_encoder) 934 KUNIT_FAIL(test, "Unexpected possible encoder"); 935 936 /* Connector 1 attached to encoder 1 and connector 2 to encoder 2 */ 937 vkms_config_connector_detach_encoder(connector_cfg1, encoder_cfg2); 938 vkms_config_connector_for_each_possible_encoder(connector_cfg1, idx, 939 possible_encoder) { 940 n_encoders++; 941 if (possible_encoder != encoder_cfg1) 942 KUNIT_FAIL(test, "Unexpected possible encoder"); 943 } 944 KUNIT_ASSERT_EQ(test, n_encoders, 1); 945 n_encoders = 0; 946 947 err = vkms_config_connector_attach_encoder(connector_cfg2, encoder_cfg2); 948 KUNIT_EXPECT_EQ(test, err, 0); 949 vkms_config_connector_for_each_possible_encoder(connector_cfg2, idx, 950 possible_encoder) { 951 n_encoders++; 952 if (possible_encoder != encoder_cfg2) 953 KUNIT_FAIL(test, "Unexpected possible encoder"); 954 } 955 KUNIT_ASSERT_EQ(test, n_encoders, 1); 956 957 vkms_config_destroy(config); 958 } 959 960 static struct kunit_case vkms_config_test_cases[] = { 961 KUNIT_CASE(vkms_config_test_empty_config), 962 KUNIT_CASE_PARAM(vkms_config_test_default_config, 963 default_config_gen_params), 964 KUNIT_CASE(vkms_config_test_get_planes), 965 KUNIT_CASE(vkms_config_test_get_crtcs), 966 KUNIT_CASE(vkms_config_test_get_encoders), 967 KUNIT_CASE(vkms_config_test_get_connectors), 968 KUNIT_CASE(vkms_config_test_invalid_plane_number), 969 KUNIT_CASE(vkms_config_test_valid_plane_type), 970 KUNIT_CASE(vkms_config_test_valid_plane_possible_crtcs), 971 KUNIT_CASE(vkms_config_test_invalid_crtc_number), 972 KUNIT_CASE(vkms_config_test_invalid_encoder_number), 973 KUNIT_CASE(vkms_config_test_valid_encoder_possible_crtcs), 974 KUNIT_CASE(vkms_config_test_invalid_connector_number), 975 KUNIT_CASE(vkms_config_test_valid_connector_possible_encoders), 976 KUNIT_CASE(vkms_config_test_attach_different_configs), 977 KUNIT_CASE(vkms_config_test_plane_attach_crtc), 978 KUNIT_CASE(vkms_config_test_plane_get_possible_crtcs), 979 KUNIT_CASE(vkms_config_test_encoder_get_possible_crtcs), 980 KUNIT_CASE(vkms_config_test_connector_get_possible_encoders), 981 {} 982 }; 983 984 static struct kunit_suite vkms_config_test_suite = { 985 .name = "vkms-config", 986 .test_cases = vkms_config_test_cases, 987 }; 988 989 kunit_test_suite(vkms_config_test_suite); 990 991 MODULE_LICENSE("GPL"); 992 MODULE_DESCRIPTION("Kunit test for vkms config utility"); 993