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_kunit_helpers.h> 13 #include <drm/drm_modes.h> 14 15 #include <drm/display/drm_hdmi_helper.h> 16 17 #include <kunit/test.h> 18 19 #include "../drm_crtc_internal.h" 20 21 struct drm_connector_init_priv { 22 struct drm_device drm; 23 struct drm_connector connector; 24 struct i2c_adapter ddc; 25 }; 26 27 static const struct drm_connector_hdmi_funcs dummy_hdmi_funcs = { 28 }; 29 30 static const struct drm_connector_funcs dummy_funcs = { 31 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 32 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 33 .reset = drm_atomic_helper_connector_reset, 34 }; 35 36 static int dummy_ddc_xfer(struct i2c_adapter *adapter, 37 struct i2c_msg *msgs, int num) 38 { 39 return num; 40 } 41 42 static u32 dummy_ddc_func(struct i2c_adapter *adapter) 43 { 44 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 45 } 46 47 static const struct i2c_algorithm dummy_ddc_algorithm = { 48 .master_xfer = dummy_ddc_xfer, 49 .functionality = dummy_ddc_func, 50 }; 51 52 static void i2c_del_adapter_wrapper(void *ptr) 53 { 54 struct i2c_adapter *adap = ptr; 55 56 i2c_del_adapter(adap); 57 } 58 59 static int drm_test_connector_init(struct kunit *test) 60 { 61 struct drm_connector_init_priv *priv; 62 struct device *dev; 63 int ret; 64 65 dev = drm_kunit_helper_alloc_device(test); 66 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 67 68 priv = drm_kunit_helper_alloc_drm_device(test, dev, 69 struct drm_connector_init_priv, drm, 70 DRIVER_MODESET | DRIVER_ATOMIC); 71 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); 72 73 strscpy(priv->ddc.name, "dummy-connector-ddc", sizeof(priv->ddc.name)); 74 priv->ddc.owner = THIS_MODULE; 75 priv->ddc.algo = &dummy_ddc_algorithm; 76 priv->ddc.dev.parent = dev; 77 78 ret = i2c_add_adapter(&priv->ddc); 79 KUNIT_ASSERT_EQ(test, ret, 0); 80 81 ret = kunit_add_action_or_reset(test, i2c_del_adapter_wrapper, &priv->ddc); 82 KUNIT_ASSERT_EQ(test, ret, 0); 83 84 test->priv = priv; 85 return 0; 86 } 87 88 /* 89 * Test that the registration of a bog standard connector works as 90 * expected and doesn't report any error. 91 */ 92 static void drm_test_drmm_connector_init(struct kunit *test) 93 { 94 struct drm_connector_init_priv *priv = test->priv; 95 int ret; 96 97 ret = drmm_connector_init(&priv->drm, &priv->connector, 98 &dummy_funcs, 99 DRM_MODE_CONNECTOR_HDMIA, 100 &priv->ddc); 101 KUNIT_EXPECT_EQ(test, ret, 0); 102 } 103 104 /* 105 * Test that the registration of a connector without a DDC adapter 106 * doesn't report any error. 107 */ 108 static void drm_test_drmm_connector_init_null_ddc(struct kunit *test) 109 { 110 struct drm_connector_init_priv *priv = test->priv; 111 int ret; 112 113 ret = drmm_connector_init(&priv->drm, &priv->connector, 114 &dummy_funcs, 115 DRM_MODE_CONNECTOR_HDMIA, 116 NULL); 117 KUNIT_EXPECT_EQ(test, ret, 0); 118 } 119 120 /* 121 * Test that the registration of a connector succeeds for all possible 122 * connector types. 123 */ 124 static void drm_test_drmm_connector_init_type_valid(struct kunit *test) 125 { 126 struct drm_connector_init_priv *priv = test->priv; 127 unsigned int connector_type = *(unsigned int *)test->param_value; 128 int ret; 129 130 ret = drmm_connector_init(&priv->drm, &priv->connector, 131 &dummy_funcs, 132 connector_type, 133 &priv->ddc); 134 KUNIT_EXPECT_EQ(test, ret, 0); 135 } 136 137 static const unsigned int drm_connector_init_type_valid_tests[] = { 138 DRM_MODE_CONNECTOR_Unknown, 139 DRM_MODE_CONNECTOR_VGA, 140 DRM_MODE_CONNECTOR_DVII, 141 DRM_MODE_CONNECTOR_DVID, 142 DRM_MODE_CONNECTOR_DVIA, 143 DRM_MODE_CONNECTOR_Composite, 144 DRM_MODE_CONNECTOR_SVIDEO, 145 DRM_MODE_CONNECTOR_LVDS, 146 DRM_MODE_CONNECTOR_Component, 147 DRM_MODE_CONNECTOR_9PinDIN, 148 DRM_MODE_CONNECTOR_DisplayPort, 149 DRM_MODE_CONNECTOR_HDMIA, 150 DRM_MODE_CONNECTOR_HDMIB, 151 DRM_MODE_CONNECTOR_TV, 152 DRM_MODE_CONNECTOR_eDP, 153 DRM_MODE_CONNECTOR_VIRTUAL, 154 DRM_MODE_CONNECTOR_DSI, 155 DRM_MODE_CONNECTOR_DPI, 156 DRM_MODE_CONNECTOR_WRITEBACK, 157 DRM_MODE_CONNECTOR_SPI, 158 DRM_MODE_CONNECTOR_USB, 159 }; 160 161 static void drm_connector_init_type_desc(const unsigned int *type, char *desc) 162 { 163 sprintf(desc, "%s", drm_get_connector_type_name(*type)); 164 } 165 166 KUNIT_ARRAY_PARAM(drm_connector_init_type_valid, 167 drm_connector_init_type_valid_tests, 168 drm_connector_init_type_desc); 169 170 static struct kunit_case drmm_connector_init_tests[] = { 171 KUNIT_CASE(drm_test_drmm_connector_init), 172 KUNIT_CASE(drm_test_drmm_connector_init_null_ddc), 173 KUNIT_CASE_PARAM(drm_test_drmm_connector_init_type_valid, 174 drm_connector_init_type_valid_gen_params), 175 { } 176 }; 177 178 static struct kunit_suite drmm_connector_init_test_suite = { 179 .name = "drmm_connector_init", 180 .init = drm_test_connector_init, 181 .test_cases = drmm_connector_init_tests, 182 }; 183 184 /* 185 * Test that the registration of a bog standard connector works as 186 * expected and doesn't report any error. 187 */ 188 static void drm_test_connector_hdmi_init_valid(struct kunit *test) 189 { 190 struct drm_connector_init_priv *priv = test->priv; 191 int ret; 192 193 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 194 "Vendor", "Product", 195 &dummy_funcs, 196 &dummy_hdmi_funcs, 197 DRM_MODE_CONNECTOR_HDMIA, 198 &priv->ddc, 199 BIT(HDMI_COLORSPACE_RGB), 200 8); 201 KUNIT_EXPECT_EQ(test, ret, 0); 202 } 203 204 /* 205 * Test that the registration of a connector without a DDC adapter 206 * doesn't report any error. 207 */ 208 static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test) 209 { 210 struct drm_connector_init_priv *priv = test->priv; 211 int ret; 212 213 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 214 "Vendor", "Product", 215 &dummy_funcs, 216 &dummy_hdmi_funcs, 217 DRM_MODE_CONNECTOR_HDMIA, 218 NULL, 219 BIT(HDMI_COLORSPACE_RGB), 220 8); 221 KUNIT_EXPECT_EQ(test, ret, 0); 222 } 223 224 /* 225 * Test that the registration of an HDMI connector with a NULL vendor 226 * fails. 227 */ 228 static void drm_test_connector_hdmi_init_null_vendor(struct kunit *test) 229 { 230 struct drm_connector_init_priv *priv = test->priv; 231 int ret; 232 233 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 234 NULL, "Product", 235 &dummy_funcs, 236 &dummy_hdmi_funcs, 237 DRM_MODE_CONNECTOR_HDMIA, 238 &priv->ddc, 239 BIT(HDMI_COLORSPACE_RGB), 240 8); 241 KUNIT_EXPECT_LT(test, ret, 0); 242 } 243 244 /* 245 * Test that the registration of an HDMI connector with a NULL product 246 * fails. 247 */ 248 static void drm_test_connector_hdmi_init_null_product(struct kunit *test) 249 { 250 struct drm_connector_init_priv *priv = test->priv; 251 int ret; 252 253 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 254 "Vendor", NULL, 255 &dummy_funcs, 256 &dummy_hdmi_funcs, 257 DRM_MODE_CONNECTOR_HDMIA, 258 &priv->ddc, 259 BIT(HDMI_COLORSPACE_RGB), 260 8); 261 KUNIT_EXPECT_LT(test, ret, 0); 262 } 263 264 /* 265 * Test that the registration of a connector with a valid, shorter than 266 * the max length, product name succeeds, and is stored padded with 0. 267 */ 268 static void drm_test_connector_hdmi_init_product_valid(struct kunit *test) 269 { 270 struct drm_connector_init_priv *priv = test->priv; 271 const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = { 272 'P', 'r', 'o', 'd', 273 }; 274 const char *product_name = "Prod"; 275 int ret; 276 277 KUNIT_ASSERT_LT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN); 278 279 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 280 "Vendor", product_name, 281 &dummy_funcs, 282 &dummy_hdmi_funcs, 283 DRM_MODE_CONNECTOR_HDMIA, 284 &priv->ddc, 285 BIT(HDMI_COLORSPACE_RGB), 286 8); 287 KUNIT_EXPECT_EQ(test, ret, 0); 288 KUNIT_EXPECT_MEMEQ(test, 289 priv->connector.hdmi.product, 290 expected_product, 291 sizeof(priv->connector.hdmi.product)); 292 } 293 294 /* 295 * Test that the registration of a connector with a valid, at max 296 * length, product name succeeds, and is stored padded without any 297 * trailing \0. 298 */ 299 static void drm_test_connector_hdmi_init_product_length_exact(struct kunit *test) 300 { 301 struct drm_connector_init_priv *priv = test->priv; 302 const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = { 303 'P', 'r', 'o', 'd', 'u', 'c', 't', 304 'P', 'r', 'o', 'd', 'u', 'c', 't', 305 'P', 'r', 306 }; 307 const char *product_name = "ProductProductPr"; 308 int ret; 309 310 KUNIT_ASSERT_EQ(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN); 311 312 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 313 "Vendor", product_name, 314 &dummy_funcs, 315 &dummy_hdmi_funcs, 316 DRM_MODE_CONNECTOR_HDMIA, 317 &priv->ddc, 318 BIT(HDMI_COLORSPACE_RGB), 319 8); 320 KUNIT_EXPECT_EQ(test, ret, 0); 321 KUNIT_EXPECT_MEMEQ(test, 322 priv->connector.hdmi.product, 323 expected_product, 324 sizeof(priv->connector.hdmi.product)); 325 } 326 327 /* 328 * Test that the registration of a connector with a product name larger 329 * than the maximum length fails. 330 */ 331 static void drm_test_connector_hdmi_init_product_length_too_long(struct kunit *test) 332 { 333 struct drm_connector_init_priv *priv = test->priv; 334 const char *product_name = "ProductProductProduct"; 335 int ret; 336 337 KUNIT_ASSERT_GT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN); 338 339 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 340 "Vendor", product_name, 341 &dummy_funcs, 342 &dummy_hdmi_funcs, 343 DRM_MODE_CONNECTOR_HDMIA, 344 &priv->ddc, 345 BIT(HDMI_COLORSPACE_RGB), 346 8); 347 KUNIT_EXPECT_LT(test, ret, 0); 348 } 349 350 /* 351 * Test that the registration of a connector with a vendor name smaller 352 * than the maximum length succeeds, and is stored padded with zeros. 353 */ 354 static void drm_test_connector_hdmi_init_vendor_valid(struct kunit *test) 355 { 356 struct drm_connector_init_priv *priv = test->priv; 357 const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = { 358 'V', 'e', 'n', 'd', 359 }; 360 const char *vendor_name = "Vend"; 361 int ret; 362 363 KUNIT_ASSERT_LT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN); 364 365 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 366 vendor_name, "Product", 367 &dummy_funcs, 368 &dummy_hdmi_funcs, 369 DRM_MODE_CONNECTOR_HDMIA, 370 &priv->ddc, 371 BIT(HDMI_COLORSPACE_RGB), 372 8); 373 KUNIT_EXPECT_EQ(test, ret, 0); 374 KUNIT_EXPECT_MEMEQ(test, 375 priv->connector.hdmi.vendor, 376 expected_vendor, 377 sizeof(priv->connector.hdmi.vendor)); 378 } 379 380 /* 381 * Test that the registration of a connector with a vendor name at the 382 * maximum length succeeds, and is stored padded without the trailing 383 * zero. 384 */ 385 static void drm_test_connector_hdmi_init_vendor_length_exact(struct kunit *test) 386 { 387 struct drm_connector_init_priv *priv = test->priv; 388 const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = { 389 'V', 'e', 'n', 'd', 'o', 'r', 390 'V', 'e', 391 }; 392 const char *vendor_name = "VendorVe"; 393 int ret; 394 395 KUNIT_ASSERT_EQ(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN); 396 397 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 398 vendor_name, "Product", 399 &dummy_funcs, 400 &dummy_hdmi_funcs, 401 DRM_MODE_CONNECTOR_HDMIA, 402 &priv->ddc, 403 BIT(HDMI_COLORSPACE_RGB), 404 8); 405 KUNIT_EXPECT_EQ(test, ret, 0); 406 KUNIT_EXPECT_MEMEQ(test, 407 priv->connector.hdmi.vendor, 408 expected_vendor, 409 sizeof(priv->connector.hdmi.vendor)); 410 } 411 412 /* 413 * Test that the registration of a connector with a vendor name larger 414 * than the maximum length fails. 415 */ 416 static void drm_test_connector_hdmi_init_vendor_length_too_long(struct kunit *test) 417 { 418 struct drm_connector_init_priv *priv = test->priv; 419 const char *vendor_name = "VendorVendor"; 420 int ret; 421 422 KUNIT_ASSERT_GT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN); 423 424 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 425 vendor_name, "Product", 426 &dummy_funcs, 427 &dummy_hdmi_funcs, 428 DRM_MODE_CONNECTOR_HDMIA, 429 &priv->ddc, 430 BIT(HDMI_COLORSPACE_RGB), 431 8); 432 KUNIT_EXPECT_LT(test, ret, 0); 433 } 434 435 /* 436 * Test that the registration of a connector with an invalid maximum bpc 437 * count fails. 438 */ 439 static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test) 440 { 441 struct drm_connector_init_priv *priv = test->priv; 442 int ret; 443 444 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 445 "Vendor", "Product", 446 &dummy_funcs, 447 &dummy_hdmi_funcs, 448 DRM_MODE_CONNECTOR_HDMIA, 449 &priv->ddc, 450 BIT(HDMI_COLORSPACE_RGB), 451 9); 452 KUNIT_EXPECT_LT(test, ret, 0); 453 } 454 455 /* 456 * Test that the registration of a connector with a null maximum bpc 457 * count fails. 458 */ 459 static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test) 460 { 461 struct drm_connector_init_priv *priv = test->priv; 462 int ret; 463 464 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 465 "Vendor", "Product", 466 &dummy_funcs, 467 &dummy_hdmi_funcs, 468 DRM_MODE_CONNECTOR_HDMIA, 469 &priv->ddc, 470 BIT(HDMI_COLORSPACE_RGB), 471 0); 472 KUNIT_EXPECT_LT(test, ret, 0); 473 } 474 475 /* 476 * Test that the registration of a connector with a maximum bpc count of 477 * 8 succeeds, registers the max bpc property, but doesn't register the 478 * HDR output metadata one. 479 */ 480 static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test) 481 { 482 struct drm_connector_init_priv *priv = test->priv; 483 struct drm_connector_state *state; 484 struct drm_connector *connector = &priv->connector; 485 struct drm_property *prop; 486 uint64_t val; 487 int ret; 488 489 ret = drmm_connector_hdmi_init(&priv->drm, connector, 490 "Vendor", "Product", 491 &dummy_funcs, 492 &dummy_hdmi_funcs, 493 DRM_MODE_CONNECTOR_HDMIA, 494 &priv->ddc, 495 BIT(HDMI_COLORSPACE_RGB), 496 8); 497 KUNIT_EXPECT_EQ(test, ret, 0); 498 499 prop = connector->max_bpc_property; 500 KUNIT_ASSERT_NOT_NULL(test, prop); 501 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 502 503 ret = drm_object_property_get_default_value(&connector->base, prop, &val); 504 KUNIT_EXPECT_EQ(test, ret, 0); 505 KUNIT_EXPECT_EQ(test, val, 8); 506 507 state = connector->state; 508 KUNIT_EXPECT_EQ(test, state->max_bpc, 8); 509 KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 8); 510 511 prop = priv->drm.mode_config.hdr_output_metadata_property; 512 KUNIT_ASSERT_NOT_NULL(test, prop); 513 KUNIT_EXPECT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 514 } 515 516 /* 517 * Test that the registration of a connector with a maximum bpc count of 518 * 10 succeeds and registers the max bpc and HDR output metadata 519 * properties. 520 */ 521 static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test) 522 { 523 struct drm_connector_init_priv *priv = test->priv; 524 struct drm_connector_state *state; 525 struct drm_connector *connector = &priv->connector; 526 struct drm_property *prop; 527 uint64_t val; 528 int ret; 529 530 ret = drmm_connector_hdmi_init(&priv->drm, connector, 531 "Vendor", "Product", 532 &dummy_funcs, 533 &dummy_hdmi_funcs, 534 DRM_MODE_CONNECTOR_HDMIA, 535 &priv->ddc, 536 BIT(HDMI_COLORSPACE_RGB), 537 10); 538 KUNIT_EXPECT_EQ(test, ret, 0); 539 540 prop = connector->max_bpc_property; 541 KUNIT_ASSERT_NOT_NULL(test, prop); 542 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 543 544 ret = drm_object_property_get_default_value(&connector->base, prop, &val); 545 KUNIT_EXPECT_EQ(test, ret, 0); 546 KUNIT_EXPECT_EQ(test, val, 10); 547 548 state = connector->state; 549 KUNIT_EXPECT_EQ(test, state->max_bpc, 10); 550 KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 10); 551 552 prop = priv->drm.mode_config.hdr_output_metadata_property; 553 KUNIT_ASSERT_NOT_NULL(test, prop); 554 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 555 } 556 557 /* 558 * Test that the registration of a connector with a maximum bpc count of 559 * 12 succeeds and registers the max bpc and HDR output metadata 560 * properties. 561 */ 562 static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test) 563 { 564 struct drm_connector_init_priv *priv = test->priv; 565 struct drm_connector_state *state; 566 struct drm_connector *connector = &priv->connector; 567 struct drm_property *prop; 568 uint64_t val; 569 int ret; 570 571 ret = drmm_connector_hdmi_init(&priv->drm, connector, 572 "Vendor", "Product", 573 &dummy_funcs, 574 &dummy_hdmi_funcs, 575 DRM_MODE_CONNECTOR_HDMIA, 576 &priv->ddc, 577 BIT(HDMI_COLORSPACE_RGB), 578 12); 579 KUNIT_EXPECT_EQ(test, ret, 0); 580 581 prop = connector->max_bpc_property; 582 KUNIT_ASSERT_NOT_NULL(test, prop); 583 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 584 585 ret = drm_object_property_get_default_value(&connector->base, prop, &val); 586 KUNIT_EXPECT_EQ(test, ret, 0); 587 KUNIT_EXPECT_EQ(test, val, 12); 588 589 state = connector->state; 590 KUNIT_EXPECT_EQ(test, state->max_bpc, 12); 591 KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 12); 592 593 prop = priv->drm.mode_config.hdr_output_metadata_property; 594 KUNIT_ASSERT_NOT_NULL(test, prop); 595 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 596 } 597 598 /* 599 * Test that the registration of an HDMI connector with no supported 600 * format fails. 601 */ 602 static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test) 603 { 604 struct drm_connector_init_priv *priv = test->priv; 605 int ret; 606 607 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 608 "Vendor", "Product", 609 &dummy_funcs, 610 &dummy_hdmi_funcs, 611 DRM_MODE_CONNECTOR_HDMIA, 612 &priv->ddc, 613 0, 614 8); 615 KUNIT_EXPECT_LT(test, ret, 0); 616 } 617 618 /* 619 * Test that the registration of an HDMI connector not listing RGB as a 620 * supported format fails. 621 */ 622 static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test) 623 { 624 struct drm_connector_init_priv *priv = test->priv; 625 int ret; 626 627 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 628 "Vendor", "Product", 629 &dummy_funcs, 630 &dummy_hdmi_funcs, 631 DRM_MODE_CONNECTOR_HDMIA, 632 &priv->ddc, 633 BIT(HDMI_COLORSPACE_YUV422), 634 8); 635 KUNIT_EXPECT_LT(test, ret, 0); 636 } 637 638 /* 639 * Test that the registration of an HDMI connector with an HDMI 640 * connector type succeeds. 641 */ 642 static void drm_test_connector_hdmi_init_type_valid(struct kunit *test) 643 { 644 struct drm_connector_init_priv *priv = test->priv; 645 unsigned int connector_type = *(unsigned int *)test->param_value; 646 int ret; 647 648 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 649 "Vendor", "Product", 650 &dummy_funcs, 651 &dummy_hdmi_funcs, 652 connector_type, 653 &priv->ddc, 654 BIT(HDMI_COLORSPACE_RGB), 655 8); 656 KUNIT_EXPECT_EQ(test, ret, 0); 657 } 658 659 static const unsigned int drm_connector_hdmi_init_type_valid_tests[] = { 660 DRM_MODE_CONNECTOR_HDMIA, 661 DRM_MODE_CONNECTOR_HDMIB, 662 }; 663 664 static void drm_connector_hdmi_init_type_desc(const unsigned int *type, char *desc) 665 { 666 sprintf(desc, "%s", drm_get_connector_type_name(*type)); 667 } 668 669 KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_valid, 670 drm_connector_hdmi_init_type_valid_tests, 671 drm_connector_hdmi_init_type_desc); 672 673 /* 674 * Test that the registration of an HDMI connector with an !HDMI 675 * connector type fails. 676 */ 677 static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test) 678 { 679 struct drm_connector_init_priv *priv = test->priv; 680 unsigned int connector_type = *(unsigned int *)test->param_value; 681 int ret; 682 683 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 684 "Vendor", "Product", 685 &dummy_funcs, 686 &dummy_hdmi_funcs, 687 connector_type, 688 &priv->ddc, 689 BIT(HDMI_COLORSPACE_RGB), 690 8); 691 KUNIT_EXPECT_LT(test, ret, 0); 692 } 693 694 static const unsigned int drm_connector_hdmi_init_type_invalid_tests[] = { 695 DRM_MODE_CONNECTOR_Unknown, 696 DRM_MODE_CONNECTOR_VGA, 697 DRM_MODE_CONNECTOR_DVII, 698 DRM_MODE_CONNECTOR_DVID, 699 DRM_MODE_CONNECTOR_DVIA, 700 DRM_MODE_CONNECTOR_Composite, 701 DRM_MODE_CONNECTOR_SVIDEO, 702 DRM_MODE_CONNECTOR_LVDS, 703 DRM_MODE_CONNECTOR_Component, 704 DRM_MODE_CONNECTOR_9PinDIN, 705 DRM_MODE_CONNECTOR_DisplayPort, 706 DRM_MODE_CONNECTOR_TV, 707 DRM_MODE_CONNECTOR_eDP, 708 DRM_MODE_CONNECTOR_VIRTUAL, 709 DRM_MODE_CONNECTOR_DSI, 710 DRM_MODE_CONNECTOR_DPI, 711 DRM_MODE_CONNECTOR_WRITEBACK, 712 DRM_MODE_CONNECTOR_SPI, 713 DRM_MODE_CONNECTOR_USB, 714 }; 715 716 KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid, 717 drm_connector_hdmi_init_type_invalid_tests, 718 drm_connector_hdmi_init_type_desc); 719 720 static struct kunit_case drmm_connector_hdmi_init_tests[] = { 721 KUNIT_CASE(drm_test_connector_hdmi_init_valid), 722 KUNIT_CASE(drm_test_connector_hdmi_init_bpc_8), 723 KUNIT_CASE(drm_test_connector_hdmi_init_bpc_10), 724 KUNIT_CASE(drm_test_connector_hdmi_init_bpc_12), 725 KUNIT_CASE(drm_test_connector_hdmi_init_bpc_invalid), 726 KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null), 727 KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty), 728 KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb), 729 KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc), 730 KUNIT_CASE(drm_test_connector_hdmi_init_null_product), 731 KUNIT_CASE(drm_test_connector_hdmi_init_null_vendor), 732 KUNIT_CASE(drm_test_connector_hdmi_init_product_length_exact), 733 KUNIT_CASE(drm_test_connector_hdmi_init_product_length_too_long), 734 KUNIT_CASE(drm_test_connector_hdmi_init_product_valid), 735 KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_exact), 736 KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_too_long), 737 KUNIT_CASE(drm_test_connector_hdmi_init_vendor_valid), 738 KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid, 739 drm_connector_hdmi_init_type_valid_gen_params), 740 KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid, 741 drm_connector_hdmi_init_type_invalid_gen_params), 742 { } 743 }; 744 745 static struct kunit_suite drmm_connector_hdmi_init_test_suite = { 746 .name = "drmm_connector_hdmi_init", 747 .init = drm_test_connector_init, 748 .test_cases = drmm_connector_hdmi_init_tests, 749 }; 750 751 struct drm_get_tv_mode_from_name_test { 752 const char *name; 753 enum drm_connector_tv_mode expected_mode; 754 }; 755 756 #define TV_MODE_NAME(_name, _mode) \ 757 { \ 758 .name = _name, \ 759 .expected_mode = _mode, \ 760 } 761 762 static void drm_test_get_tv_mode_from_name_valid(struct kunit *test) 763 { 764 const struct drm_get_tv_mode_from_name_test *params = test->param_value; 765 766 KUNIT_EXPECT_EQ(test, 767 drm_get_tv_mode_from_name(params->name, strlen(params->name)), 768 params->expected_mode); 769 } 770 771 static const 772 struct drm_get_tv_mode_from_name_test drm_get_tv_mode_from_name_valid_tests[] = { 773 TV_MODE_NAME("NTSC", DRM_MODE_TV_MODE_NTSC), 774 TV_MODE_NAME("NTSC-443", DRM_MODE_TV_MODE_NTSC_443), 775 TV_MODE_NAME("NTSC-J", DRM_MODE_TV_MODE_NTSC_J), 776 TV_MODE_NAME("PAL", DRM_MODE_TV_MODE_PAL), 777 TV_MODE_NAME("PAL-M", DRM_MODE_TV_MODE_PAL_M), 778 TV_MODE_NAME("PAL-N", DRM_MODE_TV_MODE_PAL_N), 779 TV_MODE_NAME("SECAM", DRM_MODE_TV_MODE_SECAM), 780 }; 781 782 static void 783 drm_get_tv_mode_from_name_valid_desc(const struct drm_get_tv_mode_from_name_test *t, 784 char *desc) 785 { 786 sprintf(desc, "%s", t->name); 787 } 788 789 KUNIT_ARRAY_PARAM(drm_get_tv_mode_from_name_valid, 790 drm_get_tv_mode_from_name_valid_tests, 791 drm_get_tv_mode_from_name_valid_desc); 792 793 static void drm_test_get_tv_mode_from_name_truncated(struct kunit *test) 794 { 795 const char *name = "NTS"; 796 int ret; 797 798 ret = drm_get_tv_mode_from_name(name, strlen(name)); 799 KUNIT_EXPECT_LT(test, ret, 0); 800 }; 801 802 static struct kunit_case drm_get_tv_mode_from_name_tests[] = { 803 KUNIT_CASE_PARAM(drm_test_get_tv_mode_from_name_valid, 804 drm_get_tv_mode_from_name_valid_gen_params), 805 KUNIT_CASE(drm_test_get_tv_mode_from_name_truncated), 806 { } 807 }; 808 809 static struct kunit_suite drm_get_tv_mode_from_name_test_suite = { 810 .name = "drm_get_tv_mode_from_name", 811 .test_cases = drm_get_tv_mode_from_name_tests, 812 }; 813 814 struct drm_hdmi_connector_get_broadcast_rgb_name_test { 815 unsigned int kind; 816 const char *expected_name; 817 }; 818 819 #define BROADCAST_RGB_TEST(_kind, _name) \ 820 { \ 821 .kind = _kind, \ 822 .expected_name = _name, \ 823 } 824 825 static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name(struct kunit *test) 826 { 827 const struct drm_hdmi_connector_get_broadcast_rgb_name_test *params = 828 test->param_value; 829 830 KUNIT_EXPECT_STREQ(test, 831 drm_hdmi_connector_get_broadcast_rgb_name(params->kind), 832 params->expected_name); 833 } 834 835 static const 836 struct drm_hdmi_connector_get_broadcast_rgb_name_test 837 drm_hdmi_connector_get_broadcast_rgb_name_valid_tests[] = { 838 BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic"), 839 BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_FULL, "Full"), 840 BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235"), 841 }; 842 843 static void 844 drm_hdmi_connector_get_broadcast_rgb_name_valid_desc(const struct drm_hdmi_connector_get_broadcast_rgb_name_test *t, 845 char *desc) 846 { 847 sprintf(desc, "%s", t->expected_name); 848 } 849 850 KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_broadcast_rgb_name_valid, 851 drm_hdmi_connector_get_broadcast_rgb_name_valid_tests, 852 drm_hdmi_connector_get_broadcast_rgb_name_valid_desc); 853 854 static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid(struct kunit *test) 855 { 856 KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_broadcast_rgb_name(3)); 857 }; 858 859 static struct kunit_case drm_hdmi_connector_get_broadcast_rgb_name_tests[] = { 860 KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_broadcast_rgb_name, 861 drm_hdmi_connector_get_broadcast_rgb_name_valid_gen_params), 862 KUNIT_CASE(drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid), 863 { } 864 }; 865 866 static struct kunit_suite drm_hdmi_connector_get_broadcast_rgb_name_test_suite = { 867 .name = "drm_hdmi_connector_get_broadcast_rgb_name", 868 .test_cases = drm_hdmi_connector_get_broadcast_rgb_name_tests, 869 }; 870 871 struct drm_hdmi_connector_get_output_format_name_test { 872 unsigned int kind; 873 const char *expected_name; 874 }; 875 876 #define OUTPUT_FORMAT_TEST(_kind, _name) \ 877 { \ 878 .kind = _kind, \ 879 .expected_name = _name, \ 880 } 881 882 static void drm_test_drm_hdmi_connector_get_output_format_name(struct kunit *test) 883 { 884 const struct drm_hdmi_connector_get_output_format_name_test *params = 885 test->param_value; 886 887 KUNIT_EXPECT_STREQ(test, 888 drm_hdmi_connector_get_output_format_name(params->kind), 889 params->expected_name); 890 } 891 892 static const 893 struct drm_hdmi_connector_get_output_format_name_test 894 drm_hdmi_connector_get_output_format_name_valid_tests[] = { 895 OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_RGB, "RGB"), 896 OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV420, "YUV 4:2:0"), 897 OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV422, "YUV 4:2:2"), 898 OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV444, "YUV 4:4:4"), 899 }; 900 901 static void 902 drm_hdmi_connector_get_output_format_name_valid_desc(const struct drm_hdmi_connector_get_output_format_name_test *t, 903 char *desc) 904 { 905 sprintf(desc, "%s", t->expected_name); 906 } 907 908 KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_output_format_name_valid, 909 drm_hdmi_connector_get_output_format_name_valid_tests, 910 drm_hdmi_connector_get_output_format_name_valid_desc); 911 912 static void drm_test_drm_hdmi_connector_get_output_format_name_invalid(struct kunit *test) 913 { 914 KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_output_format_name(4)); 915 }; 916 917 static struct kunit_case drm_hdmi_connector_get_output_format_name_tests[] = { 918 KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_output_format_name, 919 drm_hdmi_connector_get_output_format_name_valid_gen_params), 920 KUNIT_CASE(drm_test_drm_hdmi_connector_get_output_format_name_invalid), 921 { } 922 }; 923 924 static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite = { 925 .name = "drm_hdmi_connector_get_output_format_name", 926 .test_cases = drm_hdmi_connector_get_output_format_name_tests, 927 }; 928 929 static void drm_test_drm_connector_attach_broadcast_rgb_property(struct kunit *test) 930 { 931 struct drm_connector_init_priv *priv = test->priv; 932 struct drm_connector *connector = &priv->connector; 933 struct drm_property *prop; 934 int ret; 935 936 ret = drmm_connector_init(&priv->drm, connector, 937 &dummy_funcs, 938 DRM_MODE_CONNECTOR_HDMIA, 939 &priv->ddc); 940 KUNIT_ASSERT_EQ(test, ret, 0); 941 942 ret = drm_connector_attach_broadcast_rgb_property(connector); 943 KUNIT_ASSERT_EQ(test, ret, 0); 944 945 prop = connector->broadcast_rgb_property; 946 KUNIT_ASSERT_NOT_NULL(test, prop); 947 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 948 } 949 950 static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(struct kunit *test) 951 { 952 struct drm_connector_init_priv *priv = test->priv; 953 struct drm_connector *connector = &priv->connector; 954 struct drm_property *prop; 955 int ret; 956 957 ret = drmm_connector_hdmi_init(&priv->drm, connector, 958 "Vendor", "Product", 959 &dummy_funcs, 960 &dummy_hdmi_funcs, 961 DRM_MODE_CONNECTOR_HDMIA, 962 &priv->ddc, 963 BIT(HDMI_COLORSPACE_RGB), 964 8); 965 KUNIT_EXPECT_EQ(test, ret, 0); 966 967 ret = drm_connector_attach_broadcast_rgb_property(connector); 968 KUNIT_ASSERT_EQ(test, ret, 0); 969 970 prop = connector->broadcast_rgb_property; 971 KUNIT_ASSERT_NOT_NULL(test, prop); 972 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 973 } 974 975 static struct kunit_case drm_connector_attach_broadcast_rgb_property_tests[] = { 976 KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property), 977 KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector), 978 { } 979 }; 980 981 static struct kunit_suite drm_connector_attach_broadcast_rgb_property_test_suite = { 982 .name = "drm_connector_attach_broadcast_rgb_property", 983 .init = drm_test_connector_init, 984 .test_cases = drm_connector_attach_broadcast_rgb_property_tests, 985 }; 986 987 /* 988 * Test that for a given mode, with 8bpc and an RGB output the TMDS 989 * character rate is equal to the mode pixel clock. 990 */ 991 static void drm_test_drm_hdmi_compute_mode_clock_rgb(struct kunit *test) 992 { 993 struct drm_connector_init_priv *priv = test->priv; 994 const struct drm_display_mode *mode; 995 unsigned long long rate; 996 struct drm_device *drm = &priv->drm; 997 998 mode = drm_display_mode_from_cea_vic(drm, 16); 999 KUNIT_ASSERT_NOT_NULL(test, mode); 1000 1001 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1002 1003 rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); 1004 KUNIT_ASSERT_GT(test, rate, 0); 1005 KUNIT_EXPECT_EQ(test, mode->clock * 1000ULL, rate); 1006 } 1007 1008 /* 1009 * Test that for a given mode, with 10bpc and an RGB output the TMDS 1010 * character rate is equal to 1.25 times the mode pixel clock. 1011 */ 1012 static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc(struct kunit *test) 1013 { 1014 struct drm_connector_init_priv *priv = test->priv; 1015 const struct drm_display_mode *mode; 1016 unsigned long long rate; 1017 struct drm_device *drm = &priv->drm; 1018 1019 mode = drm_display_mode_from_cea_vic(drm, 16); 1020 KUNIT_ASSERT_NOT_NULL(test, mode); 1021 1022 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1023 1024 rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB); 1025 KUNIT_ASSERT_GT(test, rate, 0); 1026 KUNIT_EXPECT_EQ(test, mode->clock * 1250, rate); 1027 } 1028 1029 /* 1030 * Test that for the VIC-1 mode, with 10bpc and an RGB output the TMDS 1031 * character rate computation fails. 1032 */ 1033 static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *test) 1034 { 1035 struct drm_connector_init_priv *priv = test->priv; 1036 const struct drm_display_mode *mode; 1037 unsigned long long rate; 1038 struct drm_device *drm = &priv->drm; 1039 1040 mode = drm_display_mode_from_cea_vic(drm, 1); 1041 KUNIT_ASSERT_NOT_NULL(test, mode); 1042 1043 rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB); 1044 KUNIT_EXPECT_EQ(test, rate, 0); 1045 } 1046 1047 /* 1048 * Test that for a given mode, with 12bpc and an RGB output the TMDS 1049 * character rate is equal to 1.5 times the mode pixel clock. 1050 */ 1051 static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test) 1052 { 1053 struct drm_connector_init_priv *priv = test->priv; 1054 const struct drm_display_mode *mode; 1055 unsigned long long rate; 1056 struct drm_device *drm = &priv->drm; 1057 1058 mode = drm_display_mode_from_cea_vic(drm, 16); 1059 KUNIT_ASSERT_NOT_NULL(test, mode); 1060 1061 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1062 1063 rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB); 1064 KUNIT_ASSERT_GT(test, rate, 0); 1065 KUNIT_EXPECT_EQ(test, mode->clock * 1500, rate); 1066 } 1067 1068 /* 1069 * Test that for the VIC-1 mode, with 12bpc and an RGB output the TMDS 1070 * character rate computation fails. 1071 */ 1072 static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *test) 1073 { 1074 struct drm_connector_init_priv *priv = test->priv; 1075 const struct drm_display_mode *mode; 1076 unsigned long long rate; 1077 struct drm_device *drm = &priv->drm; 1078 1079 mode = drm_display_mode_from_cea_vic(drm, 1); 1080 KUNIT_ASSERT_NOT_NULL(test, mode); 1081 1082 rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB); 1083 KUNIT_EXPECT_EQ(test, rate, 0); 1084 } 1085 1086 /* 1087 * Test that for a mode with the pixel repetition flag, the TMDS 1088 * character rate is indeed double the mode pixel clock. 1089 */ 1090 static void drm_test_drm_hdmi_compute_mode_clock_rgb_double(struct kunit *test) 1091 { 1092 struct drm_connector_init_priv *priv = test->priv; 1093 const struct drm_display_mode *mode; 1094 unsigned long long rate; 1095 struct drm_device *drm = &priv->drm; 1096 1097 mode = drm_display_mode_from_cea_vic(drm, 6); 1098 KUNIT_ASSERT_NOT_NULL(test, mode); 1099 1100 KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1101 1102 rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); 1103 KUNIT_ASSERT_GT(test, rate, 0); 1104 KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) * 2, rate); 1105 } 1106 1107 /* 1108 * Test that the TMDS character rate computation for the VIC modes 1109 * explicitly listed in the spec as supporting YUV420 succeed and return 1110 * half the mode pixel clock. 1111 */ 1112 static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit *test) 1113 { 1114 struct drm_connector_init_priv *priv = test->priv; 1115 const struct drm_display_mode *mode; 1116 struct drm_device *drm = &priv->drm; 1117 unsigned long long rate; 1118 unsigned int vic = *(unsigned int *)test->param_value; 1119 1120 mode = drm_display_mode_from_cea_vic(drm, vic); 1121 KUNIT_ASSERT_NOT_NULL(test, mode); 1122 1123 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1124 1125 rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420); 1126 KUNIT_ASSERT_GT(test, rate, 0); 1127 KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) / 2, rate); 1128 } 1129 1130 static const unsigned int drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[] = { 1131 96, 97, 101, 102, 106, 107, 1132 }; 1133 1134 static void drm_hdmi_compute_mode_clock_yuv420_vic_desc(const unsigned int *vic, char *desc) 1135 { 1136 sprintf(desc, "VIC %u", *vic); 1137 } 1138 1139 KUNIT_ARRAY_PARAM(drm_hdmi_compute_mode_clock_yuv420_valid, 1140 drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests, 1141 drm_hdmi_compute_mode_clock_yuv420_vic_desc); 1142 1143 /* 1144 * Test that for a given mode listed supporting it and an YUV420 output 1145 * with 10bpc, the TMDS character rate is equal to 0.625 times the mode 1146 * pixel clock. 1147 */ 1148 static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kunit *test) 1149 { 1150 struct drm_connector_init_priv *priv = test->priv; 1151 const struct drm_display_mode *mode; 1152 struct drm_device *drm = &priv->drm; 1153 unsigned int vic = 1154 drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; 1155 unsigned long long rate; 1156 1157 mode = drm_display_mode_from_cea_vic(drm, vic); 1158 KUNIT_ASSERT_NOT_NULL(test, mode); 1159 1160 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1161 1162 rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV420); 1163 KUNIT_ASSERT_GT(test, rate, 0); 1164 1165 KUNIT_EXPECT_EQ(test, mode->clock * 625, rate); 1166 } 1167 1168 /* 1169 * Test that for a given mode listed supporting it and an YUV420 output 1170 * with 12bpc, the TMDS character rate is equal to 0.75 times the mode 1171 * pixel clock. 1172 */ 1173 static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kunit *test) 1174 { 1175 struct drm_connector_init_priv *priv = test->priv; 1176 const struct drm_display_mode *mode; 1177 struct drm_device *drm = &priv->drm; 1178 unsigned int vic = 1179 drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; 1180 unsigned long long rate; 1181 1182 mode = drm_display_mode_from_cea_vic(drm, vic); 1183 KUNIT_ASSERT_NOT_NULL(test, mode); 1184 1185 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1186 1187 rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV420); 1188 KUNIT_ASSERT_GT(test, rate, 0); 1189 1190 KUNIT_EXPECT_EQ(test, mode->clock * 750, rate); 1191 } 1192 1193 /* 1194 * Test that for a given mode, the computation of the TMDS character 1195 * rate with 8bpc and a YUV422 output succeeds and returns a rate equal 1196 * to the mode pixel clock. 1197 */ 1198 static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit *test) 1199 { 1200 struct drm_connector_init_priv *priv = test->priv; 1201 const struct drm_display_mode *mode; 1202 struct drm_device *drm = &priv->drm; 1203 unsigned long long rate; 1204 1205 mode = drm_display_mode_from_cea_vic(drm, 16); 1206 KUNIT_ASSERT_NOT_NULL(test, mode); 1207 1208 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1209 1210 rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV422); 1211 KUNIT_ASSERT_GT(test, rate, 0); 1212 KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate); 1213 } 1214 1215 /* 1216 * Test that for a given mode, the computation of the TMDS character 1217 * rate with 10bpc and a YUV422 output succeeds and returns a rate equal 1218 * to the mode pixel clock. 1219 */ 1220 static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kunit *test) 1221 { 1222 struct drm_connector_init_priv *priv = test->priv; 1223 const struct drm_display_mode *mode; 1224 struct drm_device *drm = &priv->drm; 1225 unsigned long long rate; 1226 1227 mode = drm_display_mode_from_cea_vic(drm, 16); 1228 KUNIT_ASSERT_NOT_NULL(test, mode); 1229 1230 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1231 1232 rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV422); 1233 KUNIT_ASSERT_GT(test, rate, 0); 1234 KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate); 1235 } 1236 1237 /* 1238 * Test that for a given mode, the computation of the TMDS character 1239 * rate with 12bpc and a YUV422 output succeeds and returns a rate equal 1240 * to the mode pixel clock. 1241 */ 1242 static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kunit *test) 1243 { 1244 struct drm_connector_init_priv *priv = test->priv; 1245 const struct drm_display_mode *mode; 1246 struct drm_device *drm = &priv->drm; 1247 unsigned long long rate; 1248 1249 mode = drm_display_mode_from_cea_vic(drm, 16); 1250 KUNIT_ASSERT_NOT_NULL(test, mode); 1251 1252 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1253 1254 rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV422); 1255 KUNIT_ASSERT_GT(test, rate, 0); 1256 KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate); 1257 } 1258 1259 static struct kunit_case drm_hdmi_compute_mode_clock_tests[] = { 1260 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb), 1261 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc), 1262 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1), 1263 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc), 1264 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1), 1265 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_double), 1266 KUNIT_CASE_PARAM(drm_test_connector_hdmi_compute_mode_clock_yuv420_valid, 1267 drm_hdmi_compute_mode_clock_yuv420_valid_gen_params), 1268 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc), 1269 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc), 1270 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc), 1271 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc), 1272 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc), 1273 { } 1274 }; 1275 1276 static struct kunit_suite drm_hdmi_compute_mode_clock_test_suite = { 1277 .name = "drm_test_connector_hdmi_compute_mode_clock", 1278 .init = drm_test_connector_init, 1279 .test_cases = drm_hdmi_compute_mode_clock_tests, 1280 }; 1281 1282 kunit_test_suites( 1283 &drmm_connector_hdmi_init_test_suite, 1284 &drmm_connector_init_test_suite, 1285 &drm_connector_attach_broadcast_rgb_property_test_suite, 1286 &drm_get_tv_mode_from_name_test_suite, 1287 &drm_hdmi_compute_mode_clock_test_suite, 1288 &drm_hdmi_connector_get_broadcast_rgb_name_test_suite, 1289 &drm_hdmi_connector_get_output_format_name_test_suite 1290 ); 1291 1292 MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>"); 1293 MODULE_LICENSE("GPL"); 1294