Merge tag 'drm-misc-next-2025-04-09' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next

drm-misc-next for v6.16-rc1:

UAPI Changes:
- Add ASAHI uapi header!
- Add apple fourcc modifiers.
- Add capset virtio definitions to UAPI.
- Extend EXPORT_SYNC_FILE for timeline syncobjs.

Cross-subsystem Changes:
- Adjust DMA-BUF sg handling to not cache map on attach.
- Update drm/ci, hlcdc, virtio, maintainers.
- Update fbdev todo.
- Allow setting dma-device for dma-buf import.
- Export efi_mem_desc_lookup to make efidrm build as a module.

Core Changes:
- Update drm scheduler docs.
- Use the correct resv object in TTM delayed destroy.
- Fix compiler warning with panic qr code, and other small fixes.
- drm/ci updates.
- Add debugfs file for listing all bridges.
- Small fixes to drm/client, ttm tests.
- Add documentation to display/hdmi.
- Add kunit tests for bridges.
- Dont fail managed device probing if connector polling fails.
- Create Kconfig.debug for drm core.
- Add tests for the drm scheduler.
- Add and use new access helpers for DPCPD.
- Add generic and optimized conversions for format-helper.
- Begin refcounting panel for improving lifetime handling.
- Unify simpledrm and ofdrm sysfb, and add extra features.
- Split hdmi audio in bridge to make DP audio work.

Driver Changes:
- Convert drivers to use devm_platform_ioremap_resource().
- Assorted small fixes to imx/legacy-bridg, gma500, pl111, nouveau, vc4,
  vmwgfx, ast, mxsfb, xlnx, accel/qaic, v3d, bridge/imx8qxp-ldb, ofdrm,
  bridge/fsl-ldb, udl, bridge/ti-sn65dsi86, bridge/anx7625, cirrus-qemu,
  bridge/cdns-dsi, panel/sharp, panel/himax, bridge/sil902x, renesas,
  imagination, various panels.
- Allow attaching more display to vkms.
- Add Powertip PH128800T004-ZZA01 panel.
- Add rotation quirk for ZOTAC panel.
- Convert bridge/tc358775 to atomic.
- Remove deprecated panel calls from synaptics, novatek, samsung panels.
- Refactor shmem helper page pinning and accel drivers using it.
- Add dmabuf support to accel/amdxdna.
- Use 4k page table format for panfrost/mediatek.
- Add common powerup/down dp link helper and use it.
- Assorted compiler warning fixes.
- Support dma-buf import for renesas

Signed-off-by: Dave Airlie <airlied@redhat.com>

# Conflicts:
#	include/drm/drm_kunit_helpers.h
From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Link: https://lore.kernel.org/r/e147ff95-697b-4067-9e2e-7cbd424e162a@linux.intel.com
This commit is contained in:
Dave Airlie
2025-04-14 15:29:49 +10:00
396 changed files with 14866 additions and 6309 deletions

View File

@@ -4,7 +4,9 @@ obj-$(CONFIG_DRM_KUNIT_TEST_HELPERS) += \
drm_kunit_helpers.o
obj-$(CONFIG_DRM_KUNIT_TEST) += \
drm_atomic_test.o \
drm_atomic_state_test.o \
drm_bridge_test.o \
drm_buddy_test.o \
drm_cmdline_parser_test.o \
drm_connector_test.o \

View File

@@ -0,0 +1,153 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Kunit test for drm_atomic functions
*/
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_atomic_uapi.h>
#include <drm/drm_encoder.h>
#include <drm/drm_kunit_helpers.h>
#include <drm/drm_modeset_helper_vtables.h>
#include <kunit/test.h>
struct drm_atomic_test_priv {
struct drm_device drm;
struct drm_plane *plane;
struct drm_crtc *crtc;
struct drm_encoder encoder;
struct drm_connector connector;
};
static const struct drm_connector_helper_funcs drm_atomic_init_connector_helper_funcs = {
};
static const struct drm_connector_funcs drm_atomic_init_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 struct drm_atomic_test_priv *create_device(struct kunit *test)
{
struct drm_atomic_test_priv *priv;
struct drm_connector *connector;
struct drm_encoder *enc;
struct drm_device *drm;
struct drm_plane *plane;
struct drm_crtc *crtc;
struct device *dev;
int ret;
dev = drm_kunit_helper_alloc_device(test);
if (IS_ERR(dev))
return ERR_CAST(dev);
priv = drm_kunit_helper_alloc_drm_device(test, dev,
struct drm_atomic_test_priv, drm,
DRIVER_MODESET | DRIVER_ATOMIC);
if (IS_ERR(priv))
return ERR_CAST(priv);
drm = &priv->drm;
plane = drm_kunit_helper_create_primary_plane(test, drm,
NULL,
NULL,
NULL, 0,
NULL);
if (IS_ERR(plane))
return ERR_CAST(plane);
priv->plane = plane;
crtc = drm_kunit_helper_create_crtc(test, drm,
plane, NULL,
NULL,
NULL);
if (IS_ERR(crtc))
return ERR_CAST(crtc);
priv->crtc = crtc;
enc = &priv->encoder;
ret = drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL);
if (ret)
return ERR_PTR(ret);
enc->possible_crtcs = drm_crtc_mask(crtc);
connector = &priv->connector;
ret = drmm_connector_init(drm, connector,
&drm_atomic_init_connector_funcs,
DRM_MODE_CONNECTOR_VIRTUAL,
NULL);
if (ret)
return ERR_PTR(ret);
drm_connector_helper_add(connector, &drm_atomic_init_connector_helper_funcs);
drm_connector_attach_encoder(connector, enc);
drm_mode_config_reset(drm);
return priv;
}
static void drm_test_drm_atomic_get_connector_for_encoder(struct kunit *test)
{
struct drm_modeset_acquire_ctx ctx;
struct drm_atomic_test_priv *priv;
struct drm_display_mode *mode;
struct drm_connector *curr_connector;
int ret;
priv = create_device(test);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
mode = drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode);
drm_modeset_acquire_init(&ctx, 0);
retry_enable:
ret = drm_kunit_helper_enable_crtc_connector(test, &priv->drm,
priv->crtc, &priv->connector,
mode, &ctx);
if (ret == -EDEADLK) {
drm_modeset_backoff(&ctx);
goto retry_enable;
}
KUNIT_ASSERT_EQ(test, ret, 0);
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
drm_modeset_acquire_init(&ctx, 0);
retry_conn:
curr_connector = drm_atomic_get_connector_for_encoder(&priv->encoder,
&ctx);
if (PTR_ERR(curr_connector) == -EDEADLK) {
drm_modeset_backoff(&ctx);
goto retry_conn;
}
KUNIT_EXPECT_PTR_EQ(test, curr_connector, &priv->connector);
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
}
static struct kunit_case drm_atomic_get_connector_for_encoder_tests[] = {
KUNIT_CASE(drm_test_drm_atomic_get_connector_for_encoder),
{ }
};
static struct kunit_suite drm_atomic_get_connector_for_encoder_test_suite = {
.name = "drm_test_atomic_get_connector_for_encoder",
.test_cases = drm_atomic_get_connector_for_encoder_tests,
};
kunit_test_suite(drm_atomic_get_connector_for_encoder_test_suite);
MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>");
MODULE_DESCRIPTION("Kunit test for drm_atomic functions");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,417 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Kunit test for drm_bridge functions
*/
#include <drm/drm_atomic_state_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_bridge_connector.h>
#include <drm/drm_bridge_helper.h>
#include <drm/drm_kunit_helpers.h>
#include <kunit/test.h>
struct drm_bridge_init_priv {
struct drm_device drm;
struct drm_plane *plane;
struct drm_crtc *crtc;
struct drm_encoder encoder;
struct drm_bridge bridge;
struct drm_connector *connector;
unsigned int enable_count;
unsigned int disable_count;
};
static void drm_test_bridge_enable(struct drm_bridge *bridge)
{
struct drm_bridge_init_priv *priv =
container_of(bridge, struct drm_bridge_init_priv, bridge);
priv->enable_count++;
}
static void drm_test_bridge_disable(struct drm_bridge *bridge)
{
struct drm_bridge_init_priv *priv =
container_of(bridge, struct drm_bridge_init_priv, bridge);
priv->disable_count++;
}
static const struct drm_bridge_funcs drm_test_bridge_legacy_funcs = {
.enable = drm_test_bridge_enable,
.disable = drm_test_bridge_disable,
};
static void drm_test_bridge_atomic_enable(struct drm_bridge *bridge,
struct drm_atomic_state *state)
{
struct drm_bridge_init_priv *priv =
container_of(bridge, struct drm_bridge_init_priv, bridge);
priv->enable_count++;
}
static void drm_test_bridge_atomic_disable(struct drm_bridge *bridge,
struct drm_atomic_state *state)
{
struct drm_bridge_init_priv *priv =
container_of(bridge, struct drm_bridge_init_priv, bridge);
priv->disable_count++;
}
static const struct drm_bridge_funcs drm_test_bridge_atomic_funcs = {
.atomic_enable = drm_test_bridge_atomic_enable,
.atomic_disable = drm_test_bridge_atomic_disable,
.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
.atomic_reset = drm_atomic_helper_bridge_reset,
};
KUNIT_DEFINE_ACTION_WRAPPER(drm_bridge_remove_wrapper,
drm_bridge_remove,
struct drm_bridge *);
static int drm_kunit_bridge_add(struct kunit *test,
struct drm_bridge *bridge)
{
drm_bridge_add(bridge);
return kunit_add_action_or_reset(test,
drm_bridge_remove_wrapper,
bridge);
}
static struct drm_bridge_init_priv *
drm_test_bridge_init(struct kunit *test, const struct drm_bridge_funcs *funcs)
{
struct drm_bridge_init_priv *priv;
struct drm_encoder *enc;
struct drm_bridge *bridge;
struct drm_device *drm;
struct device *dev;
int ret;
dev = drm_kunit_helper_alloc_device(test);
if (IS_ERR(dev))
return ERR_CAST(dev);
priv = drm_kunit_helper_alloc_drm_device(test, dev,
struct drm_bridge_init_priv, drm,
DRIVER_MODESET | DRIVER_ATOMIC);
if (IS_ERR(priv))
return ERR_CAST(priv);
drm = &priv->drm;
priv->plane = drm_kunit_helper_create_primary_plane(test, drm,
NULL,
NULL,
NULL, 0,
NULL);
if (IS_ERR(priv->plane))
return ERR_CAST(priv->plane);
priv->crtc = drm_kunit_helper_create_crtc(test, drm,
priv->plane, NULL,
NULL,
NULL);
if (IS_ERR(priv->crtc))
return ERR_CAST(priv->crtc);
enc = &priv->encoder;
ret = drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL);
if (ret)
return ERR_PTR(ret);
enc->possible_crtcs = drm_crtc_mask(priv->crtc);
bridge = &priv->bridge;
bridge->type = DRM_MODE_CONNECTOR_VIRTUAL;
bridge->funcs = funcs;
ret = drm_kunit_bridge_add(test, bridge);
if (ret)
return ERR_PTR(ret);
ret = drm_bridge_attach(enc, bridge, NULL, 0);
if (ret)
return ERR_PTR(ret);
priv->connector = drm_bridge_connector_init(drm, enc);
if (IS_ERR(priv->connector))
return ERR_CAST(priv->connector);
drm_connector_attach_encoder(priv->connector, enc);
drm_mode_config_reset(drm);
return priv;
}
/*
* Test that drm_bridge_get_current_state() returns the last committed
* state for an atomic bridge.
*/
static void drm_test_drm_bridge_get_current_state_atomic(struct kunit *test)
{
struct drm_modeset_acquire_ctx ctx;
struct drm_bridge_init_priv *priv;
struct drm_bridge_state *curr_bridge_state;
struct drm_bridge_state *bridge_state;
struct drm_atomic_state *state;
struct drm_bridge *bridge;
struct drm_device *drm;
int ret;
priv = drm_test_bridge_init(test, &drm_test_bridge_atomic_funcs);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
drm_modeset_acquire_init(&ctx, 0);
drm = &priv->drm;
state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
retry_commit:
bridge = &priv->bridge;
bridge_state = drm_atomic_get_bridge_state(state, bridge);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, bridge_state);
ret = drm_atomic_commit(state);
if (ret == -EDEADLK) {
drm_atomic_state_clear(state);
drm_modeset_backoff(&ctx);
goto retry_commit;
}
KUNIT_ASSERT_EQ(test, ret, 0);
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
drm_modeset_acquire_init(&ctx, 0);
retry_state:
ret = drm_modeset_lock(&bridge->base.lock, &ctx);
if (ret == -EDEADLK) {
drm_modeset_backoff(&ctx);
goto retry_state;
}
curr_bridge_state = drm_bridge_get_current_state(bridge);
KUNIT_EXPECT_PTR_EQ(test, curr_bridge_state, bridge_state);
drm_modeset_unlock(&bridge->base.lock);
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
}
/*
* Test that drm_bridge_get_current_state() returns NULL for a
* non-atomic bridge.
*/
static void drm_test_drm_bridge_get_current_state_legacy(struct kunit *test)
{
struct drm_bridge_init_priv *priv;
struct drm_bridge *bridge;
priv = drm_test_bridge_init(test, &drm_test_bridge_legacy_funcs);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
/*
* NOTE: Strictly speaking, we should take the bridge->base.lock
* before calling that function. However, bridge->base is only
* initialized if the bridge is atomic, while we explicitly
* initialize one that isn't there.
*
* In order to avoid unnecessary warnings, let's skip the
* locking. The function would return NULL in all cases anyway,
* so we don't really have any concurrency to worry about.
*/
bridge = &priv->bridge;
KUNIT_EXPECT_NULL(test, drm_bridge_get_current_state(bridge));
}
static struct kunit_case drm_bridge_get_current_state_tests[] = {
KUNIT_CASE(drm_test_drm_bridge_get_current_state_atomic),
KUNIT_CASE(drm_test_drm_bridge_get_current_state_legacy),
{ }
};
static struct kunit_suite drm_bridge_get_current_state_test_suite = {
.name = "drm_test_bridge_get_current_state",
.test_cases = drm_bridge_get_current_state_tests,
};
/*
* Test that an atomic bridge is properly power-cycled when calling
* drm_bridge_helper_reset_crtc().
*/
static void drm_test_drm_bridge_helper_reset_crtc_atomic(struct kunit *test)
{
struct drm_modeset_acquire_ctx ctx;
struct drm_bridge_init_priv *priv;
struct drm_display_mode *mode;
struct drm_bridge *bridge;
int ret;
priv = drm_test_bridge_init(test, &drm_test_bridge_atomic_funcs);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
mode = drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode);
drm_modeset_acquire_init(&ctx, 0);
retry_commit:
ret = drm_kunit_helper_enable_crtc_connector(test,
&priv->drm, priv->crtc,
priv->connector,
mode,
&ctx);
if (ret == -EDEADLK) {
drm_modeset_backoff(&ctx);
goto retry_commit;
}
KUNIT_ASSERT_EQ(test, ret, 0);
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
bridge = &priv->bridge;
KUNIT_ASSERT_EQ(test, priv->enable_count, 1);
KUNIT_ASSERT_EQ(test, priv->disable_count, 0);
drm_modeset_acquire_init(&ctx, 0);
retry_reset:
ret = drm_bridge_helper_reset_crtc(bridge, &ctx);
if (ret == -EDEADLK) {
drm_modeset_backoff(&ctx);
goto retry_reset;
}
KUNIT_ASSERT_EQ(test, ret, 0);
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
KUNIT_EXPECT_EQ(test, priv->enable_count, 2);
KUNIT_EXPECT_EQ(test, priv->disable_count, 1);
}
/*
* Test that calling drm_bridge_helper_reset_crtc() on a disabled atomic
* bridge will fail and not call the enable / disable callbacks
*/
static void drm_test_drm_bridge_helper_reset_crtc_atomic_disabled(struct kunit *test)
{
struct drm_modeset_acquire_ctx ctx;
struct drm_bridge_init_priv *priv;
struct drm_display_mode *mode;
struct drm_bridge *bridge;
int ret;
priv = drm_test_bridge_init(test, &drm_test_bridge_atomic_funcs);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
mode = drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode);
bridge = &priv->bridge;
KUNIT_ASSERT_EQ(test, priv->enable_count, 0);
KUNIT_ASSERT_EQ(test, priv->disable_count, 0);
drm_modeset_acquire_init(&ctx, 0);
retry_reset:
ret = drm_bridge_helper_reset_crtc(bridge, &ctx);
if (ret == -EDEADLK) {
drm_modeset_backoff(&ctx);
goto retry_reset;
}
KUNIT_EXPECT_LT(test, ret, 0);
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
KUNIT_EXPECT_EQ(test, priv->enable_count, 0);
KUNIT_EXPECT_EQ(test, priv->disable_count, 0);
}
/*
* Test that a non-atomic bridge is properly power-cycled when calling
* drm_bridge_helper_reset_crtc().
*/
static void drm_test_drm_bridge_helper_reset_crtc_legacy(struct kunit *test)
{
struct drm_modeset_acquire_ctx ctx;
struct drm_bridge_init_priv *priv;
struct drm_display_mode *mode;
struct drm_bridge *bridge;
int ret;
priv = drm_test_bridge_init(test, &drm_test_bridge_legacy_funcs);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv);
mode = drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode);
drm_modeset_acquire_init(&ctx, 0);
retry_commit:
ret = drm_kunit_helper_enable_crtc_connector(test,
&priv->drm, priv->crtc,
priv->connector,
mode,
&ctx);
if (ret == -EDEADLK) {
drm_modeset_backoff(&ctx);
goto retry_commit;
}
KUNIT_ASSERT_EQ(test, ret, 0);
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
bridge = &priv->bridge;
KUNIT_ASSERT_EQ(test, priv->enable_count, 1);
KUNIT_ASSERT_EQ(test, priv->disable_count, 0);
drm_modeset_acquire_init(&ctx, 0);
retry_reset:
ret = drm_bridge_helper_reset_crtc(bridge, &ctx);
if (ret == -EDEADLK) {
drm_modeset_backoff(&ctx);
goto retry_reset;
}
KUNIT_ASSERT_EQ(test, ret, 0);
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
KUNIT_EXPECT_EQ(test, priv->enable_count, 2);
KUNIT_EXPECT_EQ(test, priv->disable_count, 1);
}
static struct kunit_case drm_bridge_helper_reset_crtc_tests[] = {
KUNIT_CASE(drm_test_drm_bridge_helper_reset_crtc_atomic),
KUNIT_CASE(drm_test_drm_bridge_helper_reset_crtc_atomic_disabled),
KUNIT_CASE(drm_test_drm_bridge_helper_reset_crtc_legacy),
{ }
};
static struct kunit_suite drm_bridge_helper_reset_crtc_test_suite = {
.name = "drm_test_bridge_helper_reset_crtc",
.test_cases = drm_bridge_helper_reset_crtc_tests,
};
kunit_test_suites(
&drm_bridge_get_current_state_test_suite,
&drm_bridge_helper_reset_crtc_test_suite,
);
MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>");
MODULE_DESCRIPTION("Kunit test for drm_bridge functions");
MODULE_LICENSE("GPL");

View File

@@ -88,7 +88,8 @@ static void drm_test_pick_cmdline_res_1920_1080_60(struct kunit *test)
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;
struct drm_display_mode *expected_mode;
const struct drm_display_mode *mode;
const char *cmdline = "1920x1080@60";
int ret;

View File

@@ -134,7 +134,7 @@ static void drm_gem_shmem_test_pin_pages(struct kunit *test)
shmem = drm_gem_shmem_create(drm_dev, TEST_SIZE);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, shmem);
KUNIT_EXPECT_NULL(test, shmem->pages);
KUNIT_EXPECT_EQ(test, shmem->pages_use_count, 0);
KUNIT_EXPECT_EQ(test, refcount_read(&shmem->pages_use_count), 0);
ret = kunit_add_action_or_reset(test, drm_gem_shmem_free_wrapper, shmem);
KUNIT_ASSERT_EQ(test, ret, 0);
@@ -142,14 +142,14 @@ static void drm_gem_shmem_test_pin_pages(struct kunit *test)
ret = drm_gem_shmem_pin(shmem);
KUNIT_ASSERT_EQ(test, ret, 0);
KUNIT_ASSERT_NOT_NULL(test, shmem->pages);
KUNIT_EXPECT_EQ(test, shmem->pages_use_count, 1);
KUNIT_EXPECT_EQ(test, refcount_read(&shmem->pages_use_count), 1);
for (i = 0; i < (shmem->base.size >> PAGE_SHIFT); i++)
KUNIT_ASSERT_NOT_NULL(test, shmem->pages[i]);
drm_gem_shmem_unpin(shmem);
KUNIT_EXPECT_NULL(test, shmem->pages);
KUNIT_EXPECT_EQ(test, shmem->pages_use_count, 0);
KUNIT_EXPECT_EQ(test, refcount_read(&shmem->pages_use_count), 0);
}
/*
@@ -168,24 +168,24 @@ static void drm_gem_shmem_test_vmap(struct kunit *test)
shmem = drm_gem_shmem_create(drm_dev, TEST_SIZE);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, shmem);
KUNIT_EXPECT_NULL(test, shmem->vaddr);
KUNIT_EXPECT_EQ(test, shmem->vmap_use_count, 0);
KUNIT_EXPECT_EQ(test, refcount_read(&shmem->vmap_use_count), 0);
ret = kunit_add_action_or_reset(test, drm_gem_shmem_free_wrapper, shmem);
KUNIT_ASSERT_EQ(test, ret, 0);
ret = drm_gem_shmem_vmap(shmem, &map);
ret = drm_gem_shmem_vmap_locked(shmem, &map);
KUNIT_ASSERT_EQ(test, ret, 0);
KUNIT_ASSERT_NOT_NULL(test, shmem->vaddr);
KUNIT_ASSERT_FALSE(test, iosys_map_is_null(&map));
KUNIT_EXPECT_EQ(test, shmem->vmap_use_count, 1);
KUNIT_EXPECT_EQ(test, refcount_read(&shmem->vmap_use_count), 1);
iosys_map_memset(&map, 0, TEST_BYTE, TEST_SIZE);
for (i = 0; i < TEST_SIZE; i++)
KUNIT_EXPECT_EQ(test, iosys_map_rd(&map, i, u8), TEST_BYTE);
drm_gem_shmem_vunmap(shmem, &map);
drm_gem_shmem_vunmap_locked(shmem, &map);
KUNIT_EXPECT_NULL(test, shmem->vaddr);
KUNIT_EXPECT_EQ(test, shmem->vmap_use_count, 0);
KUNIT_EXPECT_EQ(test, refcount_read(&shmem->vmap_use_count), 0);
}
/*
@@ -251,7 +251,7 @@ static void drm_gem_shmem_test_get_sg_table(struct kunit *test)
sgt = drm_gem_shmem_get_pages_sgt(shmem);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, sgt);
KUNIT_ASSERT_NOT_NULL(test, shmem->pages);
KUNIT_EXPECT_EQ(test, shmem->pages_use_count, 1);
KUNIT_EXPECT_EQ(test, refcount_read(&shmem->pages_use_count), 1);
KUNIT_EXPECT_PTR_EQ(test, sgt, shmem->sgt);
for_each_sgtable_sg(sgt, sg, si) {
@@ -281,17 +281,17 @@ static void drm_gem_shmem_test_madvise(struct kunit *test)
ret = kunit_add_action_or_reset(test, drm_gem_shmem_free_wrapper, shmem);
KUNIT_ASSERT_EQ(test, ret, 0);
ret = drm_gem_shmem_madvise(shmem, 1);
ret = drm_gem_shmem_madvise_locked(shmem, 1);
KUNIT_EXPECT_TRUE(test, ret);
KUNIT_ASSERT_EQ(test, shmem->madv, 1);
/* Set madv to a negative value */
ret = drm_gem_shmem_madvise(shmem, -1);
ret = drm_gem_shmem_madvise_locked(shmem, -1);
KUNIT_EXPECT_FALSE(test, ret);
KUNIT_ASSERT_EQ(test, shmem->madv, -1);
/* Check that madv cannot be set back to a positive value */
ret = drm_gem_shmem_madvise(shmem, 0);
ret = drm_gem_shmem_madvise_locked(shmem, 0);
KUNIT_EXPECT_FALSE(test, ret);
KUNIT_ASSERT_EQ(test, shmem->madv, -1);
}
@@ -319,7 +319,7 @@ static void drm_gem_shmem_test_purge(struct kunit *test)
ret = drm_gem_shmem_is_purgeable(shmem);
KUNIT_EXPECT_FALSE(test, ret);
ret = drm_gem_shmem_madvise(shmem, 1);
ret = drm_gem_shmem_madvise_locked(shmem, 1);
KUNIT_EXPECT_TRUE(test, ret);
/* The scatter/gather table will be freed by drm_gem_shmem_free */
@@ -329,7 +329,7 @@ static void drm_gem_shmem_test_purge(struct kunit *test)
ret = drm_gem_shmem_is_purgeable(shmem);
KUNIT_EXPECT_TRUE(test, ret);
drm_gem_shmem_purge(shmem);
drm_gem_shmem_purge_locked(shmem);
KUNIT_EXPECT_NULL(test, shmem->pages);
KUNIT_EXPECT_NULL(test, shmem->sgt);
KUNIT_EXPECT_EQ(test, shmem->madv, -1);

View File

@@ -55,49 +55,6 @@ static struct drm_display_mode *find_preferred_mode(struct drm_connector *connec
return preferred;
}
static int light_up_connector(struct kunit *test,
struct drm_device *drm,
struct drm_crtc *crtc,
struct drm_connector *connector,
struct drm_display_mode *mode,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_atomic_state *state;
struct drm_connector_state *conn_state;
struct drm_crtc_state *crtc_state;
int ret;
state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
retry:
conn_state = drm_atomic_get_connector_state(state, connector);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, conn_state);
ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
if (ret == -EDEADLK) {
drm_atomic_state_clear(state);
ret = drm_modeset_backoff(ctx);
if (!ret)
goto retry;
}
KUNIT_EXPECT_EQ(test, ret, 0);
crtc_state = drm_atomic_get_crtc_state(state, crtc);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc_state);
ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
KUNIT_EXPECT_EQ(test, ret, 0);
crtc_state->enable = true;
crtc_state->active = true;
ret = drm_atomic_commit(state);
KUNIT_ASSERT_EQ(test, ret, 0);
return 0;
}
static int set_connector_edid(struct kunit *test, struct drm_connector *connector,
const char *edid, size_t edid_len)
{
@@ -298,7 +255,10 @@ static void drm_test_check_broadcast_rgb_crtc_mode_changed(struct kunit *test)
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_ASSERT_EQ(test, ret, 0);
state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
@@ -364,7 +324,10 @@ static void drm_test_check_broadcast_rgb_crtc_mode_not_changed(struct kunit *tes
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_ASSERT_EQ(test, ret, 0);
state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
@@ -432,7 +395,10 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode(struct kunit *test)
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_ASSERT_EQ(test, ret, 0);
state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
@@ -489,7 +455,10 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test)
KUNIT_ASSERT_NOT_NULL(test, mode);
crtc = priv->crtc;
ret = light_up_connector(test, drm, crtc, conn, mode, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
mode,
&ctx);
KUNIT_ASSERT_EQ(test, ret, 0);
state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
@@ -547,7 +516,10 @@ static void drm_test_check_broadcast_rgb_full_cea_mode(struct kunit *test)
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_ASSERT_EQ(test, ret, 0);
state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
@@ -606,7 +578,10 @@ static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test)
KUNIT_ASSERT_NOT_NULL(test, mode);
crtc = priv->crtc;
ret = light_up_connector(test, drm, crtc, conn, mode, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
mode,
&ctx);
KUNIT_ASSERT_EQ(test, ret, 0);
state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
@@ -666,7 +641,10 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode(struct kunit *test)
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_ASSERT_EQ(test, ret, 0);
state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
@@ -725,7 +703,10 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *te
KUNIT_ASSERT_NOT_NULL(test, mode);
crtc = priv->crtc;
ret = light_up_connector(test, drm, crtc, conn, mode, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
mode,
&ctx);
KUNIT_ASSERT_EQ(test, ret, 0);
state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
@@ -789,7 +770,10 @@ static void drm_test_check_output_bpc_crtc_mode_changed(struct kunit *test)
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_ASSERT_EQ(test, ret, 0);
state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
@@ -865,7 +849,10 @@ static void drm_test_check_output_bpc_crtc_mode_not_changed(struct kunit *test)
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_ASSERT_EQ(test, ret, 0);
state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);
@@ -941,7 +928,10 @@ static void drm_test_check_output_bpc_dvi(struct kunit *test)
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_ASSERT_EQ(test, ret, 0);
conn_state = conn->state;
@@ -988,7 +978,10 @@ static void drm_test_check_tmds_char_rate_rgb_8bpc(struct kunit *test)
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_ASSERT_EQ(test, ret, 0);
conn_state = conn->state;
@@ -1037,7 +1030,10 @@ static void drm_test_check_tmds_char_rate_rgb_10bpc(struct kunit *test)
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_ASSERT_EQ(test, ret, 0);
conn_state = conn->state;
@@ -1086,7 +1082,10 @@ static void drm_test_check_tmds_char_rate_rgb_12bpc(struct kunit *test)
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_ASSERT_EQ(test, ret, 0);
conn_state = conn->state;
@@ -1134,7 +1133,10 @@ static void drm_test_check_hdmi_funcs_reject_rate(struct kunit *test)
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_ASSERT_EQ(test, ret, 0);
/* You shouldn't be doing that at home. */
@@ -1208,7 +1210,10 @@ static void drm_test_check_max_tmds_rate_bpc_fallback(struct kunit *test)
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_EXPECT_EQ(test, ret, 0);
conn_state = conn->state;
@@ -1282,7 +1287,10 @@ static void drm_test_check_max_tmds_rate_format_fallback(struct kunit *test)
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_EXPECT_EQ(test, ret, 0);
conn_state = conn->state;
@@ -1347,7 +1355,10 @@ static void drm_test_check_output_bpc_format_vic_1(struct kunit *test)
drm_modeset_acquire_init(&ctx, 0);
crtc = priv->crtc;
ret = light_up_connector(test, drm, crtc, conn, mode, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
mode,
&ctx);
KUNIT_EXPECT_EQ(test, ret, 0);
conn_state = conn->state;
@@ -1414,7 +1425,10 @@ static void drm_test_check_output_bpc_format_driver_rgb_only(struct kunit *test)
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_EXPECT_EQ(test, ret, 0);
conn_state = conn->state;
@@ -1483,7 +1497,10 @@ static void drm_test_check_output_bpc_format_display_rgb_only(struct kunit *test
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_EXPECT_EQ(test, ret, 0);
conn_state = conn->state;
@@ -1543,7 +1560,10 @@ static void drm_test_check_output_bpc_format_driver_8bpc_only(struct kunit *test
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_EXPECT_EQ(test, ret, 0);
conn_state = conn->state;
@@ -1605,7 +1625,10 @@ static void drm_test_check_output_bpc_format_display_8bpc_only(struct kunit *tes
drm_modeset_acquire_init(&ctx, 0);
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_EXPECT_EQ(test, ret, 0);
conn_state = conn->state;
@@ -1645,7 +1668,10 @@ static void drm_test_check_disable_connector(struct kunit *test)
drm = &priv->drm;
crtc = priv->crtc;
ret = light_up_connector(test, drm, crtc, conn, preferred, &ctx);
ret = drm_kunit_helper_enable_crtc_connector(test, drm,
crtc, conn,
preferred,
&ctx);
KUNIT_ASSERT_EQ(test, ret, 0);
state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx);

View File

@@ -2,6 +2,7 @@
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_atomic_uapi.h>
#include <drm/drm_drv.h>
#include <drm/drm_edid.h>
#include <drm/drm_fourcc.h>
@@ -271,6 +272,66 @@ drm_kunit_helper_create_crtc(struct kunit *test,
}
EXPORT_SYMBOL_GPL(drm_kunit_helper_create_crtc);
/**
* drm_kunit_helper_enable_crtc_connector - Enables a CRTC -> Connector output
* @test: The test context object
* @drm: The device to alloc the plane for
* @crtc: The CRTC to enable
* @connector: The Connector to enable
* @mode: The display mode to configure the CRTC with
* @ctx: Locking context
*
* This function creates an atomic update to enable the route from @crtc
* to @connector, with the given @mode.
*
* Returns:
*
* A pointer to the new CRTC, or an ERR_PTR() otherwise. If the error
* returned is EDEADLK, the entire atomic sequence must be restarted.
*/
int drm_kunit_helper_enable_crtc_connector(struct kunit *test,
struct drm_device *drm,
struct drm_crtc *crtc,
struct drm_connector *connector,
const struct drm_display_mode *mode,
struct drm_modeset_acquire_ctx *ctx)
{
struct drm_atomic_state *state;
struct drm_connector_state *conn_state;
struct drm_crtc_state *crtc_state;
int ret;
state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
if (IS_ERR(state))
return PTR_ERR(state);
conn_state = drm_atomic_get_connector_state(state, connector);
if (IS_ERR(conn_state))
return PTR_ERR(conn_state);
ret = drm_atomic_set_crtc_for_connector(conn_state, crtc);
if (ret)
return ret;
crtc_state = drm_atomic_get_crtc_state(state, crtc);
if (IS_ERR(crtc_state))
return PTR_ERR(crtc_state);
ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
if (ret)
return ret;
crtc_state->enable = true;
crtc_state->active = true;
ret = drm_atomic_commit(state);
if (ret)
return ret;
return 0;
}
EXPORT_SYMBOL_GPL(drm_kunit_helper_enable_crtc_connector);
static void kunit_action_drm_mode_destroy(void *ptr)
{
struct drm_display_mode *mode = ptr;