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