| // 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"); |