xref: /linux/drivers/gpu/drm/tests/drm_hdmi_state_helper_test.c (revision 9cebfe6504488198b012e746bc6b313f88b95439)
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 void *current_edid;
37 	size_t current_edid_len;
38 
39 	int hdmi_update_failures;
40 };
41 
42 #define connector_to_priv(c) \
43 	container_of_const(c, struct drm_atomic_helper_connector_hdmi_priv, connector)
44 
45 #define encoder_to_priv(e) \
46 	container_of_const(e, struct drm_atomic_helper_connector_hdmi_priv, encoder)
47 
48 static struct drm_display_mode *find_preferred_mode(struct drm_connector *connector)
49 {
50 	struct drm_device *drm = connector->dev;
51 	struct drm_display_mode *mode, *preferred;
52 
53 	mutex_lock(&drm->mode_config.mutex);
54 	preferred = list_first_entry_or_null(&connector->modes, struct drm_display_mode, head);
55 	list_for_each_entry(mode, &connector->modes, head)
56 		if (mode->type & DRM_MODE_TYPE_PREFERRED)
57 			preferred = mode;
58 	mutex_unlock(&drm->mode_config.mutex);
59 
60 	return preferred;
61 }
62 
63 static struct drm_display_mode *find_420_only_mode(struct drm_connector *connector)
64 {
65 	struct drm_device *drm = connector->dev;
66 	struct drm_display_mode *mode;
67 
68 	mutex_lock(&drm->mode_config.mutex);
69 	list_for_each_entry(mode, &connector->modes, head) {
70 		if (drm_mode_is_420_only(&connector->display_info, mode)) {
71 			mutex_unlock(&drm->mode_config.mutex);
72 			return mode;
73 		}
74 	}
75 	mutex_unlock(&drm->mode_config.mutex);
76 
77 	return NULL;
78 }
79 
80 static struct drm_display_mode *find_420_also_mode(struct drm_connector *connector)
81 {
82 	struct drm_device *drm = connector->dev;
83 	struct drm_display_mode *mode;
84 
85 	mutex_lock(&drm->mode_config.mutex);
86 	list_for_each_entry(mode, &connector->modes, head) {
87 		if (drm_mode_is_420_also(&connector->display_info, mode)) {
88 			mutex_unlock(&drm->mode_config.mutex);
89 			return mode;
90 		}
91 	}
92 	mutex_unlock(&drm->mode_config.mutex);
93 
94 	return NULL;
95 }
96 
97 static int set_connector_edid(struct kunit *test, struct drm_connector *connector,
98 			      const void *edid, size_t edid_len)
99 {
100 	struct drm_atomic_helper_connector_hdmi_priv *priv =
101 		connector_to_priv(connector);
102 	struct drm_device *drm = connector->dev;
103 	int ret;
104 
105 	priv->current_edid = edid;
106 	priv->current_edid_len = edid_len;
107 
108 	mutex_lock(&drm->mode_config.mutex);
109 	ret = connector->funcs->fill_modes(connector, 4096, 4096);
110 	mutex_unlock(&drm->mode_config.mutex);
111 
112 	return ret;
113 }
114 
115 static int accept_infoframe_clear_infoframe(struct drm_connector *connector)
116 {
117 	return 0;
118 }
119 
120 static int accept_infoframe_write_infoframe(struct drm_connector *connector,
121 					    const u8 *buffer, size_t len)
122 {
123 	return 0;
124 }
125 
126 static const struct drm_connector_hdmi_funcs dummy_connector_hdmi_funcs = {
127 	.avi = {
128 		.clear_infoframe = accept_infoframe_clear_infoframe,
129 		.write_infoframe = accept_infoframe_write_infoframe,
130 	},
131 	.hdmi = {
132 		.clear_infoframe = accept_infoframe_clear_infoframe,
133 		.write_infoframe = accept_infoframe_write_infoframe,
134 	},
135 };
136 
137 static enum drm_mode_status
138 reject_connector_tmds_char_rate_valid(const struct drm_connector *connector,
139 				      const struct drm_display_mode *mode,
140 				      unsigned long long tmds_rate)
141 {
142 	return MODE_BAD;
143 }
144 
145 static const struct drm_connector_hdmi_funcs reject_connector_hdmi_funcs = {
146 	.tmds_char_rate_valid	= reject_connector_tmds_char_rate_valid,
147 	.avi = {
148 		.clear_infoframe = accept_infoframe_clear_infoframe,
149 		.write_infoframe = accept_infoframe_write_infoframe,
150 	},
151 	.hdmi = {
152 		.clear_infoframe = accept_infoframe_clear_infoframe,
153 		.write_infoframe = accept_infoframe_write_infoframe,
154 	},
155 };
156 
157 static enum drm_mode_status
158 reject_100mhz_connector_tmds_char_rate_valid(const struct drm_connector *connector,
159 					     const struct drm_display_mode *mode,
160 					     unsigned long long tmds_rate)
161 {
162 	return (tmds_rate > 100ULL * 1000 * 1000) ? MODE_BAD : MODE_OK;
163 }
164 
165 static const struct drm_connector_hdmi_funcs reject_100mhz_connector_hdmi_funcs = {
166 	.tmds_char_rate_valid	= reject_100mhz_connector_tmds_char_rate_valid,
167 	.avi = {
168 		.clear_infoframe = accept_infoframe_clear_infoframe,
169 		.write_infoframe = accept_infoframe_write_infoframe,
170 	},
171 	.hdmi = {
172 		.clear_infoframe = accept_infoframe_clear_infoframe,
173 		.write_infoframe = accept_infoframe_write_infoframe,
174 	},
175 };
176 
177 static int dummy_connector_get_modes(struct drm_connector *connector)
178 {
179 	struct drm_atomic_helper_connector_hdmi_priv *priv =
180 		connector_to_priv(connector);
181 	const struct drm_edid *edid;
182 	unsigned int num_modes;
183 
184 	edid = drm_edid_alloc(priv->current_edid, priv->current_edid_len);
185 	if (!edid)
186 		return -EINVAL;
187 
188 	drm_edid_connector_update(connector, edid);
189 	num_modes = drm_edid_connector_add_modes(connector);
190 
191 	drm_edid_free(edid);
192 
193 	return num_modes;
194 }
195 
196 static const struct drm_connector_helper_funcs dummy_connector_helper_funcs = {
197 	.atomic_check	= drm_atomic_helper_connector_hdmi_check,
198 	.get_modes	= dummy_connector_get_modes,
199 	.mode_valid	= drm_hdmi_connector_mode_valid,
200 };
201 
202 static void dummy_hdmi_connector_reset(struct drm_connector *connector)
203 {
204 	drm_atomic_helper_connector_reset(connector);
205 	__drm_atomic_helper_connector_hdmi_state_init(connector, connector->state);
206 }
207 
208 static const struct drm_connector_funcs dummy_connector_funcs = {
209 	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
210 	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
211 	.fill_modes		= drm_helper_probe_single_connector_modes,
212 	.reset			= dummy_hdmi_connector_reset,
213 };
214 
215 static void test_encoder_atomic_enable(struct drm_encoder *encoder,
216 			      struct drm_atomic_commit *state)
217 {
218 	struct drm_atomic_helper_connector_hdmi_priv *priv =
219 		encoder_to_priv(encoder);
220 	int ret;
221 
222 	ret = drm_atomic_helper_connector_hdmi_update_infoframes(&priv->connector, state);
223 	if (ret)
224 		priv->hdmi_update_failures++;
225 }
226 
227 static const struct drm_encoder_helper_funcs test_encoder_helper_funcs = {
228 	.atomic_enable = test_encoder_atomic_enable,
229 };
230 
231 static
232 struct drm_atomic_helper_connector_hdmi_priv *
233 __connector_hdmi_init(struct kunit *test,
234 		      unsigned int formats,
235 		      unsigned int max_bpc,
236 		      const struct drm_connector_hdmi_funcs *hdmi_funcs,
237 		      const void *edid_data, size_t edid_len)
238 {
239 	struct drm_atomic_helper_connector_hdmi_priv *priv;
240 	struct drm_connector *conn;
241 	struct drm_encoder *enc;
242 	struct drm_device *drm;
243 	struct device *dev;
244 	int ret;
245 
246 	dev = drm_kunit_helper_alloc_device(test);
247 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
248 
249 	priv = drm_kunit_helper_alloc_drm_device(test, dev,
250 						 struct drm_atomic_helper_connector_hdmi_priv, drm,
251 						 DRIVER_MODESET | DRIVER_ATOMIC);
252 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
253 	test->priv = priv;
254 
255 	drm = &priv->drm;
256 	priv->plane = drm_kunit_helper_create_primary_plane(test, drm,
257 							    NULL,
258 							    NULL,
259 							    NULL, 0,
260 							    NULL);
261 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->plane);
262 
263 	priv->crtc = drm_kunit_helper_create_crtc(test, drm,
264 						  priv->plane, NULL,
265 						  NULL,
266 						  NULL);
267 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->crtc);
268 
269 	enc = &priv->encoder;
270 	ret = drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL);
271 	KUNIT_ASSERT_EQ(test, ret, 0);
272 
273 	enc->possible_crtcs = drm_crtc_mask(priv->crtc);
274 
275 	conn = &priv->connector;
276 	conn->ycbcr_420_allowed = !!(formats & BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR420));
277 
278 	ret = drmm_connector_hdmi_init(drm, conn,
279 				       "Vendor", "Product",
280 				       &dummy_connector_funcs,
281 				       hdmi_funcs,
282 				       DRM_MODE_CONNECTOR_HDMIA,
283 				       NULL,
284 				       formats,
285 				       max_bpc);
286 	KUNIT_ASSERT_EQ(test, ret, 0);
287 
288 	drm_connector_helper_add(conn, &dummy_connector_helper_funcs);
289 	drm_connector_attach_encoder(conn, enc);
290 
291 	drm_mode_config_reset(drm);
292 
293 	if (edid_data && edid_len) {
294 		ret = set_connector_edid(test, &priv->connector, edid_data, edid_len);
295 		KUNIT_ASSERT_GT(test, ret, 0);
296 	}
297 
298 	return priv;
299 }
300 
301 #define drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test, formats, max_bpc, funcs, edid) \
302 	__connector_hdmi_init(test, formats, max_bpc, funcs, edid, ARRAY_SIZE(edid))
303 
304 static
305 struct drm_atomic_helper_connector_hdmi_priv *
306 drm_kunit_helper_connector_hdmi_init(struct kunit *test,
307 				     unsigned int formats,
308 				     unsigned int max_bpc)
309 {
310 	return drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
311 				formats,
312 				max_bpc,
313 				&dummy_connector_hdmi_funcs,
314 				test_edid_hdmi_1080p_rgb_max_200mhz);
315 }
316 
317 /*
318  * Test that if we change the RGB quantization property to a different
319  * value, we trigger a mode change on the connector's CRTC, which will
320  * in turn disable/enable the connector.
321  */
322 static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test)
323 {
324 	struct drm_atomic_helper_connector_hdmi_priv *priv;
325 	struct drm_modeset_acquire_ctx ctx;
326 	struct drm_connector_state *old_conn_state;
327 	struct drm_connector_state *new_conn_state;
328 	struct drm_crtc_state *crtc_state;
329 	struct drm_atomic_commit *state;
330 	struct drm_display_mode *preferred;
331 	struct drm_connector *conn;
332 	struct drm_device *drm;
333 	struct drm_crtc *crtc;
334 	int ret;
335 
336 	priv = drm_kunit_helper_connector_hdmi_init(test,
337 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
338 						    8);
339 	KUNIT_ASSERT_NOT_NULL(test, priv);
340 
341 	drm = &priv->drm;
342 	crtc = priv->crtc;
343 	conn = &priv->connector;
344 
345 	preferred = find_preferred_mode(conn);
346 	KUNIT_ASSERT_NOT_NULL(test, preferred);
347 
348 	drm_modeset_acquire_init(&ctx, 0);
349 
350 retry_conn_enable:
351 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
352 						     crtc, conn,
353 						     preferred,
354 						     &ctx);
355 	if (ret == -EDEADLK) {
356 		ret = drm_modeset_backoff(&ctx);
357 		if (!ret)
358 			goto retry_conn_enable;
359 	}
360 	KUNIT_ASSERT_EQ(test, ret, 0);
361 
362 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
363 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
364 
365 	new_conn_state = drm_atomic_get_connector_state(state, conn);
366 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
367 
368 	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
369 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
370 
371 	new_conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
372 
373 	KUNIT_ASSERT_NE(test,
374 			old_conn_state->hdmi.broadcast_rgb,
375 			new_conn_state->hdmi.broadcast_rgb);
376 
377 	ret = drm_atomic_check_only(state);
378 	KUNIT_ASSERT_EQ(test, ret, 0);
379 
380 	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
381 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
382 	KUNIT_EXPECT_EQ(test, new_conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_FULL);
383 
384 	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
385 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
386 	KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed);
387 
388 	drm_modeset_drop_locks(&ctx);
389 	drm_modeset_acquire_fini(&ctx);
390 }
391 
392 /*
393  * Test that if we set the RGB quantization property to the same value,
394  * we don't trigger a mode change on the connector's CRTC and leave the
395  * connector unaffected.
396  */
397 static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *test)
398 {
399 	struct drm_atomic_helper_connector_hdmi_priv *priv;
400 	struct drm_modeset_acquire_ctx ctx;
401 	struct drm_connector_state *old_conn_state;
402 	struct drm_connector_state *new_conn_state;
403 	struct drm_crtc_state *crtc_state;
404 	struct drm_atomic_commit *state;
405 	struct drm_display_mode *preferred;
406 	struct drm_connector *conn;
407 	struct drm_device *drm;
408 	struct drm_crtc *crtc;
409 	int ret;
410 
411 	priv = drm_kunit_helper_connector_hdmi_init(test,
412 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
413 						    8);
414 	KUNIT_ASSERT_NOT_NULL(test, priv);
415 
416 	drm = &priv->drm;
417 	crtc = priv->crtc;
418 	conn = &priv->connector;
419 
420 	preferred = find_preferred_mode(conn);
421 	KUNIT_ASSERT_NOT_NULL(test, preferred);
422 
423 	drm_modeset_acquire_init(&ctx, 0);
424 
425 retry_conn_enable:
426 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
427 						     crtc, conn,
428 						     preferred,
429 						     &ctx);
430 	if (ret == -EDEADLK) {
431 		ret = drm_modeset_backoff(&ctx);
432 		if (!ret)
433 			goto retry_conn_enable;
434 	}
435 	KUNIT_ASSERT_EQ(test, ret, 0);
436 
437 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
438 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
439 
440 	new_conn_state = drm_atomic_get_connector_state(state, conn);
441 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
442 
443 	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
444 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
445 
446 	new_conn_state->hdmi.broadcast_rgb = old_conn_state->hdmi.broadcast_rgb;
447 
448 	ret = drm_atomic_check_only(state);
449 	KUNIT_ASSERT_EQ(test, ret, 0);
450 
451 	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
452 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
453 
454 	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
455 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
456 
457 	KUNIT_EXPECT_EQ(test,
458 			old_conn_state->hdmi.broadcast_rgb,
459 			new_conn_state->hdmi.broadcast_rgb);
460 
461 	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
462 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
463 	KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
464 
465 	drm_modeset_drop_locks(&ctx);
466 	drm_modeset_acquire_fini(&ctx);
467 }
468 
469 /*
470  * Test that for an HDMI connector, with an HDMI monitor, if the
471  * Broadcast RGB property is set to auto with a mode that isn't the
472  * VIC-1 mode, we will get a limited RGB Quantization Range.
473  */
474 static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test)
475 {
476 	struct drm_atomic_helper_connector_hdmi_priv *priv;
477 	struct drm_modeset_acquire_ctx ctx;
478 	struct drm_connector_state *conn_state;
479 	struct drm_atomic_commit *state;
480 	struct drm_display_mode *preferred;
481 	struct drm_connector *conn;
482 	struct drm_device *drm;
483 	struct drm_crtc *crtc;
484 	int ret;
485 
486 	priv = drm_kunit_helper_connector_hdmi_init(test,
487 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
488 						    8);
489 	KUNIT_ASSERT_NOT_NULL(test, priv);
490 
491 	drm = &priv->drm;
492 	crtc = priv->crtc;
493 	conn = &priv->connector;
494 	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
495 
496 	preferred = find_preferred_mode(conn);
497 	KUNIT_ASSERT_NOT_NULL(test, preferred);
498 	KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
499 
500 	drm_modeset_acquire_init(&ctx, 0);
501 
502 retry_conn_enable:
503 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
504 						     crtc, conn,
505 						     preferred,
506 						     &ctx);
507 	if (ret == -EDEADLK) {
508 		ret = drm_modeset_backoff(&ctx);
509 		if (!ret)
510 			goto retry_conn_enable;
511 	}
512 	KUNIT_ASSERT_EQ(test, ret, 0);
513 
514 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
515 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
516 
517 	conn_state = drm_atomic_get_connector_state(state, conn);
518 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
519 
520 	KUNIT_ASSERT_EQ(test,
521 			conn_state->hdmi.broadcast_rgb,
522 			DRM_HDMI_BROADCAST_RGB_AUTO);
523 
524 	ret = drm_atomic_check_only(state);
525 	KUNIT_ASSERT_EQ(test, ret, 0);
526 
527 	conn_state = drm_atomic_get_new_connector_state(state, conn);
528 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
529 
530 	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
531 
532 	drm_modeset_drop_locks(&ctx);
533 	drm_modeset_acquire_fini(&ctx);
534 }
535 
536 /*
537  * Test that for an HDMI connector, with an HDMI monitor, if the
538  * Broadcast RGB property is set to auto with a VIC-1 mode, we will get
539  * a full RGB Quantization Range.
540  */
541 static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test)
542 {
543 	struct drm_atomic_helper_connector_hdmi_priv *priv;
544 	struct drm_modeset_acquire_ctx ctx;
545 	struct drm_connector_state *conn_state;
546 	struct drm_atomic_commit *state;
547 	struct drm_display_mode *mode;
548 	struct drm_connector *conn;
549 	struct drm_device *drm;
550 	struct drm_crtc *crtc;
551 	int ret;
552 
553 	priv = drm_kunit_helper_connector_hdmi_init(test,
554 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
555 						    8);
556 	KUNIT_ASSERT_NOT_NULL(test, priv);
557 
558 	drm = &priv->drm;
559 	conn = &priv->connector;
560 	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
561 
562 	drm_modeset_acquire_init(&ctx, 0);
563 
564 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
565 	KUNIT_ASSERT_NOT_NULL(test, mode);
566 
567 	crtc = priv->crtc;
568 
569 retry_conn_enable:
570 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
571 						     crtc, conn,
572 						     mode,
573 						     &ctx);
574 	if (ret == -EDEADLK) {
575 		ret = drm_modeset_backoff(&ctx);
576 		if (!ret)
577 			goto retry_conn_enable;
578 	}
579 	KUNIT_ASSERT_EQ(test, ret, 0);
580 
581 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
582 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
583 
584 	conn_state = drm_atomic_get_connector_state(state, conn);
585 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
586 
587 	KUNIT_ASSERT_EQ(test,
588 			conn_state->hdmi.broadcast_rgb,
589 			DRM_HDMI_BROADCAST_RGB_AUTO);
590 
591 	ret = drm_atomic_check_only(state);
592 	KUNIT_ASSERT_EQ(test, ret, 0);
593 
594 	conn_state = drm_atomic_get_new_connector_state(state, conn);
595 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
596 
597 	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range);
598 
599 	drm_modeset_drop_locks(&ctx);
600 	drm_modeset_acquire_fini(&ctx);
601 }
602 
603 /*
604  * Test that for an HDMI connector, with an HDMI monitor, if the
605  * Broadcast RGB property is set to full with a mode that isn't the
606  * VIC-1 mode, we will get a full RGB Quantization Range.
607  */
608 static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test)
609 {
610 	struct drm_atomic_helper_connector_hdmi_priv *priv;
611 	struct drm_modeset_acquire_ctx ctx;
612 	struct drm_connector_state *conn_state;
613 	struct drm_atomic_commit *state;
614 	struct drm_display_mode *preferred;
615 	struct drm_connector *conn;
616 	struct drm_device *drm;
617 	struct drm_crtc *crtc;
618 	int ret;
619 
620 	priv = drm_kunit_helper_connector_hdmi_init(test,
621 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
622 						    8);
623 	KUNIT_ASSERT_NOT_NULL(test, priv);
624 
625 	drm = &priv->drm;
626 	crtc = priv->crtc;
627 	conn = &priv->connector;
628 	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
629 
630 	preferred = find_preferred_mode(conn);
631 	KUNIT_ASSERT_NOT_NULL(test, preferred);
632 	KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
633 
634 	drm_modeset_acquire_init(&ctx, 0);
635 
636 retry_conn_enable:
637 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
638 						     crtc, conn,
639 						     preferred,
640 						     &ctx);
641 	if (ret == -EDEADLK) {
642 		ret = drm_modeset_backoff(&ctx);
643 		if (!ret)
644 			goto retry_conn_enable;
645 	}
646 	KUNIT_ASSERT_EQ(test, ret, 0);
647 
648 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
649 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
650 
651 	conn_state = drm_atomic_get_connector_state(state, conn);
652 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
653 
654 	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
655 
656 	ret = drm_atomic_check_only(state);
657 	KUNIT_ASSERT_EQ(test, ret, 0);
658 
659 	conn_state = drm_atomic_get_new_connector_state(state, conn);
660 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
661 
662 	KUNIT_ASSERT_EQ(test,
663 			conn_state->hdmi.broadcast_rgb,
664 			DRM_HDMI_BROADCAST_RGB_FULL);
665 
666 	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range);
667 
668 	drm_modeset_drop_locks(&ctx);
669 	drm_modeset_acquire_fini(&ctx);
670 }
671 
672 /*
673  * Test that for an HDMI connector, with an HDMI monitor, if the
674  * Broadcast RGB property is set to full with a VIC-1 mode, we will get
675  * a full RGB Quantization Range.
676  */
677 static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test)
678 {
679 	struct drm_atomic_helper_connector_hdmi_priv *priv;
680 	struct drm_modeset_acquire_ctx ctx;
681 	struct drm_connector_state *conn_state;
682 	struct drm_atomic_commit *state;
683 	struct drm_display_mode *mode;
684 	struct drm_connector *conn;
685 	struct drm_device *drm;
686 	struct drm_crtc *crtc;
687 	int ret;
688 
689 	priv = drm_kunit_helper_connector_hdmi_init(test,
690 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
691 						    8);
692 	KUNIT_ASSERT_NOT_NULL(test, priv);
693 
694 	drm = &priv->drm;
695 	conn = &priv->connector;
696 	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
697 
698 	drm_modeset_acquire_init(&ctx, 0);
699 
700 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
701 	KUNIT_ASSERT_NOT_NULL(test, mode);
702 
703 	crtc = priv->crtc;
704 
705 retry_conn_enable:
706 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
707 						     crtc, conn,
708 						     mode,
709 						     &ctx);
710 	if (ret == -EDEADLK) {
711 		ret = drm_modeset_backoff(&ctx);
712 		if (!ret)
713 			goto retry_conn_enable;
714 	}
715 	KUNIT_ASSERT_EQ(test, ret, 0);
716 
717 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
718 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
719 
720 	conn_state = drm_atomic_get_connector_state(state, conn);
721 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
722 
723 	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_FULL;
724 
725 	ret = drm_atomic_check_only(state);
726 	KUNIT_ASSERT_EQ(test, ret, 0);
727 
728 	conn_state = drm_atomic_get_new_connector_state(state, conn);
729 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
730 
731 	KUNIT_ASSERT_EQ(test,
732 			conn_state->hdmi.broadcast_rgb,
733 			DRM_HDMI_BROADCAST_RGB_FULL);
734 
735 	KUNIT_EXPECT_FALSE(test, conn_state->hdmi.is_limited_range);
736 
737 	drm_modeset_drop_locks(&ctx);
738 	drm_modeset_acquire_fini(&ctx);
739 }
740 
741 /*
742  * Test that for an HDMI connector, with an HDMI monitor, if the
743  * Broadcast RGB property is set to limited with a mode that isn't the
744  * VIC-1 mode, we will get a limited RGB Quantization Range.
745  */
746 static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test)
747 {
748 	struct drm_atomic_helper_connector_hdmi_priv *priv;
749 	struct drm_modeset_acquire_ctx ctx;
750 	struct drm_connector_state *conn_state;
751 	struct drm_atomic_commit *state;
752 	struct drm_display_mode *preferred;
753 	struct drm_connector *conn;
754 	struct drm_device *drm;
755 	struct drm_crtc *crtc;
756 	int ret;
757 
758 	priv = drm_kunit_helper_connector_hdmi_init(test,
759 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
760 						    8);
761 	KUNIT_ASSERT_NOT_NULL(test, priv);
762 
763 	drm = &priv->drm;
764 	crtc = priv->crtc;
765 	conn = &priv->connector;
766 	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
767 
768 	preferred = find_preferred_mode(conn);
769 	KUNIT_ASSERT_NOT_NULL(test, preferred);
770 	KUNIT_ASSERT_NE(test, drm_match_cea_mode(preferred), 1);
771 
772 	drm_modeset_acquire_init(&ctx, 0);
773 
774 retry_conn_enable:
775 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
776 						     crtc, conn,
777 						     preferred,
778 						     &ctx);
779 	if (ret == -EDEADLK) {
780 		ret = drm_modeset_backoff(&ctx);
781 		if (!ret)
782 			goto retry_conn_enable;
783 	}
784 	KUNIT_ASSERT_EQ(test, ret, 0);
785 
786 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
787 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
788 
789 	conn_state = drm_atomic_get_connector_state(state, conn);
790 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
791 
792 	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
793 
794 	ret = drm_atomic_check_only(state);
795 	KUNIT_ASSERT_EQ(test, ret, 0);
796 
797 	conn_state = drm_atomic_get_new_connector_state(state, conn);
798 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
799 
800 	KUNIT_ASSERT_EQ(test,
801 			conn_state->hdmi.broadcast_rgb,
802 			DRM_HDMI_BROADCAST_RGB_LIMITED);
803 
804 	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
805 
806 	drm_modeset_drop_locks(&ctx);
807 	drm_modeset_acquire_fini(&ctx);
808 }
809 
810 /*
811  * Test that for an HDMI connector, with an HDMI monitor, if the
812  * Broadcast RGB property is set to limited with a VIC-1 mode, we will
813  * get a limited RGB Quantization Range.
814  */
815 static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *test)
816 {
817 	struct drm_atomic_helper_connector_hdmi_priv *priv;
818 	struct drm_modeset_acquire_ctx ctx;
819 	struct drm_connector_state *conn_state;
820 	struct drm_atomic_commit *state;
821 	struct drm_display_mode *mode;
822 	struct drm_connector *conn;
823 	struct drm_device *drm;
824 	struct drm_crtc *crtc;
825 	int ret;
826 
827 	priv = drm_kunit_helper_connector_hdmi_init(test,
828 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
829 						    8);
830 	KUNIT_ASSERT_NOT_NULL(test, priv);
831 
832 	drm = &priv->drm;
833 	conn = &priv->connector;
834 	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
835 
836 	drm_modeset_acquire_init(&ctx, 0);
837 
838 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
839 	KUNIT_ASSERT_NOT_NULL(test, mode);
840 
841 	crtc = priv->crtc;
842 
843 retry_conn_enable:
844 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
845 						     crtc, conn,
846 						     mode,
847 						     &ctx);
848 	if (ret == -EDEADLK) {
849 		ret = drm_modeset_backoff(&ctx);
850 		if (!ret)
851 			goto retry_conn_enable;
852 	}
853 	KUNIT_ASSERT_EQ(test, ret, 0);
854 
855 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
856 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
857 
858 	conn_state = drm_atomic_get_connector_state(state, conn);
859 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
860 
861 	conn_state->hdmi.broadcast_rgb = DRM_HDMI_BROADCAST_RGB_LIMITED;
862 
863 	ret = drm_atomic_check_only(state);
864 	KUNIT_ASSERT_EQ(test, ret, 0);
865 
866 	conn_state = drm_atomic_get_new_connector_state(state, conn);
867 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
868 
869 	KUNIT_ASSERT_EQ(test,
870 			conn_state->hdmi.broadcast_rgb,
871 			DRM_HDMI_BROADCAST_RGB_LIMITED);
872 
873 	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
874 
875 	drm_modeset_drop_locks(&ctx);
876 	drm_modeset_acquire_fini(&ctx);
877 }
878 
879 /*
880  * Test that for an HDMI connector, with an HDMI monitor, we will
881  * get a limited RGB Quantization Range with a YUV420 mode, no
882  * matter what the value of the Broadcast RGB property is set to.
883  */
884 static void drm_test_check_broadcast_rgb_cea_mode_yuv420(struct kunit *test)
885 {
886 	struct drm_atomic_helper_connector_hdmi_priv *priv;
887 	enum drm_hdmi_broadcast_rgb broadcast_rgb;
888 	struct drm_modeset_acquire_ctx ctx;
889 	struct drm_connector_state *conn_state;
890 	struct drm_atomic_commit *state;
891 	struct drm_display_mode *mode;
892 	struct drm_connector *conn;
893 	struct drm_device *drm;
894 	struct drm_crtc *crtc;
895 	int ret;
896 
897 	broadcast_rgb = *(enum drm_hdmi_broadcast_rgb *)test->param_value;
898 
899 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
900 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
901 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR420),
902 				8,
903 				&dummy_connector_hdmi_funcs,
904 				test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz);
905 	KUNIT_ASSERT_NOT_NULL(test, priv);
906 
907 	drm = &priv->drm;
908 	crtc = priv->crtc;
909 	conn = &priv->connector;
910 	KUNIT_ASSERT_TRUE(test, conn->display_info.is_hdmi);
911 
912 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 95);
913 	KUNIT_ASSERT_NOT_NULL(test, mode);
914 
915 	drm_modeset_acquire_init(&ctx, 0);
916 
917 retry_conn_enable:
918 	ret = drm_kunit_helper_enable_crtc_connector(test, drm, crtc, conn,
919 						     mode, &ctx);
920 	if (ret == -EDEADLK) {
921 		ret = drm_modeset_backoff(&ctx);
922 		if (!ret)
923 			goto retry_conn_enable;
924 	}
925 	KUNIT_ASSERT_EQ(test, ret, 0);
926 
927 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
928 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
929 
930 retry_conn_state:
931 	conn_state = drm_atomic_get_connector_state(state, conn);
932 	if (PTR_ERR(conn_state) == -EDEADLK) {
933 		drm_atomic_commit_clear(state);
934 		ret = drm_modeset_backoff(&ctx);
935 		if (!ret)
936 			goto retry_conn_state;
937 	}
938 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
939 
940 	conn_state->hdmi.broadcast_rgb = broadcast_rgb;
941 
942 	ret = drm_atomic_check_only(state);
943 	if (ret == -EDEADLK) {
944 		drm_atomic_commit_clear(state);
945 		ret = drm_modeset_backoff(&ctx);
946 		if (!ret)
947 			goto retry_conn_state;
948 	}
949 	KUNIT_ASSERT_EQ(test, ret, 0);
950 
951 	conn_state = drm_atomic_get_new_connector_state(state, conn);
952 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
953 
954 	KUNIT_ASSERT_EQ(test, conn_state->hdmi.broadcast_rgb, broadcast_rgb);
955 	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, DRM_OUTPUT_COLOR_FORMAT_YCBCR420);
956 
957 	KUNIT_EXPECT_TRUE(test, conn_state->hdmi.is_limited_range);
958 
959 	drm_modeset_drop_locks(&ctx);
960 	drm_modeset_acquire_fini(&ctx);
961 }
962 
963 static const enum drm_hdmi_broadcast_rgb check_broadcast_rgb_cea_mode_yuv420_tests[] = {
964 	DRM_HDMI_BROADCAST_RGB_AUTO,
965 	DRM_HDMI_BROADCAST_RGB_FULL,
966 	DRM_HDMI_BROADCAST_RGB_LIMITED,
967 };
968 
969 static void
970 check_broadcast_rgb_cea_mode_yuv420_desc(const enum drm_hdmi_broadcast_rgb *broadcast_rgb,
971 					 char *desc)
972 {
973 	sprintf(desc, "%s", drm_hdmi_connector_get_broadcast_rgb_name(*broadcast_rgb));
974 }
975 
976 KUNIT_ARRAY_PARAM(check_broadcast_rgb_cea_mode_yuv420,
977 		  check_broadcast_rgb_cea_mode_yuv420_tests,
978 		  check_broadcast_rgb_cea_mode_yuv420_desc);
979 
980 /*
981  * Test that if we change the maximum bpc property to a different value,
982  * we trigger a mode change on the connector's CRTC, which will in turn
983  * disable/enable the connector.
984  */
985 static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)
986 {
987 	struct drm_atomic_helper_connector_hdmi_priv *priv;
988 	struct drm_modeset_acquire_ctx ctx;
989 	struct drm_connector_state *old_conn_state;
990 	struct drm_connector_state *new_conn_state;
991 	struct drm_crtc_state *crtc_state;
992 	struct drm_atomic_commit *state;
993 	struct drm_display_mode *preferred;
994 	struct drm_connector *conn;
995 	struct drm_device *drm;
996 	struct drm_crtc *crtc;
997 	int ret;
998 
999 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
1000 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
1001 				10,
1002 				&dummy_connector_hdmi_funcs,
1003 				test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz);
1004 	KUNIT_ASSERT_NOT_NULL(test, priv);
1005 
1006 	drm = &priv->drm;
1007 	crtc = priv->crtc;
1008 	conn = &priv->connector;
1009 	preferred = find_preferred_mode(conn);
1010 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1011 
1012 	drm_modeset_acquire_init(&ctx, 0);
1013 
1014 retry_conn_enable:
1015 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
1016 						     crtc, conn,
1017 						     preferred,
1018 						     &ctx);
1019 	if (ret == -EDEADLK) {
1020 		ret = drm_modeset_backoff(&ctx);
1021 		if (!ret)
1022 			goto retry_conn_enable;
1023 	}
1024 	KUNIT_ASSERT_EQ(test, ret, 0);
1025 
1026 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
1027 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
1028 
1029 	new_conn_state = drm_atomic_get_connector_state(state, conn);
1030 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
1031 
1032 	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
1033 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
1034 
1035 	new_conn_state->max_requested_bpc = 8;
1036 
1037 	KUNIT_ASSERT_NE(test,
1038 			old_conn_state->max_requested_bpc,
1039 			new_conn_state->max_requested_bpc);
1040 
1041 	ret = drm_atomic_check_only(state);
1042 	KUNIT_ASSERT_EQ(test, ret, 0);
1043 
1044 	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
1045 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
1046 
1047 	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
1048 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
1049 
1050 	KUNIT_ASSERT_NE(test,
1051 			old_conn_state->hdmi.output_bpc,
1052 			new_conn_state->hdmi.output_bpc);
1053 
1054 	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1055 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
1056 	KUNIT_EXPECT_TRUE(test, crtc_state->mode_changed);
1057 
1058 	drm_modeset_drop_locks(&ctx);
1059 	drm_modeset_acquire_fini(&ctx);
1060 }
1061 
1062 /*
1063  * Test that if we set the output bpc property to the same value, we
1064  * don't trigger a mode change on the connector's CRTC and leave the
1065  * connector unaffected.
1066  */
1067 static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
1068 {
1069 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1070 	struct drm_modeset_acquire_ctx ctx;
1071 	struct drm_connector_state *old_conn_state;
1072 	struct drm_connector_state *new_conn_state;
1073 	struct drm_crtc_state *crtc_state;
1074 	struct drm_atomic_commit *state;
1075 	struct drm_display_mode *preferred;
1076 	struct drm_connector *conn;
1077 	struct drm_device *drm;
1078 	struct drm_crtc *crtc;
1079 	int ret;
1080 
1081 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
1082 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
1083 				10,
1084 				&dummy_connector_hdmi_funcs,
1085 				test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz);
1086 	KUNIT_ASSERT_NOT_NULL(test, priv);
1087 
1088 	drm = &priv->drm;
1089 	crtc = priv->crtc;
1090 	conn = &priv->connector;
1091 	preferred = find_preferred_mode(conn);
1092 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1093 
1094 	drm_modeset_acquire_init(&ctx, 0);
1095 
1096 retry_conn_enable:
1097 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
1098 						     crtc, conn,
1099 						     preferred,
1100 						     &ctx);
1101 	if (ret == -EDEADLK) {
1102 		ret = drm_modeset_backoff(&ctx);
1103 		if (!ret)
1104 			goto retry_conn_enable;
1105 	}
1106 	KUNIT_ASSERT_EQ(test, ret, 0);
1107 
1108 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
1109 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
1110 
1111 	new_conn_state = drm_atomic_get_connector_state(state, conn);
1112 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
1113 
1114 	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
1115 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
1116 
1117 	KUNIT_ASSERT_EQ(test,
1118 			new_conn_state->hdmi.output_bpc,
1119 			old_conn_state->hdmi.output_bpc);
1120 
1121 	ret = drm_atomic_check_only(state);
1122 	KUNIT_ASSERT_EQ(test, ret, 0);
1123 
1124 	old_conn_state = drm_atomic_get_old_connector_state(state, conn);
1125 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, old_conn_state);
1126 
1127 	new_conn_state = drm_atomic_get_new_connector_state(state, conn);
1128 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
1129 
1130 	KUNIT_EXPECT_EQ(test,
1131 			old_conn_state->hdmi.output_bpc,
1132 			new_conn_state->hdmi.output_bpc);
1133 
1134 	crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1135 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
1136 	KUNIT_EXPECT_FALSE(test, crtc_state->mode_changed);
1137 
1138 	drm_modeset_drop_locks(&ctx);
1139 	drm_modeset_acquire_fini(&ctx);
1140 }
1141 
1142 /*
1143  * Test that if we have an HDMI connector but a !HDMI display, we always
1144  * output RGB with 8 bpc.
1145  */
1146 static void drm_test_check_output_bpc_dvi(struct kunit *test)
1147 {
1148 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1149 	struct drm_modeset_acquire_ctx ctx;
1150 	struct drm_connector_state *conn_state;
1151 	struct drm_display_info *info;
1152 	struct drm_display_mode *preferred;
1153 	struct drm_connector *conn;
1154 	struct drm_device *drm;
1155 	struct drm_crtc *crtc;
1156 	int ret;
1157 
1158 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
1159 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
1160 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422) |
1161 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444),
1162 				12,
1163 				&dummy_connector_hdmi_funcs,
1164 				test_edid_dvi_1080p);
1165 	KUNIT_ASSERT_NOT_NULL(test, priv);
1166 
1167 	drm = &priv->drm;
1168 	crtc = priv->crtc;
1169 	conn = &priv->connector;
1170 	info = &conn->display_info;
1171 	KUNIT_ASSERT_FALSE(test, info->is_hdmi);
1172 
1173 	preferred = find_preferred_mode(conn);
1174 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1175 
1176 	drm_modeset_acquire_init(&ctx, 0);
1177 
1178 retry_conn_enable:
1179 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
1180 						     crtc, conn,
1181 						     preferred,
1182 						     &ctx);
1183 	if (ret == -EDEADLK) {
1184 		ret = drm_modeset_backoff(&ctx);
1185 		if (!ret)
1186 			goto retry_conn_enable;
1187 	}
1188 	KUNIT_ASSERT_EQ(test, ret, 0);
1189 
1190 	conn_state = conn->state;
1191 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1192 
1193 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
1194 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1195 
1196 	drm_modeset_drop_locks(&ctx);
1197 	drm_modeset_acquire_fini(&ctx);
1198 }
1199 
1200 /*
1201  * Test that when doing a commit which would use RGB 8bpc, the TMDS
1202  * clock rate stored in the connector state is equal to the mode clock
1203  */
1204 static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test)
1205 {
1206 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1207 	struct drm_modeset_acquire_ctx ctx;
1208 	struct drm_connector_state *conn_state;
1209 	struct drm_display_mode *preferred;
1210 	struct drm_connector *conn;
1211 	struct drm_device *drm;
1212 	struct drm_crtc *crtc;
1213 	int ret;
1214 
1215 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
1216 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
1217 				8,
1218 				&dummy_connector_hdmi_funcs,
1219 				test_edid_hdmi_1080p_rgb_max_200mhz);
1220 	KUNIT_ASSERT_NOT_NULL(test, priv);
1221 
1222 	drm = &priv->drm;
1223 	crtc = priv->crtc;
1224 	conn = &priv->connector;
1225 	preferred = find_preferred_mode(conn);
1226 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1227 	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
1228 
1229 	drm_modeset_acquire_init(&ctx, 0);
1230 
1231 retry_conn_enable:
1232 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
1233 						     crtc, conn,
1234 						     preferred,
1235 						     &ctx);
1236 	if (ret == -EDEADLK) {
1237 		ret = drm_modeset_backoff(&ctx);
1238 		if (!ret)
1239 			goto retry_conn_enable;
1240 	}
1241 	KUNIT_ASSERT_EQ(test, ret, 0);
1242 
1243 	conn_state = conn->state;
1244 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1245 
1246 	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 8);
1247 	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1248 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1000);
1249 
1250 	drm_modeset_drop_locks(&ctx);
1251 	drm_modeset_acquire_fini(&ctx);
1252 }
1253 
1254 /*
1255  * Test that when doing a commit which would use RGB 10bpc, the TMDS
1256  * clock rate stored in the connector state is equal to 1.25 times the
1257  * mode pixel clock
1258  */
1259 static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test)
1260 {
1261 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1262 	struct drm_modeset_acquire_ctx ctx;
1263 	struct drm_connector_state *conn_state;
1264 	struct drm_display_mode *preferred;
1265 	struct drm_connector *conn;
1266 	struct drm_device *drm;
1267 	struct drm_crtc *crtc;
1268 	int ret;
1269 
1270 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
1271 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
1272 				10,
1273 				&dummy_connector_hdmi_funcs,
1274 				test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz);
1275 	KUNIT_ASSERT_NOT_NULL(test, priv);
1276 
1277 	drm = &priv->drm;
1278 	crtc = priv->crtc;
1279 	conn = &priv->connector;
1280 	preferred = find_preferred_mode(conn);
1281 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1282 	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
1283 
1284 	drm_modeset_acquire_init(&ctx, 0);
1285 
1286 retry_conn_enable:
1287 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
1288 						     crtc, conn,
1289 						     preferred,
1290 						     &ctx);
1291 	if (ret == -EDEADLK) {
1292 		ret = drm_modeset_backoff(&ctx);
1293 		if (!ret)
1294 			goto retry_conn_enable;
1295 	}
1296 	KUNIT_ASSERT_EQ(test, ret, 0);
1297 
1298 	conn_state = conn->state;
1299 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1300 
1301 	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 10);
1302 	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1303 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250);
1304 
1305 	drm_modeset_drop_locks(&ctx);
1306 	drm_modeset_acquire_fini(&ctx);
1307 }
1308 
1309 /*
1310  * Test that when doing a commit which would use RGB 12bpc, the TMDS
1311  * clock rate stored in the connector state is equal to 1.5 times the
1312  * mode pixel clock
1313  */
1314 static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test)
1315 {
1316 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1317 	struct drm_modeset_acquire_ctx ctx;
1318 	struct drm_connector_state *conn_state;
1319 	struct drm_display_mode *preferred;
1320 	struct drm_connector *conn;
1321 	struct drm_device *drm;
1322 	struct drm_crtc *crtc;
1323 	int ret;
1324 
1325 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
1326 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
1327 				12,
1328 				&dummy_connector_hdmi_funcs,
1329 				test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz);
1330 	KUNIT_ASSERT_NOT_NULL(test, priv);
1331 
1332 	drm = &priv->drm;
1333 	crtc = priv->crtc;
1334 	conn = &priv->connector;
1335 	preferred = find_preferred_mode(conn);
1336 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1337 	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
1338 
1339 	drm_modeset_acquire_init(&ctx, 0);
1340 
1341 retry_conn_enable:
1342 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
1343 						     crtc, conn,
1344 						     preferred,
1345 						     &ctx);
1346 	if (ret == -EDEADLK) {
1347 		ret = drm_modeset_backoff(&ctx);
1348 		if (!ret)
1349 			goto retry_conn_enable;
1350 	}
1351 	KUNIT_ASSERT_EQ(test, ret, 0);
1352 
1353 	conn_state = conn->state;
1354 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1355 
1356 	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_bpc, 12);
1357 	KUNIT_ASSERT_EQ(test, conn_state->hdmi.output_format, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1358 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1500);
1359 
1360 	drm_modeset_drop_locks(&ctx);
1361 	drm_modeset_acquire_fini(&ctx);
1362 }
1363 
1364 /*
1365  * Test that if we filter a rate through our hook, it's indeed rejected
1366  * by the whole atomic_check logic.
1367  *
1368  * We do so by first doing a commit on the pipeline to make sure that it
1369  * works, change the HDMI helpers pointer, and then try the same commit
1370  * again to see if it fails as it should.
1371  */
1372 static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test)
1373 {
1374 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1375 	struct drm_modeset_acquire_ctx ctx;
1376 	struct drm_atomic_commit *state;
1377 	struct drm_display_mode *preferred;
1378 	struct drm_crtc_state *crtc_state;
1379 	struct drm_connector *conn;
1380 	struct drm_device *drm;
1381 	struct drm_crtc *crtc;
1382 	int ret;
1383 
1384 	priv = drm_kunit_helper_connector_hdmi_init(test,
1385 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
1386 						    8);
1387 	KUNIT_ASSERT_NOT_NULL(test, priv);
1388 
1389 	drm = &priv->drm;
1390 	crtc = priv->crtc;
1391 	conn = &priv->connector;
1392 
1393 	preferred = find_preferred_mode(conn);
1394 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1395 
1396 	drm_modeset_acquire_init(&ctx, 0);
1397 
1398 retry_conn_enable:
1399 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
1400 						     crtc, conn,
1401 						     preferred,
1402 						     &ctx);
1403 	if (ret == -EDEADLK) {
1404 		ret = drm_modeset_backoff(&ctx);
1405 		if (!ret)
1406 			goto retry_conn_enable;
1407 	}
1408 	KUNIT_ASSERT_EQ(test, ret, 0);
1409 
1410 	/* You shouldn't be doing that at home. */
1411 	conn->hdmi.funcs = &reject_connector_hdmi_funcs;
1412 
1413 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
1414 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
1415 
1416 	crtc_state = drm_atomic_get_crtc_state(state, crtc);
1417 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
1418 
1419 	crtc_state->connectors_changed = true;
1420 
1421 	ret = drm_atomic_check_only(state);
1422 	KUNIT_EXPECT_LT(test, ret, 0);
1423 
1424 	drm_modeset_drop_locks(&ctx);
1425 	drm_modeset_acquire_fini(&ctx);
1426 }
1427 
1428 /*
1429  * Test that if:
1430  * - We have an HDMI connector supporting RGB only
1431  * - The chosen mode has a TMDS character rate higher than the display
1432  *   supports in RGB/12bpc
1433  * - The chosen mode has a TMDS character rate lower than the display
1434  *   supports in RGB/10bpc.
1435  *
1436  * Then we will pick the latter, and the computed TMDS character rate
1437  * will be equal to 1.25 times the mode pixel clock.
1438  */
1439 static void drm_test_check_max_tmds_rate_bpc_fallback_rgb(struct kunit *test)
1440 {
1441 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1442 	struct drm_modeset_acquire_ctx ctx;
1443 	struct drm_connector_state *conn_state;
1444 	struct drm_display_info *info;
1445 	struct drm_display_mode *preferred;
1446 	unsigned long long rate;
1447 	struct drm_connector *conn;
1448 	struct drm_device *drm;
1449 	struct drm_crtc *crtc;
1450 	int ret;
1451 
1452 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
1453 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
1454 				12,
1455 				&dummy_connector_hdmi_funcs,
1456 				test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz);
1457 	KUNIT_ASSERT_NOT_NULL(test, priv);
1458 
1459 	drm = &priv->drm;
1460 	crtc = priv->crtc;
1461 	conn = &priv->connector;
1462 	info = &conn->display_info;
1463 	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1464 	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1465 
1466 	preferred = find_preferred_mode(conn);
1467 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1468 	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
1469 
1470 	rate = drm_hdmi_compute_mode_clock(preferred, 12, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1471 	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1472 
1473 	rate = drm_hdmi_compute_mode_clock(preferred, 10, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1474 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1475 
1476 	drm_modeset_acquire_init(&ctx, 0);
1477 
1478 retry_conn_enable:
1479 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
1480 						     crtc, conn,
1481 						     preferred,
1482 						     &ctx);
1483 	if (ret == -EDEADLK) {
1484 		ret = drm_modeset_backoff(&ctx);
1485 		if (!ret)
1486 			goto retry_conn_enable;
1487 	}
1488 	KUNIT_EXPECT_EQ(test, ret, 0);
1489 
1490 	conn_state = conn->state;
1491 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1492 
1493 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10);
1494 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1495 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, preferred->clock * 1250);
1496 
1497 	drm_modeset_drop_locks(&ctx);
1498 	drm_modeset_acquire_fini(&ctx);
1499 }
1500 
1501 /*
1502  * Test that if:
1503  * - We have an HDMI connector and a display supporting both RGB and YUV420
1504  * - The chosen mode can be supported in YUV420 output format only
1505  * - The chosen mode has a TMDS character rate higher than the display
1506  *   supports in YUV420/12bpc
1507  * - The chosen mode has a TMDS character rate lower than the display
1508  *   supports in YUV420/10bpc.
1509  *
1510  * Then we will pick the latter, and the computed TMDS character rate
1511  * will be equal to 1.25 * 0.5 times the mode pixel clock.
1512  */
1513 static void drm_test_check_max_tmds_rate_bpc_fallback_yuv420(struct kunit *test)
1514 {
1515 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1516 	struct drm_modeset_acquire_ctx ctx;
1517 	struct drm_connector_state *conn_state;
1518 	struct drm_display_info *info;
1519 	struct drm_display_mode *yuv420_only_mode;
1520 	unsigned long long rate;
1521 	struct drm_connector *conn;
1522 	struct drm_device *drm;
1523 	struct drm_crtc *crtc;
1524 	int ret;
1525 
1526 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
1527 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
1528 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR420),
1529 				12,
1530 				&dummy_connector_hdmi_funcs,
1531 				test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz);
1532 	KUNIT_ASSERT_NOT_NULL(test, priv);
1533 
1534 	drm = &priv->drm;
1535 	crtc = priv->crtc;
1536 	conn = &priv->connector;
1537 	info = &conn->display_info;
1538 	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1539 	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1540 	KUNIT_ASSERT_TRUE(test, conn->ycbcr_420_allowed);
1541 
1542 	yuv420_only_mode = drm_kunit_display_mode_from_cea_vic(test, drm, 95);
1543 	KUNIT_ASSERT_NOT_NULL(test, yuv420_only_mode);
1544 	KUNIT_ASSERT_TRUE(test, drm_mode_is_420_only(info, yuv420_only_mode));
1545 
1546 	rate = drm_hdmi_compute_mode_clock(yuv420_only_mode, 12, DRM_OUTPUT_COLOR_FORMAT_YCBCR420);
1547 	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1548 
1549 	rate = drm_hdmi_compute_mode_clock(yuv420_only_mode, 10, DRM_OUTPUT_COLOR_FORMAT_YCBCR420);
1550 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1551 
1552 	drm_modeset_acquire_init(&ctx, 0);
1553 
1554 retry_conn_enable:
1555 	ret = drm_kunit_helper_enable_crtc_connector(test, drm, crtc, conn,
1556 						     yuv420_only_mode, &ctx);
1557 	if (ret == -EDEADLK) {
1558 		ret = drm_modeset_backoff(&ctx);
1559 		if (!ret)
1560 			goto retry_conn_enable;
1561 	}
1562 	KUNIT_EXPECT_EQ(test, ret, 0);
1563 
1564 	conn_state = conn->state;
1565 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1566 
1567 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10);
1568 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, DRM_OUTPUT_COLOR_FORMAT_YCBCR420);
1569 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, yuv420_only_mode->clock * 625);
1570 
1571 	drm_modeset_drop_locks(&ctx);
1572 	drm_modeset_acquire_fini(&ctx);
1573 }
1574 
1575 /*
1576  * Test that if:
1577  * - We have an HDMI connector supporting both RGB and YUV422 and up to
1578  *   12 bpc
1579  * - The chosen mode has a TMDS character rate higher than the display
1580  *   supports in RGB/12bpc but lower than the display supports in
1581  *   RGB/10bpc
1582  * - The chosen mode has a TMDS character rate lower than the display
1583  *   supports in YUV422/12bpc.
1584  * - The HDMI connector state's color format property is unset (i.e. AUTO)
1585  *
1586  * Then we will prefer to keep the RGB format with a lower bpc over
1587  * picking YUV422.
1588  */
1589 static void drm_test_check_max_tmds_rate_bpc_fallback_ignore_yuv422(struct kunit *test)
1590 {
1591 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1592 	struct drm_modeset_acquire_ctx ctx;
1593 	struct drm_connector_state *conn_state;
1594 	struct drm_display_info *info;
1595 	struct drm_display_mode *preferred;
1596 	unsigned long long rate;
1597 	struct drm_connector *conn;
1598 	struct drm_device *drm;
1599 	struct drm_crtc *crtc;
1600 	int ret;
1601 
1602 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
1603 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
1604 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422) |
1605 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444),
1606 				12,
1607 				&dummy_connector_hdmi_funcs,
1608 				test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz);
1609 	KUNIT_ASSERT_NOT_NULL(test, priv);
1610 
1611 	drm = &priv->drm;
1612 	crtc = priv->crtc;
1613 	conn = &priv->connector;
1614 	info = &conn->display_info;
1615 	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1616 	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1617 
1618 	preferred = find_preferred_mode(conn);
1619 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1620 	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
1621 
1622 	rate = drm_hdmi_compute_mode_clock(preferred, 10, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1623 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1624 
1625 	rate = drm_hdmi_compute_mode_clock(preferred, 12, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1626 	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1627 
1628 	rate = drm_hdmi_compute_mode_clock(preferred, 12, DRM_OUTPUT_COLOR_FORMAT_YCBCR422);
1629 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1630 
1631 	drm_modeset_acquire_init(&ctx, 0);
1632 
1633 retry_conn_enable:
1634 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
1635 						     crtc, conn,
1636 						     preferred,
1637 						     &ctx);
1638 	if (ret == -EDEADLK) {
1639 		ret = drm_modeset_backoff(&ctx);
1640 		if (!ret)
1641 			goto retry_conn_enable;
1642 	}
1643 	KUNIT_EXPECT_EQ(test, ret, 0);
1644 
1645 	conn_state = conn->state;
1646 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1647 	KUNIT_ASSERT_EQ(test, conn_state->color_format, DRM_CONNECTOR_COLOR_FORMAT_AUTO);
1648 
1649 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 10);
1650 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1651 
1652 	drm_modeset_drop_locks(&ctx);
1653 	drm_modeset_acquire_fini(&ctx);
1654 }
1655 
1656 /*
1657  * Test that if:
1658  * - We have an HDMI connector supporting both RGB and YUV420 and up to
1659  *   12 bpc
1660  * - The chosen mode has a TMDS character rate higher than the display
1661  *   supports in RGB/10bpc but lower than the display supports in
1662  *   RGB/8bpc
1663  * - The chosen mode has a TMDS character rate lower than the display
1664  *   supports in YUV420/12bpc.
1665  * - The HDMI connector state's color format property is unset (i.e. AUTO)
1666  *
1667  * Then we will prefer to keep the RGB format with a lower bpc over
1668  * picking YUV420.
1669  */
1670 static void drm_test_check_max_tmds_rate_bpc_fallback_ignore_yuv420(struct kunit *test)
1671 {
1672 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1673 	struct drm_modeset_acquire_ctx ctx;
1674 	struct drm_connector_state *conn_state;
1675 	struct drm_display_info *info;
1676 	struct drm_display_mode *preferred;
1677 	unsigned long long rate;
1678 	struct drm_connector *conn;
1679 	struct drm_device *drm;
1680 	struct drm_crtc *crtc;
1681 	int ret;
1682 
1683 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
1684 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
1685 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR420),
1686 				12,
1687 				&dummy_connector_hdmi_funcs,
1688 				test_edid_hdmi_4k_rgb_yuv420_dc_max_340mhz);
1689 	KUNIT_ASSERT_NOT_NULL(test, priv);
1690 
1691 	drm = &priv->drm;
1692 	crtc = priv->crtc;
1693 	conn = &priv->connector;
1694 	info = &conn->display_info;
1695 	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1696 	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1697 	KUNIT_ASSERT_TRUE(test, conn->ycbcr_420_allowed);
1698 
1699 	preferred = find_preferred_mode(conn);
1700 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1701 	KUNIT_ASSERT_FALSE(test, preferred->flags & DRM_MODE_FLAG_DBLCLK);
1702 	KUNIT_ASSERT_TRUE(test, drm_mode_is_420_also(info, preferred));
1703 
1704 	rate = drm_hdmi_compute_mode_clock(preferred, 8, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1705 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1706 
1707 	rate = drm_hdmi_compute_mode_clock(preferred, 10, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1708 	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1709 
1710 	rate = drm_hdmi_compute_mode_clock(preferred, 12, DRM_OUTPUT_COLOR_FORMAT_YCBCR420);
1711 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1712 
1713 	drm_modeset_acquire_init(&ctx, 0);
1714 
1715 retry_conn_enable:
1716 	ret = drm_kunit_helper_enable_crtc_connector(test, drm, crtc, conn,
1717 						     preferred, &ctx);
1718 	if (ret == -EDEADLK) {
1719 		ret = drm_modeset_backoff(&ctx);
1720 		if (!ret)
1721 			goto retry_conn_enable;
1722 	}
1723 	KUNIT_EXPECT_EQ(test, ret, 0);
1724 
1725 	conn_state = conn->state;
1726 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1727 	KUNIT_ASSERT_EQ(test, conn_state->color_format, DRM_CONNECTOR_COLOR_FORMAT_AUTO);
1728 
1729 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
1730 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1731 
1732 	drm_modeset_drop_locks(&ctx);
1733 	drm_modeset_acquire_fini(&ctx);
1734 }
1735 
1736 /*
1737  * Test that if a driver supports only RGB, but the chosen mode can be
1738  * supported by the screen only in YUV420 output format, we end up with
1739  * unsuccessful fallback attempts.
1740  */
1741 static void drm_test_check_driver_unsupported_fallback_yuv420(struct kunit *test)
1742 {
1743 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1744 	struct drm_modeset_acquire_ctx ctx;
1745 	struct drm_connector_state *conn_state;
1746 	struct drm_crtc_state *crtc_state;
1747 	struct drm_atomic_commit *state;
1748 	struct drm_display_info *info;
1749 	struct drm_display_mode *preferred, *yuv420_only_mode;
1750 	struct drm_connector *conn;
1751 	struct drm_device *drm;
1752 	struct drm_crtc *crtc;
1753 	int ret;
1754 
1755 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
1756 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
1757 				12,
1758 				&dummy_connector_hdmi_funcs,
1759 				test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz);
1760 	KUNIT_ASSERT_NOT_NULL(test, priv);
1761 
1762 	drm = &priv->drm;
1763 	crtc = priv->crtc;
1764 	conn = &priv->connector;
1765 	info = &conn->display_info;
1766 	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1767 	KUNIT_ASSERT_FALSE(test, conn->ycbcr_420_allowed);
1768 
1769 	preferred = find_preferred_mode(conn);
1770 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1771 	KUNIT_ASSERT_FALSE(test, drm_mode_is_420_also(info, preferred));
1772 
1773 	yuv420_only_mode = drm_kunit_display_mode_from_cea_vic(test, drm, 95);
1774 	KUNIT_ASSERT_NOT_NULL(test, yuv420_only_mode);
1775 	KUNIT_ASSERT_TRUE(test, drm_mode_is_420_only(info, yuv420_only_mode));
1776 
1777 	drm_modeset_acquire_init(&ctx, 0);
1778 
1779 retry_conn_enable:
1780 	ret = drm_kunit_helper_enable_crtc_connector(test, drm, crtc, conn,
1781 						     preferred, &ctx);
1782 	if (ret == -EDEADLK) {
1783 		ret = drm_modeset_backoff(&ctx);
1784 		if (!ret)
1785 			goto retry_conn_enable;
1786 	}
1787 	KUNIT_EXPECT_EQ(test, ret, 0);
1788 
1789 	conn_state = conn->state;
1790 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1791 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1792 
1793 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
1794 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
1795 
1796 retry_crtc_state:
1797 	crtc_state = drm_atomic_get_crtc_state(state, crtc);
1798 	if (PTR_ERR(crtc_state) == -EDEADLK) {
1799 		drm_atomic_commit_clear(state);
1800 		ret = drm_modeset_backoff(&ctx);
1801 		if (!ret)
1802 			goto retry_crtc_state;
1803 	}
1804 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
1805 
1806 	ret = drm_atomic_set_mode_for_crtc(crtc_state, yuv420_only_mode);
1807 	KUNIT_EXPECT_EQ(test, ret, 0);
1808 
1809 	ret = drm_atomic_check_only(state);
1810 	if (ret == -EDEADLK) {
1811 		drm_atomic_commit_clear(state);
1812 		ret = drm_modeset_backoff(&ctx);
1813 		if (!ret)
1814 			goto retry_crtc_state;
1815 	}
1816 	KUNIT_ASSERT_LT(test, ret, 0);
1817 
1818 	drm_modeset_drop_locks(&ctx);
1819 	drm_modeset_acquire_fini(&ctx);
1820 }
1821 
1822 /*
1823  * Test that if a driver and screen supports RGB and YUV formats, and we
1824  * try to set the VIC 1 mode, we end up with 8bpc RGB even if we could
1825  * have had a higher bpc.
1826  */
1827 static void drm_test_check_output_bpc_format_vic_1(struct kunit *test)
1828 {
1829 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1830 	struct drm_modeset_acquire_ctx ctx;
1831 	struct drm_connector_state *conn_state;
1832 	struct drm_display_info *info;
1833 	struct drm_display_mode *mode;
1834 	unsigned long long rate;
1835 	struct drm_connector *conn;
1836 	struct drm_device *drm;
1837 	struct drm_crtc *crtc;
1838 	int ret;
1839 
1840 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
1841 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
1842 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422) |
1843 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444),
1844 				12,
1845 				&dummy_connector_hdmi_funcs,
1846 				test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz);
1847 	KUNIT_ASSERT_NOT_NULL(test, priv);
1848 
1849 	drm = &priv->drm;
1850 	conn = &priv->connector;
1851 	info = &conn->display_info;
1852 	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1853 	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1854 
1855 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
1856 	KUNIT_ASSERT_NOT_NULL(test, mode);
1857 
1858 	/*
1859 	 * NOTE: We can't use drm_hdmi_compute_mode_clock()
1860 	 * here because we're trying to get the rate of an invalid
1861 	 * configuration.
1862 	 *
1863 	 * Thus, we have to calculate the rate by hand.
1864 	 */
1865 	rate = mode->clock * 1500;
1866 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1867 
1868 	drm_modeset_acquire_init(&ctx, 0);
1869 
1870 	crtc = priv->crtc;
1871 
1872 retry_conn_enable:
1873 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
1874 						     crtc, conn,
1875 						     mode,
1876 						     &ctx);
1877 	if (ret == -EDEADLK) {
1878 		ret = drm_modeset_backoff(&ctx);
1879 		if (!ret)
1880 			goto retry_conn_enable;
1881 	}
1882 	KUNIT_EXPECT_EQ(test, ret, 0);
1883 
1884 	conn_state = conn->state;
1885 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1886 
1887 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
1888 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1889 
1890 	drm_modeset_drop_locks(&ctx);
1891 	drm_modeset_acquire_fini(&ctx);
1892 }
1893 
1894 /*
1895  * Test that if a driver supports only RGB but the screen also supports
1896  * YUV formats, we only end up with an RGB format.
1897  */
1898 static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test)
1899 {
1900 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1901 	struct drm_modeset_acquire_ctx ctx;
1902 	struct drm_connector_state *conn_state;
1903 	struct drm_display_info *info;
1904 	struct drm_display_mode *preferred;
1905 	unsigned long long rate;
1906 	struct drm_connector *conn;
1907 	struct drm_device *drm;
1908 	struct drm_crtc *crtc;
1909 	int ret;
1910 
1911 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
1912 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
1913 				12,
1914 				&dummy_connector_hdmi_funcs,
1915 				test_edid_hdmi_1080p_rgb_yuv_dc_max_200mhz);
1916 	KUNIT_ASSERT_NOT_NULL(test, priv);
1917 
1918 	drm = &priv->drm;
1919 	crtc = priv->crtc;
1920 	conn = &priv->connector;
1921 	info = &conn->display_info;
1922 	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1923 	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1924 
1925 	preferred = find_preferred_mode(conn);
1926 	KUNIT_ASSERT_NOT_NULL(test, preferred);
1927 
1928 	/*
1929 	 * We're making sure that YUV422 would be the preferred option
1930 	 * here: we're always favouring higher bpc, we can't have RGB
1931 	 * because the TMDS character rate exceeds the maximum supported
1932 	 * by the display, and YUV422 works for that display.
1933 	 *
1934 	 * But since the driver only supports RGB, we should fallback to
1935 	 * a lower bpc with RGB.
1936 	 */
1937 	rate = drm_hdmi_compute_mode_clock(preferred, 12, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1938 	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
1939 
1940 	rate = drm_hdmi_compute_mode_clock(preferred, 12, DRM_OUTPUT_COLOR_FORMAT_YCBCR422);
1941 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
1942 
1943 	drm_modeset_acquire_init(&ctx, 0);
1944 
1945 retry_conn_enable:
1946 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
1947 						     crtc, conn,
1948 						     preferred,
1949 						     &ctx);
1950 	if (ret == -EDEADLK) {
1951 		ret = drm_modeset_backoff(&ctx);
1952 		if (!ret)
1953 			goto retry_conn_enable;
1954 	}
1955 	KUNIT_EXPECT_EQ(test, ret, 0);
1956 
1957 	conn_state = conn->state;
1958 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
1959 
1960 	KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12);
1961 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, DRM_OUTPUT_COLOR_FORMAT_RGB444);
1962 
1963 	drm_modeset_drop_locks(&ctx);
1964 	drm_modeset_acquire_fini(&ctx);
1965 }
1966 
1967 /*
1968  * Test that if a screen supports only RGB but the driver also supports
1969  * YUV formats, we only end up with an RGB format.
1970  */
1971 static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test)
1972 {
1973 	struct drm_atomic_helper_connector_hdmi_priv *priv;
1974 	struct drm_modeset_acquire_ctx ctx;
1975 	struct drm_connector_state *conn_state;
1976 	struct drm_display_info *info;
1977 	struct drm_display_mode *preferred;
1978 	unsigned long long rate;
1979 	struct drm_connector *conn;
1980 	struct drm_device *drm;
1981 	struct drm_crtc *crtc;
1982 	int ret;
1983 
1984 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
1985 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
1986 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422) |
1987 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444),
1988 				12,
1989 				&dummy_connector_hdmi_funcs,
1990 				test_edid_hdmi_1080p_rgb_max_200mhz);
1991 	KUNIT_ASSERT_NOT_NULL(test, priv);
1992 
1993 	drm = &priv->drm;
1994 	crtc = priv->crtc;
1995 	conn = &priv->connector;
1996 	info = &conn->display_info;
1997 	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
1998 	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
1999 
2000 	preferred = find_preferred_mode(conn);
2001 	KUNIT_ASSERT_NOT_NULL(test, preferred);
2002 
2003 	/*
2004 	 * We're making sure that YUV422 would be the preferred option
2005 	 * here: we're always favouring higher bpc, we can't have RGB
2006 	 * because the TMDS character rate exceeds the maximum supported
2007 	 * by the display, and YUV422 works for that display.
2008 	 *
2009 	 * But since the display only supports RGB, we should fallback to
2010 	 * a lower bpc with RGB.
2011 	 */
2012 	rate = drm_hdmi_compute_mode_clock(preferred, 12, DRM_OUTPUT_COLOR_FORMAT_RGB444);
2013 	KUNIT_ASSERT_GT(test, rate, info->max_tmds_clock * 1000);
2014 
2015 	rate = drm_hdmi_compute_mode_clock(preferred, 12, DRM_OUTPUT_COLOR_FORMAT_YCBCR422);
2016 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
2017 
2018 	drm_modeset_acquire_init(&ctx, 0);
2019 
2020 retry_conn_enable:
2021 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
2022 						     crtc, conn,
2023 						     preferred,
2024 						     &ctx);
2025 	if (ret == -EDEADLK) {
2026 		ret = drm_modeset_backoff(&ctx);
2027 		if (!ret)
2028 			goto retry_conn_enable;
2029 	}
2030 	KUNIT_EXPECT_EQ(test, ret, 0);
2031 
2032 	conn_state = conn->state;
2033 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
2034 
2035 	KUNIT_EXPECT_LT(test, conn_state->hdmi.output_bpc, 12);
2036 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, DRM_OUTPUT_COLOR_FORMAT_RGB444);
2037 
2038 	drm_modeset_drop_locks(&ctx);
2039 	drm_modeset_acquire_fini(&ctx);
2040 }
2041 
2042 /*
2043  * Test that if a display supports higher bpc but the driver only
2044  * supports 8 bpc, we only end up with 8 bpc even if we could have had a
2045  * higher bpc.
2046  */
2047 static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test)
2048 {
2049 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2050 	struct drm_modeset_acquire_ctx ctx;
2051 	struct drm_connector_state *conn_state;
2052 	struct drm_display_info *info;
2053 	struct drm_display_mode *preferred;
2054 	unsigned long long rate;
2055 	struct drm_connector *conn;
2056 	struct drm_device *drm;
2057 	struct drm_crtc *crtc;
2058 	int ret;
2059 
2060 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
2061 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
2062 				8,
2063 				&dummy_connector_hdmi_funcs,
2064 				test_edid_hdmi_1080p_rgb_yuv_dc_max_340mhz);
2065 	KUNIT_ASSERT_NOT_NULL(test, priv);
2066 
2067 	drm = &priv->drm;
2068 	crtc = priv->crtc;
2069 	conn = &priv->connector;
2070 	info = &conn->display_info;
2071 	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
2072 	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
2073 
2074 	preferred = find_preferred_mode(conn);
2075 	KUNIT_ASSERT_NOT_NULL(test, preferred);
2076 
2077 	/*
2078 	 * We're making sure that we have headroom on the TMDS character
2079 	 * clock to actually use 12bpc.
2080 	 */
2081 	rate = drm_hdmi_compute_mode_clock(preferred, 12, DRM_OUTPUT_COLOR_FORMAT_RGB444);
2082 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
2083 
2084 	drm_modeset_acquire_init(&ctx, 0);
2085 
2086 retry_conn_enable:
2087 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
2088 						     crtc, conn,
2089 						     preferred,
2090 						     &ctx);
2091 	if (ret == -EDEADLK) {
2092 		ret = drm_modeset_backoff(&ctx);
2093 		if (!ret)
2094 			goto retry_conn_enable;
2095 	}
2096 	KUNIT_EXPECT_EQ(test, ret, 0);
2097 
2098 	conn_state = conn->state;
2099 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
2100 
2101 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
2102 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, DRM_OUTPUT_COLOR_FORMAT_RGB444);
2103 
2104 	drm_modeset_drop_locks(&ctx);
2105 	drm_modeset_acquire_fini(&ctx);
2106 }
2107 
2108 /*
2109  * Test that if a driver supports higher bpc but the display only
2110  * supports 8 bpc, we only end up with 8 bpc even if we could have had a
2111  * higher bpc.
2112  */
2113 static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *test)
2114 {
2115 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2116 	struct drm_modeset_acquire_ctx ctx;
2117 	struct drm_connector_state *conn_state;
2118 	struct drm_display_info *info;
2119 	struct drm_display_mode *preferred;
2120 	unsigned long long rate;
2121 	struct drm_connector *conn;
2122 	struct drm_device *drm;
2123 	struct drm_crtc *crtc;
2124 	int ret;
2125 
2126 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
2127 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
2128 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422) |
2129 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444),
2130 				12,
2131 				&dummy_connector_hdmi_funcs,
2132 				test_edid_hdmi_1080p_rgb_max_340mhz);
2133 	KUNIT_ASSERT_NOT_NULL(test, priv);
2134 
2135 	drm = &priv->drm;
2136 	crtc = priv->crtc;
2137 	conn = &priv->connector;
2138 	info = &conn->display_info;
2139 	KUNIT_ASSERT_TRUE(test, info->is_hdmi);
2140 	KUNIT_ASSERT_GT(test, info->max_tmds_clock, 0);
2141 
2142 	preferred = find_preferred_mode(conn);
2143 	KUNIT_ASSERT_NOT_NULL(test, preferred);
2144 
2145 	/*
2146 	 * We're making sure that we have headroom on the TMDS character
2147 	 * clock to actually use 12bpc.
2148 	 */
2149 	rate = drm_hdmi_compute_mode_clock(preferred, 12, DRM_OUTPUT_COLOR_FORMAT_RGB444);
2150 	KUNIT_ASSERT_LT(test, rate, info->max_tmds_clock * 1000);
2151 
2152 	drm_modeset_acquire_init(&ctx, 0);
2153 
2154 retry_conn_enable:
2155 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
2156 						     crtc, conn,
2157 						     preferred,
2158 						     &ctx);
2159 	if (ret == -EDEADLK) {
2160 		ret = drm_modeset_backoff(&ctx);
2161 		if (!ret)
2162 			goto retry_conn_enable;
2163 	}
2164 	KUNIT_EXPECT_EQ(test, ret, 0);
2165 
2166 	conn_state = conn->state;
2167 	KUNIT_ASSERT_NOT_NULL(test, conn_state);
2168 
2169 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 8);
2170 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, DRM_OUTPUT_COLOR_FORMAT_RGB444);
2171 
2172 	drm_modeset_drop_locks(&ctx);
2173 	drm_modeset_acquire_fini(&ctx);
2174 }
2175 
2176 /* Test that atomic check succeeds when disabling a connector. */
2177 static void drm_test_check_disable_connector(struct kunit *test)
2178 {
2179 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2180 	struct drm_modeset_acquire_ctx ctx;
2181 	struct drm_connector_state *conn_state;
2182 	struct drm_crtc_state *crtc_state;
2183 	struct drm_atomic_commit *state;
2184 	struct drm_display_mode *preferred;
2185 	struct drm_connector *conn;
2186 	struct drm_device *drm;
2187 	struct drm_crtc *crtc;
2188 	int ret;
2189 
2190 	priv = drm_kunit_helper_connector_hdmi_init(test,
2191 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
2192 						    8);
2193 	KUNIT_ASSERT_NOT_NULL(test, priv);
2194 
2195 	drm_modeset_acquire_init(&ctx, 0);
2196 
2197 	conn = &priv->connector;
2198 	preferred = find_preferred_mode(conn);
2199 	KUNIT_ASSERT_NOT_NULL(test, preferred);
2200 
2201 	drm = &priv->drm;
2202 	crtc = priv->crtc;
2203 
2204 retry_conn_enable:
2205 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
2206 						     crtc, conn,
2207 						     preferred,
2208 						     &ctx);
2209 	if (ret == -EDEADLK) {
2210 		ret = drm_modeset_backoff(&ctx);
2211 		if (!ret)
2212 			goto retry_conn_enable;
2213 	}
2214 	KUNIT_ASSERT_EQ(test, ret, 0);
2215 
2216 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
2217 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
2218 
2219 	crtc_state = drm_atomic_get_crtc_state(state, crtc);
2220 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
2221 
2222 	crtc_state->active = false;
2223 	ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL);
2224 	KUNIT_EXPECT_EQ(test, ret, 0);
2225 
2226 	conn_state = drm_atomic_get_connector_state(state, conn);
2227 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
2228 
2229 	ret = drm_atomic_set_crtc_for_connector(conn_state, NULL);
2230 	KUNIT_EXPECT_EQ(test, ret, 0);
2231 
2232 	ret = drm_atomic_check_only(state);
2233 	KUNIT_ASSERT_EQ(test, ret, 0);
2234 
2235 	drm_modeset_drop_locks(&ctx);
2236 	drm_modeset_acquire_fini(&ctx);
2237 }
2238 
2239 struct color_format_test_param {
2240 	enum drm_connector_color_format fmt;
2241 	enum drm_output_color_format expected;
2242 	int expected_ret;
2243 	const char *desc;
2244 };
2245 
2246 /* Test that if:
2247  * - an HDMI connector supports RGB, YUV444, YUV422, and YUV420
2248  * - the display supports RGB, YUV444, YUV422, and YUV420
2249  * - the "color format" property is set
2250  * then, for the preferred mode, for a given "color format" option:
2251  * - DRM_CONNECTOR_COLOR_FORMAT_AUTO results in an output format of RGB
2252  * - DRM_CONNECTOR_COLOR_FORMAT_YCBCR422 results in an output format of YUV422
2253  * - DRM_CONNECTOR_COLOR_FORMAT_YCBCR420 results in an output format of YUV420
2254  * - DRM_CONNECTOR_COLOR_FORMAT_YCBCR444 results in an output format of YUV444
2255  * - DRM_CONNECTOR_COLOR_FORMAT_RGB results in an HDMI output format of RGB
2256  */
2257 static void drm_test_check_hdmi_color_format(struct kunit *test)
2258 {
2259 	const struct color_format_test_param *param = test->param_value;
2260 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2261 	struct drm_connector_state *conn_state;
2262 	struct drm_modeset_acquire_ctx ctx;
2263 	struct drm_crtc_state *crtc_state;
2264 	struct drm_atomic_commit *state;
2265 	struct drm_display_info *info;
2266 	struct drm_display_mode *preferred;
2267 	int ret;
2268 
2269 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
2270 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
2271 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422) |
2272 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR420) |
2273 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444),
2274 				12,
2275 				&dummy_connector_hdmi_funcs,
2276 				test_edid_hdmi_4k_rgb_yuv420_dc_max_340mhz);
2277 	KUNIT_ASSERT_NOT_NULL(test, priv);
2278 
2279 	drm_modeset_acquire_init(&ctx, 0);
2280 
2281 	KUNIT_ASSERT_TRUE(test, priv->connector.ycbcr_420_allowed);
2282 
2283 	info = &priv->connector.display_info;
2284 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, info);
2285 	preferred = find_preferred_mode(&priv->connector);
2286 	KUNIT_ASSERT_TRUE(test, drm_mode_is_420(info, preferred));
2287 
2288 	state = drm_kunit_helper_atomic_state_alloc(test, &priv->drm, &ctx);
2289 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
2290 
2291 	conn_state = drm_atomic_get_connector_state(state, &priv->connector);
2292 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
2293 
2294 	conn_state->color_format = param->fmt;
2295 
2296 	ret = drm_atomic_set_crtc_for_connector(conn_state, priv->crtc);
2297 	KUNIT_ASSERT_EQ(test, ret, 0);
2298 
2299 	crtc_state = drm_atomic_get_crtc_state(state, priv->crtc);
2300 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
2301 
2302 	ret = drm_atomic_set_mode_for_crtc(crtc_state, preferred);
2303 	KUNIT_ASSERT_EQ(test, ret, 0);
2304 
2305 	crtc_state->enable = true;
2306 	crtc_state->active = true;
2307 
2308 	ret = drm_atomic_check_only(state);
2309 	KUNIT_EXPECT_EQ(test, ret, param->expected_ret);
2310 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, param->expected);
2311 
2312 	drm_modeset_drop_locks(&ctx);
2313 	drm_modeset_acquire_fini(&ctx);
2314 }
2315 
2316 static const struct color_format_test_param hdmi_color_format_params[] = {
2317 	{
2318 		.fmt = DRM_CONNECTOR_COLOR_FORMAT_AUTO,
2319 		.expected = DRM_OUTPUT_COLOR_FORMAT_RGB444,
2320 		.expected_ret = 0,
2321 		.desc = "AUTO -> RGB"
2322 	},
2323 	{
2324 		.fmt = DRM_CONNECTOR_COLOR_FORMAT_YCBCR422,
2325 		.expected = DRM_OUTPUT_COLOR_FORMAT_YCBCR422,
2326 		.expected_ret = 0,
2327 		.desc = "YCBCR422 -> YUV422"
2328 	},
2329 	{
2330 		.fmt = DRM_CONNECTOR_COLOR_FORMAT_YCBCR420,
2331 		.expected = DRM_OUTPUT_COLOR_FORMAT_YCBCR420,
2332 		.expected_ret = 0,
2333 		.desc = "YCBCR420 -> YUV420"
2334 	},
2335 	{
2336 		.fmt = DRM_CONNECTOR_COLOR_FORMAT_YCBCR444,
2337 		.expected = DRM_OUTPUT_COLOR_FORMAT_YCBCR444,
2338 		.expected_ret = 0,
2339 		.desc = "YCBCR444 -> YUV444"
2340 	},
2341 	{
2342 		.fmt = DRM_CONNECTOR_COLOR_FORMAT_RGB444,
2343 		.expected = DRM_OUTPUT_COLOR_FORMAT_RGB444,
2344 		.expected_ret = 0,
2345 		.desc = "RGB -> RGB"
2346 	},
2347 };
2348 
2349 KUNIT_ARRAY_PARAM_DESC(check_hdmi_color_format, hdmi_color_format_params, desc);
2350 
2351 /* Test that if:
2352  * - the HDMI connector supports RGB, YUV422, YUV420, and YUV444
2353  * - the display has a YUV420-only mode
2354  * - the "color format" property is explicitly set (i.e. !AUTO)
2355  * then:
2356  * - color format DRM_CONNECTOR_COLOR_FORMAT_RGB444 will fail
2357  *   drm_atomic_check_only for the YUV420-only mode with -EINVAL
2358  * - color format DRM_CONNECTOR_COLOR_FORMAT_YCBCR444 will fail
2359  *   drm_atomic_check_only for the YUV420-only mode with -EINVAL
2360  * - color format DRM_CONNECTOR_COLOR_FORMAT_YCBCR422 will fail
2361  *   drm_atomic_check_only for the YUV420-only mode with -EINVAL
2362  * - color format DRM_CONNECTOR_COLOR_FORMAT_YCBCR420 passes
2363  *   drm_atomic_check_only for the YUV420-only mode
2364  */
2365 static void drm_test_check_hdmi_color_format_420_only(struct kunit *test)
2366 {
2367 	const struct color_format_test_param *param = test->param_value;
2368 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2369 	struct drm_connector_state *conn_state;
2370 	struct drm_modeset_acquire_ctx ctx;
2371 	struct drm_crtc_state *crtc_state;
2372 	struct drm_atomic_commit *state;
2373 	struct drm_display_mode *dank;
2374 	int ret;
2375 
2376 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
2377 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
2378 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422) |
2379 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR420) |
2380 				BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444),
2381 				12,
2382 				&dummy_connector_hdmi_funcs,
2383 				test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz);
2384 	KUNIT_ASSERT_NOT_NULL(test, priv);
2385 
2386 	drm_modeset_acquire_init(&ctx, 0);
2387 
2388 	dank = find_420_only_mode(&priv->connector);
2389 	KUNIT_ASSERT_NOT_NULL(test, dank);
2390 
2391 	state = drm_kunit_helper_atomic_state_alloc(test, &priv->drm, &ctx);
2392 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
2393 
2394 	conn_state = drm_atomic_get_connector_state(state, &priv->connector);
2395 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
2396 
2397 	conn_state->color_format = param->fmt;
2398 
2399 	ret = drm_atomic_set_crtc_for_connector(conn_state, priv->crtc);
2400 	KUNIT_ASSERT_EQ(test, ret, 0);
2401 
2402 	crtc_state = drm_atomic_get_crtc_state(state, priv->crtc);
2403 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
2404 
2405 	ret = drm_atomic_set_mode_for_crtc(crtc_state, dank);
2406 	KUNIT_ASSERT_EQ(test, ret, 0);
2407 
2408 	crtc_state->enable = true;
2409 	crtc_state->active = true;
2410 
2411 	ret = drm_atomic_check_only(state);
2412 	KUNIT_EXPECT_EQ(test, ret, param->expected_ret);
2413 	if (!param->expected_ret)
2414 		KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, param->expected);
2415 
2416 	drm_modeset_drop_locks(&ctx);
2417 	drm_modeset_acquire_fini(&ctx);
2418 };
2419 
2420 static const struct color_format_test_param hdmi_color_format_420_only_params[] = {
2421 	{
2422 		.fmt = DRM_CONNECTOR_COLOR_FORMAT_RGB444,
2423 		.expected = DRM_OUTPUT_COLOR_FORMAT_RGB444,
2424 		.expected_ret = -EINVAL,
2425 		.desc = "RGB should fail"
2426 	},
2427 	{
2428 		.fmt = DRM_CONNECTOR_COLOR_FORMAT_YCBCR444,
2429 		.expected = DRM_OUTPUT_COLOR_FORMAT_YCBCR444,
2430 		.expected_ret = -EINVAL,
2431 		.desc = "YUV444 should fail"
2432 	},
2433 	{
2434 		.fmt = DRM_CONNECTOR_COLOR_FORMAT_YCBCR422,
2435 		.expected = DRM_OUTPUT_COLOR_FORMAT_YCBCR422,
2436 		.expected_ret = -EINVAL,
2437 		.desc = "YUV422 should fail"
2438 	},
2439 	{
2440 		.fmt = DRM_CONNECTOR_COLOR_FORMAT_YCBCR420,
2441 		.expected = DRM_OUTPUT_COLOR_FORMAT_YCBCR420,
2442 		.expected_ret = 0,
2443 		.desc = "YUV420 should work"
2444 	},
2445 };
2446 
2447 KUNIT_ARRAY_PARAM_DESC(check_hdmi_color_format_420_only,
2448 		       hdmi_color_format_420_only_params, desc);
2449 
2450 static struct kunit_case drm_atomic_helper_connector_hdmi_check_tests[] = {
2451 	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode),
2452 	KUNIT_CASE(drm_test_check_broadcast_rgb_auto_cea_mode_vic_1),
2453 	KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode),
2454 	KUNIT_CASE(drm_test_check_broadcast_rgb_full_cea_mode_vic_1),
2455 	KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode),
2456 	KUNIT_CASE(drm_test_check_broadcast_rgb_limited_cea_mode_vic_1),
2457 	KUNIT_CASE_PARAM(drm_test_check_broadcast_rgb_cea_mode_yuv420,
2458 			 check_broadcast_rgb_cea_mode_yuv420_gen_params),
2459 	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_changed),
2460 	KUNIT_CASE(drm_test_check_broadcast_rgb_crtc_mode_not_changed),
2461 	KUNIT_CASE(drm_test_check_disable_connector),
2462 	KUNIT_CASE(drm_test_check_hdmi_funcs_reject_rate),
2463 	KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback_rgb),
2464 	KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback_yuv420),
2465 	KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback_ignore_yuv422),
2466 	KUNIT_CASE(drm_test_check_max_tmds_rate_bpc_fallback_ignore_yuv420),
2467 	KUNIT_CASE(drm_test_check_driver_unsupported_fallback_yuv420),
2468 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_changed),
2469 	KUNIT_CASE(drm_test_check_output_bpc_crtc_mode_not_changed),
2470 	KUNIT_CASE(drm_test_check_output_bpc_dvi),
2471 	KUNIT_CASE(drm_test_check_output_bpc_format_vic_1),
2472 	KUNIT_CASE(drm_test_check_output_bpc_format_display_8bpc_only),
2473 	KUNIT_CASE(drm_test_check_output_bpc_format_display_rgb_only),
2474 	KUNIT_CASE(drm_test_check_output_bpc_format_driver_8bpc_only),
2475 	KUNIT_CASE(drm_test_check_output_bpc_format_driver_rgb_only),
2476 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_8bpc),
2477 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_10bpc),
2478 	KUNIT_CASE(drm_test_check_tmds_char_rate_rgb_12bpc),
2479 	KUNIT_CASE_PARAM(drm_test_check_hdmi_color_format,
2480 			 check_hdmi_color_format_gen_params),
2481 	KUNIT_CASE_PARAM(drm_test_check_hdmi_color_format_420_only,
2482 			 check_hdmi_color_format_420_only_gen_params),
2483 	/*
2484 	 * TODO: We should have tests to check that a change in the
2485 	 * format triggers a CRTC mode change just like we do for the
2486 	 * RGB Quantization and BPC.
2487 	 *
2488 	 * However, we don't have any way to control which format gets
2489 	 * picked up aside from changing the BPC or mode which would
2490 	 * already trigger a mode change.
2491 	 */
2492 	{ }
2493 };
2494 
2495 static struct kunit_suite drm_atomic_helper_connector_hdmi_check_test_suite = {
2496 	.name		= "drm_atomic_helper_connector_hdmi_check",
2497 	.test_cases	= drm_atomic_helper_connector_hdmi_check_tests,
2498 };
2499 
2500 /*
2501  * Test that the value of the Broadcast RGB property out of reset is set
2502  * to auto.
2503  */
2504 static void drm_test_check_broadcast_rgb_value(struct kunit *test)
2505 {
2506 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2507 	struct drm_connector_state *conn_state;
2508 	struct drm_connector *conn;
2509 
2510 	priv = drm_kunit_helper_connector_hdmi_init(test,
2511 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
2512 						    8);
2513 	KUNIT_ASSERT_NOT_NULL(test, priv);
2514 
2515 	conn = &priv->connector;
2516 	conn_state = conn->state;
2517 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.broadcast_rgb, DRM_HDMI_BROADCAST_RGB_AUTO);
2518 }
2519 
2520 /*
2521  * Test that if the connector was initialised with a maximum bpc of 8,
2522  * the value of the max_bpc and max_requested_bpc properties out of
2523  * reset are also set to 8, and output_bpc is set to 0 and will be
2524  * filled at atomic_check time.
2525  */
2526 static void drm_test_check_bpc_8_value(struct kunit *test)
2527 {
2528 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2529 	struct drm_connector_state *conn_state;
2530 	struct drm_connector *conn;
2531 
2532 	priv = drm_kunit_helper_connector_hdmi_init(test,
2533 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
2534 						    8);
2535 	KUNIT_ASSERT_NOT_NULL(test, priv);
2536 
2537 	conn = &priv->connector;
2538 	conn_state = conn->state;
2539 	KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 8);
2540 	KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 8);
2541 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
2542 }
2543 
2544 /*
2545  * Test that if the connector was initialised with a maximum bpc of 10,
2546  * the value of the max_bpc and max_requested_bpc properties out of
2547  * reset are also set to 10, and output_bpc is set to 0 and will be
2548  * filled at atomic_check time.
2549  */
2550 static void drm_test_check_bpc_10_value(struct kunit *test)
2551 {
2552 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2553 	struct drm_connector_state *conn_state;
2554 	struct drm_connector *conn;
2555 
2556 	priv = drm_kunit_helper_connector_hdmi_init(test,
2557 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
2558 						    10);
2559 	KUNIT_ASSERT_NOT_NULL(test, priv);
2560 
2561 	conn = &priv->connector;
2562 	conn_state = conn->state;
2563 	KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 10);
2564 	KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 10);
2565 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
2566 }
2567 
2568 /*
2569  * Test that if the connector was initialised with a maximum bpc of 12,
2570  * the value of the max_bpc and max_requested_bpc properties out of
2571  * reset are also set to 12, and output_bpc is set to 0 and will be
2572  * filled at atomic_check time.
2573  */
2574 static void drm_test_check_bpc_12_value(struct kunit *test)
2575 {
2576 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2577 	struct drm_connector_state *conn_state;
2578 	struct drm_connector *conn;
2579 
2580 	priv = drm_kunit_helper_connector_hdmi_init(test,
2581 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
2582 						    12);
2583 	KUNIT_ASSERT_NOT_NULL(test, priv);
2584 
2585 	conn = &priv->connector;
2586 	conn_state = conn->state;
2587 	KUNIT_EXPECT_EQ(test, conn_state->max_bpc, 12);
2588 	KUNIT_EXPECT_EQ(test, conn_state->max_requested_bpc, 12);
2589 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_bpc, 0);
2590 }
2591 
2592 /*
2593  * Test that the value of the output format property out of reset is set
2594  * to RGB, even if the driver supports more than that.
2595  */
2596 static void drm_test_check_format_value(struct kunit *test)
2597 {
2598 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2599 	struct drm_connector_state *conn_state;
2600 	struct drm_connector *conn;
2601 
2602 	priv = drm_kunit_helper_connector_hdmi_init(test,
2603 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
2604 						    BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422) |
2605 						    BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444),
2606 						    8);
2607 	KUNIT_ASSERT_NOT_NULL(test, priv);
2608 
2609 	conn = &priv->connector;
2610 	conn_state = conn->state;
2611 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.output_format, 0);
2612 }
2613 
2614 /*
2615  * Test that the value of the output format property out of reset is set
2616  * to 0, and will be computed at atomic_check time.
2617  */
2618 static void drm_test_check_tmds_char_value(struct kunit *test)
2619 {
2620 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2621 	struct drm_connector_state *conn_state;
2622 	struct drm_connector *conn;
2623 
2624 	priv = drm_kunit_helper_connector_hdmi_init(test,
2625 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444) |
2626 						    BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR422) |
2627 						    BIT(DRM_OUTPUT_COLOR_FORMAT_YCBCR444),
2628 						    12);
2629 	KUNIT_ASSERT_NOT_NULL(test, priv);
2630 
2631 	conn = &priv->connector;
2632 	conn_state = conn->state;
2633 	KUNIT_EXPECT_EQ(test, conn_state->hdmi.tmds_char_rate, 0);
2634 }
2635 
2636 static struct kunit_case drm_atomic_helper_connector_hdmi_reset_tests[] = {
2637 	KUNIT_CASE(drm_test_check_broadcast_rgb_value),
2638 	KUNIT_CASE(drm_test_check_bpc_8_value),
2639 	KUNIT_CASE(drm_test_check_bpc_10_value),
2640 	KUNIT_CASE(drm_test_check_bpc_12_value),
2641 	KUNIT_CASE(drm_test_check_format_value),
2642 	KUNIT_CASE(drm_test_check_tmds_char_value),
2643 	{ }
2644 };
2645 
2646 static struct kunit_suite drm_atomic_helper_connector_hdmi_reset_test_suite = {
2647 	.name		= "drm_atomic_helper_connector_hdmi_reset",
2648 	.test_cases	= drm_atomic_helper_connector_hdmi_reset_tests,
2649 };
2650 
2651 /*
2652  * Test that the default behaviour for drm_hdmi_connector_mode_valid() is not
2653  * to reject any modes. Pass a correct EDID and verify that preferred mode
2654  * matches the expectations (1080p).
2655  */
2656 static void drm_test_check_mode_valid(struct kunit *test)
2657 {
2658 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2659 	struct drm_connector *conn;
2660 	struct drm_display_mode *preferred;
2661 
2662 	priv = drm_kunit_helper_connector_hdmi_init(test,
2663 						    BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
2664 						    8);
2665 	KUNIT_ASSERT_NOT_NULL(test, priv);
2666 
2667 	conn = &priv->connector;
2668 	preferred = find_preferred_mode(conn);
2669 	KUNIT_ASSERT_NOT_NULL(test, preferred);
2670 
2671 	KUNIT_EXPECT_EQ(test, preferred->hdisplay, 1920);
2672 	KUNIT_EXPECT_EQ(test, preferred->vdisplay, 1080);
2673 	KUNIT_EXPECT_EQ(test, preferred->clock, 148500);
2674 }
2675 
2676 /*
2677  * Test that the drm_hdmi_connector_mode_valid() will reject modes depending on
2678  * the .tmds_char_rate_valid() behaviour.
2679  * Pass a correct EDID and verify that high-rate modes are filtered.
2680  */
2681 static void drm_test_check_mode_valid_reject_rate(struct kunit *test)
2682 {
2683 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2684 	struct drm_display_mode *preferred;
2685 
2686 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
2687 					BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
2688 					8,
2689 					&reject_100mhz_connector_hdmi_funcs,
2690 					test_edid_hdmi_1080p_rgb_max_200mhz);
2691 	KUNIT_ASSERT_NOT_NULL(test, priv);
2692 
2693 	/*
2694 	 * Unlike the drm_test_check_mode_valid() here 1080p is rejected, but
2695 	 * 480p is allowed.
2696 	 */
2697 	preferred = find_preferred_mode(&priv->connector);
2698 	KUNIT_ASSERT_NOT_NULL(test, preferred);
2699 	KUNIT_EXPECT_EQ(test, preferred->hdisplay, 640);
2700 	KUNIT_EXPECT_EQ(test, preferred->vdisplay, 480);
2701 	KUNIT_EXPECT_EQ(test, preferred->clock, 25200);
2702 }
2703 
2704 /*
2705  * Test that the drm_hdmi_connector_mode_valid() will not mark any modes as
2706  * valid if .tmds_char_rate_valid() rejects all of them. Pass a correct EDID
2707  * and verify that there is no preferred mode and no modes were set for the
2708  * connector.
2709  */
2710 static void drm_test_check_mode_valid_reject(struct kunit *test)
2711 {
2712 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2713 	struct drm_connector *conn;
2714 	struct drm_display_mode *preferred;
2715 	unsigned char no_edid[] = {};
2716 	int ret;
2717 
2718 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
2719 					BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
2720 					8,
2721 					&reject_connector_hdmi_funcs,
2722 					no_edid);
2723 	KUNIT_ASSERT_NOT_NULL(test, priv);
2724 
2725 	conn = &priv->connector;
2726 
2727 	/* should reject all modes */
2728 	ret = set_connector_edid(test, conn,
2729 				 test_edid_hdmi_1080p_rgb_max_200mhz,
2730 				 ARRAY_SIZE(test_edid_hdmi_1080p_rgb_max_200mhz));
2731 	KUNIT_ASSERT_EQ(test, ret, 0);
2732 
2733 	preferred = find_preferred_mode(conn);
2734 	KUNIT_ASSERT_NULL(test, preferred);
2735 }
2736 
2737 /*
2738  * Test that the drm_hdmi_connector_mode_valid() will reject modes that don't
2739  * pass the info.max_tmds_clock filter. Pass crafted EDID and verify that
2740  * high-rate modes are filtered.
2741  */
2742 static void drm_test_check_mode_valid_reject_max_clock(struct kunit *test)
2743 {
2744 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2745 	struct drm_connector *conn;
2746 	struct drm_display_mode *preferred;
2747 
2748 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
2749 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
2750 				8,
2751 				&dummy_connector_hdmi_funcs,
2752 				test_edid_hdmi_1080p_rgb_max_100mhz);
2753 	KUNIT_ASSERT_NOT_NULL(test, priv);
2754 
2755 	conn = &priv->connector;
2756 	KUNIT_ASSERT_EQ(test, conn->display_info.max_tmds_clock, 100 * 1000);
2757 
2758 	preferred = find_preferred_mode(conn);
2759 	KUNIT_ASSERT_NOT_NULL(test, preferred);
2760 	KUNIT_EXPECT_EQ(test, preferred->hdisplay, 640);
2761 	KUNIT_EXPECT_EQ(test, preferred->vdisplay, 480);
2762 	KUNIT_EXPECT_EQ(test, preferred->clock, 25200);
2763 }
2764 
2765 /*
2766  * Test that drm_hdmi_connector_mode_valid() will accept modes that require a
2767  * 4:2:0 chroma subsampling, even if said mode would violate maximum clock
2768  * constraints if it used RGB 4:4:4.
2769  */
2770 static void drm_test_check_mode_valid_yuv420_only_max_clock(struct kunit *test)
2771 {
2772 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2773 	struct drm_display_mode *dank;
2774 	struct drm_connector *conn;
2775 
2776 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
2777 				BIT(HDMI_COLORSPACE_RGB) |
2778 				BIT(HDMI_COLORSPACE_YUV420),
2779 				8,
2780 				&dummy_connector_hdmi_funcs,
2781 				test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz);
2782 	KUNIT_ASSERT_NOT_NULL(test, priv);
2783 
2784 	conn = &priv->connector;
2785 	KUNIT_ASSERT_EQ(test, conn->display_info.max_tmds_clock, 200 * 1000);
2786 
2787 	dank = find_420_only_mode(conn);
2788 	KUNIT_ASSERT_NOT_NULL(test, dank);
2789 	KUNIT_EXPECT_EQ(test, dank->hdisplay, 3840);
2790 	KUNIT_EXPECT_EQ(test, dank->vdisplay, 2160);
2791 
2792 	/*
2793 	 * Note: The mode's "clock" here is not accurate to the actual TMDS
2794 	 * clock that HDMI will use for a subsampled mode. Hence, why the mode's
2795 	 * clock is above the .max_tmds_clock of 200MHz.
2796 	 */
2797 	KUNIT_EXPECT_EQ(test, dank->clock, 297000);
2798 }
2799 
2800 /*
2801  * Test that drm_hdmi_connector_mode_valid() will reject modes that require
2802  * 4:2:0 chroma subsampling, if the connector does not support 4:2:0.
2803  */
2804 static void
2805 drm_test_check_mode_valid_reject_yuv420_only_connector(struct kunit *test)
2806 {
2807 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2808 	struct drm_display_mode *dank;
2809 	struct drm_connector *conn;
2810 
2811 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
2812 				BIT(HDMI_COLORSPACE_RGB),
2813 				8,
2814 				&dummy_connector_hdmi_funcs,
2815 				test_edid_hdmi_1080p_rgb_yuv_4k_yuv420_dc_max_200mhz);
2816 	KUNIT_ASSERT_NOT_NULL(test, priv);
2817 
2818 	conn = &priv->connector;
2819 	KUNIT_ASSERT_EQ(test, conn->display_info.max_tmds_clock, 200 * 1000);
2820 
2821 	dank = find_420_only_mode(conn);
2822 	KUNIT_EXPECT_NULL(test, dank);
2823 }
2824 
2825 /*
2826  * Test that drm_hdmi_connector_mode_valid() will accept modes that allow (among
2827  * other color formats) 4:2:0 chroma subsampling, even if the connector does not
2828  * support 4:2:0, but the mode's clock works for RGB 4:4:4.
2829  */
2830 static void
2831 drm_test_check_mode_valid_accept_yuv420_also_connector_rgb(struct kunit *test)
2832 {
2833 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2834 	struct drm_display_mode *mode;
2835 	struct drm_connector *conn;
2836 
2837 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
2838 				BIT(HDMI_COLORSPACE_RGB),
2839 				8,
2840 				&dummy_connector_hdmi_funcs,
2841 				test_edid_hdmi_4k_rgb_yuv420_dc_max_340mhz);
2842 	KUNIT_ASSERT_NOT_NULL(test, priv);
2843 
2844 	conn = &priv->connector;
2845 	KUNIT_ASSERT_EQ(test, conn->display_info.max_tmds_clock, 340 * 1000);
2846 
2847 	mode = find_420_also_mode(conn);
2848 	KUNIT_ASSERT_NOT_NULL(test, mode);
2849 	KUNIT_EXPECT_EQ(test, mode->hdisplay, 3840);
2850 	KUNIT_EXPECT_EQ(test, mode->vdisplay, 2160);
2851 	KUNIT_EXPECT_EQ(test, mode->clock, 297000);
2852 }
2853 
2854 static struct kunit_case drm_atomic_helper_connector_hdmi_mode_valid_tests[] = {
2855 	KUNIT_CASE(drm_test_check_mode_valid),
2856 	KUNIT_CASE(drm_test_check_mode_valid_reject),
2857 	KUNIT_CASE(drm_test_check_mode_valid_reject_rate),
2858 	KUNIT_CASE(drm_test_check_mode_valid_reject_max_clock),
2859 	KUNIT_CASE(drm_test_check_mode_valid_yuv420_only_max_clock),
2860 	KUNIT_CASE(drm_test_check_mode_valid_reject_yuv420_only_connector),
2861 	KUNIT_CASE(drm_test_check_mode_valid_accept_yuv420_also_connector_rgb),
2862 	{ }
2863 };
2864 
2865 static struct kunit_suite drm_atomic_helper_connector_hdmi_mode_valid_test_suite = {
2866 	.name		= "drm_atomic_helper_connector_hdmi_mode_valid",
2867 	.test_cases	= drm_atomic_helper_connector_hdmi_mode_valid_tests,
2868 };
2869 
2870 /*
2871  * Test that the default behaviour works without errors. We expect that
2872  * infoframe-related hooks are called and there are no errors raised.
2873  */
2874 static void drm_test_check_infoframes(struct kunit *test)
2875 {
2876 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2877 	struct drm_modeset_acquire_ctx ctx;
2878 	struct drm_crtc_state *crtc_state;
2879 	struct drm_atomic_commit *state;
2880 	struct drm_display_mode *preferred;
2881 	struct drm_connector *conn;
2882 	struct drm_device *drm;
2883 	struct drm_crtc *crtc;
2884 	int old_hdmi_update_failures;
2885 	int ret;
2886 
2887 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
2888 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
2889 				8,
2890 				&dummy_connector_hdmi_funcs,
2891 				test_edid_hdmi_1080p_rgb_max_200mhz);
2892 	KUNIT_ASSERT_NOT_NULL(test, priv);
2893 
2894 	drm = &priv->drm;
2895 	crtc = priv->crtc;
2896 	conn = &priv->connector;
2897 
2898 	preferred = find_preferred_mode(conn);
2899 	KUNIT_ASSERT_NOT_NULL(test, preferred);
2900 
2901 	drm_modeset_acquire_init(&ctx, 0);
2902 
2903 retry_conn_enable:
2904 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
2905 						     crtc, conn,
2906 						     preferred,
2907 						     &ctx);
2908 	if (ret == -EDEADLK) {
2909 		ret = drm_modeset_backoff(&ctx);
2910 		if (!ret)
2911 			goto retry_conn_enable;
2912 	}
2913 	KUNIT_ASSERT_EQ(test, ret, 0);
2914 
2915 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
2916 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
2917 
2918 retry_crtc_state:
2919 	crtc_state = drm_atomic_get_crtc_state(state, crtc);
2920 	if (PTR_ERR(crtc_state) == -EDEADLK) {
2921 		drm_atomic_commit_clear(state);
2922 		ret = drm_modeset_backoff(&ctx);
2923 		if (!ret)
2924 			goto retry_crtc_state;
2925 	}
2926 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
2927 
2928 	crtc_state->mode_changed = true;
2929 
2930 	old_hdmi_update_failures = priv->hdmi_update_failures;
2931 
2932 	ret = drm_atomic_check_only(state);
2933 	if (ret == -EDEADLK) {
2934 		drm_atomic_commit_clear(state);
2935 		ret = drm_modeset_backoff(&ctx);
2936 		if (!ret)
2937 			goto retry_crtc_state;
2938 	}
2939 	KUNIT_ASSERT_EQ(test, ret, 0);
2940 
2941 	ret = drm_atomic_commit(state);
2942 	if (ret == -EDEADLK) {
2943 		drm_atomic_commit_clear(state);
2944 		ret = drm_modeset_backoff(&ctx);
2945 		if (!ret)
2946 			goto retry_crtc_state;
2947 	}
2948 	KUNIT_ASSERT_EQ(test, ret, 0);
2949 
2950 	KUNIT_EXPECT_GE(test, old_hdmi_update_failures, priv->hdmi_update_failures);
2951 
2952 	drm_modeset_drop_locks(&ctx);
2953 	drm_modeset_acquire_fini(&ctx);
2954 }
2955 
2956 static int reject_infoframe_write_infoframe(struct drm_connector *connector,
2957 					    const u8 *buffer, size_t len)
2958 {
2959 	return -EOPNOTSUPP;
2960 }
2961 
2962 static const struct drm_connector_hdmi_funcs reject_avi_infoframe_hdmi_funcs = {
2963 	.avi = {
2964 		.clear_infoframe = accept_infoframe_clear_infoframe,
2965 		.write_infoframe = reject_infoframe_write_infoframe,
2966 	},
2967 	.hdmi = {
2968 		.clear_infoframe = accept_infoframe_clear_infoframe,
2969 		.write_infoframe = accept_infoframe_write_infoframe,
2970 	},
2971 };
2972 
2973 /*
2974  * Test that the rejection of AVI InfoFrame results in the failure of
2975  * drm_atomic_helper_connector_hdmi_update_infoframes().
2976  */
2977 static void drm_test_check_reject_avi_infoframe(struct kunit *test)
2978 {
2979 	struct drm_atomic_helper_connector_hdmi_priv *priv;
2980 	struct drm_modeset_acquire_ctx ctx;
2981 	struct drm_atomic_commit *state;
2982 	struct drm_crtc_state *crtc_state;
2983 	struct drm_display_mode *preferred;
2984 	struct drm_connector *conn;
2985 	struct drm_device *drm;
2986 	struct drm_crtc *crtc;
2987 	int old_hdmi_update_failures;
2988 	int ret;
2989 
2990 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
2991 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
2992 				8,
2993 				&reject_avi_infoframe_hdmi_funcs,
2994 				test_edid_hdmi_1080p_rgb_max_200mhz);
2995 	KUNIT_ASSERT_NOT_NULL(test, priv);
2996 
2997 	drm = &priv->drm;
2998 	crtc = priv->crtc;
2999 	conn = &priv->connector;
3000 
3001 	preferred = find_preferred_mode(conn);
3002 	KUNIT_ASSERT_NOT_NULL(test, preferred);
3003 
3004 	drm_modeset_acquire_init(&ctx, 0);
3005 
3006 retry_conn_enable:
3007 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
3008 						     crtc, conn,
3009 						     preferred,
3010 						     &ctx);
3011 	if (ret == -EDEADLK) {
3012 		ret = drm_modeset_backoff(&ctx);
3013 		if (!ret)
3014 			goto retry_conn_enable;
3015 	}
3016 	KUNIT_ASSERT_EQ(test, ret, 0);
3017 
3018 	drm_encoder_helper_add(&priv->encoder, &test_encoder_helper_funcs);
3019 
3020 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
3021 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
3022 
3023 retry_crtc_state:
3024 	crtc_state = drm_atomic_get_crtc_state(state, crtc);
3025 	if (PTR_ERR(crtc_state) == -EDEADLK) {
3026 		drm_atomic_commit_clear(state);
3027 		ret = drm_modeset_backoff(&ctx);
3028 		if (!ret)
3029 			goto retry_crtc_state;
3030 	}
3031 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
3032 
3033 	crtc_state->mode_changed = true;
3034 
3035 	old_hdmi_update_failures = priv->hdmi_update_failures;
3036 
3037 	ret = drm_atomic_check_only(state);
3038 	if (ret == -EDEADLK) {
3039 		drm_atomic_commit_clear(state);
3040 		ret = drm_modeset_backoff(&ctx);
3041 		if (!ret)
3042 			goto retry_crtc_state;
3043 	}
3044 	KUNIT_ASSERT_EQ(test, ret, 0);
3045 
3046 	ret = drm_atomic_commit(state);
3047 	if (ret == -EDEADLK) {
3048 		drm_atomic_commit_clear(state);
3049 		ret = drm_modeset_backoff(&ctx);
3050 		if (!ret)
3051 			goto retry_crtc_state;
3052 	}
3053 	KUNIT_ASSERT_EQ(test, ret, 0);
3054 
3055 	KUNIT_EXPECT_NE(test, old_hdmi_update_failures, priv->hdmi_update_failures);
3056 
3057 	drm_modeset_drop_locks(&ctx);
3058 	drm_modeset_acquire_fini(&ctx);
3059 }
3060 
3061 static const struct drm_connector_hdmi_funcs reject_hdr_infoframe_hdmi_funcs = {
3062 	.avi = {
3063 		.clear_infoframe = accept_infoframe_clear_infoframe,
3064 		.write_infoframe = accept_infoframe_write_infoframe,
3065 	},
3066 	.hdmi = {
3067 		.clear_infoframe = accept_infoframe_clear_infoframe,
3068 		.write_infoframe = accept_infoframe_write_infoframe,
3069 	},
3070 	.hdr_drm = {
3071 		.clear_infoframe = accept_infoframe_clear_infoframe,
3072 		.write_infoframe = reject_infoframe_write_infoframe,
3073 	},
3074 };
3075 
3076 /*
3077  * Test that the HDR InfoFrame isn't programmed in
3078  * drm_atomic_helper_connector_hdmi_update_infoframes() if the max_bpc is 8.
3079  */
3080 static void drm_test_check_reject_hdr_infoframe_bpc_8(struct kunit *test)
3081 {
3082 	struct drm_atomic_helper_connector_hdmi_priv *priv;
3083 	struct drm_modeset_acquire_ctx ctx;
3084 	struct drm_atomic_commit *state;
3085 	struct drm_connector_state *new_conn_state;
3086 	struct drm_crtc_state *crtc_state;
3087 	struct drm_display_mode *preferred;
3088 	struct drm_connector *conn;
3089 	struct drm_device *drm;
3090 	struct drm_crtc *crtc;
3091 	int old_hdmi_update_failures;
3092 	int ret;
3093 
3094 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
3095 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
3096 				8,
3097 				&reject_hdr_infoframe_hdmi_funcs,
3098 				test_edid_hdmi_1080p_rgb_max_200mhz_hdr);
3099 	KUNIT_ASSERT_NOT_NULL(test, priv);
3100 
3101 	drm = &priv->drm;
3102 	crtc = priv->crtc;
3103 	conn = &priv->connector;
3104 
3105 	preferred = find_preferred_mode(conn);
3106 	KUNIT_ASSERT_NOT_NULL(test, preferred);
3107 
3108 	drm_modeset_acquire_init(&ctx, 0);
3109 
3110 retry_conn_enable:
3111 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
3112 						     crtc, conn,
3113 						     preferred,
3114 						     &ctx);
3115 	if (ret == -EDEADLK) {
3116 		ret = drm_modeset_backoff(&ctx);
3117 		if (!ret)
3118 			goto retry_conn_enable;
3119 	}
3120 	KUNIT_ASSERT_EQ(test, ret, 0);
3121 
3122 	drm_encoder_helper_add(&priv->encoder, &test_encoder_helper_funcs);
3123 
3124 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
3125 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
3126 
3127 retry_conn_state:
3128 	new_conn_state = drm_atomic_get_connector_state(state, conn);
3129 	if (PTR_ERR(new_conn_state) == -EDEADLK) {
3130 		drm_atomic_commit_clear(state);
3131 		ret = drm_modeset_backoff(&ctx);
3132 		if (!ret)
3133 			goto retry_conn_state;
3134 	}
3135 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
3136 
3137 	crtc_state = drm_atomic_get_crtc_state(state, crtc);
3138 	if (PTR_ERR(crtc_state) == -EDEADLK) {
3139 		drm_atomic_commit_clear(state);
3140 		ret = drm_modeset_backoff(&ctx);
3141 		if (!ret)
3142 			goto retry_conn_state;
3143 	}
3144 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
3145 
3146 	/* Verify that there is no HDR property, so "userspace" can't set it. */
3147 	for (int i = 0; i < conn->base.properties->count; i++)
3148 		KUNIT_ASSERT_PTR_NE(test,
3149 				    drm->mode_config.hdr_output_metadata_property,
3150 				    conn->base.properties->properties[i]);
3151 
3152 	crtc_state->mode_changed = true;
3153 
3154 	old_hdmi_update_failures = priv->hdmi_update_failures;
3155 
3156 	ret = drm_atomic_check_only(state);
3157 	if (ret == -EDEADLK) {
3158 		drm_atomic_commit_clear(state);
3159 		ret = drm_modeset_backoff(&ctx);
3160 		if (!ret)
3161 			goto retry_conn_state;
3162 	}
3163 	KUNIT_ASSERT_EQ(test, ret, 0);
3164 
3165 	ret = drm_atomic_commit(state);
3166 	if (ret == -EDEADLK) {
3167 		drm_atomic_commit_clear(state);
3168 		ret = drm_modeset_backoff(&ctx);
3169 		if (!ret)
3170 			goto retry_conn_state;
3171 	}
3172 	KUNIT_ASSERT_EQ(test, ret, 0);
3173 
3174 	KUNIT_EXPECT_EQ(test, old_hdmi_update_failures, priv->hdmi_update_failures);
3175 
3176 	new_conn_state = conn->state;
3177 	KUNIT_ASSERT_NOT_NULL(test, new_conn_state);
3178 
3179 	KUNIT_ASSERT_EQ(test, new_conn_state->hdmi.output_bpc, 8);
3180 	KUNIT_ASSERT_EQ(test, new_conn_state->hdmi.infoframes.hdr_drm.set, false);
3181 
3182 	drm_modeset_drop_locks(&ctx);
3183 	drm_modeset_acquire_fini(&ctx);
3184 }
3185 
3186 /*
3187  * Test that the rejection of HDR InfoFrame results in the failure of
3188  * drm_atomic_helper_connector_hdmi_update_infoframes() in the high bpc is
3189  * supported.
3190  */
3191 static void drm_test_check_reject_hdr_infoframe_bpc_10(struct kunit *test)
3192 {
3193 	struct drm_atomic_helper_connector_hdmi_priv *priv;
3194 	struct drm_modeset_acquire_ctx ctx;
3195 	struct drm_atomic_commit *state;
3196 	struct drm_connector_state *new_conn_state;
3197 	struct drm_crtc_state *crtc_state;
3198 	struct drm_display_mode *preferred;
3199 	struct drm_connector *conn;
3200 	struct drm_device *drm;
3201 	struct drm_crtc *crtc;
3202 	int old_hdmi_update_failures;
3203 	struct hdr_output_metadata hdr_data;
3204 	struct drm_property_blob *hdr_blob;
3205 	bool replaced;
3206 	int ret;
3207 
3208 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
3209 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
3210 				10,
3211 				&reject_hdr_infoframe_hdmi_funcs,
3212 				test_edid_hdmi_1080p_rgb_max_200mhz_hdr);
3213 	KUNIT_ASSERT_NOT_NULL(test, priv);
3214 
3215 	drm = &priv->drm;
3216 	crtc = priv->crtc;
3217 	conn = &priv->connector;
3218 
3219 	preferred = find_preferred_mode(conn);
3220 	KUNIT_ASSERT_NOT_NULL(test, preferred);
3221 
3222 	drm_modeset_acquire_init(&ctx, 0);
3223 
3224 retry_conn_enable:
3225 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
3226 						     crtc, conn,
3227 						     preferred,
3228 						     &ctx);
3229 	if (ret == -EDEADLK) {
3230 		ret = drm_modeset_backoff(&ctx);
3231 		if (!ret)
3232 			goto retry_conn_enable;
3233 	}
3234 	KUNIT_ASSERT_EQ(test, ret, 0);
3235 
3236 	drm_encoder_helper_add(&priv->encoder, &test_encoder_helper_funcs);
3237 
3238 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
3239 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
3240 
3241 retry_conn_state:
3242 	new_conn_state = drm_atomic_get_connector_state(state, conn);
3243 	if (PTR_ERR(new_conn_state) == -EDEADLK) {
3244 		drm_atomic_commit_clear(state);
3245 		ret = drm_modeset_backoff(&ctx);
3246 		if (!ret)
3247 			goto retry_conn_state;
3248 	}
3249 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state);
3250 
3251 	crtc_state = drm_atomic_get_crtc_state(state, crtc);
3252 	if (PTR_ERR(crtc_state) == -EDEADLK) {
3253 		drm_atomic_commit_clear(state);
3254 		ret = drm_modeset_backoff(&ctx);
3255 		if (!ret)
3256 			goto retry_conn_state;
3257 	}
3258 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
3259 
3260 	hdr_data.metadata_type = HDMI_STATIC_METADATA_TYPE1;
3261 	hdr_data.hdmi_metadata_type1.eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
3262 	hdr_data.hdmi_metadata_type1.metadata_type = HDMI_STATIC_METADATA_TYPE1;
3263 
3264 	hdr_blob = drm_property_create_blob(drm, sizeof(hdr_data), &hdr_data);
3265 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hdr_blob);
3266 
3267 	ret = drm_property_replace_blob_from_id(drm,
3268 						&new_conn_state->hdr_output_metadata,
3269 						hdr_blob->base.id,
3270 						-1, sizeof(struct hdr_output_metadata), -1,
3271 						&replaced);
3272 	KUNIT_ASSERT_EQ(test, ret, 0);
3273 	KUNIT_ASSERT_EQ(test, replaced, true);
3274 
3275 	crtc_state->mode_changed = true;
3276 
3277 	old_hdmi_update_failures = priv->hdmi_update_failures;
3278 
3279 	ret = drm_atomic_check_only(state);
3280 	if (ret == -EDEADLK) {
3281 		drm_atomic_commit_clear(state);
3282 		ret = drm_modeset_backoff(&ctx);
3283 		if (!ret)
3284 			goto retry_conn_state;
3285 	}
3286 	KUNIT_ASSERT_EQ(test, ret, 0);
3287 
3288 	ret = drm_atomic_commit(state);
3289 	if (ret == -EDEADLK) {
3290 		drm_atomic_commit_clear(state);
3291 		ret = drm_modeset_backoff(&ctx);
3292 		if (!ret)
3293 			goto retry_conn_state;
3294 	}
3295 	KUNIT_ASSERT_EQ(test, ret, 0);
3296 
3297 	KUNIT_EXPECT_LE(test, old_hdmi_update_failures, priv->hdmi_update_failures);
3298 
3299 	new_conn_state = conn->state;
3300 	KUNIT_ASSERT_NOT_NULL(test, new_conn_state);
3301 
3302 	KUNIT_ASSERT_EQ(test, new_conn_state->hdmi.output_bpc, 10);
3303 	KUNIT_ASSERT_EQ(test, new_conn_state->hdmi.infoframes.hdr_drm.set, true);
3304 
3305 	drm_modeset_drop_locks(&ctx);
3306 	drm_modeset_acquire_fini(&ctx);
3307 }
3308 
3309 static const struct drm_connector_hdmi_funcs reject_audio_infoframe_hdmi_funcs = {
3310 	.avi = {
3311 		.clear_infoframe = accept_infoframe_clear_infoframe,
3312 		.write_infoframe = accept_infoframe_write_infoframe,
3313 	},
3314 	.hdmi = {
3315 		.clear_infoframe = accept_infoframe_clear_infoframe,
3316 		.write_infoframe = accept_infoframe_write_infoframe,
3317 	},
3318 	.audio = {
3319 		.clear_infoframe = accept_infoframe_clear_infoframe,
3320 		.write_infoframe = reject_infoframe_write_infoframe,
3321 	},
3322 };
3323 
3324 /*
3325  * Test that Audio InfoFrame is only programmed if we call a corresponding API,
3326  * thus the drivers can safely assume that they won't get Audio InfoFrames if
3327  * they don't call it.
3328  */
3329 static void drm_test_check_reject_audio_infoframe(struct kunit *test)
3330 {
3331 	struct drm_atomic_helper_connector_hdmi_priv *priv;
3332 	struct drm_modeset_acquire_ctx ctx;
3333 	struct drm_atomic_commit *state;
3334 	struct drm_crtc_state *crtc_state;
3335 	struct drm_display_mode *preferred;
3336 	struct drm_connector *conn;
3337 	struct drm_device *drm;
3338 	struct drm_crtc *crtc;
3339 	int old_hdmi_update_failures;
3340 	struct hdmi_audio_infoframe cea;
3341 	int ret;
3342 
3343 	priv = drm_kunit_helper_connector_hdmi_init_with_edid_funcs(test,
3344 				BIT(DRM_OUTPUT_COLOR_FORMAT_RGB444),
3345 				8,
3346 				&reject_audio_infoframe_hdmi_funcs,
3347 				test_edid_hdmi_1080p_rgb_max_200mhz);
3348 	KUNIT_ASSERT_NOT_NULL(test, priv);
3349 
3350 	drm = &priv->drm;
3351 	crtc = priv->crtc;
3352 	conn = &priv->connector;
3353 
3354 	preferred = find_preferred_mode(conn);
3355 	KUNIT_ASSERT_NOT_NULL(test, preferred);
3356 
3357 	drm_modeset_acquire_init(&ctx, 0);
3358 
3359 retry_conn_enable:
3360 	ret = drm_kunit_helper_enable_crtc_connector(test, drm,
3361 						     crtc, conn,
3362 						     preferred,
3363 						     &ctx);
3364 	if (ret == -EDEADLK) {
3365 		ret = drm_modeset_backoff(&ctx);
3366 		if (!ret)
3367 			goto retry_conn_enable;
3368 	}
3369 	KUNIT_ASSERT_EQ(test, ret, 0);
3370 
3371 	drm_encoder_helper_add(&priv->encoder, &test_encoder_helper_funcs);
3372 
3373 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
3374 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
3375 
3376 retry_crtc_state:
3377 	crtc_state = drm_atomic_get_crtc_state(state, crtc);
3378 	if (PTR_ERR(crtc_state) == -EDEADLK) {
3379 		drm_atomic_commit_clear(state);
3380 		ret = drm_modeset_backoff(&ctx);
3381 		if (!ret)
3382 			goto retry_crtc_state;
3383 	}
3384 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
3385 
3386 	crtc_state->mode_changed = true;
3387 
3388 	old_hdmi_update_failures = priv->hdmi_update_failures;
3389 
3390 	ret = drm_atomic_check_only(state);
3391 	if (ret == -EDEADLK) {
3392 		drm_atomic_commit_clear(state);
3393 		ret = drm_modeset_backoff(&ctx);
3394 		if (!ret)
3395 			goto retry_crtc_state;
3396 	}
3397 	KUNIT_ASSERT_EQ(test, ret, 0);
3398 
3399 	ret = drm_atomic_commit(state);
3400 	if (ret == -EDEADLK) {
3401 		drm_atomic_commit_clear(state);
3402 		ret = drm_modeset_backoff(&ctx);
3403 		if (!ret)
3404 			goto retry_crtc_state;
3405 	}
3406 	KUNIT_ASSERT_EQ(test, ret, 0);
3407 
3408 	KUNIT_EXPECT_EQ(test, old_hdmi_update_failures, priv->hdmi_update_failures);
3409 
3410 	/*
3411 	 * So, it works without Audio InfoFrame, let's fail with it in place,
3412 	 * checking that writing the infofraem actually gets triggered.
3413 	 */
3414 
3415 	hdmi_audio_infoframe_init(&cea);
3416 	cea.channels = 2;
3417 	cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
3418 	cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
3419 	cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
3420 
3421 	ret = drm_atomic_helper_connector_hdmi_update_audio_infoframe(conn, &cea);
3422 	KUNIT_ASSERT_EQ(test, ret, -EOPNOTSUPP);
3423 
3424 	state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
3425 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
3426 
3427 retry_crtc_state_2:
3428 	crtc_state = drm_atomic_get_crtc_state(state, crtc);
3429 	if (PTR_ERR(crtc_state) == -EDEADLK) {
3430 		drm_atomic_commit_clear(state);
3431 		ret = drm_modeset_backoff(&ctx);
3432 		if (!ret)
3433 			goto retry_crtc_state_2;
3434 	}
3435 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
3436 
3437 	crtc_state->mode_changed = true;
3438 
3439 	old_hdmi_update_failures = priv->hdmi_update_failures;
3440 
3441 	ret = drm_atomic_check_only(state);
3442 	if (ret == -EDEADLK) {
3443 		drm_atomic_commit_clear(state);
3444 		ret = drm_modeset_backoff(&ctx);
3445 		if (!ret)
3446 			goto retry_crtc_state_2;
3447 	}
3448 	KUNIT_ASSERT_EQ(test, ret, 0);
3449 
3450 	ret = drm_atomic_commit(state);
3451 	if (ret == -EDEADLK) {
3452 		drm_atomic_commit_clear(state);
3453 		ret = drm_modeset_backoff(&ctx);
3454 		if (!ret)
3455 			goto retry_crtc_state_2;
3456 	}
3457 	KUNIT_ASSERT_EQ(test, ret, 0);
3458 
3459 	KUNIT_EXPECT_LE(test, old_hdmi_update_failures, priv->hdmi_update_failures);
3460 
3461 	drm_modeset_drop_locks(&ctx);
3462 	drm_modeset_acquire_fini(&ctx);
3463 }
3464 
3465 
3466 static struct kunit_case drm_atomic_helper_connector_hdmi_infoframes_tests[] = {
3467 	KUNIT_CASE(drm_test_check_infoframes),
3468 	KUNIT_CASE(drm_test_check_reject_avi_infoframe),
3469 	KUNIT_CASE(drm_test_check_reject_hdr_infoframe_bpc_8),
3470 	KUNIT_CASE(drm_test_check_reject_hdr_infoframe_bpc_10),
3471 	KUNIT_CASE(drm_test_check_reject_audio_infoframe),
3472 	{ }
3473 };
3474 
3475 static struct kunit_suite drm_atomic_helper_connector_hdmi_infoframes_test_suite = {
3476 	.name		= "drm_atomic_helper_connector_hdmi_infoframes",
3477 	.test_cases	= drm_atomic_helper_connector_hdmi_infoframes_tests,
3478 };
3479 
3480 kunit_test_suites(
3481 	&drm_atomic_helper_connector_hdmi_check_test_suite,
3482 	&drm_atomic_helper_connector_hdmi_reset_test_suite,
3483 	&drm_atomic_helper_connector_hdmi_mode_valid_test_suite,
3484 	&drm_atomic_helper_connector_hdmi_infoframes_test_suite,
3485 );
3486 
3487 MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>");
3488 MODULE_DESCRIPTION("Kunit test for drm_hdmi_state_helper functions");
3489 MODULE_LICENSE("GPL");
3490