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