]> Git Repo - J-linux.git/blob - drivers/gpu/drm/tests/drm_probe_helper_test.c
Merge tag 'ktest-v6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux...
[J-linux.git] / drivers / gpu / drm / tests / drm_probe_helper_test.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Kunit test for drm_probe_helper functions
4  */
5
6 #include <drm/drm_atomic_state_helper.h>
7 #include <drm/drm_connector.h>
8 #include <drm/drm_device.h>
9 #include <drm/drm_drv.h>
10 #include <drm/drm_kunit_helpers.h>
11 #include <drm/drm_mode.h>
12 #include <drm/drm_modes.h>
13 #include <drm/drm_modeset_helper_vtables.h>
14 #include <drm/drm_probe_helper.h>
15
16 #include <kunit/test.h>
17
18 struct drm_probe_helper_test_priv {
19         struct drm_device *drm;
20         struct device *dev;
21         struct drm_connector connector;
22 };
23
24 static const struct drm_connector_helper_funcs drm_probe_helper_connector_helper_funcs = {
25 };
26
27 static const struct drm_connector_funcs drm_probe_helper_connector_funcs = {
28         .atomic_destroy_state   = drm_atomic_helper_connector_destroy_state,
29         .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
30         .reset                  = drm_atomic_helper_connector_reset,
31 };
32
33 static int drm_probe_helper_test_init(struct kunit *test)
34 {
35         struct drm_probe_helper_test_priv *priv;
36         struct drm_connector *connector;
37         int ret;
38
39         priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
40         KUNIT_ASSERT_NOT_NULL(test, priv);
41         test->priv = priv;
42
43         priv->dev = drm_kunit_helper_alloc_device(test);
44         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->dev);
45
46         priv->drm = __drm_kunit_helper_alloc_drm_device(test, priv->dev,
47                                                         sizeof(*priv->drm), 0,
48                                                         DRIVER_MODESET | DRIVER_ATOMIC);
49         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);
50
51         connector = &priv->connector;
52         ret = drmm_connector_init(priv->drm, connector,
53                                   &drm_probe_helper_connector_funcs,
54                                   DRM_MODE_CONNECTOR_Unknown,
55                                   NULL);
56         KUNIT_ASSERT_EQ(test, ret, 0);
57
58         drm_connector_helper_add(connector, &drm_probe_helper_connector_helper_funcs);
59
60         return 0;
61 }
62
63 static void drm_probe_helper_test_exit(struct kunit *test)
64 {
65         struct drm_probe_helper_test_priv *priv = test->priv;
66
67         drm_kunit_helper_free_device(test, priv->dev);
68 }
69
70 typedef struct drm_display_mode *(*expected_mode_func_t)(struct drm_device *);
71
72 struct drm_connector_helper_tv_get_modes_test {
73         const char *name;
74         unsigned int supported_tv_modes;
75         enum drm_connector_tv_mode default_mode;
76         bool cmdline;
77         enum drm_connector_tv_mode cmdline_mode;
78         expected_mode_func_t *expected_modes;
79         unsigned int num_expected_modes;
80 };
81
82 #define _TV_MODE_TEST(_name, _supported, _default, _cmdline, _cmdline_mode, ...)                \
83         {                                                                                       \
84                 .name = _name,                                                                  \
85                 .supported_tv_modes = _supported,                                               \
86                 .default_mode = _default,                                                       \
87                 .cmdline = _cmdline,                                                            \
88                 .cmdline_mode = _cmdline_mode,                                                  \
89                 .expected_modes = (expected_mode_func_t[]) { __VA_ARGS__ },                     \
90                 .num_expected_modes = sizeof((expected_mode_func_t[]) { __VA_ARGS__ }) /        \
91                                       (sizeof(expected_mode_func_t)),                           \
92         }
93
94 #define TV_MODE_TEST(_name, _supported, _default, ...)                  \
95         _TV_MODE_TEST(_name, _supported, _default, false, 0, __VA_ARGS__)
96
97 #define TV_MODE_TEST_CMDLINE(_name, _supported, _default, _cmdline, ...) \
98         _TV_MODE_TEST(_name, _supported, _default, true, _cmdline, __VA_ARGS__)
99
100 static void
101 drm_test_connector_helper_tv_get_modes_check(struct kunit *test)
102 {
103         const struct drm_connector_helper_tv_get_modes_test *params = test->param_value;
104         struct drm_probe_helper_test_priv *priv = test->priv;
105         struct drm_connector *connector = &priv->connector;
106         struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
107         struct drm_display_mode *mode;
108         const struct drm_display_mode *expected;
109         size_t len;
110         int ret;
111
112         if (params->cmdline) {
113                 cmdline->tv_mode_specified = true;
114                 cmdline->tv_mode = params->cmdline_mode;
115         }
116
117         ret = drm_mode_create_tv_properties(priv->drm, params->supported_tv_modes);
118         KUNIT_ASSERT_EQ(test, ret, 0);
119
120         drm_object_attach_property(&connector->base,
121                                    priv->drm->mode_config.tv_mode_property,
122                                    params->default_mode);
123
124         mutex_lock(&priv->drm->mode_config.mutex);
125
126         ret = drm_connector_helper_tv_get_modes(connector);
127         KUNIT_EXPECT_EQ(test, ret, params->num_expected_modes);
128
129         len = 0;
130         list_for_each_entry(mode, &connector->probed_modes, head)
131                 len++;
132         KUNIT_EXPECT_EQ(test, len, params->num_expected_modes);
133
134         if (params->num_expected_modes >= 1) {
135                 mode = list_first_entry_or_null(&connector->probed_modes,
136                                                 struct drm_display_mode, head);
137                 KUNIT_ASSERT_NOT_NULL(test, mode);
138
139                 expected = params->expected_modes[0](priv->drm);
140                 KUNIT_ASSERT_NOT_NULL(test, expected);
141
142                 KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected));
143                 KUNIT_EXPECT_TRUE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
144         }
145
146         if (params->num_expected_modes >= 2) {
147                 mode = list_next_entry(mode, head);
148                 KUNIT_ASSERT_NOT_NULL(test, mode);
149
150                 expected = params->expected_modes[1](priv->drm);
151                 KUNIT_ASSERT_NOT_NULL(test, expected);
152
153                 KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected));
154                 KUNIT_EXPECT_FALSE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
155         }
156
157         mutex_unlock(&priv->drm->mode_config.mutex);
158 }
159
160 static const
161 struct drm_connector_helper_tv_get_modes_test drm_connector_helper_tv_get_modes_tests[] = {
162         { .name = "None" },
163         TV_MODE_TEST("PAL",
164                      BIT(DRM_MODE_TV_MODE_PAL),
165                      DRM_MODE_TV_MODE_PAL,
166                      drm_mode_analog_pal_576i),
167         TV_MODE_TEST("NTSC",
168                      BIT(DRM_MODE_TV_MODE_NTSC),
169                      DRM_MODE_TV_MODE_NTSC,
170                      drm_mode_analog_ntsc_480i),
171         TV_MODE_TEST("Both, NTSC Default",
172                      BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
173                      DRM_MODE_TV_MODE_NTSC,
174                      drm_mode_analog_ntsc_480i, drm_mode_analog_pal_576i),
175         TV_MODE_TEST("Both, PAL Default",
176                      BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
177                      DRM_MODE_TV_MODE_PAL,
178                      drm_mode_analog_pal_576i, drm_mode_analog_ntsc_480i),
179         TV_MODE_TEST_CMDLINE("Both, NTSC Default, with PAL on command-line",
180                              BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
181                              DRM_MODE_TV_MODE_NTSC,
182                              DRM_MODE_TV_MODE_PAL,
183                              drm_mode_analog_pal_576i, drm_mode_analog_ntsc_480i),
184         TV_MODE_TEST_CMDLINE("Both, PAL Default, with NTSC on command-line",
185                              BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
186                              DRM_MODE_TV_MODE_PAL,
187                              DRM_MODE_TV_MODE_NTSC,
188                              drm_mode_analog_ntsc_480i, drm_mode_analog_pal_576i),
189 };
190
191 static void
192 drm_connector_helper_tv_get_modes_desc(const struct drm_connector_helper_tv_get_modes_test *t,
193                                        char *desc)
194 {
195         sprintf(desc, "%s", t->name);
196 }
197
198 KUNIT_ARRAY_PARAM(drm_connector_helper_tv_get_modes,
199                   drm_connector_helper_tv_get_modes_tests,
200                   drm_connector_helper_tv_get_modes_desc);
201
202 static struct kunit_case drm_test_connector_helper_tv_get_modes_tests[] = {
203         KUNIT_CASE_PARAM(drm_test_connector_helper_tv_get_modes_check,
204                          drm_connector_helper_tv_get_modes_gen_params),
205         { }
206 };
207
208 static struct kunit_suite drm_test_connector_helper_tv_get_modes_suite = {
209         .name = "drm_connector_helper_tv_get_modes",
210         .init = drm_probe_helper_test_init,
211         .exit = drm_probe_helper_test_exit,
212         .test_cases = drm_test_connector_helper_tv_get_modes_tests,
213 };
214
215 kunit_test_suite(drm_test_connector_helper_tv_get_modes_suite);
216
217 MODULE_AUTHOR("Maxime Ripard <[email protected]>");
218 MODULE_LICENSE("GPL");
This page took 0.0414679999999999 seconds and 4 git commands to generate.