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