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 TV_MODE_NAME("Mono", DRM_MODE_TV_MODE_MONOCHROME), 781 }; 782 783 static void 784 drm_get_tv_mode_from_name_valid_desc(const struct drm_get_tv_mode_from_name_test *t, 785 char *desc) 786 { 787 sprintf(desc, "%s", t->name); 788 } 789 790 KUNIT_ARRAY_PARAM(drm_get_tv_mode_from_name_valid, 791 drm_get_tv_mode_from_name_valid_tests, 792 drm_get_tv_mode_from_name_valid_desc); 793 794 static void drm_test_get_tv_mode_from_name_truncated(struct kunit *test) 795 { 796 const char *name = "NTS"; 797 int ret; 798 799 ret = drm_get_tv_mode_from_name(name, strlen(name)); 800 KUNIT_EXPECT_LT(test, ret, 0); 801 }; 802 803 static struct kunit_case drm_get_tv_mode_from_name_tests[] = { 804 KUNIT_CASE_PARAM(drm_test_get_tv_mode_from_name_valid, 805 drm_get_tv_mode_from_name_valid_gen_params), 806 KUNIT_CASE(drm_test_get_tv_mode_from_name_truncated), 807 { } 808 }; 809 810 static struct kunit_suite drm_get_tv_mode_from_name_test_suite = { 811 .name = "drm_get_tv_mode_from_name", 812 .test_cases = drm_get_tv_mode_from_name_tests, 813 }; 814 815 struct drm_hdmi_connector_get_broadcast_rgb_name_test { 816 unsigned int kind; 817 const char *expected_name; 818 }; 819 820 #define BROADCAST_RGB_TEST(_kind, _name) \ 821 { \ 822 .kind = _kind, \ 823 .expected_name = _name, \ 824 } 825 826 static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name(struct kunit *test) 827 { 828 const struct drm_hdmi_connector_get_broadcast_rgb_name_test *params = 829 test->param_value; 830 831 KUNIT_EXPECT_STREQ(test, 832 drm_hdmi_connector_get_broadcast_rgb_name(params->kind), 833 params->expected_name); 834 } 835 836 static const 837 struct drm_hdmi_connector_get_broadcast_rgb_name_test 838 drm_hdmi_connector_get_broadcast_rgb_name_valid_tests[] = { 839 BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic"), 840 BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_FULL, "Full"), 841 BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235"), 842 }; 843 844 static void 845 drm_hdmi_connector_get_broadcast_rgb_name_valid_desc(const struct drm_hdmi_connector_get_broadcast_rgb_name_test *t, 846 char *desc) 847 { 848 sprintf(desc, "%s", t->expected_name); 849 } 850 851 KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_broadcast_rgb_name_valid, 852 drm_hdmi_connector_get_broadcast_rgb_name_valid_tests, 853 drm_hdmi_connector_get_broadcast_rgb_name_valid_desc); 854 855 static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid(struct kunit *test) 856 { 857 KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_broadcast_rgb_name(3)); 858 }; 859 860 static struct kunit_case drm_hdmi_connector_get_broadcast_rgb_name_tests[] = { 861 KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_broadcast_rgb_name, 862 drm_hdmi_connector_get_broadcast_rgb_name_valid_gen_params), 863 KUNIT_CASE(drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid), 864 { } 865 }; 866 867 static struct kunit_suite drm_hdmi_connector_get_broadcast_rgb_name_test_suite = { 868 .name = "drm_hdmi_connector_get_broadcast_rgb_name", 869 .test_cases = drm_hdmi_connector_get_broadcast_rgb_name_tests, 870 }; 871 872 struct drm_hdmi_connector_get_output_format_name_test { 873 unsigned int kind; 874 const char *expected_name; 875 }; 876 877 #define OUTPUT_FORMAT_TEST(_kind, _name) \ 878 { \ 879 .kind = _kind, \ 880 .expected_name = _name, \ 881 } 882 883 static void drm_test_drm_hdmi_connector_get_output_format_name(struct kunit *test) 884 { 885 const struct drm_hdmi_connector_get_output_format_name_test *params = 886 test->param_value; 887 888 KUNIT_EXPECT_STREQ(test, 889 drm_hdmi_connector_get_output_format_name(params->kind), 890 params->expected_name); 891 } 892 893 static const 894 struct drm_hdmi_connector_get_output_format_name_test 895 drm_hdmi_connector_get_output_format_name_valid_tests[] = { 896 OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_RGB, "RGB"), 897 OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV420, "YUV 4:2:0"), 898 OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV422, "YUV 4:2:2"), 899 OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV444, "YUV 4:4:4"), 900 }; 901 902 static void 903 drm_hdmi_connector_get_output_format_name_valid_desc(const struct drm_hdmi_connector_get_output_format_name_test *t, 904 char *desc) 905 { 906 sprintf(desc, "%s", t->expected_name); 907 } 908 909 KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_output_format_name_valid, 910 drm_hdmi_connector_get_output_format_name_valid_tests, 911 drm_hdmi_connector_get_output_format_name_valid_desc); 912 913 static void drm_test_drm_hdmi_connector_get_output_format_name_invalid(struct kunit *test) 914 { 915 KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_output_format_name(4)); 916 }; 917 918 static struct kunit_case drm_hdmi_connector_get_output_format_name_tests[] = { 919 KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_output_format_name, 920 drm_hdmi_connector_get_output_format_name_valid_gen_params), 921 KUNIT_CASE(drm_test_drm_hdmi_connector_get_output_format_name_invalid), 922 { } 923 }; 924 925 static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite = { 926 .name = "drm_hdmi_connector_get_output_format_name", 927 .test_cases = drm_hdmi_connector_get_output_format_name_tests, 928 }; 929 930 static void drm_test_drm_connector_attach_broadcast_rgb_property(struct kunit *test) 931 { 932 struct drm_connector_init_priv *priv = test->priv; 933 struct drm_connector *connector = &priv->connector; 934 struct drm_property *prop; 935 int ret; 936 937 ret = drmm_connector_init(&priv->drm, connector, 938 &dummy_funcs, 939 DRM_MODE_CONNECTOR_HDMIA, 940 &priv->ddc); 941 KUNIT_ASSERT_EQ(test, ret, 0); 942 943 ret = drm_connector_attach_broadcast_rgb_property(connector); 944 KUNIT_ASSERT_EQ(test, ret, 0); 945 946 prop = connector->broadcast_rgb_property; 947 KUNIT_ASSERT_NOT_NULL(test, prop); 948 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 949 } 950 951 static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(struct kunit *test) 952 { 953 struct drm_connector_init_priv *priv = test->priv; 954 struct drm_connector *connector = &priv->connector; 955 struct drm_property *prop; 956 int ret; 957 958 ret = drmm_connector_hdmi_init(&priv->drm, connector, 959 "Vendor", "Product", 960 &dummy_funcs, 961 &dummy_hdmi_funcs, 962 DRM_MODE_CONNECTOR_HDMIA, 963 &priv->ddc, 964 BIT(HDMI_COLORSPACE_RGB), 965 8); 966 KUNIT_EXPECT_EQ(test, ret, 0); 967 968 ret = drm_connector_attach_broadcast_rgb_property(connector); 969 KUNIT_ASSERT_EQ(test, ret, 0); 970 971 prop = connector->broadcast_rgb_property; 972 KUNIT_ASSERT_NOT_NULL(test, prop); 973 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 974 } 975 976 static struct kunit_case drm_connector_attach_broadcast_rgb_property_tests[] = { 977 KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property), 978 KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector), 979 { } 980 }; 981 982 static struct kunit_suite drm_connector_attach_broadcast_rgb_property_test_suite = { 983 .name = "drm_connector_attach_broadcast_rgb_property", 984 .init = drm_test_connector_init, 985 .test_cases = drm_connector_attach_broadcast_rgb_property_tests, 986 }; 987 988 /* 989 * Test that for a given mode, with 8bpc and an RGB output the TMDS 990 * character rate is equal to the mode pixel clock. 991 */ 992 static void drm_test_drm_hdmi_compute_mode_clock_rgb(struct kunit *test) 993 { 994 struct drm_connector_init_priv *priv = test->priv; 995 const struct drm_display_mode *mode; 996 unsigned long long rate; 997 struct drm_device *drm = &priv->drm; 998 999 mode = drm_display_mode_from_cea_vic(drm, 16); 1000 KUNIT_ASSERT_NOT_NULL(test, mode); 1001 1002 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1003 1004 rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); 1005 KUNIT_ASSERT_GT(test, rate, 0); 1006 KUNIT_EXPECT_EQ(test, mode->clock * 1000ULL, rate); 1007 } 1008 1009 /* 1010 * Test that for a given mode, with 10bpc and an RGB output the TMDS 1011 * character rate is equal to 1.25 times the mode pixel clock. 1012 */ 1013 static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc(struct kunit *test) 1014 { 1015 struct drm_connector_init_priv *priv = test->priv; 1016 const struct drm_display_mode *mode; 1017 unsigned long long rate; 1018 struct drm_device *drm = &priv->drm; 1019 1020 mode = drm_display_mode_from_cea_vic(drm, 16); 1021 KUNIT_ASSERT_NOT_NULL(test, mode); 1022 1023 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1024 1025 rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB); 1026 KUNIT_ASSERT_GT(test, rate, 0); 1027 KUNIT_EXPECT_EQ(test, mode->clock * 1250, rate); 1028 } 1029 1030 /* 1031 * Test that for the VIC-1 mode, with 10bpc and an RGB output the TMDS 1032 * character rate computation fails. 1033 */ 1034 static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *test) 1035 { 1036 struct drm_connector_init_priv *priv = test->priv; 1037 const struct drm_display_mode *mode; 1038 unsigned long long rate; 1039 struct drm_device *drm = &priv->drm; 1040 1041 mode = drm_display_mode_from_cea_vic(drm, 1); 1042 KUNIT_ASSERT_NOT_NULL(test, mode); 1043 1044 rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB); 1045 KUNIT_EXPECT_EQ(test, rate, 0); 1046 } 1047 1048 /* 1049 * Test that for a given mode, with 12bpc and an RGB output the TMDS 1050 * character rate is equal to 1.5 times the mode pixel clock. 1051 */ 1052 static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test) 1053 { 1054 struct drm_connector_init_priv *priv = test->priv; 1055 const struct drm_display_mode *mode; 1056 unsigned long long rate; 1057 struct drm_device *drm = &priv->drm; 1058 1059 mode = drm_display_mode_from_cea_vic(drm, 16); 1060 KUNIT_ASSERT_NOT_NULL(test, mode); 1061 1062 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1063 1064 rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB); 1065 KUNIT_ASSERT_GT(test, rate, 0); 1066 KUNIT_EXPECT_EQ(test, mode->clock * 1500, rate); 1067 } 1068 1069 /* 1070 * Test that for the VIC-1 mode, with 12bpc and an RGB output the TMDS 1071 * character rate computation fails. 1072 */ 1073 static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *test) 1074 { 1075 struct drm_connector_init_priv *priv = test->priv; 1076 const struct drm_display_mode *mode; 1077 unsigned long long rate; 1078 struct drm_device *drm = &priv->drm; 1079 1080 mode = drm_display_mode_from_cea_vic(drm, 1); 1081 KUNIT_ASSERT_NOT_NULL(test, mode); 1082 1083 rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB); 1084 KUNIT_EXPECT_EQ(test, rate, 0); 1085 } 1086 1087 /* 1088 * Test that for a mode with the pixel repetition flag, the TMDS 1089 * character rate is indeed double the mode pixel clock. 1090 */ 1091 static void drm_test_drm_hdmi_compute_mode_clock_rgb_double(struct kunit *test) 1092 { 1093 struct drm_connector_init_priv *priv = test->priv; 1094 const struct drm_display_mode *mode; 1095 unsigned long long rate; 1096 struct drm_device *drm = &priv->drm; 1097 1098 mode = drm_display_mode_from_cea_vic(drm, 6); 1099 KUNIT_ASSERT_NOT_NULL(test, mode); 1100 1101 KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1102 1103 rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); 1104 KUNIT_ASSERT_GT(test, rate, 0); 1105 KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) * 2, rate); 1106 } 1107 1108 /* 1109 * Test that the TMDS character rate computation for the VIC modes 1110 * explicitly listed in the spec as supporting YUV420 succeed and return 1111 * half the mode pixel clock. 1112 */ 1113 static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit *test) 1114 { 1115 struct drm_connector_init_priv *priv = test->priv; 1116 const struct drm_display_mode *mode; 1117 struct drm_device *drm = &priv->drm; 1118 unsigned long long rate; 1119 unsigned int vic = *(unsigned int *)test->param_value; 1120 1121 mode = drm_display_mode_from_cea_vic(drm, vic); 1122 KUNIT_ASSERT_NOT_NULL(test, mode); 1123 1124 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1125 1126 rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420); 1127 KUNIT_ASSERT_GT(test, rate, 0); 1128 KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) / 2, rate); 1129 } 1130 1131 static const unsigned int drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[] = { 1132 96, 97, 101, 102, 106, 107, 1133 }; 1134 1135 static void drm_hdmi_compute_mode_clock_yuv420_vic_desc(const unsigned int *vic, char *desc) 1136 { 1137 sprintf(desc, "VIC %u", *vic); 1138 } 1139 1140 KUNIT_ARRAY_PARAM(drm_hdmi_compute_mode_clock_yuv420_valid, 1141 drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests, 1142 drm_hdmi_compute_mode_clock_yuv420_vic_desc); 1143 1144 /* 1145 * Test that for a given mode listed supporting it and an YUV420 output 1146 * with 10bpc, the TMDS character rate is equal to 0.625 times the mode 1147 * pixel clock. 1148 */ 1149 static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kunit *test) 1150 { 1151 struct drm_connector_init_priv *priv = test->priv; 1152 const struct drm_display_mode *mode; 1153 struct drm_device *drm = &priv->drm; 1154 unsigned int vic = 1155 drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; 1156 unsigned long long rate; 1157 1158 mode = drm_display_mode_from_cea_vic(drm, vic); 1159 KUNIT_ASSERT_NOT_NULL(test, mode); 1160 1161 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1162 1163 rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV420); 1164 KUNIT_ASSERT_GT(test, rate, 0); 1165 1166 KUNIT_EXPECT_EQ(test, mode->clock * 625, rate); 1167 } 1168 1169 /* 1170 * Test that for a given mode listed supporting it and an YUV420 output 1171 * with 12bpc, the TMDS character rate is equal to 0.75 times the mode 1172 * pixel clock. 1173 */ 1174 static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kunit *test) 1175 { 1176 struct drm_connector_init_priv *priv = test->priv; 1177 const struct drm_display_mode *mode; 1178 struct drm_device *drm = &priv->drm; 1179 unsigned int vic = 1180 drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; 1181 unsigned long long rate; 1182 1183 mode = drm_display_mode_from_cea_vic(drm, vic); 1184 KUNIT_ASSERT_NOT_NULL(test, mode); 1185 1186 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1187 1188 rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV420); 1189 KUNIT_ASSERT_GT(test, rate, 0); 1190 1191 KUNIT_EXPECT_EQ(test, mode->clock * 750, rate); 1192 } 1193 1194 /* 1195 * Test that for a given mode, the computation of the TMDS character 1196 * rate with 8bpc and a YUV422 output succeeds and returns a rate equal 1197 * to the mode pixel clock. 1198 */ 1199 static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit *test) 1200 { 1201 struct drm_connector_init_priv *priv = test->priv; 1202 const struct drm_display_mode *mode; 1203 struct drm_device *drm = &priv->drm; 1204 unsigned long long rate; 1205 1206 mode = drm_display_mode_from_cea_vic(drm, 16); 1207 KUNIT_ASSERT_NOT_NULL(test, mode); 1208 1209 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1210 1211 rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV422); 1212 KUNIT_ASSERT_GT(test, rate, 0); 1213 KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate); 1214 } 1215 1216 /* 1217 * Test that for a given mode, the computation of the TMDS character 1218 * rate with 10bpc and a YUV422 output succeeds and returns a rate equal 1219 * to the mode pixel clock. 1220 */ 1221 static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kunit *test) 1222 { 1223 struct drm_connector_init_priv *priv = test->priv; 1224 const struct drm_display_mode *mode; 1225 struct drm_device *drm = &priv->drm; 1226 unsigned long long rate; 1227 1228 mode = drm_display_mode_from_cea_vic(drm, 16); 1229 KUNIT_ASSERT_NOT_NULL(test, mode); 1230 1231 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1232 1233 rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV422); 1234 KUNIT_ASSERT_GT(test, rate, 0); 1235 KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate); 1236 } 1237 1238 /* 1239 * Test that for a given mode, the computation of the TMDS character 1240 * rate with 12bpc and a YUV422 output succeeds and returns a rate equal 1241 * to the mode pixel clock. 1242 */ 1243 static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kunit *test) 1244 { 1245 struct drm_connector_init_priv *priv = test->priv; 1246 const struct drm_display_mode *mode; 1247 struct drm_device *drm = &priv->drm; 1248 unsigned long long rate; 1249 1250 mode = drm_display_mode_from_cea_vic(drm, 16); 1251 KUNIT_ASSERT_NOT_NULL(test, mode); 1252 1253 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1254 1255 rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV422); 1256 KUNIT_ASSERT_GT(test, rate, 0); 1257 KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate); 1258 } 1259 1260 static struct kunit_case drm_hdmi_compute_mode_clock_tests[] = { 1261 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb), 1262 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc), 1263 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1), 1264 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc), 1265 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1), 1266 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_double), 1267 KUNIT_CASE_PARAM(drm_test_connector_hdmi_compute_mode_clock_yuv420_valid, 1268 drm_hdmi_compute_mode_clock_yuv420_valid_gen_params), 1269 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc), 1270 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc), 1271 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc), 1272 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc), 1273 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc), 1274 { } 1275 }; 1276 1277 static struct kunit_suite drm_hdmi_compute_mode_clock_test_suite = { 1278 .name = "drm_test_connector_hdmi_compute_mode_clock", 1279 .init = drm_test_connector_init, 1280 .test_cases = drm_hdmi_compute_mode_clock_tests, 1281 }; 1282 1283 kunit_test_suites( 1284 &drmm_connector_hdmi_init_test_suite, 1285 &drmm_connector_init_test_suite, 1286 &drm_connector_attach_broadcast_rgb_property_test_suite, 1287 &drm_get_tv_mode_from_name_test_suite, 1288 &drm_hdmi_compute_mode_clock_test_suite, 1289 &drm_hdmi_connector_get_broadcast_rgb_name_test_suite, 1290 &drm_hdmi_connector_get_output_format_name_test_suite 1291 ); 1292 1293 MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>"); 1294 MODULE_DESCRIPTION("Kunit test for drm_modes functions"); 1295 MODULE_LICENSE("GPL"); 1296