Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.19-rc7 1818 lines 57 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Kunit test for drm_modes functions 4 */ 5 6#include <linux/i2c.h> 7 8#include <drm/drm_atomic_state_helper.h> 9#include <drm/drm_connector.h> 10#include <drm/drm_drv.h> 11#include <drm/drm_edid.h> 12#include <drm/drm_file.h> 13#include <drm/drm_kunit_helpers.h> 14#include <drm/drm_modes.h> 15 16#include <drm/display/drm_hdmi_helper.h> 17 18#include <kunit/test.h> 19 20#include "../drm_crtc_internal.h" 21 22struct drm_connector_init_priv { 23 struct drm_device drm; 24 struct drm_connector connector; 25 struct i2c_adapter ddc; 26}; 27 28static const struct drm_connector_hdmi_funcs dummy_hdmi_funcs = { 29}; 30 31static const struct drm_connector_funcs dummy_funcs = { 32 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 33 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 34 .reset = drm_atomic_helper_connector_reset, 35}; 36 37static int dummy_ddc_xfer(struct i2c_adapter *adapter, 38 struct i2c_msg *msgs, int num) 39{ 40 return num; 41} 42 43static u32 dummy_ddc_func(struct i2c_adapter *adapter) 44{ 45 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 46} 47 48static const struct i2c_algorithm dummy_ddc_algorithm = { 49 .master_xfer = dummy_ddc_xfer, 50 .functionality = dummy_ddc_func, 51}; 52 53static void i2c_del_adapter_wrapper(void *ptr) 54{ 55 struct i2c_adapter *adap = ptr; 56 57 i2c_del_adapter(adap); 58} 59 60static int drm_test_connector_init(struct kunit *test) 61{ 62 struct drm_connector_init_priv *priv; 63 struct device *dev; 64 int ret; 65 66 dev = drm_kunit_helper_alloc_device(test); 67 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 68 69 priv = drm_kunit_helper_alloc_drm_device(test, dev, 70 struct drm_connector_init_priv, drm, 71 DRIVER_MODESET | DRIVER_ATOMIC); 72 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); 73 74 strscpy(priv->ddc.name, "dummy-connector-ddc", sizeof(priv->ddc.name)); 75 priv->ddc.owner = THIS_MODULE; 76 priv->ddc.algo = &dummy_ddc_algorithm; 77 priv->ddc.dev.parent = dev; 78 79 ret = i2c_add_adapter(&priv->ddc); 80 KUNIT_ASSERT_EQ(test, ret, 0); 81 82 ret = kunit_add_action_or_reset(test, i2c_del_adapter_wrapper, &priv->ddc); 83 KUNIT_ASSERT_EQ(test, ret, 0); 84 85 test->priv = priv; 86 return 0; 87} 88 89/* 90 * Test that the registration of a bog standard connector works as 91 * expected and doesn't report any error. 92 */ 93static void drm_test_drmm_connector_init(struct kunit *test) 94{ 95 struct drm_connector_init_priv *priv = test->priv; 96 int ret; 97 98 ret = drmm_connector_init(&priv->drm, &priv->connector, 99 &dummy_funcs, 100 DRM_MODE_CONNECTOR_HDMIA, 101 &priv->ddc); 102 KUNIT_EXPECT_EQ(test, ret, 0); 103} 104 105/* 106 * Test that the registration of a connector without a DDC adapter 107 * doesn't report any error. 108 */ 109static void drm_test_drmm_connector_init_null_ddc(struct kunit *test) 110{ 111 struct drm_connector_init_priv *priv = test->priv; 112 int ret; 113 114 ret = drmm_connector_init(&priv->drm, &priv->connector, 115 &dummy_funcs, 116 DRM_MODE_CONNECTOR_HDMIA, 117 NULL); 118 KUNIT_EXPECT_EQ(test, ret, 0); 119} 120 121/* 122 * Test that the registration of a connector succeeds for all possible 123 * connector types. 124 */ 125static void drm_test_drmm_connector_init_type_valid(struct kunit *test) 126{ 127 struct drm_connector_init_priv *priv = test->priv; 128 unsigned int connector_type = *(unsigned int *)test->param_value; 129 int ret; 130 131 ret = drmm_connector_init(&priv->drm, &priv->connector, 132 &dummy_funcs, 133 connector_type, 134 &priv->ddc); 135 KUNIT_EXPECT_EQ(test, ret, 0); 136} 137 138static const unsigned int drm_connector_init_type_valid_tests[] = { 139 DRM_MODE_CONNECTOR_Unknown, 140 DRM_MODE_CONNECTOR_VGA, 141 DRM_MODE_CONNECTOR_DVII, 142 DRM_MODE_CONNECTOR_DVID, 143 DRM_MODE_CONNECTOR_DVIA, 144 DRM_MODE_CONNECTOR_Composite, 145 DRM_MODE_CONNECTOR_SVIDEO, 146 DRM_MODE_CONNECTOR_LVDS, 147 DRM_MODE_CONNECTOR_Component, 148 DRM_MODE_CONNECTOR_9PinDIN, 149 DRM_MODE_CONNECTOR_DisplayPort, 150 DRM_MODE_CONNECTOR_HDMIA, 151 DRM_MODE_CONNECTOR_HDMIB, 152 DRM_MODE_CONNECTOR_TV, 153 DRM_MODE_CONNECTOR_eDP, 154 DRM_MODE_CONNECTOR_VIRTUAL, 155 DRM_MODE_CONNECTOR_DSI, 156 DRM_MODE_CONNECTOR_DPI, 157 DRM_MODE_CONNECTOR_WRITEBACK, 158 DRM_MODE_CONNECTOR_SPI, 159 DRM_MODE_CONNECTOR_USB, 160}; 161 162static void drm_connector_init_type_desc(const unsigned int *type, char *desc) 163{ 164 sprintf(desc, "%s", drm_get_connector_type_name(*type)); 165} 166 167KUNIT_ARRAY_PARAM(drm_connector_init_type_valid, 168 drm_connector_init_type_valid_tests, 169 drm_connector_init_type_desc); 170 171static struct kunit_case drmm_connector_init_tests[] = { 172 KUNIT_CASE(drm_test_drmm_connector_init), 173 KUNIT_CASE(drm_test_drmm_connector_init_null_ddc), 174 KUNIT_CASE_PARAM(drm_test_drmm_connector_init_type_valid, 175 drm_connector_init_type_valid_gen_params), 176 { } 177}; 178 179static struct kunit_suite drmm_connector_init_test_suite = { 180 .name = "drmm_connector_init", 181 .init = drm_test_connector_init, 182 .test_cases = drmm_connector_init_tests, 183}; 184 185static const struct drm_connector_funcs dummy_dynamic_init_funcs = { 186 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 187 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 188 .reset = drm_atomic_helper_connector_reset, 189 .destroy = drm_connector_cleanup, 190}; 191 192/* 193 * Test that the initialization of a bog standard dynamic connector works 194 * as expected and doesn't report any error. 195 */ 196static void drm_test_drm_connector_dynamic_init(struct kunit *test) 197{ 198 struct drm_connector_init_priv *priv = test->priv; 199 struct drm_connector *connector = &priv->connector; 200 int ret; 201 202 ret = drm_connector_dynamic_init(&priv->drm, connector, 203 &dummy_dynamic_init_funcs, 204 DRM_MODE_CONNECTOR_DisplayPort, 205 &priv->ddc); 206 KUNIT_ASSERT_EQ(test, ret, 0); 207} 208 209static void drm_test_connector_dynamic_init_cleanup(struct kunit *test) 210{ 211 struct drm_connector_init_priv *priv = test->priv; 212 struct drm_connector *connector = &priv->connector; 213 214 drm_connector_cleanup(connector); 215} 216 217/* 218 * Test that the initialization of a dynamic connector without a DDC adapter 219 * doesn't report any error. 220 */ 221static void drm_test_drm_connector_dynamic_init_null_ddc(struct kunit *test) 222{ 223 struct drm_connector_init_priv *priv = test->priv; 224 struct drm_connector *connector = &priv->connector; 225 int ret; 226 227 ret = drm_connector_dynamic_init(&priv->drm, connector, 228 &dummy_dynamic_init_funcs, 229 DRM_MODE_CONNECTOR_DisplayPort, 230 NULL); 231 KUNIT_ASSERT_EQ(test, ret, 0); 232} 233 234/* 235 * Test that the initialization of a dynamic connector doesn't add the 236 * connector to the connector list. 237 */ 238static void drm_test_drm_connector_dynamic_init_not_added(struct kunit *test) 239{ 240 struct drm_connector_init_priv *priv = test->priv; 241 struct drm_connector *connector = &priv->connector; 242 int ret; 243 244 ret = drm_connector_dynamic_init(&priv->drm, connector, 245 &dummy_dynamic_init_funcs, 246 DRM_MODE_CONNECTOR_DisplayPort, 247 &priv->ddc); 248 KUNIT_ASSERT_EQ(test, ret, 0); 249 KUNIT_ASSERT_PTR_EQ(test, connector->head.next, &connector->head); 250} 251 252static void test_connector_property(struct kunit *test, 253 struct drm_connector *connector, 254 const struct drm_property *expected_prop) 255{ 256 struct drm_property *prop; 257 uint64_t val; 258 int ret; 259 260 KUNIT_ASSERT_NOT_NULL(test, expected_prop); 261 prop = drm_mode_obj_find_prop_id(&connector->base, expected_prop->base.id); 262 KUNIT_ASSERT_PTR_EQ_MSG(test, prop, expected_prop, 263 "Can't find property %s", expected_prop->name); 264 265 ret = drm_object_property_get_default_value(&connector->base, prop, &val); 266 KUNIT_EXPECT_EQ(test, ret, 0); 267 KUNIT_EXPECT_EQ(test, val, 0); 268 269 /* TODO: Check property value in the connector state. */ 270} 271 272/* 273 * Test that the initialization of a dynamic connector adds all the expected 274 * properties to it. 275 */ 276static void drm_test_drm_connector_dynamic_init_properties(struct kunit *test) 277{ 278 struct drm_connector_init_priv *priv = test->priv; 279 struct drm_connector *connector = &priv->connector; 280 struct drm_mode_config *config = &priv->drm.mode_config; 281 const struct drm_property *props[] = { 282 config->edid_property, 283 config->dpms_property, 284 config->link_status_property, 285 config->non_desktop_property, 286 config->tile_property, 287 config->prop_crtc_id, 288 }; 289 int ret; 290 int i; 291 292 ret = drm_connector_dynamic_init(&priv->drm, connector, 293 &dummy_dynamic_init_funcs, 294 DRM_MODE_CONNECTOR_DisplayPort, 295 &priv->ddc); 296 KUNIT_ASSERT_EQ(test, ret, 0); 297 298 for (i = 0; i < ARRAY_SIZE(props); i++) 299 test_connector_property(test, connector, props[i]); 300} 301 302/* 303 * Test that the initialization of a dynamic connector succeeds for all 304 * possible connector types. 305 */ 306static void drm_test_drm_connector_dynamic_init_type_valid(struct kunit *test) 307{ 308 struct drm_connector_init_priv *priv = test->priv; 309 struct drm_connector *connector = &priv->connector; 310 unsigned int connector_type = *(unsigned int *)test->param_value; 311 int ret; 312 313 ret = drm_connector_dynamic_init(&priv->drm, connector, 314 &dummy_dynamic_init_funcs, 315 connector_type, 316 &priv->ddc); 317 KUNIT_ASSERT_EQ(test, ret, 0); 318} 319 320/* 321 * Test that the initialization of a dynamic connector sets the expected name 322 * for it for all possible connector types. 323 */ 324static void drm_test_drm_connector_dynamic_init_name(struct kunit *test) 325{ 326 struct drm_connector_init_priv *priv = test->priv; 327 struct drm_connector *connector = &priv->connector; 328 unsigned int connector_type = *(unsigned int *)test->param_value; 329 char expected_name[128]; 330 int ret; 331 332 ret = drm_connector_dynamic_init(&priv->drm, connector, 333 &dummy_dynamic_init_funcs, 334 connector_type, 335 &priv->ddc); 336 KUNIT_ASSERT_EQ(test, ret, 0); 337 338 snprintf(expected_name, sizeof(expected_name), "%s-%d", 339 drm_get_connector_type_name(connector_type), connector->connector_type_id); 340 KUNIT_ASSERT_STREQ(test, connector->name, expected_name); 341} 342 343static struct kunit_case drm_connector_dynamic_init_tests[] = { 344 KUNIT_CASE(drm_test_drm_connector_dynamic_init), 345 KUNIT_CASE(drm_test_drm_connector_dynamic_init_null_ddc), 346 KUNIT_CASE(drm_test_drm_connector_dynamic_init_not_added), 347 KUNIT_CASE(drm_test_drm_connector_dynamic_init_properties), 348 KUNIT_CASE_PARAM(drm_test_drm_connector_dynamic_init_type_valid, 349 drm_connector_init_type_valid_gen_params), 350 KUNIT_CASE_PARAM(drm_test_drm_connector_dynamic_init_name, 351 drm_connector_init_type_valid_gen_params), 352 {} 353}; 354 355static struct kunit_suite drm_connector_dynamic_init_test_suite = { 356 .name = "drm_connector_dynamic_init", 357 .init = drm_test_connector_init, 358 .exit = drm_test_connector_dynamic_init_cleanup, 359 .test_cases = drm_connector_dynamic_init_tests, 360}; 361 362static int drm_test_connector_dynamic_register_early_init(struct kunit *test) 363{ 364 struct drm_connector_init_priv *priv; 365 int ret; 366 367 ret = drm_test_connector_init(test); 368 KUNIT_ASSERT_EQ(test, ret, 0); 369 370 priv = test->priv; 371 372 ret = drm_connector_dynamic_init(&priv->drm, &priv->connector, 373 &dummy_dynamic_init_funcs, 374 DRM_MODE_CONNECTOR_DisplayPort, 375 &priv->ddc); 376 KUNIT_ASSERT_EQ(test, ret, 0); 377 378 return 0; 379} 380 381static void drm_test_connector_dynamic_register_early_cleanup(struct kunit *test) 382{ 383 struct drm_connector_init_priv *priv = test->priv; 384 struct drm_connector *connector = &priv->connector; 385 386 drm_connector_unregister(connector); 387 drm_connector_put(connector); 388} 389 390/* 391 * Test that registration of a dynamic connector adds it to the connector list. 392 */ 393static void drm_test_drm_connector_dynamic_register_early_on_list(struct kunit *test) 394{ 395 struct drm_connector_init_priv *priv = test->priv; 396 struct drm_connector *connector = &priv->connector; 397 int ret; 398 399 KUNIT_ASSERT_TRUE(test, list_empty(&connector->head)); 400 401 ret = drm_connector_dynamic_register(connector); 402 KUNIT_ASSERT_EQ(test, ret, 0); 403 404 KUNIT_ASSERT_PTR_EQ(test, connector->head.next, &priv->drm.mode_config.connector_list); 405} 406 407/* 408 * Test that the registration of a dynamic connector before the drm device is 409 * registered results in deferring the connector's user interface registration. 410 */ 411static void drm_test_drm_connector_dynamic_register_early_defer(struct kunit *test) 412{ 413 struct drm_connector_init_priv *priv = test->priv; 414 struct drm_connector *connector = &priv->connector; 415 int ret; 416 417 ret = drm_connector_dynamic_register(connector); 418 KUNIT_ASSERT_EQ(test, ret, 0); 419 420 KUNIT_ASSERT_EQ(test, connector->registration_state, DRM_CONNECTOR_INITIALIZING); 421} 422 423/* 424 * Test that the registration of a dynamic connector fails, if this is done before 425 * the connector is initialized. 426 */ 427static void drm_test_drm_connector_dynamic_register_early_no_init(struct kunit *test) 428{ 429 struct drm_connector *connector; 430 int ret; 431 432 connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL); /* auto freed */ 433 KUNIT_ASSERT_NOT_NULL(test, connector); 434 435 ret = drm_connector_dynamic_register(connector); 436 KUNIT_ASSERT_EQ(test, ret, -EINVAL); 437} 438 439/* 440 * Test that the registration of a dynamic connector before the drm device is 441 * registered results in deferring adding a mode object for the connector. 442 */ 443static void drm_test_drm_connector_dynamic_register_early_no_mode_object(struct kunit *test) 444{ 445 struct drm_connector_init_priv *priv = test->priv; 446 struct drm_connector *connector = &priv->connector; 447 struct drm_connector *tmp_connector; 448 int ret; 449 450 ret = drm_connector_dynamic_register(&priv->connector); 451 KUNIT_ASSERT_EQ(test, ret, 0); 452 453 tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id); 454 KUNIT_ASSERT_NULL(test, tmp_connector); 455} 456 457static struct kunit_case drm_connector_dynamic_register_early_tests[] = { 458 KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_on_list), 459 KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_defer), 460 KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_no_init), 461 KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_no_mode_object), 462 { } 463}; 464 465static struct kunit_suite drm_connector_dynamic_register_early_test_suite = { 466 .name = "drm_connector_dynamic_register_early", 467 .init = drm_test_connector_dynamic_register_early_init, 468 .exit = drm_test_connector_dynamic_register_early_cleanup, 469 .test_cases = drm_connector_dynamic_register_early_tests, 470}; 471 472static int drm_test_connector_dynamic_register_init(struct kunit *test) 473{ 474 struct drm_connector_init_priv *priv; 475 int ret; 476 477 ret = drm_test_connector_dynamic_register_early_init(test); 478 KUNIT_ASSERT_EQ(test, ret, 0); 479 480 priv = test->priv; 481 482 ret = drm_dev_register(priv->connector.dev, 0); 483 KUNIT_ASSERT_EQ(test, ret, 0); 484 485 return 0; 486} 487 488static void drm_test_connector_dynamic_register_cleanup(struct kunit *test) 489{ 490 struct drm_connector_init_priv *priv = test->priv; 491 struct drm_device *dev = priv->connector.dev; 492 493 drm_connector_unregister(&priv->connector); 494 drm_connector_put(&priv->connector); 495 496 drm_dev_unregister(dev); 497 498 drm_test_connector_dynamic_register_early_cleanup(test); 499} 500 501static void drm_test_drm_connector_dynamic_register_on_list(struct kunit *test) 502{ 503 struct drm_connector_init_priv *priv = test->priv; 504 int ret; 505 506 KUNIT_ASSERT_TRUE(test, list_empty(&priv->connector.head)); 507 508 ret = drm_connector_dynamic_register(&priv->connector); 509 KUNIT_ASSERT_EQ(test, ret, 0); 510 511 KUNIT_ASSERT_PTR_EQ(test, priv->connector.head.next, &priv->drm.mode_config.connector_list); 512} 513 514/* 515 * Test that the registration of a dynamic connector doesn't get deferred if 516 * this is done after the drm device is registered. 517 */ 518static void drm_test_drm_connector_dynamic_register_no_defer(struct kunit *test) 519{ 520 struct drm_connector_init_priv *priv = test->priv; 521 int ret; 522 523 KUNIT_ASSERT_EQ(test, priv->connector.registration_state, DRM_CONNECTOR_INITIALIZING); 524 525 ret = drm_connector_dynamic_register(&priv->connector); 526 KUNIT_ASSERT_EQ(test, ret, 0); 527 528 KUNIT_ASSERT_EQ(test, priv->connector.registration_state, DRM_CONNECTOR_REGISTERED); 529} 530 531/* 532 * Test that the registration of a dynamic connector fails if this is done after the 533 * drm device is registered, but before the connector is initialized. 534 */ 535static void drm_test_drm_connector_dynamic_register_no_init(struct kunit *test) 536{ 537 struct drm_connector *connector; 538 int ret; 539 540 connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL); /* auto freed */ 541 KUNIT_ASSERT_NOT_NULL(test, connector); 542 543 ret = drm_connector_dynamic_register(connector); 544 KUNIT_ASSERT_EQ(test, ret, -EINVAL); 545} 546 547/* 548 * Test that the registration of a dynamic connector after the drm device is 549 * registered adds the mode object for the connector. 550 */ 551static void drm_test_drm_connector_dynamic_register_mode_object(struct kunit *test) 552{ 553 struct drm_connector_init_priv *priv = test->priv; 554 struct drm_connector *connector = &priv->connector; 555 struct drm_connector *tmp_connector; 556 int ret; 557 558 tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id); 559 KUNIT_ASSERT_NULL(test, tmp_connector); 560 561 ret = drm_connector_dynamic_register(&priv->connector); 562 KUNIT_ASSERT_EQ(test, ret, 0); 563 564 tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id); 565 KUNIT_ASSERT_PTR_EQ(test, tmp_connector, connector); 566} 567 568/* 569 * Test that the registration of a dynamic connector after the drm device is 570 * registered adds the connector to sysfs. 571 */ 572static void drm_test_drm_connector_dynamic_register_sysfs(struct kunit *test) 573{ 574 struct drm_connector_init_priv *priv = test->priv; 575 struct drm_connector *connector = &priv->connector; 576 int ret; 577 578 KUNIT_ASSERT_NULL(test, connector->kdev); 579 580 ret = drm_connector_dynamic_register(connector); 581 KUNIT_ASSERT_EQ(test, ret, 0); 582 583 KUNIT_ASSERT_NOT_NULL(test, connector->kdev); 584} 585 586/* 587 * Test that the registration of a dynamic connector after the drm device is 588 * registered sets the connector's sysfs name as expected. 589 */ 590static void drm_test_drm_connector_dynamic_register_sysfs_name(struct kunit *test) 591{ 592 struct drm_connector_init_priv *priv = test->priv; 593 struct drm_connector *connector = &priv->connector; 594 char expected_name[128]; 595 int ret; 596 597 ret = drm_connector_dynamic_register(connector); 598 KUNIT_ASSERT_EQ(test, ret, 0); 599 600 snprintf(expected_name, sizeof(expected_name), "card%d-%s", 601 connector->dev->primary->index, connector->name); 602 603 KUNIT_ASSERT_STREQ(test, dev_name(connector->kdev), expected_name); 604} 605 606/* 607 * Test that the registration of a dynamic connector after the drm device is 608 * registered adds the connector to debugfs. 609 */ 610static void drm_test_drm_connector_dynamic_register_debugfs(struct kunit *test) 611{ 612 struct drm_connector_init_priv *priv = test->priv; 613 int ret; 614 615 KUNIT_ASSERT_NULL(test, priv->connector.debugfs_entry); 616 617 ret = drm_connector_dynamic_register(&priv->connector); 618 KUNIT_ASSERT_EQ(test, ret, 0); 619 620 if (IS_ENABLED(CONFIG_DEBUG_FS)) 621 KUNIT_ASSERT_NOT_NULL(test, priv->connector.debugfs_entry); 622 else 623 KUNIT_ASSERT_NULL(test, priv->connector.debugfs_entry); 624} 625 626static struct kunit_case drm_connector_dynamic_register_tests[] = { 627 KUNIT_CASE(drm_test_drm_connector_dynamic_register_on_list), 628 KUNIT_CASE(drm_test_drm_connector_dynamic_register_no_defer), 629 KUNIT_CASE(drm_test_drm_connector_dynamic_register_no_init), 630 KUNIT_CASE(drm_test_drm_connector_dynamic_register_mode_object), 631 KUNIT_CASE(drm_test_drm_connector_dynamic_register_sysfs), 632 KUNIT_CASE(drm_test_drm_connector_dynamic_register_sysfs_name), 633 KUNIT_CASE(drm_test_drm_connector_dynamic_register_debugfs), 634 { } 635}; 636 637static struct kunit_suite drm_connector_dynamic_register_test_suite = { 638 .name = "drm_connector_dynamic_register", 639 .init = drm_test_connector_dynamic_register_init, 640 .exit = drm_test_connector_dynamic_register_cleanup, 641 .test_cases = drm_connector_dynamic_register_tests, 642}; 643 644/* 645 * Test that the registration of a bog standard connector works as 646 * expected and doesn't report any error. 647 */ 648static void drm_test_connector_hdmi_init_valid(struct kunit *test) 649{ 650 struct drm_connector_init_priv *priv = test->priv; 651 int ret; 652 653 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 654 "Vendor", "Product", 655 &dummy_funcs, 656 &dummy_hdmi_funcs, 657 DRM_MODE_CONNECTOR_HDMIA, 658 &priv->ddc, 659 BIT(HDMI_COLORSPACE_RGB), 660 8); 661 KUNIT_EXPECT_EQ(test, ret, 0); 662} 663 664/* 665 * Test that the registration of a connector without a DDC adapter 666 * doesn't report any error. 667 */ 668static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test) 669{ 670 struct drm_connector_init_priv *priv = test->priv; 671 int ret; 672 673 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 674 "Vendor", "Product", 675 &dummy_funcs, 676 &dummy_hdmi_funcs, 677 DRM_MODE_CONNECTOR_HDMIA, 678 NULL, 679 BIT(HDMI_COLORSPACE_RGB), 680 8); 681 KUNIT_EXPECT_EQ(test, ret, 0); 682} 683 684/* 685 * Test that the registration of an HDMI connector with a NULL vendor 686 * fails. 687 */ 688static void drm_test_connector_hdmi_init_null_vendor(struct kunit *test) 689{ 690 struct drm_connector_init_priv *priv = test->priv; 691 int ret; 692 693 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 694 NULL, "Product", 695 &dummy_funcs, 696 &dummy_hdmi_funcs, 697 DRM_MODE_CONNECTOR_HDMIA, 698 &priv->ddc, 699 BIT(HDMI_COLORSPACE_RGB), 700 8); 701 KUNIT_EXPECT_LT(test, ret, 0); 702} 703 704/* 705 * Test that the registration of an HDMI connector with a NULL product 706 * fails. 707 */ 708static void drm_test_connector_hdmi_init_null_product(struct kunit *test) 709{ 710 struct drm_connector_init_priv *priv = test->priv; 711 int ret; 712 713 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 714 "Vendor", NULL, 715 &dummy_funcs, 716 &dummy_hdmi_funcs, 717 DRM_MODE_CONNECTOR_HDMIA, 718 &priv->ddc, 719 BIT(HDMI_COLORSPACE_RGB), 720 8); 721 KUNIT_EXPECT_LT(test, ret, 0); 722} 723 724/* 725 * Test that the registration of a connector with a valid, shorter than 726 * the max length, product name succeeds, and is stored padded with 0. 727 */ 728static void drm_test_connector_hdmi_init_product_valid(struct kunit *test) 729{ 730 struct drm_connector_init_priv *priv = test->priv; 731 const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = { 732 'P', 'r', 'o', 'd', 733 }; 734 const char *product_name = "Prod"; 735 int ret; 736 737 KUNIT_ASSERT_LT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN); 738 739 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 740 "Vendor", product_name, 741 &dummy_funcs, 742 &dummy_hdmi_funcs, 743 DRM_MODE_CONNECTOR_HDMIA, 744 &priv->ddc, 745 BIT(HDMI_COLORSPACE_RGB), 746 8); 747 KUNIT_EXPECT_EQ(test, ret, 0); 748 KUNIT_EXPECT_MEMEQ(test, 749 priv->connector.hdmi.product, 750 expected_product, 751 sizeof(priv->connector.hdmi.product)); 752} 753 754/* 755 * Test that the registration of a connector with a valid, at max 756 * length, product name succeeds, and is stored padded without any 757 * trailing \0. 758 */ 759static void drm_test_connector_hdmi_init_product_length_exact(struct kunit *test) 760{ 761 struct drm_connector_init_priv *priv = test->priv; 762 const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = { 763 'P', 'r', 'o', 'd', 'u', 'c', 't', 764 'P', 'r', 'o', 'd', 'u', 'c', 't', 765 'P', 'r', 766 }; 767 const char *product_name = "ProductProductPr"; 768 int ret; 769 770 KUNIT_ASSERT_EQ(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN); 771 772 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 773 "Vendor", product_name, 774 &dummy_funcs, 775 &dummy_hdmi_funcs, 776 DRM_MODE_CONNECTOR_HDMIA, 777 &priv->ddc, 778 BIT(HDMI_COLORSPACE_RGB), 779 8); 780 KUNIT_EXPECT_EQ(test, ret, 0); 781 KUNIT_EXPECT_MEMEQ(test, 782 priv->connector.hdmi.product, 783 expected_product, 784 sizeof(priv->connector.hdmi.product)); 785} 786 787/* 788 * Test that the registration of a connector with a product name larger 789 * than the maximum length fails. 790 */ 791static void drm_test_connector_hdmi_init_product_length_too_long(struct kunit *test) 792{ 793 struct drm_connector_init_priv *priv = test->priv; 794 const char *product_name = "ProductProductProduct"; 795 int ret; 796 797 KUNIT_ASSERT_GT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN); 798 799 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 800 "Vendor", product_name, 801 &dummy_funcs, 802 &dummy_hdmi_funcs, 803 DRM_MODE_CONNECTOR_HDMIA, 804 &priv->ddc, 805 BIT(HDMI_COLORSPACE_RGB), 806 8); 807 KUNIT_EXPECT_LT(test, ret, 0); 808} 809 810/* 811 * Test that the registration of a connector with a vendor name smaller 812 * than the maximum length succeeds, and is stored padded with zeros. 813 */ 814static void drm_test_connector_hdmi_init_vendor_valid(struct kunit *test) 815{ 816 struct drm_connector_init_priv *priv = test->priv; 817 const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = { 818 'V', 'e', 'n', 'd', 819 }; 820 const char *vendor_name = "Vend"; 821 int ret; 822 823 KUNIT_ASSERT_LT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN); 824 825 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 826 vendor_name, "Product", 827 &dummy_funcs, 828 &dummy_hdmi_funcs, 829 DRM_MODE_CONNECTOR_HDMIA, 830 &priv->ddc, 831 BIT(HDMI_COLORSPACE_RGB), 832 8); 833 KUNIT_EXPECT_EQ(test, ret, 0); 834 KUNIT_EXPECT_MEMEQ(test, 835 priv->connector.hdmi.vendor, 836 expected_vendor, 837 sizeof(priv->connector.hdmi.vendor)); 838} 839 840/* 841 * Test that the registration of a connector with a vendor name at the 842 * maximum length succeeds, and is stored padded without the trailing 843 * zero. 844 */ 845static void drm_test_connector_hdmi_init_vendor_length_exact(struct kunit *test) 846{ 847 struct drm_connector_init_priv *priv = test->priv; 848 const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = { 849 'V', 'e', 'n', 'd', 'o', 'r', 850 'V', 'e', 851 }; 852 const char *vendor_name = "VendorVe"; 853 int ret; 854 855 KUNIT_ASSERT_EQ(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN); 856 857 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 858 vendor_name, "Product", 859 &dummy_funcs, 860 &dummy_hdmi_funcs, 861 DRM_MODE_CONNECTOR_HDMIA, 862 &priv->ddc, 863 BIT(HDMI_COLORSPACE_RGB), 864 8); 865 KUNIT_EXPECT_EQ(test, ret, 0); 866 KUNIT_EXPECT_MEMEQ(test, 867 priv->connector.hdmi.vendor, 868 expected_vendor, 869 sizeof(priv->connector.hdmi.vendor)); 870} 871 872/* 873 * Test that the registration of a connector with a vendor name larger 874 * than the maximum length fails. 875 */ 876static void drm_test_connector_hdmi_init_vendor_length_too_long(struct kunit *test) 877{ 878 struct drm_connector_init_priv *priv = test->priv; 879 const char *vendor_name = "VendorVendor"; 880 int ret; 881 882 KUNIT_ASSERT_GT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN); 883 884 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 885 vendor_name, "Product", 886 &dummy_funcs, 887 &dummy_hdmi_funcs, 888 DRM_MODE_CONNECTOR_HDMIA, 889 &priv->ddc, 890 BIT(HDMI_COLORSPACE_RGB), 891 8); 892 KUNIT_EXPECT_LT(test, ret, 0); 893} 894 895/* 896 * Test that the registration of a connector with an invalid maximum bpc 897 * count fails. 898 */ 899static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test) 900{ 901 struct drm_connector_init_priv *priv = test->priv; 902 int ret; 903 904 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 905 "Vendor", "Product", 906 &dummy_funcs, 907 &dummy_hdmi_funcs, 908 DRM_MODE_CONNECTOR_HDMIA, 909 &priv->ddc, 910 BIT(HDMI_COLORSPACE_RGB), 911 9); 912 KUNIT_EXPECT_LT(test, ret, 0); 913} 914 915/* 916 * Test that the registration of a connector with a null maximum bpc 917 * count fails. 918 */ 919static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test) 920{ 921 struct drm_connector_init_priv *priv = test->priv; 922 int ret; 923 924 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 925 "Vendor", "Product", 926 &dummy_funcs, 927 &dummy_hdmi_funcs, 928 DRM_MODE_CONNECTOR_HDMIA, 929 &priv->ddc, 930 BIT(HDMI_COLORSPACE_RGB), 931 0); 932 KUNIT_EXPECT_LT(test, ret, 0); 933} 934 935/* 936 * Test that the registration of a connector with a maximum bpc count of 937 * 8 succeeds, registers the max bpc property, but doesn't register the 938 * HDR output metadata one. 939 */ 940static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test) 941{ 942 struct drm_connector_init_priv *priv = test->priv; 943 struct drm_connector_state *state; 944 struct drm_connector *connector = &priv->connector; 945 struct drm_property *prop; 946 uint64_t val; 947 int ret; 948 949 ret = drmm_connector_hdmi_init(&priv->drm, connector, 950 "Vendor", "Product", 951 &dummy_funcs, 952 &dummy_hdmi_funcs, 953 DRM_MODE_CONNECTOR_HDMIA, 954 &priv->ddc, 955 BIT(HDMI_COLORSPACE_RGB), 956 8); 957 KUNIT_EXPECT_EQ(test, ret, 0); 958 959 prop = connector->max_bpc_property; 960 KUNIT_ASSERT_NOT_NULL(test, prop); 961 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 962 963 ret = drm_object_property_get_default_value(&connector->base, prop, &val); 964 KUNIT_EXPECT_EQ(test, ret, 0); 965 KUNIT_EXPECT_EQ(test, val, 8); 966 967 state = connector->state; 968 KUNIT_EXPECT_EQ(test, state->max_bpc, 8); 969 KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 8); 970 971 prop = priv->drm.mode_config.hdr_output_metadata_property; 972 KUNIT_ASSERT_NOT_NULL(test, prop); 973 KUNIT_EXPECT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 974} 975 976/* 977 * Test that the registration of a connector with a maximum bpc count of 978 * 10 succeeds and registers the max bpc and HDR output metadata 979 * properties. 980 */ 981static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test) 982{ 983 struct drm_connector_init_priv *priv = test->priv; 984 struct drm_connector_state *state; 985 struct drm_connector *connector = &priv->connector; 986 struct drm_property *prop; 987 uint64_t val; 988 int ret; 989 990 ret = drmm_connector_hdmi_init(&priv->drm, connector, 991 "Vendor", "Product", 992 &dummy_funcs, 993 &dummy_hdmi_funcs, 994 DRM_MODE_CONNECTOR_HDMIA, 995 &priv->ddc, 996 BIT(HDMI_COLORSPACE_RGB), 997 10); 998 KUNIT_EXPECT_EQ(test, ret, 0); 999 1000 prop = connector->max_bpc_property; 1001 KUNIT_ASSERT_NOT_NULL(test, prop); 1002 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 1003 1004 ret = drm_object_property_get_default_value(&connector->base, prop, &val); 1005 KUNIT_EXPECT_EQ(test, ret, 0); 1006 KUNIT_EXPECT_EQ(test, val, 10); 1007 1008 state = connector->state; 1009 KUNIT_EXPECT_EQ(test, state->max_bpc, 10); 1010 KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 10); 1011 1012 prop = priv->drm.mode_config.hdr_output_metadata_property; 1013 KUNIT_ASSERT_NOT_NULL(test, prop); 1014 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 1015} 1016 1017/* 1018 * Test that the registration of a connector with a maximum bpc count of 1019 * 12 succeeds and registers the max bpc and HDR output metadata 1020 * properties. 1021 */ 1022static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test) 1023{ 1024 struct drm_connector_init_priv *priv = test->priv; 1025 struct drm_connector_state *state; 1026 struct drm_connector *connector = &priv->connector; 1027 struct drm_property *prop; 1028 uint64_t val; 1029 int ret; 1030 1031 ret = drmm_connector_hdmi_init(&priv->drm, connector, 1032 "Vendor", "Product", 1033 &dummy_funcs, 1034 &dummy_hdmi_funcs, 1035 DRM_MODE_CONNECTOR_HDMIA, 1036 &priv->ddc, 1037 BIT(HDMI_COLORSPACE_RGB), 1038 12); 1039 KUNIT_EXPECT_EQ(test, ret, 0); 1040 1041 prop = connector->max_bpc_property; 1042 KUNIT_ASSERT_NOT_NULL(test, prop); 1043 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 1044 1045 ret = drm_object_property_get_default_value(&connector->base, prop, &val); 1046 KUNIT_EXPECT_EQ(test, ret, 0); 1047 KUNIT_EXPECT_EQ(test, val, 12); 1048 1049 state = connector->state; 1050 KUNIT_EXPECT_EQ(test, state->max_bpc, 12); 1051 KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 12); 1052 1053 prop = priv->drm.mode_config.hdr_output_metadata_property; 1054 KUNIT_ASSERT_NOT_NULL(test, prop); 1055 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 1056} 1057 1058/* 1059 * Test that the registration of an HDMI connector with no supported 1060 * format fails. 1061 */ 1062static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test) 1063{ 1064 struct drm_connector_init_priv *priv = test->priv; 1065 int ret; 1066 1067 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 1068 "Vendor", "Product", 1069 &dummy_funcs, 1070 &dummy_hdmi_funcs, 1071 DRM_MODE_CONNECTOR_HDMIA, 1072 &priv->ddc, 1073 0, 1074 8); 1075 KUNIT_EXPECT_LT(test, ret, 0); 1076} 1077 1078/* 1079 * Test that the registration of an HDMI connector not listing RGB as a 1080 * supported format fails. 1081 */ 1082static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test) 1083{ 1084 struct drm_connector_init_priv *priv = test->priv; 1085 int ret; 1086 1087 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 1088 "Vendor", "Product", 1089 &dummy_funcs, 1090 &dummy_hdmi_funcs, 1091 DRM_MODE_CONNECTOR_HDMIA, 1092 &priv->ddc, 1093 BIT(HDMI_COLORSPACE_YUV422), 1094 8); 1095 KUNIT_EXPECT_LT(test, ret, 0); 1096} 1097 1098struct drm_connector_hdmi_init_formats_yuv420_allowed_test { 1099 unsigned long supported_formats; 1100 bool yuv420_allowed; 1101 int expected_result; 1102}; 1103 1104#define YUV420_ALLOWED_TEST(_formats, _allowed, _result) \ 1105 { \ 1106 .supported_formats = BIT(HDMI_COLORSPACE_RGB) | (_formats), \ 1107 .yuv420_allowed = _allowed, \ 1108 .expected_result = _result, \ 1109 } 1110 1111static const struct drm_connector_hdmi_init_formats_yuv420_allowed_test 1112drm_connector_hdmi_init_formats_yuv420_allowed_tests[] = { 1113 YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV420), true, 0), 1114 YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV420), false, -EINVAL), 1115 YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV422), true, -EINVAL), 1116 YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV422), false, 0), 1117}; 1118 1119static void 1120drm_connector_hdmi_init_formats_yuv420_allowed_desc(const struct drm_connector_hdmi_init_formats_yuv420_allowed_test *t, 1121 char *desc) 1122{ 1123 sprintf(desc, "supported_formats=0x%lx yuv420_allowed=%d", 1124 t->supported_formats, t->yuv420_allowed); 1125} 1126 1127KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_formats_yuv420_allowed, 1128 drm_connector_hdmi_init_formats_yuv420_allowed_tests, 1129 drm_connector_hdmi_init_formats_yuv420_allowed_desc); 1130 1131/* 1132 * Test that the registration of an HDMI connector succeeds only when 1133 * the presence of YUV420 in the supported formats matches the value 1134 * of the ycbcr_420_allowed flag. 1135 */ 1136static void drm_test_connector_hdmi_init_formats_yuv420_allowed(struct kunit *test) 1137{ 1138 const struct drm_connector_hdmi_init_formats_yuv420_allowed_test *params; 1139 struct drm_connector_init_priv *priv = test->priv; 1140 int ret; 1141 1142 params = test->param_value; 1143 priv->connector.ycbcr_420_allowed = params->yuv420_allowed; 1144 1145 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 1146 "Vendor", "Product", 1147 &dummy_funcs, 1148 &dummy_hdmi_funcs, 1149 DRM_MODE_CONNECTOR_HDMIA, 1150 &priv->ddc, 1151 params->supported_formats, 1152 8); 1153 KUNIT_EXPECT_EQ(test, ret, params->expected_result); 1154} 1155 1156/* 1157 * Test that the registration of an HDMI connector with an HDMI 1158 * connector type succeeds. 1159 */ 1160static void drm_test_connector_hdmi_init_type_valid(struct kunit *test) 1161{ 1162 struct drm_connector_init_priv *priv = test->priv; 1163 unsigned int connector_type = *(unsigned int *)test->param_value; 1164 int ret; 1165 1166 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 1167 "Vendor", "Product", 1168 &dummy_funcs, 1169 &dummy_hdmi_funcs, 1170 connector_type, 1171 &priv->ddc, 1172 BIT(HDMI_COLORSPACE_RGB), 1173 8); 1174 KUNIT_EXPECT_EQ(test, ret, 0); 1175} 1176 1177static const unsigned int drm_connector_hdmi_init_type_valid_tests[] = { 1178 DRM_MODE_CONNECTOR_HDMIA, 1179 DRM_MODE_CONNECTOR_HDMIB, 1180}; 1181 1182static void drm_connector_hdmi_init_type_desc(const unsigned int *type, char *desc) 1183{ 1184 sprintf(desc, "%s", drm_get_connector_type_name(*type)); 1185} 1186 1187KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_valid, 1188 drm_connector_hdmi_init_type_valid_tests, 1189 drm_connector_hdmi_init_type_desc); 1190 1191/* 1192 * Test that the registration of an HDMI connector with an !HDMI 1193 * connector type fails. 1194 */ 1195static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test) 1196{ 1197 struct drm_connector_init_priv *priv = test->priv; 1198 unsigned int connector_type = *(unsigned int *)test->param_value; 1199 int ret; 1200 1201 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 1202 "Vendor", "Product", 1203 &dummy_funcs, 1204 &dummy_hdmi_funcs, 1205 connector_type, 1206 &priv->ddc, 1207 BIT(HDMI_COLORSPACE_RGB), 1208 8); 1209 KUNIT_EXPECT_LT(test, ret, 0); 1210} 1211 1212static const unsigned int drm_connector_hdmi_init_type_invalid_tests[] = { 1213 DRM_MODE_CONNECTOR_Unknown, 1214 DRM_MODE_CONNECTOR_VGA, 1215 DRM_MODE_CONNECTOR_DVII, 1216 DRM_MODE_CONNECTOR_DVID, 1217 DRM_MODE_CONNECTOR_DVIA, 1218 DRM_MODE_CONNECTOR_Composite, 1219 DRM_MODE_CONNECTOR_SVIDEO, 1220 DRM_MODE_CONNECTOR_LVDS, 1221 DRM_MODE_CONNECTOR_Component, 1222 DRM_MODE_CONNECTOR_9PinDIN, 1223 DRM_MODE_CONNECTOR_DisplayPort, 1224 DRM_MODE_CONNECTOR_TV, 1225 DRM_MODE_CONNECTOR_eDP, 1226 DRM_MODE_CONNECTOR_VIRTUAL, 1227 DRM_MODE_CONNECTOR_DSI, 1228 DRM_MODE_CONNECTOR_DPI, 1229 DRM_MODE_CONNECTOR_WRITEBACK, 1230 DRM_MODE_CONNECTOR_SPI, 1231 DRM_MODE_CONNECTOR_USB, 1232}; 1233 1234KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid, 1235 drm_connector_hdmi_init_type_invalid_tests, 1236 drm_connector_hdmi_init_type_desc); 1237 1238static struct kunit_case drmm_connector_hdmi_init_tests[] = { 1239 KUNIT_CASE(drm_test_connector_hdmi_init_valid), 1240 KUNIT_CASE(drm_test_connector_hdmi_init_bpc_8), 1241 KUNIT_CASE(drm_test_connector_hdmi_init_bpc_10), 1242 KUNIT_CASE(drm_test_connector_hdmi_init_bpc_12), 1243 KUNIT_CASE(drm_test_connector_hdmi_init_bpc_invalid), 1244 KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null), 1245 KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty), 1246 KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb), 1247 KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_formats_yuv420_allowed, 1248 drm_connector_hdmi_init_formats_yuv420_allowed_gen_params), 1249 KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc), 1250 KUNIT_CASE(drm_test_connector_hdmi_init_null_product), 1251 KUNIT_CASE(drm_test_connector_hdmi_init_null_vendor), 1252 KUNIT_CASE(drm_test_connector_hdmi_init_product_length_exact), 1253 KUNIT_CASE(drm_test_connector_hdmi_init_product_length_too_long), 1254 KUNIT_CASE(drm_test_connector_hdmi_init_product_valid), 1255 KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_exact), 1256 KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_too_long), 1257 KUNIT_CASE(drm_test_connector_hdmi_init_vendor_valid), 1258 KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid, 1259 drm_connector_hdmi_init_type_valid_gen_params), 1260 KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid, 1261 drm_connector_hdmi_init_type_invalid_gen_params), 1262 { } 1263}; 1264 1265static struct kunit_suite drmm_connector_hdmi_init_test_suite = { 1266 .name = "drmm_connector_hdmi_init", 1267 .init = drm_test_connector_init, 1268 .test_cases = drmm_connector_hdmi_init_tests, 1269}; 1270 1271struct drm_get_tv_mode_from_name_test { 1272 const char *name; 1273 enum drm_connector_tv_mode expected_mode; 1274}; 1275 1276#define TV_MODE_NAME(_name, _mode) \ 1277 { \ 1278 .name = _name, \ 1279 .expected_mode = _mode, \ 1280 } 1281 1282static void drm_test_get_tv_mode_from_name_valid(struct kunit *test) 1283{ 1284 const struct drm_get_tv_mode_from_name_test *params = test->param_value; 1285 1286 KUNIT_EXPECT_EQ(test, 1287 drm_get_tv_mode_from_name(params->name, strlen(params->name)), 1288 params->expected_mode); 1289} 1290 1291static const 1292struct drm_get_tv_mode_from_name_test drm_get_tv_mode_from_name_valid_tests[] = { 1293 TV_MODE_NAME("NTSC", DRM_MODE_TV_MODE_NTSC), 1294 TV_MODE_NAME("NTSC-443", DRM_MODE_TV_MODE_NTSC_443), 1295 TV_MODE_NAME("NTSC-J", DRM_MODE_TV_MODE_NTSC_J), 1296 TV_MODE_NAME("PAL", DRM_MODE_TV_MODE_PAL), 1297 TV_MODE_NAME("PAL-M", DRM_MODE_TV_MODE_PAL_M), 1298 TV_MODE_NAME("PAL-N", DRM_MODE_TV_MODE_PAL_N), 1299 TV_MODE_NAME("SECAM", DRM_MODE_TV_MODE_SECAM), 1300 TV_MODE_NAME("Mono", DRM_MODE_TV_MODE_MONOCHROME), 1301}; 1302 1303static void 1304drm_get_tv_mode_from_name_valid_desc(const struct drm_get_tv_mode_from_name_test *t, 1305 char *desc) 1306{ 1307 sprintf(desc, "%s", t->name); 1308} 1309 1310KUNIT_ARRAY_PARAM(drm_get_tv_mode_from_name_valid, 1311 drm_get_tv_mode_from_name_valid_tests, 1312 drm_get_tv_mode_from_name_valid_desc); 1313 1314static void drm_test_get_tv_mode_from_name_truncated(struct kunit *test) 1315{ 1316 const char *name = "NTS"; 1317 int ret; 1318 1319 ret = drm_get_tv_mode_from_name(name, strlen(name)); 1320 KUNIT_EXPECT_LT(test, ret, 0); 1321}; 1322 1323static struct kunit_case drm_get_tv_mode_from_name_tests[] = { 1324 KUNIT_CASE_PARAM(drm_test_get_tv_mode_from_name_valid, 1325 drm_get_tv_mode_from_name_valid_gen_params), 1326 KUNIT_CASE(drm_test_get_tv_mode_from_name_truncated), 1327 { } 1328}; 1329 1330static struct kunit_suite drm_get_tv_mode_from_name_test_suite = { 1331 .name = "drm_get_tv_mode_from_name", 1332 .test_cases = drm_get_tv_mode_from_name_tests, 1333}; 1334 1335struct drm_hdmi_connector_get_broadcast_rgb_name_test { 1336 unsigned int kind; 1337 const char *expected_name; 1338}; 1339 1340#define BROADCAST_RGB_TEST(_kind, _name) \ 1341 { \ 1342 .kind = _kind, \ 1343 .expected_name = _name, \ 1344 } 1345 1346static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name(struct kunit *test) 1347{ 1348 const struct drm_hdmi_connector_get_broadcast_rgb_name_test *params = 1349 test->param_value; 1350 1351 KUNIT_EXPECT_STREQ(test, 1352 drm_hdmi_connector_get_broadcast_rgb_name(params->kind), 1353 params->expected_name); 1354} 1355 1356static const 1357struct drm_hdmi_connector_get_broadcast_rgb_name_test 1358drm_hdmi_connector_get_broadcast_rgb_name_valid_tests[] = { 1359 BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic"), 1360 BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_FULL, "Full"), 1361 BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235"), 1362}; 1363 1364static void 1365drm_hdmi_connector_get_broadcast_rgb_name_valid_desc(const struct drm_hdmi_connector_get_broadcast_rgb_name_test *t, 1366 char *desc) 1367{ 1368 sprintf(desc, "%s", t->expected_name); 1369} 1370 1371KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_broadcast_rgb_name_valid, 1372 drm_hdmi_connector_get_broadcast_rgb_name_valid_tests, 1373 drm_hdmi_connector_get_broadcast_rgb_name_valid_desc); 1374 1375static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid(struct kunit *test) 1376{ 1377 KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_broadcast_rgb_name(3)); 1378}; 1379 1380static struct kunit_case drm_hdmi_connector_get_broadcast_rgb_name_tests[] = { 1381 KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_broadcast_rgb_name, 1382 drm_hdmi_connector_get_broadcast_rgb_name_valid_gen_params), 1383 KUNIT_CASE(drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid), 1384 { } 1385}; 1386 1387static struct kunit_suite drm_hdmi_connector_get_broadcast_rgb_name_test_suite = { 1388 .name = "drm_hdmi_connector_get_broadcast_rgb_name", 1389 .test_cases = drm_hdmi_connector_get_broadcast_rgb_name_tests, 1390}; 1391 1392struct drm_hdmi_connector_get_output_format_name_test { 1393 unsigned int kind; 1394 const char *expected_name; 1395}; 1396 1397#define OUTPUT_FORMAT_TEST(_kind, _name) \ 1398 { \ 1399 .kind = _kind, \ 1400 .expected_name = _name, \ 1401 } 1402 1403static void drm_test_drm_hdmi_connector_get_output_format_name(struct kunit *test) 1404{ 1405 const struct drm_hdmi_connector_get_output_format_name_test *params = 1406 test->param_value; 1407 1408 KUNIT_EXPECT_STREQ(test, 1409 drm_hdmi_connector_get_output_format_name(params->kind), 1410 params->expected_name); 1411} 1412 1413static const 1414struct drm_hdmi_connector_get_output_format_name_test 1415drm_hdmi_connector_get_output_format_name_valid_tests[] = { 1416 OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_RGB, "RGB"), 1417 OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV420, "YUV 4:2:0"), 1418 OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV422, "YUV 4:2:2"), 1419 OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV444, "YUV 4:4:4"), 1420}; 1421 1422static void 1423drm_hdmi_connector_get_output_format_name_valid_desc(const struct drm_hdmi_connector_get_output_format_name_test *t, 1424 char *desc) 1425{ 1426 sprintf(desc, "%s", t->expected_name); 1427} 1428 1429KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_output_format_name_valid, 1430 drm_hdmi_connector_get_output_format_name_valid_tests, 1431 drm_hdmi_connector_get_output_format_name_valid_desc); 1432 1433static void drm_test_drm_hdmi_connector_get_output_format_name_invalid(struct kunit *test) 1434{ 1435 KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_output_format_name(4)); 1436}; 1437 1438static struct kunit_case drm_hdmi_connector_get_output_format_name_tests[] = { 1439 KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_output_format_name, 1440 drm_hdmi_connector_get_output_format_name_valid_gen_params), 1441 KUNIT_CASE(drm_test_drm_hdmi_connector_get_output_format_name_invalid), 1442 { } 1443}; 1444 1445static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite = { 1446 .name = "drm_hdmi_connector_get_output_format_name", 1447 .test_cases = drm_hdmi_connector_get_output_format_name_tests, 1448}; 1449 1450static void drm_test_drm_connector_attach_broadcast_rgb_property(struct kunit *test) 1451{ 1452 struct drm_connector_init_priv *priv = test->priv; 1453 struct drm_connector *connector = &priv->connector; 1454 struct drm_property *prop; 1455 int ret; 1456 1457 ret = drmm_connector_init(&priv->drm, connector, 1458 &dummy_funcs, 1459 DRM_MODE_CONNECTOR_HDMIA, 1460 &priv->ddc); 1461 KUNIT_ASSERT_EQ(test, ret, 0); 1462 1463 ret = drm_connector_attach_broadcast_rgb_property(connector); 1464 KUNIT_ASSERT_EQ(test, ret, 0); 1465 1466 prop = connector->broadcast_rgb_property; 1467 KUNIT_ASSERT_NOT_NULL(test, prop); 1468 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 1469} 1470 1471static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(struct kunit *test) 1472{ 1473 struct drm_connector_init_priv *priv = test->priv; 1474 struct drm_connector *connector = &priv->connector; 1475 struct drm_property *prop; 1476 int ret; 1477 1478 ret = drmm_connector_hdmi_init(&priv->drm, connector, 1479 "Vendor", "Product", 1480 &dummy_funcs, 1481 &dummy_hdmi_funcs, 1482 DRM_MODE_CONNECTOR_HDMIA, 1483 &priv->ddc, 1484 BIT(HDMI_COLORSPACE_RGB), 1485 8); 1486 KUNIT_EXPECT_EQ(test, ret, 0); 1487 1488 ret = drm_connector_attach_broadcast_rgb_property(connector); 1489 KUNIT_ASSERT_EQ(test, ret, 0); 1490 1491 prop = connector->broadcast_rgb_property; 1492 KUNIT_ASSERT_NOT_NULL(test, prop); 1493 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 1494} 1495 1496static struct kunit_case drm_connector_attach_broadcast_rgb_property_tests[] = { 1497 KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property), 1498 KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector), 1499 { } 1500}; 1501 1502static struct kunit_suite drm_connector_attach_broadcast_rgb_property_test_suite = { 1503 .name = "drm_connector_attach_broadcast_rgb_property", 1504 .init = drm_test_connector_init, 1505 .test_cases = drm_connector_attach_broadcast_rgb_property_tests, 1506}; 1507 1508/* 1509 * Test that for a given mode, with 8bpc and an RGB output the TMDS 1510 * character rate is equal to the mode pixel clock. 1511 */ 1512static void drm_test_drm_hdmi_compute_mode_clock_rgb(struct kunit *test) 1513{ 1514 struct drm_connector_init_priv *priv = test->priv; 1515 const struct drm_display_mode *mode; 1516 unsigned long long rate; 1517 struct drm_device *drm = &priv->drm; 1518 1519 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16); 1520 KUNIT_ASSERT_NOT_NULL(test, mode); 1521 1522 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1523 1524 rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); 1525 KUNIT_ASSERT_GT(test, rate, 0); 1526 KUNIT_EXPECT_EQ(test, mode->clock * 1000ULL, rate); 1527} 1528 1529/* 1530 * Test that for a given mode, with 10bpc and an RGB output the TMDS 1531 * character rate is equal to 1.25 times the mode pixel clock. 1532 */ 1533static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc(struct kunit *test) 1534{ 1535 struct drm_connector_init_priv *priv = test->priv; 1536 const struct drm_display_mode *mode; 1537 unsigned long long rate; 1538 struct drm_device *drm = &priv->drm; 1539 1540 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16); 1541 KUNIT_ASSERT_NOT_NULL(test, mode); 1542 1543 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1544 1545 rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB); 1546 KUNIT_ASSERT_GT(test, rate, 0); 1547 KUNIT_EXPECT_EQ(test, mode->clock * 1250, rate); 1548} 1549 1550/* 1551 * Test that for the VIC-1 mode, with 10bpc and an RGB output the TMDS 1552 * character rate computation fails. 1553 */ 1554static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *test) 1555{ 1556 struct drm_connector_init_priv *priv = test->priv; 1557 const struct drm_display_mode *mode; 1558 unsigned long long rate; 1559 struct drm_device *drm = &priv->drm; 1560 1561 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); 1562 KUNIT_ASSERT_NOT_NULL(test, mode); 1563 1564 rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB); 1565 KUNIT_EXPECT_EQ(test, rate, 0); 1566} 1567 1568/* 1569 * Test that for a given mode, with 12bpc and an RGB output the TMDS 1570 * character rate is equal to 1.5 times the mode pixel clock. 1571 */ 1572static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test) 1573{ 1574 struct drm_connector_init_priv *priv = test->priv; 1575 const struct drm_display_mode *mode; 1576 unsigned long long rate; 1577 struct drm_device *drm = &priv->drm; 1578 1579 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16); 1580 KUNIT_ASSERT_NOT_NULL(test, mode); 1581 1582 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1583 1584 rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB); 1585 KUNIT_ASSERT_GT(test, rate, 0); 1586 KUNIT_EXPECT_EQ(test, mode->clock * 1500, rate); 1587} 1588 1589/* 1590 * Test that for the VIC-1 mode, with 12bpc and an RGB output the TMDS 1591 * character rate computation fails. 1592 */ 1593static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *test) 1594{ 1595 struct drm_connector_init_priv *priv = test->priv; 1596 const struct drm_display_mode *mode; 1597 unsigned long long rate; 1598 struct drm_device *drm = &priv->drm; 1599 1600 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); 1601 KUNIT_ASSERT_NOT_NULL(test, mode); 1602 1603 rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB); 1604 KUNIT_EXPECT_EQ(test, rate, 0); 1605} 1606 1607/* 1608 * Test that for a mode with the pixel repetition flag, the TMDS 1609 * character rate is indeed double the mode pixel clock. 1610 */ 1611static void drm_test_drm_hdmi_compute_mode_clock_rgb_double(struct kunit *test) 1612{ 1613 struct drm_connector_init_priv *priv = test->priv; 1614 const struct drm_display_mode *mode; 1615 unsigned long long rate; 1616 struct drm_device *drm = &priv->drm; 1617 1618 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 6); 1619 KUNIT_ASSERT_NOT_NULL(test, mode); 1620 1621 KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1622 1623 rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); 1624 KUNIT_ASSERT_GT(test, rate, 0); 1625 KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) * 2, rate); 1626} 1627 1628/* 1629 * Test that the TMDS character rate computation for the VIC modes 1630 * explicitly listed in the spec as supporting YUV420 succeed and return 1631 * half the mode pixel clock. 1632 */ 1633static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit *test) 1634{ 1635 struct drm_connector_init_priv *priv = test->priv; 1636 const struct drm_display_mode *mode; 1637 struct drm_device *drm = &priv->drm; 1638 unsigned long long rate; 1639 unsigned int vic = *(unsigned int *)test->param_value; 1640 1641 mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic); 1642 KUNIT_ASSERT_NOT_NULL(test, mode); 1643 1644 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1645 1646 rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420); 1647 KUNIT_ASSERT_GT(test, rate, 0); 1648 KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) / 2, rate); 1649} 1650 1651static const unsigned int drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[] = { 1652 96, 97, 101, 102, 106, 107, 1653}; 1654 1655static void drm_hdmi_compute_mode_clock_yuv420_vic_desc(const unsigned int *vic, char *desc) 1656{ 1657 sprintf(desc, "VIC %u", *vic); 1658} 1659 1660KUNIT_ARRAY_PARAM(drm_hdmi_compute_mode_clock_yuv420_valid, 1661 drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests, 1662 drm_hdmi_compute_mode_clock_yuv420_vic_desc); 1663 1664/* 1665 * Test that for a given mode listed supporting it and an YUV420 output 1666 * with 10bpc, the TMDS character rate is equal to 0.625 times the mode 1667 * pixel clock. 1668 */ 1669static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kunit *test) 1670{ 1671 struct drm_connector_init_priv *priv = test->priv; 1672 const struct drm_display_mode *mode; 1673 struct drm_device *drm = &priv->drm; 1674 unsigned int vic = 1675 drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; 1676 unsigned long long rate; 1677 1678 mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic); 1679 KUNIT_ASSERT_NOT_NULL(test, mode); 1680 1681 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1682 1683 rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV420); 1684 KUNIT_ASSERT_GT(test, rate, 0); 1685 1686 KUNIT_EXPECT_EQ(test, mode->clock * 625, rate); 1687} 1688 1689/* 1690 * Test that for a given mode listed supporting it and an YUV420 output 1691 * with 12bpc, the TMDS character rate is equal to 0.75 times the mode 1692 * pixel clock. 1693 */ 1694static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kunit *test) 1695{ 1696 struct drm_connector_init_priv *priv = test->priv; 1697 const struct drm_display_mode *mode; 1698 struct drm_device *drm = &priv->drm; 1699 unsigned int vic = 1700 drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; 1701 unsigned long long rate; 1702 1703 mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic); 1704 KUNIT_ASSERT_NOT_NULL(test, mode); 1705 1706 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1707 1708 rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV420); 1709 KUNIT_ASSERT_GT(test, rate, 0); 1710 1711 KUNIT_EXPECT_EQ(test, mode->clock * 750, rate); 1712} 1713 1714/* 1715 * Test that for a given mode, the computation of the TMDS character 1716 * rate with 8bpc and a YUV422 output succeeds and returns a rate equal 1717 * to the mode pixel clock. 1718 */ 1719static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit *test) 1720{ 1721 struct drm_connector_init_priv *priv = test->priv; 1722 const struct drm_display_mode *mode; 1723 struct drm_device *drm = &priv->drm; 1724 unsigned long long rate; 1725 1726 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16); 1727 KUNIT_ASSERT_NOT_NULL(test, mode); 1728 1729 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1730 1731 rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV422); 1732 KUNIT_ASSERT_GT(test, rate, 0); 1733 KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate); 1734} 1735 1736/* 1737 * Test that for a given mode, the computation of the TMDS character 1738 * rate with 10bpc and a YUV422 output succeeds and returns a rate equal 1739 * to the mode pixel clock. 1740 */ 1741static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kunit *test) 1742{ 1743 struct drm_connector_init_priv *priv = test->priv; 1744 const struct drm_display_mode *mode; 1745 struct drm_device *drm = &priv->drm; 1746 unsigned long long rate; 1747 1748 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16); 1749 KUNIT_ASSERT_NOT_NULL(test, mode); 1750 1751 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1752 1753 rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV422); 1754 KUNIT_ASSERT_GT(test, rate, 0); 1755 KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate); 1756} 1757 1758/* 1759 * Test that for a given mode, the computation of the TMDS character 1760 * rate with 12bpc and a YUV422 output succeeds and returns a rate equal 1761 * to the mode pixel clock. 1762 */ 1763static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kunit *test) 1764{ 1765 struct drm_connector_init_priv *priv = test->priv; 1766 const struct drm_display_mode *mode; 1767 struct drm_device *drm = &priv->drm; 1768 unsigned long long rate; 1769 1770 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16); 1771 KUNIT_ASSERT_NOT_NULL(test, mode); 1772 1773 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1774 1775 rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV422); 1776 KUNIT_ASSERT_GT(test, rate, 0); 1777 KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate); 1778} 1779 1780static struct kunit_case drm_hdmi_compute_mode_clock_tests[] = { 1781 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb), 1782 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc), 1783 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1), 1784 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc), 1785 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1), 1786 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_double), 1787 KUNIT_CASE_PARAM(drm_test_connector_hdmi_compute_mode_clock_yuv420_valid, 1788 drm_hdmi_compute_mode_clock_yuv420_valid_gen_params), 1789 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc), 1790 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc), 1791 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc), 1792 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc), 1793 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc), 1794 { } 1795}; 1796 1797static struct kunit_suite drm_hdmi_compute_mode_clock_test_suite = { 1798 .name = "drm_test_connector_hdmi_compute_mode_clock", 1799 .init = drm_test_connector_init, 1800 .test_cases = drm_hdmi_compute_mode_clock_tests, 1801}; 1802 1803kunit_test_suites( 1804 &drmm_connector_hdmi_init_test_suite, 1805 &drmm_connector_init_test_suite, 1806 &drm_connector_dynamic_init_test_suite, 1807 &drm_connector_dynamic_register_early_test_suite, 1808 &drm_connector_dynamic_register_test_suite, 1809 &drm_connector_attach_broadcast_rgb_property_test_suite, 1810 &drm_get_tv_mode_from_name_test_suite, 1811 &drm_hdmi_compute_mode_clock_test_suite, 1812 &drm_hdmi_connector_get_broadcast_rgb_name_test_suite, 1813 &drm_hdmi_connector_get_output_format_name_test_suite 1814); 1815 1816MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>"); 1817MODULE_DESCRIPTION("Kunit test for drm_modes functions"); 1818MODULE_LICENSE("GPL");