1// SPDX-License-Identifier: GPL-2.0
2
3#include <drm/drm_drv.h>
4#include <drm/drm_kunit_helpers.h>
5
6#include <kunit/test.h>
7
8#include "vc4_mock.h"
9
10struct vc4_mock_output_desc {
11 enum vc4_encoder_type vc4_encoder_type;
12 unsigned int encoder_type;
13 unsigned int connector_type;
14};
15
16#define VC4_MOCK_OUTPUT_DESC(_vc4_type, _etype, _ctype) \
17 { \
18 .vc4_encoder_type = _vc4_type, \
19 .encoder_type = _etype, \
20 .connector_type = _ctype, \
21 }
22
23struct vc4_mock_pipe_desc {
24 const struct vc4_crtc_data *data;
25 const struct vc4_mock_output_desc *outputs;
26 unsigned int noutputs;
27};
28
29#define VC4_MOCK_CRTC_DESC(_data, ...) \
30 { \
31 .data = _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), \
35 }
36
37#define VC4_MOCK_PIXELVALVE_DESC(_data, ...) \
38 VC4_MOCK_CRTC_DESC(&(_data)->base, __VA_ARGS__)
39
40struct vc4_mock_desc {
41 const struct vc4_mock_pipe_desc *pipes;
42 unsigned int npipes;
43};
44
45#define VC4_MOCK_DESC(...) \
46 { \
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), \
50 }
51
52static const struct vc4_mock_desc vc4_mock =
53 VC4_MOCK_DESC(
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,
60 DRM_MODE_ENCODER_DSI,
61 DRM_MODE_CONNECTOR_DSI),
62 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DPI,
63 DRM_MODE_ENCODER_DPI,
64 DRM_MODE_CONNECTOR_DPI)),
65 VC4_MOCK_PIXELVALVE_DESC(&bcm2835_pv1_data,
66 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DSI1,
67 DRM_MODE_ENCODER_DSI,
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)),
76);
77
78static const struct vc4_mock_desc vc5_mock =
79 VC4_MOCK_DESC(
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,
86 DRM_MODE_ENCODER_DSI,
87 DRM_MODE_CONNECTOR_DSI),
88 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DPI,
89 DRM_MODE_ENCODER_DPI,
90 DRM_MODE_CONNECTOR_DPI)),
91 VC4_MOCK_PIXELVALVE_DESC(&bcm2711_pv1_data,
92 VC4_MOCK_OUTPUT_DESC(VC4_ENCODER_TYPE_DSI1,
93 DRM_MODE_ENCODER_DSI,
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)),
107);
108
109static int __build_one_pipe(struct kunit *test, struct drm_device *drm,
110 const struct vc4_mock_pipe_desc *pipe)
111{
112 struct vc4_dummy_plane *dummy_plane;
113 struct drm_plane *plane;
114 struct vc4_dummy_crtc *dummy_crtc;
115 struct drm_crtc *crtc;
116 unsigned int i;
117
118 dummy_plane = vc4_dummy_plane(test, drm, type: DRM_PLANE_TYPE_PRIMARY);
119 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_plane);
120
121 plane = &dummy_plane->plane.base;
122 dummy_crtc = vc4_mock_pv(test, drm, plane, data: pipe->data);
123 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_crtc);
124
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;
129
130 dummy_output = vc4_dummy_output(test, drm, crtc,
131 vc4_encoder_type: mock_output->vc4_encoder_type,
132 kms_encoder_type: mock_output->encoder_type,
133 connector_type: mock_output->connector_type);
134 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_output);
135 }
136
137 return 0;
138}
139
140static int __build_mock(struct kunit *test, struct drm_device *drm,
141 const struct vc4_mock_desc *mock)
142{
143 unsigned int i;
144
145 for (i = 0; i < mock->npipes; i++) {
146 const struct vc4_mock_pipe_desc *pipe = &mock->pipes[i];
147 int ret;
148
149 ret = __build_one_pipe(test, drm, pipe);
150 KUNIT_ASSERT_EQ(test, ret, 0);
151 }
152
153 return 0;
154}
155
156KUNIT_DEFINE_ACTION_WRAPPER(kunit_action_drm_dev_unregister,
157 drm_dev_unregister,
158 struct drm_device *);
159
160static struct vc4_dev *__mock_device(struct kunit *test, bool is_vc5)
161{
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;
165 struct vc4_dev *vc4;
166 struct device *dev;
167 int ret;
168
169 dev = drm_kunit_helper_alloc_device(test);
170 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
171
172 vc4 = drm_kunit_helper_alloc_drm_device_with_driver(test, dev,
173 struct vc4_dev, base,
174 drv);
175 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
176
177 vc4->dev = dev;
178 vc4->is_vc5 = is_vc5;
179
180 vc4->hvs = __vc4_hvs_alloc(vc4, NULL);
181 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4->hvs);
182
183 drm = &vc4->base;
184 ret = __build_mock(test, drm, mock: desc);
185 KUNIT_ASSERT_EQ(test, ret, 0);
186
187 ret = vc4_kms_load(dev: drm);
188 KUNIT_ASSERT_EQ(test, ret, 0);
189
190 ret = drm_dev_register(dev: drm, flags: 0);
191 KUNIT_ASSERT_EQ(test, ret, 0);
192
193 ret = kunit_add_action_or_reset(test,
194 action: kunit_action_drm_dev_unregister,
195 ctx: drm);
196 KUNIT_ASSERT_EQ(test, ret, 0);
197
198 return vc4;
199}
200
201struct vc4_dev *vc4_mock_device(struct kunit *test)
202{
203 return __mock_device(test, is_vc5: false);
204}
205
206struct vc4_dev *vc5_mock_device(struct kunit *test)
207{
208 return __mock_device(test, is_vc5: true);
209}
210

source code of linux/drivers/gpu/drm/vc4/tests/vc4_mock.c