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

Configure Feed

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

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