xref: /linux/drivers/gpu/drm/vc4/tests/vc4_mock.c (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
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 
10 struct 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 
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;
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 
40 struct 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 
52 static 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 
78 static 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 
__build_one_pipe(struct kunit * test,struct drm_device * drm,const struct vc4_mock_pipe_desc * pipe)109 static int __build_one_pipe(struct kunit *test, struct drm_device *drm,
110 			    const struct vc4_mock_pipe_desc *pipe)
111 {
112 	struct drm_plane *plane;
113 	struct vc4_dummy_crtc *dummy_crtc;
114 	struct drm_crtc *crtc;
115 	unsigned int i;
116 
117 	plane = vc4_dummy_plane(test, drm, DRM_PLANE_TYPE_PRIMARY);
118 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane);
119 
120 	dummy_crtc = vc4_mock_pv(test, drm, plane, pipe->data);
121 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_crtc);
122 
123 	crtc = &dummy_crtc->crtc.base;
124 	for (i = 0; i < pipe->noutputs; i++) {
125 		const struct vc4_mock_output_desc *mock_output = &pipe->outputs[i];
126 		struct vc4_dummy_output *dummy_output;
127 
128 		dummy_output = vc4_dummy_output(test, drm, crtc,
129 						mock_output->vc4_encoder_type,
130 						mock_output->encoder_type,
131 						mock_output->connector_type);
132 		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dummy_output);
133 	}
134 
135 	return 0;
136 }
137 
__build_mock(struct kunit * test,struct drm_device * drm,const struct vc4_mock_desc * mock)138 static int __build_mock(struct kunit *test, struct drm_device *drm,
139 			const struct vc4_mock_desc *mock)
140 {
141 	unsigned int i;
142 
143 	for (i = 0; i < mock->npipes; i++) {
144 		const struct vc4_mock_pipe_desc *pipe = &mock->pipes[i];
145 		int ret;
146 
147 		ret = __build_one_pipe(test, drm, pipe);
148 		KUNIT_ASSERT_EQ(test, ret, 0);
149 	}
150 
151 	return 0;
152 }
153 
154 KUNIT_DEFINE_ACTION_WRAPPER(kunit_action_drm_dev_unregister,
155 			    drm_dev_unregister,
156 			    struct drm_device *);
157 
__mock_device(struct kunit * test,bool is_vc5)158 static struct vc4_dev *__mock_device(struct kunit *test, bool is_vc5)
159 {
160 	struct drm_device *drm;
161 	const struct drm_driver *drv = is_vc5 ? &vc5_drm_driver : &vc4_drm_driver;
162 	const struct vc4_mock_desc *desc = is_vc5 ? &vc5_mock : &vc4_mock;
163 	struct vc4_dev *vc4;
164 	struct device *dev;
165 	int ret;
166 
167 	dev = drm_kunit_helper_alloc_device(test);
168 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
169 
170 	vc4 = drm_kunit_helper_alloc_drm_device_with_driver(test, dev,
171 							    struct vc4_dev, base,
172 							    drv);
173 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
174 
175 	vc4->dev = dev;
176 	vc4->is_vc5 = is_vc5;
177 
178 	vc4->hvs = __vc4_hvs_alloc(vc4, NULL);
179 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4->hvs);
180 
181 	drm = &vc4->base;
182 	ret = __build_mock(test, drm, desc);
183 	KUNIT_ASSERT_EQ(test, ret, 0);
184 
185 	ret = vc4_kms_load(drm);
186 	KUNIT_ASSERT_EQ(test, ret, 0);
187 
188 	ret = drm_dev_register(drm, 0);
189 	KUNIT_ASSERT_EQ(test, ret, 0);
190 
191 	ret = kunit_add_action_or_reset(test,
192 					kunit_action_drm_dev_unregister,
193 					drm);
194 	KUNIT_ASSERT_EQ(test, ret, 0);
195 
196 	return vc4;
197 }
198 
vc4_mock_device(struct kunit * test)199 struct vc4_dev *vc4_mock_device(struct kunit *test)
200 {
201 	return __mock_device(test, false);
202 }
203 
vc5_mock_device(struct kunit * test)204 struct vc4_dev *vc5_mock_device(struct kunit *test)
205 {
206 	return __mock_device(test, true);
207 }
208