1 // SPDX-License-Identifier: GPL-2.0 2 3 #include <drm/drm_atomic_state_helper.h> 4 #include <drm/drm_atomic_uapi.h> 5 #include <drm/drm_connector.h> 6 #include <drm/drm_crtc.h> 7 #include <drm/drm_encoder.h> 8 #include <drm/drm_modeset_helper_vtables.h> 9 10 #include <kunit/test.h> 11 12 #include "vc4_mock.h" 13 14 static const struct drm_connector_helper_funcs vc4_dummy_connector_helper_funcs = { 15 }; 16 17 static const struct drm_connector_funcs vc4_dummy_connector_funcs = { 18 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 19 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 20 .reset = drm_atomic_helper_connector_reset, 21 }; 22 23 struct vc4_dummy_output *vc4_dummy_output(struct kunit *test, 24 struct drm_device *drm, 25 struct drm_crtc *crtc, 26 enum vc4_encoder_type vc4_encoder_type, 27 unsigned int kms_encoder_type, 28 unsigned int connector_type) 29 { 30 struct vc4_dummy_output *dummy_output; 31 struct drm_connector *conn; 32 struct drm_encoder *enc; 33 int ret; 34 35 dummy_output = drmm_kzalloc(drm, sizeof(*dummy_output), GFP_KERNEL); 36 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_output); 37 dummy_output->encoder.type = vc4_encoder_type; 38 39 enc = &dummy_output->encoder.base; 40 ret = drmm_encoder_init(drm, enc, 41 NULL, 42 kms_encoder_type, 43 NULL); 44 KUNIT_ASSERT_EQ(test, ret, 0); 45 enc->possible_crtcs = drm_crtc_mask(crtc); 46 47 conn = &dummy_output->connector; 48 ret = drmm_connector_init(drm, conn, 49 &vc4_dummy_connector_funcs, 50 connector_type, 51 NULL); 52 KUNIT_ASSERT_EQ(test, ret, 0); 53 54 drm_connector_helper_add(conn, &vc4_dummy_connector_helper_funcs); 55 drm_connector_attach_encoder(conn, enc); 56 57 return dummy_output; 58 } 59 60 static const struct drm_display_mode default_mode = { 61 DRM_SIMPLE_MODE(640, 480, 64, 48) 62 }; 63 64 int vc4_mock_atomic_add_output(struct kunit *test, 65 struct drm_atomic_state *state, 66 enum vc4_encoder_type type) 67 { 68 struct drm_device *drm = state->dev; 69 struct drm_connector_state *conn_state; 70 struct drm_crtc_state *crtc_state; 71 struct vc4_dummy_output *output; 72 struct drm_connector *conn; 73 struct drm_encoder *encoder; 74 struct drm_crtc *crtc; 75 int ret; 76 77 encoder = vc4_find_encoder_by_type(drm, type); 78 if (!encoder) 79 return -ENODEV; 80 81 crtc = vc4_find_crtc_for_encoder(test, drm, encoder); 82 if (!crtc) 83 return -ENODEV; 84 85 output = encoder_to_vc4_dummy_output(encoder); 86 conn = &output->connector; 87 conn_state = drm_atomic_get_connector_state(state, conn); 88 if (IS_ERR(conn_state)) 89 return PTR_ERR(conn_state); 90 91 ret = drm_atomic_set_crtc_for_connector(conn_state, crtc); 92 if (ret) 93 return ret; 94 95 crtc_state = drm_atomic_get_crtc_state(state, crtc); 96 if (IS_ERR(crtc_state)) 97 return PTR_ERR(crtc_state); 98 99 ret = drm_atomic_set_mode_for_crtc(crtc_state, &default_mode); 100 if (ret) 101 return ret; 102 103 crtc_state->active = true; 104 105 return 0; 106 } 107 108 int vc4_mock_atomic_del_output(struct kunit *test, 109 struct drm_atomic_state *state, 110 enum vc4_encoder_type type) 111 { 112 struct drm_device *drm = state->dev; 113 struct drm_connector_state *conn_state; 114 struct drm_crtc_state *crtc_state; 115 struct vc4_dummy_output *output; 116 struct drm_connector *conn; 117 struct drm_encoder *encoder; 118 struct drm_crtc *crtc; 119 int ret; 120 121 encoder = vc4_find_encoder_by_type(drm, type); 122 if (!encoder) 123 return -ENODEV; 124 125 crtc = vc4_find_crtc_for_encoder(test, drm, encoder); 126 if (!crtc) 127 return -ENODEV; 128 129 crtc_state = drm_atomic_get_crtc_state(state, crtc); 130 if (IS_ERR(crtc_state)) 131 return PTR_ERR(crtc_state); 132 133 crtc_state->active = false; 134 135 ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL); 136 if (ret) 137 return ret; 138 139 output = encoder_to_vc4_dummy_output(encoder); 140 conn = &output->connector; 141 conn_state = drm_atomic_get_connector_state(state, conn); 142 if (IS_ERR(conn_state)) 143 return PTR_ERR(conn_state); 144 145 ret = drm_atomic_set_crtc_for_connector(conn_state, NULL); 146 if (ret) 147 return ret; 148 149 return 0; 150 } 151