drm_atomic_commit_fill_with_defaults() is used by the DRM_MODE_ATOMIC_RESET flag to bring all objects back to their pristine state. However, it has no dedicated test coverage.
Add two tests that verify the reset cycle. The first enables a CRTC, plane, and connector, then calls drm_atomic_commit_fill_with_defaults() and verifies all objects return to their disabled state: CRTC inactive, plane disabled with no framebuffer, and connector unbound. The second goes further and commits the default-filled state to verify the init -> enable -> reset -> commit sequence completes without errors. Suggested-by: Daniel Stone <[email protected]> Signed-off-by: Maxime Ripard <[email protected]> --- drivers/gpu/drm/tests/drm_atomic_test.c | 128 +++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/tests/drm_atomic_test.c b/drivers/gpu/drm/tests/drm_atomic_test.c index 0aca5c1bbeae..fe6477264c24 100644 --- a/drivers/gpu/drm/tests/drm_atomic_test.c +++ b/drivers/gpu/drm/tests/drm_atomic_test.c @@ -140,16 +140,140 @@ static void drm_test_drm_atomic_get_connector_for_encoder(struct kunit *test) 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); +/* + * Test that after enabling a CRTC, plane, and connector, filling with + * defaults produces a state where all objects are disabled: CRTC is + * inactive, plane has no framebuffer, and connector is unbound. + */ +static void drm_test_check_fill_with_defaults(struct kunit *test) +{ + struct drm_atomic_test_priv *priv; + struct drm_modeset_acquire_ctx ctx; + struct drm_connector_state *new_conn_state; + struct drm_crtc_state *new_crtc_state; + struct drm_plane_state *new_plane_state; + struct drm_atomic_commit *state; + struct drm_display_mode *mode; + struct drm_device *drm; + int ret; + + priv = create_device(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); + + drm = &priv->drm; + + mode = drm_kunit_display_mode_from_cea_vic(test, 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, drm, + priv->crtc, + &priv->connector, + mode, &ctx); + if (ret == -EDEADLK) { + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_enable; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + ret = drm_atomic_commit_fill_with_defaults(state); + KUNIT_ASSERT_EQ(test, ret, 0); + + new_crtc_state = drm_atomic_get_new_crtc_state(state, priv->crtc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_crtc_state); + KUNIT_EXPECT_FALSE(test, new_crtc_state->enable); + KUNIT_EXPECT_FALSE(test, new_crtc_state->active); + + new_plane_state = drm_atomic_get_new_plane_state(state, priv->plane); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_plane_state); + KUNIT_EXPECT_NULL(test, new_plane_state->crtc); + KUNIT_EXPECT_NULL(test, new_plane_state->fb); + + new_conn_state = drm_atomic_get_new_connector_state(state, &priv->connector); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_conn_state); + KUNIT_EXPECT_NULL(test, new_conn_state->crtc); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + +/* + * Test that fill_with_defaults produces a state that can be + * successfully committed, completing the full reset round-trip. + */ +static void drm_test_check_fill_with_defaults_commit(struct kunit *test) +{ + struct drm_atomic_test_priv *priv; + struct drm_modeset_acquire_ctx ctx; + struct drm_atomic_commit *state; + struct drm_display_mode *mode; + struct drm_device *drm; + int ret; + + priv = create_device(test); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv); + + drm = &priv->drm; + + mode = drm_kunit_display_mode_from_cea_vic(test, 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, drm, + priv->crtc, + &priv->connector, + mode, &ctx); + if (ret == -EDEADLK) { + ret = drm_modeset_backoff(&ctx); + if (!ret) + goto retry_enable; + } + KUNIT_ASSERT_EQ(test, ret, 0); + + state = drm_kunit_helper_atomic_state_alloc(test, drm, &ctx); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); + + ret = drm_atomic_commit_fill_with_defaults(state); + KUNIT_ASSERT_EQ(test, ret, 0); + + state->allow_modeset = true; + + ret = drm_atomic_commit(state); + KUNIT_EXPECT_EQ(test, ret, 0); + + drm_modeset_drop_locks(&ctx); + drm_modeset_acquire_fini(&ctx); +} + +static struct kunit_case drm_atomic_fill_with_defaults_tests[] = { + KUNIT_CASE(drm_test_check_fill_with_defaults), + KUNIT_CASE(drm_test_check_fill_with_defaults_commit), + { } +}; + +static struct kunit_suite drm_atomic_fill_with_defaults_test_suite = { + .name = "drm_atomic_commit_fill_with_defaults", + .test_cases = drm_atomic_fill_with_defaults_tests, +}; + +kunit_test_suites(&drm_atomic_get_connector_for_encoder_test_suite, + &drm_atomic_fill_with_defaults_test_suite); MODULE_AUTHOR("Maxime Ripard <[email protected]>"); MODULE_DESCRIPTION("Kunit test for drm_atomic functions"); MODULE_LICENSE("GPL"); -- 2.55.0
