Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/tests: Create tests for drm_atomic

We don't have a set of kunit tests for the functions under drm_atomic.h.
Let's use the introduction of drm_atomic_get_connector_for_encoder() to
create some tests for it and thus create that set.

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20250313-bridge-connector-v6-7-511c54a604fb@kernel.org
Signed-off-by: Maxime Ripard <mripard@kernel.org>

+154
+1
drivers/gpu/drm/tests/Makefile
··· 4 4 drm_kunit_helpers.o 5 5 6 6 obj-$(CONFIG_DRM_KUNIT_TEST) += \ 7 + drm_atomic_test.o \ 7 8 drm_atomic_state_test.o \ 8 9 drm_bridge_test.o \ 9 10 drm_buddy_test.o \
+153
drivers/gpu/drm/tests/drm_atomic_test.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Kunit test for drm_atomic functions 4 + */ 5 + #include <drm/drm_atomic.h> 6 + #include <drm/drm_atomic_state_helper.h> 7 + #include <drm/drm_atomic_uapi.h> 8 + #include <drm/drm_encoder.h> 9 + #include <drm/drm_kunit_helpers.h> 10 + #include <drm/drm_modeset_helper_vtables.h> 11 + 12 + #include <kunit/test.h> 13 + 14 + struct drm_atomic_test_priv { 15 + struct drm_device drm; 16 + struct drm_plane *plane; 17 + struct drm_crtc *crtc; 18 + struct drm_encoder encoder; 19 + struct drm_connector connector; 20 + }; 21 + 22 + static const struct drm_connector_helper_funcs drm_atomic_init_connector_helper_funcs = { 23 + }; 24 + 25 + static const struct drm_connector_funcs drm_atomic_init_connector_funcs = { 26 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 27 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 28 + .reset = drm_atomic_helper_connector_reset, 29 + }; 30 + 31 + static struct drm_atomic_test_priv *create_device(struct kunit *test) 32 + { 33 + struct drm_atomic_test_priv *priv; 34 + struct drm_connector *connector; 35 + struct drm_encoder *enc; 36 + struct drm_device *drm; 37 + struct drm_plane *plane; 38 + struct drm_crtc *crtc; 39 + struct device *dev; 40 + int ret; 41 + 42 + dev = drm_kunit_helper_alloc_device(test); 43 + if (IS_ERR(dev)) 44 + return ERR_CAST(dev); 45 + 46 + priv = drm_kunit_helper_alloc_drm_device(test, dev, 47 + struct drm_atomic_test_priv, drm, 48 + DRIVER_MODESET | DRIVER_ATOMIC); 49 + if (IS_ERR(priv)) 50 + return ERR_CAST(priv); 51 + 52 + drm = &priv->drm; 53 + plane = drm_kunit_helper_create_primary_plane(test, drm, 54 + NULL, 55 + NULL, 56 + NULL, 0, 57 + NULL); 58 + if (IS_ERR(plane)) 59 + return ERR_CAST(plane); 60 + priv->plane = plane; 61 + 62 + crtc = drm_kunit_helper_create_crtc(test, drm, 63 + plane, NULL, 64 + NULL, 65 + NULL); 66 + if (IS_ERR(crtc)) 67 + return ERR_CAST(crtc); 68 + priv->crtc = crtc; 69 + 70 + enc = &priv->encoder; 71 + ret = drmm_encoder_init(drm, enc, NULL, DRM_MODE_ENCODER_TMDS, NULL); 72 + if (ret) 73 + return ERR_PTR(ret); 74 + 75 + enc->possible_crtcs = drm_crtc_mask(crtc); 76 + 77 + connector = &priv->connector; 78 + ret = drmm_connector_init(drm, connector, 79 + &drm_atomic_init_connector_funcs, 80 + DRM_MODE_CONNECTOR_VIRTUAL, 81 + NULL); 82 + if (ret) 83 + return ERR_PTR(ret); 84 + 85 + drm_connector_helper_add(connector, &drm_atomic_init_connector_helper_funcs); 86 + 87 + drm_connector_attach_encoder(connector, enc); 88 + 89 + drm_mode_config_reset(drm); 90 + 91 + return priv; 92 + } 93 + 94 + static void drm_test_drm_atomic_get_connector_for_encoder(struct kunit *test) 95 + { 96 + struct drm_modeset_acquire_ctx ctx; 97 + struct drm_atomic_test_priv *priv; 98 + struct drm_display_mode *mode; 99 + struct drm_connector *curr_connector; 100 + int ret; 101 + 102 + priv = create_device(test); 103 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); 104 + 105 + mode = drm_kunit_display_mode_from_cea_vic(test, &priv->drm, 16); 106 + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, mode); 107 + 108 + drm_modeset_acquire_init(&ctx, 0); 109 + 110 + retry_enable: 111 + ret = drm_kunit_helper_enable_crtc_connector(test, &priv->drm, 112 + priv->crtc, &priv->connector, 113 + mode, &ctx); 114 + if (ret == -EDEADLK) { 115 + drm_modeset_backoff(&ctx); 116 + goto retry_enable; 117 + } 118 + KUNIT_ASSERT_EQ(test, ret, 0); 119 + 120 + drm_modeset_drop_locks(&ctx); 121 + drm_modeset_acquire_fini(&ctx); 122 + 123 + drm_modeset_acquire_init(&ctx, 0); 124 + 125 + retry_conn: 126 + curr_connector = drm_atomic_get_connector_for_encoder(&priv->encoder, 127 + &ctx); 128 + if (PTR_ERR(curr_connector) == -EDEADLK) { 129 + drm_modeset_backoff(&ctx); 130 + goto retry_conn; 131 + } 132 + KUNIT_EXPECT_PTR_EQ(test, curr_connector, &priv->connector); 133 + 134 + drm_modeset_drop_locks(&ctx); 135 + drm_modeset_acquire_fini(&ctx); 136 + } 137 + 138 + static struct kunit_case drm_atomic_get_connector_for_encoder_tests[] = { 139 + KUNIT_CASE(drm_test_drm_atomic_get_connector_for_encoder), 140 + { } 141 + }; 142 + 143 + 144 + static struct kunit_suite drm_atomic_get_connector_for_encoder_test_suite = { 145 + .name = "drm_test_atomic_get_connector_for_encoder", 146 + .test_cases = drm_atomic_get_connector_for_encoder_tests, 147 + }; 148 + 149 + kunit_test_suite(drm_atomic_get_connector_for_encoder_test_suite); 150 + 151 + MODULE_AUTHOR("Maxime Ripard <mripard@kernel.org>"); 152 + MODULE_DESCRIPTION("Kunit test for drm_atomic functions"); 153 + MODULE_LICENSE("GPL");