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