// SPDX-License-Identifier: GPL-2.0 /* * Kunit test for drm_atomic functions */ #include #include #include #include #include #include #include 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 "); MODULE_DESCRIPTION("Kunit test for drm_atomic functions"); MODULE_LICENSE("GPL");