| 1 | |
| 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 <[email protected]>");
|
| 152 | MODULE_DESCRIPTION("Kunit test for drm_atomic functions");
|
| 153 | MODULE_LICENSE("GPL");
|