1 // SPDX-License-Identifier: GPL-2.0 2 3 /* 4 * Kunit test for drm_hdmi_state_helper functions 5 */ 6 7 #include <drm/drm_atomic.h> 8 #include <drm/drm_atomic_state_helper.h> 9 #include <drm/drm_atomic_uapi.h> 10 #include <drm/drm_drv.h> 11 #include <drm/drm_edid.h> 12 #include <drm/drm_connector.h> 13 #include <drm/drm_fourcc.h> 14 #include <drm/drm_kunit_helpers.h> 15 #include <drm/drm_managed.h> 16 #include <drm/drm_modeset_helper_vtables.h> 17 #include <drm/drm_print.h> 18 #include <drm/drm_probe_helper.h> 19 20 #include <drm/display/drm_hdmi_helper.h> 21 #include <drm/display/drm_hdmi_state_helper.h> 22 23 #include "../drm_crtc_internal.h" 24 25 #include <kunit/test.h> 26 27 #include "drm_kunit_edid.h" 28 29 struct drm_atomic_helper_connector_hdmi_priv { 30 struct drm_device drm; 31 struct drm_plane *plane; 32 struct drm_crtc *crtc; 33 struct drm_encoder encoder; 34 struct drm_connector connector; 35 36 const char *current_edid; 37 size_t current_edid_len; 38 }; 39 40 #define connector_to_priv(c) \ 41 container_of_const(c, struct drm_atomic_helper_connector_hdmi_priv, connector) 42 43 static struct drm_display_mode *find_preferred_mode(struct drm_connector *connector) 44 { 45 struct drm_device *drm = connector->dev; 46 struct drm_display_mode *mode, *preferred; 47 48 mutex_lock(&drm->mode_config.mutex); 49 preferred = list_first_entry_or_null(&connector->modes, struct drm_display_mode, head); 50 list_for_each_entry(mode, &connector->modes, head) 51 if (mode->type & DRM_MODE_TYPE_PREFERRED) 52 preferred = mode; 53 mutex_unlock(&drm->mode_config.mutex); 54 55 return preferred; 56 } 57 58 static int set_connector_edid(struct kunit *test, struct drm_connector *connector, 59 const char *edid, size_t edid_len) 60 { 61 struct drm_atomic_helper_connector_hdmi_priv *priv = 62 connector_to_priv(connector); 63 struct drm_device *drm = connector->dev; 64 int ret; 65 66 priv->current_edid = edid; 67 priv->current_edid_len = edid_len; 68 69 mutex_lock(&drm->mode_config.mutex); 70 ret = connector->funcs->fill_modes(connector, 4096, 4096); 71 mutex_unlock(&drm->mode_config.mutex); 72 73 return ret; 74 } 75 76 static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = { 77 }; 78 79 static enum drm_mode_status 80 reject_connector_tmds_char_rate_valid(const struct drm_connector *connector, 81 const struct drm_display_mode *mode, 82 unsigned long long tmds_rate) 83 { 84 return MODE_BAD; 85 } 86 87 static const struct drm_connector_hdmi_funcs reject_connector_hdmi_funcs = { 88 .tmds_char_rate_valid = reject_connector_tmds_char_rate_valid, 89 }; 90 91 static enum drm_mode_status 92 reject_100MHz_connector_tmds_char_rate_valid(const struct drm_connector *connector, 93 const struct drm_display_mode *mode, 94 unsigned long long tmds_rate) 95 { 96 return (tmds_rate > 100ULL * 1000 * 1000) ? MODE_BAD : MODE_OK; 97 } 98 99 static const struct drm_connector_hdmi_funcs reject_100_MHz_connector_hdmi_funcs = { 100 .tmds_char_rate_valid = reject_100MHz_connector_tmds_char_rate_valid, 101 }; 102 103 static int dummy_connector_get_modes(struct drm_connector *connector) 104 { 105 struct drm_atomic_helper_connector_hdmi_priv *priv = 106 connector_to_priv(connector); 107 const struct drm_edid *edid; 108 unsigned int num_modes; 109 110 edid = drm_edid_alloc(priv->current_edid, priv->current_edid_len); 111 if (!edid) 112 return -EINVAL; 113 114 drm_edid_connector_update(connector, edid); 115 num_modes = drm_edid_connector_add_modes(connector); 116 117 drm_edid_free(edid); 118 119 return num_modes; 120 } 121 122 static const struct drm_connector_helper_funcs dummy_connector_helper_funcs = { 123 .atomic_check = drm_atomic_helper_connector_hdmi_check, 124 .get_modes = dummy_connector_get_modes, 125 .mode_valid = drm_hdmi_connector_mode_valid, 126 }; 127 128 static void dummy_hdmi_connector_reset(struct drm_connector *connector) 129 { 130 drm_atomic_helper_connector_reset(connector); 131 __drm_atomic_helper_connector_hdmi_reset(connector, connector->state); 132 } 133 134 static const struct drm_connector_funcs dummy_connector_funcs = { 135 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 136 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 137 .fill_modes = drm_helper_probe_single_connector_modes, 138 .reset = dummy_hdmi_connector_reset, 139 }; 140 141 static 142 struct drm_atomic_helper_connector_hdmi_priv * 143 drm_kunit_helper_connector_hdmi_init_funcs(struct kunit *test, 144 unsigned int formats, 145 unsigned int max_bpc, 146 const struct drm_connector_hdmi_funcs *hdmi_funcs) 147 { 148 struct drm_atomic_helper_connector_hdmi_priv *priv; 149 struct drm_connector *conn; 150 struct drm_encoder *enc; 151 struct drm_device *drm; 152 struct device *dev; 153 int ret; 154 155 dev = drm_kunit_helper_alloc_device(test); 156 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); 157 158 priv = drm_kunit_helper_alloc_drm_device(test, dev, 159 struct drm_atomic_helper_connector_hdmi_priv, drm, 160 DRIVER_MODESET | DRIVER_ATOMIC); 161 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); 162 test->priv = priv; 163 164 drm = &priv->drm; 165 priv->plane = drm_kunit_helper_create_primary_plane(test, drm, 166 NULL, 167 NULL, 168 NULL, 0, 169 NULL); 170 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->plane); 171 172 priv->crtc = drm_kunit_helper_create_crtc(test, drm, 173 priv->plane, NULL, 174 NULL, 175 NULL); 176 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->crtc); 177 178 enc = &priv->encoder; 179 ret = drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL); 180 KUNIT_ASSERT_EQ(test, ret, 0); 181 182 enc->possible_crtcs = drm_crtc_mask(priv->crtc); 183 184 conn = &priv->connector; 185 ret = drmm_connector_hdmi_init(drm, conn, 186 "Vendor", "Product", 187 &dummy_connector_funcs, 188 hdmi_funcs, 189 DRM_MODE_CONNECTOR_HDMIA, 190 NULL, 191 formats, 192 max_bpc); 193 KUNIT_ASSERT_EQ(test, ret, 0); 194 195 drm_connector_helper_add(conn, &dummy_connector_helper_funcs); 196 drm_connector_attach_encoder(conn, enc); 197 198 drm_mode_config_reset(drm); 199 200 return priv; 201 } 202 203 static 204 struct drm_atomic_helper_connector_hdmi_priv * 205 drm_kunit_helper_connector_hdmi_init(struct kunit *test, 206 unsigned int formats, 207 unsigned int max_bpc) 208 { 209 struct drm_atomic_helper_connector_hdmi_priv *priv; 210 int ret; 211 212 priv = drm_kunit_helper_connector_hdmi_init_funcs(test, 213 formats, max_bpc, 214 &dummy_connector_hdmi_funcs); 215 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); 216 217 ret = set_connector_edid(test, &priv->connector, 218 test_edid_hdmi_1080p_rgb_max_200mhz, 219 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); 220 KUNIT_ASSERT_GT(test, ret, 0); 221 222 return priv; 223 } 224 225 /* 226 * Test that if we change the RGB quantization property to a different 227 * value, we trigger a mode change on the connector's CRTC, which will 228 * in turn disable/enable the connector. 229 */ 230 static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test) 231 { 232 struct drm_atomic_helper_connector_hdmi_priv *priv; 233 struct drm_modeset_acquire_ctx ctx; 234 struct drm_connector_state *old_conn_state; 235 struct drm_connector_state *new_conn_state; 236 struct drm_crtc_state *crtc_state; 237 struct drm_atomic_state *state; 238 struct drm_display_mode *preferred; 239 struct drm_connector *conn; 240 struct drm_device *drm; 241 struct drm_crtc *crtc; 242 int ret; 243 244 priv = drm_kunit_helper_connector_hdmi_init(test, 245 BIT(HDMI_COLORSPACE_RGB), 246 8); 247 KUNIT_ASSERT_NOT_NULL(test, priv); 248 249 drm = &priv->drm; 250 crtc = priv->crtc; 251 conn = &priv->connector; 252 253 preferred = find_preferred_mode(conn); 254 KUNIT_ASSERT_NOT_NULL(test, preferred); 255 256 drm_modeset_acquire_init(&ctx, 0); 257 258 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 259 crtc, conn, 260 preferred, 261 &ctx); 262 KUNIT_ASSERT_EQ(test, ret, 0); 263 264 state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 265 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 266 267 new_conn_state = drm_atomic_get_connector_state(state, conn); 268 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); 269 270 old_conn_state = drm_atomic_get_old_connector_state(state, conn); 271 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state); 272 273 new_conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL; 274 275 KUNIT_ASSERT_NE(test, 276 old_conn_state->hdmi.broadcast_rgb, 277 new_conn_state->hdmi.broadcast_rgb); 278 279 ret = drm_atomic_check_only(state); 280 KUNIT_ASSERT_EQ(test, ret, 0); 281 282 new_conn_state = drm_atomic_get_new_connector_state(state, conn); 283 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); 284 KUNIT_EXPECT_EQ(test, new_conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_FULL); 285 286 crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 287 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); 288 KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed); 289 290 drm_modeset_drop_locks(&ctx); 291 drm_modeset_acquire_fini(&ctx); 292 } 293 294 /* 295 * Test that if we set the RGB quantization property to the same value, 296 * we don't trigger a mode change on the connector's CRTC and leave the 297 * connector unaffected. 298 */ 299 static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *test) 300 { 301 struct drm_atomic_helper_connector_hdmi_priv *priv; 302 struct drm_modeset_acquire_ctx ctx; 303 struct drm_connector_state *old_conn_state; 304 struct drm_connector_state *new_conn_state; 305 struct drm_crtc_state *crtc_state; 306 struct drm_atomic_state *state; 307 struct drm_display_mode *preferred; 308 struct drm_connector *conn; 309 struct drm_device *drm; 310 struct drm_crtc *crtc; 311 int ret; 312 313 priv = drm_kunit_helper_connector_hdmi_init(test, 314 BIT(HDMI_COLORSPACE_RGB), 315 8); 316 KUNIT_ASSERT_NOT_NULL(test, priv); 317 318 drm = &priv->drm; 319 crtc = priv->crtc; 320 conn = &priv->connector; 321 322 preferred = find_preferred_mode(conn); 323 KUNIT_ASSERT_NOT_NULL(test, preferred); 324 325 drm_modeset_acquire_init(&ctx, 0); 326 327 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 328 crtc, conn, 329 preferred, 330 &ctx); 331 KUNIT_ASSERT_EQ(test, ret, 0); 332 333 state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 334 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 335 336 new_conn_state = drm_atomic_get_connector_state(state, conn); 337 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); 338 339 old_conn_state = drm_atomic_get_old_connector_state(state, conn); 340 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state); 341 342 new_conn_state->hdmi.broadcast_rgb = old_conn_state->hdmi.broadcast_rgb; 343 344 ret = drm_atomic_check_only(state); 345 KUNIT_ASSERT_EQ(test, ret, 0); 346 347 old_conn_state = drm_atomic_get_old_connector_state(state, conn); 348 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state); 349 350 new_conn_state = drm_atomic_get_new_connector_state(state, conn); 351 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); 352 353 KUNIT_EXPECT_EQ(test, 354 old_conn_state->hdmi.broadcast_rgb, 355 new_conn_state->hdmi.broadcast_rgb); 356 357 crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 358 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); 359 KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed); 360 361 drm_modeset_drop_locks(&ctx); 362 drm_modeset_acquire_fini(&ctx); 363 } 364 365 /* 366 * Test that for an HDMI connector, with an HDMI monitor, if the 367 * Broadcast RGB property is set to auto with a mode that isn't the 368 * VIC-1 mode, we will get a limited RGB Quantization Range. 369 */ 370 static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test) 371 { 372 struct drm_atomic_helper_connector_hdmi_priv *priv; 373 struct drm_modeset_acquire_ctx ctx; 374 struct drm_connector_state *conn_state; 375 struct drm_atomic_state *state; 376 struct drm_display_mode *preferred; 377 struct drm_connector *conn; 378 struct drm_device *drm; 379 struct drm_crtc *crtc; 380 int ret; 381 382 priv = drm_kunit_helper_connector_hdmi_init(test, 383 BIT(HDMI_COLORSPACE_RGB), 384 8); 385 KUNIT_ASSERT_NOT_NULL(test, priv); 386 387 drm = &priv->drm; 388 crtc = priv->crtc; 389 conn = &priv->connector; 390 KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); 391 392 preferred = find_preferred_mode(conn); 393 KUNIT_ASSERT_NOT_NULL(test, preferred); 394 KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1); 395 396 drm_modeset_acquire_init(&ctx, 0); 397 398 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 399 crtc, conn, 400 preferred, 401 &ctx); 402 KUNIT_ASSERT_EQ(test, ret, 0); 403 404 state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 405 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 406 407 conn_state = drm_atomic_get_connector_state(state, conn); 408 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); 409 410 KUNIT_ASSERT_EQ(test, 411 conn_state->hdmi.broadcast_rgb, 412 DRM_HDMI_BROADCAST_RGB_AUTO); 413 414 ret = drm_atomic_check_only(state); 415 KUNIT_ASSERT_EQ(test, ret, 0); 416 417 conn_state = drm_atomic_get_connector_state(state, conn); 418 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); 419 420 KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range); 421 422 drm_modeset_drop_locks(&ctx); 423 drm_modeset_acquire_fini(&ctx); 424 } 425 426 /* 427 * Test that for an HDMI connector, with an HDMI monitor, if the 428 * Broadcast RGB property is set to auto with a VIC-1 mode, we will get 429 * a full RGB Quantization Range. 430 */ 431 static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test) 432 { 433 struct drm_atomic_helper_connector_hdmi_priv *priv; 434 struct drm_modeset_acquire_ctx ctx; 435 struct drm_connector_state *conn_state; 436 struct drm_atomic_state *state; 437 struct drm_display_mode *mode; 438 struct drm_connector *conn; 439 struct drm_device *drm; 440 struct drm_crtc *crtc; 441 int ret; 442 443 priv = drm_kunit_helper_connector_hdmi_init(test, 444 BIT(HDMI_COLORSPACE_RGB), 445 8); 446 KUNIT_ASSERT_NOT_NULL(test, priv); 447 448 drm = &priv->drm; 449 conn = &priv->connector; 450 KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); 451 452 drm_modeset_acquire_init(&ctx, 0); 453 454 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); 455 KUNIT_ASSERT_NOT_NULL(test, mode); 456 457 crtc = priv->crtc; 458 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 459 crtc, conn, 460 mode, 461 &ctx); 462 KUNIT_ASSERT_EQ(test, ret, 0); 463 464 state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 465 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 466 467 conn_state = drm_atomic_get_connector_state(state, conn); 468 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); 469 470 KUNIT_ASSERT_EQ(test, 471 conn_state->hdmi.broadcast_rgb, 472 DRM_HDMI_BROADCAST_RGB_AUTO); 473 474 ret = drm_atomic_check_only(state); 475 KUNIT_ASSERT_EQ(test, ret, 0); 476 477 conn_state = drm_atomic_get_connector_state(state, conn); 478 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); 479 480 KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range); 481 482 drm_modeset_drop_locks(&ctx); 483 drm_modeset_acquire_fini(&ctx); 484 } 485 486 /* 487 * Test that for an HDMI connector, with an HDMI monitor, if the 488 * Broadcast RGB property is set to full with a mode that isn't the 489 * VIC-1 mode, we will get a full RGB Quantization Range. 490 */ 491 static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test) 492 { 493 struct drm_atomic_helper_connector_hdmi_priv *priv; 494 struct drm_modeset_acquire_ctx ctx; 495 struct drm_connector_state *conn_state; 496 struct drm_atomic_state *state; 497 struct drm_display_mode *preferred; 498 struct drm_connector *conn; 499 struct drm_device *drm; 500 struct drm_crtc *crtc; 501 int ret; 502 503 priv = drm_kunit_helper_connector_hdmi_init(test, 504 BIT(HDMI_COLORSPACE_RGB), 505 8); 506 KUNIT_ASSERT_NOT_NULL(test, priv); 507 508 drm = &priv->drm; 509 crtc = priv->crtc; 510 conn = &priv->connector; 511 KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); 512 513 preferred = find_preferred_mode(conn); 514 KUNIT_ASSERT_NOT_NULL(test, preferred); 515 KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1); 516 517 drm_modeset_acquire_init(&ctx, 0); 518 519 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 520 crtc, conn, 521 preferred, 522 &ctx); 523 KUNIT_ASSERT_EQ(test, ret, 0); 524 525 state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 526 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 527 528 conn_state = drm_atomic_get_connector_state(state, conn); 529 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); 530 531 conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL; 532 533 ret = drm_atomic_check_only(state); 534 KUNIT_ASSERT_EQ(test, ret, 0); 535 536 conn_state = drm_atomic_get_connector_state(state, conn); 537 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); 538 539 KUNIT_ASSERT_EQ(test, 540 conn_state->hdmi.broadcast_rgb, 541 DRM_HDMI_BROADCAST_RGB_FULL); 542 543 KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range); 544 545 drm_modeset_drop_locks(&ctx); 546 drm_modeset_acquire_fini(&ctx); 547 } 548 549 /* 550 * Test that for an HDMI connector, with an HDMI monitor, if the 551 * Broadcast RGB property is set to full with a VIC-1 mode, we will get 552 * a full RGB Quantization Range. 553 */ 554 static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test) 555 { 556 struct drm_atomic_helper_connector_hdmi_priv *priv; 557 struct drm_modeset_acquire_ctx ctx; 558 struct drm_connector_state *conn_state; 559 struct drm_atomic_state *state; 560 struct drm_display_mode *mode; 561 struct drm_connector *conn; 562 struct drm_device *drm; 563 struct drm_crtc *crtc; 564 int ret; 565 566 priv = drm_kunit_helper_connector_hdmi_init(test, 567 BIT(HDMI_COLORSPACE_RGB), 568 8); 569 KUNIT_ASSERT_NOT_NULL(test, priv); 570 571 drm = &priv->drm; 572 conn = &priv->connector; 573 KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); 574 575 drm_modeset_acquire_init(&ctx, 0); 576 577 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); 578 KUNIT_ASSERT_NOT_NULL(test, mode); 579 580 crtc = priv->crtc; 581 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 582 crtc, conn, 583 mode, 584 &ctx); 585 KUNIT_ASSERT_EQ(test, ret, 0); 586 587 state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 588 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 589 590 conn_state = drm_atomic_get_connector_state(state, conn); 591 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); 592 593 conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL; 594 595 ret = drm_atomic_check_only(state); 596 KUNIT_ASSERT_EQ(test, ret, 0); 597 598 conn_state = drm_atomic_get_connector_state(state, conn); 599 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); 600 601 KUNIT_ASSERT_EQ(test, 602 conn_state->hdmi.broadcast_rgb, 603 DRM_HDMI_BROADCAST_RGB_FULL); 604 605 KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range); 606 607 drm_modeset_drop_locks(&ctx); 608 drm_modeset_acquire_fini(&ctx); 609 } 610 611 /* 612 * Test that for an HDMI connector, with an HDMI monitor, if the 613 * Broadcast RGB property is set to limited with a mode that isn't the 614 * VIC-1 mode, we will get a limited RGB Quantization Range. 615 */ 616 static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test) 617 { 618 struct drm_atomic_helper_connector_hdmi_priv *priv; 619 struct drm_modeset_acquire_ctx ctx; 620 struct drm_connector_state *conn_state; 621 struct drm_atomic_state *state; 622 struct drm_display_mode *preferred; 623 struct drm_connector *conn; 624 struct drm_device *drm; 625 struct drm_crtc *crtc; 626 int ret; 627 628 priv = drm_kunit_helper_connector_hdmi_init(test, 629 BIT(HDMI_COLORSPACE_RGB), 630 8); 631 KUNIT_ASSERT_NOT_NULL(test, priv); 632 633 drm = &priv->drm; 634 crtc = priv->crtc; 635 conn = &priv->connector; 636 KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); 637 638 preferred = find_preferred_mode(conn); 639 KUNIT_ASSERT_NOT_NULL(test, preferred); 640 KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1); 641 642 drm_modeset_acquire_init(&ctx, 0); 643 644 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 645 crtc, conn, 646 preferred, 647 &ctx); 648 KUNIT_ASSERT_EQ(test, ret, 0); 649 650 state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 651 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 652 653 conn_state = drm_atomic_get_connector_state(state, conn); 654 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); 655 656 conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED; 657 658 ret = drm_atomic_check_only(state); 659 KUNIT_ASSERT_EQ(test, ret, 0); 660 661 conn_state = drm_atomic_get_connector_state(state, conn); 662 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); 663 664 KUNIT_ASSERT_EQ(test, 665 conn_state->hdmi.broadcast_rgb, 666 DRM_HDMI_BROADCAST_RGB_LIMITED); 667 668 KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range); 669 670 drm_modeset_drop_locks(&ctx); 671 drm_modeset_acquire_fini(&ctx); 672 } 673 674 /* 675 * Test that for an HDMI connector, with an HDMI monitor, if the 676 * Broadcast RGB property is set to limited with a VIC-1 mode, we will 677 * get a limited RGB Quantization Range. 678 */ 679 static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *test) 680 { 681 struct drm_atomic_helper_connector_hdmi_priv *priv; 682 struct drm_modeset_acquire_ctx ctx; 683 struct drm_connector_state *conn_state; 684 struct drm_atomic_state *state; 685 struct drm_display_mode *mode; 686 struct drm_connector *conn; 687 struct drm_device *drm; 688 struct drm_crtc *crtc; 689 int ret; 690 691 priv = drm_kunit_helper_connector_hdmi_init(test, 692 BIT(HDMI_COLORSPACE_RGB), 693 8); 694 KUNIT_ASSERT_NOT_NULL(test, priv); 695 696 drm = &priv->drm; 697 conn = &priv->connector; 698 KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi); 699 700 drm_modeset_acquire_init(&ctx, 0); 701 702 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); 703 KUNIT_ASSERT_NOT_NULL(test, mode); 704 705 crtc = priv->crtc; 706 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 707 crtc, conn, 708 mode, 709 &ctx); 710 KUNIT_ASSERT_EQ(test, ret, 0); 711 712 state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 713 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 714 715 conn_state = drm_atomic_get_connector_state(state, conn); 716 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); 717 718 conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED; 719 720 ret = drm_atomic_check_only(state); 721 KUNIT_ASSERT_EQ(test, ret, 0); 722 723 conn_state = drm_atomic_get_connector_state(state, conn); 724 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); 725 726 KUNIT_ASSERT_EQ(test, 727 conn_state->hdmi.broadcast_rgb, 728 DRM_HDMI_BROADCAST_RGB_LIMITED); 729 730 KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range); 731 732 drm_modeset_drop_locks(&ctx); 733 drm_modeset_acquire_fini(&ctx); 734 } 735 736 /* 737 * Test that if we change the maximum bpc property to a different value, 738 * we trigger a mode change on the connector's CRTC, which will in turn 739 * disable/enable the connector. 740 */ 741 static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test) 742 { 743 struct drm_atomic_helper_connector_hdmi_priv *priv; 744 struct drm_modeset_acquire_ctx ctx; 745 struct drm_connector_state *old_conn_state; 746 struct drm_connector_state *new_conn_state; 747 struct drm_crtc_state *crtc_state; 748 struct drm_atomic_state *state; 749 struct drm_display_mode *preferred; 750 struct drm_connector *conn; 751 struct drm_device *drm; 752 struct drm_crtc *crtc; 753 int ret; 754 755 priv = drm_kunit_helper_connector_hdmi_init(test, 756 BIT(HDMI_COLORSPACE_RGB), 757 10); 758 KUNIT_ASSERT_NOT_NULL(test, priv); 759 760 drm = &priv->drm; 761 crtc = priv->crtc; 762 conn = &priv->connector; 763 ret = set_connector_edid(test, conn, 764 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, 765 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); 766 KUNIT_ASSERT_GT(test, ret, 0); 767 768 preferred = find_preferred_mode(conn); 769 KUNIT_ASSERT_NOT_NULL(test, preferred); 770 771 drm_modeset_acquire_init(&ctx, 0); 772 773 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 774 crtc, conn, 775 preferred, 776 &ctx); 777 KUNIT_ASSERT_EQ(test, ret, 0); 778 779 state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 780 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 781 782 new_conn_state = drm_atomic_get_connector_state(state, conn); 783 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); 784 785 old_conn_state = drm_atomic_get_old_connector_state(state, conn); 786 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state); 787 788 new_conn_state->max_requested_bpc = 8; 789 790 KUNIT_ASSERT_NE(test, 791 old_conn_state->max_requested_bpc, 792 new_conn_state->max_requested_bpc); 793 794 ret = drm_atomic_check_only(state); 795 KUNIT_ASSERT_EQ(test, ret, 0); 796 797 old_conn_state = drm_atomic_get_old_connector_state(state, conn); 798 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state); 799 800 new_conn_state = drm_atomic_get_new_connector_state(state, conn); 801 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); 802 803 KUNIT_ASSERT_NE(test, 804 old_conn_state->hdmi.output_bpc, 805 new_conn_state->hdmi.output_bpc); 806 807 crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 808 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); 809 KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed); 810 811 drm_modeset_drop_locks(&ctx); 812 drm_modeset_acquire_fini(&ctx); 813 } 814 815 /* 816 * Test that if we set the output bpc property to the same value, we 817 * don't trigger a mode change on the connector's CRTC and leave the 818 * connector unaffected. 819 */ 820 static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test) 821 { 822 struct drm_atomic_helper_connector_hdmi_priv *priv; 823 struct drm_modeset_acquire_ctx ctx; 824 struct drm_connector_state *old_conn_state; 825 struct drm_connector_state *new_conn_state; 826 struct drm_crtc_state *crtc_state; 827 struct drm_atomic_state *state; 828 struct drm_display_mode *preferred; 829 struct drm_connector *conn; 830 struct drm_device *drm; 831 struct drm_crtc *crtc; 832 int ret; 833 834 priv = drm_kunit_helper_connector_hdmi_init(test, 835 BIT(HDMI_COLORSPACE_RGB), 836 10); 837 KUNIT_ASSERT_NOT_NULL(test, priv); 838 839 drm = &priv->drm; 840 crtc = priv->crtc; 841 conn = &priv->connector; 842 ret = set_connector_edid(test, conn, 843 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, 844 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); 845 KUNIT_ASSERT_GT(test, ret, 0); 846 847 preferred = find_preferred_mode(conn); 848 KUNIT_ASSERT_NOT_NULL(test, preferred); 849 850 drm_modeset_acquire_init(&ctx, 0); 851 852 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 853 crtc, conn, 854 preferred, 855 &ctx); 856 KUNIT_ASSERT_EQ(test, ret, 0); 857 858 state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 859 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 860 861 new_conn_state = drm_atomic_get_connector_state(state, conn); 862 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); 863 864 old_conn_state = drm_atomic_get_old_connector_state(state, conn); 865 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state); 866 867 KUNIT_ASSERT_EQ(test, 868 new_conn_state->hdmi.output_bpc, 869 old_conn_state->hdmi.output_bpc); 870 871 ret = drm_atomic_check_only(state); 872 KUNIT_ASSERT_EQ(test, ret, 0); 873 874 old_conn_state = drm_atomic_get_old_connector_state(state, conn); 875 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state); 876 877 new_conn_state = drm_atomic_get_new_connector_state(state, conn); 878 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); 879 880 KUNIT_EXPECT_EQ(test, 881 old_conn_state->hdmi.output_bpc, 882 new_conn_state->hdmi.output_bpc); 883 884 crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 885 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); 886 KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed); 887 888 drm_modeset_drop_locks(&ctx); 889 drm_modeset_acquire_fini(&ctx); 890 } 891 892 /* 893 * Test that if we have an HDMI connector but a !HDMI display, we always 894 * output RGB with 8 bpc. 895 */ 896 static void drm_test_check_output_bpc_dvi(struct kunit *test) 897 { 898 struct drm_atomic_helper_connector_hdmi_priv *priv; 899 struct drm_modeset_acquire_ctx ctx; 900 struct drm_connector_state *conn_state; 901 struct drm_display_info *info; 902 struct drm_display_mode *preferred; 903 struct drm_connector *conn; 904 struct drm_device *drm; 905 struct drm_crtc *crtc; 906 int ret; 907 908 priv = drm_kunit_helper_connector_hdmi_init(test, 909 BIT(HDMI_COLORSPACE_RGB) | 910 BIT(HDMI_COLORSPACE_YUV422) | 911 BIT(HDMI_COLORSPACE_YUV444), 912 12); 913 KUNIT_ASSERT_NOT_NULL(test, priv); 914 915 drm = &priv->drm; 916 crtc = priv->crtc; 917 conn = &priv->connector; 918 ret = set_connector_edid(test, conn, 919 test_edid_dvi_1080p, 920 ARRAY_SIZE(test_edid_dvi_1080p)); 921 KUNIT_ASSERT_GT(test, ret, 0); 922 923 info = &conn->display_info; 924 KUNIT_ASSERT_FALSE(test, info->is_hdmi); 925 926 preferred = find_preferred_mode(conn); 927 KUNIT_ASSERT_NOT_NULL(test, preferred); 928 929 drm_modeset_acquire_init(&ctx, 0); 930 931 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 932 crtc, conn, 933 preferred, 934 &ctx); 935 KUNIT_ASSERT_EQ(test, ret, 0); 936 937 conn_state = conn->state; 938 KUNIT_ASSERT_NOT_NULL(test, conn_state); 939 940 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8); 941 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); 942 943 drm_modeset_drop_locks(&ctx); 944 drm_modeset_acquire_fini(&ctx); 945 } 946 947 /* 948 * Test that when doing a commit which would use RGB 8bpc, the TMDS 949 * clock rate stored in the connector state is equal to the mode clock 950 */ 951 static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test) 952 { 953 struct drm_atomic_helper_connector_hdmi_priv *priv; 954 struct drm_modeset_acquire_ctx ctx; 955 struct drm_connector_state *conn_state; 956 struct drm_display_mode *preferred; 957 struct drm_connector *conn; 958 struct drm_device *drm; 959 struct drm_crtc *crtc; 960 int ret; 961 962 priv = drm_kunit_helper_connector_hdmi_init(test, 963 BIT(HDMI_COLORSPACE_RGB), 964 8); 965 KUNIT_ASSERT_NOT_NULL(test, priv); 966 967 drm = &priv->drm; 968 crtc = priv->crtc; 969 conn = &priv->connector; 970 ret = set_connector_edid(test, conn, 971 test_edid_hdmi_1080p_rgb_max_200mhz, 972 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); 973 KUNIT_ASSERT_GT(test, ret, 0); 974 975 preferred = find_preferred_mode(conn); 976 KUNIT_ASSERT_NOT_NULL(test, preferred); 977 KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); 978 979 drm_modeset_acquire_init(&ctx, 0); 980 981 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 982 crtc, conn, 983 preferred, 984 &ctx); 985 KUNIT_ASSERT_EQ(test, ret, 0); 986 987 conn_state = conn->state; 988 KUNIT_ASSERT_NOT_NULL(test, conn_state); 989 990 KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 8); 991 KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); 992 KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1000); 993 994 drm_modeset_drop_locks(&ctx); 995 drm_modeset_acquire_fini(&ctx); 996 } 997 998 /* 999 * Test that when doing a commit which would use RGB 10bpc, the TMDS 1000 * clock rate stored in the connector state is equal to 1.25 times the 1001 * mode pixel clock 1002 */ 1003 static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test) 1004 { 1005 struct drm_atomic_helper_connector_hdmi_priv *priv; 1006 struct drm_modeset_acquire_ctx ctx; 1007 struct drm_connector_state *conn_state; 1008 struct drm_display_mode *preferred; 1009 struct drm_connector *conn; 1010 struct drm_device *drm; 1011 struct drm_crtc *crtc; 1012 int ret; 1013 1014 priv = drm_kunit_helper_connector_hdmi_init(test, 1015 BIT(HDMI_COLORSPACE_RGB), 1016 10); 1017 KUNIT_ASSERT_NOT_NULL(test, priv); 1018 1019 drm = &priv->drm; 1020 crtc = priv->crtc; 1021 conn = &priv->connector; 1022 ret = set_connector_edid(test, conn, 1023 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz, 1024 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz)); 1025 KUNIT_ASSERT_GT(test, ret, 0); 1026 1027 preferred = find_preferred_mode(conn); 1028 KUNIT_ASSERT_NOT_NULL(test, preferred); 1029 KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); 1030 1031 drm_modeset_acquire_init(&ctx, 0); 1032 1033 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 1034 crtc, conn, 1035 preferred, 1036 &ctx); 1037 KUNIT_ASSERT_EQ(test, ret, 0); 1038 1039 conn_state = conn->state; 1040 KUNIT_ASSERT_NOT_NULL(test, conn_state); 1041 1042 KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 10); 1043 KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); 1044 KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250); 1045 1046 drm_modeset_drop_locks(&ctx); 1047 drm_modeset_acquire_fini(&ctx); 1048 } 1049 1050 /* 1051 * Test that when doing a commit which would use RGB 12bpc, the TMDS 1052 * clock rate stored in the connector state is equal to 1.5 times the 1053 * mode pixel clock 1054 */ 1055 static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test) 1056 { 1057 struct drm_atomic_helper_connector_hdmi_priv *priv; 1058 struct drm_modeset_acquire_ctx ctx; 1059 struct drm_connector_state *conn_state; 1060 struct drm_display_mode *preferred; 1061 struct drm_connector *conn; 1062 struct drm_device *drm; 1063 struct drm_crtc *crtc; 1064 int ret; 1065 1066 priv = drm_kunit_helper_connector_hdmi_init(test, 1067 BIT(HDMI_COLORSPACE_RGB), 1068 12); 1069 KUNIT_ASSERT_NOT_NULL(test, priv); 1070 1071 drm = &priv->drm; 1072 crtc = priv->crtc; 1073 conn = &priv->connector; 1074 ret = set_connector_edid(test, conn, 1075 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz, 1076 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz)); 1077 KUNIT_ASSERT_GT(test, ret, 0); 1078 1079 preferred = find_preferred_mode(conn); 1080 KUNIT_ASSERT_NOT_NULL(test, preferred); 1081 KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); 1082 1083 drm_modeset_acquire_init(&ctx, 0); 1084 1085 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 1086 crtc, conn, 1087 preferred, 1088 &ctx); 1089 KUNIT_ASSERT_EQ(test, ret, 0); 1090 1091 conn_state = conn->state; 1092 KUNIT_ASSERT_NOT_NULL(test, conn_state); 1093 1094 KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 12); 1095 KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); 1096 KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1500); 1097 1098 drm_modeset_drop_locks(&ctx); 1099 drm_modeset_acquire_fini(&ctx); 1100 } 1101 1102 /* 1103 * Test that if we filter a rate through our hook, it's indeed rejected 1104 * by the whole atomic_check logic. 1105 * 1106 * We do so by first doing a commit on the pipeline to make sure that it 1107 * works, change the HDMI helpers pointer, and then try the same commit 1108 * again to see if it fails as it should. 1109 */ 1110 static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test) 1111 { 1112 struct drm_atomic_helper_connector_hdmi_priv *priv; 1113 struct drm_modeset_acquire_ctx ctx; 1114 struct drm_atomic_state *state; 1115 struct drm_display_mode *preferred; 1116 struct drm_crtc_state *crtc_state; 1117 struct drm_connector *conn; 1118 struct drm_device *drm; 1119 struct drm_crtc *crtc; 1120 int ret; 1121 1122 priv = drm_kunit_helper_connector_hdmi_init(test, 1123 BIT(HDMI_COLORSPACE_RGB), 1124 8); 1125 KUNIT_ASSERT_NOT_NULL(test, priv); 1126 1127 drm = &priv->drm; 1128 crtc = priv->crtc; 1129 conn = &priv->connector; 1130 1131 preferred = find_preferred_mode(conn); 1132 KUNIT_ASSERT_NOT_NULL(test, preferred); 1133 1134 drm_modeset_acquire_init(&ctx, 0); 1135 1136 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 1137 crtc, conn, 1138 preferred, 1139 &ctx); 1140 KUNIT_ASSERT_EQ(test, ret, 0); 1141 1142 /* You shouldn't be doing that at home. */ 1143 conn->hdmi.funcs = &reject_connector_hdmi_funcs; 1144 1145 state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 1146 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 1147 1148 crtc_state = drm_atomic_get_crtc_state(state, crtc); 1149 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); 1150 1151 crtc_state->connectors_changed = true; 1152 1153 ret = drm_atomic_check_only(state); 1154 KUNIT_EXPECT_LT(test, ret, 0); 1155 1156 drm_modeset_drop_locks(&ctx); 1157 drm_modeset_acquire_fini(&ctx); 1158 } 1159 1160 /* 1161 * Test that if: 1162 * - We have an HDMI connector supporting RGB only 1163 * - The chosen mode has a TMDS character rate higher than the display 1164 * supports in RGB/12bpc 1165 * - The chosen mode has a TMDS character rate lower than the display 1166 * supports in RGB/10bpc. 1167 * 1168 * Then we will pick the latter, and the computed TMDS character rate 1169 * will be equal to 1.25 times the mode pixel clock. 1170 */ 1171 static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test) 1172 { 1173 struct drm_atomic_helper_connector_hdmi_priv *priv; 1174 struct drm_modeset_acquire_ctx ctx; 1175 struct drm_connector_state *conn_state; 1176 struct drm_display_info *info; 1177 struct drm_display_mode *preferred; 1178 unsigned long long rate; 1179 struct drm_connector *conn; 1180 struct drm_device *drm; 1181 struct drm_crtc *crtc; 1182 int ret; 1183 1184 priv = drm_kunit_helper_connector_hdmi_init(test, 1185 BIT(HDMI_COLORSPACE_RGB), 1186 12); 1187 KUNIT_ASSERT_NOT_NULL(test, priv); 1188 1189 drm = &priv->drm; 1190 crtc = priv->crtc; 1191 conn = &priv->connector; 1192 ret = set_connector_edid(test, conn, 1193 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, 1194 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); 1195 KUNIT_ASSERT_GT(test, ret, 0); 1196 1197 info = &conn->display_info; 1198 KUNIT_ASSERT_TRUE(test, info->is_hdmi); 1199 KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); 1200 1201 preferred = find_preferred_mode(conn); 1202 KUNIT_ASSERT_NOT_NULL(test, preferred); 1203 KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); 1204 1205 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB); 1206 KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000); 1207 1208 rate = drm_hdmi_compute_mode_clock(preferred, 10, HDMI_COLORSPACE_RGB); 1209 KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); 1210 1211 drm_modeset_acquire_init(&ctx, 0); 1212 1213 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 1214 crtc, conn, 1215 preferred, 1216 &ctx); 1217 KUNIT_EXPECT_EQ(test, ret, 0); 1218 1219 conn_state = conn->state; 1220 KUNIT_ASSERT_NOT_NULL(test, conn_state); 1221 1222 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10); 1223 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); 1224 KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250); 1225 1226 drm_modeset_drop_locks(&ctx); 1227 drm_modeset_acquire_fini(&ctx); 1228 } 1229 1230 /* 1231 * Test that if: 1232 * - We have an HDMI connector supporting both RGB and YUV422 and up to 1233 * 12 bpc 1234 * - The chosen mode has a TMDS character rate higher than the display 1235 * supports in RGB/12bpc but lower than the display supports in 1236 * RGB/10bpc 1237 * - The chosen mode has a TMDS character rate lower than the display 1238 * supports in YUV422/12bpc. 1239 * 1240 * Then we will prefer to keep the RGB format with a lower bpc over 1241 * picking YUV422. 1242 */ 1243 static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test) 1244 { 1245 struct drm_atomic_helper_connector_hdmi_priv *priv; 1246 struct drm_modeset_acquire_ctx ctx; 1247 struct drm_connector_state *conn_state; 1248 struct drm_display_info *info; 1249 struct drm_display_mode *preferred; 1250 unsigned long long rate; 1251 struct drm_connector *conn; 1252 struct drm_device *drm; 1253 struct drm_crtc *crtc; 1254 int ret; 1255 1256 priv = drm_kunit_helper_connector_hdmi_init(test, 1257 BIT(HDMI_COLORSPACE_RGB) | 1258 BIT(HDMI_COLORSPACE_YUV422) | 1259 BIT(HDMI_COLORSPACE_YUV444), 1260 12); 1261 KUNIT_ASSERT_NOT_NULL(test, priv); 1262 1263 drm = &priv->drm; 1264 crtc = priv->crtc; 1265 conn = &priv->connector; 1266 ret = set_connector_edid(test, conn, 1267 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, 1268 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); 1269 KUNIT_ASSERT_GT(test, ret, 0); 1270 1271 info = &conn->display_info; 1272 KUNIT_ASSERT_TRUE(test, info->is_hdmi); 1273 KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); 1274 1275 preferred = find_preferred_mode(conn); 1276 KUNIT_ASSERT_NOT_NULL(test, preferred); 1277 KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK); 1278 1279 rate = drm_hdmi_compute_mode_clock(preferred, 10, HDMI_COLORSPACE_RGB); 1280 KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); 1281 1282 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB); 1283 KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000); 1284 1285 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422); 1286 KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); 1287 1288 drm_modeset_acquire_init(&ctx, 0); 1289 1290 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 1291 crtc, conn, 1292 preferred, 1293 &ctx); 1294 KUNIT_EXPECT_EQ(test, ret, 0); 1295 1296 conn_state = conn->state; 1297 KUNIT_ASSERT_NOT_NULL(test, conn_state); 1298 1299 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10); 1300 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); 1301 1302 drm_modeset_drop_locks(&ctx); 1303 drm_modeset_acquire_fini(&ctx); 1304 } 1305 1306 /* 1307 * Test that if a driver and screen supports RGB and YUV formats, and we 1308 * try to set the VIC 1 mode, we end up with 8bpc RGB even if we could 1309 * have had a higher bpc. 1310 */ 1311 static void drm_test_check_output_bpc_format_vic_1(struct kunit *test) 1312 { 1313 struct drm_atomic_helper_connector_hdmi_priv *priv; 1314 struct drm_modeset_acquire_ctx ctx; 1315 struct drm_connector_state *conn_state; 1316 struct drm_display_info *info; 1317 struct drm_display_mode *mode; 1318 unsigned long long rate; 1319 struct drm_connector *conn; 1320 struct drm_device *drm; 1321 struct drm_crtc *crtc; 1322 int ret; 1323 1324 priv = drm_kunit_helper_connector_hdmi_init(test, 1325 BIT(HDMI_COLORSPACE_RGB) | 1326 BIT(HDMI_COLORSPACE_YUV422) | 1327 BIT(HDMI_COLORSPACE_YUV444), 1328 12); 1329 KUNIT_ASSERT_NOT_NULL(test, priv); 1330 1331 drm = &priv->drm; 1332 conn = &priv->connector; 1333 ret = set_connector_edid(test, conn, 1334 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, 1335 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); 1336 KUNIT_ASSERT_GT(test, ret, 0); 1337 1338 info = &conn->display_info; 1339 KUNIT_ASSERT_TRUE(test, info->is_hdmi); 1340 KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); 1341 1342 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); 1343 KUNIT_ASSERT_NOT_NULL(test, mode); 1344 1345 /* 1346 * NOTE: We can't use drm_hdmi_compute_mode_clock() 1347 * here because we're trying to get the rate of an invalid 1348 * configuration. 1349 * 1350 * Thus, we have to calculate the rate by hand. 1351 */ 1352 rate = mode->clock * 1500; 1353 KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); 1354 1355 drm_modeset_acquire_init(&ctx, 0); 1356 1357 crtc = priv->crtc; 1358 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 1359 crtc, conn, 1360 mode, 1361 &ctx); 1362 KUNIT_EXPECT_EQ(test, ret, 0); 1363 1364 conn_state = conn->state; 1365 KUNIT_ASSERT_NOT_NULL(test, conn_state); 1366 1367 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8); 1368 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); 1369 1370 drm_modeset_drop_locks(&ctx); 1371 drm_modeset_acquire_fini(&ctx); 1372 } 1373 1374 /* 1375 * Test that if a driver supports only RGB but the screen also supports 1376 * YUV formats, we only end up with an RGB format. 1377 */ 1378 static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test) 1379 { 1380 struct drm_atomic_helper_connector_hdmi_priv *priv; 1381 struct drm_modeset_acquire_ctx ctx; 1382 struct drm_connector_state *conn_state; 1383 struct drm_display_info *info; 1384 struct drm_display_mode *preferred; 1385 unsigned long long rate; 1386 struct drm_connector *conn; 1387 struct drm_device *drm; 1388 struct drm_crtc *crtc; 1389 int ret; 1390 1391 priv = drm_kunit_helper_connector_hdmi_init(test, 1392 BIT(HDMI_COLORSPACE_RGB), 1393 12); 1394 KUNIT_ASSERT_NOT_NULL(test, priv); 1395 1396 drm = &priv->drm; 1397 crtc = priv->crtc; 1398 conn = &priv->connector; 1399 ret = set_connector_edid(test, conn, 1400 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz, 1401 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz)); 1402 KUNIT_ASSERT_GT(test, ret, 0); 1403 1404 info = &conn->display_info; 1405 KUNIT_ASSERT_TRUE(test, info->is_hdmi); 1406 KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); 1407 1408 preferred = find_preferred_mode(conn); 1409 KUNIT_ASSERT_NOT_NULL(test, preferred); 1410 1411 /* 1412 * We're making sure that YUV422 would be the preferred option 1413 * here: we're always favouring higher bpc, we can't have RGB 1414 * because the TMDS character rate exceeds the maximum supported 1415 * by the display, and YUV422 works for that display. 1416 * 1417 * But since the driver only supports RGB, we should fallback to 1418 * a lower bpc with RGB. 1419 */ 1420 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB); 1421 KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000); 1422 1423 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422); 1424 KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); 1425 1426 drm_modeset_acquire_init(&ctx, 0); 1427 1428 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 1429 crtc, conn, 1430 preferred, 1431 &ctx); 1432 KUNIT_EXPECT_EQ(test, ret, 0); 1433 1434 conn_state = conn->state; 1435 KUNIT_ASSERT_NOT_NULL(test, conn_state); 1436 1437 KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12); 1438 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); 1439 1440 drm_modeset_drop_locks(&ctx); 1441 drm_modeset_acquire_fini(&ctx); 1442 } 1443 1444 /* 1445 * Test that if a screen supports only RGB but the driver also supports 1446 * YUV formats, we only end up with an RGB format. 1447 */ 1448 static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test) 1449 { 1450 struct drm_atomic_helper_connector_hdmi_priv *priv; 1451 struct drm_modeset_acquire_ctx ctx; 1452 struct drm_connector_state *conn_state; 1453 struct drm_display_info *info; 1454 struct drm_display_mode *preferred; 1455 unsigned long long rate; 1456 struct drm_connector *conn; 1457 struct drm_device *drm; 1458 struct drm_crtc *crtc; 1459 int ret; 1460 1461 priv = drm_kunit_helper_connector_hdmi_init(test, 1462 BIT(HDMI_COLORSPACE_RGB) | 1463 BIT(HDMI_COLORSPACE_YUV422) | 1464 BIT(HDMI_COLORSPACE_YUV444), 1465 12); 1466 KUNIT_ASSERT_NOT_NULL(test, priv); 1467 1468 drm = &priv->drm; 1469 crtc = priv->crtc; 1470 conn = &priv->connector; 1471 ret = set_connector_edid(test, conn, 1472 test_edid_hdmi_1080p_rgb_max_200mhz, 1473 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); 1474 KUNIT_ASSERT_GT(test, ret, 0); 1475 1476 info = &conn->display_info; 1477 KUNIT_ASSERT_TRUE(test, info->is_hdmi); 1478 KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); 1479 1480 preferred = find_preferred_mode(conn); 1481 KUNIT_ASSERT_NOT_NULL(test, preferred); 1482 1483 /* 1484 * We're making sure that YUV422 would be the preferred option 1485 * here: we're always favouring higher bpc, we can't have RGB 1486 * because the TMDS character rate exceeds the maximum supported 1487 * by the display, and YUV422 works for that display. 1488 * 1489 * But since the display only supports RGB, we should fallback to 1490 * a lower bpc with RGB. 1491 */ 1492 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB); 1493 KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000); 1494 1495 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422); 1496 KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); 1497 1498 drm_modeset_acquire_init(&ctx, 0); 1499 1500 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 1501 crtc, conn, 1502 preferred, 1503 &ctx); 1504 KUNIT_EXPECT_EQ(test, ret, 0); 1505 1506 conn_state = conn->state; 1507 KUNIT_ASSERT_NOT_NULL(test, conn_state); 1508 1509 KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12); 1510 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); 1511 1512 drm_modeset_drop_locks(&ctx); 1513 drm_modeset_acquire_fini(&ctx); 1514 } 1515 1516 /* 1517 * Test that if a display supports higher bpc but the driver only 1518 * supports 8 bpc, we only end up with 8 bpc even if we could have had a 1519 * higher bpc. 1520 */ 1521 static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test) 1522 { 1523 struct drm_atomic_helper_connector_hdmi_priv *priv; 1524 struct drm_modeset_acquire_ctx ctx; 1525 struct drm_connector_state *conn_state; 1526 struct drm_display_info *info; 1527 struct drm_display_mode *preferred; 1528 unsigned long long rate; 1529 struct drm_connector *conn; 1530 struct drm_device *drm; 1531 struct drm_crtc *crtc; 1532 int ret; 1533 1534 priv = drm_kunit_helper_connector_hdmi_init(test, 1535 BIT(HDMI_COLORSPACE_RGB), 1536 8); 1537 KUNIT_ASSERT_NOT_NULL(test, priv); 1538 1539 drm = &priv->drm; 1540 crtc = priv->crtc; 1541 conn = &priv->connector; 1542 ret = set_connector_edid(test, conn, 1543 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz, 1544 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz)); 1545 KUNIT_ASSERT_GT(test, ret, 0); 1546 1547 info = &conn->display_info; 1548 KUNIT_ASSERT_TRUE(test, info->is_hdmi); 1549 KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); 1550 1551 preferred = find_preferred_mode(conn); 1552 KUNIT_ASSERT_NOT_NULL(test, preferred); 1553 1554 /* 1555 * We're making sure that we have headroom on the TMDS character 1556 * clock to actually use 12bpc. 1557 */ 1558 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB); 1559 KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); 1560 1561 drm_modeset_acquire_init(&ctx, 0); 1562 1563 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 1564 crtc, conn, 1565 preferred, 1566 &ctx); 1567 KUNIT_EXPECT_EQ(test, ret, 0); 1568 1569 conn_state = conn->state; 1570 KUNIT_ASSERT_NOT_NULL(test, conn_state); 1571 1572 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8); 1573 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); 1574 1575 drm_modeset_drop_locks(&ctx); 1576 drm_modeset_acquire_fini(&ctx); 1577 } 1578 1579 /* 1580 * Test that if a driver supports higher bpc but the display only 1581 * supports 8 bpc, we only end up with 8 bpc even if we could have had a 1582 * higher bpc. 1583 */ 1584 static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *test) 1585 { 1586 struct drm_atomic_helper_connector_hdmi_priv *priv; 1587 struct drm_modeset_acquire_ctx ctx; 1588 struct drm_connector_state *conn_state; 1589 struct drm_display_info *info; 1590 struct drm_display_mode *preferred; 1591 unsigned long long rate; 1592 struct drm_connector *conn; 1593 struct drm_device *drm; 1594 struct drm_crtc *crtc; 1595 int ret; 1596 1597 priv = drm_kunit_helper_connector_hdmi_init(test, 1598 BIT(HDMI_COLORSPACE_RGB) | 1599 BIT(HDMI_COLORSPACE_YUV422) | 1600 BIT(HDMI_COLORSPACE_YUV444), 1601 12); 1602 KUNIT_ASSERT_NOT_NULL(test, priv); 1603 1604 drm = &priv->drm; 1605 crtc = priv->crtc; 1606 conn = &priv->connector; 1607 ret = set_connector_edid(test, conn, 1608 test_edid_hdmi_1080p_rgb_max_340mhz, 1609 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_340mhz)); 1610 KUNIT_ASSERT_GT(test, ret, 0); 1611 1612 info = &conn->display_info; 1613 KUNIT_ASSERT_TRUE(test, info->is_hdmi); 1614 KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0); 1615 1616 preferred = find_preferred_mode(conn); 1617 KUNIT_ASSERT_NOT_NULL(test, preferred); 1618 1619 /* 1620 * We're making sure that we have headroom on the TMDS character 1621 * clock to actually use 12bpc. 1622 */ 1623 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB); 1624 KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000); 1625 1626 drm_modeset_acquire_init(&ctx, 0); 1627 1628 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 1629 crtc, conn, 1630 preferred, 1631 &ctx); 1632 KUNIT_EXPECT_EQ(test, ret, 0); 1633 1634 conn_state = conn->state; 1635 KUNIT_ASSERT_NOT_NULL(test, conn_state); 1636 1637 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8); 1638 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB); 1639 1640 drm_modeset_drop_locks(&ctx); 1641 drm_modeset_acquire_fini(&ctx); 1642 } 1643 1644 /* Test that atomic check succeeds when disabling a connector. */ 1645 static void drm_test_check_disable_connector(struct kunit *test) 1646 { 1647 struct drm_atomic_helper_connector_hdmi_priv *priv; 1648 struct drm_modeset_acquire_ctx ctx; 1649 struct drm_connector_state *conn_state; 1650 struct drm_crtc_state *crtc_state; 1651 struct drm_atomic_state *state; 1652 struct drm_display_mode *preferred; 1653 struct drm_connector *conn; 1654 struct drm_device *drm; 1655 struct drm_crtc *crtc; 1656 int ret; 1657 1658 priv = drm_kunit_helper_connector_hdmi_init(test, 1659 BIT(HDMI_COLORSPACE_RGB), 1660 8); 1661 KUNIT_ASSERT_NOT_NULL(test, priv); 1662 1663 drm_modeset_acquire_init(&ctx, 0); 1664 1665 conn = &priv->connector; 1666 preferred = find_preferred_mode(conn); 1667 KUNIT_ASSERT_NOT_NULL(test, preferred); 1668 1669 drm = &priv->drm; 1670 crtc = priv->crtc; 1671 ret = drm_kunit_helper_enable_crtc_connector(test, drm, 1672 crtc, conn, 1673 preferred, 1674 &ctx); 1675 KUNIT_ASSERT_EQ(test, ret, 0); 1676 1677 state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); 1678 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 1679 1680 crtc_state = drm_atomic_get_crtc_state(state, crtc); 1681 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state); 1682 1683 crtc_state->active = false; 1684 ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL); 1685 KUNIT_EXPECT_EQ(test, ret, 0); 1686 1687 conn_state = drm_atomic_get_connector_state(state, conn); 1688 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state); 1689 1690 ret = drm_atomic_set_crtc_for_connector(conn_state, NULL); 1691 KUNIT_EXPECT_EQ(test, ret, 0); 1692 1693 ret = drm_atomic_check_only(state); 1694 KUNIT_ASSERT_EQ(test, ret, 0); 1695 1696 drm_modeset_drop_locks(&ctx); 1697 drm_modeset_acquire_fini(&ctx); 1698 } 1699 1700 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = { 1701 KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode), 1702 KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1), 1703 KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode), 1704 KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode_vic_1), 1705 KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode), 1706 KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode_vic_1), 1707 /* 1708 * TODO: When we'll have YUV output support, we need to check 1709 * that the limited range is always set to limited no matter 1710 * what the value of Broadcast RGB is. 1711 */ 1712 KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed), 1713 KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed), 1714 KUNIT_CASE(drm_test_check_disable_connector), 1715 KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate), 1716 KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback), 1717 KUNIT_CASE(drm_test_check_max_tmds_rate_format_fallback), 1718 KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed), 1719 KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed), 1720 KUNIT_CASE(drm_test_check_output_bpc_dvi), 1721 KUNIT_CASE(drm_test_check_output_bpc_format_vic_1), 1722 KUNIT_CASE(drm_test_check_output_bpc_format_display_8bpc_only), 1723 KUNIT_CASE(drm_test_check_output_bpc_format_display_rgb_only), 1724 KUNIT_CASE(drm_test_check_output_bpc_format_driver_8bpc_only), 1725 KUNIT_CASE(drm_test_check_output_bpc_format_driver_rgb_only), 1726 KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc), 1727 KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_10bpc), 1728 KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_12bpc), 1729 /* 1730 * TODO: We should have tests to check that a change in the 1731 * format triggers a CRTC mode change just like we do for the 1732 * RGB Quantization and BPC. 1733 * 1734 * However, we don't have any way to control which format gets 1735 * picked up aside from changing the BPC or mode which would 1736 * already trigger a mode change. 1737 */ 1738 { } 1739 }; 1740 1741 static struct kunit_suite drm_atomic_helper_connector_hdmi_check_test_suite = { 1742 .name = "drm_atomic_helper_connector_hdmi_check", 1743 .test_cases = drm_atomic_helper_connector_hdmi_check_tests, 1744 }; 1745 1746 /* 1747 * Test that the value of the Broadcast RGB property out of reset is set 1748 * to auto. 1749 */ 1750 static void drm_test_check_broadcast_rgb_value(struct kunit *test) 1751 { 1752 struct drm_atomic_helper_connector_hdmi_priv *priv; 1753 struct drm_connector_state *conn_state; 1754 struct drm_connector *conn; 1755 1756 priv = drm_kunit_helper_connector_hdmi_init(test, 1757 BIT(HDMI_COLORSPACE_RGB), 1758 8); 1759 KUNIT_ASSERT_NOT_NULL(test, priv); 1760 1761 conn = &priv->connector; 1762 conn_state = conn->state; 1763 KUNIT_EXPECT_EQ(test, conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_AUTO); 1764 } 1765 1766 /* 1767 * Test that if the connector was initialised with a maximum bpc of 8, 1768 * the value of the max_bpc and max_requested_bpc properties out of 1769 * reset are also set to 8, and output_bpc is set to 0 and will be 1770 * filled at atomic_check time. 1771 */ 1772 static void drm_test_check_bpc_8_value(struct kunit *test) 1773 { 1774 struct drm_atomic_helper_connector_hdmi_priv *priv; 1775 struct drm_connector_state *conn_state; 1776 struct drm_connector *conn; 1777 1778 priv = drm_kunit_helper_connector_hdmi_init(test, 1779 BIT(HDMI_COLORSPACE_RGB), 1780 8); 1781 KUNIT_ASSERT_NOT_NULL(test, priv); 1782 1783 conn = &priv->connector; 1784 conn_state = conn->state; 1785 KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 8); 1786 KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 8); 1787 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0); 1788 } 1789 1790 /* 1791 * Test that if the connector was initialised with a maximum bpc of 10, 1792 * the value of the max_bpc and max_requested_bpc properties out of 1793 * reset are also set to 10, and output_bpc is set to 0 and will be 1794 * filled at atomic_check time. 1795 */ 1796 static void drm_test_check_bpc_10_value(struct kunit *test) 1797 { 1798 struct drm_atomic_helper_connector_hdmi_priv *priv; 1799 struct drm_connector_state *conn_state; 1800 struct drm_connector *conn; 1801 1802 priv = drm_kunit_helper_connector_hdmi_init(test, 1803 BIT(HDMI_COLORSPACE_RGB), 1804 10); 1805 KUNIT_ASSERT_NOT_NULL(test, priv); 1806 1807 conn = &priv->connector; 1808 conn_state = conn->state; 1809 KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 10); 1810 KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 10); 1811 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0); 1812 } 1813 1814 /* 1815 * Test that if the connector was initialised with a maximum bpc of 12, 1816 * the value of the max_bpc and max_requested_bpc properties out of 1817 * reset are also set to 12, and output_bpc is set to 0 and will be 1818 * filled at atomic_check time. 1819 */ 1820 static void drm_test_check_bpc_12_value(struct kunit *test) 1821 { 1822 struct drm_atomic_helper_connector_hdmi_priv *priv; 1823 struct drm_connector_state *conn_state; 1824 struct drm_connector *conn; 1825 1826 priv = drm_kunit_helper_connector_hdmi_init(test, 1827 BIT(HDMI_COLORSPACE_RGB), 1828 12); 1829 KUNIT_ASSERT_NOT_NULL(test, priv); 1830 1831 conn = &priv->connector; 1832 conn_state = conn->state; 1833 KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 12); 1834 KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 12); 1835 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0); 1836 } 1837 1838 /* 1839 * Test that the value of the output format property out of reset is set 1840 * to RGB, even if the driver supports more than that. 1841 */ 1842 static void drm_test_check_format_value(struct kunit *test) 1843 { 1844 struct drm_atomic_helper_connector_hdmi_priv *priv; 1845 struct drm_connector_state *conn_state; 1846 struct drm_connector *conn; 1847 1848 priv = drm_kunit_helper_connector_hdmi_init(test, 1849 BIT(HDMI_COLORSPACE_RGB) | 1850 BIT(HDMI_COLORSPACE_YUV422) | 1851 BIT(HDMI_COLORSPACE_YUV444), 1852 8); 1853 KUNIT_ASSERT_NOT_NULL(test, priv); 1854 1855 conn = &priv->connector; 1856 conn_state = conn->state; 1857 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, 0); 1858 } 1859 1860 /* 1861 * Test that the value of the output format property out of reset is set 1862 * to 0, and will be computed at atomic_check time. 1863 */ 1864 static void drm_test_check_tmds_char_value(struct kunit *test) 1865 { 1866 struct drm_atomic_helper_connector_hdmi_priv *priv; 1867 struct drm_connector_state *conn_state; 1868 struct drm_connector *conn; 1869 1870 priv = drm_kunit_helper_connector_hdmi_init(test, 1871 BIT(HDMI_COLORSPACE_RGB) | 1872 BIT(HDMI_COLORSPACE_YUV422) | 1873 BIT(HDMI_COLORSPACE_YUV444), 1874 12); 1875 KUNIT_ASSERT_NOT_NULL(test, priv); 1876 1877 conn = &priv->connector; 1878 conn_state = conn->state; 1879 KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, 0); 1880 } 1881 1882 static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = { 1883 KUNIT_CASE(drm_test_check_broadcast_rgb_value), 1884 KUNIT_CASE(drm_test_check_bpc_8_value), 1885 KUNIT_CASE(drm_test_check_bpc_10_value), 1886 KUNIT_CASE(drm_test_check_bpc_12_value), 1887 KUNIT_CASE(drm_test_check_format_value), 1888 KUNIT_CASE(drm_test_check_tmds_char_value), 1889 { } 1890 }; 1891 1892 static struct kunit_suite drm_atomic_helper_connector_hdmi_reset_test_suite = { 1893 .name = "drm_atomic_helper_connector_hdmi_reset", 1894 .test_cases = drm_atomic_helper_connector_hdmi_reset_tests, 1895 }; 1896 1897 /* 1898 * Test that the default behaviour for drm_hdmi_connector_mode_valid() is not 1899 * to reject any modes. Pass a correct EDID and verify that preferred mode 1900 * matches the expectations (1080p). 1901 */ 1902 static void drm_test_check_mode_valid(struct kunit *test) 1903 { 1904 struct drm_atomic_helper_connector_hdmi_priv *priv; 1905 struct drm_connector *conn; 1906 struct drm_display_mode *preferred; 1907 1908 priv = drm_kunit_helper_connector_hdmi_init(test, 1909 BIT(HDMI_COLORSPACE_RGB), 1910 8); 1911 KUNIT_ASSERT_NOT_NULL(test, priv); 1912 1913 conn = &priv->connector; 1914 preferred = find_preferred_mode(conn); 1915 KUNIT_ASSERT_NOT_NULL(test, preferred); 1916 1917 KUNIT_EXPECT_EQ(test, preferred->hdisplay, 1920); 1918 KUNIT_EXPECT_EQ(test, preferred->vdisplay, 1080); 1919 KUNIT_EXPECT_EQ(test, preferred->clock, 148500); 1920 } 1921 1922 /* 1923 * Test that the drm_hdmi_connector_mode_valid() will reject modes depending on 1924 * the .tmds_char_rate_valid() behaviour. 1925 * Pass a correct EDID and verify that high-rate modes are filtered. 1926 */ 1927 static void drm_test_check_mode_valid_reject_rate(struct kunit *test) 1928 { 1929 struct drm_atomic_helper_connector_hdmi_priv *priv; 1930 struct drm_connector *conn; 1931 struct drm_display_mode *preferred; 1932 int ret; 1933 1934 priv = drm_kunit_helper_connector_hdmi_init_funcs(test, 1935 BIT(HDMI_COLORSPACE_RGB), 1936 8, 1937 &reject_100_MHz_connector_hdmi_funcs); 1938 KUNIT_ASSERT_NOT_NULL(test, priv); 1939 1940 conn = &priv->connector; 1941 1942 ret = set_connector_edid(test, conn, 1943 test_edid_hdmi_1080p_rgb_max_200mhz, 1944 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); 1945 KUNIT_ASSERT_GT(test, ret, 0); 1946 1947 /* 1948 * Unlike the drm_test_check_mode_valid() here 1080p is rejected, but 1949 * 480p is allowed. 1950 */ 1951 preferred = find_preferred_mode(conn); 1952 KUNIT_ASSERT_NOT_NULL(test, preferred); 1953 KUNIT_EXPECT_EQ(test, preferred->hdisplay, 640); 1954 KUNIT_EXPECT_EQ(test, preferred->vdisplay, 480); 1955 KUNIT_EXPECT_EQ(test, preferred->clock, 25200); 1956 } 1957 1958 /* 1959 * Test that the drm_hdmi_connector_mode_valid() will not mark any modes as 1960 * valid if .tmds_char_rate_valid() rejects all of them. Pass a correct EDID 1961 * and verify that there is no preferred mode and no modes were set for the 1962 * connector. 1963 */ 1964 static void drm_test_check_mode_valid_reject(struct kunit *test) 1965 { 1966 struct drm_atomic_helper_connector_hdmi_priv *priv; 1967 struct drm_connector *conn; 1968 struct drm_display_mode *preferred; 1969 int ret; 1970 1971 priv = drm_kunit_helper_connector_hdmi_init_funcs(test, 1972 BIT(HDMI_COLORSPACE_RGB), 1973 8, 1974 &reject_connector_hdmi_funcs); 1975 KUNIT_ASSERT_NOT_NULL(test, priv); 1976 1977 conn = &priv->connector; 1978 1979 /* should reject all modes */ 1980 ret = set_connector_edid(test, conn, 1981 test_edid_hdmi_1080p_rgb_max_200mhz, 1982 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz)); 1983 KUNIT_ASSERT_EQ(test, ret, 0); 1984 1985 preferred = find_preferred_mode(conn); 1986 KUNIT_ASSERT_NULL(test, preferred); 1987 } 1988 1989 /* 1990 * Test that the drm_hdmi_connector_mode_valid() will reject modes that don't 1991 * pass the info.max_tmds_clock filter. Pass crafted EDID and verify that 1992 * high-rate modes are filtered. 1993 */ 1994 static void drm_test_check_mode_valid_reject_max_clock(struct kunit *test) 1995 { 1996 struct drm_atomic_helper_connector_hdmi_priv *priv; 1997 struct drm_connector *conn; 1998 struct drm_display_mode *preferred; 1999 int ret; 2000 2001 priv = drm_kunit_helper_connector_hdmi_init(test, 2002 BIT(HDMI_COLORSPACE_RGB), 2003 8); 2004 KUNIT_ASSERT_NOT_NULL(test, priv); 2005 2006 conn = &priv->connector; 2007 2008 ret = set_connector_edid(test, conn, 2009 test_edid_hdmi_1080p_rgb_max_100mhz, 2010 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_100mhz)); 2011 KUNIT_ASSERT_GT(test, ret, 0); 2012 2013 KUNIT_ASSERT_EQ(test, conn->display_info.max_tmds_clock, 100 * 1000); 2014 2015 preferred = find_preferred_mode(conn); 2016 KUNIT_ASSERT_NOT_NULL(test, preferred); 2017 KUNIT_EXPECT_EQ(test, preferred->hdisplay, 640); 2018 KUNIT_EXPECT_EQ(test, preferred->vdisplay, 480); 2019 KUNIT_EXPECT_EQ(test, preferred->clock, 25200); 2020 } 2021 2022 static struct kunit_case drm_atomic_helper_connector_hdmi_mode_valid_tests[] = { 2023 KUNIT_CASE(drm_test_check_mode_valid), 2024 KUNIT_CASE(drm_test_check_mode_valid_reject), 2025 KUNIT_CASE(drm_test_check_mode_valid_reject_rate), 2026 KUNIT_CASE(drm_test_check_mode_valid_reject_max_clock), 2027 { } 2028 }; 2029 2030 static struct kunit_suite drm_atomic_helper_connector_hdmi_mode_valid_test_suite = { 2031 .name = "drm_atomic_helper_connector_hdmi_mode_valid", 2032 .test_cases = drm_atomic_helper_connector_hdmi_mode_valid_tests, 2033 }; 2034 2035 kunit_test_suites( 2036 &drm_atomic_helper_connector_hdmi_check_test_suite, 2037 &drm_atomic_helper_connector_hdmi_reset_test_suite, 2038 &drm_atomic_helper_connector_hdmi_mode_valid_test_suite, 2039 ); 2040 2041 MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>"); 2042 MODULE_DESCRIPTION("Kunit test for drm_hdmi_state_helper functions"); 2043 MODULE_LICENSE("GPL"); 2044