mirror of
https://github.com/torvalds/linux.git
synced 2026-05-04 22:43:04 -04:00
Merge tag 'drm-misc-next-2023-01-03' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
drm-misc-next for v6.3: UAPI Changes: * connector: Support analog-TV mode property * media: Add MEDIA_BUS_FMT_RGB565_1X24_CPADHI, MEDIA_BUS_FMT_RGB666_1X18 and MEDIA_BUS_FMT_RGB666_1X24_CPADHI Cross-subsystem Changes: * dma-buf: Documentation fixes * i2c: Introduce i2c_client_get_device_id() helper Core Changes: * Improve support for analog TV output * bridge: Remove unused drm_bridge_chain functions * debugfs: Add per-device helpers and convert various DRM drivers * dp-mst: Various fixes * fbdev emulation: Always pick 32 bpp as default * KUnit: Add tests for managed helpers; Various cleanups * panel-orientation: Add quirks for Lenovo Yoga Tab 3 X90F and DynaBook K50 * TTM: Open-code ttm_bo_wait() and remove the helper Driver Changes: * Fix preferred depth and bpp values throughout DRM drivers * Remove #CONFIG_PM guards throughout DRM drivers * ast: Various fixes * bridge: Implement i2c's probe_new in various drivers; Fixes; ite-it6505: Locking fixes, Cache EDID data; ite-it66121: Support IT6610 chip, Cleanups; lontium-tl9611: Fix HDMI on DragonBoard 845c; parade-ps8640: Use atomic bridge functions * gud: Convert to DRM shadow-plane helpers; Perform flushing synchronously during atomic update * ili9486: Support 16-bit pixel data * imx: Split off IPUv3 driver; Various fixes * mipi-dbi: Convert to DRM shadow-plane helpers plus rsp driver changes;i Support separate I/O-voltage supply * mxsfb: Depend on ARCH_MXS or ARCH_MXC * omapdrm: Various fixes * panel: Use ktime_get_boottime() to measure power-down delay in various drivers; Fix auto-suspend delay in various drivers; orisetech-ota5601a: Add support * sprd: Cleanups * sun4i: Convert to new TV-mode property * tidss: Various fixes * v3d: Various fixes * vc4: Convert to new TV-mode property; Support Kunit tests; Cleanups; dpi: Support RGB565 and RGB666 formats; dsi: Convert DSI driver to bridge * virtio: Improve tracing * vkms: Support small cursors in IGT tests; Various fixes Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> From: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/Y7QIwlfElAYWxRcR@linux-uq9g
This commit is contained in:
@@ -1,14 +1,20 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-$(CONFIG_DRM_KUNIT_TEST_HELPERS) += \
|
||||
drm_kunit_helpers.o
|
||||
|
||||
obj-$(CONFIG_DRM_KUNIT_TEST) += \
|
||||
drm_buddy_test.o \
|
||||
drm_cmdline_parser_test.o \
|
||||
drm_connector_test.o \
|
||||
drm_damage_helper_test.o \
|
||||
drm_dp_mst_helper_test.o \
|
||||
drm_format_helper_test.o \
|
||||
drm_format_test.o \
|
||||
drm_framebuffer_test.o \
|
||||
drm_kunit_helpers.o \
|
||||
drm_managed_test.o \
|
||||
drm_mm_test.o \
|
||||
drm_modes_test.o \
|
||||
drm_plane_helper_test.o \
|
||||
drm_probe_helper_test.o \
|
||||
drm_rect_test.o
|
||||
|
||||
@@ -8,20 +8,39 @@
|
||||
#include <drm/drm_connector.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_kunit_helpers.h>
|
||||
#include <drm/drm_modes.h>
|
||||
#include <drm/drm_modeset_helper_vtables.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include "drm_kunit_helpers.h"
|
||||
|
||||
struct drm_client_modeset_test_priv {
|
||||
struct drm_device *drm;
|
||||
struct device *dev;
|
||||
struct drm_connector connector;
|
||||
};
|
||||
|
||||
static int drm_client_modeset_connector_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
return drm_add_modes_noedid(connector, 1920, 1200);
|
||||
struct drm_display_mode *mode;
|
||||
int count;
|
||||
|
||||
count = drm_add_modes_noedid(connector, 1920, 1200);
|
||||
|
||||
mode = drm_mode_analog_ntsc_480i(connector->dev);
|
||||
if (!mode)
|
||||
return count;
|
||||
|
||||
drm_mode_probed_add(connector, mode);
|
||||
count += 1;
|
||||
|
||||
mode = drm_mode_analog_pal_576i(connector->dev);
|
||||
if (!mode)
|
||||
return count;
|
||||
|
||||
drm_mode_probed_add(connector, mode);
|
||||
count += 1;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct drm_connector_helper_funcs drm_client_modeset_connector_helper_funcs = {
|
||||
@@ -41,7 +60,12 @@ static int drm_client_modeset_test_init(struct kunit *test)
|
||||
|
||||
test->priv = priv;
|
||||
|
||||
priv->drm = drm_kunit_device_init(test, DRIVER_MODESET, "drm-client-modeset-test");
|
||||
priv->dev = drm_kunit_helper_alloc_device(test);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->dev);
|
||||
|
||||
priv->drm = __drm_kunit_helper_alloc_drm_device(test, priv->dev,
|
||||
sizeof(*priv->drm), 0,
|
||||
DRIVER_MODESET);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);
|
||||
|
||||
ret = drmm_connector_init(priv->drm, &priv->connector,
|
||||
@@ -52,9 +76,19 @@ static int drm_client_modeset_test_init(struct kunit *test)
|
||||
|
||||
drm_connector_helper_add(&priv->connector, &drm_client_modeset_connector_helper_funcs);
|
||||
|
||||
priv->connector.interlace_allowed = true;
|
||||
priv->connector.doublescan_allowed = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void drm_client_modeset_test_exit(struct kunit *test)
|
||||
{
|
||||
struct drm_client_modeset_test_priv *priv = test->priv;
|
||||
|
||||
drm_kunit_helper_free_device(test, priv->dev);
|
||||
}
|
||||
|
||||
static void drm_test_pick_cmdline_res_1920_1080_60(struct kunit *test)
|
||||
{
|
||||
struct drm_client_modeset_test_priv *priv = test->priv;
|
||||
@@ -84,15 +118,83 @@ static void drm_test_pick_cmdline_res_1920_1080_60(struct kunit *test)
|
||||
KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected_mode, mode));
|
||||
}
|
||||
|
||||
struct drm_connector_pick_cmdline_mode_test {
|
||||
const char *cmdline;
|
||||
struct drm_display_mode *(*func)(struct drm_device *drm);
|
||||
};
|
||||
|
||||
#define TEST_CMDLINE(_cmdline, _fn) \
|
||||
{ \
|
||||
.cmdline = _cmdline, \
|
||||
.func = _fn, \
|
||||
}
|
||||
|
||||
static void drm_test_pick_cmdline_named(struct kunit *test)
|
||||
{
|
||||
const struct drm_connector_pick_cmdline_mode_test *params = test->param_value;
|
||||
struct drm_client_modeset_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;
|
||||
const struct drm_display_mode *expected_mode, *mode;
|
||||
const char *cmdline = params->cmdline;
|
||||
int ret;
|
||||
|
||||
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_NOT_NULL(test, mode);
|
||||
|
||||
expected_mode = params->func(drm);
|
||||
KUNIT_ASSERT_NOT_NULL(test, expected_mode);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected_mode, mode));
|
||||
}
|
||||
|
||||
static const
|
||||
struct drm_connector_pick_cmdline_mode_test drm_connector_pick_cmdline_mode_tests[] = {
|
||||
TEST_CMDLINE("NTSC", drm_mode_analog_ntsc_480i),
|
||||
TEST_CMDLINE("NTSC-J", drm_mode_analog_ntsc_480i),
|
||||
TEST_CMDLINE("PAL", drm_mode_analog_pal_576i),
|
||||
TEST_CMDLINE("PAL-M", drm_mode_analog_ntsc_480i),
|
||||
};
|
||||
|
||||
static void
|
||||
drm_connector_pick_cmdline_mode_desc(const struct drm_connector_pick_cmdline_mode_test *t,
|
||||
char *desc)
|
||||
{
|
||||
sprintf(desc, "%s", t->cmdline);
|
||||
}
|
||||
|
||||
KUNIT_ARRAY_PARAM(drm_connector_pick_cmdline_mode,
|
||||
drm_connector_pick_cmdline_mode_tests,
|
||||
drm_connector_pick_cmdline_mode_desc);
|
||||
|
||||
static struct kunit_case drm_test_pick_cmdline_tests[] = {
|
||||
KUNIT_CASE(drm_test_pick_cmdline_res_1920_1080_60),
|
||||
KUNIT_CASE_PARAM(drm_test_pick_cmdline_named,
|
||||
drm_connector_pick_cmdline_mode_gen_params),
|
||||
{}
|
||||
};
|
||||
|
||||
static struct kunit_suite drm_test_pick_cmdline_test_suite = {
|
||||
.name = "drm_test_pick_cmdline",
|
||||
.init = drm_client_modeset_test_init,
|
||||
.exit = drm_client_modeset_test_exit,
|
||||
.test_cases = drm_test_pick_cmdline_tests
|
||||
};
|
||||
|
||||
kunit_test_suite(drm_test_pick_cmdline_test_suite);
|
||||
|
||||
/*
|
||||
* This file is included directly by drm_client_modeset.c so we can't
|
||||
* use any MODULE_* macro here.
|
||||
*/
|
||||
|
||||
@@ -927,6 +927,14 @@ static const struct drm_cmdline_invalid_test drm_cmdline_invalid_tests[] = {
|
||||
.name = "invalid_option",
|
||||
.cmdline = "720x480,test=42",
|
||||
},
|
||||
{
|
||||
.name = "invalid_tv_option",
|
||||
.cmdline = "720x480i,tv_mode=invalid",
|
||||
},
|
||||
{
|
||||
.name = "truncated_tv_option",
|
||||
.cmdline = "720x480i,tv_mode=NTS",
|
||||
},
|
||||
};
|
||||
|
||||
static void drm_cmdline_invalid_desc(const struct drm_cmdline_invalid_test *t,
|
||||
@@ -937,6 +945,65 @@ static void drm_cmdline_invalid_desc(const struct drm_cmdline_invalid_test *t,
|
||||
|
||||
KUNIT_ARRAY_PARAM(drm_cmdline_invalid, drm_cmdline_invalid_tests, drm_cmdline_invalid_desc);
|
||||
|
||||
struct drm_cmdline_tv_option_test {
|
||||
const char *name;
|
||||
const char *cmdline;
|
||||
struct drm_display_mode *(*mode_fn)(struct drm_device *dev);
|
||||
enum drm_connector_tv_mode tv_mode;
|
||||
};
|
||||
|
||||
static void drm_test_cmdline_tv_options(struct kunit *test)
|
||||
{
|
||||
const struct drm_cmdline_tv_option_test *params = test->param_value;
|
||||
const struct drm_display_mode *expected_mode = params->mode_fn(NULL);
|
||||
struct drm_cmdline_mode mode = { };
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, drm_mode_parse_command_line_for_connector(params->cmdline,
|
||||
&no_connector, &mode));
|
||||
KUNIT_EXPECT_TRUE(test, mode.specified);
|
||||
KUNIT_EXPECT_EQ(test, mode.xres, expected_mode->hdisplay);
|
||||
KUNIT_EXPECT_EQ(test, mode.yres, expected_mode->vdisplay);
|
||||
KUNIT_EXPECT_EQ(test, mode.tv_mode, params->tv_mode);
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, mode.refresh_specified);
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, mode.bpp_specified);
|
||||
|
||||
KUNIT_EXPECT_FALSE(test, mode.rb);
|
||||
KUNIT_EXPECT_FALSE(test, mode.cvt);
|
||||
KUNIT_EXPECT_EQ(test, mode.interlace, !!(expected_mode->flags & DRM_MODE_FLAG_INTERLACE));
|
||||
KUNIT_EXPECT_FALSE(test, mode.margins);
|
||||
KUNIT_EXPECT_EQ(test, mode.force, DRM_FORCE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
#define TV_OPT_TEST(_opt, _cmdline, _mode_fn) \
|
||||
{ \
|
||||
.name = #_opt, \
|
||||
.cmdline = _cmdline, \
|
||||
.mode_fn = _mode_fn, \
|
||||
.tv_mode = DRM_MODE_TV_MODE_ ## _opt, \
|
||||
}
|
||||
|
||||
static const struct drm_cmdline_tv_option_test drm_cmdline_tv_option_tests[] = {
|
||||
TV_OPT_TEST(NTSC, "720x480i,tv_mode=NTSC", drm_mode_analog_ntsc_480i),
|
||||
TV_OPT_TEST(NTSC_443, "720x480i,tv_mode=NTSC-443", drm_mode_analog_ntsc_480i),
|
||||
TV_OPT_TEST(NTSC_J, "720x480i,tv_mode=NTSC-J", drm_mode_analog_ntsc_480i),
|
||||
TV_OPT_TEST(PAL, "720x576i,tv_mode=PAL", drm_mode_analog_pal_576i),
|
||||
TV_OPT_TEST(PAL_M, "720x480i,tv_mode=PAL-M", drm_mode_analog_ntsc_480i),
|
||||
TV_OPT_TEST(PAL_N, "720x576i,tv_mode=PAL-N", drm_mode_analog_pal_576i),
|
||||
TV_OPT_TEST(SECAM, "720x576i,tv_mode=SECAM", drm_mode_analog_pal_576i),
|
||||
};
|
||||
|
||||
static void drm_cmdline_tv_option_desc(const struct drm_cmdline_tv_option_test *t,
|
||||
char *desc)
|
||||
{
|
||||
sprintf(desc, "%s", t->name);
|
||||
}
|
||||
|
||||
KUNIT_ARRAY_PARAM(drm_cmdline_tv_option,
|
||||
drm_cmdline_tv_option_tests,
|
||||
drm_cmdline_tv_option_desc);
|
||||
|
||||
static struct kunit_case drm_cmdline_parser_tests[] = {
|
||||
KUNIT_CASE(drm_test_cmdline_force_d_only),
|
||||
KUNIT_CASE(drm_test_cmdline_force_D_only_dvi),
|
||||
@@ -977,6 +1044,7 @@ static struct kunit_case drm_cmdline_parser_tests[] = {
|
||||
KUNIT_CASE(drm_test_cmdline_freestanding_force_e_and_options),
|
||||
KUNIT_CASE(drm_test_cmdline_panel_orientation),
|
||||
KUNIT_CASE_PARAM(drm_test_cmdline_invalid, drm_cmdline_invalid_gen_params),
|
||||
KUNIT_CASE_PARAM(drm_test_cmdline_tv_options, drm_cmdline_tv_option_gen_params),
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
76
drivers/gpu/drm/tests/drm_connector_test.c
Normal file
76
drivers/gpu/drm/tests/drm_connector_test.c
Normal file
@@ -0,0 +1,76 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Kunit test for drm_modes functions
|
||||
*/
|
||||
|
||||
#include <drm/drm_connector.h>
|
||||
|
||||
#include <kunit/test.h>
|
||||
|
||||
struct drm_get_tv_mode_from_name_test {
|
||||
const char *name;
|
||||
enum drm_connector_tv_mode expected_mode;
|
||||
};
|
||||
|
||||
#define TV_MODE_NAME(_name, _mode) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.expected_mode = _mode, \
|
||||
}
|
||||
|
||||
static void drm_test_get_tv_mode_from_name_valid(struct kunit *test)
|
||||
{
|
||||
const struct drm_get_tv_mode_from_name_test *params = test->param_value;
|
||||
|
||||
KUNIT_EXPECT_EQ(test,
|
||||
drm_get_tv_mode_from_name(params->name, strlen(params->name)),
|
||||
params->expected_mode);
|
||||
}
|
||||
|
||||
static const
|
||||
struct drm_get_tv_mode_from_name_test drm_get_tv_mode_from_name_valid_tests[] = {
|
||||
TV_MODE_NAME("NTSC", DRM_MODE_TV_MODE_NTSC),
|
||||
TV_MODE_NAME("NTSC-443", DRM_MODE_TV_MODE_NTSC_443),
|
||||
TV_MODE_NAME("NTSC-J", DRM_MODE_TV_MODE_NTSC_J),
|
||||
TV_MODE_NAME("PAL", DRM_MODE_TV_MODE_PAL),
|
||||
TV_MODE_NAME("PAL-M", DRM_MODE_TV_MODE_PAL_M),
|
||||
TV_MODE_NAME("PAL-N", DRM_MODE_TV_MODE_PAL_N),
|
||||
TV_MODE_NAME("SECAM", DRM_MODE_TV_MODE_SECAM),
|
||||
};
|
||||
|
||||
static void
|
||||
drm_get_tv_mode_from_name_valid_desc(const struct drm_get_tv_mode_from_name_test *t,
|
||||
char *desc)
|
||||
{
|
||||
sprintf(desc, "%s", t->name);
|
||||
}
|
||||
|
||||
KUNIT_ARRAY_PARAM(drm_get_tv_mode_from_name_valid,
|
||||
drm_get_tv_mode_from_name_valid_tests,
|
||||
drm_get_tv_mode_from_name_valid_desc);
|
||||
|
||||
static void drm_test_get_tv_mode_from_name_truncated(struct kunit *test)
|
||||
{
|
||||
const char *name = "NTS";
|
||||
int ret;
|
||||
|
||||
ret = drm_get_tv_mode_from_name(name, strlen(name));
|
||||
KUNIT_EXPECT_LT(test, ret, 0);
|
||||
};
|
||||
|
||||
static struct kunit_case drm_get_tv_mode_from_name_tests[] = {
|
||||
KUNIT_CASE_PARAM(drm_test_get_tv_mode_from_name_valid,
|
||||
drm_get_tv_mode_from_name_valid_gen_params),
|
||||
KUNIT_CASE(drm_test_get_tv_mode_from_name_truncated),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct kunit_suite drm_get_tv_mode_from_name_test_suite = {
|
||||
.name = "drm_get_tv_mode_from_name",
|
||||
.test_cases = drm_get_tv_mode_from_name_tests,
|
||||
};
|
||||
|
||||
kunit_test_suite(drm_get_tv_mode_from_name_test_suite);
|
||||
|
||||
MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -1,63 +1,101 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_kunit_helpers.h>
|
||||
#include <drm/drm_managed.h>
|
||||
|
||||
#include <kunit/resource.h>
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "drm_kunit_helpers.h"
|
||||
|
||||
struct kunit_dev {
|
||||
struct drm_device base;
|
||||
};
|
||||
#define KUNIT_DEVICE_NAME "drm-kunit-mock-device"
|
||||
|
||||
static const struct drm_mode_config_funcs drm_mode_config_funcs = {
|
||||
};
|
||||
|
||||
static int dev_init(struct kunit_resource *res, void *ptr)
|
||||
static int fake_probe(struct platform_device *pdev)
|
||||
{
|
||||
char *name = ptr;
|
||||
struct device *dev;
|
||||
|
||||
dev = root_device_register(name);
|
||||
if (IS_ERR(dev))
|
||||
return PTR_ERR(dev);
|
||||
|
||||
res->data = dev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dev_free(struct kunit_resource *res)
|
||||
static int fake_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = res->data;
|
||||
|
||||
root_device_unregister(dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct drm_device *drm_kunit_device_init(struct kunit *test, u32 features, char *name)
|
||||
static struct platform_driver fake_platform_driver = {
|
||||
.probe = fake_probe,
|
||||
.remove = fake_remove,
|
||||
.driver = {
|
||||
.name = KUNIT_DEVICE_NAME,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* drm_kunit_helper_alloc_device - Allocate a mock device for a KUnit test
|
||||
* @test: The test context object
|
||||
*
|
||||
* This allocates a fake struct &device to create a mock for a KUnit
|
||||
* test. The device will also be bound to a fake driver. It will thus be
|
||||
* able to leverage the usual infrastructure and most notably the
|
||||
* device-managed resources just like a "real" device.
|
||||
*
|
||||
* Callers need to make sure drm_kunit_helper_free_device() on the
|
||||
* device when done.
|
||||
*
|
||||
* Returns:
|
||||
* A pointer to the new device, or an ERR_PTR() otherwise.
|
||||
*/
|
||||
struct device *drm_kunit_helper_alloc_device(struct kunit *test)
|
||||
{
|
||||
struct kunit_dev *kdev;
|
||||
struct drm_device *drm;
|
||||
struct drm_driver *driver;
|
||||
struct device *dev;
|
||||
struct platform_device *pdev;
|
||||
int ret;
|
||||
|
||||
dev = kunit_alloc_resource(test, dev_init, dev_free, GFP_KERNEL, name);
|
||||
if (!dev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
ret = platform_driver_register(&fake_platform_driver);
|
||||
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||
|
||||
driver = kunit_kzalloc(test, sizeof(*driver), GFP_KERNEL);
|
||||
if (!driver)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
pdev = platform_device_alloc(KUNIT_DEVICE_NAME, PLATFORM_DEVID_NONE);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev);
|
||||
|
||||
driver->driver_features = features;
|
||||
kdev = devm_drm_dev_alloc(dev, driver, struct kunit_dev, base);
|
||||
if (IS_ERR(kdev))
|
||||
return ERR_CAST(kdev);
|
||||
ret = platform_device_add(pdev);
|
||||
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||
|
||||
drm = &kdev->base;
|
||||
return &pdev->dev;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(drm_kunit_helper_alloc_device);
|
||||
|
||||
/**
|
||||
* drm_kunit_helper_free_device - Frees a mock device
|
||||
* @test: The test context object
|
||||
* @dev: The device to free
|
||||
*
|
||||
* Frees a device allocated with drm_kunit_helper_alloc_device().
|
||||
*/
|
||||
void drm_kunit_helper_free_device(struct kunit *test, struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
|
||||
platform_device_unregister(pdev);
|
||||
platform_driver_unregister(&fake_platform_driver);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(drm_kunit_helper_free_device);
|
||||
|
||||
struct drm_device *
|
||||
__drm_kunit_helper_alloc_drm_device_with_driver(struct kunit *test,
|
||||
struct device *dev,
|
||||
size_t size, size_t offset,
|
||||
const struct drm_driver *driver)
|
||||
{
|
||||
struct drm_device *drm;
|
||||
void *container;
|
||||
int ret;
|
||||
|
||||
container = __devm_drm_dev_alloc(dev, driver, size, offset);
|
||||
if (IS_ERR(container))
|
||||
return ERR_CAST(container);
|
||||
|
||||
drm = container + offset;
|
||||
drm->mode_config.funcs = &drm_mode_config_funcs;
|
||||
|
||||
ret = drmm_mode_config_init(drm);
|
||||
@@ -66,6 +104,7 @@ struct drm_device *drm_kunit_device_init(struct kunit *test, u32 features, char
|
||||
|
||||
return drm;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__drm_kunit_helper_alloc_drm_device_with_driver);
|
||||
|
||||
MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#ifndef DRM_KUNIT_HELPERS_H_
|
||||
#define DRM_KUNIT_HELPERS_H_
|
||||
|
||||
struct drm_device;
|
||||
struct kunit;
|
||||
|
||||
struct drm_device *drm_kunit_device_init(struct kunit *test, u32 features, char *name);
|
||||
|
||||
#endif // DRM_KUNIT_HELPERS_H_
|
||||
71
drivers/gpu/drm/tests/drm_managed_test.c
Normal file
71
drivers/gpu/drm/tests/drm_managed_test.c
Normal file
@@ -0,0 +1,71 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_kunit_helpers.h>
|
||||
#include <drm/drm_managed.h>
|
||||
|
||||
#include <kunit/resource.h>
|
||||
|
||||
#include <linux/device.h>
|
||||
|
||||
/* Ought to be enough for anybody */
|
||||
#define TEST_TIMEOUT_MS 100
|
||||
|
||||
struct managed_test_priv {
|
||||
bool action_done;
|
||||
wait_queue_head_t action_wq;
|
||||
};
|
||||
|
||||
static void drm_action(struct drm_device *drm, void *ptr)
|
||||
{
|
||||
struct managed_test_priv *priv = ptr;
|
||||
|
||||
priv->action_done = true;
|
||||
wake_up_interruptible(&priv->action_wq);
|
||||
}
|
||||
|
||||
static void drm_test_managed_run_action(struct kunit *test)
|
||||
{
|
||||
struct managed_test_priv *priv;
|
||||
struct drm_device *drm;
|
||||
struct device *dev;
|
||||
int ret;
|
||||
|
||||
priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
|
||||
init_waitqueue_head(&priv->action_wq);
|
||||
|
||||
dev = drm_kunit_helper_alloc_device(test);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||
|
||||
drm = __drm_kunit_helper_alloc_drm_device(test, dev, sizeof(*drm), 0, DRIVER_MODESET);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, drm);
|
||||
|
||||
ret = drmm_add_action_or_reset(drm, drm_action, priv);
|
||||
KUNIT_EXPECT_EQ(test, ret, 0);
|
||||
|
||||
ret = drm_dev_register(drm, 0);
|
||||
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||
|
||||
drm_dev_unregister(drm);
|
||||
drm_kunit_helper_free_device(test, dev);
|
||||
|
||||
ret = wait_event_interruptible_timeout(priv->action_wq, priv->action_done,
|
||||
msecs_to_jiffies(TEST_TIMEOUT_MS));
|
||||
KUNIT_EXPECT_GT(test, ret, 0);
|
||||
}
|
||||
|
||||
static struct kunit_case drm_managed_tests[] = {
|
||||
KUNIT_CASE(drm_test_managed_run_action),
|
||||
{}
|
||||
};
|
||||
|
||||
static struct kunit_suite drm_managed_test_suite = {
|
||||
.name = "drm-test-managed",
|
||||
.test_cases = drm_managed_tests
|
||||
};
|
||||
|
||||
kunit_test_suite(drm_managed_test_suite);
|
||||
|
||||
MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
|
||||
MODULE_LICENSE("GPL");
|
||||
158
drivers/gpu/drm/tests/drm_modes_test.c
Normal file
158
drivers/gpu/drm/tests/drm_modes_test.c
Normal file
@@ -0,0 +1,158 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Kunit test for drm_modes functions
|
||||
*/
|
||||
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_kunit_helpers.h>
|
||||
#include <drm/drm_modes.h>
|
||||
|
||||
#include <kunit/test.h>
|
||||
|
||||
#include <linux/units.h>
|
||||
|
||||
struct drm_test_modes_priv {
|
||||
struct drm_device *drm;
|
||||
struct device *dev;
|
||||
};
|
||||
|
||||
static int drm_test_modes_init(struct kunit *test)
|
||||
{
|
||||
struct drm_test_modes_priv *priv;
|
||||
|
||||
priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, priv);
|
||||
|
||||
priv->dev = drm_kunit_helper_alloc_device(test);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->dev);
|
||||
|
||||
priv->drm = __drm_kunit_helper_alloc_drm_device(test, priv->dev,
|
||||
sizeof(*priv->drm), 0,
|
||||
DRIVER_MODESET);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);
|
||||
|
||||
test->priv = priv;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void drm_test_modes_exit(struct kunit *test)
|
||||
{
|
||||
struct drm_test_modes_priv *priv = test->priv;
|
||||
|
||||
drm_kunit_helper_free_device(test, priv->dev);
|
||||
}
|
||||
|
||||
static void drm_test_modes_analog_tv_ntsc_480i(struct kunit *test)
|
||||
{
|
||||
struct drm_test_modes_priv *priv = test->priv;
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
mode = drm_analog_tv_mode(priv->drm,
|
||||
DRM_MODE_TV_MODE_NTSC,
|
||||
13500 * HZ_PER_KHZ, 720, 480,
|
||||
true);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_mode_vrefresh(mode), 60);
|
||||
KUNIT_EXPECT_EQ(test, mode->hdisplay, 720);
|
||||
|
||||
/* BT.601 defines hsync_start at 736 for 480i */
|
||||
KUNIT_EXPECT_EQ(test, mode->hsync_start, 736);
|
||||
|
||||
/*
|
||||
* The NTSC standard expects a line to take 63.556us. With a
|
||||
* pixel clock of 13.5 MHz, a pixel takes around 74ns, so we
|
||||
* need to have 63556ns / 74ns = 858.
|
||||
*
|
||||
* This is also mandated by BT.601.
|
||||
*/
|
||||
KUNIT_EXPECT_EQ(test, mode->htotal, 858);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, mode->vdisplay, 480);
|
||||
KUNIT_EXPECT_EQ(test, mode->vtotal, 525);
|
||||
}
|
||||
|
||||
static void drm_test_modes_analog_tv_ntsc_480i_inlined(struct kunit *test)
|
||||
{
|
||||
struct drm_test_modes_priv *priv = test->priv;
|
||||
struct drm_display_mode *expected, *mode;
|
||||
|
||||
expected = drm_analog_tv_mode(priv->drm,
|
||||
DRM_MODE_TV_MODE_NTSC,
|
||||
13500 * HZ_PER_KHZ, 720, 480,
|
||||
true);
|
||||
KUNIT_ASSERT_NOT_NULL(test, expected);
|
||||
|
||||
mode = drm_mode_analog_ntsc_480i(priv->drm);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected, mode));
|
||||
}
|
||||
|
||||
static void drm_test_modes_analog_tv_pal_576i(struct kunit *test)
|
||||
{
|
||||
struct drm_test_modes_priv *priv = test->priv;
|
||||
struct drm_display_mode *mode;
|
||||
|
||||
mode = drm_analog_tv_mode(priv->drm,
|
||||
DRM_MODE_TV_MODE_PAL,
|
||||
13500 * HZ_PER_KHZ, 720, 576,
|
||||
true);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, drm_mode_vrefresh(mode), 50);
|
||||
KUNIT_EXPECT_EQ(test, mode->hdisplay, 720);
|
||||
|
||||
/* BT.601 defines hsync_start at 732 for 576i */
|
||||
KUNIT_EXPECT_EQ(test, mode->hsync_start, 732);
|
||||
|
||||
/*
|
||||
* The PAL standard expects a line to take 64us. With a pixel
|
||||
* clock of 13.5 MHz, a pixel takes around 74ns, so we need to
|
||||
* have 64000ns / 74ns = 864.
|
||||
*
|
||||
* This is also mandated by BT.601.
|
||||
*/
|
||||
KUNIT_EXPECT_EQ(test, mode->htotal, 864);
|
||||
|
||||
KUNIT_EXPECT_EQ(test, mode->vdisplay, 576);
|
||||
KUNIT_EXPECT_EQ(test, mode->vtotal, 625);
|
||||
}
|
||||
|
||||
static void drm_test_modes_analog_tv_pal_576i_inlined(struct kunit *test)
|
||||
{
|
||||
struct drm_test_modes_priv *priv = test->priv;
|
||||
struct drm_display_mode *expected, *mode;
|
||||
|
||||
expected = drm_analog_tv_mode(priv->drm,
|
||||
DRM_MODE_TV_MODE_PAL,
|
||||
13500 * HZ_PER_KHZ, 720, 576,
|
||||
true);
|
||||
KUNIT_ASSERT_NOT_NULL(test, expected);
|
||||
|
||||
mode = drm_mode_analog_pal_576i(priv->drm);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, drm_mode_equal(expected, mode));
|
||||
}
|
||||
|
||||
static struct kunit_case drm_modes_analog_tv_tests[] = {
|
||||
KUNIT_CASE(drm_test_modes_analog_tv_ntsc_480i),
|
||||
KUNIT_CASE(drm_test_modes_analog_tv_ntsc_480i_inlined),
|
||||
KUNIT_CASE(drm_test_modes_analog_tv_pal_576i),
|
||||
KUNIT_CASE(drm_test_modes_analog_tv_pal_576i_inlined),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct kunit_suite drm_modes_analog_tv_test_suite = {
|
||||
.name = "drm_modes_analog_tv",
|
||||
.init = drm_test_modes_init,
|
||||
.exit = drm_test_modes_exit,
|
||||
.test_cases = drm_modes_analog_tv_tests,
|
||||
};
|
||||
|
||||
kunit_test_suite(drm_modes_analog_tv_test_suite);
|
||||
|
||||
MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
|
||||
MODULE_LICENSE("GPL");
|
||||
218
drivers/gpu/drm/tests/drm_probe_helper_test.c
Normal file
218
drivers/gpu/drm/tests/drm_probe_helper_test.c
Normal file
@@ -0,0 +1,218 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Kunit test for drm_probe_helper functions
|
||||
*/
|
||||
|
||||
#include <drm/drm_atomic_state_helper.h>
|
||||
#include <drm/drm_connector.h>
|
||||
#include <drm/drm_device.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_kunit_helpers.h>
|
||||
#include <drm/drm_mode.h>
|
||||
#include <drm/drm_modes.h>
|
||||
#include <drm/drm_modeset_helper_vtables.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
|
||||
#include <kunit/test.h>
|
||||
|
||||
struct drm_probe_helper_test_priv {
|
||||
struct drm_device *drm;
|
||||
struct device *dev;
|
||||
struct drm_connector connector;
|
||||
};
|
||||
|
||||
static const struct drm_connector_helper_funcs drm_probe_helper_connector_helper_funcs = {
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs drm_probe_helper_connector_funcs = {
|
||||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
|
||||
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
|
||||
.reset = drm_atomic_helper_connector_reset,
|
||||
};
|
||||
|
||||
static int drm_probe_helper_test_init(struct kunit *test)
|
||||
{
|
||||
struct drm_probe_helper_test_priv *priv;
|
||||
struct drm_connector *connector;
|
||||
int ret;
|
||||
|
||||
priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
|
||||
KUNIT_ASSERT_NOT_NULL(test, priv);
|
||||
test->priv = priv;
|
||||
|
||||
priv->dev = drm_kunit_helper_alloc_device(test);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->dev);
|
||||
|
||||
priv->drm = __drm_kunit_helper_alloc_drm_device(test, priv->dev,
|
||||
sizeof(*priv->drm), 0,
|
||||
DRIVER_MODESET | DRIVER_ATOMIC);
|
||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->drm);
|
||||
|
||||
connector = &priv->connector;
|
||||
ret = drmm_connector_init(priv->drm, connector,
|
||||
&drm_probe_helper_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_Unknown,
|
||||
NULL);
|
||||
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||
|
||||
drm_connector_helper_add(connector, &drm_probe_helper_connector_helper_funcs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void drm_probe_helper_test_exit(struct kunit *test)
|
||||
{
|
||||
struct drm_probe_helper_test_priv *priv = test->priv;
|
||||
|
||||
drm_kunit_helper_free_device(test, priv->dev);
|
||||
}
|
||||
|
||||
typedef struct drm_display_mode *(*expected_mode_func_t)(struct drm_device *);
|
||||
|
||||
struct drm_connector_helper_tv_get_modes_test {
|
||||
const char *name;
|
||||
unsigned int supported_tv_modes;
|
||||
enum drm_connector_tv_mode default_mode;
|
||||
bool cmdline;
|
||||
enum drm_connector_tv_mode cmdline_mode;
|
||||
expected_mode_func_t *expected_modes;
|
||||
unsigned int num_expected_modes;
|
||||
};
|
||||
|
||||
#define _TV_MODE_TEST(_name, _supported, _default, _cmdline, _cmdline_mode, ...) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.supported_tv_modes = _supported, \
|
||||
.default_mode = _default, \
|
||||
.cmdline = _cmdline, \
|
||||
.cmdline_mode = _cmdline_mode, \
|
||||
.expected_modes = (expected_mode_func_t[]) { __VA_ARGS__ }, \
|
||||
.num_expected_modes = sizeof((expected_mode_func_t[]) { __VA_ARGS__ }) / \
|
||||
(sizeof(expected_mode_func_t)), \
|
||||
}
|
||||
|
||||
#define TV_MODE_TEST(_name, _supported, _default, ...) \
|
||||
_TV_MODE_TEST(_name, _supported, _default, false, 0, __VA_ARGS__)
|
||||
|
||||
#define TV_MODE_TEST_CMDLINE(_name, _supported, _default, _cmdline, ...) \
|
||||
_TV_MODE_TEST(_name, _supported, _default, true, _cmdline, __VA_ARGS__)
|
||||
|
||||
static void
|
||||
drm_test_connector_helper_tv_get_modes_check(struct kunit *test)
|
||||
{
|
||||
const struct drm_connector_helper_tv_get_modes_test *params = test->param_value;
|
||||
struct drm_probe_helper_test_priv *priv = test->priv;
|
||||
struct drm_connector *connector = &priv->connector;
|
||||
struct drm_cmdline_mode *cmdline = &connector->cmdline_mode;
|
||||
struct drm_display_mode *mode;
|
||||
const struct drm_display_mode *expected;
|
||||
size_t len;
|
||||
int ret;
|
||||
|
||||
if (params->cmdline) {
|
||||
cmdline->tv_mode_specified = true;
|
||||
cmdline->tv_mode = params->cmdline_mode;
|
||||
}
|
||||
|
||||
ret = drm_mode_create_tv_properties(priv->drm, params->supported_tv_modes);
|
||||
KUNIT_ASSERT_EQ(test, ret, 0);
|
||||
|
||||
drm_object_attach_property(&connector->base,
|
||||
priv->drm->mode_config.tv_mode_property,
|
||||
params->default_mode);
|
||||
|
||||
mutex_lock(&priv->drm->mode_config.mutex);
|
||||
|
||||
ret = drm_connector_helper_tv_get_modes(connector);
|
||||
KUNIT_EXPECT_EQ(test, ret, params->num_expected_modes);
|
||||
|
||||
len = 0;
|
||||
list_for_each_entry(mode, &connector->probed_modes, head)
|
||||
len++;
|
||||
KUNIT_EXPECT_EQ(test, len, params->num_expected_modes);
|
||||
|
||||
if (params->num_expected_modes >= 1) {
|
||||
mode = list_first_entry_or_null(&connector->probed_modes,
|
||||
struct drm_display_mode, head);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
expected = params->expected_modes[0](priv->drm);
|
||||
KUNIT_ASSERT_NOT_NULL(test, expected);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected));
|
||||
KUNIT_EXPECT_TRUE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
|
||||
}
|
||||
|
||||
if (params->num_expected_modes >= 2) {
|
||||
mode = list_next_entry(mode, head);
|
||||
KUNIT_ASSERT_NOT_NULL(test, mode);
|
||||
|
||||
expected = params->expected_modes[1](priv->drm);
|
||||
KUNIT_ASSERT_NOT_NULL(test, expected);
|
||||
|
||||
KUNIT_EXPECT_TRUE(test, drm_mode_equal(mode, expected));
|
||||
KUNIT_EXPECT_FALSE(test, mode->type & DRM_MODE_TYPE_PREFERRED);
|
||||
}
|
||||
|
||||
mutex_unlock(&priv->drm->mode_config.mutex);
|
||||
}
|
||||
|
||||
static const
|
||||
struct drm_connector_helper_tv_get_modes_test drm_connector_helper_tv_get_modes_tests[] = {
|
||||
{ .name = "None" },
|
||||
TV_MODE_TEST("PAL",
|
||||
BIT(DRM_MODE_TV_MODE_PAL),
|
||||
DRM_MODE_TV_MODE_PAL,
|
||||
drm_mode_analog_pal_576i),
|
||||
TV_MODE_TEST("NTSC",
|
||||
BIT(DRM_MODE_TV_MODE_NTSC),
|
||||
DRM_MODE_TV_MODE_NTSC,
|
||||
drm_mode_analog_ntsc_480i),
|
||||
TV_MODE_TEST("Both, NTSC Default",
|
||||
BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
|
||||
DRM_MODE_TV_MODE_NTSC,
|
||||
drm_mode_analog_ntsc_480i, drm_mode_analog_pal_576i),
|
||||
TV_MODE_TEST("Both, PAL Default",
|
||||
BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
|
||||
DRM_MODE_TV_MODE_PAL,
|
||||
drm_mode_analog_pal_576i, drm_mode_analog_ntsc_480i),
|
||||
TV_MODE_TEST_CMDLINE("Both, NTSC Default, with PAL on command-line",
|
||||
BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
|
||||
DRM_MODE_TV_MODE_NTSC,
|
||||
DRM_MODE_TV_MODE_PAL,
|
||||
drm_mode_analog_pal_576i, drm_mode_analog_ntsc_480i),
|
||||
TV_MODE_TEST_CMDLINE("Both, PAL Default, with NTSC on command-line",
|
||||
BIT(DRM_MODE_TV_MODE_NTSC) | BIT(DRM_MODE_TV_MODE_PAL),
|
||||
DRM_MODE_TV_MODE_PAL,
|
||||
DRM_MODE_TV_MODE_NTSC,
|
||||
drm_mode_analog_ntsc_480i, drm_mode_analog_pal_576i),
|
||||
};
|
||||
|
||||
static void
|
||||
drm_connector_helper_tv_get_modes_desc(const struct drm_connector_helper_tv_get_modes_test *t,
|
||||
char *desc)
|
||||
{
|
||||
sprintf(desc, "%s", t->name);
|
||||
}
|
||||
|
||||
KUNIT_ARRAY_PARAM(drm_connector_helper_tv_get_modes,
|
||||
drm_connector_helper_tv_get_modes_tests,
|
||||
drm_connector_helper_tv_get_modes_desc);
|
||||
|
||||
static struct kunit_case drm_test_connector_helper_tv_get_modes_tests[] = {
|
||||
KUNIT_CASE_PARAM(drm_test_connector_helper_tv_get_modes_check,
|
||||
drm_connector_helper_tv_get_modes_gen_params),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct kunit_suite drm_test_connector_helper_tv_get_modes_suite = {
|
||||
.name = "drm_connector_helper_tv_get_modes",
|
||||
.init = drm_probe_helper_test_init,
|
||||
.exit = drm_probe_helper_test_exit,
|
||||
.test_cases = drm_test_connector_helper_tv_get_modes_tests,
|
||||
};
|
||||
|
||||
kunit_test_suite(drm_test_connector_helper_tv_get_modes_suite);
|
||||
|
||||
MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>");
|
||||
MODULE_LICENSE("GPL");
|
||||
Reference in New Issue
Block a user