xref: /linux/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 /*
4  * Kunit test for drm_hdmi_state_helper functions
5  */
6 
7 #include <drm/drm_atomic.h>
8 #include <drm/drm_atomic_state_helper.h>
9 #include <drm/drm_atomic_uapi.h>
10 #include <drm/drm_drv.h>
11 #include <drm/drm_edid.h>
12 #include <drm/drm_connector.h>
13 #include <drm/drm_fourcc.h>
14 #include <drm/drm_kunit_helpers.h>
15 #include <drm/drm_managed.h>
16 #include <drm/drm_modeset_helper_vtables.h>
17 #include <drm/drm_print.h>
18 #include <drm/drm_probe_helper.h>
19 
20 #include <drm/display/drm_hdmi_helper.h>
21 #include <drm/display/drm_hdmi_state_helper.h>
22 
23 #include "../drm_crtc_internal.h"
24 
25 #include <kunit/test.h>
26 
27 #include "drm_kunit_edid.h"
28 
29 struct drm_atomic_helper_connector_hdmi_priv {
30 	struct drm_device drm;
31 	struct drm_plane *plane;
32 	struct drm_crtc *crtc;
33 	struct drm_encoder encoder;
34 	struct drm_connector connector;
35 
36 	const char *current_edid;
37 	size_t current_edid_len;
38 };
39 
40 #define connector_to_priv(c) \
41 	container_of_const(c, struct drm_atomic_helper_connector_hdmi_priv, connector)
42 
43 static struct drm_display_mode *find_preferred_mode(struct drm_connector *connector)
44 {
45 	struct drm_device *drm = connector->dev;
46 	struct drm_display_mode *mode, *preferred;
47 
48 	mutex_lock(&drm->mode_config.mutex);
49 	preferred = list_first_entry(&connector->modes, struct drm_display_mode, head);
50 	list_for_each_entry(mode, &connector->modes, head)
51 		if (mode->type & DRM_MODE_TYPE_PREFERRED)
52 			preferred = mode;
53 	mutex_unlock(&drm->mode_config.mutex);
54 
55 	return preferred;
56 }
57 
58 static int 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 
94 static 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 
113 static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = {
114 };
115 
116 static enum drm_mode_status
117 reject_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 
124 static const struct drm_connector_hdmi_funcs reject_connector_hdmi_funcs = {
125 	.tmds_char_rate_valid	= reject_connector_tmds_char_rate_valid,
126 };
127 
128 static 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 
147 static 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 
152 static 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 
158 static 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 
165 static
166 struct drm_atomic_helper_connector_hdmi_priv *
167 drm_atomic_helper_connector_hdmi_init(struct kunit *test,
168 				      unsigned int formats,
169 				      unsigned int max_bpc)
170 {
171 	struct drm_atomic_helper_connector_hdmi_priv *priv;
172 	struct drm_connector *conn;
173 	struct drm_encoder *enc;
174 	struct drm_device *drm;
175 	struct device *dev;
176 	int ret;
177 
178 	dev = drm_kunit_helper_alloc_device(test);
179 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
180 
181 	priv = drm_kunit_helper_alloc_drm_device(test, dev,
182 						 struct drm_atomic_helper_connector_hdmi_priv, drm,
183 						 DRIVER_MODESET | DRIVER_ATOMIC);
184 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
185 	test->priv = priv;
186 
187 	drm = &priv->drm;
188 	priv->plane = drm_kunit_helper_create_primary_plane(test, drm,
189 							    NULL,
190 							    NULL,
191 							    NULL, 0,
192 							    NULL);
193 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->plane);
194 
195 	priv->crtc = drm_kunit_helper_create_crtc(test, drm,
196 						  priv->plane, NULL,
197 						  NULL,
198 						  NULL);
199 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->crtc);
200 
201 	enc = &priv->encoder;
202 	ret = drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL);
203 	KUNIT_ASSERT_EQ(test, ret, 0);
204 
205 	enc->possible_crtcs = drm_crtc_mask(priv->crtc);
206 
207 	conn = &priv->connector;
208 	ret = drmm_connector_hdmi_init(drm, conn,
209 				       "Vendor", "Product",
210 				       &dummy_connector_funcs,
211 				       &dummy_connector_hdmi_funcs,
212 				       DRM_MODE_CONNECTOR_HDMIA,
213 				       NULL,
214 				       formats,
215 				       max_bpc);
216 	KUNIT_ASSERT_EQ(test, ret, 0);
217 
218 	drm_connector_helper_add(conn, &dummy_connector_helper_funcs);
219 	drm_connector_attach_encoder(conn, enc);
220 
221 	drm_mode_config_reset(drm);
222 
223 	ret = set_connector_edid(test, conn,
224 				 test_edid_hdmi_1080p_rgb_max_200mhz,
225 				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
226 	KUNIT_ASSERT_EQ(test, ret, 0);
227 
228 	return priv;
229 }
230 
231 /*
232  * Test that if we change the RGB quantization property to a different
233  * value, we trigger a mode change on the connector's CRTC, which will
234  * in turn disable/enable the connector.
235  */
236 static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test)
237 {
238 	struct drm_atomic_helper_connector_hdmi_priv *priv;
239 	struct drm_modeset_acquire_ctx *ctx;
240 	struct drm_connector_state *old_conn_state;
241 	struct drm_connector_state *new_conn_state;
242 	struct drm_crtc_state *crtc_state;
243 	struct drm_atomic_state *state;
244 	struct drm_display_mode *preferred;
245 	struct drm_connector *conn;
246 	struct drm_device *drm;
247 	struct drm_crtc *crtc;
248 	int ret;
249 
250 	priv = drm_atomic_helper_connector_hdmi_init(test,
251 						     BIT(HDMI_COLORSPACE_RGB),
252 						     8);
253 	KUNIT_ASSERT_NOT_NULL(test, priv);
254 
255 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
256 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
257 
258 	conn = &priv->connector;
259 	preferred = find_preferred_mode(conn);
260 	KUNIT_ASSERT_NOT_NULL(test, preferred);
261 
262 	drm = &priv->drm;
263 	crtc = priv->crtc;
264 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
265 	KUNIT_ASSERT_EQ(test, ret, 0);
266 
267 	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
268 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
269 
270 	new_conn_state = drm_atomic_get_connector_state(state, conn);
271 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
272 
273 	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
274 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
275 
276 	new_conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
277 
278 	KUNIT_ASSERT_NE(test,
279 			old_conn_state->hdmi.broadcast_rgb,
280 			new_conn_state->hdmi.broadcast_rgb);
281 
282 	ret = drm_atomic_check_only(state);
283 	KUNIT_ASSERT_EQ(test, ret, 0);
284 
285 	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
286 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
287 	KUNIT_EXPECT_EQ(test, new_conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_FULL);
288 
289 	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
290 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
291 	KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed);
292 }
293 
294 /*
295  * Test that if we set the RGB quantization property to the same value,
296  * we don't trigger a mode change on the connector's CRTC and leave the
297  * connector unaffected.
298  */
299 static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *test)
300 {
301 	struct drm_atomic_helper_connector_hdmi_priv *priv;
302 	struct drm_modeset_acquire_ctx *ctx;
303 	struct drm_connector_state *old_conn_state;
304 	struct drm_connector_state *new_conn_state;
305 	struct drm_crtc_state *crtc_state;
306 	struct drm_atomic_state *state;
307 	struct drm_display_mode *preferred;
308 	struct drm_connector *conn;
309 	struct drm_device *drm;
310 	struct drm_crtc *crtc;
311 	int ret;
312 
313 	priv = drm_atomic_helper_connector_hdmi_init(test,
314 						     BIT(HDMI_COLORSPACE_RGB),
315 						     8);
316 	KUNIT_ASSERT_NOT_NULL(test, priv);
317 
318 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
319 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
320 
321 	conn = &priv->connector;
322 	preferred = find_preferred_mode(conn);
323 	KUNIT_ASSERT_NOT_NULL(test, preferred);
324 
325 	drm = &priv->drm;
326 	crtc = priv->crtc;
327 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
328 	KUNIT_ASSERT_EQ(test, ret, 0);
329 
330 	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
331 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
332 
333 	new_conn_state = drm_atomic_get_connector_state(state, conn);
334 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
335 
336 	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
337 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
338 
339 	new_conn_state->hdmi.broadcast_rgb = old_conn_state->hdmi.broadcast_rgb;
340 
341 	ret = drm_atomic_check_only(state);
342 	KUNIT_ASSERT_EQ(test, ret, 0);
343 
344 	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
345 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
346 
347 	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
348 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
349 
350 	KUNIT_EXPECT_EQ(test,
351 			old_conn_state->hdmi.broadcast_rgb,
352 			new_conn_state->hdmi.broadcast_rgb);
353 
354 	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
355 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
356 	KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
357 }
358 
359 /*
360  * Test that for an HDMI connector, with an HDMI monitor, if the
361  * Broadcast RGB property is set to auto with a mode that isn't the
362  * VIC-1 mode, we will get a limited RGB Quantization Range.
363  */
364 static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test)
365 {
366 	struct drm_atomic_helper_connector_hdmi_priv *priv;
367 	struct drm_modeset_acquire_ctx *ctx;
368 	struct drm_connector_state *conn_state;
369 	struct drm_atomic_state *state;
370 	struct drm_display_mode *preferred;
371 	struct drm_connector *conn;
372 	struct drm_device *drm;
373 	struct drm_crtc *crtc;
374 	int ret;
375 
376 	priv = drm_atomic_helper_connector_hdmi_init(test,
377 						     BIT(HDMI_COLORSPACE_RGB),
378 						     8);
379 	KUNIT_ASSERT_NOT_NULL(test, priv);
380 
381 	conn = &priv->connector;
382 	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
383 
384 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
385 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
386 
387 	preferred = find_preferred_mode(conn);
388 	KUNIT_ASSERT_NOT_NULL(test, preferred);
389 	KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
390 
391 	drm = &priv->drm;
392 	crtc = priv->crtc;
393 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
394 	KUNIT_ASSERT_EQ(test, ret, 0);
395 
396 	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
397 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
398 
399 	conn_state = drm_atomic_get_connector_state(state, conn);
400 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
401 
402 	KUNIT_ASSERT_EQ(test,
403 			conn_state->hdmi.broadcast_rgb,
404 			DRM_HDMI_BROADCAST_RGB_AUTO);
405 
406 	ret = drm_atomic_check_only(state);
407 	KUNIT_ASSERT_EQ(test, ret, 0);
408 
409 	conn_state = drm_atomic_get_connector_state(state, conn);
410 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
411 
412 	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
413 }
414 
415 /*
416  * Test that for an HDMI connector, with an HDMI monitor, if the
417  * Broadcast RGB property is set to auto with a VIC-1 mode, we will get
418  * a full RGB Quantization Range.
419  */
420 static 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 the
473  * Broadcast RGB property is set to full with a mode that isn't the
474  * VIC-1 mode, we will get a full RGB Quantization Range.
475  */
476 static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test)
477 {
478 	struct drm_atomic_helper_connector_hdmi_priv *priv;
479 	struct drm_modeset_acquire_ctx *ctx;
480 	struct drm_connector_state *conn_state;
481 	struct drm_atomic_state *state;
482 	struct drm_display_mode *preferred;
483 	struct drm_connector *conn;
484 	struct drm_device *drm;
485 	struct drm_crtc *crtc;
486 	int ret;
487 
488 	priv = drm_atomic_helper_connector_hdmi_init(test,
489 						     BIT(HDMI_COLORSPACE_RGB),
490 						     8);
491 	KUNIT_ASSERT_NOT_NULL(test, priv);
492 
493 	conn = &priv->connector;
494 	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
495 
496 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
497 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
498 
499 	preferred = find_preferred_mode(conn);
500 	KUNIT_ASSERT_NOT_NULL(test, preferred);
501 	KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
502 
503 	drm = &priv->drm;
504 	crtc = priv->crtc;
505 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
506 	KUNIT_ASSERT_EQ(test, ret, 0);
507 
508 	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
509 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
510 
511 	conn_state = drm_atomic_get_connector_state(state, conn);
512 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
513 
514 	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
515 
516 	ret = drm_atomic_check_only(state);
517 	KUNIT_ASSERT_EQ(test, ret, 0);
518 
519 	conn_state = drm_atomic_get_connector_state(state, conn);
520 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
521 
522 	KUNIT_ASSERT_EQ(test,
523 			conn_state->hdmi.broadcast_rgb,
524 			DRM_HDMI_BROADCAST_RGB_FULL);
525 
526 	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range);
527 }
528 
529 /*
530  * Test that for an HDMI connector, with an HDMI monitor, if the
531  * Broadcast RGB property is set to full with a VIC-1 mode, we will get
532  * a full RGB Quantization Range.
533  */
534 static 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 the
589  * Broadcast RGB property is set to limited with a mode that isn't the
590  * VIC-1 mode, we will get a limited RGB Quantization Range.
591  */
592 static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test)
593 {
594 	struct drm_atomic_helper_connector_hdmi_priv *priv;
595 	struct drm_modeset_acquire_ctx *ctx;
596 	struct drm_connector_state *conn_state;
597 	struct drm_atomic_state *state;
598 	struct drm_display_mode *preferred;
599 	struct drm_connector *conn;
600 	struct drm_device *drm;
601 	struct drm_crtc *crtc;
602 	int ret;
603 
604 	priv = drm_atomic_helper_connector_hdmi_init(test,
605 						     BIT(HDMI_COLORSPACE_RGB),
606 						     8);
607 	KUNIT_ASSERT_NOT_NULL(test, priv);
608 
609 	conn = &priv->connector;
610 	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
611 
612 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
613 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
614 
615 	preferred = find_preferred_mode(conn);
616 	KUNIT_ASSERT_NOT_NULL(test, preferred);
617 	KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
618 
619 	drm = &priv->drm;
620 	crtc = priv->crtc;
621 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
622 	KUNIT_ASSERT_EQ(test, ret, 0);
623 
624 	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
625 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
626 
627 	conn_state = drm_atomic_get_connector_state(state, conn);
628 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
629 
630 	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
631 
632 	ret = drm_atomic_check_only(state);
633 	KUNIT_ASSERT_EQ(test, ret, 0);
634 
635 	conn_state = drm_atomic_get_connector_state(state, conn);
636 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
637 
638 	KUNIT_ASSERT_EQ(test,
639 			conn_state->hdmi.broadcast_rgb,
640 			DRM_HDMI_BROADCAST_RGB_LIMITED);
641 
642 	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
643 }
644 
645 /*
646  * Test that for an HDMI connector, with an HDMI monitor, if the
647  * Broadcast RGB property is set to limited with a VIC-1 mode, we will
648  * get a limited RGB Quantization Range.
649  */
650 static 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 turn
706  * disable/enable the connector.
707  */
708 static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)
709 {
710 	struct drm_atomic_helper_connector_hdmi_priv *priv;
711 	struct drm_modeset_acquire_ctx *ctx;
712 	struct drm_connector_state *old_conn_state;
713 	struct drm_connector_state *new_conn_state;
714 	struct drm_crtc_state *crtc_state;
715 	struct drm_atomic_state *state;
716 	struct drm_display_mode *preferred;
717 	struct drm_connector *conn;
718 	struct drm_device *drm;
719 	struct drm_crtc *crtc;
720 	int ret;
721 
722 	priv = drm_atomic_helper_connector_hdmi_init(test,
723 						     BIT(HDMI_COLORSPACE_RGB),
724 						     10);
725 	KUNIT_ASSERT_NOT_NULL(test, priv);
726 
727 	conn = &priv->connector;
728 	ret = set_connector_edid(test, conn,
729 				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
730 				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
731 	KUNIT_ASSERT_EQ(test, ret, 0);
732 
733 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
734 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
735 
736 	preferred = find_preferred_mode(conn);
737 	KUNIT_ASSERT_NOT_NULL(test, preferred);
738 
739 	drm = &priv->drm;
740 	crtc = priv->crtc;
741 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
742 	KUNIT_ASSERT_EQ(test, ret, 0);
743 
744 	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
745 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
746 
747 	new_conn_state = drm_atomic_get_connector_state(state, conn);
748 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
749 
750 	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
751 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
752 
753 	new_conn_state->max_requested_bpc = 8;
754 
755 	KUNIT_ASSERT_NE(test,
756 			old_conn_state->max_requested_bpc,
757 			new_conn_state->max_requested_bpc);
758 
759 	ret = drm_atomic_check_only(state);
760 	KUNIT_ASSERT_EQ(test, ret, 0);
761 
762 	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
763 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
764 
765 	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
766 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
767 
768 	KUNIT_ASSERT_NE(test,
769 			old_conn_state->hdmi.output_bpc,
770 			new_conn_state->hdmi.output_bpc);
771 
772 	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
773 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
774 	KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed);
775 }
776 
777 /*
778  * Test that if we set the output bpc property to the same value, we
779  * don't trigger a mode change on the connector's CRTC and leave the
780  * connector unaffected.
781  */
782 static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
783 {
784 	struct drm_atomic_helper_connector_hdmi_priv *priv;
785 	struct drm_modeset_acquire_ctx *ctx;
786 	struct drm_connector_state *old_conn_state;
787 	struct drm_connector_state *new_conn_state;
788 	struct drm_crtc_state *crtc_state;
789 	struct drm_atomic_state *state;
790 	struct drm_display_mode *preferred;
791 	struct drm_connector *conn;
792 	struct drm_device *drm;
793 	struct drm_crtc *crtc;
794 	int ret;
795 
796 	priv = drm_atomic_helper_connector_hdmi_init(test,
797 						     BIT(HDMI_COLORSPACE_RGB),
798 						     10);
799 	KUNIT_ASSERT_NOT_NULL(test, priv);
800 
801 	conn = &priv->connector;
802 	ret = set_connector_edid(test, conn,
803 				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
804 				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
805 	KUNIT_ASSERT_EQ(test, ret, 0);
806 
807 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
808 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
809 
810 	preferred = find_preferred_mode(conn);
811 	KUNIT_ASSERT_NOT_NULL(test, preferred);
812 
813 	drm = &priv->drm;
814 	crtc = priv->crtc;
815 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
816 	KUNIT_ASSERT_EQ(test, ret, 0);
817 
818 	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
819 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
820 
821 	new_conn_state = drm_atomic_get_connector_state(state, conn);
822 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
823 
824 	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
825 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
826 
827 	KUNIT_ASSERT_EQ(test,
828 			new_conn_state->hdmi.output_bpc,
829 			old_conn_state->hdmi.output_bpc);
830 
831 	ret = drm_atomic_check_only(state);
832 	KUNIT_ASSERT_EQ(test, ret, 0);
833 
834 	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
835 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
836 
837 	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
838 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
839 
840 	KUNIT_EXPECT_EQ(test,
841 			old_conn_state->hdmi.output_bpc,
842 			new_conn_state->hdmi.output_bpc);
843 
844 	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
845 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
846 	KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
847 }
848 
849 /*
850  * Test that if we have an HDMI connector but a !HDMI display, we always
851  * output RGB with 8 bpc.
852  */
853 static void drm_test_check_output_bpc_dvi(struct kunit *test)
854 {
855 	struct drm_atomic_helper_connector_hdmi_priv *priv;
856 	struct drm_modeset_acquire_ctx *ctx;
857 	struct drm_connector_state *conn_state;
858 	struct drm_display_info *info;
859 	struct drm_display_mode *preferred;
860 	struct drm_connector *conn;
861 	struct drm_device *drm;
862 	struct drm_crtc *crtc;
863 	int ret;
864 
865 	priv = drm_atomic_helper_connector_hdmi_init(test,
866 						     BIT(HDMI_COLORSPACE_RGB) |
867 						     BIT(HDMI_COLORSPACE_YUV422) |
868 						     BIT(HDMI_COLORSPACE_YUV444),
869 						     12);
870 	KUNIT_ASSERT_NOT_NULL(test, priv);
871 
872 	conn = &priv->connector;
873 	ret = set_connector_edid(test, conn,
874 				 test_edid_dvi_1080p,
875 				 ARRAY_SIZE(test_edid_dvi_1080p));
876 	KUNIT_ASSERT_EQ(test, ret, 0);
877 
878 	info = &conn->display_info;
879 	KUNIT_ASSERT_FALSE(test, info->is_hdmi);
880 
881 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
882 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
883 
884 	preferred = find_preferred_mode(conn);
885 	KUNIT_ASSERT_NOT_NULL(test, preferred);
886 
887 	drm = &priv->drm;
888 	crtc = priv->crtc;
889 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
890 	KUNIT_ASSERT_EQ(test, ret, 0);
891 
892 	conn_state = conn->state;
893 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
894 
895 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
896 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
897 }
898 
899 /*
900  * Test that when doing a commit which would use RGB 8bpc, the TMDS
901  * clock rate stored in the connector state is equal to the mode clock
902  */
903 static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test)
904 {
905 	struct drm_atomic_helper_connector_hdmi_priv *priv;
906 	struct drm_modeset_acquire_ctx *ctx;
907 	struct drm_connector_state *conn_state;
908 	struct drm_display_mode *preferred;
909 	struct drm_connector *conn;
910 	struct drm_device *drm;
911 	struct drm_crtc *crtc;
912 	int ret;
913 
914 	priv = drm_atomic_helper_connector_hdmi_init(test,
915 						     BIT(HDMI_COLORSPACE_RGB),
916 						     8);
917 	KUNIT_ASSERT_NOT_NULL(test, priv);
918 
919 	conn = &priv->connector;
920 	ret = set_connector_edid(test, conn,
921 				 test_edid_hdmi_1080p_rgb_max_200mhz,
922 				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
923 	KUNIT_ASSERT_EQ(test, ret, 0);
924 
925 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
926 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
927 
928 	preferred = find_preferred_mode(conn);
929 	KUNIT_ASSERT_NOT_NULL(test, preferred);
930 	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
931 
932 	drm = &priv->drm;
933 	crtc = priv->crtc;
934 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
935 	KUNIT_ASSERT_EQ(test, ret, 0);
936 
937 	conn_state = conn->state;
938 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
939 
940 	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 8);
941 	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
942 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1000);
943 }
944 
945 /*
946  * Test that when doing a commit which would use RGB 10bpc, the TMDS
947  * clock rate stored in the connector state is equal to 1.25 times the
948  * mode pixel clock
949  */
950 static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test)
951 {
952 	struct drm_atomic_helper_connector_hdmi_priv *priv;
953 	struct drm_modeset_acquire_ctx *ctx;
954 	struct drm_connector_state *conn_state;
955 	struct drm_display_mode *preferred;
956 	struct drm_connector *conn;
957 	struct drm_device *drm;
958 	struct drm_crtc *crtc;
959 	int ret;
960 
961 	priv = drm_atomic_helper_connector_hdmi_init(test,
962 						     BIT(HDMI_COLORSPACE_RGB),
963 						     10);
964 	KUNIT_ASSERT_NOT_NULL(test, priv);
965 
966 	conn = &priv->connector;
967 	ret = set_connector_edid(test, conn,
968 				 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
969 				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
970 	KUNIT_ASSERT_EQ(test, ret, 0);
971 
972 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
973 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
974 
975 	preferred = find_preferred_mode(conn);
976 	KUNIT_ASSERT_NOT_NULL(test, preferred);
977 	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
978 
979 	drm = &priv->drm;
980 	crtc = priv->crtc;
981 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
982 	KUNIT_ASSERT_EQ(test, ret, 0);
983 
984 	conn_state = conn->state;
985 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
986 
987 	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 10);
988 	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
989 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250);
990 }
991 
992 /*
993  * Test that when doing a commit which would use RGB 12bpc, the TMDS
994  * clock rate stored in the connector state is equal to 1.5 times the
995  * mode pixel clock
996  */
997 static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test)
998 {
999 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1000 	struct drm_modeset_acquire_ctx *ctx;
1001 	struct drm_connector_state *conn_state;
1002 	struct drm_display_mode *preferred;
1003 	struct drm_connector *conn;
1004 	struct drm_device *drm;
1005 	struct drm_crtc *crtc;
1006 	int ret;
1007 
1008 	priv = drm_atomic_helper_connector_hdmi_init(test,
1009 						     BIT(HDMI_COLORSPACE_RGB),
1010 						     12);
1011 	KUNIT_ASSERT_NOT_NULL(test, priv);
1012 
1013 	conn = &priv->connector;
1014 	ret = set_connector_edid(test, conn,
1015 				 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
1016 				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
1017 	KUNIT_ASSERT_EQ(test, ret, 0);
1018 
1019 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1020 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1021 
1022 	preferred = find_preferred_mode(conn);
1023 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1024 	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
1025 
1026 	drm = &priv->drm;
1027 	crtc = priv->crtc;
1028 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1029 	KUNIT_ASSERT_EQ(test, ret, 0);
1030 
1031 	conn_state = conn->state;
1032 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1033 
1034 	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 12);
1035 	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1036 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1500);
1037 }
1038 
1039 /*
1040  * Test that if we filter a rate through our hook, it's indeed rejected
1041  * by the whole atomic_check logic.
1042  *
1043  * We do so by first doing a commit on the pipeline to make sure that it
1044  * works, change the HDMI helpers pointer, and then try the same commit
1045  * again to see if it fails as it should.
1046  */
1047 static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test)
1048 {
1049 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1050 	struct drm_modeset_acquire_ctx *ctx;
1051 	struct drm_atomic_state *state;
1052 	struct drm_display_mode *preferred;
1053 	struct drm_crtc_state *crtc_state;
1054 	struct drm_connector *conn;
1055 	struct drm_device *drm;
1056 	struct drm_crtc *crtc;
1057 	int ret;
1058 
1059 	priv = drm_atomic_helper_connector_hdmi_init(test,
1060 						     BIT(HDMI_COLORSPACE_RGB),
1061 						     8);
1062 	KUNIT_ASSERT_NOT_NULL(test, priv);
1063 
1064 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1065 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1066 
1067 	conn = &priv->connector;
1068 	preferred = find_preferred_mode(conn);
1069 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1070 
1071 	drm = &priv->drm;
1072 	crtc = priv->crtc;
1073 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1074 	KUNIT_ASSERT_EQ(test, ret, 0);
1075 
1076 	/* You shouldn't be doing that at home. */
1077 	conn->hdmi.funcs = &reject_connector_hdmi_funcs;
1078 
1079 	state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
1080 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
1081 
1082 	crtc_state = drm_atomic_get_crtc_state(state, crtc);
1083 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
1084 
1085 	crtc_state->connectors_changed = true;
1086 
1087 	ret = drm_atomic_check_only(state);
1088 	KUNIT_EXPECT_LT(test, ret, 0);
1089 }
1090 
1091 /*
1092  * Test that if:
1093  * - We have an HDMI connector supporting RGB only
1094  * - The chosen mode has a TMDS character rate higher than the display
1095  *   supports in RGB/12bpc
1096  * - The chosen mode has a TMDS character rate lower than the display
1097  *   supports in RGB/10bpc.
1098  *
1099  * Then we will pick the latter, and the computed TMDS character rate
1100  * will be equal to 1.25 times the mode pixel clock.
1101  */
1102 static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test)
1103 {
1104 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1105 	struct drm_modeset_acquire_ctx *ctx;
1106 	struct drm_connector_state *conn_state;
1107 	struct drm_display_info *info;
1108 	struct drm_display_mode *preferred;
1109 	unsigned long long rate;
1110 	struct drm_connector *conn;
1111 	struct drm_device *drm;
1112 	struct drm_crtc *crtc;
1113 	int ret;
1114 
1115 	priv = drm_atomic_helper_connector_hdmi_init(test,
1116 						     BIT(HDMI_COLORSPACE_RGB),
1117 						     12);
1118 	KUNIT_ASSERT_NOT_NULL(test, priv);
1119 
1120 	conn = &priv->connector;
1121 	ret = set_connector_edid(test, conn,
1122 				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
1123 				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
1124 	KUNIT_ASSERT_EQ(test, ret, 0);
1125 
1126 	info = &conn->display_info;
1127 	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1128 	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1129 
1130 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1131 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1132 
1133 	preferred = find_preferred_mode(conn);
1134 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1135 	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
1136 
1137 	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1138 	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1139 
1140 	rate = drm_hdmi_compute_mode_clock(preferred, 10, HDMI_COLORSPACE_RGB);
1141 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1142 
1143 	drm = &priv->drm;
1144 	crtc = priv->crtc;
1145 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1146 	KUNIT_EXPECT_EQ(test, ret, 0);
1147 
1148 	conn_state = conn->state;
1149 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1150 
1151 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10);
1152 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1153 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250);
1154 }
1155 
1156 /*
1157  * Test that if:
1158  * - We have an HDMI connector supporting both RGB and YUV422 and up to
1159  *   12 bpc
1160  * - The chosen mode has a TMDS character rate higher than the display
1161  *   supports in RGB/12bpc but lower than the display supports in
1162  *   RGB/10bpc
1163  * - The chosen mode has a TMDS character rate lower than the display
1164  *   supports in YUV422/12bpc.
1165  *
1166  * Then we will prefer to keep the RGB format with a lower bpc over
1167  * picking YUV422.
1168  */
1169 static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test)
1170 {
1171 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1172 	struct drm_modeset_acquire_ctx *ctx;
1173 	struct drm_connector_state *conn_state;
1174 	struct drm_display_info *info;
1175 	struct drm_display_mode *preferred;
1176 	unsigned long long rate;
1177 	struct drm_connector *conn;
1178 	struct drm_device *drm;
1179 	struct drm_crtc *crtc;
1180 	int ret;
1181 
1182 	priv = drm_atomic_helper_connector_hdmi_init(test,
1183 						     BIT(HDMI_COLORSPACE_RGB) |
1184 						     BIT(HDMI_COLORSPACE_YUV422) |
1185 						     BIT(HDMI_COLORSPACE_YUV444),
1186 						     12);
1187 	KUNIT_ASSERT_NOT_NULL(test, priv);
1188 
1189 	conn = &priv->connector;
1190 	ret = set_connector_edid(test, conn,
1191 				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
1192 				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
1193 	KUNIT_ASSERT_EQ(test, ret, 0);
1194 
1195 	info = &conn->display_info;
1196 	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1197 	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1198 
1199 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1200 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1201 
1202 	preferred = find_preferred_mode(conn);
1203 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1204 	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
1205 
1206 	rate = drm_hdmi_compute_mode_clock(preferred, 10, HDMI_COLORSPACE_RGB);
1207 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1208 
1209 	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1210 	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1211 
1212 	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
1213 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1214 
1215 	drm = &priv->drm;
1216 	crtc = priv->crtc;
1217 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1218 	KUNIT_EXPECT_EQ(test, ret, 0);
1219 
1220 	conn_state = conn->state;
1221 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1222 
1223 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10);
1224 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1225 }
1226 
1227 /*
1228  * Test that if a driver and screen supports RGB and YUV formats, and we
1229  * try to set the VIC 1 mode, we end up with 8bpc RGB even if we could
1230  * have had a higher bpc.
1231  */
1232 static 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 invalid
1272 	 * configuration.
1273 	 *
1274 	 * Thus, we have to calculate the rate by hand.
1275 	 */
1276 	rate = mode->clock * 1500;
1277 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1278 
1279 	drm = &priv->drm;
1280 	crtc = priv->crtc;
1281 	ret = light_up_connector(test, drm, crtc, conn, mode, ctx);
1282 	KUNIT_EXPECT_EQ(test, ret, 0);
1283 
1284 	conn_state = conn->state;
1285 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1286 
1287 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
1288 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1289 }
1290 
1291 /*
1292  * Test that if a driver supports only RGB but the screen also supports
1293  * YUV formats, we only end up with an RGB format.
1294  */
1295 static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test)
1296 {
1297 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1298 	struct drm_modeset_acquire_ctx *ctx;
1299 	struct drm_connector_state *conn_state;
1300 	struct drm_display_info *info;
1301 	struct drm_display_mode *preferred;
1302 	unsigned long long rate;
1303 	struct drm_connector *conn;
1304 	struct drm_device *drm;
1305 	struct drm_crtc *crtc;
1306 	int ret;
1307 
1308 	priv = drm_atomic_helper_connector_hdmi_init(test,
1309 						     BIT(HDMI_COLORSPACE_RGB),
1310 						     12);
1311 	KUNIT_ASSERT_NOT_NULL(test, priv);
1312 
1313 	conn = &priv->connector;
1314 	ret = set_connector_edid(test, conn,
1315 				 test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz,
1316 				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz));
1317 	KUNIT_ASSERT_EQ(test, ret, 0);
1318 
1319 	info = &conn->display_info;
1320 	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1321 	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1322 
1323 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1324 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1325 
1326 	preferred = find_preferred_mode(conn);
1327 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1328 
1329 	/*
1330 	 * We're making sure that YUV422 would be the preferred option
1331 	 * here: we're always favouring higher bpc, we can't have RGB
1332 	 * because the TMDS character rate exceeds the maximum supported
1333 	 * by the display, and YUV422 works for that display.
1334 	 *
1335 	 * But since the driver only supports RGB, we should fallback to
1336 	 * a lower bpc with RGB.
1337 	 */
1338 	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1339 	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1340 
1341 	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
1342 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1343 
1344 	drm = &priv->drm;
1345 	crtc = priv->crtc;
1346 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1347 	KUNIT_EXPECT_EQ(test, ret, 0);
1348 
1349 	conn_state = conn->state;
1350 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1351 
1352 	KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12);
1353 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1354 }
1355 
1356 /*
1357  * Test that if a screen supports only RGB but the driver also supports
1358  * YUV formats, we only end up with an RGB format.
1359  */
1360 static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test)
1361 {
1362 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1363 	struct drm_modeset_acquire_ctx *ctx;
1364 	struct drm_connector_state *conn_state;
1365 	struct drm_display_info *info;
1366 	struct drm_display_mode *preferred;
1367 	unsigned long long rate;
1368 	struct drm_connector *conn;
1369 	struct drm_device *drm;
1370 	struct drm_crtc *crtc;
1371 	int ret;
1372 
1373 	priv = drm_atomic_helper_connector_hdmi_init(test,
1374 						     BIT(HDMI_COLORSPACE_RGB) |
1375 						     BIT(HDMI_COLORSPACE_YUV422) |
1376 						     BIT(HDMI_COLORSPACE_YUV444),
1377 						     12);
1378 	KUNIT_ASSERT_NOT_NULL(test, priv);
1379 
1380 	conn = &priv->connector;
1381 	ret = set_connector_edid(test, conn,
1382 				 test_edid_hdmi_1080p_rgb_max_200mhz,
1383 				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
1384 	KUNIT_ASSERT_EQ(test, ret, 0);
1385 
1386 	info = &conn->display_info;
1387 	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1388 	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1389 
1390 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1391 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1392 
1393 	preferred = find_preferred_mode(conn);
1394 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1395 
1396 	/*
1397 	 * We're making sure that YUV422 would be the preferred option
1398 	 * here: we're always favouring higher bpc, we can't have RGB
1399 	 * because the TMDS character rate exceeds the maximum supported
1400 	 * by the display, and YUV422 works for that display.
1401 	 *
1402 	 * But since the display only supports RGB, we should fallback to
1403 	 * a lower bpc with RGB.
1404 	 */
1405 	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1406 	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1407 
1408 	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_YUV422);
1409 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1410 
1411 	drm = &priv->drm;
1412 	crtc = priv->crtc;
1413 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1414 	KUNIT_EXPECT_EQ(test, ret, 0);
1415 
1416 	conn_state = conn->state;
1417 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1418 
1419 	KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12);
1420 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1421 }
1422 
1423 /*
1424  * Test that if a display supports higher bpc but the driver only
1425  * supports 8 bpc, we only end up with 8 bpc even if we could have had a
1426  * higher bpc.
1427  */
1428 static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test)
1429 {
1430 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1431 	struct drm_modeset_acquire_ctx *ctx;
1432 	struct drm_connector_state *conn_state;
1433 	struct drm_display_info *info;
1434 	struct drm_display_mode *preferred;
1435 	unsigned long long rate;
1436 	struct drm_connector *conn;
1437 	struct drm_device *drm;
1438 	struct drm_crtc *crtc;
1439 	int ret;
1440 
1441 	priv = drm_atomic_helper_connector_hdmi_init(test,
1442 						     BIT(HDMI_COLORSPACE_RGB),
1443 						     8);
1444 	KUNIT_ASSERT_NOT_NULL(test, priv);
1445 
1446 	conn = &priv->connector;
1447 	ret = set_connector_edid(test, conn,
1448 				 test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz,
1449 				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz));
1450 	KUNIT_ASSERT_EQ(test, ret, 0);
1451 
1452 	info = &conn->display_info;
1453 	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1454 	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1455 
1456 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1457 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1458 
1459 	preferred = find_preferred_mode(conn);
1460 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1461 
1462 	/*
1463 	 * We're making sure that we have headroom on the TMDS character
1464 	 * clock to actually use 12bpc.
1465 	 */
1466 	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1467 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1468 
1469 	drm = &priv->drm;
1470 	crtc = priv->crtc;
1471 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1472 	KUNIT_EXPECT_EQ(test, ret, 0);
1473 
1474 	conn_state = conn->state;
1475 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1476 
1477 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
1478 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1479 }
1480 
1481 /*
1482  * Test that if a driver supports higher bpc but the display only
1483  * supports 8 bpc, we only end up with 8 bpc even if we could have had a
1484  * higher bpc.
1485  */
1486 static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *test)
1487 {
1488 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1489 	struct drm_modeset_acquire_ctx *ctx;
1490 	struct drm_connector_state *conn_state;
1491 	struct drm_display_info *info;
1492 	struct drm_display_mode *preferred;
1493 	unsigned long long rate;
1494 	struct drm_connector *conn;
1495 	struct drm_device *drm;
1496 	struct drm_crtc *crtc;
1497 	int ret;
1498 
1499 	priv = drm_atomic_helper_connector_hdmi_init(test,
1500 						     BIT(HDMI_COLORSPACE_RGB) |
1501 						     BIT(HDMI_COLORSPACE_YUV422) |
1502 						     BIT(HDMI_COLORSPACE_YUV444),
1503 						     12);
1504 	KUNIT_ASSERT_NOT_NULL(test, priv);
1505 
1506 	conn = &priv->connector;
1507 	ret = set_connector_edid(test, conn,
1508 				 test_edid_hdmi_1080p_rgb_max_340mhz,
1509 				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_340mhz));
1510 	KUNIT_ASSERT_EQ(test, ret, 0);
1511 
1512 	info = &conn->display_info;
1513 	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1514 	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1515 
1516 	ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1517 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1518 
1519 	preferred = find_preferred_mode(conn);
1520 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1521 
1522 	/*
1523 	 * We're making sure that we have headroom on the TMDS character
1524 	 * clock to actually use 12bpc.
1525 	 */
1526 	rate = drm_hdmi_compute_mode_clock(preferred, 12, HDMI_COLORSPACE_RGB);
1527 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1528 
1529 	drm = &priv->drm;
1530 	crtc = priv->crtc;
1531 	ret = light_up_connector(test, drm, crtc, conn, preferred, ctx);
1532 	KUNIT_EXPECT_EQ(test, ret, 0);
1533 
1534 	conn_state = conn->state;
1535 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1536 
1537 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
1538 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, HDMI_COLORSPACE_RGB);
1539 }
1540 
1541 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
1542 	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode),
1543 	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1),
1544 	KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode),
1545 	KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode_vic_1),
1546 	KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode),
1547 	KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode_vic_1),
1548 	/*
1549 	 * TODO: When we'll have YUV output support, we need to check
1550 	 * that the limited range is always set to limited no matter
1551 	 * what the value of Broadcast RGB is.
1552 	 */
1553 	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed),
1554 	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed),
1555 	KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate),
1556 	KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback),
1557 	KUNIT_CASE(drm_test_check_max_tmds_rate_format_fallback),
1558 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
1559 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
1560 	KUNIT_CASE(drm_test_check_output_bpc_dvi),
1561 	KUNIT_CASE(drm_test_check_output_bpc_format_vic_1),
1562 	KUNIT_CASE(drm_test_check_output_bpc_format_display_8bpc_only),
1563 	KUNIT_CASE(drm_test_check_output_bpc_format_display_rgb_only),
1564 	KUNIT_CASE(drm_test_check_output_bpc_format_driver_8bpc_only),
1565 	KUNIT_CASE(drm_test_check_output_bpc_format_driver_rgb_only),
1566 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc),
1567 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_10bpc),
1568 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_12bpc),
1569 	/*
1570 	 * TODO: We should have tests to check that a change in the
1571 	 * format triggers a CRTC mode change just like we do for the
1572 	 * RGB Quantization and BPC.
1573 	 *
1574 	 * However, we don't have any way to control which format gets
1575 	 * picked up aside from changing the BPC or mode which would
1576 	 * already trigger a mode change.
1577 	 */
1578 	{ }
1579 };
1580 
1581 static struct kunit_suite drm_atomic_helper_connector_hdmi_check_test_suite = {
1582 	.name		= "drm_atomic_helper_connector_hdmi_check",
1583 	.test_cases	= drm_atomic_helper_connector_hdmi_check_tests,
1584 };
1585 
1586 /*
1587  * Test that the value of the Broadcast RGB property out of reset is set
1588  * to auto.
1589  */
1590 static void drm_test_check_broadcast_rgb_value(struct kunit *test)
1591 {
1592 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1593 	struct drm_connector_state *conn_state;
1594 	struct drm_connector *conn;
1595 
1596 	priv = drm_atomic_helper_connector_hdmi_init(test,
1597 						     BIT(HDMI_COLORSPACE_RGB),
1598 						     8);
1599 	KUNIT_ASSERT_NOT_NULL(test, priv);
1600 
1601 	conn = &priv->connector;
1602 	conn_state = conn->state;
1603 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_AUTO);
1604 }
1605 
1606 /*
1607  * Test that if the connector was initialised with a maximum bpc of 8,
1608  * the value of the max_bpc and max_requested_bpc properties out of
1609  * reset are also set to 8, and output_bpc is set to 0 and will be
1610  * filled at atomic_check time.
1611  */
1612 static void drm_test_check_bpc_8_value(struct kunit *test)
1613 {
1614 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1615 	struct drm_connector_state *conn_state;
1616 	struct drm_connector *conn;
1617 
1618 	priv = drm_atomic_helper_connector_hdmi_init(test,
1619 						     BIT(HDMI_COLORSPACE_RGB),
1620 						     8);
1621 	KUNIT_ASSERT_NOT_NULL(test, priv);
1622 
1623 	conn = &priv->connector;
1624 	conn_state = conn->state;
1625 	KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 8);
1626 	KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 8);
1627 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
1628 }
1629 
1630 /*
1631  * Test that if the connector was initialised with a maximum bpc of 10,
1632  * the value of the max_bpc and max_requested_bpc properties out of
1633  * reset are also set to 10, and output_bpc is set to 0 and will be
1634  * filled at atomic_check time.
1635  */
1636 static void drm_test_check_bpc_10_value(struct kunit *test)
1637 {
1638 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1639 	struct drm_connector_state *conn_state;
1640 	struct drm_connector *conn;
1641 
1642 	priv = drm_atomic_helper_connector_hdmi_init(test,
1643 						     BIT(HDMI_COLORSPACE_RGB),
1644 						     10);
1645 	KUNIT_ASSERT_NOT_NULL(test, priv);
1646 
1647 	conn = &priv->connector;
1648 	conn_state = conn->state;
1649 	KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 10);
1650 	KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 10);
1651 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
1652 }
1653 
1654 /*
1655  * Test that if the connector was initialised with a maximum bpc of 12,
1656  * the value of the max_bpc and max_requested_bpc properties out of
1657  * reset are also set to 12, and output_bpc is set to 0 and will be
1658  * filled at atomic_check time.
1659  */
1660 static void drm_test_check_bpc_12_value(struct kunit *test)
1661 {
1662 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1663 	struct drm_connector_state *conn_state;
1664 	struct drm_connector *conn;
1665 
1666 	priv = drm_atomic_helper_connector_hdmi_init(test,
1667 						     BIT(HDMI_COLORSPACE_RGB),
1668 						     12);
1669 	KUNIT_ASSERT_NOT_NULL(test, priv);
1670 
1671 	conn = &priv->connector;
1672 	conn_state = conn->state;
1673 	KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 12);
1674 	KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 12);
1675 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
1676 }
1677 
1678 /*
1679  * Test that the value of the output format property out of reset is set
1680  * to RGB, even if the driver supports more than that.
1681  */
1682 static void drm_test_check_format_value(struct kunit *test)
1683 {
1684 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1685 	struct drm_connector_state *conn_state;
1686 	struct drm_connector *conn;
1687 
1688 	priv = drm_atomic_helper_connector_hdmi_init(test,
1689 						     BIT(HDMI_COLORSPACE_RGB) |
1690 						     BIT(HDMI_COLORSPACE_YUV422) |
1691 						     BIT(HDMI_COLORSPACE_YUV444),
1692 						     8);
1693 	KUNIT_ASSERT_NOT_NULL(test, priv);
1694 
1695 	conn = &priv->connector;
1696 	conn_state = conn->state;
1697 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, 0);
1698 }
1699 
1700 /*
1701  * Test that the value of the output format property out of reset is set
1702  * to 0, and will be computed at atomic_check time.
1703  */
1704 static 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 
1722 static 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 
1732 static 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 
1737 kunit_test_suites(
1738 	&drm_atomic_helper_connector_hdmi_check_test_suite,
1739 	&drm_atomic_helper_connector_hdmi_reset_test_suite,
1740 );
1741 
1742 MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>");
1743 MODULE_DESCRIPTION("Kunit test for drm_hdmi_state_helper functions");
1744 MODULE_LICENSE("GPL");
1745