]> Git Repo - linux.git/blob - drivers/gpu/drm/tests/drm_connector_test.c
Merge tag 'hyperv-next-signed-20250123' of git://git.kernel.org/pub/scm/linux/kernel...
[linux.git] / drivers / gpu / drm / tests / drm_connector_test.c
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
37 static int dummy_ddc_xfer(struct i2c_adapter *adapter,
38                           struct i2c_msg *msgs, int num)
39 {
40         return num;
41 }
42
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
53 static void i2c_del_adapter_wrapper(void *ptr)
54 {
55         struct i2c_adapter *adap = ptr;
56
57         i2c_del_adapter(adap);
58 }
59
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  */
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  */
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  */
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
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  */
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
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  */
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  */
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
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  */
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  */
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  */
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
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
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  */
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  */
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  */
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  */
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
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
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
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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
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  */
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  */
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
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  */
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
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
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
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
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
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
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
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
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
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
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
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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
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  */
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  */
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  */
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  */
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  */
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 <[email protected]>");
1817 MODULE_DESCRIPTION("Kunit test for drm_modes functions");
1818 MODULE_LICENSE("GPL");
This page took 0.133366 seconds and 4 git commands to generate.