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 struct drm_connector_hdmi_init_formats_yuv420_allowed_test { 639 unsigned long supported_formats; 640 bool yuv420_allowed; 641 int expected_result; 642 }; 643 644 #define YUV420_ALLOWED_TEST(_formats, _allowed, _result) \ 645 { \ 646 .supported_formats = BIT(HDMI_COLORSPACE_RGB) | (_formats), \ 647 .yuv420_allowed = _allowed, \ 648 .expected_result = _result, \ 649 } 650 651 static const struct drm_connector_hdmi_init_formats_yuv420_allowed_test 652 drm_connector_hdmi_init_formats_yuv420_allowed_tests[] = { 653 YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV420), true, 0), 654 YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV420), false, -EINVAL), 655 YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV422), true, -EINVAL), 656 YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV422), false, 0), 657 }; 658 659 static void 660 drm_connector_hdmi_init_formats_yuv420_allowed_desc(const struct drm_connector_hdmi_init_formats_yuv420_allowed_test *t, 661 char *desc) 662 { 663 sprintf(desc, "supported_formats=0x%lx yuv420_allowed=%d", 664 t->supported_formats, t->yuv420_allowed); 665 } 666 667 KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_formats_yuv420_allowed, 668 drm_connector_hdmi_init_formats_yuv420_allowed_tests, 669 drm_connector_hdmi_init_formats_yuv420_allowed_desc); 670 671 /* 672 * Test that the registration of an HDMI connector succeeds only when 673 * the presence of YUV420 in the supported formats matches the value 674 * of the ycbcr_420_allowed flag. 675 */ 676 static void drm_test_connector_hdmi_init_formats_yuv420_allowed(struct kunit *test) 677 { 678 const struct drm_connector_hdmi_init_formats_yuv420_allowed_test *params; 679 struct drm_connector_init_priv *priv = test->priv; 680 int ret; 681 682 params = test->param_value; 683 priv->connector.ycbcr_420_allowed = params->yuv420_allowed; 684 685 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 686 "Vendor", "Product", 687 &dummy_funcs, 688 &dummy_hdmi_funcs, 689 DRM_MODE_CONNECTOR_HDMIA, 690 &priv->ddc, 691 params->supported_formats, 692 8); 693 KUNIT_EXPECT_EQ(test, ret, params->expected_result); 694 } 695 696 /* 697 * Test that the registration of an HDMI connector with an HDMI 698 * connector type succeeds. 699 */ 700 static void drm_test_connector_hdmi_init_type_valid(struct kunit *test) 701 { 702 struct drm_connector_init_priv *priv = test->priv; 703 unsigned int connector_type = *(unsigned int *)test->param_value; 704 int ret; 705 706 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 707 "Vendor", "Product", 708 &dummy_funcs, 709 &dummy_hdmi_funcs, 710 connector_type, 711 &priv->ddc, 712 BIT(HDMI_COLORSPACE_RGB), 713 8); 714 KUNIT_EXPECT_EQ(test, ret, 0); 715 } 716 717 static const unsigned int drm_connector_hdmi_init_type_valid_tests[] = { 718 DRM_MODE_CONNECTOR_HDMIA, 719 DRM_MODE_CONNECTOR_HDMIB, 720 }; 721 722 static void drm_connector_hdmi_init_type_desc(const unsigned int *type, char *desc) 723 { 724 sprintf(desc, "%s", drm_get_connector_type_name(*type)); 725 } 726 727 KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_valid, 728 drm_connector_hdmi_init_type_valid_tests, 729 drm_connector_hdmi_init_type_desc); 730 731 /* 732 * Test that the registration of an HDMI connector with an !HDMI 733 * connector type fails. 734 */ 735 static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test) 736 { 737 struct drm_connector_init_priv *priv = test->priv; 738 unsigned int connector_type = *(unsigned int *)test->param_value; 739 int ret; 740 741 ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector, 742 "Vendor", "Product", 743 &dummy_funcs, 744 &dummy_hdmi_funcs, 745 connector_type, 746 &priv->ddc, 747 BIT(HDMI_COLORSPACE_RGB), 748 8); 749 KUNIT_EXPECT_LT(test, ret, 0); 750 } 751 752 static const unsigned int drm_connector_hdmi_init_type_invalid_tests[] = { 753 DRM_MODE_CONNECTOR_Unknown, 754 DRM_MODE_CONNECTOR_VGA, 755 DRM_MODE_CONNECTOR_DVII, 756 DRM_MODE_CONNECTOR_DVID, 757 DRM_MODE_CONNECTOR_DVIA, 758 DRM_MODE_CONNECTOR_Composite, 759 DRM_MODE_CONNECTOR_SVIDEO, 760 DRM_MODE_CONNECTOR_LVDS, 761 DRM_MODE_CONNECTOR_Component, 762 DRM_MODE_CONNECTOR_9PinDIN, 763 DRM_MODE_CONNECTOR_DisplayPort, 764 DRM_MODE_CONNECTOR_TV, 765 DRM_MODE_CONNECTOR_eDP, 766 DRM_MODE_CONNECTOR_VIRTUAL, 767 DRM_MODE_CONNECTOR_DSI, 768 DRM_MODE_CONNECTOR_DPI, 769 DRM_MODE_CONNECTOR_WRITEBACK, 770 DRM_MODE_CONNECTOR_SPI, 771 DRM_MODE_CONNECTOR_USB, 772 }; 773 774 KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid, 775 drm_connector_hdmi_init_type_invalid_tests, 776 drm_connector_hdmi_init_type_desc); 777 778 static struct kunit_case drmm_connector_hdmi_init_tests[] = { 779 KUNIT_CASE(drm_test_connector_hdmi_init_valid), 780 KUNIT_CASE(drm_test_connector_hdmi_init_bpc_8), 781 KUNIT_CASE(drm_test_connector_hdmi_init_bpc_10), 782 KUNIT_CASE(drm_test_connector_hdmi_init_bpc_12), 783 KUNIT_CASE(drm_test_connector_hdmi_init_bpc_invalid), 784 KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null), 785 KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty), 786 KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb), 787 KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_formats_yuv420_allowed, 788 drm_connector_hdmi_init_formats_yuv420_allowed_gen_params), 789 KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc), 790 KUNIT_CASE(drm_test_connector_hdmi_init_null_product), 791 KUNIT_CASE(drm_test_connector_hdmi_init_null_vendor), 792 KUNIT_CASE(drm_test_connector_hdmi_init_product_length_exact), 793 KUNIT_CASE(drm_test_connector_hdmi_init_product_length_too_long), 794 KUNIT_CASE(drm_test_connector_hdmi_init_product_valid), 795 KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_exact), 796 KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_too_long), 797 KUNIT_CASE(drm_test_connector_hdmi_init_vendor_valid), 798 KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid, 799 drm_connector_hdmi_init_type_valid_gen_params), 800 KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid, 801 drm_connector_hdmi_init_type_invalid_gen_params), 802 { } 803 }; 804 805 static struct kunit_suite drmm_connector_hdmi_init_test_suite = { 806 .name = "drmm_connector_hdmi_init", 807 .init = drm_test_connector_init, 808 .test_cases = drmm_connector_hdmi_init_tests, 809 }; 810 811 struct drm_get_tv_mode_from_name_test { 812 const char *name; 813 enum drm_connector_tv_mode expected_mode; 814 }; 815 816 #define TV_MODE_NAME(_name, _mode) \ 817 { \ 818 .name = _name, \ 819 .expected_mode = _mode, \ 820 } 821 822 static void drm_test_get_tv_mode_from_name_valid(struct kunit *test) 823 { 824 const struct drm_get_tv_mode_from_name_test *params = test->param_value; 825 826 KUNIT_EXPECT_EQ(test, 827 drm_get_tv_mode_from_name(params->name, strlen(params->name)), 828 params->expected_mode); 829 } 830 831 static const 832 struct drm_get_tv_mode_from_name_test drm_get_tv_mode_from_name_valid_tests[] = { 833 TV_MODE_NAME("NTSC", DRM_MODE_TV_MODE_NTSC), 834 TV_MODE_NAME("NTSC-443", DRM_MODE_TV_MODE_NTSC_443), 835 TV_MODE_NAME("NTSC-J", DRM_MODE_TV_MODE_NTSC_J), 836 TV_MODE_NAME("PAL", DRM_MODE_TV_MODE_PAL), 837 TV_MODE_NAME("PAL-M", DRM_MODE_TV_MODE_PAL_M), 838 TV_MODE_NAME("PAL-N", DRM_MODE_TV_MODE_PAL_N), 839 TV_MODE_NAME("SECAM", DRM_MODE_TV_MODE_SECAM), 840 TV_MODE_NAME("Mono", DRM_MODE_TV_MODE_MONOCHROME), 841 }; 842 843 static void 844 drm_get_tv_mode_from_name_valid_desc(const struct drm_get_tv_mode_from_name_test *t, 845 char *desc) 846 { 847 sprintf(desc, "%s", t->name); 848 } 849 850 KUNIT_ARRAY_PARAM(drm_get_tv_mode_from_name_valid, 851 drm_get_tv_mode_from_name_valid_tests, 852 drm_get_tv_mode_from_name_valid_desc); 853 854 static void drm_test_get_tv_mode_from_name_truncated(struct kunit *test) 855 { 856 const char *name = "NTS"; 857 int ret; 858 859 ret = drm_get_tv_mode_from_name(name, strlen(name)); 860 KUNIT_EXPECT_LT(test, ret, 0); 861 }; 862 863 static struct kunit_case drm_get_tv_mode_from_name_tests[] = { 864 KUNIT_CASE_PARAM(drm_test_get_tv_mode_from_name_valid, 865 drm_get_tv_mode_from_name_valid_gen_params), 866 KUNIT_CASE(drm_test_get_tv_mode_from_name_truncated), 867 { } 868 }; 869 870 static struct kunit_suite drm_get_tv_mode_from_name_test_suite = { 871 .name = "drm_get_tv_mode_from_name", 872 .test_cases = drm_get_tv_mode_from_name_tests, 873 }; 874 875 struct drm_hdmi_connector_get_broadcast_rgb_name_test { 876 unsigned int kind; 877 const char *expected_name; 878 }; 879 880 #define BROADCAST_RGB_TEST(_kind, _name) \ 881 { \ 882 .kind = _kind, \ 883 .expected_name = _name, \ 884 } 885 886 static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name(struct kunit *test) 887 { 888 const struct drm_hdmi_connector_get_broadcast_rgb_name_test *params = 889 test->param_value; 890 891 KUNIT_EXPECT_STREQ(test, 892 drm_hdmi_connector_get_broadcast_rgb_name(params->kind), 893 params->expected_name); 894 } 895 896 static const 897 struct drm_hdmi_connector_get_broadcast_rgb_name_test 898 drm_hdmi_connector_get_broadcast_rgb_name_valid_tests[] = { 899 BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic"), 900 BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_FULL, "Full"), 901 BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235"), 902 }; 903 904 static void 905 drm_hdmi_connector_get_broadcast_rgb_name_valid_desc(const struct drm_hdmi_connector_get_broadcast_rgb_name_test *t, 906 char *desc) 907 { 908 sprintf(desc, "%s", t->expected_name); 909 } 910 911 KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_broadcast_rgb_name_valid, 912 drm_hdmi_connector_get_broadcast_rgb_name_valid_tests, 913 drm_hdmi_connector_get_broadcast_rgb_name_valid_desc); 914 915 static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid(struct kunit *test) 916 { 917 KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_broadcast_rgb_name(3)); 918 }; 919 920 static struct kunit_case drm_hdmi_connector_get_broadcast_rgb_name_tests[] = { 921 KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_broadcast_rgb_name, 922 drm_hdmi_connector_get_broadcast_rgb_name_valid_gen_params), 923 KUNIT_CASE(drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid), 924 { } 925 }; 926 927 static struct kunit_suite drm_hdmi_connector_get_broadcast_rgb_name_test_suite = { 928 .name = "drm_hdmi_connector_get_broadcast_rgb_name", 929 .test_cases = drm_hdmi_connector_get_broadcast_rgb_name_tests, 930 }; 931 932 struct drm_hdmi_connector_get_output_format_name_test { 933 unsigned int kind; 934 const char *expected_name; 935 }; 936 937 #define OUTPUT_FORMAT_TEST(_kind, _name) \ 938 { \ 939 .kind = _kind, \ 940 .expected_name = _name, \ 941 } 942 943 static void drm_test_drm_hdmi_connector_get_output_format_name(struct kunit *test) 944 { 945 const struct drm_hdmi_connector_get_output_format_name_test *params = 946 test->param_value; 947 948 KUNIT_EXPECT_STREQ(test, 949 drm_hdmi_connector_get_output_format_name(params->kind), 950 params->expected_name); 951 } 952 953 static const 954 struct drm_hdmi_connector_get_output_format_name_test 955 drm_hdmi_connector_get_output_format_name_valid_tests[] = { 956 OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_RGB, "RGB"), 957 OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV420, "YUV 4:2:0"), 958 OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV422, "YUV 4:2:2"), 959 OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV444, "YUV 4:4:4"), 960 }; 961 962 static void 963 drm_hdmi_connector_get_output_format_name_valid_desc(const struct drm_hdmi_connector_get_output_format_name_test *t, 964 char *desc) 965 { 966 sprintf(desc, "%s", t->expected_name); 967 } 968 969 KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_output_format_name_valid, 970 drm_hdmi_connector_get_output_format_name_valid_tests, 971 drm_hdmi_connector_get_output_format_name_valid_desc); 972 973 static void drm_test_drm_hdmi_connector_get_output_format_name_invalid(struct kunit *test) 974 { 975 KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_output_format_name(4)); 976 }; 977 978 static struct kunit_case drm_hdmi_connector_get_output_format_name_tests[] = { 979 KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_output_format_name, 980 drm_hdmi_connector_get_output_format_name_valid_gen_params), 981 KUNIT_CASE(drm_test_drm_hdmi_connector_get_output_format_name_invalid), 982 { } 983 }; 984 985 static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite = { 986 .name = "drm_hdmi_connector_get_output_format_name", 987 .test_cases = drm_hdmi_connector_get_output_format_name_tests, 988 }; 989 990 static void drm_test_drm_connector_attach_broadcast_rgb_property(struct kunit *test) 991 { 992 struct drm_connector_init_priv *priv = test->priv; 993 struct drm_connector *connector = &priv->connector; 994 struct drm_property *prop; 995 int ret; 996 997 ret = drmm_connector_init(&priv->drm, connector, 998 &dummy_funcs, 999 DRM_MODE_CONNECTOR_HDMIA, 1000 &priv->ddc); 1001 KUNIT_ASSERT_EQ(test, ret, 0); 1002 1003 ret = drm_connector_attach_broadcast_rgb_property(connector); 1004 KUNIT_ASSERT_EQ(test, ret, 0); 1005 1006 prop = connector->broadcast_rgb_property; 1007 KUNIT_ASSERT_NOT_NULL(test, prop); 1008 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 1009 } 1010 1011 static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(struct kunit *test) 1012 { 1013 struct drm_connector_init_priv *priv = test->priv; 1014 struct drm_connector *connector = &priv->connector; 1015 struct drm_property *prop; 1016 int ret; 1017 1018 ret = drmm_connector_hdmi_init(&priv->drm, connector, 1019 "Vendor", "Product", 1020 &dummy_funcs, 1021 &dummy_hdmi_funcs, 1022 DRM_MODE_CONNECTOR_HDMIA, 1023 &priv->ddc, 1024 BIT(HDMI_COLORSPACE_RGB), 1025 8); 1026 KUNIT_EXPECT_EQ(test, ret, 0); 1027 1028 ret = drm_connector_attach_broadcast_rgb_property(connector); 1029 KUNIT_ASSERT_EQ(test, ret, 0); 1030 1031 prop = connector->broadcast_rgb_property; 1032 KUNIT_ASSERT_NOT_NULL(test, prop); 1033 KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id)); 1034 } 1035 1036 static struct kunit_case drm_connector_attach_broadcast_rgb_property_tests[] = { 1037 KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property), 1038 KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector), 1039 { } 1040 }; 1041 1042 static struct kunit_suite drm_connector_attach_broadcast_rgb_property_test_suite = { 1043 .name = "drm_connector_attach_broadcast_rgb_property", 1044 .init = drm_test_connector_init, 1045 .test_cases = drm_connector_attach_broadcast_rgb_property_tests, 1046 }; 1047 1048 /* 1049 * Test that for a given mode, with 8bpc and an RGB output the TMDS 1050 * character rate is equal to the mode pixel clock. 1051 */ 1052 static void drm_test_drm_hdmi_compute_mode_clock_rgb(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_kunit_display_mode_from_cea_vic(test, 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, 8, HDMI_COLORSPACE_RGB); 1065 KUNIT_ASSERT_GT(test, rate, 0); 1066 KUNIT_EXPECT_EQ(test, mode->clock * 1000ULL, rate); 1067 } 1068 1069 /* 1070 * Test that for a given mode, with 10bpc and an RGB output the TMDS 1071 * character rate is equal to 1.25 times the mode pixel clock. 1072 */ 1073 static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc(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_kunit_display_mode_from_cea_vic(test, drm, 16); 1081 KUNIT_ASSERT_NOT_NULL(test, mode); 1082 1083 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1084 1085 rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB); 1086 KUNIT_ASSERT_GT(test, rate, 0); 1087 KUNIT_EXPECT_EQ(test, mode->clock * 1250, rate); 1088 } 1089 1090 /* 1091 * Test that for the VIC-1 mode, with 10bpc and an RGB output the TMDS 1092 * character rate computation fails. 1093 */ 1094 static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *test) 1095 { 1096 struct drm_connector_init_priv *priv = test->priv; 1097 const struct drm_display_mode *mode; 1098 unsigned long long rate; 1099 struct drm_device *drm = &priv->drm; 1100 1101 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); 1102 KUNIT_ASSERT_NOT_NULL(test, mode); 1103 1104 rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB); 1105 KUNIT_EXPECT_EQ(test, rate, 0); 1106 } 1107 1108 /* 1109 * Test that for a given mode, with 12bpc and an RGB output the TMDS 1110 * character rate is equal to 1.5 times the mode pixel clock. 1111 */ 1112 static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test) 1113 { 1114 struct drm_connector_init_priv *priv = test->priv; 1115 const struct drm_display_mode *mode; 1116 unsigned long long rate; 1117 struct drm_device *drm = &priv->drm; 1118 1119 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16); 1120 KUNIT_ASSERT_NOT_NULL(test, mode); 1121 1122 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1123 1124 rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB); 1125 KUNIT_ASSERT_GT(test, rate, 0); 1126 KUNIT_EXPECT_EQ(test, mode->clock * 1500, rate); 1127 } 1128 1129 /* 1130 * Test that for the VIC-1 mode, with 12bpc and an RGB output the TMDS 1131 * character rate computation fails. 1132 */ 1133 static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *test) 1134 { 1135 struct drm_connector_init_priv *priv = test->priv; 1136 const struct drm_display_mode *mode; 1137 unsigned long long rate; 1138 struct drm_device *drm = &priv->drm; 1139 1140 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); 1141 KUNIT_ASSERT_NOT_NULL(test, mode); 1142 1143 rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB); 1144 KUNIT_EXPECT_EQ(test, rate, 0); 1145 } 1146 1147 /* 1148 * Test that for a mode with the pixel repetition flag, the TMDS 1149 * character rate is indeed double the mode pixel clock. 1150 */ 1151 static void drm_test_drm_hdmi_compute_mode_clock_rgb_double(struct kunit *test) 1152 { 1153 struct drm_connector_init_priv *priv = test->priv; 1154 const struct drm_display_mode *mode; 1155 unsigned long long rate; 1156 struct drm_device *drm = &priv->drm; 1157 1158 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 6); 1159 KUNIT_ASSERT_NOT_NULL(test, mode); 1160 1161 KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1162 1163 rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB); 1164 KUNIT_ASSERT_GT(test, rate, 0); 1165 KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) * 2, rate); 1166 } 1167 1168 /* 1169 * Test that the TMDS character rate computation for the VIC modes 1170 * explicitly listed in the spec as supporting YUV420 succeed and return 1171 * half the mode pixel clock. 1172 */ 1173 static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(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 long long rate; 1179 unsigned int vic = *(unsigned int *)test->param_value; 1180 1181 mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic); 1182 KUNIT_ASSERT_NOT_NULL(test, mode); 1183 1184 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1185 1186 rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420); 1187 KUNIT_ASSERT_GT(test, rate, 0); 1188 KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) / 2, rate); 1189 } 1190 1191 static const unsigned int drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[] = { 1192 96, 97, 101, 102, 106, 107, 1193 }; 1194 1195 static void drm_hdmi_compute_mode_clock_yuv420_vic_desc(const unsigned int *vic, char *desc) 1196 { 1197 sprintf(desc, "VIC %u", *vic); 1198 } 1199 1200 KUNIT_ARRAY_PARAM(drm_hdmi_compute_mode_clock_yuv420_valid, 1201 drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests, 1202 drm_hdmi_compute_mode_clock_yuv420_vic_desc); 1203 1204 /* 1205 * Test that for a given mode listed supporting it and an YUV420 output 1206 * with 10bpc, the TMDS character rate is equal to 0.625 times the mode 1207 * pixel clock. 1208 */ 1209 static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kunit *test) 1210 { 1211 struct drm_connector_init_priv *priv = test->priv; 1212 const struct drm_display_mode *mode; 1213 struct drm_device *drm = &priv->drm; 1214 unsigned int vic = 1215 drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; 1216 unsigned long long rate; 1217 1218 mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic); 1219 KUNIT_ASSERT_NOT_NULL(test, mode); 1220 1221 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1222 1223 rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV420); 1224 KUNIT_ASSERT_GT(test, rate, 0); 1225 1226 KUNIT_EXPECT_EQ(test, mode->clock * 625, rate); 1227 } 1228 1229 /* 1230 * Test that for a given mode listed supporting it and an YUV420 output 1231 * with 12bpc, the TMDS character rate is equal to 0.75 times the mode 1232 * pixel clock. 1233 */ 1234 static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kunit *test) 1235 { 1236 struct drm_connector_init_priv *priv = test->priv; 1237 const struct drm_display_mode *mode; 1238 struct drm_device *drm = &priv->drm; 1239 unsigned int vic = 1240 drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; 1241 unsigned long long rate; 1242 1243 mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic); 1244 KUNIT_ASSERT_NOT_NULL(test, mode); 1245 1246 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1247 1248 rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV420); 1249 KUNIT_ASSERT_GT(test, rate, 0); 1250 1251 KUNIT_EXPECT_EQ(test, mode->clock * 750, rate); 1252 } 1253 1254 /* 1255 * Test that for a given mode, the computation of the TMDS character 1256 * rate with 8bpc and a YUV422 output succeeds and returns a rate equal 1257 * to the mode pixel clock. 1258 */ 1259 static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit *test) 1260 { 1261 struct drm_connector_init_priv *priv = test->priv; 1262 const struct drm_display_mode *mode; 1263 struct drm_device *drm = &priv->drm; 1264 unsigned long long rate; 1265 1266 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16); 1267 KUNIT_ASSERT_NOT_NULL(test, mode); 1268 1269 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1270 1271 rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV422); 1272 KUNIT_ASSERT_GT(test, rate, 0); 1273 KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate); 1274 } 1275 1276 /* 1277 * Test that for a given mode, the computation of the TMDS character 1278 * rate with 10bpc and a YUV422 output succeeds and returns a rate equal 1279 * to the mode pixel clock. 1280 */ 1281 static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kunit *test) 1282 { 1283 struct drm_connector_init_priv *priv = test->priv; 1284 const struct drm_display_mode *mode; 1285 struct drm_device *drm = &priv->drm; 1286 unsigned long long rate; 1287 1288 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16); 1289 KUNIT_ASSERT_NOT_NULL(test, mode); 1290 1291 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1292 1293 rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV422); 1294 KUNIT_ASSERT_GT(test, rate, 0); 1295 KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate); 1296 } 1297 1298 /* 1299 * Test that for a given mode, the computation of the TMDS character 1300 * rate with 12bpc and a YUV422 output succeeds and returns a rate equal 1301 * to the mode pixel clock. 1302 */ 1303 static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kunit *test) 1304 { 1305 struct drm_connector_init_priv *priv = test->priv; 1306 const struct drm_display_mode *mode; 1307 struct drm_device *drm = &priv->drm; 1308 unsigned long long rate; 1309 1310 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16); 1311 KUNIT_ASSERT_NOT_NULL(test, mode); 1312 1313 KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); 1314 1315 rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV422); 1316 KUNIT_ASSERT_GT(test, rate, 0); 1317 KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate); 1318 } 1319 1320 static struct kunit_case drm_hdmi_compute_mode_clock_tests[] = { 1321 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb), 1322 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc), 1323 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1), 1324 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc), 1325 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1), 1326 KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_double), 1327 KUNIT_CASE_PARAM(drm_test_connector_hdmi_compute_mode_clock_yuv420_valid, 1328 drm_hdmi_compute_mode_clock_yuv420_valid_gen_params), 1329 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc), 1330 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc), 1331 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc), 1332 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc), 1333 KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc), 1334 { } 1335 }; 1336 1337 static struct kunit_suite drm_hdmi_compute_mode_clock_test_suite = { 1338 .name = "drm_test_connector_hdmi_compute_mode_clock", 1339 .init = drm_test_connector_init, 1340 .test_cases = drm_hdmi_compute_mode_clock_tests, 1341 }; 1342 1343 kunit_test_suites( 1344 &drmm_connector_hdmi_init_test_suite, 1345 &drmm_connector_init_test_suite, 1346 &drm_connector_attach_broadcast_rgb_property_test_suite, 1347 &drm_get_tv_mode_from_name_test_suite, 1348 &drm_hdmi_compute_mode_clock_test_suite, 1349 &drm_hdmi_connector_get_broadcast_rgb_name_test_suite, 1350 &drm_hdmi_connector_get_output_format_name_test_suite 1351 ); 1352 1353 MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>"); 1354 MODULE_DESCRIPTION("Kunit test for drm_modes functions"); 1355 MODULE_LICENSE("GPL"); 1356