1 // SPDX-License-Identifier: GPL-2.0
3 #include <drm/drm_drv.h>
4 #include <drm/drm_kunit_helpers.h>
6 #include <kunit/test.h>
10 struct vc4_mock_output_desc {
11 enum vc4_encoder_type vc4_encoder_type;
12 unsigned int encoder_type;
13 unsigned int connector_type;
16 #define VC4_MOCK_OUTPUT_DESC(_vc4_type, _etype, _ctype) \
18 .vc4_encoder_type = _vc4_type, \
19 .encoder_type = _etype, \
20 .connector_type = _ctype, \
23 struct vc4_mock_pipe_desc {
24 const struct vc4_crtc_data *data;
25 const struct vc4_mock_output_desc *outputs;
26 unsigned int noutputs;
29 #define VC4_MOCK_CRTC_DESC(_data, ...) \
32 .outputs = (struct vc4_mock_output_desc[]) { __VA_ARGS__ }, \
33 .noutputs = sizeof((struct vc4_mock_output_desc[]) { __VA_ARGS__ }) / \
34 sizeof(struct vc4_mock_output_desc), \
37 #define VC4_MOCK_PIXELVALVE_DESC(_data, ...) \
38 VC4_MOCK_CRTC_DESC(&(_data)->base, __VA_ARGS__)
40 struct vc4_mock_desc {
41 const struct vc4_mock_pipe_desc *pipes;
45 #define VC4_MOCK_DESC(...) \
47 .pipes = (struct vc4_mock_pipe_desc[]) { __VA_ARGS__ }, \
48 .npipes = sizeof((struct vc4_mock_pipe_desc[]) { __VA_ARGS__ }) / \
49 sizeof(struct vc4_mock_pipe_desc), \
52 static const struct vc4_mock_desc vc4_mock =
54 VC4_MOCK_CRTC_DESC(&vc4_txp_crtc_data,
55 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_TXP,
56 DRM_MODE_ENCODER_VIRTUAL,
57 DRM_MODE_CONNECTOR_WRITEBACK)),
58 VC4_MOCK_PIXELVALVE_DESC(&bcm2835_pv0_data,
59 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DSI0,
61 DRM_MODE_CONNECTOR_DSI),
62 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DPI,
64 DRM_MODE_CONNECTOR_DPI)),
65 VC4_MOCK_PIXELVALVE_DESC(&bcm2835_pv1_data,
66 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DSI1,
68 DRM_MODE_CONNECTOR_DSI)),
69 VC4_MOCK_PIXELVALVE_DESC(&bcm2835_pv2_data,
70 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_HDMI0,
71 DRM_MODE_ENCODER_TMDS,
72 DRM_MODE_CONNECTOR_HDMIA),
73 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_VEC,
74 DRM_MODE_ENCODER_TVDAC,
75 DRM_MODE_CONNECTOR_Composite)),
78 static const struct vc4_mock_desc vc5_mock =
80 VC4_MOCK_CRTC_DESC(&vc4_txp_crtc_data,
81 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_TXP,
82 DRM_MODE_ENCODER_VIRTUAL,
83 DRM_MODE_CONNECTOR_WRITEBACK)),
84 VC4_MOCK_PIXELVALVE_DESC(&bcm2711_pv0_data,
85 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DSI0,
87 DRM_MODE_CONNECTOR_DSI),
88 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DPI,
90 DRM_MODE_CONNECTOR_DPI)),
91 VC4_MOCK_PIXELVALVE_DESC(&bcm2711_pv1_data,
92 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DSI1,
94 DRM_MODE_CONNECTOR_DSI)),
95 VC4_MOCK_PIXELVALVE_DESC(&bcm2711_pv2_data,
96 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_HDMI0,
97 DRM_MODE_ENCODER_TMDS,
98 DRM_MODE_CONNECTOR_HDMIA)),
99 VC4_MOCK_PIXELVALVE_DESC(&bcm2711_pv3_data,
100 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_VEC,
101 DRM_MODE_ENCODER_TVDAC,
102 DRM_MODE_CONNECTOR_Composite)),
103 VC4_MOCK_PIXELVALVE_DESC(&bcm2711_pv4_data,
104 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_HDMI1,
105 DRM_MODE_ENCODER_TMDS,
106 DRM_MODE_CONNECTOR_HDMIA)),
109 static int __build_one_pipe(struct kunit *test, struct drm_device *drm,
110 const struct vc4_mock_pipe_desc *pipe)
112 struct vc4_dummy_plane *dummy_plane;
113 struct drm_plane *plane;
114 struct vc4_dummy_crtc *dummy_crtc;
115 struct drm_crtc *crtc;
118 dummy_plane = vc4_dummy_plane(test, drm, DRM_PLANE_TYPE_PRIMARY);
119 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_plane);
121 plane = &dummy_plane->plane.base;
122 dummy_crtc = vc4_mock_pv(test, drm, plane, pipe->data);
123 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_crtc);
125 crtc = &dummy_crtc->crtc.base;
126 for (i = 0; i < pipe->noutputs; i++) {
127 const struct vc4_mock_output_desc *mock_output = &pipe->outputs[i];
128 struct vc4_dummy_output *dummy_output;
130 dummy_output = vc4_dummy_output(test, drm, crtc,
131 mock_output->vc4_encoder_type,
132 mock_output->encoder_type,
133 mock_output->connector_type);
134 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_output);
140 static int __build_mock(struct kunit *test, struct drm_device *drm,
141 const struct vc4_mock_desc *mock)
145 for (i = 0; i < mock->npipes; i++) {
146 const struct vc4_mock_pipe_desc *pipe = &mock->pipes[i];
149 ret = __build_one_pipe(test, drm, pipe);
150 KUNIT_ASSERT_EQ(test, ret, 0);
156 KUNIT_DEFINE_ACTION_WRAPPER(kunit_action_drm_dev_unregister,
158 struct drm_device *);
160 static struct vc4_dev *__mock_device(struct kunit *test, bool is_vc5)
162 struct drm_device *drm;
163 const struct drm_driver *drv = is_vc5 ? &vc5_drm_driver : &vc4_drm_driver;
164 const struct vc4_mock_desc *desc = is_vc5 ? &vc5_mock : &vc4_mock;
169 dev = drm_kunit_helper_alloc_device(test);
170 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
172 vc4 = drm_kunit_helper_alloc_drm_device_with_driver(test, dev,
173 struct vc4_dev, base,
175 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
178 vc4->is_vc5 = is_vc5;
180 vc4->hvs = __vc4_hvs_alloc(vc4, NULL);
181 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4->hvs);
184 ret = __build_mock(test, drm, desc);
185 KUNIT_ASSERT_EQ(test, ret, 0);
187 ret = vc4_kms_load(drm);
188 KUNIT_ASSERT_EQ(test, ret, 0);
190 ret = drm_dev_register(drm, 0);
191 KUNIT_ASSERT_EQ(test, ret, 0);
193 ret = kunit_add_action_or_reset(test,
194 kunit_action_drm_dev_unregister,
196 KUNIT_ASSERT_EQ(test, ret, 0);
201 struct vc4_dev *vc4_mock_device(struct kunit *test)
203 return __mock_device(test, false);
206 struct vc4_dev *vc5_mock_device(struct kunit *test)
208 return __mock_device(test, true);