xref: /linux/drivers/gpu/drm/tests/drm_connector_test.c (revision 1cbfb828e05171ca2dd77b5988d068e6872480fe)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Kunit test for drm_modes functions
4  */
5 
6 #include <linux/i2c.h>
7 
8 #include <drm/drm_atomic_state_helper.h>
9 #include <drm/drm_connector.h>
10 #include <drm/drm_drv.h>
11 #include <drm/drm_edid.h>
12 #include <drm/drm_kunit_helpers.h>
13 #include <drm/drm_modes.h>
14 
15 #include <drm/display/drm_hdmi_helper.h>
16 
17 #include <kunit/test.h>
18 
19 #include "../drm_crtc_internal.h"
20 
21 struct drm_connector_init_priv {
22 	struct drm_device drm;
23 	struct drm_connector connector;
24 	struct i2c_adapter ddc;
25 };
26 
27 static const struct drm_connector_hdmi_funcs dummy_hdmi_funcs = {
28 };
29 
30 static const struct drm_connector_funcs dummy_funcs = {
31 	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
32 	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
33 	.reset			= drm_atomic_helper_connector_reset,
34 };
35 
36 static int dummy_ddc_xfer(struct i2c_adapter *adapter,
37 			  struct i2c_msg *msgs, int num)
38 {
39 	return num;
40 }
41 
42 static u32 dummy_ddc_func(struct i2c_adapter *adapter)
43 {
44 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
45 }
46 
47 static const struct i2c_algorithm dummy_ddc_algorithm = {
48 	.master_xfer = dummy_ddc_xfer,
49 	.functionality = dummy_ddc_func,
50 };
51 
52 static void i2c_del_adapter_wrapper(void *ptr)
53 {
54 	struct i2c_adapter *adap = ptr;
55 
56 	i2c_del_adapter(adap);
57 }
58 
59 static int drm_test_connector_init(struct kunit *test)
60 {
61 	struct drm_connector_init_priv *priv;
62 	struct device *dev;
63 	int ret;
64 
65 	dev = drm_kunit_helper_alloc_device(test);
66 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
67 
68 	priv = drm_kunit_helper_alloc_drm_device(test, dev,
69 						 struct drm_connector_init_priv, drm,
70 						 DRIVER_MODESET | DRIVER_ATOMIC);
71 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
72 
73 	strscpy(priv->ddc.name, "dummy-connector-ddc", sizeof(priv->ddc.name));
74 	priv->ddc.owner = THIS_MODULE;
75 	priv->ddc.algo = &dummy_ddc_algorithm;
76 	priv->ddc.dev.parent = dev;
77 
78 	ret = i2c_add_adapter(&priv->ddc);
79 	KUNIT_ASSERT_EQ(test, ret, 0);
80 
81 	ret = kunit_add_action_or_reset(test, i2c_del_adapter_wrapper, &priv->ddc);
82 	KUNIT_ASSERT_EQ(test, ret, 0);
83 
84 	test->priv = priv;
85 	return 0;
86 }
87 
88 /*
89  * Test that the registration of a bog standard connector works as
90  * expected and doesn't report any error.
91  */
92 static void drm_test_drmm_connector_init(struct kunit *test)
93 {
94 	struct drm_connector_init_priv *priv = test->priv;
95 	int ret;
96 
97 	ret = drmm_connector_init(&priv->drm, &priv->connector,
98 				  &dummy_funcs,
99 				  DRM_MODE_CONNECTOR_HDMIA,
100 				  &priv->ddc);
101 	KUNIT_EXPECT_EQ(test, ret, 0);
102 }
103 
104 /*
105  * Test that the registration of a connector without a DDC adapter
106  * doesn't report any error.
107  */
108 static void drm_test_drmm_connector_init_null_ddc(struct kunit *test)
109 {
110 	struct drm_connector_init_priv *priv = test->priv;
111 	int ret;
112 
113 	ret = drmm_connector_init(&priv->drm, &priv->connector,
114 				  &dummy_funcs,
115 				  DRM_MODE_CONNECTOR_HDMIA,
116 				  NULL);
117 	KUNIT_EXPECT_EQ(test, ret, 0);
118 }
119 
120 /*
121  * Test that the registration of a connector succeeds for all possible
122  * connector types.
123  */
124 static void drm_test_drmm_connector_init_type_valid(struct kunit *test)
125 {
126 	struct drm_connector_init_priv *priv = test->priv;
127 	unsigned int connector_type = *(unsigned int *)test->param_value;
128 	int ret;
129 
130 	ret = drmm_connector_init(&priv->drm, &priv->connector,
131 				  &dummy_funcs,
132 				  connector_type,
133 				  &priv->ddc);
134 	KUNIT_EXPECT_EQ(test, ret, 0);
135 }
136 
137 static const unsigned int drm_connector_init_type_valid_tests[] = {
138 	DRM_MODE_CONNECTOR_Unknown,
139 	DRM_MODE_CONNECTOR_VGA,
140 	DRM_MODE_CONNECTOR_DVII,
141 	DRM_MODE_CONNECTOR_DVID,
142 	DRM_MODE_CONNECTOR_DVIA,
143 	DRM_MODE_CONNECTOR_Composite,
144 	DRM_MODE_CONNECTOR_SVIDEO,
145 	DRM_MODE_CONNECTOR_LVDS,
146 	DRM_MODE_CONNECTOR_Component,
147 	DRM_MODE_CONNECTOR_9PinDIN,
148 	DRM_MODE_CONNECTOR_DisplayPort,
149 	DRM_MODE_CONNECTOR_HDMIA,
150 	DRM_MODE_CONNECTOR_HDMIB,
151 	DRM_MODE_CONNECTOR_TV,
152 	DRM_MODE_CONNECTOR_eDP,
153 	DRM_MODE_CONNECTOR_VIRTUAL,
154 	DRM_MODE_CONNECTOR_DSI,
155 	DRM_MODE_CONNECTOR_DPI,
156 	DRM_MODE_CONNECTOR_WRITEBACK,
157 	DRM_MODE_CONNECTOR_SPI,
158 	DRM_MODE_CONNECTOR_USB,
159 };
160 
161 static void drm_connector_init_type_desc(const unsigned int *type, char *desc)
162 {
163 	sprintf(desc, "%s", drm_get_connector_type_name(*type));
164 }
165 
166 KUNIT_ARRAY_PARAM(drm_connector_init_type_valid,
167 		  drm_connector_init_type_valid_tests,
168 		  drm_connector_init_type_desc);
169 
170 static struct kunit_case drmm_connector_init_tests[] = {
171 	KUNIT_CASE(drm_test_drmm_connector_init),
172 	KUNIT_CASE(drm_test_drmm_connector_init_null_ddc),
173 	KUNIT_CASE_PARAM(drm_test_drmm_connector_init_type_valid,
174 			 drm_connector_init_type_valid_gen_params),
175 	{ }
176 };
177 
178 static struct kunit_suite drmm_connector_init_test_suite = {
179 	.name = "drmm_connector_init",
180 	.init = drm_test_connector_init,
181 	.test_cases = drmm_connector_init_tests,
182 };
183 
184 /*
185  * Test that the registration of a bog standard connector works as
186  * expected and doesn't report any error.
187  */
188 static void drm_test_connector_hdmi_init_valid(struct kunit *test)
189 {
190 	struct drm_connector_init_priv *priv = test->priv;
191 	int ret;
192 
193 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
194 				       "Vendor", "Product",
195 				       &dummy_funcs,
196 				       &dummy_hdmi_funcs,
197 				       DRM_MODE_CONNECTOR_HDMIA,
198 				       &priv->ddc,
199 				       BIT(HDMI_COLORSPACE_RGB),
200 				       8);
201 	KUNIT_EXPECT_EQ(test, ret, 0);
202 }
203 
204 /*
205  * Test that the registration of a connector without a DDC adapter
206  * doesn't report any error.
207  */
208 static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
209 {
210 	struct drm_connector_init_priv *priv = test->priv;
211 	int ret;
212 
213 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
214 				       "Vendor", "Product",
215 				       &dummy_funcs,
216 				       &dummy_hdmi_funcs,
217 				       DRM_MODE_CONNECTOR_HDMIA,
218 				       NULL,
219 				       BIT(HDMI_COLORSPACE_RGB),
220 				       8);
221 	KUNIT_EXPECT_EQ(test, ret, 0);
222 }
223 
224 /*
225  * Test that the registration of an HDMI connector with a NULL vendor
226  * fails.
227  */
228 static void drm_test_connector_hdmi_init_null_vendor(struct kunit *test)
229 {
230 	struct drm_connector_init_priv *priv = test->priv;
231 	int ret;
232 
233 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
234 				       NULL, "Product",
235 				       &dummy_funcs,
236 				       &dummy_hdmi_funcs,
237 				       DRM_MODE_CONNECTOR_HDMIA,
238 				       &priv->ddc,
239 				       BIT(HDMI_COLORSPACE_RGB),
240 				       8);
241 	KUNIT_EXPECT_LT(test, ret, 0);
242 }
243 
244 /*
245  * Test that the registration of an HDMI connector with a NULL product
246  * fails.
247  */
248 static void drm_test_connector_hdmi_init_null_product(struct kunit *test)
249 {
250 	struct drm_connector_init_priv *priv = test->priv;
251 	int ret;
252 
253 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
254 				       "Vendor", NULL,
255 				       &dummy_funcs,
256 				       &dummy_hdmi_funcs,
257 				       DRM_MODE_CONNECTOR_HDMIA,
258 				       &priv->ddc,
259 				       BIT(HDMI_COLORSPACE_RGB),
260 				       8);
261 	KUNIT_EXPECT_LT(test, ret, 0);
262 }
263 
264 /*
265  * Test that the registration of a connector with a valid, shorter than
266  * the max length, product name succeeds, and is stored padded with 0.
267  */
268 static void drm_test_connector_hdmi_init_product_valid(struct kunit *test)
269 {
270 	struct drm_connector_init_priv *priv = test->priv;
271 	const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
272 		'P', 'r', 'o', 'd',
273 	};
274 	const char *product_name = "Prod";
275 	int ret;
276 
277 	KUNIT_ASSERT_LT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
278 
279 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
280 				       "Vendor", product_name,
281 				       &dummy_funcs,
282 				       &dummy_hdmi_funcs,
283 				       DRM_MODE_CONNECTOR_HDMIA,
284 				       &priv->ddc,
285 				       BIT(HDMI_COLORSPACE_RGB),
286 				       8);
287 	KUNIT_EXPECT_EQ(test, ret, 0);
288 	KUNIT_EXPECT_MEMEQ(test,
289 			   priv->connector.hdmi.product,
290 			   expected_product,
291 			   sizeof(priv->connector.hdmi.product));
292 }
293 
294 /*
295  * Test that the registration of a connector with a valid, at max
296  * length, product name succeeds, and is stored padded without any
297  * trailing \0.
298  */
299 static void drm_test_connector_hdmi_init_product_length_exact(struct kunit *test)
300 {
301 	struct drm_connector_init_priv *priv = test->priv;
302 	const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
303 		'P', 'r', 'o', 'd', 'u', 'c', 't',
304 		'P', 'r', 'o', 'd', 'u', 'c', 't',
305 		'P', 'r',
306 	};
307 	const char *product_name = "ProductProductPr";
308 	int ret;
309 
310 	KUNIT_ASSERT_EQ(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
311 
312 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
313 				       "Vendor", product_name,
314 				       &dummy_funcs,
315 				       &dummy_hdmi_funcs,
316 				       DRM_MODE_CONNECTOR_HDMIA,
317 				       &priv->ddc,
318 				       BIT(HDMI_COLORSPACE_RGB),
319 				       8);
320 	KUNIT_EXPECT_EQ(test, ret, 0);
321 	KUNIT_EXPECT_MEMEQ(test,
322 			   priv->connector.hdmi.product,
323 			   expected_product,
324 			   sizeof(priv->connector.hdmi.product));
325 }
326 
327 /*
328  * Test that the registration of a connector with a product name larger
329  * than the maximum length fails.
330  */
331 static void drm_test_connector_hdmi_init_product_length_too_long(struct kunit *test)
332 {
333 	struct drm_connector_init_priv *priv = test->priv;
334 	const char *product_name = "ProductProductProduct";
335 	int ret;
336 
337 	KUNIT_ASSERT_GT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
338 
339 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
340 				       "Vendor", product_name,
341 				       &dummy_funcs,
342 				       &dummy_hdmi_funcs,
343 				       DRM_MODE_CONNECTOR_HDMIA,
344 				       &priv->ddc,
345 				       BIT(HDMI_COLORSPACE_RGB),
346 				       8);
347 	KUNIT_EXPECT_LT(test, ret, 0);
348 }
349 
350 /*
351  * Test that the registration of a connector with a vendor name smaller
352  * than the maximum length succeeds, and is stored padded with zeros.
353  */
354 static void drm_test_connector_hdmi_init_vendor_valid(struct kunit *test)
355 {
356 	struct drm_connector_init_priv *priv = test->priv;
357 	const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = {
358 		'V', 'e', 'n', 'd',
359 	};
360 	const char *vendor_name = "Vend";
361 	int ret;
362 
363 	KUNIT_ASSERT_LT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
364 
365 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
366 				       vendor_name, "Product",
367 				       &dummy_funcs,
368 				       &dummy_hdmi_funcs,
369 				       DRM_MODE_CONNECTOR_HDMIA,
370 				       &priv->ddc,
371 				       BIT(HDMI_COLORSPACE_RGB),
372 				       8);
373 	KUNIT_EXPECT_EQ(test, ret, 0);
374 	KUNIT_EXPECT_MEMEQ(test,
375 			   priv->connector.hdmi.vendor,
376 			   expected_vendor,
377 			   sizeof(priv->connector.hdmi.vendor));
378 }
379 
380 /*
381  * Test that the registration of a connector with a vendor name at the
382  * maximum length succeeds, and is stored padded without the trailing
383  * zero.
384  */
385 static void drm_test_connector_hdmi_init_vendor_length_exact(struct kunit *test)
386 {
387 	struct drm_connector_init_priv *priv = test->priv;
388 	const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = {
389 		'V', 'e', 'n', 'd', 'o', 'r',
390 		'V', 'e',
391 	};
392 	const char *vendor_name = "VendorVe";
393 	int ret;
394 
395 	KUNIT_ASSERT_EQ(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
396 
397 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
398 				       vendor_name, "Product",
399 				       &dummy_funcs,
400 				       &dummy_hdmi_funcs,
401 				       DRM_MODE_CONNECTOR_HDMIA,
402 				       &priv->ddc,
403 				       BIT(HDMI_COLORSPACE_RGB),
404 				       8);
405 	KUNIT_EXPECT_EQ(test, ret, 0);
406 	KUNIT_EXPECT_MEMEQ(test,
407 			   priv->connector.hdmi.vendor,
408 			   expected_vendor,
409 			   sizeof(priv->connector.hdmi.vendor));
410 }
411 
412 /*
413  * Test that the registration of a connector with a vendor name larger
414  * than the maximum length fails.
415  */
416 static void drm_test_connector_hdmi_init_vendor_length_too_long(struct kunit *test)
417 {
418 	struct drm_connector_init_priv *priv = test->priv;
419 	const char *vendor_name = "VendorVendor";
420 	int ret;
421 
422 	KUNIT_ASSERT_GT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
423 
424 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
425 				       vendor_name, "Product",
426 				       &dummy_funcs,
427 				       &dummy_hdmi_funcs,
428 				       DRM_MODE_CONNECTOR_HDMIA,
429 				       &priv->ddc,
430 				       BIT(HDMI_COLORSPACE_RGB),
431 				       8);
432 	KUNIT_EXPECT_LT(test, ret, 0);
433 }
434 
435 /*
436  * Test that the registration of a connector with an invalid maximum bpc
437  * count fails.
438  */
439 static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test)
440 {
441 	struct drm_connector_init_priv *priv = test->priv;
442 	int ret;
443 
444 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
445 				       "Vendor", "Product",
446 				       &dummy_funcs,
447 				       &dummy_hdmi_funcs,
448 				       DRM_MODE_CONNECTOR_HDMIA,
449 				       &priv->ddc,
450 				       BIT(HDMI_COLORSPACE_RGB),
451 				       9);
452 	KUNIT_EXPECT_LT(test, ret, 0);
453 }
454 
455 /*
456  * Test that the registration of a connector with a null maximum bpc
457  * count fails.
458  */
459 static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test)
460 {
461 	struct drm_connector_init_priv *priv = test->priv;
462 	int ret;
463 
464 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
465 				       "Vendor", "Product",
466 				       &dummy_funcs,
467 				       &dummy_hdmi_funcs,
468 				       DRM_MODE_CONNECTOR_HDMIA,
469 				       &priv->ddc,
470 				       BIT(HDMI_COLORSPACE_RGB),
471 				       0);
472 	KUNIT_EXPECT_LT(test, ret, 0);
473 }
474 
475 /*
476  * Test that the registration of a connector with a maximum bpc count of
477  * 8 succeeds, registers the max bpc property, but doesn't register the
478  * HDR output metadata one.
479  */
480 static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test)
481 {
482 	struct drm_connector_init_priv *priv = test->priv;
483 	struct drm_connector_state *state;
484 	struct drm_connector *connector = &priv->connector;
485 	struct drm_property *prop;
486 	uint64_t val;
487 	int ret;
488 
489 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
490 				       "Vendor", "Product",
491 				       &dummy_funcs,
492 				       &dummy_hdmi_funcs,
493 				       DRM_MODE_CONNECTOR_HDMIA,
494 				       &priv->ddc,
495 				       BIT(HDMI_COLORSPACE_RGB),
496 				       8);
497 	KUNIT_EXPECT_EQ(test, ret, 0);
498 
499 	prop = connector->max_bpc_property;
500 	KUNIT_ASSERT_NOT_NULL(test, prop);
501 	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
502 
503 	ret = drm_object_property_get_default_value(&connector->base, prop, &val);
504 	KUNIT_EXPECT_EQ(test, ret, 0);
505 	KUNIT_EXPECT_EQ(test, val, 8);
506 
507 	state = connector->state;
508 	KUNIT_EXPECT_EQ(test, state->max_bpc, 8);
509 	KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 8);
510 
511 	prop = priv->drm.mode_config.hdr_output_metadata_property;
512 	KUNIT_ASSERT_NOT_NULL(test, prop);
513 	KUNIT_EXPECT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
514 }
515 
516 /*
517  * Test that the registration of a connector with a maximum bpc count of
518  * 10 succeeds and registers the max bpc and HDR output metadata
519  * properties.
520  */
521 static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test)
522 {
523 	struct drm_connector_init_priv *priv = test->priv;
524 	struct drm_connector_state *state;
525 	struct drm_connector *connector = &priv->connector;
526 	struct drm_property *prop;
527 	uint64_t val;
528 	int ret;
529 
530 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
531 				       "Vendor", "Product",
532 				       &dummy_funcs,
533 				       &dummy_hdmi_funcs,
534 				       DRM_MODE_CONNECTOR_HDMIA,
535 				       &priv->ddc,
536 				       BIT(HDMI_COLORSPACE_RGB),
537 				       10);
538 	KUNIT_EXPECT_EQ(test, ret, 0);
539 
540 	prop = connector->max_bpc_property;
541 	KUNIT_ASSERT_NOT_NULL(test, prop);
542 	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
543 
544 	ret = drm_object_property_get_default_value(&connector->base, prop, &val);
545 	KUNIT_EXPECT_EQ(test, ret, 0);
546 	KUNIT_EXPECT_EQ(test, val, 10);
547 
548 	state = connector->state;
549 	KUNIT_EXPECT_EQ(test, state->max_bpc, 10);
550 	KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 10);
551 
552 	prop = priv->drm.mode_config.hdr_output_metadata_property;
553 	KUNIT_ASSERT_NOT_NULL(test, prop);
554 	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
555 }
556 
557 /*
558  * Test that the registration of a connector with a maximum bpc count of
559  * 12 succeeds and registers the max bpc and HDR output metadata
560  * properties.
561  */
562 static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
563 {
564 	struct drm_connector_init_priv *priv = test->priv;
565 	struct drm_connector_state *state;
566 	struct drm_connector *connector = &priv->connector;
567 	struct drm_property *prop;
568 	uint64_t val;
569 	int ret;
570 
571 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
572 				       "Vendor", "Product",
573 				       &dummy_funcs,
574 				       &dummy_hdmi_funcs,
575 				       DRM_MODE_CONNECTOR_HDMIA,
576 				       &priv->ddc,
577 				       BIT(HDMI_COLORSPACE_RGB),
578 				       12);
579 	KUNIT_EXPECT_EQ(test, ret, 0);
580 
581 	prop = connector->max_bpc_property;
582 	KUNIT_ASSERT_NOT_NULL(test, prop);
583 	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
584 
585 	ret = drm_object_property_get_default_value(&connector->base, prop, &val);
586 	KUNIT_EXPECT_EQ(test, ret, 0);
587 	KUNIT_EXPECT_EQ(test, val, 12);
588 
589 	state = connector->state;
590 	KUNIT_EXPECT_EQ(test, state->max_bpc, 12);
591 	KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 12);
592 
593 	prop = priv->drm.mode_config.hdr_output_metadata_property;
594 	KUNIT_ASSERT_NOT_NULL(test, prop);
595 	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
596 }
597 
598 /*
599  * Test that the registration of an HDMI connector with no supported
600  * format fails.
601  */
602 static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test)
603 {
604 	struct drm_connector_init_priv *priv = test->priv;
605 	int ret;
606 
607 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
608 				       "Vendor", "Product",
609 				       &dummy_funcs,
610 				       &dummy_hdmi_funcs,
611 				       DRM_MODE_CONNECTOR_HDMIA,
612 				       &priv->ddc,
613 				       0,
614 				       8);
615 	KUNIT_EXPECT_LT(test, ret, 0);
616 }
617 
618 /*
619  * Test that the registration of an HDMI connector not listing RGB as a
620  * supported format fails.
621  */
622 static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test)
623 {
624 	struct drm_connector_init_priv *priv = test->priv;
625 	int ret;
626 
627 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
628 				       "Vendor", "Product",
629 				       &dummy_funcs,
630 				       &dummy_hdmi_funcs,
631 				       DRM_MODE_CONNECTOR_HDMIA,
632 				       &priv->ddc,
633 				       BIT(HDMI_COLORSPACE_YUV422),
634 				       8);
635 	KUNIT_EXPECT_LT(test, ret, 0);
636 }
637 
638 struct drm_connector_hdmi_init_formats_yuv420_allowed_test {
639 	unsigned long supported_formats;
640 	bool yuv420_allowed;
641 	int expected_result;
642 };
643 
644 #define YUV420_ALLOWED_TEST(_formats, _allowed, _result)			\
645 	{									\
646 		.supported_formats = BIT(HDMI_COLORSPACE_RGB) | (_formats),	\
647 		.yuv420_allowed = _allowed,					\
648 		.expected_result = _result,					\
649 	}
650 
651 static const struct drm_connector_hdmi_init_formats_yuv420_allowed_test
652 drm_connector_hdmi_init_formats_yuv420_allowed_tests[] = {
653 	YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV420), true, 0),
654 	YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV420), false, -EINVAL),
655 	YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV422), true, -EINVAL),
656 	YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV422), false, 0),
657 };
658 
659 static void
660 drm_connector_hdmi_init_formats_yuv420_allowed_desc(const struct drm_connector_hdmi_init_formats_yuv420_allowed_test *t,
661 						    char *desc)
662 {
663 	sprintf(desc, "supported_formats=0x%lx yuv420_allowed=%d",
664 		t->supported_formats, t->yuv420_allowed);
665 }
666 
667 KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_formats_yuv420_allowed,
668 		  drm_connector_hdmi_init_formats_yuv420_allowed_tests,
669 		  drm_connector_hdmi_init_formats_yuv420_allowed_desc);
670 
671 /*
672  * Test that the registration of an HDMI connector succeeds only when
673  * the presence of YUV420 in the supported formats matches the value
674  * of the ycbcr_420_allowed flag.
675  */
676 static void drm_test_connector_hdmi_init_formats_yuv420_allowed(struct kunit *test)
677 {
678 	const struct drm_connector_hdmi_init_formats_yuv420_allowed_test *params;
679 	struct drm_connector_init_priv *priv = test->priv;
680 	int ret;
681 
682 	params = test->param_value;
683 	priv->connector.ycbcr_420_allowed = params->yuv420_allowed;
684 
685 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
686 				       "Vendor", "Product",
687 				       &dummy_funcs,
688 				       &dummy_hdmi_funcs,
689 				       DRM_MODE_CONNECTOR_HDMIA,
690 				       &priv->ddc,
691 				       params->supported_formats,
692 				       8);
693 	KUNIT_EXPECT_EQ(test, ret, params->expected_result);
694 }
695 
696 /*
697  * Test that the registration of an HDMI connector with an HDMI
698  * connector type succeeds.
699  */
700 static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
701 {
702 	struct drm_connector_init_priv *priv = test->priv;
703 	unsigned int connector_type = *(unsigned int *)test->param_value;
704 	int ret;
705 
706 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
707 				       "Vendor", "Product",
708 				       &dummy_funcs,
709 				       &dummy_hdmi_funcs,
710 				       connector_type,
711 				       &priv->ddc,
712 				       BIT(HDMI_COLORSPACE_RGB),
713 				       8);
714 	KUNIT_EXPECT_EQ(test, ret, 0);
715 }
716 
717 static const unsigned int drm_connector_hdmi_init_type_valid_tests[] = {
718 	DRM_MODE_CONNECTOR_HDMIA,
719 	DRM_MODE_CONNECTOR_HDMIB,
720 };
721 
722 static void drm_connector_hdmi_init_type_desc(const unsigned int *type, char *desc)
723 {
724 	sprintf(desc, "%s", drm_get_connector_type_name(*type));
725 }
726 
727 KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_valid,
728 		  drm_connector_hdmi_init_type_valid_tests,
729 		  drm_connector_hdmi_init_type_desc);
730 
731 /*
732  * Test that the registration of an HDMI connector with an !HDMI
733  * connector type fails.
734  */
735 static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
736 {
737 	struct drm_connector_init_priv *priv = test->priv;
738 	unsigned int connector_type = *(unsigned int *)test->param_value;
739 	int ret;
740 
741 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
742 				       "Vendor", "Product",
743 				       &dummy_funcs,
744 				       &dummy_hdmi_funcs,
745 				       connector_type,
746 				       &priv->ddc,
747 				       BIT(HDMI_COLORSPACE_RGB),
748 				       8);
749 	KUNIT_EXPECT_LT(test, ret, 0);
750 }
751 
752 static const unsigned int drm_connector_hdmi_init_type_invalid_tests[] = {
753 	DRM_MODE_CONNECTOR_Unknown,
754 	DRM_MODE_CONNECTOR_VGA,
755 	DRM_MODE_CONNECTOR_DVII,
756 	DRM_MODE_CONNECTOR_DVID,
757 	DRM_MODE_CONNECTOR_DVIA,
758 	DRM_MODE_CONNECTOR_Composite,
759 	DRM_MODE_CONNECTOR_SVIDEO,
760 	DRM_MODE_CONNECTOR_LVDS,
761 	DRM_MODE_CONNECTOR_Component,
762 	DRM_MODE_CONNECTOR_9PinDIN,
763 	DRM_MODE_CONNECTOR_DisplayPort,
764 	DRM_MODE_CONNECTOR_TV,
765 	DRM_MODE_CONNECTOR_eDP,
766 	DRM_MODE_CONNECTOR_VIRTUAL,
767 	DRM_MODE_CONNECTOR_DSI,
768 	DRM_MODE_CONNECTOR_DPI,
769 	DRM_MODE_CONNECTOR_WRITEBACK,
770 	DRM_MODE_CONNECTOR_SPI,
771 	DRM_MODE_CONNECTOR_USB,
772 };
773 
774 KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid,
775 		  drm_connector_hdmi_init_type_invalid_tests,
776 		  drm_connector_hdmi_init_type_desc);
777 
778 static struct kunit_case drmm_connector_hdmi_init_tests[] = {
779 	KUNIT_CASE(drm_test_connector_hdmi_init_valid),
780 	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_8),
781 	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_10),
782 	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_12),
783 	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_invalid),
784 	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null),
785 	KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty),
786 	KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb),
787 	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_formats_yuv420_allowed,
788 			 drm_connector_hdmi_init_formats_yuv420_allowed_gen_params),
789 	KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc),
790 	KUNIT_CASE(drm_test_connector_hdmi_init_null_product),
791 	KUNIT_CASE(drm_test_connector_hdmi_init_null_vendor),
792 	KUNIT_CASE(drm_test_connector_hdmi_init_product_length_exact),
793 	KUNIT_CASE(drm_test_connector_hdmi_init_product_length_too_long),
794 	KUNIT_CASE(drm_test_connector_hdmi_init_product_valid),
795 	KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_exact),
796 	KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_too_long),
797 	KUNIT_CASE(drm_test_connector_hdmi_init_vendor_valid),
798 	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid,
799 			 drm_connector_hdmi_init_type_valid_gen_params),
800 	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid,
801 			 drm_connector_hdmi_init_type_invalid_gen_params),
802 	{ }
803 };
804 
805 static struct kunit_suite drmm_connector_hdmi_init_test_suite = {
806 	.name = "drmm_connector_hdmi_init",
807 	.init = drm_test_connector_init,
808 	.test_cases = drmm_connector_hdmi_init_tests,
809 };
810 
811 struct drm_get_tv_mode_from_name_test {
812 	const char *name;
813 	enum drm_connector_tv_mode expected_mode;
814 };
815 
816 #define TV_MODE_NAME(_name, _mode)		\
817 	{					\
818 		.name = _name,			\
819 		.expected_mode = _mode,		\
820 	}
821 
822 static void drm_test_get_tv_mode_from_name_valid(struct kunit *test)
823 {
824 	const struct drm_get_tv_mode_from_name_test *params = test->param_value;
825 
826 	KUNIT_EXPECT_EQ(test,
827 			drm_get_tv_mode_from_name(params->name, strlen(params->name)),
828 			params->expected_mode);
829 }
830 
831 static const
832 struct drm_get_tv_mode_from_name_test drm_get_tv_mode_from_name_valid_tests[] = {
833 	TV_MODE_NAME("NTSC", DRM_MODE_TV_MODE_NTSC),
834 	TV_MODE_NAME("NTSC-443", DRM_MODE_TV_MODE_NTSC_443),
835 	TV_MODE_NAME("NTSC-J", DRM_MODE_TV_MODE_NTSC_J),
836 	TV_MODE_NAME("PAL", DRM_MODE_TV_MODE_PAL),
837 	TV_MODE_NAME("PAL-M", DRM_MODE_TV_MODE_PAL_M),
838 	TV_MODE_NAME("PAL-N", DRM_MODE_TV_MODE_PAL_N),
839 	TV_MODE_NAME("SECAM", DRM_MODE_TV_MODE_SECAM),
840 	TV_MODE_NAME("Mono", DRM_MODE_TV_MODE_MONOCHROME),
841 };
842 
843 static void
844 drm_get_tv_mode_from_name_valid_desc(const struct drm_get_tv_mode_from_name_test *t,
845 				     char *desc)
846 {
847 	sprintf(desc, "%s", t->name);
848 }
849 
850 KUNIT_ARRAY_PARAM(drm_get_tv_mode_from_name_valid,
851 		  drm_get_tv_mode_from_name_valid_tests,
852 		  drm_get_tv_mode_from_name_valid_desc);
853 
854 static void drm_test_get_tv_mode_from_name_truncated(struct kunit *test)
855 {
856 	const char *name = "NTS";
857 	int ret;
858 
859 	ret = drm_get_tv_mode_from_name(name, strlen(name));
860 	KUNIT_EXPECT_LT(test, ret, 0);
861 };
862 
863 static struct kunit_case drm_get_tv_mode_from_name_tests[] = {
864 	KUNIT_CASE_PARAM(drm_test_get_tv_mode_from_name_valid,
865 			 drm_get_tv_mode_from_name_valid_gen_params),
866 	KUNIT_CASE(drm_test_get_tv_mode_from_name_truncated),
867 	{ }
868 };
869 
870 static struct kunit_suite drm_get_tv_mode_from_name_test_suite = {
871 	.name = "drm_get_tv_mode_from_name",
872 	.test_cases = drm_get_tv_mode_from_name_tests,
873 };
874 
875 struct drm_hdmi_connector_get_broadcast_rgb_name_test {
876 	unsigned int kind;
877 	const char *expected_name;
878 };
879 
880 #define BROADCAST_RGB_TEST(_kind, _name)	\
881 	{					\
882 		.kind = _kind,			\
883 		.expected_name = _name,		\
884 	}
885 
886 static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name(struct kunit *test)
887 {
888 	const struct drm_hdmi_connector_get_broadcast_rgb_name_test *params =
889 		test->param_value;
890 
891 	KUNIT_EXPECT_STREQ(test,
892 			   drm_hdmi_connector_get_broadcast_rgb_name(params->kind),
893 			   params->expected_name);
894 }
895 
896 static const
897 struct drm_hdmi_connector_get_broadcast_rgb_name_test
898 drm_hdmi_connector_get_broadcast_rgb_name_valid_tests[] = {
899 	BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic"),
900 	BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_FULL, "Full"),
901 	BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235"),
902 };
903 
904 static void
905 drm_hdmi_connector_get_broadcast_rgb_name_valid_desc(const struct drm_hdmi_connector_get_broadcast_rgb_name_test *t,
906 						     char *desc)
907 {
908 	sprintf(desc, "%s", t->expected_name);
909 }
910 
911 KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_broadcast_rgb_name_valid,
912 		  drm_hdmi_connector_get_broadcast_rgb_name_valid_tests,
913 		  drm_hdmi_connector_get_broadcast_rgb_name_valid_desc);
914 
915 static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid(struct kunit *test)
916 {
917 	KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_broadcast_rgb_name(3));
918 };
919 
920 static struct kunit_case drm_hdmi_connector_get_broadcast_rgb_name_tests[] = {
921 	KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_broadcast_rgb_name,
922 			 drm_hdmi_connector_get_broadcast_rgb_name_valid_gen_params),
923 	KUNIT_CASE(drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid),
924 	{ }
925 };
926 
927 static struct kunit_suite drm_hdmi_connector_get_broadcast_rgb_name_test_suite = {
928 	.name = "drm_hdmi_connector_get_broadcast_rgb_name",
929 	.test_cases = drm_hdmi_connector_get_broadcast_rgb_name_tests,
930 };
931 
932 struct drm_hdmi_connector_get_output_format_name_test {
933 	unsigned int kind;
934 	const char *expected_name;
935 };
936 
937 #define OUTPUT_FORMAT_TEST(_kind, _name)	\
938 	{					\
939 		.kind = _kind,			\
940 		.expected_name = _name,		\
941 	}
942 
943 static void drm_test_drm_hdmi_connector_get_output_format_name(struct kunit *test)
944 {
945 	const struct drm_hdmi_connector_get_output_format_name_test *params =
946 		test->param_value;
947 
948 	KUNIT_EXPECT_STREQ(test,
949 			   drm_hdmi_connector_get_output_format_name(params->kind),
950 			   params->expected_name);
951 }
952 
953 static const
954 struct drm_hdmi_connector_get_output_format_name_test
955 drm_hdmi_connector_get_output_format_name_valid_tests[] = {
956 	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_RGB, "RGB"),
957 	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV420, "YUV 4:2:0"),
958 	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV422, "YUV 4:2:2"),
959 	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV444, "YUV 4:4:4"),
960 };
961 
962 static void
963 drm_hdmi_connector_get_output_format_name_valid_desc(const struct drm_hdmi_connector_get_output_format_name_test *t,
964 						     char *desc)
965 {
966 	sprintf(desc, "%s", t->expected_name);
967 }
968 
969 KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_output_format_name_valid,
970 		  drm_hdmi_connector_get_output_format_name_valid_tests,
971 		  drm_hdmi_connector_get_output_format_name_valid_desc);
972 
973 static void drm_test_drm_hdmi_connector_get_output_format_name_invalid(struct kunit *test)
974 {
975 	KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_output_format_name(4));
976 };
977 
978 static struct kunit_case drm_hdmi_connector_get_output_format_name_tests[] = {
979 	KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_output_format_name,
980 			 drm_hdmi_connector_get_output_format_name_valid_gen_params),
981 	KUNIT_CASE(drm_test_drm_hdmi_connector_get_output_format_name_invalid),
982 	{ }
983 };
984 
985 static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite = {
986 	.name = "drm_hdmi_connector_get_output_format_name",
987 	.test_cases = drm_hdmi_connector_get_output_format_name_tests,
988 };
989 
990 static void drm_test_drm_connector_attach_broadcast_rgb_property(struct kunit *test)
991 {
992 	struct drm_connector_init_priv *priv = test->priv;
993 	struct drm_connector *connector = &priv->connector;
994 	struct drm_property *prop;
995 	int ret;
996 
997 	ret = drmm_connector_init(&priv->drm, connector,
998 				  &dummy_funcs,
999 				  DRM_MODE_CONNECTOR_HDMIA,
1000 				  &priv->ddc);
1001 	KUNIT_ASSERT_EQ(test, ret, 0);
1002 
1003 	ret = drm_connector_attach_broadcast_rgb_property(connector);
1004 	KUNIT_ASSERT_EQ(test, ret, 0);
1005 
1006 	prop = connector->broadcast_rgb_property;
1007 	KUNIT_ASSERT_NOT_NULL(test, prop);
1008 	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
1009 }
1010 
1011 static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(struct kunit *test)
1012 {
1013 	struct drm_connector_init_priv *priv = test->priv;
1014 	struct drm_connector *connector = &priv->connector;
1015 	struct drm_property *prop;
1016 	int ret;
1017 
1018 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
1019 				       "Vendor", "Product",
1020 				       &dummy_funcs,
1021 				       &dummy_hdmi_funcs,
1022 				       DRM_MODE_CONNECTOR_HDMIA,
1023 				       &priv->ddc,
1024 				       BIT(HDMI_COLORSPACE_RGB),
1025 				       8);
1026 	KUNIT_EXPECT_EQ(test, ret, 0);
1027 
1028 	ret = drm_connector_attach_broadcast_rgb_property(connector);
1029 	KUNIT_ASSERT_EQ(test, ret, 0);
1030 
1031 	prop = connector->broadcast_rgb_property;
1032 	KUNIT_ASSERT_NOT_NULL(test, prop);
1033 	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
1034 }
1035 
1036 static struct kunit_case drm_connector_attach_broadcast_rgb_property_tests[] = {
1037 	KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property),
1038 	KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector),
1039 	{ }
1040 };
1041 
1042 static struct kunit_suite drm_connector_attach_broadcast_rgb_property_test_suite = {
1043 	.name = "drm_connector_attach_broadcast_rgb_property",
1044 	.init = drm_test_connector_init,
1045 	.test_cases = drm_connector_attach_broadcast_rgb_property_tests,
1046 };
1047 
1048 /*
1049  * Test that for a given mode, with 8bpc and an RGB output the TMDS
1050  * character rate is equal to the mode pixel clock.
1051  */
1052 static void drm_test_drm_hdmi_compute_mode_clock_rgb(struct kunit *test)
1053 {
1054 	struct drm_connector_init_priv *priv = test->priv;
1055 	const struct drm_display_mode *mode;
1056 	unsigned long long rate;
1057 	struct drm_device *drm = &priv->drm;
1058 
1059 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1060 	KUNIT_ASSERT_NOT_NULL(test, mode);
1061 
1062 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1063 
1064 	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
1065 	KUNIT_ASSERT_GT(test, rate, 0);
1066 	KUNIT_EXPECT_EQ(test, mode->clock * 1000ULL, rate);
1067 }
1068 
1069 /*
1070  * Test that for a given mode, with 10bpc and an RGB output the TMDS
1071  * character rate is equal to 1.25 times the mode pixel clock.
1072  */
1073 static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc(struct kunit *test)
1074 {
1075 	struct drm_connector_init_priv *priv = test->priv;
1076 	const struct drm_display_mode *mode;
1077 	unsigned long long rate;
1078 	struct drm_device *drm = &priv->drm;
1079 
1080 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1081 	KUNIT_ASSERT_NOT_NULL(test, mode);
1082 
1083 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1084 
1085 	rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
1086 	KUNIT_ASSERT_GT(test, rate, 0);
1087 	KUNIT_EXPECT_EQ(test, mode->clock * 1250, rate);
1088 }
1089 
1090 /*
1091  * Test that for the VIC-1 mode, with 10bpc and an RGB output the TMDS
1092  * character rate computation fails.
1093  */
1094 static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *test)
1095 {
1096 	struct drm_connector_init_priv *priv = test->priv;
1097 	const struct drm_display_mode *mode;
1098 	unsigned long long rate;
1099 	struct drm_device *drm = &priv->drm;
1100 
1101 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
1102 	KUNIT_ASSERT_NOT_NULL(test, mode);
1103 
1104 	rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
1105 	KUNIT_EXPECT_EQ(test, rate, 0);
1106 }
1107 
1108 /*
1109  * Test that for a given mode, with 12bpc and an RGB output the TMDS
1110  * character rate is equal to 1.5 times the mode pixel clock.
1111  */
1112 static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test)
1113 {
1114 	struct drm_connector_init_priv *priv = test->priv;
1115 	const struct drm_display_mode *mode;
1116 	unsigned long long rate;
1117 	struct drm_device *drm = &priv->drm;
1118 
1119 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1120 	KUNIT_ASSERT_NOT_NULL(test, mode);
1121 
1122 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1123 
1124 	rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
1125 	KUNIT_ASSERT_GT(test, rate, 0);
1126 	KUNIT_EXPECT_EQ(test, mode->clock * 1500, rate);
1127 }
1128 
1129 /*
1130  * Test that for the VIC-1 mode, with 12bpc and an RGB output the TMDS
1131  * character rate computation fails.
1132  */
1133 static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *test)
1134 {
1135 	struct drm_connector_init_priv *priv = test->priv;
1136 	const struct drm_display_mode *mode;
1137 	unsigned long long rate;
1138 	struct drm_device *drm = &priv->drm;
1139 
1140 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
1141 	KUNIT_ASSERT_NOT_NULL(test, mode);
1142 
1143 	rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
1144 	KUNIT_EXPECT_EQ(test, rate, 0);
1145 }
1146 
1147 /*
1148  * Test that for a mode with the pixel repetition flag, the TMDS
1149  * character rate is indeed double the mode pixel clock.
1150  */
1151 static void drm_test_drm_hdmi_compute_mode_clock_rgb_double(struct kunit *test)
1152 {
1153 	struct drm_connector_init_priv *priv = test->priv;
1154 	const struct drm_display_mode *mode;
1155 	unsigned long long rate;
1156 	struct drm_device *drm = &priv->drm;
1157 
1158 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 6);
1159 	KUNIT_ASSERT_NOT_NULL(test, mode);
1160 
1161 	KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1162 
1163 	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
1164 	KUNIT_ASSERT_GT(test, rate, 0);
1165 	KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) * 2, rate);
1166 }
1167 
1168 /*
1169  * Test that the TMDS character rate computation for the VIC modes
1170  * explicitly listed in the spec as supporting YUV420 succeed and return
1171  * half the mode pixel clock.
1172  */
1173 static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit *test)
1174 {
1175 	struct drm_connector_init_priv *priv = test->priv;
1176 	const struct drm_display_mode *mode;
1177 	struct drm_device *drm = &priv->drm;
1178 	unsigned long long rate;
1179 	unsigned int vic = *(unsigned int *)test->param_value;
1180 
1181 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
1182 	KUNIT_ASSERT_NOT_NULL(test, mode);
1183 
1184 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1185 
1186 	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420);
1187 	KUNIT_ASSERT_GT(test, rate, 0);
1188 	KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) / 2, rate);
1189 }
1190 
1191 static const unsigned int drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[] = {
1192 	96, 97, 101, 102, 106, 107,
1193 };
1194 
1195 static void drm_hdmi_compute_mode_clock_yuv420_vic_desc(const unsigned int *vic, char *desc)
1196 {
1197 	sprintf(desc, "VIC %u", *vic);
1198 }
1199 
1200 KUNIT_ARRAY_PARAM(drm_hdmi_compute_mode_clock_yuv420_valid,
1201 		  drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests,
1202 		  drm_hdmi_compute_mode_clock_yuv420_vic_desc);
1203 
1204 /*
1205  * Test that for a given mode listed supporting it and an YUV420 output
1206  * with 10bpc, the TMDS character rate is equal to 0.625 times the mode
1207  * pixel clock.
1208  */
1209 static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kunit *test)
1210 {
1211 	struct drm_connector_init_priv *priv = test->priv;
1212 	const struct drm_display_mode *mode;
1213 	struct drm_device *drm = &priv->drm;
1214 	unsigned int vic =
1215 		drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
1216 	unsigned long long rate;
1217 
1218 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
1219 	KUNIT_ASSERT_NOT_NULL(test, mode);
1220 
1221 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1222 
1223 	rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV420);
1224 	KUNIT_ASSERT_GT(test, rate, 0);
1225 
1226 	KUNIT_EXPECT_EQ(test, mode->clock * 625, rate);
1227 }
1228 
1229 /*
1230  * Test that for a given mode listed supporting it and an YUV420 output
1231  * with 12bpc, the TMDS character rate is equal to 0.75 times the mode
1232  * pixel clock.
1233  */
1234 static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kunit *test)
1235 {
1236 	struct drm_connector_init_priv *priv = test->priv;
1237 	const struct drm_display_mode *mode;
1238 	struct drm_device *drm = &priv->drm;
1239 	unsigned int vic =
1240 		drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
1241 	unsigned long long rate;
1242 
1243 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
1244 	KUNIT_ASSERT_NOT_NULL(test, mode);
1245 
1246 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1247 
1248 	rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV420);
1249 	KUNIT_ASSERT_GT(test, rate, 0);
1250 
1251 	KUNIT_EXPECT_EQ(test, mode->clock * 750, rate);
1252 }
1253 
1254 /*
1255  * Test that for a given mode, the computation of the TMDS character
1256  * rate with 8bpc and a YUV422 output succeeds and returns a rate equal
1257  * to the mode pixel clock.
1258  */
1259 static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit *test)
1260 {
1261 	struct drm_connector_init_priv *priv = test->priv;
1262 	const struct drm_display_mode *mode;
1263 	struct drm_device *drm = &priv->drm;
1264 	unsigned long long rate;
1265 
1266 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1267 	KUNIT_ASSERT_NOT_NULL(test, mode);
1268 
1269 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1270 
1271 	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV422);
1272 	KUNIT_ASSERT_GT(test, rate, 0);
1273 	KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
1274 }
1275 
1276 /*
1277  * Test that for a given mode, the computation of the TMDS character
1278  * rate with 10bpc and a YUV422 output succeeds and returns a rate equal
1279  * to the mode pixel clock.
1280  */
1281 static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kunit *test)
1282 {
1283 	struct drm_connector_init_priv *priv = test->priv;
1284 	const struct drm_display_mode *mode;
1285 	struct drm_device *drm = &priv->drm;
1286 	unsigned long long rate;
1287 
1288 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1289 	KUNIT_ASSERT_NOT_NULL(test, mode);
1290 
1291 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1292 
1293 	rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV422);
1294 	KUNIT_ASSERT_GT(test, rate, 0);
1295 	KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
1296 }
1297 
1298 /*
1299  * Test that for a given mode, the computation of the TMDS character
1300  * rate with 12bpc and a YUV422 output succeeds and returns a rate equal
1301  * to the mode pixel clock.
1302  */
1303 static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kunit *test)
1304 {
1305 	struct drm_connector_init_priv *priv = test->priv;
1306 	const struct drm_display_mode *mode;
1307 	struct drm_device *drm = &priv->drm;
1308 	unsigned long long rate;
1309 
1310 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1311 	KUNIT_ASSERT_NOT_NULL(test, mode);
1312 
1313 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1314 
1315 	rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV422);
1316 	KUNIT_ASSERT_GT(test, rate, 0);
1317 	KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
1318 }
1319 
1320 static struct kunit_case drm_hdmi_compute_mode_clock_tests[] = {
1321 	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb),
1322 	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc),
1323 	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1),
1324 	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc),
1325 	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1),
1326 	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_double),
1327 	KUNIT_CASE_PARAM(drm_test_connector_hdmi_compute_mode_clock_yuv420_valid,
1328 			 drm_hdmi_compute_mode_clock_yuv420_valid_gen_params),
1329 	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc),
1330 	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc),
1331 	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc),
1332 	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc),
1333 	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc),
1334 	{ }
1335 };
1336 
1337 static struct kunit_suite drm_hdmi_compute_mode_clock_test_suite = {
1338 	.name = "drm_test_connector_hdmi_compute_mode_clock",
1339 	.init = drm_test_connector_init,
1340 	.test_cases = drm_hdmi_compute_mode_clock_tests,
1341 };
1342 
1343 kunit_test_suites(
1344 	&drmm_connector_hdmi_init_test_suite,
1345 	&drmm_connector_init_test_suite,
1346 	&drm_connector_attach_broadcast_rgb_property_test_suite,
1347 	&drm_get_tv_mode_from_name_test_suite,
1348 	&drm_hdmi_compute_mode_clock_test_suite,
1349 	&drm_hdmi_connector_get_broadcast_rgb_name_test_suite,
1350 	&drm_hdmi_connector_get_output_format_name_test_suite
1351 );
1352 
1353 MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
1354 MODULE_DESCRIPTION("Kunit test for drm_modes functions");
1355 MODULE_LICENSE("GPL");
1356