1 // SPDX-License-Identifier: GPL-2.0
4 * Kunit test for drm_hdmi_state_helper functions
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>
20 #include <drm/display/drm_hdmi_helper.h>
21 #include <drm/display/drm_hdmi_state_helper.h>
23 #include "../drm_crtc_internal.h"
25 #include <kunit/test.h>
27 #include "drm_kunit_edid.h"
29 struct drm_atomic_helper_connector_hdmi_priv {
30 struct drm_device drm;
31 struct drm_plane *plane;
32 struct drm_crtc *crtc;
33 struct drm_encoder encoder;
34 struct drm_connector connector;
36 const char *current_edid;
37 size_t current_edid_len;
40 #define connector_to_priv(c) \
41 container_of_const(c, struct drm_atomic_helper_connector_hdmi_priv, connector)
43 static struct drm_display_mode *find_preferred_mode(struct drm_connector *connector)
45 struct drm_device *drm = connector->dev;
46 struct drm_display_mode *mode, *preferred;
48 mutex_lock(&drm->mode_config.mutex);
49 preferred = list_first_entry_or_null(&connector->modes, struct drm_display_mode, head);
50 list_for_each_entry(mode, &connector->modes, head)
51 if (mode->type & DRM_MODE_TYPE_PREFERRED)
53 mutex_unlock(&drm->mode_config.mutex);
58 static 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)
65 struct drm_atomic_state *state;
66 struct drm_connector_state *conn_state;
67 struct drm_crtc_state *crtc_state;
70 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
71 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
74 conn_state = drm_atomic_get_connector_state(state, connector);
75 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
77 ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
78 if (ret == -EDEADLK) {
79 drm_atomic_state_clear(state);
80 ret = drm_modeset_backoff(ctx);
84 KUNIT_EXPECT_EQ(test, ret, 0);
86 crtc_state = drm_atomic_get_crtc_state(state, crtc);
87 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
89 ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
90 KUNIT_EXPECT_EQ(test, ret, 0);
92 crtc_state->enable = true;
93 crtc_state->active = true;
95 ret = drm_atomic_commit(state);
96 KUNIT_ASSERT_EQ(test, ret, 0);
101 static int set_connector_edid(struct kunit *test, struct drm_connector *connector,
102 const char *edid, size_t edid_len)
104 struct drm_atomic_helper_connector_hdmi_priv *priv =
105 connector_to_priv(connector);
106 struct drm_device *drm = connector->dev;
109 priv->current_edid = edid;
110 priv->current_edid_len = edid_len;
112 mutex_lock(&drm->mode_config.mutex);
113 ret = connector->funcs->fill_modes(connector, 4096, 4096);
114 mutex_unlock(&drm->mode_config.mutex);
119 static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = {
122 static enum drm_mode_status
123 reject_connector_tmds_char_rate_valid(const struct drm_connector *connector,
124 const struct drm_display_mode *mode,
125 unsigned long long tmds_rate)
130 static const struct drm_connector_hdmi_funcs reject_connector_hdmi_funcs = {
131 .tmds_char_rate_valid = reject_connector_tmds_char_rate_valid,
134 static enum drm_mode_status
135 reject_100MHz_connector_tmds_char_rate_valid(const struct drm_connector *connector,
136 const struct drm_display_mode *mode,
137 unsigned long long tmds_rate)
139 return (tmds_rate > 100ULL * 1000 * 1000) ? MODE_BAD : MODE_OK;
142 static const struct drm_connector_hdmi_funcs reject_100_MHz_connector_hdmi_funcs = {
143 .tmds_char_rate_valid = reject_100MHz_connector_tmds_char_rate_valid,
146 static int dummy_connector_get_modes(struct drm_connector *connector)
148 struct drm_atomic_helper_connector_hdmi_priv *priv =
149 connector_to_priv(connector);
150 const struct drm_edid *edid;
151 unsigned int num_modes;
153 edid = drm_edid_alloc(priv->current_edid, priv->current_edid_len);
157 drm_edid_connector_update(connector, edid);
158 num_modes = drm_edid_connector_add_modes(connector);
165 static const struct drm_connector_helper_funcs dummy_connector_helper_funcs = {
166 .atomic_check = drm_atomic_helper_connector_hdmi_check,
167 .get_modes = dummy_connector_get_modes,
168 .mode_valid = drm_hdmi_connector_mode_valid,
171 static void dummy_hdmi_connector_reset(struct drm_connector *connector)
173 drm_atomic_helper_connector_reset(connector);
174 __drm_atomic_helper_connector_hdmi_reset(connector, connector->state);
177 static const struct drm_connector_funcs dummy_connector_funcs = {
178 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
179 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
180 .fill_modes = drm_helper_probe_single_connector_modes,
181 .reset = dummy_hdmi_connector_reset,
185 struct drm_atomic_helper_connector_hdmi_priv *
186 drm_kunit_helper_connector_hdmi_init_funcs(struct kunit *test,
187 unsigned int formats,
188 unsigned int max_bpc,
189 const struct drm_connector_hdmi_funcs *hdmi_funcs)
191 struct drm_atomic_helper_connector_hdmi_priv *priv;
192 struct drm_connector *conn;
193 struct drm_encoder *enc;
194 struct drm_device *drm;
198 dev = drm_kunit_helper_alloc_device(test);
199 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
201 priv = drm_kunit_helper_alloc_drm_device(test, dev,
202 struct drm_atomic_helper_connector_hdmi_priv, drm,
203 DRIVER_MODESET | DRIVER_ATOMIC);
204 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
208 priv->plane = drm_kunit_helper_create_primary_plane(test, drm,
213 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->plane);
215 priv->crtc = drm_kunit_helper_create_crtc(test, drm,
219 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->crtc);
221 enc = &priv->encoder;
222 ret = drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL);
223 KUNIT_ASSERT_EQ(test, ret, 0);
225 enc->possible_crtcs = drm_crtc_mask(priv->crtc);
227 conn = &priv->connector;
228 ret = drmm_connector_hdmi_init(drm, conn,
230 &dummy_connector_funcs,
232 DRM_MODE_CONNECTOR_HDMIA,
236 KUNIT_ASSERT_EQ(test, ret, 0);
238 drm_connector_helper_add(conn, &dummy_connector_helper_funcs);
239 drm_connector_attach_encoder(conn, enc);
241 drm_mode_config_reset(drm);
247 struct drm_atomic_helper_connector_hdmi_priv *
248 drm_kunit_helper_connector_hdmi_init(struct kunit *test,
249 unsigned int formats,
250 unsigned int max_bpc)
252 struct drm_atomic_helper_connector_hdmi_priv *priv;
255 priv = drm_kunit_helper_connector_hdmi_init_funcs(test,
257 &dummy_connector_hdmi_funcs);
258 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
260 ret = set_connector_edid(test, &priv->connector,
261 test_edid_hdmi_1080p_rgb_max_200mhz,
262 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
263 KUNIT_ASSERT_GT(test, ret, 0);
269 * Test that if we change the RGB quantization property to a different
270 * value, we trigger a mode change on the connector's CRTC, which will
271 * in turn disable/enable the connector.
273 static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test)
275 struct drm_atomic_helper_connector_hdmi_priv *priv;
276 struct drm_modeset_acquire_ctx *ctx;
277 struct drm_connector_state *old_conn_state;
278 struct drm_connector_state *new_conn_state;
279 struct drm_crtc_state *crtc_state;
280 struct drm_atomic_state *state;
281 struct drm_display_mode *preferred;
282 struct drm_connector *conn;
283 struct drm_device *drm;
284 struct drm_crtc *crtc;
287 priv = drm_kunit_helper_connector_hdmi_init(test,
288 BIT(HDMI_COLORSPACE_RGB),
290 KUNIT_ASSERT_NOT_NULL(test, priv);
294 conn = &priv->connector;
296 preferred = find_preferred_mode(conn);
297 KUNIT_ASSERT_NOT_NULL(test, preferred);
299 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
300 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
302 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
303 KUNIT_ASSERT_EQ(test, ret, 0);
305 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
306 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
308 new_conn_state = drm_atomic_get_connector_state(state, conn);
309 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
311 old_conn_state = drm_atomic_get_old_connector_state(state, conn);
312 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
314 new_conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
316 KUNIT_ASSERT_NE(test,
317 old_conn_state->hdmi.broadcast_rgb,
318 new_conn_state->hdmi.broadcast_rgb);
320 ret = drm_atomic_check_only(state);
321 KUNIT_ASSERT_EQ(test, ret, 0);
323 new_conn_state = drm_atomic_get_new_connector_state(state, conn);
324 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
325 KUNIT_EXPECT_EQ(test, new_conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_FULL);
327 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
328 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
329 KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed);
333 * Test that if we set the RGB quantization property to the same value,
334 * we don't trigger a mode change on the connector's CRTC and leave the
335 * connector unaffected.
337 static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *test)
339 struct drm_atomic_helper_connector_hdmi_priv *priv;
340 struct drm_modeset_acquire_ctx *ctx;
341 struct drm_connector_state *old_conn_state;
342 struct drm_connector_state *new_conn_state;
343 struct drm_crtc_state *crtc_state;
344 struct drm_atomic_state *state;
345 struct drm_display_mode *preferred;
346 struct drm_connector *conn;
347 struct drm_device *drm;
348 struct drm_crtc *crtc;
351 priv = drm_kunit_helper_connector_hdmi_init(test,
352 BIT(HDMI_COLORSPACE_RGB),
354 KUNIT_ASSERT_NOT_NULL(test, priv);
358 conn = &priv->connector;
360 preferred = find_preferred_mode(conn);
361 KUNIT_ASSERT_NOT_NULL(test, preferred);
363 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
364 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
366 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
367 KUNIT_ASSERT_EQ(test, ret, 0);
369 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
370 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
372 new_conn_state = drm_atomic_get_connector_state(state, conn);
373 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
375 old_conn_state = drm_atomic_get_old_connector_state(state, conn);
376 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
378 new_conn_state->hdmi.broadcast_rgb = old_conn_state->hdmi.broadcast_rgb;
380 ret = drm_atomic_check_only(state);
381 KUNIT_ASSERT_EQ(test, ret, 0);
383 old_conn_state = drm_atomic_get_old_connector_state(state, conn);
384 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
386 new_conn_state = drm_atomic_get_new_connector_state(state, conn);
387 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
389 KUNIT_EXPECT_EQ(test,
390 old_conn_state->hdmi.broadcast_rgb,
391 new_conn_state->hdmi.broadcast_rgb);
393 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
394 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
395 KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
399 * Test that for an HDMI connector, with an HDMI monitor, if the
400 * Broadcast RGB property is set to auto with a mode that isn't the
401 * VIC-1 mode, we will get a limited RGB Quantization Range.
403 static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test)
405 struct drm_atomic_helper_connector_hdmi_priv *priv;
406 struct drm_modeset_acquire_ctx *ctx;
407 struct drm_connector_state *conn_state;
408 struct drm_atomic_state *state;
409 struct drm_display_mode *preferred;
410 struct drm_connector *conn;
411 struct drm_device *drm;
412 struct drm_crtc *crtc;
415 priv = drm_kunit_helper_connector_hdmi_init(test,
416 BIT(HDMI_COLORSPACE_RGB),
418 KUNIT_ASSERT_NOT_NULL(test, priv);
422 conn = &priv->connector;
423 KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
425 preferred = find_preferred_mode(conn);
426 KUNIT_ASSERT_NOT_NULL(test, preferred);
427 KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
429 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
430 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
432 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
433 KUNIT_ASSERT_EQ(test, ret, 0);
435 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
436 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
438 conn_state = drm_atomic_get_connector_state(state, conn);
439 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
441 KUNIT_ASSERT_EQ(test,
442 conn_state->hdmi.broadcast_rgb,
443 DRM_HDMI_BROADCAST_RGB_AUTO);
445 ret = drm_atomic_check_only(state);
446 KUNIT_ASSERT_EQ(test, ret, 0);
448 conn_state = drm_atomic_get_connector_state(state, conn);
449 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
451 KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
455 * Test that for an HDMI connector, with an HDMI monitor, if the
456 * Broadcast RGB property is set to auto with a VIC-1 mode, we will get
457 * a full RGB Quantization Range.
459 static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test)
461 struct drm_atomic_helper_connector_hdmi_priv *priv;
462 struct drm_modeset_acquire_ctx *ctx;
463 struct drm_connector_state *conn_state;
464 struct drm_atomic_state *state;
465 struct drm_display_mode *mode;
466 struct drm_connector *conn;
467 struct drm_device *drm;
468 struct drm_crtc *crtc;
471 priv = drm_kunit_helper_connector_hdmi_init(test,
472 BIT(HDMI_COLORSPACE_RGB),
474 KUNIT_ASSERT_NOT_NULL(test, priv);
477 conn = &priv->connector;
478 KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
480 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
481 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
483 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
484 KUNIT_ASSERT_NOT_NULL(test, mode);
487 ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
488 KUNIT_ASSERT_EQ(test, ret, 0);
490 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
491 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
493 conn_state = drm_atomic_get_connector_state(state, conn);
494 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
496 KUNIT_ASSERT_EQ(test,
497 conn_state->hdmi.broadcast_rgb,
498 DRM_HDMI_BROADCAST_RGB_AUTO);
500 ret = drm_atomic_check_only(state);
501 KUNIT_ASSERT_EQ(test, ret, 0);
503 conn_state = drm_atomic_get_connector_state(state, conn);
504 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
506 KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range);
510 * Test that for an HDMI connector, with an HDMI monitor, if the
511 * Broadcast RGB property is set to full with a mode that isn't the
512 * VIC-1 mode, we will get a full RGB Quantization Range.
514 static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test)
516 struct drm_atomic_helper_connector_hdmi_priv *priv;
517 struct drm_modeset_acquire_ctx *ctx;
518 struct drm_connector_state *conn_state;
519 struct drm_atomic_state *state;
520 struct drm_display_mode *preferred;
521 struct drm_connector *conn;
522 struct drm_device *drm;
523 struct drm_crtc *crtc;
526 priv = drm_kunit_helper_connector_hdmi_init(test,
527 BIT(HDMI_COLORSPACE_RGB),
529 KUNIT_ASSERT_NOT_NULL(test, priv);
533 conn = &priv->connector;
534 KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
536 preferred = find_preferred_mode(conn);
537 KUNIT_ASSERT_NOT_NULL(test, preferred);
538 KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
540 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
541 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
543 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
544 KUNIT_ASSERT_EQ(test, ret, 0);
546 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
547 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
549 conn_state = drm_atomic_get_connector_state(state, conn);
550 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
552 conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
554 ret = drm_atomic_check_only(state);
555 KUNIT_ASSERT_EQ(test, ret, 0);
557 conn_state = drm_atomic_get_connector_state(state, conn);
558 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
560 KUNIT_ASSERT_EQ(test,
561 conn_state->hdmi.broadcast_rgb,
562 DRM_HDMI_BROADCAST_RGB_FULL);
564 KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range);
568 * Test that for an HDMI connector, with an HDMI monitor, if the
569 * Broadcast RGB property is set to full with a VIC-1 mode, we will get
570 * a full RGB Quantization Range.
572 static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test)
574 struct drm_atomic_helper_connector_hdmi_priv *priv;
575 struct drm_modeset_acquire_ctx *ctx;
576 struct drm_connector_state *conn_state;
577 struct drm_atomic_state *state;
578 struct drm_display_mode *mode;
579 struct drm_connector *conn;
580 struct drm_device *drm;
581 struct drm_crtc *crtc;
584 priv = drm_kunit_helper_connector_hdmi_init(test,
585 BIT(HDMI_COLORSPACE_RGB),
587 KUNIT_ASSERT_NOT_NULL(test, priv);
590 conn = &priv->connector;
591 KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
593 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
594 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
596 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
597 KUNIT_ASSERT_NOT_NULL(test, mode);
600 ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
601 KUNIT_ASSERT_EQ(test, ret, 0);
603 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
604 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
606 conn_state = drm_atomic_get_connector_state(state, conn);
607 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
609 conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
611 ret = drm_atomic_check_only(state);
612 KUNIT_ASSERT_EQ(test, ret, 0);
614 conn_state = drm_atomic_get_connector_state(state, conn);
615 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
617 KUNIT_ASSERT_EQ(test,
618 conn_state->hdmi.broadcast_rgb,
619 DRM_HDMI_BROADCAST_RGB_FULL);
621 KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range);
625 * Test that for an HDMI connector, with an HDMI monitor, if the
626 * Broadcast RGB property is set to limited with a mode that isn't the
627 * VIC-1 mode, we will get a limited RGB Quantization Range.
629 static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test)
631 struct drm_atomic_helper_connector_hdmi_priv *priv;
632 struct drm_modeset_acquire_ctx *ctx;
633 struct drm_connector_state *conn_state;
634 struct drm_atomic_state *state;
635 struct drm_display_mode *preferred;
636 struct drm_connector *conn;
637 struct drm_device *drm;
638 struct drm_crtc *crtc;
641 priv = drm_kunit_helper_connector_hdmi_init(test,
642 BIT(HDMI_COLORSPACE_RGB),
644 KUNIT_ASSERT_NOT_NULL(test, priv);
648 conn = &priv->connector;
649 KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
651 preferred = find_preferred_mode(conn);
652 KUNIT_ASSERT_NOT_NULL(test, preferred);
653 KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
655 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
656 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
658 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
659 KUNIT_ASSERT_EQ(test, ret, 0);
661 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
662 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
664 conn_state = drm_atomic_get_connector_state(state, conn);
665 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
667 conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
669 ret = drm_atomic_check_only(state);
670 KUNIT_ASSERT_EQ(test, ret, 0);
672 conn_state = drm_atomic_get_connector_state(state, conn);
673 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
675 KUNIT_ASSERT_EQ(test,
676 conn_state->hdmi.broadcast_rgb,
677 DRM_HDMI_BROADCAST_RGB_LIMITED);
679 KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
683 * Test that for an HDMI connector, with an HDMI monitor, if the
684 * Broadcast RGB property is set to limited with a VIC-1 mode, we will
685 * get a limited RGB Quantization Range.
687 static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *test)
689 struct drm_atomic_helper_connector_hdmi_priv *priv;
690 struct drm_modeset_acquire_ctx *ctx;
691 struct drm_connector_state *conn_state;
692 struct drm_atomic_state *state;
693 struct drm_display_mode *mode;
694 struct drm_connector *conn;
695 struct drm_device *drm;
696 struct drm_crtc *crtc;
699 priv = drm_kunit_helper_connector_hdmi_init(test,
700 BIT(HDMI_COLORSPACE_RGB),
702 KUNIT_ASSERT_NOT_NULL(test, priv);
705 conn = &priv->connector;
706 KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
708 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
709 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
711 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
712 KUNIT_ASSERT_NOT_NULL(test, mode);
715 ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
716 KUNIT_ASSERT_EQ(test, ret, 0);
718 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
719 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
721 conn_state = drm_atomic_get_connector_state(state, conn);
722 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
724 conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
726 ret = drm_atomic_check_only(state);
727 KUNIT_ASSERT_EQ(test, ret, 0);
729 conn_state = drm_atomic_get_connector_state(state, conn);
730 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
732 KUNIT_ASSERT_EQ(test,
733 conn_state->hdmi.broadcast_rgb,
734 DRM_HDMI_BROADCAST_RGB_LIMITED);
736 KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
740 * Test that if we change the maximum bpc property to a different value,
741 * we trigger a mode change on the connector's CRTC, which will in turn
742 * disable/enable the connector.
744 static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)
746 struct drm_atomic_helper_connector_hdmi_priv *priv;
747 struct drm_modeset_acquire_ctx *ctx;
748 struct drm_connector_state *old_conn_state;
749 struct drm_connector_state *new_conn_state;
750 struct drm_crtc_state *crtc_state;
751 struct drm_atomic_state *state;
752 struct drm_display_mode *preferred;
753 struct drm_connector *conn;
754 struct drm_device *drm;
755 struct drm_crtc *crtc;
758 priv = drm_kunit_helper_connector_hdmi_init(test,
759 BIT(HDMI_COLORSPACE_RGB),
761 KUNIT_ASSERT_NOT_NULL(test, priv);
765 conn = &priv->connector;
766 ret = set_connector_edid(test, conn,
767 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
768 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
769 KUNIT_ASSERT_GT(test, ret, 0);
771 preferred = find_preferred_mode(conn);
772 KUNIT_ASSERT_NOT_NULL(test, preferred);
774 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
775 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
777 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
778 KUNIT_ASSERT_EQ(test, ret, 0);
780 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
781 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
783 new_conn_state = drm_atomic_get_connector_state(state, conn);
784 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
786 old_conn_state = drm_atomic_get_old_connector_state(state, conn);
787 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
789 new_conn_state->max_requested_bpc = 8;
791 KUNIT_ASSERT_NE(test,
792 old_conn_state->max_requested_bpc,
793 new_conn_state->max_requested_bpc);
795 ret = drm_atomic_check_only(state);
796 KUNIT_ASSERT_EQ(test, ret, 0);
798 old_conn_state = drm_atomic_get_old_connector_state(state, conn);
799 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
801 new_conn_state = drm_atomic_get_new_connector_state(state, conn);
802 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
804 KUNIT_ASSERT_NE(test,
805 old_conn_state->hdmi.output_bpc,
806 new_conn_state->hdmi.output_bpc);
808 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
809 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
810 KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed);
814 * Test that if we set the output bpc property to the same value, we
815 * don't trigger a mode change on the connector's CRTC and leave the
816 * connector unaffected.
818 static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
820 struct drm_atomic_helper_connector_hdmi_priv *priv;
821 struct drm_modeset_acquire_ctx *ctx;
822 struct drm_connector_state *old_conn_state;
823 struct drm_connector_state *new_conn_state;
824 struct drm_crtc_state *crtc_state;
825 struct drm_atomic_state *state;
826 struct drm_display_mode *preferred;
827 struct drm_connector *conn;
828 struct drm_device *drm;
829 struct drm_crtc *crtc;
832 priv = drm_kunit_helper_connector_hdmi_init(test,
833 BIT(HDMI_COLORSPACE_RGB),
835 KUNIT_ASSERT_NOT_NULL(test, priv);
839 conn = &priv->connector;
840 ret = set_connector_edid(test, conn,
841 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
842 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
843 KUNIT_ASSERT_GT(test, ret, 0);
845 preferred = find_preferred_mode(conn);
846 KUNIT_ASSERT_NOT_NULL(test, preferred);
848 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
849 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
851 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
852 KUNIT_ASSERT_EQ(test, ret, 0);
854 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
855 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
857 new_conn_state = drm_atomic_get_connector_state(state, conn);
858 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
860 old_conn_state = drm_atomic_get_old_connector_state(state, conn);
861 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
863 KUNIT_ASSERT_EQ(test,
864 new_conn_state->hdmi.output_bpc,
865 old_conn_state->hdmi.output_bpc);
867 ret = drm_atomic_check_only(state);
868 KUNIT_ASSERT_EQ(test, ret, 0);
870 old_conn_state = drm_atomic_get_old_connector_state(state, conn);
871 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
873 new_conn_state = drm_atomic_get_new_connector_state(state, conn);
874 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
876 KUNIT_EXPECT_EQ(test,
877 old_conn_state->hdmi.output_bpc,
878 new_conn_state->hdmi.output_bpc);
880 crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
881 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
882 KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
886 * Test that if we have an HDMI connector but a !HDMI display, we always
887 * output RGB with 8 bpc.
889 static void drm_test_check_output_bpc_dvi(struct kunit *test)
891 struct drm_atomic_helper_connector_hdmi_priv *priv;
892 struct drm_modeset_acquire_ctx *ctx;
893 struct drm_connector_state *conn_state;
894 struct drm_display_info *info;
895 struct drm_display_mode *preferred;
896 struct drm_connector *conn;
897 struct drm_device *drm;
898 struct drm_crtc *crtc;
901 priv = drm_kunit_helper_connector_hdmi_init(test,
902 BIT(HDMI_COLORSPACE_RGB) |
903 BIT(HDMI_COLORSPACE_YUV422) |
904 BIT(HDMI_COLORSPACE_YUV444),
906 KUNIT_ASSERT_NOT_NULL(test, priv);
910 conn = &priv->connector;
911 ret = set_connector_edid(test, conn,
913 ARRAY_SIZE(test_edid_dvi_1080p));
914 KUNIT_ASSERT_GT(test, ret, 0);
916 info = &conn->display_info;
917 KUNIT_ASSERT_FALSE(test, info->is_hdmi);
919 preferred = find_preferred_mode(conn);
920 KUNIT_ASSERT_NOT_NULL(test, preferred);
922 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
923 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
925 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
926 KUNIT_ASSERT_EQ(test, ret, 0);
928 conn_state = conn->state;
929 KUNIT_ASSERT_NOT_NULL(test, conn_state);
931 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
932 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
936 * Test that when doing a commit which would use RGB 8bpc, the TMDS
937 * clock rate stored in the connector state is equal to the mode clock
939 static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test)
941 struct drm_atomic_helper_connector_hdmi_priv *priv;
942 struct drm_modeset_acquire_ctx *ctx;
943 struct drm_connector_state *conn_state;
944 struct drm_display_mode *preferred;
945 struct drm_connector *conn;
946 struct drm_device *drm;
947 struct drm_crtc *crtc;
950 priv = drm_kunit_helper_connector_hdmi_init(test,
951 BIT(HDMI_COLORSPACE_RGB),
953 KUNIT_ASSERT_NOT_NULL(test, priv);
957 conn = &priv->connector;
958 ret = set_connector_edid(test, conn,
959 test_edid_hdmi_1080p_rgb_max_200mhz,
960 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
961 KUNIT_ASSERT_GT(test, ret, 0);
963 preferred = find_preferred_mode(conn);
964 KUNIT_ASSERT_NOT_NULL(test, preferred);
965 KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
967 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
968 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
970 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
971 KUNIT_ASSERT_EQ(test, ret, 0);
973 conn_state = conn->state;
974 KUNIT_ASSERT_NOT_NULL(test, conn_state);
976 KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 8);
977 KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
978 KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1000);
982 * Test that when doing a commit which would use RGB 10bpc, the TMDS
983 * clock rate stored in the connector state is equal to 1.25 times the
986 static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test)
988 struct drm_atomic_helper_connector_hdmi_priv *priv;
989 struct drm_modeset_acquire_ctx *ctx;
990 struct drm_connector_state *conn_state;
991 struct drm_display_mode *preferred;
992 struct drm_connector *conn;
993 struct drm_device *drm;
994 struct drm_crtc *crtc;
997 priv = drm_kunit_helper_connector_hdmi_init(test,
998 BIT(HDMI_COLORSPACE_RGB),
1000 KUNIT_ASSERT_NOT_NULL(test, priv);
1004 conn = &priv->connector;
1005 ret = set_connector_edid(test, conn,
1006 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
1007 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
1008 KUNIT_ASSERT_GT(test, ret, 0);
1010 preferred = find_preferred_mode(conn);
1011 KUNIT_ASSERT_NOT_NULL(test, preferred);
1012 KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
1014 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1015 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1017 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1018 KUNIT_ASSERT_EQ(test, ret, 0);
1020 conn_state = conn->state;
1021 KUNIT_ASSERT_NOT_NULL(test, conn_state);
1023 KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 10);
1024 KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1025 KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250);
1029 * Test that when doing a commit which would use RGB 12bpc, the TMDS
1030 * clock rate stored in the connector state is equal to 1.5 times the
1033 static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test)
1035 struct drm_atomic_helper_connector_hdmi_priv *priv;
1036 struct drm_modeset_acquire_ctx *ctx;
1037 struct drm_connector_state *conn_state;
1038 struct drm_display_mode *preferred;
1039 struct drm_connector *conn;
1040 struct drm_device *drm;
1041 struct drm_crtc *crtc;
1044 priv = drm_kunit_helper_connector_hdmi_init(test,
1045 BIT(HDMI_COLORSPACE_RGB),
1047 KUNIT_ASSERT_NOT_NULL(test, priv);
1051 conn = &priv->connector;
1052 ret = set_connector_edid(test, conn,
1053 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
1054 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
1055 KUNIT_ASSERT_GT(test, ret, 0);
1057 preferred = find_preferred_mode(conn);
1058 KUNIT_ASSERT_NOT_NULL(test, preferred);
1059 KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
1061 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1062 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1064 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1065 KUNIT_ASSERT_EQ(test, ret, 0);
1067 conn_state = conn->state;
1068 KUNIT_ASSERT_NOT_NULL(test, conn_state);
1070 KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 12);
1071 KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1072 KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1500);
1076 * Test that if we filter a rate through our hook, it's indeed rejected
1077 * by the whole atomic_check logic.
1079 * We do so by first doing a commit on the pipeline to make sure that it
1080 * works, change the HDMI helpers pointer, and then try the same commit
1081 * again to see if it fails as it should.
1083 static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test)
1085 struct drm_atomic_helper_connector_hdmi_priv *priv;
1086 struct drm_modeset_acquire_ctx *ctx;
1087 struct drm_atomic_state *state;
1088 struct drm_display_mode *preferred;
1089 struct drm_crtc_state *crtc_state;
1090 struct drm_connector *conn;
1091 struct drm_device *drm;
1092 struct drm_crtc *crtc;
1095 priv = drm_kunit_helper_connector_hdmi_init(test,
1096 BIT(HDMI_COLORSPACE_RGB),
1098 KUNIT_ASSERT_NOT_NULL(test, priv);
1102 conn = &priv->connector;
1104 preferred = find_preferred_mode(conn);
1105 KUNIT_ASSERT_NOT_NULL(test, preferred);
1107 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1108 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1110 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1111 KUNIT_ASSERT_EQ(test, ret, 0);
1113 /* You shouldn't be doing that at home. */
1114 conn->hdmi.funcs = &reject_connector_hdmi_funcs;
1116 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
1117 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
1119 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1120 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
1122 crtc_state->connectors_changed = true;
1124 ret = drm_atomic_check_only(state);
1125 KUNIT_EXPECT_LT(test, ret, 0);
1130 * - We have an HDMI connector supporting RGB only
1131 * - The chosen mode has a TMDS character rate higher than the display
1132 * supports in RGB/12bpc
1133 * - The chosen mode has a TMDS character rate lower than the display
1134 * supports in RGB/10bpc.
1136 * Then we will pick the latter, and the computed TMDS character rate
1137 * will be equal to 1.25 times the mode pixel clock.
1139 static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test)
1141 struct drm_atomic_helper_connector_hdmi_priv *priv;
1142 struct drm_modeset_acquire_ctx *ctx;
1143 struct drm_connector_state *conn_state;
1144 struct drm_display_info *info;
1145 struct drm_display_mode *preferred;
1146 unsigned long long rate;
1147 struct drm_connector *conn;
1148 struct drm_device *drm;
1149 struct drm_crtc *crtc;
1152 priv = drm_kunit_helper_connector_hdmi_init(test,
1153 BIT(HDMI_COLORSPACE_RGB),
1155 KUNIT_ASSERT_NOT_NULL(test, priv);
1159 conn = &priv->connector;
1160 ret = set_connector_edid(test, conn,
1161 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
1162 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
1163 KUNIT_ASSERT_GT(test, ret, 0);
1165 info = &conn->display_info;
1166 KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1167 KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1169 preferred = find_preferred_mode(conn);
1170 KUNIT_ASSERT_NOT_NULL(test, preferred);
1171 KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
1173 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1174 KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1176 rate = drm_hdmi_compute_mode_clock(preferred, 10, HDMI_COLORSPACE_RGB);
1177 KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1179 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1180 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1182 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1183 KUNIT_EXPECT_EQ(test, ret, 0);
1185 conn_state = conn->state;
1186 KUNIT_ASSERT_NOT_NULL(test, conn_state);
1188 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10);
1189 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1190 KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250);
1195 * - We have an HDMI connector supporting both RGB and YUV422 and up to
1197 * - The chosen mode has a TMDS character rate higher than the display
1198 * supports in RGB/12bpc but lower than the display supports in
1200 * - The chosen mode has a TMDS character rate lower than the display
1201 * supports in YUV422/12bpc.
1203 * Then we will prefer to keep the RGB format with a lower bpc over
1206 static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test)
1208 struct drm_atomic_helper_connector_hdmi_priv *priv;
1209 struct drm_modeset_acquire_ctx *ctx;
1210 struct drm_connector_state *conn_state;
1211 struct drm_display_info *info;
1212 struct drm_display_mode *preferred;
1213 unsigned long long rate;
1214 struct drm_connector *conn;
1215 struct drm_device *drm;
1216 struct drm_crtc *crtc;
1219 priv = drm_kunit_helper_connector_hdmi_init(test,
1220 BIT(HDMI_COLORSPACE_RGB) |
1221 BIT(HDMI_COLORSPACE_YUV422) |
1222 BIT(HDMI_COLORSPACE_YUV444),
1224 KUNIT_ASSERT_NOT_NULL(test, priv);
1228 conn = &priv->connector;
1229 ret = set_connector_edid(test, conn,
1230 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
1231 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
1232 KUNIT_ASSERT_GT(test, ret, 0);
1234 info = &conn->display_info;
1235 KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1236 KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1238 preferred = find_preferred_mode(conn);
1239 KUNIT_ASSERT_NOT_NULL(test, preferred);
1240 KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
1242 rate = drm_hdmi_compute_mode_clock(preferred, 10, HDMI_COLORSPACE_RGB);
1243 KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1245 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1246 KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1248 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
1249 KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1251 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1252 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1254 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1255 KUNIT_EXPECT_EQ(test, ret, 0);
1257 conn_state = conn->state;
1258 KUNIT_ASSERT_NOT_NULL(test, conn_state);
1260 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10);
1261 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1265 * Test that if a driver and screen supports RGB and YUV formats, and we
1266 * try to set the VIC 1 mode, we end up with 8bpc RGB even if we could
1267 * have had a higher bpc.
1269 static void drm_test_check_output_bpc_format_vic_1(struct kunit *test)
1271 struct drm_atomic_helper_connector_hdmi_priv *priv;
1272 struct drm_modeset_acquire_ctx *ctx;
1273 struct drm_connector_state *conn_state;
1274 struct drm_display_info *info;
1275 struct drm_display_mode *mode;
1276 unsigned long long rate;
1277 struct drm_connector *conn;
1278 struct drm_device *drm;
1279 struct drm_crtc *crtc;
1282 priv = drm_kunit_helper_connector_hdmi_init(test,
1283 BIT(HDMI_COLORSPACE_RGB) |
1284 BIT(HDMI_COLORSPACE_YUV422) |
1285 BIT(HDMI_COLORSPACE_YUV444),
1287 KUNIT_ASSERT_NOT_NULL(test, priv);
1290 conn = &priv->connector;
1291 ret = set_connector_edid(test, conn,
1292 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
1293 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
1294 KUNIT_ASSERT_GT(test, ret, 0);
1296 info = &conn->display_info;
1297 KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1298 KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1300 mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
1301 KUNIT_ASSERT_NOT_NULL(test, mode);
1304 * NOTE: We can't use drm_hdmi_compute_mode_clock()
1305 * here because we're trying to get the rate of an invalid
1308 * Thus, we have to calculate the rate by hand.
1310 rate = mode->clock * 1500;
1311 KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1313 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1314 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1317 ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
1318 KUNIT_EXPECT_EQ(test, ret, 0);
1320 conn_state = conn->state;
1321 KUNIT_ASSERT_NOT_NULL(test, conn_state);
1323 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
1324 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1328 * Test that if a driver supports only RGB but the screen also supports
1329 * YUV formats, we only end up with an RGB format.
1331 static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test)
1333 struct drm_atomic_helper_connector_hdmi_priv *priv;
1334 struct drm_modeset_acquire_ctx *ctx;
1335 struct drm_connector_state *conn_state;
1336 struct drm_display_info *info;
1337 struct drm_display_mode *preferred;
1338 unsigned long long rate;
1339 struct drm_connector *conn;
1340 struct drm_device *drm;
1341 struct drm_crtc *crtc;
1344 priv = drm_kunit_helper_connector_hdmi_init(test,
1345 BIT(HDMI_COLORSPACE_RGB),
1347 KUNIT_ASSERT_NOT_NULL(test, priv);
1351 conn = &priv->connector;
1352 ret = set_connector_edid(test, conn,
1353 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
1354 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
1355 KUNIT_ASSERT_GT(test, ret, 0);
1357 info = &conn->display_info;
1358 KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1359 KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1361 preferred = find_preferred_mode(conn);
1362 KUNIT_ASSERT_NOT_NULL(test, preferred);
1365 * We're making sure that YUV422 would be the preferred option
1366 * here: we're always favouring higher bpc, we can't have RGB
1367 * because the TMDS character rate exceeds the maximum supported
1368 * by the display, and YUV422 works for that display.
1370 * But since the driver only supports RGB, we should fallback to
1371 * a lower bpc with RGB.
1373 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1374 KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1376 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
1377 KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1379 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1380 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1382 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1383 KUNIT_EXPECT_EQ(test, ret, 0);
1385 conn_state = conn->state;
1386 KUNIT_ASSERT_NOT_NULL(test, conn_state);
1388 KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12);
1389 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1393 * Test that if a screen supports only RGB but the driver also supports
1394 * YUV formats, we only end up with an RGB format.
1396 static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test)
1398 struct drm_atomic_helper_connector_hdmi_priv *priv;
1399 struct drm_modeset_acquire_ctx *ctx;
1400 struct drm_connector_state *conn_state;
1401 struct drm_display_info *info;
1402 struct drm_display_mode *preferred;
1403 unsigned long long rate;
1404 struct drm_connector *conn;
1405 struct drm_device *drm;
1406 struct drm_crtc *crtc;
1409 priv = drm_kunit_helper_connector_hdmi_init(test,
1410 BIT(HDMI_COLORSPACE_RGB) |
1411 BIT(HDMI_COLORSPACE_YUV422) |
1412 BIT(HDMI_COLORSPACE_YUV444),
1414 KUNIT_ASSERT_NOT_NULL(test, priv);
1418 conn = &priv->connector;
1419 ret = set_connector_edid(test, conn,
1420 test_edid_hdmi_1080p_rgb_max_200mhz,
1421 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
1422 KUNIT_ASSERT_GT(test, ret, 0);
1424 info = &conn->display_info;
1425 KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1426 KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1428 preferred = find_preferred_mode(conn);
1429 KUNIT_ASSERT_NOT_NULL(test, preferred);
1432 * We're making sure that YUV422 would be the preferred option
1433 * here: we're always favouring higher bpc, we can't have RGB
1434 * because the TMDS character rate exceeds the maximum supported
1435 * by the display, and YUV422 works for that display.
1437 * But since the display only supports RGB, we should fallback to
1438 * a lower bpc with RGB.
1440 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1441 KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1443 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
1444 KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1446 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1447 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1449 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1450 KUNIT_EXPECT_EQ(test, ret, 0);
1452 conn_state = conn->state;
1453 KUNIT_ASSERT_NOT_NULL(test, conn_state);
1455 KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12);
1456 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1460 * Test that if a display supports higher bpc but the driver only
1461 * supports 8 bpc, we only end up with 8 bpc even if we could have had a
1464 static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test)
1466 struct drm_atomic_helper_connector_hdmi_priv *priv;
1467 struct drm_modeset_acquire_ctx *ctx;
1468 struct drm_connector_state *conn_state;
1469 struct drm_display_info *info;
1470 struct drm_display_mode *preferred;
1471 unsigned long long rate;
1472 struct drm_connector *conn;
1473 struct drm_device *drm;
1474 struct drm_crtc *crtc;
1477 priv = drm_kunit_helper_connector_hdmi_init(test,
1478 BIT(HDMI_COLORSPACE_RGB),
1480 KUNIT_ASSERT_NOT_NULL(test, priv);
1484 conn = &priv->connector;
1485 ret = set_connector_edid(test, conn,
1486 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
1487 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
1488 KUNIT_ASSERT_GT(test, ret, 0);
1490 info = &conn->display_info;
1491 KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1492 KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1494 preferred = find_preferred_mode(conn);
1495 KUNIT_ASSERT_NOT_NULL(test, preferred);
1498 * We're making sure that we have headroom on the TMDS character
1499 * clock to actually use 12bpc.
1501 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1502 KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1504 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1505 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1507 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1508 KUNIT_EXPECT_EQ(test, ret, 0);
1510 conn_state = conn->state;
1511 KUNIT_ASSERT_NOT_NULL(test, conn_state);
1513 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
1514 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1518 * Test that if a driver supports higher bpc but the display only
1519 * supports 8 bpc, we only end up with 8 bpc even if we could have had a
1522 static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *test)
1524 struct drm_atomic_helper_connector_hdmi_priv *priv;
1525 struct drm_modeset_acquire_ctx *ctx;
1526 struct drm_connector_state *conn_state;
1527 struct drm_display_info *info;
1528 struct drm_display_mode *preferred;
1529 unsigned long long rate;
1530 struct drm_connector *conn;
1531 struct drm_device *drm;
1532 struct drm_crtc *crtc;
1535 priv = drm_kunit_helper_connector_hdmi_init(test,
1536 BIT(HDMI_COLORSPACE_RGB) |
1537 BIT(HDMI_COLORSPACE_YUV422) |
1538 BIT(HDMI_COLORSPACE_YUV444),
1540 KUNIT_ASSERT_NOT_NULL(test, priv);
1544 conn = &priv->connector;
1545 ret = set_connector_edid(test, conn,
1546 test_edid_hdmi_1080p_rgb_max_340mhz,
1547 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_340mhz));
1548 KUNIT_ASSERT_GT(test, ret, 0);
1550 info = &conn->display_info;
1551 KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1552 KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1554 preferred = find_preferred_mode(conn);
1555 KUNIT_ASSERT_NOT_NULL(test, preferred);
1558 * We're making sure that we have headroom on the TMDS character
1559 * clock to actually use 12bpc.
1561 rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1562 KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1564 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1565 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1567 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1568 KUNIT_EXPECT_EQ(test, ret, 0);
1570 conn_state = conn->state;
1571 KUNIT_ASSERT_NOT_NULL(test, conn_state);
1573 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
1574 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1577 /* Test that atomic check succeeds when disabling a connector. */
1578 static void drm_test_check_disable_connector(struct kunit *test)
1580 struct drm_atomic_helper_connector_hdmi_priv *priv;
1581 struct drm_modeset_acquire_ctx *ctx;
1582 struct drm_connector_state *conn_state;
1583 struct drm_crtc_state *crtc_state;
1584 struct drm_atomic_state *state;
1585 struct drm_display_mode *preferred;
1586 struct drm_connector *conn;
1587 struct drm_device *drm;
1588 struct drm_crtc *crtc;
1591 priv = drm_kunit_helper_connector_hdmi_init(test,
1592 BIT(HDMI_COLORSPACE_RGB),
1594 KUNIT_ASSERT_NOT_NULL(test, priv);
1596 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1597 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1599 conn = &priv->connector;
1600 preferred = find_preferred_mode(conn);
1601 KUNIT_ASSERT_NOT_NULL(test, preferred);
1605 ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1606 KUNIT_ASSERT_EQ(test, ret, 0);
1608 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
1609 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
1611 crtc_state = drm_atomic_get_crtc_state(state, crtc);
1612 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
1614 crtc_state->active = false;
1615 ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
1616 KUNIT_EXPECT_EQ(test, ret, 0);
1618 conn_state = drm_atomic_get_connector_state(state, conn);
1619 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
1621 ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
1622 KUNIT_EXPECT_EQ(test, ret, 0);
1624 ret = drm_atomic_check_only(state);
1625 KUNIT_ASSERT_EQ(test, ret, 0);
1628 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
1629 KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode),
1630 KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1),
1631 KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode),
1632 KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode_vic_1),
1633 KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode),
1634 KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode_vic_1),
1636 * TODO: When we'll have YUV output support, we need to check
1637 * that the limited range is always set to limited no matter
1638 * what the value of Broadcast RGB is.
1640 KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed),
1641 KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed),
1642 KUNIT_CASE(drm_test_check_disable_connector),
1643 KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate),
1644 KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback),
1645 KUNIT_CASE(drm_test_check_max_tmds_rate_format_fallback),
1646 KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
1647 KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
1648 KUNIT_CASE(drm_test_check_output_bpc_dvi),
1649 KUNIT_CASE(drm_test_check_output_bpc_format_vic_1),
1650 KUNIT_CASE(drm_test_check_output_bpc_format_display_8bpc_only),
1651 KUNIT_CASE(drm_test_check_output_bpc_format_display_rgb_only),
1652 KUNIT_CASE(drm_test_check_output_bpc_format_driver_8bpc_only),
1653 KUNIT_CASE(drm_test_check_output_bpc_format_driver_rgb_only),
1654 KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc),
1655 KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_10bpc),
1656 KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_12bpc),
1658 * TODO: We should have tests to check that a change in the
1659 * format triggers a CRTC mode change just like we do for the
1660 * RGB Quantization and BPC.
1662 * However, we don't have any way to control which format gets
1663 * picked up aside from changing the BPC or mode which would
1664 * already trigger a mode change.
1669 static struct kunit_suite drm_atomic_helper_connector_hdmi_check_test_suite = {
1670 .name = "drm_atomic_helper_connector_hdmi_check",
1671 .test_cases = drm_atomic_helper_connector_hdmi_check_tests,
1675 * Test that the value of the Broadcast RGB property out of reset is set
1678 static void drm_test_check_broadcast_rgb_value(struct kunit *test)
1680 struct drm_atomic_helper_connector_hdmi_priv *priv;
1681 struct drm_connector_state *conn_state;
1682 struct drm_connector *conn;
1684 priv = drm_kunit_helper_connector_hdmi_init(test,
1685 BIT(HDMI_COLORSPACE_RGB),
1687 KUNIT_ASSERT_NOT_NULL(test, priv);
1689 conn = &priv->connector;
1690 conn_state = conn->state;
1691 KUNIT_EXPECT_EQ(test, conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_AUTO);
1695 * Test that if the connector was initialised with a maximum bpc of 8,
1696 * the value of the max_bpc and max_requested_bpc properties out of
1697 * reset are also set to 8, and output_bpc is set to 0 and will be
1698 * filled at atomic_check time.
1700 static void drm_test_check_bpc_8_value(struct kunit *test)
1702 struct drm_atomic_helper_connector_hdmi_priv *priv;
1703 struct drm_connector_state *conn_state;
1704 struct drm_connector *conn;
1706 priv = drm_kunit_helper_connector_hdmi_init(test,
1707 BIT(HDMI_COLORSPACE_RGB),
1709 KUNIT_ASSERT_NOT_NULL(test, priv);
1711 conn = &priv->connector;
1712 conn_state = conn->state;
1713 KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 8);
1714 KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 8);
1715 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
1719 * Test that if the connector was initialised with a maximum bpc of 10,
1720 * the value of the max_bpc and max_requested_bpc properties out of
1721 * reset are also set to 10, and output_bpc is set to 0 and will be
1722 * filled at atomic_check time.
1724 static void drm_test_check_bpc_10_value(struct kunit *test)
1726 struct drm_atomic_helper_connector_hdmi_priv *priv;
1727 struct drm_connector_state *conn_state;
1728 struct drm_connector *conn;
1730 priv = drm_kunit_helper_connector_hdmi_init(test,
1731 BIT(HDMI_COLORSPACE_RGB),
1733 KUNIT_ASSERT_NOT_NULL(test, priv);
1735 conn = &priv->connector;
1736 conn_state = conn->state;
1737 KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 10);
1738 KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 10);
1739 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
1743 * Test that if the connector was initialised with a maximum bpc of 12,
1744 * the value of the max_bpc and max_requested_bpc properties out of
1745 * reset are also set to 12, and output_bpc is set to 0 and will be
1746 * filled at atomic_check time.
1748 static void drm_test_check_bpc_12_value(struct kunit *test)
1750 struct drm_atomic_helper_connector_hdmi_priv *priv;
1751 struct drm_connector_state *conn_state;
1752 struct drm_connector *conn;
1754 priv = drm_kunit_helper_connector_hdmi_init(test,
1755 BIT(HDMI_COLORSPACE_RGB),
1757 KUNIT_ASSERT_NOT_NULL(test, priv);
1759 conn = &priv->connector;
1760 conn_state = conn->state;
1761 KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 12);
1762 KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 12);
1763 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
1767 * Test that the value of the output format property out of reset is set
1768 * to RGB, even if the driver supports more than that.
1770 static void drm_test_check_format_value(struct kunit *test)
1772 struct drm_atomic_helper_connector_hdmi_priv *priv;
1773 struct drm_connector_state *conn_state;
1774 struct drm_connector *conn;
1776 priv = drm_kunit_helper_connector_hdmi_init(test,
1777 BIT(HDMI_COLORSPACE_RGB) |
1778 BIT(HDMI_COLORSPACE_YUV422) |
1779 BIT(HDMI_COLORSPACE_YUV444),
1781 KUNIT_ASSERT_NOT_NULL(test, priv);
1783 conn = &priv->connector;
1784 conn_state = conn->state;
1785 KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, 0);
1789 * Test that the value of the output format property out of reset is set
1790 * to 0, and will be computed at atomic_check time.
1792 static void drm_test_check_tmds_char_value(struct kunit *test)
1794 struct drm_atomic_helper_connector_hdmi_priv *priv;
1795 struct drm_connector_state *conn_state;
1796 struct drm_connector *conn;
1798 priv = drm_kunit_helper_connector_hdmi_init(test,
1799 BIT(HDMI_COLORSPACE_RGB) |
1800 BIT(HDMI_COLORSPACE_YUV422) |
1801 BIT(HDMI_COLORSPACE_YUV444),
1803 KUNIT_ASSERT_NOT_NULL(test, priv);
1805 conn = &priv->connector;
1806 conn_state = conn->state;
1807 KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, 0);
1810 static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = {
1811 KUNIT_CASE(drm_test_check_broadcast_rgb_value),
1812 KUNIT_CASE(drm_test_check_bpc_8_value),
1813 KUNIT_CASE(drm_test_check_bpc_10_value),
1814 KUNIT_CASE(drm_test_check_bpc_12_value),
1815 KUNIT_CASE(drm_test_check_format_value),
1816 KUNIT_CASE(drm_test_check_tmds_char_value),
1820 static struct kunit_suite drm_atomic_helper_connector_hdmi_reset_test_suite = {
1821 .name = "drm_atomic_helper_connector_hdmi_reset",
1822 .test_cases = drm_atomic_helper_connector_hdmi_reset_tests,
1826 * Test that the default behaviour for drm_hdmi_connector_mode_valid() is not
1827 * to reject any modes. Pass a correct EDID and verify that preferred mode
1828 * matches the expectations (1080p).
1830 static void drm_test_check_mode_valid(struct kunit *test)
1832 struct drm_atomic_helper_connector_hdmi_priv *priv;
1833 struct drm_connector *conn;
1834 struct drm_display_mode *preferred;
1836 priv = drm_kunit_helper_connector_hdmi_init(test,
1837 BIT(HDMI_COLORSPACE_RGB),
1839 KUNIT_ASSERT_NOT_NULL(test, priv);
1841 conn = &priv->connector;
1842 preferred = find_preferred_mode(conn);
1843 KUNIT_ASSERT_NOT_NULL(test, preferred);
1845 KUNIT_EXPECT_EQ(test, preferred->hdisplay, 1920);
1846 KUNIT_EXPECT_EQ(test, preferred->vdisplay, 1080);
1847 KUNIT_EXPECT_EQ(test, preferred->clock, 148500);
1851 * Test that the drm_hdmi_connector_mode_valid() will reject modes depending on
1852 * the .tmds_char_rate_valid() behaviour.
1853 * Pass a correct EDID and verify that high-rate modes are filtered.
1855 static void drm_test_check_mode_valid_reject_rate(struct kunit *test)
1857 struct drm_atomic_helper_connector_hdmi_priv *priv;
1858 struct drm_connector *conn;
1859 struct drm_display_mode *preferred;
1862 priv = drm_kunit_helper_connector_hdmi_init_funcs(test,
1863 BIT(HDMI_COLORSPACE_RGB),
1865 &reject_100_MHz_connector_hdmi_funcs);
1866 KUNIT_ASSERT_NOT_NULL(test, priv);
1868 conn = &priv->connector;
1870 ret = set_connector_edid(test, conn,
1871 test_edid_hdmi_1080p_rgb_max_200mhz,
1872 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
1873 KUNIT_ASSERT_GT(test, ret, 0);
1876 * Unlike the drm_test_check_mode_valid() here 1080p is rejected, but
1879 preferred = find_preferred_mode(conn);
1880 KUNIT_ASSERT_NOT_NULL(test, preferred);
1881 KUNIT_EXPECT_EQ(test, preferred->hdisplay, 640);
1882 KUNIT_EXPECT_EQ(test, preferred->vdisplay, 480);
1883 KUNIT_EXPECT_EQ(test, preferred->clock, 25200);
1887 * Test that the drm_hdmi_connector_mode_valid() will not mark any modes as
1888 * valid if .tmds_char_rate_valid() rejects all of them. Pass a correct EDID
1889 * and verify that there is no preferred mode and no modes were set for the
1892 static void drm_test_check_mode_valid_reject(struct kunit *test)
1894 struct drm_atomic_helper_connector_hdmi_priv *priv;
1895 struct drm_connector *conn;
1896 struct drm_display_mode *preferred;
1899 priv = drm_kunit_helper_connector_hdmi_init_funcs(test,
1900 BIT(HDMI_COLORSPACE_RGB),
1902 &reject_connector_hdmi_funcs);
1903 KUNIT_ASSERT_NOT_NULL(test, priv);
1905 conn = &priv->connector;
1907 /* should reject all modes */
1908 ret = set_connector_edid(test, conn,
1909 test_edid_hdmi_1080p_rgb_max_200mhz,
1910 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
1911 KUNIT_ASSERT_EQ(test, ret, 0);
1913 preferred = find_preferred_mode(conn);
1914 KUNIT_ASSERT_NULL(test, preferred);
1918 * Test that the drm_hdmi_connector_mode_valid() will reject modes that don't
1919 * pass the info.max_tmds_clock filter. Pass crafted EDID and verify that
1920 * high-rate modes are filtered.
1922 static void drm_test_check_mode_valid_reject_max_clock(struct kunit *test)
1924 struct drm_atomic_helper_connector_hdmi_priv *priv;
1925 struct drm_connector *conn;
1926 struct drm_display_mode *preferred;
1929 priv = drm_kunit_helper_connector_hdmi_init(test,
1930 BIT(HDMI_COLORSPACE_RGB),
1932 KUNIT_ASSERT_NOT_NULL(test, priv);
1934 conn = &priv->connector;
1936 ret = set_connector_edid(test, conn,
1937 test_edid_hdmi_1080p_rgb_max_100mhz,
1938 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_100mhz));
1939 KUNIT_ASSERT_GT(test, ret, 0);
1941 KUNIT_ASSERT_EQ(test, conn->display_info.max_tmds_clock, 100 * 1000);
1943 preferred = find_preferred_mode(conn);
1944 KUNIT_ASSERT_NOT_NULL(test, preferred);
1945 KUNIT_EXPECT_EQ(test, preferred->hdisplay, 640);
1946 KUNIT_EXPECT_EQ(test, preferred->vdisplay, 480);
1947 KUNIT_EXPECT_EQ(test, preferred->clock, 25200);
1950 static struct kunit_case drm_atomic_helper_connector_hdmi_mode_valid_tests[] = {
1951 KUNIT_CASE(drm_test_check_mode_valid),
1952 KUNIT_CASE(drm_test_check_mode_valid_reject),
1953 KUNIT_CASE(drm_test_check_mode_valid_reject_rate),
1954 KUNIT_CASE(drm_test_check_mode_valid_reject_max_clock),
1958 static struct kunit_suite drm_atomic_helper_connector_hdmi_mode_valid_test_suite = {
1959 .name = "drm_atomic_helper_connector_hdmi_mode_valid",
1960 .test_cases = drm_atomic_helper_connector_hdmi_mode_valid_tests,
1964 &drm_atomic_helper_connector_hdmi_check_test_suite,
1965 &drm_atomic_helper_connector_hdmi_reset_test_suite,
1966 &drm_atomic_helper_connector_hdmi_mode_valid_test_suite,
1970 MODULE_DESCRIPTION("Kunit test for drm_hdmi_state_helper functions");
1971 MODULE_LICENSE("GPL");