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