xref: /linux/drivers/gpu/drm/tests/drm_connector_test.c (revision 2c1ed907520c50326b8f604907a8478b27881a2e)
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_file.h>
13 #include <drm/drm_kunit_helpers.h>
14 #include <drm/drm_modes.h>
15 
16 #include <drm/display/drm_hdmi_helper.h>
17 
18 #include <kunit/test.h>
19 
20 #include "../drm_crtc_internal.h"
21 
22 struct drm_connector_init_priv {
23 	struct drm_device drm;
24 	struct drm_connector connector;
25 	struct i2c_adapter ddc;
26 };
27 
28 static const struct drm_connector_hdmi_funcs dummy_hdmi_funcs = {
29 };
30 
31 static const struct drm_connector_funcs dummy_funcs = {
32 	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
33 	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
34 	.reset			= drm_atomic_helper_connector_reset,
35 };
36 
dummy_ddc_xfer(struct i2c_adapter * adapter,struct i2c_msg * msgs,int num)37 static int dummy_ddc_xfer(struct i2c_adapter *adapter,
38 			  struct i2c_msg *msgs, int num)
39 {
40 	return num;
41 }
42 
dummy_ddc_func(struct i2c_adapter * adapter)43 static u32 dummy_ddc_func(struct i2c_adapter *adapter)
44 {
45 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
46 }
47 
48 static const struct i2c_algorithm dummy_ddc_algorithm = {
49 	.master_xfer = dummy_ddc_xfer,
50 	.functionality = dummy_ddc_func,
51 };
52 
i2c_del_adapter_wrapper(void * ptr)53 static void i2c_del_adapter_wrapper(void *ptr)
54 {
55 	struct i2c_adapter *adap = ptr;
56 
57 	i2c_del_adapter(adap);
58 }
59 
drm_test_connector_init(struct kunit * test)60 static int drm_test_connector_init(struct kunit *test)
61 {
62 	struct drm_connector_init_priv *priv;
63 	struct device *dev;
64 	int ret;
65 
66 	dev = drm_kunit_helper_alloc_device(test);
67 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
68 
69 	priv = drm_kunit_helper_alloc_drm_device(test, dev,
70 						 struct drm_connector_init_priv, drm,
71 						 DRIVER_MODESET | DRIVER_ATOMIC);
72 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
73 
74 	strscpy(priv->ddc.name, "dummy-connector-ddc", sizeof(priv->ddc.name));
75 	priv->ddc.owner = THIS_MODULE;
76 	priv->ddc.algo = &dummy_ddc_algorithm;
77 	priv->ddc.dev.parent = dev;
78 
79 	ret = i2c_add_adapter(&priv->ddc);
80 	KUNIT_ASSERT_EQ(test, ret, 0);
81 
82 	ret = kunit_add_action_or_reset(test, i2c_del_adapter_wrapper, &priv->ddc);
83 	KUNIT_ASSERT_EQ(test, ret, 0);
84 
85 	test->priv = priv;
86 	return 0;
87 }
88 
89 /*
90  * Test that the registration of a bog standard connector works as
91  * expected and doesn't report any error.
92  */
drm_test_drmm_connector_init(struct kunit * test)93 static void drm_test_drmm_connector_init(struct kunit *test)
94 {
95 	struct drm_connector_init_priv *priv = test->priv;
96 	int ret;
97 
98 	ret = drmm_connector_init(&priv->drm, &priv->connector,
99 				  &dummy_funcs,
100 				  DRM_MODE_CONNECTOR_HDMIA,
101 				  &priv->ddc);
102 	KUNIT_EXPECT_EQ(test, ret, 0);
103 }
104 
105 /*
106  * Test that the registration of a connector without a DDC adapter
107  * doesn't report any error.
108  */
drm_test_drmm_connector_init_null_ddc(struct kunit * test)109 static void drm_test_drmm_connector_init_null_ddc(struct kunit *test)
110 {
111 	struct drm_connector_init_priv *priv = test->priv;
112 	int ret;
113 
114 	ret = drmm_connector_init(&priv->drm, &priv->connector,
115 				  &dummy_funcs,
116 				  DRM_MODE_CONNECTOR_HDMIA,
117 				  NULL);
118 	KUNIT_EXPECT_EQ(test, ret, 0);
119 }
120 
121 /*
122  * Test that the registration of a connector succeeds for all possible
123  * connector types.
124  */
drm_test_drmm_connector_init_type_valid(struct kunit * test)125 static void drm_test_drmm_connector_init_type_valid(struct kunit *test)
126 {
127 	struct drm_connector_init_priv *priv = test->priv;
128 	unsigned int connector_type = *(unsigned int *)test->param_value;
129 	int ret;
130 
131 	ret = drmm_connector_init(&priv->drm, &priv->connector,
132 				  &dummy_funcs,
133 				  connector_type,
134 				  &priv->ddc);
135 	KUNIT_EXPECT_EQ(test, ret, 0);
136 }
137 
138 static const unsigned int drm_connector_init_type_valid_tests[] = {
139 	DRM_MODE_CONNECTOR_Unknown,
140 	DRM_MODE_CONNECTOR_VGA,
141 	DRM_MODE_CONNECTOR_DVII,
142 	DRM_MODE_CONNECTOR_DVID,
143 	DRM_MODE_CONNECTOR_DVIA,
144 	DRM_MODE_CONNECTOR_Composite,
145 	DRM_MODE_CONNECTOR_SVIDEO,
146 	DRM_MODE_CONNECTOR_LVDS,
147 	DRM_MODE_CONNECTOR_Component,
148 	DRM_MODE_CONNECTOR_9PinDIN,
149 	DRM_MODE_CONNECTOR_DisplayPort,
150 	DRM_MODE_CONNECTOR_HDMIA,
151 	DRM_MODE_CONNECTOR_HDMIB,
152 	DRM_MODE_CONNECTOR_TV,
153 	DRM_MODE_CONNECTOR_eDP,
154 	DRM_MODE_CONNECTOR_VIRTUAL,
155 	DRM_MODE_CONNECTOR_DSI,
156 	DRM_MODE_CONNECTOR_DPI,
157 	DRM_MODE_CONNECTOR_WRITEBACK,
158 	DRM_MODE_CONNECTOR_SPI,
159 	DRM_MODE_CONNECTOR_USB,
160 };
161 
drm_connector_init_type_desc(const unsigned int * type,char * desc)162 static void drm_connector_init_type_desc(const unsigned int *type, char *desc)
163 {
164 	sprintf(desc, "%s", drm_get_connector_type_name(*type));
165 }
166 
167 KUNIT_ARRAY_PARAM(drm_connector_init_type_valid,
168 		  drm_connector_init_type_valid_tests,
169 		  drm_connector_init_type_desc);
170 
171 static struct kunit_case drmm_connector_init_tests[] = {
172 	KUNIT_CASE(drm_test_drmm_connector_init),
173 	KUNIT_CASE(drm_test_drmm_connector_init_null_ddc),
174 	KUNIT_CASE_PARAM(drm_test_drmm_connector_init_type_valid,
175 			 drm_connector_init_type_valid_gen_params),
176 	{ }
177 };
178 
179 static struct kunit_suite drmm_connector_init_test_suite = {
180 	.name = "drmm_connector_init",
181 	.init = drm_test_connector_init,
182 	.test_cases = drmm_connector_init_tests,
183 };
184 
185 static const struct drm_connector_funcs dummy_dynamic_init_funcs = {
186 	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,
187 	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,
188 	.reset			= drm_atomic_helper_connector_reset,
189 	.destroy		= drm_connector_cleanup,
190 };
191 
192 /*
193  * Test that the initialization of a bog standard dynamic connector works
194  * as expected and doesn't report any error.
195  */
drm_test_drm_connector_dynamic_init(struct kunit * test)196 static void drm_test_drm_connector_dynamic_init(struct kunit *test)
197 {
198 	struct drm_connector_init_priv *priv = test->priv;
199 	struct drm_connector *connector = &priv->connector;
200 	int ret;
201 
202 	ret = drm_connector_dynamic_init(&priv->drm, connector,
203 					 &dummy_dynamic_init_funcs,
204 					 DRM_MODE_CONNECTOR_DisplayPort,
205 					 &priv->ddc);
206 	KUNIT_ASSERT_EQ(test, ret, 0);
207 }
208 
drm_test_connector_dynamic_init_cleanup(struct kunit * test)209 static void drm_test_connector_dynamic_init_cleanup(struct kunit *test)
210 {
211 	struct drm_connector_init_priv *priv = test->priv;
212 	struct drm_connector *connector = &priv->connector;
213 
214 	drm_connector_cleanup(connector);
215 }
216 
217 /*
218  * Test that the initialization of a dynamic connector without a DDC adapter
219  * doesn't report any error.
220  */
drm_test_drm_connector_dynamic_init_null_ddc(struct kunit * test)221 static void drm_test_drm_connector_dynamic_init_null_ddc(struct kunit *test)
222 {
223 	struct drm_connector_init_priv *priv = test->priv;
224 	struct drm_connector *connector = &priv->connector;
225 	int ret;
226 
227 	ret = drm_connector_dynamic_init(&priv->drm, connector,
228 					 &dummy_dynamic_init_funcs,
229 					 DRM_MODE_CONNECTOR_DisplayPort,
230 					 NULL);
231 	KUNIT_ASSERT_EQ(test, ret, 0);
232 }
233 
234 /*
235  * Test that the initialization of a dynamic connector doesn't add the
236  * connector to the connector list.
237  */
drm_test_drm_connector_dynamic_init_not_added(struct kunit * test)238 static void drm_test_drm_connector_dynamic_init_not_added(struct kunit *test)
239 {
240 	struct drm_connector_init_priv *priv = test->priv;
241 	struct drm_connector *connector = &priv->connector;
242 	int ret;
243 
244 	ret = drm_connector_dynamic_init(&priv->drm, connector,
245 					 &dummy_dynamic_init_funcs,
246 					 DRM_MODE_CONNECTOR_DisplayPort,
247 					 &priv->ddc);
248 	KUNIT_ASSERT_EQ(test, ret, 0);
249 	KUNIT_ASSERT_PTR_EQ(test, connector->head.next, &connector->head);
250 }
251 
test_connector_property(struct kunit * test,struct drm_connector * connector,const struct drm_property * expected_prop)252 static void test_connector_property(struct kunit *test,
253 				    struct drm_connector *connector,
254 				    const struct drm_property *expected_prop)
255 {
256 	struct drm_property *prop;
257 	uint64_t val;
258 	int ret;
259 
260 	KUNIT_ASSERT_NOT_NULL(test, expected_prop);
261 	prop = drm_mode_obj_find_prop_id(&connector->base, expected_prop->base.id);
262 	KUNIT_ASSERT_PTR_EQ_MSG(test, prop, expected_prop,
263 				"Can't find property %s", expected_prop->name);
264 
265 	ret = drm_object_property_get_default_value(&connector->base, prop, &val);
266 	KUNIT_EXPECT_EQ(test, ret, 0);
267 	KUNIT_EXPECT_EQ(test, val, 0);
268 
269 	/* TODO: Check property value in the connector state. */
270 }
271 
272 /*
273  * Test that the initialization of a dynamic connector adds all the expected
274  * properties to it.
275  */
drm_test_drm_connector_dynamic_init_properties(struct kunit * test)276 static void drm_test_drm_connector_dynamic_init_properties(struct kunit *test)
277 {
278 	struct drm_connector_init_priv *priv = test->priv;
279 	struct drm_connector *connector = &priv->connector;
280 	struct drm_mode_config *config = &priv->drm.mode_config;
281 	const struct drm_property *props[] = {
282 		config->edid_property,
283 		config->dpms_property,
284 		config->link_status_property,
285 		config->non_desktop_property,
286 		config->tile_property,
287 		config->prop_crtc_id,
288 	};
289 	int ret;
290 	int i;
291 
292 	ret = drm_connector_dynamic_init(&priv->drm, connector,
293 					 &dummy_dynamic_init_funcs,
294 					 DRM_MODE_CONNECTOR_DisplayPort,
295 					 &priv->ddc);
296 	KUNIT_ASSERT_EQ(test, ret, 0);
297 
298 	for (i = 0; i < ARRAY_SIZE(props); i++)
299 		test_connector_property(test, connector, props[i]);
300 }
301 
302 /*
303  * Test that the initialization of a dynamic connector succeeds for all
304  * possible connector types.
305  */
drm_test_drm_connector_dynamic_init_type_valid(struct kunit * test)306 static void drm_test_drm_connector_dynamic_init_type_valid(struct kunit *test)
307 {
308 	struct drm_connector_init_priv *priv = test->priv;
309 	struct drm_connector *connector = &priv->connector;
310 	unsigned int connector_type = *(unsigned int *)test->param_value;
311 	int ret;
312 
313 	ret = drm_connector_dynamic_init(&priv->drm, connector,
314 					 &dummy_dynamic_init_funcs,
315 					 connector_type,
316 					 &priv->ddc);
317 	KUNIT_ASSERT_EQ(test, ret, 0);
318 }
319 
320 /*
321  * Test that the initialization of a dynamic connector sets the expected name
322  * for it for all possible connector types.
323  */
drm_test_drm_connector_dynamic_init_name(struct kunit * test)324 static void drm_test_drm_connector_dynamic_init_name(struct kunit *test)
325 {
326 	struct drm_connector_init_priv *priv = test->priv;
327 	struct drm_connector *connector = &priv->connector;
328 	unsigned int connector_type = *(unsigned int *)test->param_value;
329 	char expected_name[128];
330 	int ret;
331 
332 	ret = drm_connector_dynamic_init(&priv->drm, connector,
333 					 &dummy_dynamic_init_funcs,
334 					 connector_type,
335 					 &priv->ddc);
336 	KUNIT_ASSERT_EQ(test, ret, 0);
337 
338 	snprintf(expected_name, sizeof(expected_name), "%s-%d",
339 		 drm_get_connector_type_name(connector_type), connector->connector_type_id);
340 	KUNIT_ASSERT_STREQ(test, connector->name, expected_name);
341 }
342 
343 static struct kunit_case drm_connector_dynamic_init_tests[] = {
344 	KUNIT_CASE(drm_test_drm_connector_dynamic_init),
345 	KUNIT_CASE(drm_test_drm_connector_dynamic_init_null_ddc),
346 	KUNIT_CASE(drm_test_drm_connector_dynamic_init_not_added),
347 	KUNIT_CASE(drm_test_drm_connector_dynamic_init_properties),
348 	KUNIT_CASE_PARAM(drm_test_drm_connector_dynamic_init_type_valid,
349 			 drm_connector_init_type_valid_gen_params),
350 	KUNIT_CASE_PARAM(drm_test_drm_connector_dynamic_init_name,
351 			 drm_connector_init_type_valid_gen_params),
352 	{}
353 };
354 
355 static struct kunit_suite drm_connector_dynamic_init_test_suite = {
356 	.name = "drm_connector_dynamic_init",
357 	.init = drm_test_connector_init,
358 	.exit = drm_test_connector_dynamic_init_cleanup,
359 	.test_cases = drm_connector_dynamic_init_tests,
360 };
361 
drm_test_connector_dynamic_register_early_init(struct kunit * test)362 static int drm_test_connector_dynamic_register_early_init(struct kunit *test)
363 {
364 	struct drm_connector_init_priv *priv;
365 	int ret;
366 
367 	ret = drm_test_connector_init(test);
368 	KUNIT_ASSERT_EQ(test, ret, 0);
369 
370 	priv = test->priv;
371 
372 	ret = drm_connector_dynamic_init(&priv->drm, &priv->connector,
373 					 &dummy_dynamic_init_funcs,
374 					 DRM_MODE_CONNECTOR_DisplayPort,
375 					 &priv->ddc);
376 	KUNIT_ASSERT_EQ(test, ret, 0);
377 
378 	return 0;
379 }
380 
drm_test_connector_dynamic_register_early_cleanup(struct kunit * test)381 static void drm_test_connector_dynamic_register_early_cleanup(struct kunit *test)
382 {
383 	struct drm_connector_init_priv *priv = test->priv;
384 	struct drm_connector *connector = &priv->connector;
385 
386 	drm_connector_unregister(connector);
387 	drm_connector_put(connector);
388 }
389 
390 /*
391  * Test that registration of a dynamic connector adds it to the connector list.
392  */
drm_test_drm_connector_dynamic_register_early_on_list(struct kunit * test)393 static void drm_test_drm_connector_dynamic_register_early_on_list(struct kunit *test)
394 {
395 	struct drm_connector_init_priv *priv = test->priv;
396 	struct drm_connector *connector = &priv->connector;
397 	int ret;
398 
399 	KUNIT_ASSERT_TRUE(test, list_empty(&connector->head));
400 
401 	ret = drm_connector_dynamic_register(connector);
402 	KUNIT_ASSERT_EQ(test, ret, 0);
403 
404 	KUNIT_ASSERT_PTR_EQ(test, connector->head.next, &priv->drm.mode_config.connector_list);
405 }
406 
407 /*
408  * Test that the registration of a dynamic connector before the drm device is
409  * registered results in deferring the connector's user interface registration.
410  */
drm_test_drm_connector_dynamic_register_early_defer(struct kunit * test)411 static void drm_test_drm_connector_dynamic_register_early_defer(struct kunit *test)
412 {
413 	struct drm_connector_init_priv *priv = test->priv;
414 	struct drm_connector *connector = &priv->connector;
415 	int ret;
416 
417 	ret = drm_connector_dynamic_register(connector);
418 	KUNIT_ASSERT_EQ(test, ret, 0);
419 
420 	KUNIT_ASSERT_EQ(test, connector->registration_state, DRM_CONNECTOR_INITIALIZING);
421 }
422 
423 /*
424  * Test that the registration of a dynamic connector fails, if this is done before
425  * the connector is initialized.
426  */
drm_test_drm_connector_dynamic_register_early_no_init(struct kunit * test)427 static void drm_test_drm_connector_dynamic_register_early_no_init(struct kunit *test)
428 {
429 	struct drm_connector *connector;
430 	int ret;
431 
432 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL); /* auto freed */
433 	KUNIT_ASSERT_NOT_NULL(test, connector);
434 
435 	ret = drm_connector_dynamic_register(connector);
436 	KUNIT_ASSERT_EQ(test, ret, -EINVAL);
437 }
438 
439 /*
440  * Test that the registration of a dynamic connector before the drm device is
441  * registered results in deferring adding a mode object for the connector.
442  */
drm_test_drm_connector_dynamic_register_early_no_mode_object(struct kunit * test)443 static void drm_test_drm_connector_dynamic_register_early_no_mode_object(struct kunit *test)
444 {
445 	struct drm_connector_init_priv *priv = test->priv;
446 	struct drm_connector *connector = &priv->connector;
447 	struct drm_connector *tmp_connector;
448 	int ret;
449 
450 	ret = drm_connector_dynamic_register(&priv->connector);
451 	KUNIT_ASSERT_EQ(test, ret, 0);
452 
453 	tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id);
454 	KUNIT_ASSERT_NULL(test, tmp_connector);
455 }
456 
457 static struct kunit_case drm_connector_dynamic_register_early_tests[] = {
458 	KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_on_list),
459 	KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_defer),
460 	KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_no_init),
461 	KUNIT_CASE(drm_test_drm_connector_dynamic_register_early_no_mode_object),
462 	{ }
463 };
464 
465 static struct kunit_suite drm_connector_dynamic_register_early_test_suite = {
466 	.name = "drm_connector_dynamic_register_early",
467 	.init = drm_test_connector_dynamic_register_early_init,
468 	.exit = drm_test_connector_dynamic_register_early_cleanup,
469 	.test_cases = drm_connector_dynamic_register_early_tests,
470 };
471 
drm_test_connector_dynamic_register_init(struct kunit * test)472 static int drm_test_connector_dynamic_register_init(struct kunit *test)
473 {
474 	struct drm_connector_init_priv *priv;
475 	int ret;
476 
477 	ret = drm_test_connector_dynamic_register_early_init(test);
478 	KUNIT_ASSERT_EQ(test, ret, 0);
479 
480 	priv = test->priv;
481 
482 	ret = drm_dev_register(priv->connector.dev, 0);
483 	KUNIT_ASSERT_EQ(test, ret, 0);
484 
485 	return 0;
486 }
487 
drm_test_connector_dynamic_register_cleanup(struct kunit * test)488 static void drm_test_connector_dynamic_register_cleanup(struct kunit *test)
489 {
490 	struct drm_connector_init_priv *priv = test->priv;
491 	struct drm_device *dev = priv->connector.dev;
492 
493 	drm_connector_unregister(&priv->connector);
494 	drm_connector_put(&priv->connector);
495 
496 	drm_dev_unregister(dev);
497 
498 	drm_test_connector_dynamic_register_early_cleanup(test);
499 }
500 
drm_test_drm_connector_dynamic_register_on_list(struct kunit * test)501 static void drm_test_drm_connector_dynamic_register_on_list(struct kunit *test)
502 {
503 	struct drm_connector_init_priv *priv = test->priv;
504 	int ret;
505 
506 	KUNIT_ASSERT_TRUE(test, list_empty(&priv->connector.head));
507 
508 	ret = drm_connector_dynamic_register(&priv->connector);
509 	KUNIT_ASSERT_EQ(test, ret, 0);
510 
511 	KUNIT_ASSERT_PTR_EQ(test, priv->connector.head.next, &priv->drm.mode_config.connector_list);
512 }
513 
514 /*
515  * Test that the registration of a dynamic connector doesn't get deferred if
516  * this is done after the drm device is registered.
517  */
drm_test_drm_connector_dynamic_register_no_defer(struct kunit * test)518 static void drm_test_drm_connector_dynamic_register_no_defer(struct kunit *test)
519 {
520 	struct drm_connector_init_priv *priv = test->priv;
521 	int ret;
522 
523 	KUNIT_ASSERT_EQ(test, priv->connector.registration_state, DRM_CONNECTOR_INITIALIZING);
524 
525 	ret = drm_connector_dynamic_register(&priv->connector);
526 	KUNIT_ASSERT_EQ(test, ret, 0);
527 
528 	KUNIT_ASSERT_EQ(test, priv->connector.registration_state, DRM_CONNECTOR_REGISTERED);
529 }
530 
531 /*
532  * Test that the registration of a dynamic connector fails if this is done after the
533  * drm device is registered, but before the connector is initialized.
534  */
drm_test_drm_connector_dynamic_register_no_init(struct kunit * test)535 static void drm_test_drm_connector_dynamic_register_no_init(struct kunit *test)
536 {
537 	struct drm_connector *connector;
538 	int ret;
539 
540 	connector = kunit_kzalloc(test, sizeof(*connector), GFP_KERNEL); /* auto freed */
541 	KUNIT_ASSERT_NOT_NULL(test, connector);
542 
543 	ret = drm_connector_dynamic_register(connector);
544 	KUNIT_ASSERT_EQ(test, ret, -EINVAL);
545 }
546 
547 /*
548  * Test that the registration of a dynamic connector after the drm device is
549  * registered adds the mode object for the connector.
550  */
drm_test_drm_connector_dynamic_register_mode_object(struct kunit * test)551 static void drm_test_drm_connector_dynamic_register_mode_object(struct kunit *test)
552 {
553 	struct drm_connector_init_priv *priv = test->priv;
554 	struct drm_connector *connector = &priv->connector;
555 	struct drm_connector *tmp_connector;
556 	int ret;
557 
558 	tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id);
559 	KUNIT_ASSERT_NULL(test, tmp_connector);
560 
561 	ret = drm_connector_dynamic_register(&priv->connector);
562 	KUNIT_ASSERT_EQ(test, ret, 0);
563 
564 	tmp_connector = drm_connector_lookup(connector->dev, NULL, connector->base.id);
565 	KUNIT_ASSERT_PTR_EQ(test, tmp_connector, connector);
566 }
567 
568 /*
569  * Test that the registration of a dynamic connector after the drm device is
570  * registered adds the connector to sysfs.
571  */
drm_test_drm_connector_dynamic_register_sysfs(struct kunit * test)572 static void drm_test_drm_connector_dynamic_register_sysfs(struct kunit *test)
573 {
574 	struct drm_connector_init_priv *priv = test->priv;
575 	struct drm_connector *connector = &priv->connector;
576 	int ret;
577 
578 	KUNIT_ASSERT_NULL(test, connector->kdev);
579 
580 	ret = drm_connector_dynamic_register(connector);
581 	KUNIT_ASSERT_EQ(test, ret, 0);
582 
583 	KUNIT_ASSERT_NOT_NULL(test, connector->kdev);
584 }
585 
586 /*
587  * Test that the registration of a dynamic connector after the drm device is
588  * registered sets the connector's sysfs name as expected.
589  */
drm_test_drm_connector_dynamic_register_sysfs_name(struct kunit * test)590 static void drm_test_drm_connector_dynamic_register_sysfs_name(struct kunit *test)
591 {
592 	struct drm_connector_init_priv *priv = test->priv;
593 	struct drm_connector *connector = &priv->connector;
594 	char expected_name[128];
595 	int ret;
596 
597 	ret = drm_connector_dynamic_register(connector);
598 	KUNIT_ASSERT_EQ(test, ret, 0);
599 
600 	snprintf(expected_name, sizeof(expected_name), "card%d-%s",
601 		 connector->dev->primary->index, connector->name);
602 
603 	KUNIT_ASSERT_STREQ(test, dev_name(connector->kdev), expected_name);
604 }
605 
606 /*
607  * Test that the registration of a dynamic connector after the drm device is
608  * registered adds the connector to debugfs.
609  */
drm_test_drm_connector_dynamic_register_debugfs(struct kunit * test)610 static void drm_test_drm_connector_dynamic_register_debugfs(struct kunit *test)
611 {
612 	struct drm_connector_init_priv *priv = test->priv;
613 	int ret;
614 
615 	KUNIT_ASSERT_NULL(test, priv->connector.debugfs_entry);
616 
617 	ret = drm_connector_dynamic_register(&priv->connector);
618 	KUNIT_ASSERT_EQ(test, ret, 0);
619 
620 	if (IS_ENABLED(CONFIG_DEBUG_FS))
621 		KUNIT_ASSERT_NOT_NULL(test, priv->connector.debugfs_entry);
622 	else
623 		KUNIT_ASSERT_NULL(test, priv->connector.debugfs_entry);
624 }
625 
626 static struct kunit_case drm_connector_dynamic_register_tests[] = {
627 	KUNIT_CASE(drm_test_drm_connector_dynamic_register_on_list),
628 	KUNIT_CASE(drm_test_drm_connector_dynamic_register_no_defer),
629 	KUNIT_CASE(drm_test_drm_connector_dynamic_register_no_init),
630 	KUNIT_CASE(drm_test_drm_connector_dynamic_register_mode_object),
631 	KUNIT_CASE(drm_test_drm_connector_dynamic_register_sysfs),
632 	KUNIT_CASE(drm_test_drm_connector_dynamic_register_sysfs_name),
633 	KUNIT_CASE(drm_test_drm_connector_dynamic_register_debugfs),
634 	{ }
635 };
636 
637 static struct kunit_suite drm_connector_dynamic_register_test_suite = {
638 	.name = "drm_connector_dynamic_register",
639 	.init = drm_test_connector_dynamic_register_init,
640 	.exit = drm_test_connector_dynamic_register_cleanup,
641 	.test_cases = drm_connector_dynamic_register_tests,
642 };
643 
644 /*
645  * Test that the registration of a bog standard connector works as
646  * expected and doesn't report any error.
647  */
drm_test_connector_hdmi_init_valid(struct kunit * test)648 static void drm_test_connector_hdmi_init_valid(struct kunit *test)
649 {
650 	struct drm_connector_init_priv *priv = test->priv;
651 	int ret;
652 
653 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
654 				       "Vendor", "Product",
655 				       &dummy_funcs,
656 				       &dummy_hdmi_funcs,
657 				       DRM_MODE_CONNECTOR_HDMIA,
658 				       &priv->ddc,
659 				       BIT(HDMI_COLORSPACE_RGB),
660 				       8);
661 	KUNIT_EXPECT_EQ(test, ret, 0);
662 }
663 
664 /*
665  * Test that the registration of a connector without a DDC adapter
666  * doesn't report any error.
667  */
drm_test_connector_hdmi_init_null_ddc(struct kunit * test)668 static void drm_test_connector_hdmi_init_null_ddc(struct kunit *test)
669 {
670 	struct drm_connector_init_priv *priv = test->priv;
671 	int ret;
672 
673 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
674 				       "Vendor", "Product",
675 				       &dummy_funcs,
676 				       &dummy_hdmi_funcs,
677 				       DRM_MODE_CONNECTOR_HDMIA,
678 				       NULL,
679 				       BIT(HDMI_COLORSPACE_RGB),
680 				       8);
681 	KUNIT_EXPECT_EQ(test, ret, 0);
682 }
683 
684 /*
685  * Test that the registration of an HDMI connector with a NULL vendor
686  * fails.
687  */
drm_test_connector_hdmi_init_null_vendor(struct kunit * test)688 static void drm_test_connector_hdmi_init_null_vendor(struct kunit *test)
689 {
690 	struct drm_connector_init_priv *priv = test->priv;
691 	int ret;
692 
693 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
694 				       NULL, "Product",
695 				       &dummy_funcs,
696 				       &dummy_hdmi_funcs,
697 				       DRM_MODE_CONNECTOR_HDMIA,
698 				       &priv->ddc,
699 				       BIT(HDMI_COLORSPACE_RGB),
700 				       8);
701 	KUNIT_EXPECT_LT(test, ret, 0);
702 }
703 
704 /*
705  * Test that the registration of an HDMI connector with a NULL product
706  * fails.
707  */
drm_test_connector_hdmi_init_null_product(struct kunit * test)708 static void drm_test_connector_hdmi_init_null_product(struct kunit *test)
709 {
710 	struct drm_connector_init_priv *priv = test->priv;
711 	int ret;
712 
713 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
714 				       "Vendor", NULL,
715 				       &dummy_funcs,
716 				       &dummy_hdmi_funcs,
717 				       DRM_MODE_CONNECTOR_HDMIA,
718 				       &priv->ddc,
719 				       BIT(HDMI_COLORSPACE_RGB),
720 				       8);
721 	KUNIT_EXPECT_LT(test, ret, 0);
722 }
723 
724 /*
725  * Test that the registration of a connector with a valid, shorter than
726  * the max length, product name succeeds, and is stored padded with 0.
727  */
drm_test_connector_hdmi_init_product_valid(struct kunit * test)728 static void drm_test_connector_hdmi_init_product_valid(struct kunit *test)
729 {
730 	struct drm_connector_init_priv *priv = test->priv;
731 	const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
732 		'P', 'r', 'o', 'd',
733 	};
734 	const char *product_name = "Prod";
735 	int ret;
736 
737 	KUNIT_ASSERT_LT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
738 
739 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
740 				       "Vendor", product_name,
741 				       &dummy_funcs,
742 				       &dummy_hdmi_funcs,
743 				       DRM_MODE_CONNECTOR_HDMIA,
744 				       &priv->ddc,
745 				       BIT(HDMI_COLORSPACE_RGB),
746 				       8);
747 	KUNIT_EXPECT_EQ(test, ret, 0);
748 	KUNIT_EXPECT_MEMEQ(test,
749 			   priv->connector.hdmi.product,
750 			   expected_product,
751 			   sizeof(priv->connector.hdmi.product));
752 }
753 
754 /*
755  * Test that the registration of a connector with a valid, at max
756  * length, product name succeeds, and is stored padded without any
757  * trailing \0.
758  */
drm_test_connector_hdmi_init_product_length_exact(struct kunit * test)759 static void drm_test_connector_hdmi_init_product_length_exact(struct kunit *test)
760 {
761 	struct drm_connector_init_priv *priv = test->priv;
762 	const unsigned char expected_product[DRM_CONNECTOR_HDMI_PRODUCT_LEN] = {
763 		'P', 'r', 'o', 'd', 'u', 'c', 't',
764 		'P', 'r', 'o', 'd', 'u', 'c', 't',
765 		'P', 'r',
766 	};
767 	const char *product_name = "ProductProductPr";
768 	int ret;
769 
770 	KUNIT_ASSERT_EQ(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
771 
772 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
773 				       "Vendor", product_name,
774 				       &dummy_funcs,
775 				       &dummy_hdmi_funcs,
776 				       DRM_MODE_CONNECTOR_HDMIA,
777 				       &priv->ddc,
778 				       BIT(HDMI_COLORSPACE_RGB),
779 				       8);
780 	KUNIT_EXPECT_EQ(test, ret, 0);
781 	KUNIT_EXPECT_MEMEQ(test,
782 			   priv->connector.hdmi.product,
783 			   expected_product,
784 			   sizeof(priv->connector.hdmi.product));
785 }
786 
787 /*
788  * Test that the registration of a connector with a product name larger
789  * than the maximum length fails.
790  */
drm_test_connector_hdmi_init_product_length_too_long(struct kunit * test)791 static void drm_test_connector_hdmi_init_product_length_too_long(struct kunit *test)
792 {
793 	struct drm_connector_init_priv *priv = test->priv;
794 	const char *product_name = "ProductProductProduct";
795 	int ret;
796 
797 	KUNIT_ASSERT_GT(test, strlen(product_name), DRM_CONNECTOR_HDMI_PRODUCT_LEN);
798 
799 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
800 				       "Vendor", product_name,
801 				       &dummy_funcs,
802 				       &dummy_hdmi_funcs,
803 				       DRM_MODE_CONNECTOR_HDMIA,
804 				       &priv->ddc,
805 				       BIT(HDMI_COLORSPACE_RGB),
806 				       8);
807 	KUNIT_EXPECT_LT(test, ret, 0);
808 }
809 
810 /*
811  * Test that the registration of a connector with a vendor name smaller
812  * than the maximum length succeeds, and is stored padded with zeros.
813  */
drm_test_connector_hdmi_init_vendor_valid(struct kunit * test)814 static void drm_test_connector_hdmi_init_vendor_valid(struct kunit *test)
815 {
816 	struct drm_connector_init_priv *priv = test->priv;
817 	const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = {
818 		'V', 'e', 'n', 'd',
819 	};
820 	const char *vendor_name = "Vend";
821 	int ret;
822 
823 	KUNIT_ASSERT_LT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
824 
825 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
826 				       vendor_name, "Product",
827 				       &dummy_funcs,
828 				       &dummy_hdmi_funcs,
829 				       DRM_MODE_CONNECTOR_HDMIA,
830 				       &priv->ddc,
831 				       BIT(HDMI_COLORSPACE_RGB),
832 				       8);
833 	KUNIT_EXPECT_EQ(test, ret, 0);
834 	KUNIT_EXPECT_MEMEQ(test,
835 			   priv->connector.hdmi.vendor,
836 			   expected_vendor,
837 			   sizeof(priv->connector.hdmi.vendor));
838 }
839 
840 /*
841  * Test that the registration of a connector with a vendor name at the
842  * maximum length succeeds, and is stored padded without the trailing
843  * zero.
844  */
drm_test_connector_hdmi_init_vendor_length_exact(struct kunit * test)845 static void drm_test_connector_hdmi_init_vendor_length_exact(struct kunit *test)
846 {
847 	struct drm_connector_init_priv *priv = test->priv;
848 	const char expected_vendor[DRM_CONNECTOR_HDMI_VENDOR_LEN] = {
849 		'V', 'e', 'n', 'd', 'o', 'r',
850 		'V', 'e',
851 	};
852 	const char *vendor_name = "VendorVe";
853 	int ret;
854 
855 	KUNIT_ASSERT_EQ(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
856 
857 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
858 				       vendor_name, "Product",
859 				       &dummy_funcs,
860 				       &dummy_hdmi_funcs,
861 				       DRM_MODE_CONNECTOR_HDMIA,
862 				       &priv->ddc,
863 				       BIT(HDMI_COLORSPACE_RGB),
864 				       8);
865 	KUNIT_EXPECT_EQ(test, ret, 0);
866 	KUNIT_EXPECT_MEMEQ(test,
867 			   priv->connector.hdmi.vendor,
868 			   expected_vendor,
869 			   sizeof(priv->connector.hdmi.vendor));
870 }
871 
872 /*
873  * Test that the registration of a connector with a vendor name larger
874  * than the maximum length fails.
875  */
drm_test_connector_hdmi_init_vendor_length_too_long(struct kunit * test)876 static void drm_test_connector_hdmi_init_vendor_length_too_long(struct kunit *test)
877 {
878 	struct drm_connector_init_priv *priv = test->priv;
879 	const char *vendor_name = "VendorVendor";
880 	int ret;
881 
882 	KUNIT_ASSERT_GT(test, strlen(vendor_name), DRM_CONNECTOR_HDMI_VENDOR_LEN);
883 
884 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
885 				       vendor_name, "Product",
886 				       &dummy_funcs,
887 				       &dummy_hdmi_funcs,
888 				       DRM_MODE_CONNECTOR_HDMIA,
889 				       &priv->ddc,
890 				       BIT(HDMI_COLORSPACE_RGB),
891 				       8);
892 	KUNIT_EXPECT_LT(test, ret, 0);
893 }
894 
895 /*
896  * Test that the registration of a connector with an invalid maximum bpc
897  * count fails.
898  */
drm_test_connector_hdmi_init_bpc_invalid(struct kunit * test)899 static void drm_test_connector_hdmi_init_bpc_invalid(struct kunit *test)
900 {
901 	struct drm_connector_init_priv *priv = test->priv;
902 	int ret;
903 
904 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
905 				       "Vendor", "Product",
906 				       &dummy_funcs,
907 				       &dummy_hdmi_funcs,
908 				       DRM_MODE_CONNECTOR_HDMIA,
909 				       &priv->ddc,
910 				       BIT(HDMI_COLORSPACE_RGB),
911 				       9);
912 	KUNIT_EXPECT_LT(test, ret, 0);
913 }
914 
915 /*
916  * Test that the registration of a connector with a null maximum bpc
917  * count fails.
918  */
drm_test_connector_hdmi_init_bpc_null(struct kunit * test)919 static void drm_test_connector_hdmi_init_bpc_null(struct kunit *test)
920 {
921 	struct drm_connector_init_priv *priv = test->priv;
922 	int ret;
923 
924 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
925 				       "Vendor", "Product",
926 				       &dummy_funcs,
927 				       &dummy_hdmi_funcs,
928 				       DRM_MODE_CONNECTOR_HDMIA,
929 				       &priv->ddc,
930 				       BIT(HDMI_COLORSPACE_RGB),
931 				       0);
932 	KUNIT_EXPECT_LT(test, ret, 0);
933 }
934 
935 /*
936  * Test that the registration of a connector with a maximum bpc count of
937  * 8 succeeds, registers the max bpc property, but doesn't register the
938  * HDR output metadata one.
939  */
drm_test_connector_hdmi_init_bpc_8(struct kunit * test)940 static void drm_test_connector_hdmi_init_bpc_8(struct kunit *test)
941 {
942 	struct drm_connector_init_priv *priv = test->priv;
943 	struct drm_connector_state *state;
944 	struct drm_connector *connector = &priv->connector;
945 	struct drm_property *prop;
946 	uint64_t val;
947 	int ret;
948 
949 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
950 				       "Vendor", "Product",
951 				       &dummy_funcs,
952 				       &dummy_hdmi_funcs,
953 				       DRM_MODE_CONNECTOR_HDMIA,
954 				       &priv->ddc,
955 				       BIT(HDMI_COLORSPACE_RGB),
956 				       8);
957 	KUNIT_EXPECT_EQ(test, ret, 0);
958 
959 	prop = connector->max_bpc_property;
960 	KUNIT_ASSERT_NOT_NULL(test, prop);
961 	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
962 
963 	ret = drm_object_property_get_default_value(&connector->base, prop, &val);
964 	KUNIT_EXPECT_EQ(test, ret, 0);
965 	KUNIT_EXPECT_EQ(test, val, 8);
966 
967 	state = connector->state;
968 	KUNIT_EXPECT_EQ(test, state->max_bpc, 8);
969 	KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 8);
970 
971 	prop = priv->drm.mode_config.hdr_output_metadata_property;
972 	KUNIT_ASSERT_NOT_NULL(test, prop);
973 	KUNIT_EXPECT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
974 }
975 
976 /*
977  * Test that the registration of a connector with a maximum bpc count of
978  * 10 succeeds and registers the max bpc and HDR output metadata
979  * properties.
980  */
drm_test_connector_hdmi_init_bpc_10(struct kunit * test)981 static void drm_test_connector_hdmi_init_bpc_10(struct kunit *test)
982 {
983 	struct drm_connector_init_priv *priv = test->priv;
984 	struct drm_connector_state *state;
985 	struct drm_connector *connector = &priv->connector;
986 	struct drm_property *prop;
987 	uint64_t val;
988 	int ret;
989 
990 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
991 				       "Vendor", "Product",
992 				       &dummy_funcs,
993 				       &dummy_hdmi_funcs,
994 				       DRM_MODE_CONNECTOR_HDMIA,
995 				       &priv->ddc,
996 				       BIT(HDMI_COLORSPACE_RGB),
997 				       10);
998 	KUNIT_EXPECT_EQ(test, ret, 0);
999 
1000 	prop = connector->max_bpc_property;
1001 	KUNIT_ASSERT_NOT_NULL(test, prop);
1002 	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
1003 
1004 	ret = drm_object_property_get_default_value(&connector->base, prop, &val);
1005 	KUNIT_EXPECT_EQ(test, ret, 0);
1006 	KUNIT_EXPECT_EQ(test, val, 10);
1007 
1008 	state = connector->state;
1009 	KUNIT_EXPECT_EQ(test, state->max_bpc, 10);
1010 	KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 10);
1011 
1012 	prop = priv->drm.mode_config.hdr_output_metadata_property;
1013 	KUNIT_ASSERT_NOT_NULL(test, prop);
1014 	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
1015 }
1016 
1017 /*
1018  * Test that the registration of a connector with a maximum bpc count of
1019  * 12 succeeds and registers the max bpc and HDR output metadata
1020  * properties.
1021  */
drm_test_connector_hdmi_init_bpc_12(struct kunit * test)1022 static void drm_test_connector_hdmi_init_bpc_12(struct kunit *test)
1023 {
1024 	struct drm_connector_init_priv *priv = test->priv;
1025 	struct drm_connector_state *state;
1026 	struct drm_connector *connector = &priv->connector;
1027 	struct drm_property *prop;
1028 	uint64_t val;
1029 	int ret;
1030 
1031 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
1032 				       "Vendor", "Product",
1033 				       &dummy_funcs,
1034 				       &dummy_hdmi_funcs,
1035 				       DRM_MODE_CONNECTOR_HDMIA,
1036 				       &priv->ddc,
1037 				       BIT(HDMI_COLORSPACE_RGB),
1038 				       12);
1039 	KUNIT_EXPECT_EQ(test, ret, 0);
1040 
1041 	prop = connector->max_bpc_property;
1042 	KUNIT_ASSERT_NOT_NULL(test, prop);
1043 	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
1044 
1045 	ret = drm_object_property_get_default_value(&connector->base, prop, &val);
1046 	KUNIT_EXPECT_EQ(test, ret, 0);
1047 	KUNIT_EXPECT_EQ(test, val, 12);
1048 
1049 	state = connector->state;
1050 	KUNIT_EXPECT_EQ(test, state->max_bpc, 12);
1051 	KUNIT_EXPECT_EQ(test, state->max_requested_bpc, 12);
1052 
1053 	prop = priv->drm.mode_config.hdr_output_metadata_property;
1054 	KUNIT_ASSERT_NOT_NULL(test, prop);
1055 	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
1056 }
1057 
1058 /*
1059  * Test that the registration of an HDMI connector with no supported
1060  * format fails.
1061  */
drm_test_connector_hdmi_init_formats_empty(struct kunit * test)1062 static void drm_test_connector_hdmi_init_formats_empty(struct kunit *test)
1063 {
1064 	struct drm_connector_init_priv *priv = test->priv;
1065 	int ret;
1066 
1067 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
1068 				       "Vendor", "Product",
1069 				       &dummy_funcs,
1070 				       &dummy_hdmi_funcs,
1071 				       DRM_MODE_CONNECTOR_HDMIA,
1072 				       &priv->ddc,
1073 				       0,
1074 				       8);
1075 	KUNIT_EXPECT_LT(test, ret, 0);
1076 }
1077 
1078 /*
1079  * Test that the registration of an HDMI connector not listing RGB as a
1080  * supported format fails.
1081  */
drm_test_connector_hdmi_init_formats_no_rgb(struct kunit * test)1082 static void drm_test_connector_hdmi_init_formats_no_rgb(struct kunit *test)
1083 {
1084 	struct drm_connector_init_priv *priv = test->priv;
1085 	int ret;
1086 
1087 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
1088 				       "Vendor", "Product",
1089 				       &dummy_funcs,
1090 				       &dummy_hdmi_funcs,
1091 				       DRM_MODE_CONNECTOR_HDMIA,
1092 				       &priv->ddc,
1093 				       BIT(HDMI_COLORSPACE_YUV422),
1094 				       8);
1095 	KUNIT_EXPECT_LT(test, ret, 0);
1096 }
1097 
1098 struct drm_connector_hdmi_init_formats_yuv420_allowed_test {
1099 	unsigned long supported_formats;
1100 	bool yuv420_allowed;
1101 	int expected_result;
1102 };
1103 
1104 #define YUV420_ALLOWED_TEST(_formats, _allowed, _result)			\
1105 	{									\
1106 		.supported_formats = BIT(HDMI_COLORSPACE_RGB) | (_formats),	\
1107 		.yuv420_allowed = _allowed,					\
1108 		.expected_result = _result,					\
1109 	}
1110 
1111 static const struct drm_connector_hdmi_init_formats_yuv420_allowed_test
1112 drm_connector_hdmi_init_formats_yuv420_allowed_tests[] = {
1113 	YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV420), true, 0),
1114 	YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV420), false, -EINVAL),
1115 	YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV422), true, -EINVAL),
1116 	YUV420_ALLOWED_TEST(BIT(HDMI_COLORSPACE_YUV422), false, 0),
1117 };
1118 
1119 static void
drm_connector_hdmi_init_formats_yuv420_allowed_desc(const struct drm_connector_hdmi_init_formats_yuv420_allowed_test * t,char * desc)1120 drm_connector_hdmi_init_formats_yuv420_allowed_desc(const struct drm_connector_hdmi_init_formats_yuv420_allowed_test *t,
1121 						    char *desc)
1122 {
1123 	sprintf(desc, "supported_formats=0x%lx yuv420_allowed=%d",
1124 		t->supported_formats, t->yuv420_allowed);
1125 }
1126 
1127 KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_formats_yuv420_allowed,
1128 		  drm_connector_hdmi_init_formats_yuv420_allowed_tests,
1129 		  drm_connector_hdmi_init_formats_yuv420_allowed_desc);
1130 
1131 /*
1132  * Test that the registration of an HDMI connector succeeds only when
1133  * the presence of YUV420 in the supported formats matches the value
1134  * of the ycbcr_420_allowed flag.
1135  */
drm_test_connector_hdmi_init_formats_yuv420_allowed(struct kunit * test)1136 static void drm_test_connector_hdmi_init_formats_yuv420_allowed(struct kunit *test)
1137 {
1138 	const struct drm_connector_hdmi_init_formats_yuv420_allowed_test *params;
1139 	struct drm_connector_init_priv *priv = test->priv;
1140 	int ret;
1141 
1142 	params = test->param_value;
1143 	priv->connector.ycbcr_420_allowed = params->yuv420_allowed;
1144 
1145 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
1146 				       "Vendor", "Product",
1147 				       &dummy_funcs,
1148 				       &dummy_hdmi_funcs,
1149 				       DRM_MODE_CONNECTOR_HDMIA,
1150 				       &priv->ddc,
1151 				       params->supported_formats,
1152 				       8);
1153 	KUNIT_EXPECT_EQ(test, ret, params->expected_result);
1154 }
1155 
1156 /*
1157  * Test that the registration of an HDMI connector with an HDMI
1158  * connector type succeeds.
1159  */
drm_test_connector_hdmi_init_type_valid(struct kunit * test)1160 static void drm_test_connector_hdmi_init_type_valid(struct kunit *test)
1161 {
1162 	struct drm_connector_init_priv *priv = test->priv;
1163 	unsigned int connector_type = *(unsigned int *)test->param_value;
1164 	int ret;
1165 
1166 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
1167 				       "Vendor", "Product",
1168 				       &dummy_funcs,
1169 				       &dummy_hdmi_funcs,
1170 				       connector_type,
1171 				       &priv->ddc,
1172 				       BIT(HDMI_COLORSPACE_RGB),
1173 				       8);
1174 	KUNIT_EXPECT_EQ(test, ret, 0);
1175 }
1176 
1177 static const unsigned int drm_connector_hdmi_init_type_valid_tests[] = {
1178 	DRM_MODE_CONNECTOR_HDMIA,
1179 	DRM_MODE_CONNECTOR_HDMIB,
1180 };
1181 
drm_connector_hdmi_init_type_desc(const unsigned int * type,char * desc)1182 static void drm_connector_hdmi_init_type_desc(const unsigned int *type, char *desc)
1183 {
1184 	sprintf(desc, "%s", drm_get_connector_type_name(*type));
1185 }
1186 
1187 KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_valid,
1188 		  drm_connector_hdmi_init_type_valid_tests,
1189 		  drm_connector_hdmi_init_type_desc);
1190 
1191 /*
1192  * Test that the registration of an HDMI connector with an !HDMI
1193  * connector type fails.
1194  */
drm_test_connector_hdmi_init_type_invalid(struct kunit * test)1195 static void drm_test_connector_hdmi_init_type_invalid(struct kunit *test)
1196 {
1197 	struct drm_connector_init_priv *priv = test->priv;
1198 	unsigned int connector_type = *(unsigned int *)test->param_value;
1199 	int ret;
1200 
1201 	ret = drmm_connector_hdmi_init(&priv->drm, &priv->connector,
1202 				       "Vendor", "Product",
1203 				       &dummy_funcs,
1204 				       &dummy_hdmi_funcs,
1205 				       connector_type,
1206 				       &priv->ddc,
1207 				       BIT(HDMI_COLORSPACE_RGB),
1208 				       8);
1209 	KUNIT_EXPECT_LT(test, ret, 0);
1210 }
1211 
1212 static const unsigned int drm_connector_hdmi_init_type_invalid_tests[] = {
1213 	DRM_MODE_CONNECTOR_Unknown,
1214 	DRM_MODE_CONNECTOR_VGA,
1215 	DRM_MODE_CONNECTOR_DVII,
1216 	DRM_MODE_CONNECTOR_DVID,
1217 	DRM_MODE_CONNECTOR_DVIA,
1218 	DRM_MODE_CONNECTOR_Composite,
1219 	DRM_MODE_CONNECTOR_SVIDEO,
1220 	DRM_MODE_CONNECTOR_LVDS,
1221 	DRM_MODE_CONNECTOR_Component,
1222 	DRM_MODE_CONNECTOR_9PinDIN,
1223 	DRM_MODE_CONNECTOR_DisplayPort,
1224 	DRM_MODE_CONNECTOR_TV,
1225 	DRM_MODE_CONNECTOR_eDP,
1226 	DRM_MODE_CONNECTOR_VIRTUAL,
1227 	DRM_MODE_CONNECTOR_DSI,
1228 	DRM_MODE_CONNECTOR_DPI,
1229 	DRM_MODE_CONNECTOR_WRITEBACK,
1230 	DRM_MODE_CONNECTOR_SPI,
1231 	DRM_MODE_CONNECTOR_USB,
1232 };
1233 
1234 KUNIT_ARRAY_PARAM(drm_connector_hdmi_init_type_invalid,
1235 		  drm_connector_hdmi_init_type_invalid_tests,
1236 		  drm_connector_hdmi_init_type_desc);
1237 
1238 static struct kunit_case drmm_connector_hdmi_init_tests[] = {
1239 	KUNIT_CASE(drm_test_connector_hdmi_init_valid),
1240 	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_8),
1241 	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_10),
1242 	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_12),
1243 	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_invalid),
1244 	KUNIT_CASE(drm_test_connector_hdmi_init_bpc_null),
1245 	KUNIT_CASE(drm_test_connector_hdmi_init_formats_empty),
1246 	KUNIT_CASE(drm_test_connector_hdmi_init_formats_no_rgb),
1247 	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_formats_yuv420_allowed,
1248 			 drm_connector_hdmi_init_formats_yuv420_allowed_gen_params),
1249 	KUNIT_CASE(drm_test_connector_hdmi_init_null_ddc),
1250 	KUNIT_CASE(drm_test_connector_hdmi_init_null_product),
1251 	KUNIT_CASE(drm_test_connector_hdmi_init_null_vendor),
1252 	KUNIT_CASE(drm_test_connector_hdmi_init_product_length_exact),
1253 	KUNIT_CASE(drm_test_connector_hdmi_init_product_length_too_long),
1254 	KUNIT_CASE(drm_test_connector_hdmi_init_product_valid),
1255 	KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_exact),
1256 	KUNIT_CASE(drm_test_connector_hdmi_init_vendor_length_too_long),
1257 	KUNIT_CASE(drm_test_connector_hdmi_init_vendor_valid),
1258 	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_valid,
1259 			 drm_connector_hdmi_init_type_valid_gen_params),
1260 	KUNIT_CASE_PARAM(drm_test_connector_hdmi_init_type_invalid,
1261 			 drm_connector_hdmi_init_type_invalid_gen_params),
1262 	{ }
1263 };
1264 
1265 static struct kunit_suite drmm_connector_hdmi_init_test_suite = {
1266 	.name = "drmm_connector_hdmi_init",
1267 	.init = drm_test_connector_init,
1268 	.test_cases = drmm_connector_hdmi_init_tests,
1269 };
1270 
1271 struct drm_get_tv_mode_from_name_test {
1272 	const char *name;
1273 	enum drm_connector_tv_mode expected_mode;
1274 };
1275 
1276 #define TV_MODE_NAME(_name, _mode)		\
1277 	{					\
1278 		.name = _name,			\
1279 		.expected_mode = _mode,		\
1280 	}
1281 
drm_test_get_tv_mode_from_name_valid(struct kunit * test)1282 static void drm_test_get_tv_mode_from_name_valid(struct kunit *test)
1283 {
1284 	const struct drm_get_tv_mode_from_name_test *params = test->param_value;
1285 
1286 	KUNIT_EXPECT_EQ(test,
1287 			drm_get_tv_mode_from_name(params->name, strlen(params->name)),
1288 			params->expected_mode);
1289 }
1290 
1291 static const
1292 struct drm_get_tv_mode_from_name_test drm_get_tv_mode_from_name_valid_tests[] = {
1293 	TV_MODE_NAME("NTSC", DRM_MODE_TV_MODE_NTSC),
1294 	TV_MODE_NAME("NTSC-443", DRM_MODE_TV_MODE_NTSC_443),
1295 	TV_MODE_NAME("NTSC-J", DRM_MODE_TV_MODE_NTSC_J),
1296 	TV_MODE_NAME("PAL", DRM_MODE_TV_MODE_PAL),
1297 	TV_MODE_NAME("PAL-M", DRM_MODE_TV_MODE_PAL_M),
1298 	TV_MODE_NAME("PAL-N", DRM_MODE_TV_MODE_PAL_N),
1299 	TV_MODE_NAME("SECAM", DRM_MODE_TV_MODE_SECAM),
1300 	TV_MODE_NAME("Mono", DRM_MODE_TV_MODE_MONOCHROME),
1301 };
1302 
1303 static void
drm_get_tv_mode_from_name_valid_desc(const struct drm_get_tv_mode_from_name_test * t,char * desc)1304 drm_get_tv_mode_from_name_valid_desc(const struct drm_get_tv_mode_from_name_test *t,
1305 				     char *desc)
1306 {
1307 	sprintf(desc, "%s", t->name);
1308 }
1309 
1310 KUNIT_ARRAY_PARAM(drm_get_tv_mode_from_name_valid,
1311 		  drm_get_tv_mode_from_name_valid_tests,
1312 		  drm_get_tv_mode_from_name_valid_desc);
1313 
drm_test_get_tv_mode_from_name_truncated(struct kunit * test)1314 static void drm_test_get_tv_mode_from_name_truncated(struct kunit *test)
1315 {
1316 	const char *name = "NTS";
1317 	int ret;
1318 
1319 	ret = drm_get_tv_mode_from_name(name, strlen(name));
1320 	KUNIT_EXPECT_LT(test, ret, 0);
1321 };
1322 
1323 static struct kunit_case drm_get_tv_mode_from_name_tests[] = {
1324 	KUNIT_CASE_PARAM(drm_test_get_tv_mode_from_name_valid,
1325 			 drm_get_tv_mode_from_name_valid_gen_params),
1326 	KUNIT_CASE(drm_test_get_tv_mode_from_name_truncated),
1327 	{ }
1328 };
1329 
1330 static struct kunit_suite drm_get_tv_mode_from_name_test_suite = {
1331 	.name = "drm_get_tv_mode_from_name",
1332 	.test_cases = drm_get_tv_mode_from_name_tests,
1333 };
1334 
1335 struct drm_hdmi_connector_get_broadcast_rgb_name_test {
1336 	unsigned int kind;
1337 	const char *expected_name;
1338 };
1339 
1340 #define BROADCAST_RGB_TEST(_kind, _name)	\
1341 	{					\
1342 		.kind = _kind,			\
1343 		.expected_name = _name,		\
1344 	}
1345 
drm_test_drm_hdmi_connector_get_broadcast_rgb_name(struct kunit * test)1346 static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name(struct kunit *test)
1347 {
1348 	const struct drm_hdmi_connector_get_broadcast_rgb_name_test *params =
1349 		test->param_value;
1350 
1351 	KUNIT_EXPECT_STREQ(test,
1352 			   drm_hdmi_connector_get_broadcast_rgb_name(params->kind),
1353 			   params->expected_name);
1354 }
1355 
1356 static const
1357 struct drm_hdmi_connector_get_broadcast_rgb_name_test
1358 drm_hdmi_connector_get_broadcast_rgb_name_valid_tests[] = {
1359 	BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_AUTO, "Automatic"),
1360 	BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_FULL, "Full"),
1361 	BROADCAST_RGB_TEST(DRM_HDMI_BROADCAST_RGB_LIMITED, "Limited 16:235"),
1362 };
1363 
1364 static void
drm_hdmi_connector_get_broadcast_rgb_name_valid_desc(const struct drm_hdmi_connector_get_broadcast_rgb_name_test * t,char * desc)1365 drm_hdmi_connector_get_broadcast_rgb_name_valid_desc(const struct drm_hdmi_connector_get_broadcast_rgb_name_test *t,
1366 						     char *desc)
1367 {
1368 	sprintf(desc, "%s", t->expected_name);
1369 }
1370 
1371 KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_broadcast_rgb_name_valid,
1372 		  drm_hdmi_connector_get_broadcast_rgb_name_valid_tests,
1373 		  drm_hdmi_connector_get_broadcast_rgb_name_valid_desc);
1374 
drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid(struct kunit * test)1375 static void drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid(struct kunit *test)
1376 {
1377 	KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_broadcast_rgb_name(3));
1378 };
1379 
1380 static struct kunit_case drm_hdmi_connector_get_broadcast_rgb_name_tests[] = {
1381 	KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_broadcast_rgb_name,
1382 			 drm_hdmi_connector_get_broadcast_rgb_name_valid_gen_params),
1383 	KUNIT_CASE(drm_test_drm_hdmi_connector_get_broadcast_rgb_name_invalid),
1384 	{ }
1385 };
1386 
1387 static struct kunit_suite drm_hdmi_connector_get_broadcast_rgb_name_test_suite = {
1388 	.name = "drm_hdmi_connector_get_broadcast_rgb_name",
1389 	.test_cases = drm_hdmi_connector_get_broadcast_rgb_name_tests,
1390 };
1391 
1392 struct drm_hdmi_connector_get_output_format_name_test {
1393 	unsigned int kind;
1394 	const char *expected_name;
1395 };
1396 
1397 #define OUTPUT_FORMAT_TEST(_kind, _name)	\
1398 	{					\
1399 		.kind = _kind,			\
1400 		.expected_name = _name,		\
1401 	}
1402 
drm_test_drm_hdmi_connector_get_output_format_name(struct kunit * test)1403 static void drm_test_drm_hdmi_connector_get_output_format_name(struct kunit *test)
1404 {
1405 	const struct drm_hdmi_connector_get_output_format_name_test *params =
1406 		test->param_value;
1407 
1408 	KUNIT_EXPECT_STREQ(test,
1409 			   drm_hdmi_connector_get_output_format_name(params->kind),
1410 			   params->expected_name);
1411 }
1412 
1413 static const
1414 struct drm_hdmi_connector_get_output_format_name_test
1415 drm_hdmi_connector_get_output_format_name_valid_tests[] = {
1416 	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_RGB, "RGB"),
1417 	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV420, "YUV 4:2:0"),
1418 	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV422, "YUV 4:2:2"),
1419 	OUTPUT_FORMAT_TEST(HDMI_COLORSPACE_YUV444, "YUV 4:4:4"),
1420 };
1421 
1422 static void
drm_hdmi_connector_get_output_format_name_valid_desc(const struct drm_hdmi_connector_get_output_format_name_test * t,char * desc)1423 drm_hdmi_connector_get_output_format_name_valid_desc(const struct drm_hdmi_connector_get_output_format_name_test *t,
1424 						     char *desc)
1425 {
1426 	sprintf(desc, "%s", t->expected_name);
1427 }
1428 
1429 KUNIT_ARRAY_PARAM(drm_hdmi_connector_get_output_format_name_valid,
1430 		  drm_hdmi_connector_get_output_format_name_valid_tests,
1431 		  drm_hdmi_connector_get_output_format_name_valid_desc);
1432 
drm_test_drm_hdmi_connector_get_output_format_name_invalid(struct kunit * test)1433 static void drm_test_drm_hdmi_connector_get_output_format_name_invalid(struct kunit *test)
1434 {
1435 	KUNIT_EXPECT_NULL(test, drm_hdmi_connector_get_output_format_name(4));
1436 };
1437 
1438 static struct kunit_case drm_hdmi_connector_get_output_format_name_tests[] = {
1439 	KUNIT_CASE_PARAM(drm_test_drm_hdmi_connector_get_output_format_name,
1440 			 drm_hdmi_connector_get_output_format_name_valid_gen_params),
1441 	KUNIT_CASE(drm_test_drm_hdmi_connector_get_output_format_name_invalid),
1442 	{ }
1443 };
1444 
1445 static struct kunit_suite drm_hdmi_connector_get_output_format_name_test_suite = {
1446 	.name = "drm_hdmi_connector_get_output_format_name",
1447 	.test_cases = drm_hdmi_connector_get_output_format_name_tests,
1448 };
1449 
drm_test_drm_connector_attach_broadcast_rgb_property(struct kunit * test)1450 static void drm_test_drm_connector_attach_broadcast_rgb_property(struct kunit *test)
1451 {
1452 	struct drm_connector_init_priv *priv = test->priv;
1453 	struct drm_connector *connector = &priv->connector;
1454 	struct drm_property *prop;
1455 	int ret;
1456 
1457 	ret = drmm_connector_init(&priv->drm, connector,
1458 				  &dummy_funcs,
1459 				  DRM_MODE_CONNECTOR_HDMIA,
1460 				  &priv->ddc);
1461 	KUNIT_ASSERT_EQ(test, ret, 0);
1462 
1463 	ret = drm_connector_attach_broadcast_rgb_property(connector);
1464 	KUNIT_ASSERT_EQ(test, ret, 0);
1465 
1466 	prop = connector->broadcast_rgb_property;
1467 	KUNIT_ASSERT_NOT_NULL(test, prop);
1468 	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
1469 }
1470 
drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(struct kunit * test)1471 static void drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector(struct kunit *test)
1472 {
1473 	struct drm_connector_init_priv *priv = test->priv;
1474 	struct drm_connector *connector = &priv->connector;
1475 	struct drm_property *prop;
1476 	int ret;
1477 
1478 	ret = drmm_connector_hdmi_init(&priv->drm, connector,
1479 				       "Vendor", "Product",
1480 				       &dummy_funcs,
1481 				       &dummy_hdmi_funcs,
1482 				       DRM_MODE_CONNECTOR_HDMIA,
1483 				       &priv->ddc,
1484 				       BIT(HDMI_COLORSPACE_RGB),
1485 				       8);
1486 	KUNIT_EXPECT_EQ(test, ret, 0);
1487 
1488 	ret = drm_connector_attach_broadcast_rgb_property(connector);
1489 	KUNIT_ASSERT_EQ(test, ret, 0);
1490 
1491 	prop = connector->broadcast_rgb_property;
1492 	KUNIT_ASSERT_NOT_NULL(test, prop);
1493 	KUNIT_EXPECT_NOT_NULL(test, drm_mode_obj_find_prop_id(&connector->base, prop->base.id));
1494 }
1495 
1496 static struct kunit_case drm_connector_attach_broadcast_rgb_property_tests[] = {
1497 	KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property),
1498 	KUNIT_CASE(drm_test_drm_connector_attach_broadcast_rgb_property_hdmi_connector),
1499 	{ }
1500 };
1501 
1502 static struct kunit_suite drm_connector_attach_broadcast_rgb_property_test_suite = {
1503 	.name = "drm_connector_attach_broadcast_rgb_property",
1504 	.init = drm_test_connector_init,
1505 	.test_cases = drm_connector_attach_broadcast_rgb_property_tests,
1506 };
1507 
1508 /*
1509  * Test that for a given mode, with 8bpc and an RGB output the TMDS
1510  * character rate is equal to the mode pixel clock.
1511  */
drm_test_drm_hdmi_compute_mode_clock_rgb(struct kunit * test)1512 static void drm_test_drm_hdmi_compute_mode_clock_rgb(struct kunit *test)
1513 {
1514 	struct drm_connector_init_priv *priv = test->priv;
1515 	const struct drm_display_mode *mode;
1516 	unsigned long long rate;
1517 	struct drm_device *drm = &priv->drm;
1518 
1519 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1520 	KUNIT_ASSERT_NOT_NULL(test, mode);
1521 
1522 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1523 
1524 	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
1525 	KUNIT_ASSERT_GT(test, rate, 0);
1526 	KUNIT_EXPECT_EQ(test, mode->clock * 1000ULL, rate);
1527 }
1528 
1529 /*
1530  * Test that for a given mode, with 10bpc and an RGB output the TMDS
1531  * character rate is equal to 1.25 times the mode pixel clock.
1532  */
drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc(struct kunit * test)1533 static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc(struct kunit *test)
1534 {
1535 	struct drm_connector_init_priv *priv = test->priv;
1536 	const struct drm_display_mode *mode;
1537 	unsigned long long rate;
1538 	struct drm_device *drm = &priv->drm;
1539 
1540 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1541 	KUNIT_ASSERT_NOT_NULL(test, mode);
1542 
1543 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1544 
1545 	rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
1546 	KUNIT_ASSERT_GT(test, rate, 0);
1547 	KUNIT_EXPECT_EQ(test, mode->clock * 1250, rate);
1548 }
1549 
1550 /*
1551  * Test that for the VIC-1 mode, with 10bpc and an RGB output the TMDS
1552  * character rate computation fails.
1553  */
drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit * test)1554 static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *test)
1555 {
1556 	struct drm_connector_init_priv *priv = test->priv;
1557 	const struct drm_display_mode *mode;
1558 	unsigned long long rate;
1559 	struct drm_device *drm = &priv->drm;
1560 
1561 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
1562 	KUNIT_ASSERT_NOT_NULL(test, mode);
1563 
1564 	rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB);
1565 	KUNIT_EXPECT_EQ(test, rate, 0);
1566 }
1567 
1568 /*
1569  * Test that for a given mode, with 12bpc and an RGB output the TMDS
1570  * character rate is equal to 1.5 times the mode pixel clock.
1571  */
drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc(struct kunit * test)1572 static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test)
1573 {
1574 	struct drm_connector_init_priv *priv = test->priv;
1575 	const struct drm_display_mode *mode;
1576 	unsigned long long rate;
1577 	struct drm_device *drm = &priv->drm;
1578 
1579 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1580 	KUNIT_ASSERT_NOT_NULL(test, mode);
1581 
1582 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1583 
1584 	rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
1585 	KUNIT_ASSERT_GT(test, rate, 0);
1586 	KUNIT_EXPECT_EQ(test, mode->clock * 1500, rate);
1587 }
1588 
1589 /*
1590  * Test that for the VIC-1 mode, with 12bpc and an RGB output the TMDS
1591  * character rate computation fails.
1592  */
drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit * test)1593 static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *test)
1594 {
1595 	struct drm_connector_init_priv *priv = test->priv;
1596 	const struct drm_display_mode *mode;
1597 	unsigned long long rate;
1598 	struct drm_device *drm = &priv->drm;
1599 
1600 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1);
1601 	KUNIT_ASSERT_NOT_NULL(test, mode);
1602 
1603 	rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB);
1604 	KUNIT_EXPECT_EQ(test, rate, 0);
1605 }
1606 
1607 /*
1608  * Test that for a mode with the pixel repetition flag, the TMDS
1609  * character rate is indeed double the mode pixel clock.
1610  */
drm_test_drm_hdmi_compute_mode_clock_rgb_double(struct kunit * test)1611 static void drm_test_drm_hdmi_compute_mode_clock_rgb_double(struct kunit *test)
1612 {
1613 	struct drm_connector_init_priv *priv = test->priv;
1614 	const struct drm_display_mode *mode;
1615 	unsigned long long rate;
1616 	struct drm_device *drm = &priv->drm;
1617 
1618 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 6);
1619 	KUNIT_ASSERT_NOT_NULL(test, mode);
1620 
1621 	KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1622 
1623 	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_RGB);
1624 	KUNIT_ASSERT_GT(test, rate, 0);
1625 	KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) * 2, rate);
1626 }
1627 
1628 /*
1629  * Test that the TMDS character rate computation for the VIC modes
1630  * explicitly listed in the spec as supporting YUV420 succeed and return
1631  * half the mode pixel clock.
1632  */
drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit * test)1633 static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit *test)
1634 {
1635 	struct drm_connector_init_priv *priv = test->priv;
1636 	const struct drm_display_mode *mode;
1637 	struct drm_device *drm = &priv->drm;
1638 	unsigned long long rate;
1639 	unsigned int vic = *(unsigned int *)test->param_value;
1640 
1641 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
1642 	KUNIT_ASSERT_NOT_NULL(test, mode);
1643 
1644 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1645 
1646 	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV420);
1647 	KUNIT_ASSERT_GT(test, rate, 0);
1648 	KUNIT_EXPECT_EQ(test, (mode->clock * 1000ULL) / 2, rate);
1649 }
1650 
1651 static const unsigned int drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[] = {
1652 	96, 97, 101, 102, 106, 107,
1653 };
1654 
drm_hdmi_compute_mode_clock_yuv420_vic_desc(const unsigned int * vic,char * desc)1655 static void drm_hdmi_compute_mode_clock_yuv420_vic_desc(const unsigned int *vic, char *desc)
1656 {
1657 	sprintf(desc, "VIC %u", *vic);
1658 }
1659 
1660 KUNIT_ARRAY_PARAM(drm_hdmi_compute_mode_clock_yuv420_valid,
1661 		  drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests,
1662 		  drm_hdmi_compute_mode_clock_yuv420_vic_desc);
1663 
1664 /*
1665  * Test that for a given mode listed supporting it and an YUV420 output
1666  * with 10bpc, the TMDS character rate is equal to 0.625 times the mode
1667  * pixel clock.
1668  */
drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kunit * test)1669 static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kunit *test)
1670 {
1671 	struct drm_connector_init_priv *priv = test->priv;
1672 	const struct drm_display_mode *mode;
1673 	struct drm_device *drm = &priv->drm;
1674 	unsigned int vic =
1675 		drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
1676 	unsigned long long rate;
1677 
1678 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
1679 	KUNIT_ASSERT_NOT_NULL(test, mode);
1680 
1681 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1682 
1683 	rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV420);
1684 	KUNIT_ASSERT_GT(test, rate, 0);
1685 
1686 	KUNIT_EXPECT_EQ(test, mode->clock * 625, rate);
1687 }
1688 
1689 /*
1690  * Test that for a given mode listed supporting it and an YUV420 output
1691  * with 12bpc, the TMDS character rate is equal to 0.75 times the mode
1692  * pixel clock.
1693  */
drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kunit * test)1694 static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kunit *test)
1695 {
1696 	struct drm_connector_init_priv *priv = test->priv;
1697 	const struct drm_display_mode *mode;
1698 	struct drm_device *drm = &priv->drm;
1699 	unsigned int vic =
1700 		drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0];
1701 	unsigned long long rate;
1702 
1703 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic);
1704 	KUNIT_ASSERT_NOT_NULL(test, mode);
1705 
1706 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1707 
1708 	rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV420);
1709 	KUNIT_ASSERT_GT(test, rate, 0);
1710 
1711 	KUNIT_EXPECT_EQ(test, mode->clock * 750, rate);
1712 }
1713 
1714 /*
1715  * Test that for a given mode, the computation of the TMDS character
1716  * rate with 8bpc and a YUV422 output succeeds and returns a rate equal
1717  * to the mode pixel clock.
1718  */
drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit * test)1719 static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit *test)
1720 {
1721 	struct drm_connector_init_priv *priv = test->priv;
1722 	const struct drm_display_mode *mode;
1723 	struct drm_device *drm = &priv->drm;
1724 	unsigned long long rate;
1725 
1726 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1727 	KUNIT_ASSERT_NOT_NULL(test, mode);
1728 
1729 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1730 
1731 	rate = drm_hdmi_compute_mode_clock(mode, 8, HDMI_COLORSPACE_YUV422);
1732 	KUNIT_ASSERT_GT(test, rate, 0);
1733 	KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
1734 }
1735 
1736 /*
1737  * Test that for a given mode, the computation of the TMDS character
1738  * rate with 10bpc and a YUV422 output succeeds and returns a rate equal
1739  * to the mode pixel clock.
1740  */
drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kunit * test)1741 static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kunit *test)
1742 {
1743 	struct drm_connector_init_priv *priv = test->priv;
1744 	const struct drm_display_mode *mode;
1745 	struct drm_device *drm = &priv->drm;
1746 	unsigned long long rate;
1747 
1748 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1749 	KUNIT_ASSERT_NOT_NULL(test, mode);
1750 
1751 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1752 
1753 	rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_YUV422);
1754 	KUNIT_ASSERT_GT(test, rate, 0);
1755 	KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
1756 }
1757 
1758 /*
1759  * Test that for a given mode, the computation of the TMDS character
1760  * rate with 12bpc and a YUV422 output succeeds and returns a rate equal
1761  * to the mode pixel clock.
1762  */
drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kunit * test)1763 static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kunit *test)
1764 {
1765 	struct drm_connector_init_priv *priv = test->priv;
1766 	const struct drm_display_mode *mode;
1767 	struct drm_device *drm = &priv->drm;
1768 	unsigned long long rate;
1769 
1770 	mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16);
1771 	KUNIT_ASSERT_NOT_NULL(test, mode);
1772 
1773 	KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK);
1774 
1775 	rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_YUV422);
1776 	KUNIT_ASSERT_GT(test, rate, 0);
1777 	KUNIT_EXPECT_EQ(test, mode->clock * 1000, rate);
1778 }
1779 
1780 static struct kunit_case drm_hdmi_compute_mode_clock_tests[] = {
1781 	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb),
1782 	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc),
1783 	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1),
1784 	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc),
1785 	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1),
1786 	KUNIT_CASE(drm_test_drm_hdmi_compute_mode_clock_rgb_double),
1787 	KUNIT_CASE_PARAM(drm_test_connector_hdmi_compute_mode_clock_yuv420_valid,
1788 			 drm_hdmi_compute_mode_clock_yuv420_valid_gen_params),
1789 	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc),
1790 	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc),
1791 	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc),
1792 	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc),
1793 	KUNIT_CASE(drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc),
1794 	{ }
1795 };
1796 
1797 static struct kunit_suite drm_hdmi_compute_mode_clock_test_suite = {
1798 	.name = "drm_test_connector_hdmi_compute_mode_clock",
1799 	.init = drm_test_connector_init,
1800 	.test_cases = drm_hdmi_compute_mode_clock_tests,
1801 };
1802 
1803 kunit_test_suites(
1804 	&drmm_connector_hdmi_init_test_suite,
1805 	&drmm_connector_init_test_suite,
1806 	&drm_connector_dynamic_init_test_suite,
1807 	&drm_connector_dynamic_register_early_test_suite,
1808 	&drm_connector_dynamic_register_test_suite,
1809 	&drm_connector_attach_broadcast_rgb_property_test_suite,
1810 	&drm_get_tv_mode_from_name_test_suite,
1811 	&drm_hdmi_compute_mode_clock_test_suite,
1812 	&drm_hdmi_connector_get_broadcast_rgb_name_test_suite,
1813 	&drm_hdmi_connector_get_output_format_name_test_suite
1814 );
1815 
1816 MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
1817 MODULE_DESCRIPTION("Kunit test for drm_modes functions");
1818 MODULE_LICENSE("GPL");
1819