Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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
 18struct drm_probe_helper_test_priv {
 19	struct drm_device *drm;
 20	struct device *dev;
 21	struct drm_connector connector;
 22};
 23
 24static const struct drm_connector_helper_funcs drm_probe_helper_connector_helper_funcs = {
 25};
 26
 27static 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
 33static 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
 63typedef struct drm_display_mode *(*expected_mode_func_t)(struct drm_device *);
 64
 65struct drm_connector_helper_tv_get_modes_test {
 66	const char *name;
 67	unsigned int supported_tv_modes;
 68	enum drm_connector_tv_mode default_mode;
 69	bool cmdline;
 70	enum drm_connector_tv_mode cmdline_mode;
 71	expected_mode_func_t *expected_modes;
 72	unsigned int num_expected_modes;
 73};
 74
 75#define _TV_MODE_TEST(_name, _supported, _default, _cmdline, _cmdline_mode, ...)		\
 76	{											\
 77		.name = _name,									\
 78		.supported_tv_modes = _supported,						\
 79		.default_mode = _default,							\
 80		.cmdline = _cmdline,								\
 81		.cmdline_mode = _cmdline_mode,							\
 82		.expected_modes = (expected_mode_func_t[]) { __VA_ARGS__ },			\
 83		.num_expected_modes = sizeof((expected_mode_func_t[]) { __VA_ARGS__ }) /	\
 84				      (sizeof(expected_mode_func_t)),				\
 85	}
 86
 87#define TV_MODE_TEST(_name, _supported, _default, ...)			\
 88	_TV_MODE_TEST(_name, _supported, _default, false, 0, __VA_ARGS__)
 89
 90#define TV_MODE_TEST_CMDLINE(_name, _supported, _default, _cmdline, ...) \
 91	_TV_MODE_TEST(_name, _supported, _default, true, _cmdline, __VA_ARGS__)
 92
 93static void
 94drm_test_connector_helper_tv_get_modes_check(struct kunit *test)
 95{
 96	const struct drm_connector_helper_tv_get_modes_test *params = test->param_value;
 97	struct drm_probe_helper_test_priv *priv = test->priv;
 98	struct drm_connector *connector = &priv->connector;
 99	struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
100	struct drm_display_mode *mode;
101	const struct drm_display_mode *expected;
102	size_t len;
103	int ret;
104
105	if (params->cmdline) {
106		cmdline->tv_mode_specified = true;
107		cmdline->tv_mode = params->cmdline_mode;
108	}
109
110	ret = drm_mode_create_tv_properties(priv->drm, params->supported_tv_modes);
111	KUNIT_ASSERT_EQ(test, ret, 0);
112
113	drm_object_attach_property(&connector->base,
114				   priv->drm->mode_config.tv_mode_property,
115				   params->default_mode);
116
117	mutex_lock(&priv->drm->mode_config.mutex);
118
119	ret = drm_connector_helper_tv_get_modes(connector);
120	KUNIT_EXPECT_EQ(test, ret, params->num_expected_modes);
121
122	len = 0;
123	list_for_each_entry(mode, &connector->probed_modes, head)
124		len++;
125	KUNIT_EXPECT_EQ(test, len, params->num_expected_modes);
126
127	if (params->num_expected_modes >= 1) {
128		mode = list_first_entry_or_null(&connector->probed_modes,
129						struct drm_display_mode, head);
130		KUNIT_ASSERT_NOT_NULL(test, mode);
131
132		expected = params->expected_modes[0](priv->drm);
133		KUNIT_ASSERT_NOT_NULL(test, expected);
134
135		KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected));
136		KUNIT_EXPECT_TRUE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
137	}
138
139	if (params->num_expected_modes >= 2) {
140		mode = list_next_entry(mode, head);
141		KUNIT_ASSERT_NOT_NULL(test, mode);
142
143		expected = params->expected_modes[1](priv->drm);
144		KUNIT_ASSERT_NOT_NULL(test, expected);
145
146		KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected));
147		KUNIT_EXPECT_FALSE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
148	}
149
150	mutex_unlock(&priv->drm->mode_config.mutex);
151}
152
153static const
154struct drm_connector_helper_tv_get_modes_test drm_connector_helper_tv_get_modes_tests[] = {
155	{ .name = "None" },
156	TV_MODE_TEST("PAL",
157		     BIT(DRM_MODE_TV_MODE_PAL),
158		     DRM_MODE_TV_MODE_PAL,
159		     drm_mode_analog_pal_576i),
160	TV_MODE_TEST("NTSC",
161		     BIT(DRM_MODE_TV_MODE_NTSC),
162		     DRM_MODE_TV_MODE_NTSC,
163		     drm_mode_analog_ntsc_480i),
164	TV_MODE_TEST("Both, NTSC Default",
165		     BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
166		     DRM_MODE_TV_MODE_NTSC,
167		     drm_mode_analog_ntsc_480i, drm_mode_analog_pal_576i),
168	TV_MODE_TEST("Both, PAL Default",
169		     BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
170		     DRM_MODE_TV_MODE_PAL,
171		     drm_mode_analog_pal_576i, drm_mode_analog_ntsc_480i),
172	TV_MODE_TEST_CMDLINE("Both, NTSC Default, with PAL on command-line",
173			     BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
174			     DRM_MODE_TV_MODE_NTSC,
175			     DRM_MODE_TV_MODE_PAL,
176			     drm_mode_analog_pal_576i, drm_mode_analog_ntsc_480i),
177	TV_MODE_TEST_CMDLINE("Both, PAL Default, with NTSC on command-line",
178			     BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
179			     DRM_MODE_TV_MODE_PAL,
180			     DRM_MODE_TV_MODE_NTSC,
181			     drm_mode_analog_ntsc_480i, drm_mode_analog_pal_576i),
182};
183
184static void
185drm_connector_helper_tv_get_modes_desc(const struct drm_connector_helper_tv_get_modes_test *t,
186				       char *desc)
187{
188	sprintf(desc, "%s", t->name);
189}
190
191KUNIT_ARRAY_PARAM(drm_connector_helper_tv_get_modes,
192		  drm_connector_helper_tv_get_modes_tests,
193		  drm_connector_helper_tv_get_modes_desc);
194
195static struct kunit_case drm_test_connector_helper_tv_get_modes_tests[] = {
196	KUNIT_CASE_PARAM(drm_test_connector_helper_tv_get_modes_check,
197			 drm_connector_helper_tv_get_modes_gen_params),
198	{ }
199};
200
201static struct kunit_suite drm_test_connector_helper_tv_get_modes_suite = {
202	.name = "drm_connector_helper_tv_get_modes",
203	.init = drm_probe_helper_test_init,
204	.test_cases = drm_test_connector_helper_tv_get_modes_tests,
205};
206
207kunit_test_suite(drm_test_connector_helper_tv_get_modes_suite);
208
209MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
210MODULE_LICENSE("GPL");