1745 lines · c
1// SPDX-License-Identifier: GPL-2.02 3/*4 * Kunit test for drm_hdmi_state_helper functions5 */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_status117reject_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 165static166struct 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 different233 * value, we trigger a mode change on the connector's CRTC, which will234 * 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 the297 * 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 the361 * Broadcast RGB property is set to auto with a mode that isn't the362 * 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 the417 * Broadcast RGB property is set to auto with a VIC-1 mode, we will get418 * 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_kunit_display_mode_from_cea_vic(test, 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 the473 * Broadcast RGB property is set to full with a mode that isn't the474 * 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 the531 * Broadcast RGB property is set to full with a VIC-1 mode, we will get532 * 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_kunit_display_mode_from_cea_vic(test, 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 the589 * Broadcast RGB property is set to limited with a mode that isn't the590 * 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 the647 * Broadcast RGB property is set to limited with a VIC-1 mode, we will648 * 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_kunit_display_mode_from_cea_vic(test, 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 turn706 * 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, we779 * don't trigger a mode change on the connector's CRTC and leave the780 * 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 always851 * 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 TMDS901 * clock rate stored in the connector state is equal to the mode clock902 */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 TMDS947 * clock rate stored in the connector state is equal to 1.25 times the948 * mode pixel clock949 */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 TMDS994 * clock rate stored in the connector state is equal to 1.5 times the995 * mode pixel clock996 */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 rejected1041 * by the whole atomic_check logic.1042 *1043 * We do so by first doing a commit on the pipeline to make sure that it1044 * works, change the HDMI helpers pointer, and then try the same commit1045 * 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 only1094 * - The chosen mode has a TMDS character rate higher than the display1095 * supports in RGB/12bpc1096 * - The chosen mode has a TMDS character rate lower than the display1097 * supports in RGB/10bpc.1098 *1099 * Then we will pick the latter, and the computed TMDS character rate1100 * 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 to1159 * 12 bpc1160 * - The chosen mode has a TMDS character rate higher than the display1161 * supports in RGB/12bpc but lower than the display supports in1162 * RGB/10bpc1163 * - The chosen mode has a TMDS character rate lower than the display1164 * supports in YUV422/12bpc.1165 *1166 * Then we will prefer to keep the RGB format with a lower bpc over1167 * 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 we1229 * try to set the VIC 1 mode, we end up with 8bpc RGB even if we could1230 * 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_kunit_display_mode_from_cea_vic(test, 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 invalid1272 * 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 supports1293 * 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 option1331 * here: we're always favouring higher bpc, we can't have RGB1332 * because the TMDS character rate exceeds the maximum supported1333 * by the display, and YUV422 works for that display.1334 *1335 * But since the driver only supports RGB, we should fallback to1336 * 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 supports1358 * 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 option1398 * here: we're always favouring higher bpc, we can't have RGB1399 * because the TMDS character rate exceeds the maximum supported1400 * by the display, and YUV422 works for that display.1401 *1402 * But since the display only supports RGB, we should fallback to1403 * 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 only1425 * supports 8 bpc, we only end up with 8 bpc even if we could have had a1426 * 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 character1464 * 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 only1483 * supports 8 bpc, we only end up with 8 bpc even if we could have had a1484 * 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 character1524 * 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 check1550 * that the limited range is always set to limited no matter1551 * 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 the1571 * format triggers a CRTC mode change just like we do for the1572 * RGB Quantization and BPC.1573 *1574 * However, we don't have any way to control which format gets1575 * picked up aside from changing the BPC or mode which would1576 * 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 set1588 * 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 of1609 * reset are also set to 8, and output_bpc is set to 0 and will be1610 * 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 of1633 * reset are also set to 10, and output_bpc is set to 0 and will be1634 * 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 of1657 * reset are also set to 12, and output_bpc is set to 0 and will be1658 * 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 set1680 * 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 set1702 * 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");1745