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