Hi Maxime Am 29.07.22 um 18:34 schrieb Maxime Ripard:
drm_connector_pick_cmdline_mode() is in charge of finding a proper drm_display_mode from the definition we got in the video= command line argument. Let's add some unit tests to make sure we're not getting any regressions there. Signed-off-by: Maxime Ripard <maxime@xxxxxxxxxx> diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c index bbc535cc50dd..ee6b8f193c24 100644 --- a/drivers/gpu/drm/drm_client_modeset.c +++ b/drivers/gpu/drm/drm_client_modeset.c @@ -1237,3 +1237,7 @@ int drm_client_modeset_dpms(struct drm_client_dev *client, int mode) return ret; } EXPORT_SYMBOL(drm_client_modeset_dpms); + +#ifdef CONFIG_DRM_KUNIT_TEST +#include "tests/drm_mode_test.c" +#endif
Including source files is somewhat ugly, prolongs compile times and could even interfere with the actual source code. Can we do this in some other way?
I suggest to add the tests here and export them for use in the test case. Something like
#ifdef CONFIG_DRM_KUNIT_TEST static drm_mode_res_1920_1080_60() { ... } struct kunit_case drm_mode_tests[] = { drm_mode_res_1920_1080_60 }; EXPORT_SYMBOL(drm_mode_tests); #endifThis would add the tests next to the tested code, but leave the test driver in drm_mode_test.c.
Best regards Thomas
diff --git a/drivers/gpu/drm/tests/drm_mode_test.c b/drivers/gpu/drm/tests/drm_mode_test.c new file mode 100644 index 000000000000..0f71519788a7 --- /dev/null +++ b/drivers/gpu/drm/tests/drm_mode_test.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Maxime Ripard <mripard@xxxxxxxxxx> + */ + +#include <drm/drm_mode.h> +#include <kunit/test.h> + +#include <drm/drm_connector.h> +#include <drm/drm_edid.h> +#include <drm/drm_drv.h> +#include <drm/drm_modes.h> +#include <drm/drm_modeset_helper_vtables.h> +#include <drm/drm_probe_helper.h> + +struct drm_mode_test_priv { + struct device *dev; + struct drm_device *drm; + struct drm_connector connector; +}; + +static const struct drm_mode_config_funcs drm_mode_config_funcs = { +}; + +static const struct drm_driver drm_mode_driver = { +}; + +static int drm_mode_connector_get_modes(struct drm_connector *connector) +{ + struct drm_display_mode *mode; + int ret; + + ret = drm_add_modes_noedid(connector, 1920, 1200); + if (ret) + return ret; + + return 0; +} + +static const struct drm_connector_helper_funcs drm_mode_connector_helper_funcs = { + .get_modes = drm_mode_connector_get_modes, +}; + +static const struct drm_connector_funcs drm_mode_connector_funcs = { +}; + +static int drm_mode_test_init(struct kunit *test) +{ + struct drm_mode_test_priv *priv; + int ret; + + priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + test->priv = priv; + + priv->dev = root_device_register("drm-mode-test"); + if (IS_ERR(priv->dev)) + return PTR_ERR(priv->dev); + + priv->drm = drm_dev_alloc(&drm_mode_driver, priv->dev); + if (IS_ERR(priv->drm)) + return PTR_ERR(priv->drm); + priv->drm->mode_config.funcs = &drm_mode_config_funcs; + + ret = drmm_mode_config_init(priv->drm); + if (ret) + return ret; + + ret = drmm_connector_init(priv->drm, &priv->connector, + &drm_mode_connector_funcs, + DRM_MODE_CONNECTOR_Unknown, + NULL); + if (ret) + return ret; + drm_connector_helper_add(&priv->connector, &drm_mode_connector_helper_funcs); + + return 0; +} + +static void drm_mode_test_exit(struct kunit *test) +{ + struct drm_mode_test_priv *priv = test->priv; + + drm_dev_put(priv->drm); + root_device_unregister(priv->dev); +} + +static void drm_mode_res_1920_1080_60(struct kunit *test) +{ + struct drm_mode_test_priv *priv = test->priv; + struct drm_device *drm = priv->drm; + struct drm_connector *connector = &priv->connector; + struct drm_cmdline_mode *cmdline_mode = &connector->cmdline_mode; + struct drm_display_mode *expected_mode, *mode; + const char *cmdline = "1920x1080@60"; + int ret; + + expected_mode = drm_mode_find_dmt(priv->drm, 1920, 1080, 60, false); + KUNIT_ASSERT_PTR_NE(test, expected_mode, NULL); + + KUNIT_ASSERT_TRUE(test, + drm_mode_parse_command_line_for_connector(cmdline, + connector, + cmdline_mode)); + + mutex_lock(&drm->mode_config.mutex); + ret = drm_helper_probe_single_connector_modes(connector, 1920, 1080); + mutex_unlock(&drm->mode_config.mutex); + KUNIT_ASSERT_GT(test, ret, 0); + + mode = drm_connector_pick_cmdline_mode(connector); + KUNIT_ASSERT_PTR_NE(test, mode, NULL); + + KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected_mode, mode)); +} + +static struct kunit_case drm_mode_tests[] = { + KUNIT_CASE(drm_mode_res_1920_1080_60), + {} +}; + +static struct kunit_suite drm_mode_test_suite = { + .name = "drm_mode", + .init = drm_mode_test_init, + .exit = drm_mode_test_exit, + .test_cases = drm_mode_tests +}; + +kunit_test_suite(drm_mode_test_suite); +MODULE_AUTHOR("Maxime Ripard <mripard@xxxxxxxxxx>"); +MODULE_LICENSE("GPL");
-- Thomas Zimmermann Graphics Driver Developer SUSE Software Solutions Germany GmbH Maxfeldstr. 5, 90409 Nürnberg, Germany (HRB 36809, AG Nürnberg) Geschäftsführer: Ivo Totev
Attachment:
OpenPGP_signature
Description: OpenPGP digital signature