1 // SPDX-License-Identifier: GPL-2.0
3 #include <drm/drm_atomic.h>
4 #include <drm/drm_atomic_helper.h>
5 #include <drm/drm_atomic_state_helper.h>
6 #include <drm/drm_atomic_uapi.h>
7 #include <drm/drm_crtc.h>
8 #include <drm/drm_drv.h>
9 #include <drm/drm_fourcc.h>
10 #include <drm/drm_kunit_helpers.h>
11 #include <drm/drm_mode.h>
12 #include <drm/drm_modeset_helper_vtables.h>
13 #include <drm/drm_plane.h>
15 #include <kunit/test.h>
17 #include "../vc4_drv.h"
21 struct pv_muxing_priv {
23 struct drm_atomic_state *state;
26 static bool check_fifo_conflict(struct kunit *test,
27 const struct drm_atomic_state *state)
29 struct vc4_hvs_state *hvs_state;
30 unsigned int used_fifos = 0;
33 hvs_state = vc4_hvs_get_new_global_state(state);
34 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hvs_state);
36 for (i = 0; i < HVS_NUM_CHANNELS; i++) {
37 if (!hvs_state->fifo_state[i].in_use)
40 KUNIT_EXPECT_FALSE(test, used_fifos & BIT(i));
47 struct encoder_constraint {
48 enum vc4_encoder_type type;
49 unsigned int *channels;
53 #define ENCODER_CONSTRAINT(_type, ...) \
56 .channels = (unsigned int[]) { __VA_ARGS__ }, \
57 .nchannels = sizeof((unsigned int[]) { __VA_ARGS__ }) / \
58 sizeof(unsigned int), \
61 static bool __check_encoder_constraints(const struct encoder_constraint *constraints,
63 enum vc4_encoder_type type,
68 for (i = 0; i < nconstraints; i++) {
69 const struct encoder_constraint *constraint = &constraints[i];
72 if (constraint->type != type)
75 for (j = 0; j < constraint->nchannels; j++) {
76 unsigned int _channel = constraint->channels[j];
78 if (channel != _channel)
88 static const struct encoder_constraint vc4_encoder_constraints[] = {
89 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_DPI, 0),
90 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_DSI0, 0),
91 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_HDMI0, 1),
92 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_VEC, 1),
93 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_TXP0, 2),
94 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_DSI1, 2),
97 static const struct encoder_constraint vc5_encoder_constraints[] = {
98 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_DPI, 0),
99 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_DSI0, 0),
100 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_VEC, 1),
101 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_TXP0, 0, 2),
102 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_DSI1, 0, 1, 2),
103 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_HDMI0, 0, 1, 2),
104 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_HDMI1, 0, 1, 2),
107 static bool check_vc4_encoder_constraints(enum vc4_encoder_type type, unsigned int channel)
109 return __check_encoder_constraints(vc4_encoder_constraints,
110 ARRAY_SIZE(vc4_encoder_constraints),
114 static bool check_vc5_encoder_constraints(enum vc4_encoder_type type, unsigned int channel)
116 return __check_encoder_constraints(vc5_encoder_constraints,
117 ARRAY_SIZE(vc5_encoder_constraints),
121 static struct vc4_crtc_state *
122 get_vc4_crtc_state_for_encoder(struct kunit *test,
123 const struct drm_atomic_state *state,
124 enum vc4_encoder_type type)
126 struct drm_device *drm = state->dev;
127 struct drm_crtc_state *new_crtc_state;
128 struct drm_encoder *encoder;
129 struct drm_crtc *crtc;
131 encoder = vc4_find_encoder_by_type(drm, type);
132 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder);
134 crtc = vc4_find_crtc_for_encoder(test, encoder);
135 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc);
137 new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
141 return to_vc4_crtc_state(new_crtc_state);
144 static bool check_channel_for_encoder(struct kunit *test,
145 const struct drm_atomic_state *state,
146 enum vc4_encoder_type type,
147 bool (*check_fn)(enum vc4_encoder_type type, unsigned int channel))
149 struct vc4_crtc_state *new_vc4_crtc_state;
150 struct vc4_hvs_state *new_hvs_state;
151 unsigned int channel;
153 new_hvs_state = vc4_hvs_get_new_global_state(state);
154 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state);
156 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state, type);
157 KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state);
159 channel = new_vc4_crtc_state->assigned_channel;
160 KUNIT_EXPECT_NE(test, channel, VC4_HVS_CHANNEL_DISABLED);
162 KUNIT_EXPECT_TRUE(test, new_hvs_state->fifo_state[channel].in_use);
164 KUNIT_EXPECT_TRUE(test, check_fn(type, channel));
169 struct pv_muxing_param {
171 struct vc4_dev *(*mock_fn)(struct kunit *test);
172 bool (*check_fn)(enum vc4_encoder_type type, unsigned int channel);
173 enum vc4_encoder_type *encoders;
177 static void vc4_test_pv_muxing_desc(const struct pv_muxing_param *t, char *desc)
179 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
182 #define PV_MUXING_TEST(_name, _mock_fn, _check_fn, ...) \
185 .mock_fn = &_mock_fn, \
186 .check_fn = &_check_fn, \
187 .encoders = (enum vc4_encoder_type[]) { __VA_ARGS__ }, \
188 .nencoders = sizeof((enum vc4_encoder_type[]) { __VA_ARGS__ }) / \
189 sizeof(enum vc4_encoder_type), \
192 #define VC4_PV_MUXING_TEST(_name, ...) \
193 PV_MUXING_TEST(_name, vc4_mock_device, check_vc4_encoder_constraints, __VA_ARGS__)
195 #define VC5_PV_MUXING_TEST(_name, ...) \
196 PV_MUXING_TEST(_name, vc5_mock_device, check_vc5_encoder_constraints, __VA_ARGS__)
198 static const struct pv_muxing_param vc4_test_pv_muxing_params[] = {
199 VC4_PV_MUXING_TEST("1 output: DSI0",
200 VC4_ENCODER_TYPE_DSI0),
201 VC4_PV_MUXING_TEST("1 output: DPI",
202 VC4_ENCODER_TYPE_DPI),
203 VC4_PV_MUXING_TEST("1 output: HDMI0",
204 VC4_ENCODER_TYPE_HDMI0),
205 VC4_PV_MUXING_TEST("1 output: VEC",
206 VC4_ENCODER_TYPE_VEC),
207 VC4_PV_MUXING_TEST("1 output: DSI1",
208 VC4_ENCODER_TYPE_DSI1),
209 VC4_PV_MUXING_TEST("1 output: TXP",
210 VC4_ENCODER_TYPE_TXP0),
211 VC4_PV_MUXING_TEST("2 outputs: DSI0, HDMI0",
212 VC4_ENCODER_TYPE_DSI0,
213 VC4_ENCODER_TYPE_HDMI0),
214 VC4_PV_MUXING_TEST("2 outputs: DSI0, VEC",
215 VC4_ENCODER_TYPE_DSI0,
216 VC4_ENCODER_TYPE_VEC),
217 VC4_PV_MUXING_TEST("2 outputs: DSI0, DSI1",
218 VC4_ENCODER_TYPE_DSI0,
219 VC4_ENCODER_TYPE_DSI1),
220 VC4_PV_MUXING_TEST("2 outputs: DSI0, TXP",
221 VC4_ENCODER_TYPE_DSI0,
222 VC4_ENCODER_TYPE_TXP0),
223 VC4_PV_MUXING_TEST("2 outputs: DPI, HDMI0",
224 VC4_ENCODER_TYPE_DPI,
225 VC4_ENCODER_TYPE_HDMI0),
226 VC4_PV_MUXING_TEST("2 outputs: DPI, VEC",
227 VC4_ENCODER_TYPE_DPI,
228 VC4_ENCODER_TYPE_VEC),
229 VC4_PV_MUXING_TEST("2 outputs: DPI, DSI1",
230 VC4_ENCODER_TYPE_DPI,
231 VC4_ENCODER_TYPE_DSI1),
232 VC4_PV_MUXING_TEST("2 outputs: DPI, TXP",
233 VC4_ENCODER_TYPE_DPI,
234 VC4_ENCODER_TYPE_TXP0),
235 VC4_PV_MUXING_TEST("2 outputs: HDMI0, DSI1",
236 VC4_ENCODER_TYPE_HDMI0,
237 VC4_ENCODER_TYPE_DSI1),
238 VC4_PV_MUXING_TEST("2 outputs: HDMI0, TXP",
239 VC4_ENCODER_TYPE_HDMI0,
240 VC4_ENCODER_TYPE_TXP0),
241 VC4_PV_MUXING_TEST("2 outputs: VEC, DSI1",
242 VC4_ENCODER_TYPE_VEC,
243 VC4_ENCODER_TYPE_DSI1),
244 VC4_PV_MUXING_TEST("2 outputs: VEC, TXP",
245 VC4_ENCODER_TYPE_VEC,
246 VC4_ENCODER_TYPE_TXP0),
247 VC4_PV_MUXING_TEST("3 outputs: DSI0, HDMI0, DSI1",
248 VC4_ENCODER_TYPE_DSI0,
249 VC4_ENCODER_TYPE_HDMI0,
250 VC4_ENCODER_TYPE_DSI1),
251 VC4_PV_MUXING_TEST("3 outputs: DSI0, HDMI0, TXP",
252 VC4_ENCODER_TYPE_DSI0,
253 VC4_ENCODER_TYPE_HDMI0,
254 VC4_ENCODER_TYPE_TXP0),
255 VC4_PV_MUXING_TEST("3 outputs: DSI0, VEC, DSI1",
256 VC4_ENCODER_TYPE_DSI0,
257 VC4_ENCODER_TYPE_VEC,
258 VC4_ENCODER_TYPE_DSI1),
259 VC4_PV_MUXING_TEST("3 outputs: DSI0, VEC, TXP",
260 VC4_ENCODER_TYPE_DSI0,
261 VC4_ENCODER_TYPE_VEC,
262 VC4_ENCODER_TYPE_TXP0),
263 VC4_PV_MUXING_TEST("3 outputs: DPI, HDMI0, DSI1",
264 VC4_ENCODER_TYPE_DPI,
265 VC4_ENCODER_TYPE_HDMI0,
266 VC4_ENCODER_TYPE_DSI1),
267 VC4_PV_MUXING_TEST("3 outputs: DPI, HDMI0, TXP",
268 VC4_ENCODER_TYPE_DPI,
269 VC4_ENCODER_TYPE_HDMI0,
270 VC4_ENCODER_TYPE_TXP0),
271 VC4_PV_MUXING_TEST("3 outputs: DPI, VEC, DSI1",
272 VC4_ENCODER_TYPE_DPI,
273 VC4_ENCODER_TYPE_VEC,
274 VC4_ENCODER_TYPE_DSI1),
275 VC4_PV_MUXING_TEST("3 outputs: DPI, VEC, TXP",
276 VC4_ENCODER_TYPE_DPI,
277 VC4_ENCODER_TYPE_VEC,
278 VC4_ENCODER_TYPE_TXP0),
281 KUNIT_ARRAY_PARAM(vc4_test_pv_muxing,
282 vc4_test_pv_muxing_params,
283 vc4_test_pv_muxing_desc);
285 static const struct pv_muxing_param vc4_test_pv_muxing_invalid_params[] = {
286 VC4_PV_MUXING_TEST("DPI/DSI0 Conflict",
287 VC4_ENCODER_TYPE_DPI,
288 VC4_ENCODER_TYPE_DSI0),
289 VC4_PV_MUXING_TEST("TXP/DSI1 Conflict",
290 VC4_ENCODER_TYPE_TXP0,
291 VC4_ENCODER_TYPE_DSI1),
292 VC4_PV_MUXING_TEST("HDMI0/VEC Conflict",
293 VC4_ENCODER_TYPE_HDMI0,
294 VC4_ENCODER_TYPE_VEC),
295 VC4_PV_MUXING_TEST("More than 3 outputs: DSI0, HDMI0, DSI1, TXP",
296 VC4_ENCODER_TYPE_DSI0,
297 VC4_ENCODER_TYPE_HDMI0,
298 VC4_ENCODER_TYPE_DSI1,
299 VC4_ENCODER_TYPE_TXP0),
300 VC4_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, DSI1, TXP",
301 VC4_ENCODER_TYPE_DSI0,
302 VC4_ENCODER_TYPE_VEC,
303 VC4_ENCODER_TYPE_DSI1,
304 VC4_ENCODER_TYPE_TXP0),
305 VC4_PV_MUXING_TEST("More than 3 outputs: DPI, HDMI0, DSI1, TXP",
306 VC4_ENCODER_TYPE_DPI,
307 VC4_ENCODER_TYPE_HDMI0,
308 VC4_ENCODER_TYPE_DSI1,
309 VC4_ENCODER_TYPE_TXP0),
310 VC4_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, DSI1, TXP",
311 VC4_ENCODER_TYPE_DPI,
312 VC4_ENCODER_TYPE_VEC,
313 VC4_ENCODER_TYPE_DSI1,
314 VC4_ENCODER_TYPE_TXP0),
317 KUNIT_ARRAY_PARAM(vc4_test_pv_muxing_invalid,
318 vc4_test_pv_muxing_invalid_params,
319 vc4_test_pv_muxing_desc);
321 static const struct pv_muxing_param vc5_test_pv_muxing_params[] = {
322 VC5_PV_MUXING_TEST("1 output: DPI",
323 VC4_ENCODER_TYPE_DPI),
324 VC5_PV_MUXING_TEST("1 output: DSI0",
325 VC4_ENCODER_TYPE_DSI0),
326 VC5_PV_MUXING_TEST("1 output: DSI1",
327 VC4_ENCODER_TYPE_DSI1),
328 VC5_PV_MUXING_TEST("1 output: HDMI0",
329 VC4_ENCODER_TYPE_HDMI0),
330 VC5_PV_MUXING_TEST("1 output: HDMI1",
331 VC4_ENCODER_TYPE_HDMI1),
332 VC5_PV_MUXING_TEST("1 output: VEC",
333 VC4_ENCODER_TYPE_VEC),
334 VC5_PV_MUXING_TEST("2 outputs: DPI, DSI1",
335 VC4_ENCODER_TYPE_DPI,
336 VC4_ENCODER_TYPE_DSI1),
337 VC5_PV_MUXING_TEST("2 outputs: DPI, HDMI0",
338 VC4_ENCODER_TYPE_DPI,
339 VC4_ENCODER_TYPE_HDMI0),
340 VC5_PV_MUXING_TEST("2 outputs: DPI, HDMI1",
341 VC4_ENCODER_TYPE_DPI,
342 VC4_ENCODER_TYPE_HDMI1),
343 VC5_PV_MUXING_TEST("2 outputs: DPI, TXP",
344 VC4_ENCODER_TYPE_DPI,
345 VC4_ENCODER_TYPE_TXP0),
346 VC5_PV_MUXING_TEST("2 outputs: DPI, VEC",
347 VC4_ENCODER_TYPE_DPI,
348 VC4_ENCODER_TYPE_VEC),
349 VC5_PV_MUXING_TEST("2 outputs: DPI, DSI1",
350 VC4_ENCODER_TYPE_DPI,
351 VC4_ENCODER_TYPE_DSI1),
352 VC5_PV_MUXING_TEST("2 outputs: DSI0, DSI1",
353 VC4_ENCODER_TYPE_DSI0,
354 VC4_ENCODER_TYPE_DSI1),
355 VC5_PV_MUXING_TEST("2 outputs: DSI0, HDMI0",
356 VC4_ENCODER_TYPE_DSI0,
357 VC4_ENCODER_TYPE_HDMI0),
358 VC5_PV_MUXING_TEST("2 outputs: DSI0, HDMI1",
359 VC4_ENCODER_TYPE_DSI0,
360 VC4_ENCODER_TYPE_HDMI1),
361 VC5_PV_MUXING_TEST("2 outputs: DSI0, TXP",
362 VC4_ENCODER_TYPE_DSI0,
363 VC4_ENCODER_TYPE_TXP0),
364 VC5_PV_MUXING_TEST("2 outputs: DSI0, VEC",
365 VC4_ENCODER_TYPE_DSI0,
366 VC4_ENCODER_TYPE_VEC),
367 VC5_PV_MUXING_TEST("2 outputs: DSI0, DSI1",
368 VC4_ENCODER_TYPE_DSI0,
369 VC4_ENCODER_TYPE_DSI1),
370 VC5_PV_MUXING_TEST("2 outputs: DSI1, VEC",
371 VC4_ENCODER_TYPE_DSI1,
372 VC4_ENCODER_TYPE_VEC),
373 VC5_PV_MUXING_TEST("2 outputs: DSI1, TXP",
374 VC4_ENCODER_TYPE_DSI1,
375 VC4_ENCODER_TYPE_TXP0),
376 VC5_PV_MUXING_TEST("2 outputs: DSI1, HDMI0",
377 VC4_ENCODER_TYPE_DSI1,
378 VC4_ENCODER_TYPE_HDMI0),
379 VC5_PV_MUXING_TEST("2 outputs: DSI1, HDMI1",
380 VC4_ENCODER_TYPE_DSI1,
381 VC4_ENCODER_TYPE_HDMI1),
382 VC5_PV_MUXING_TEST("2 outputs: HDMI0, VEC",
383 VC4_ENCODER_TYPE_HDMI0,
384 VC4_ENCODER_TYPE_VEC),
385 VC5_PV_MUXING_TEST("2 outputs: HDMI0, TXP",
386 VC4_ENCODER_TYPE_HDMI0,
387 VC4_ENCODER_TYPE_TXP0),
388 VC5_PV_MUXING_TEST("2 outputs: HDMI0, HDMI1",
389 VC4_ENCODER_TYPE_HDMI0,
390 VC4_ENCODER_TYPE_HDMI1),
391 VC5_PV_MUXING_TEST("2 outputs: HDMI1, VEC",
392 VC4_ENCODER_TYPE_HDMI1,
393 VC4_ENCODER_TYPE_VEC),
394 VC5_PV_MUXING_TEST("2 outputs: HDMI1, TXP",
395 VC4_ENCODER_TYPE_HDMI1,
396 VC4_ENCODER_TYPE_TXP0),
397 VC5_PV_MUXING_TEST("2 outputs: TXP, VEC",
398 VC4_ENCODER_TYPE_TXP0,
399 VC4_ENCODER_TYPE_VEC),
400 VC5_PV_MUXING_TEST("3 outputs: DPI, VEC, TXP",
401 VC4_ENCODER_TYPE_DPI,
402 VC4_ENCODER_TYPE_VEC,
403 VC4_ENCODER_TYPE_TXP0),
404 VC5_PV_MUXING_TEST("3 outputs: DPI, VEC, DSI1",
405 VC4_ENCODER_TYPE_DPI,
406 VC4_ENCODER_TYPE_VEC,
407 VC4_ENCODER_TYPE_DSI1),
408 VC5_PV_MUXING_TEST("3 outputs: DPI, VEC, HDMI0",
409 VC4_ENCODER_TYPE_DPI,
410 VC4_ENCODER_TYPE_VEC,
411 VC4_ENCODER_TYPE_HDMI0),
412 VC5_PV_MUXING_TEST("3 outputs: DPI, VEC, HDMI1",
413 VC4_ENCODER_TYPE_DPI,
414 VC4_ENCODER_TYPE_VEC,
415 VC4_ENCODER_TYPE_HDMI1),
416 VC5_PV_MUXING_TEST("3 outputs: DPI, TXP, DSI1",
417 VC4_ENCODER_TYPE_DPI,
418 VC4_ENCODER_TYPE_TXP0,
419 VC4_ENCODER_TYPE_DSI1),
420 VC5_PV_MUXING_TEST("3 outputs: DPI, TXP, HDMI0",
421 VC4_ENCODER_TYPE_DPI,
422 VC4_ENCODER_TYPE_TXP0,
423 VC4_ENCODER_TYPE_HDMI0),
424 VC5_PV_MUXING_TEST("3 outputs: DPI, TXP, HDMI1",
425 VC4_ENCODER_TYPE_DPI,
426 VC4_ENCODER_TYPE_TXP0,
427 VC4_ENCODER_TYPE_HDMI1),
428 VC5_PV_MUXING_TEST("3 outputs: DPI, DSI1, HDMI0",
429 VC4_ENCODER_TYPE_DPI,
430 VC4_ENCODER_TYPE_DSI1,
431 VC4_ENCODER_TYPE_HDMI0),
432 VC5_PV_MUXING_TEST("3 outputs: DPI, DSI1, HDMI1",
433 VC4_ENCODER_TYPE_DPI,
434 VC4_ENCODER_TYPE_DSI1,
435 VC4_ENCODER_TYPE_HDMI1),
436 VC5_PV_MUXING_TEST("3 outputs: DPI, HDMI0, HDMI1",
437 VC4_ENCODER_TYPE_DPI,
438 VC4_ENCODER_TYPE_HDMI0,
439 VC4_ENCODER_TYPE_HDMI1),
440 VC5_PV_MUXING_TEST("3 outputs: DSI0, VEC, TXP",
441 VC4_ENCODER_TYPE_DSI0,
442 VC4_ENCODER_TYPE_VEC,
443 VC4_ENCODER_TYPE_TXP0),
444 VC5_PV_MUXING_TEST("3 outputs: DSI0, VEC, DSI1",
445 VC4_ENCODER_TYPE_DSI0,
446 VC4_ENCODER_TYPE_VEC,
447 VC4_ENCODER_TYPE_DSI1),
448 VC5_PV_MUXING_TEST("3 outputs: DSI0, VEC, HDMI0",
449 VC4_ENCODER_TYPE_DSI0,
450 VC4_ENCODER_TYPE_VEC,
451 VC4_ENCODER_TYPE_HDMI0),
452 VC5_PV_MUXING_TEST("3 outputs: DSI0, VEC, HDMI1",
453 VC4_ENCODER_TYPE_DSI0,
454 VC4_ENCODER_TYPE_VEC,
455 VC4_ENCODER_TYPE_HDMI1),
456 VC5_PV_MUXING_TEST("3 outputs: DSI0, TXP, DSI1",
457 VC4_ENCODER_TYPE_DSI0,
458 VC4_ENCODER_TYPE_TXP0,
459 VC4_ENCODER_TYPE_DSI1),
460 VC5_PV_MUXING_TEST("3 outputs: DSI0, TXP, HDMI0",
461 VC4_ENCODER_TYPE_DSI0,
462 VC4_ENCODER_TYPE_TXP0,
463 VC4_ENCODER_TYPE_HDMI0),
464 VC5_PV_MUXING_TEST("3 outputs: DSI0, TXP, HDMI1",
465 VC4_ENCODER_TYPE_DSI0,
466 VC4_ENCODER_TYPE_TXP0,
467 VC4_ENCODER_TYPE_HDMI1),
468 VC5_PV_MUXING_TEST("3 outputs: DSI0, DSI1, HDMI0",
469 VC4_ENCODER_TYPE_DSI0,
470 VC4_ENCODER_TYPE_DSI1,
471 VC4_ENCODER_TYPE_HDMI0),
472 VC5_PV_MUXING_TEST("3 outputs: DSI0, DSI1, HDMI1",
473 VC4_ENCODER_TYPE_DSI0,
474 VC4_ENCODER_TYPE_DSI1,
475 VC4_ENCODER_TYPE_HDMI1),
476 VC5_PV_MUXING_TEST("3 outputs: DSI0, HDMI0, HDMI1",
477 VC4_ENCODER_TYPE_DSI0,
478 VC4_ENCODER_TYPE_HDMI0,
479 VC4_ENCODER_TYPE_HDMI1),
482 KUNIT_ARRAY_PARAM(vc5_test_pv_muxing,
483 vc5_test_pv_muxing_params,
484 vc4_test_pv_muxing_desc);
486 static const struct pv_muxing_param vc5_test_pv_muxing_invalid_params[] = {
487 VC5_PV_MUXING_TEST("DPI/DSI0 Conflict",
488 VC4_ENCODER_TYPE_DPI,
489 VC4_ENCODER_TYPE_DSI0),
490 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, DSI1",
491 VC4_ENCODER_TYPE_DPI,
492 VC4_ENCODER_TYPE_VEC,
493 VC4_ENCODER_TYPE_TXP0,
494 VC4_ENCODER_TYPE_DSI1),
495 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, HDMI0",
496 VC4_ENCODER_TYPE_DPI,
497 VC4_ENCODER_TYPE_VEC,
498 VC4_ENCODER_TYPE_TXP0,
499 VC4_ENCODER_TYPE_HDMI0),
500 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, HDMI1",
501 VC4_ENCODER_TYPE_DPI,
502 VC4_ENCODER_TYPE_VEC,
503 VC4_ENCODER_TYPE_TXP0,
504 VC4_ENCODER_TYPE_HDMI1),
505 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, DSI1, HDMI0",
506 VC4_ENCODER_TYPE_DPI,
507 VC4_ENCODER_TYPE_VEC,
508 VC4_ENCODER_TYPE_DSI1,
509 VC4_ENCODER_TYPE_HDMI0),
510 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, DSI1, HDMI1",
511 VC4_ENCODER_TYPE_DPI,
512 VC4_ENCODER_TYPE_VEC,
513 VC4_ENCODER_TYPE_DSI1,
514 VC4_ENCODER_TYPE_HDMI1),
515 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, HDMI0, HDMI1",
516 VC4_ENCODER_TYPE_DPI,
517 VC4_ENCODER_TYPE_VEC,
518 VC4_ENCODER_TYPE_HDMI0,
519 VC4_ENCODER_TYPE_HDMI1),
520 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, TXP, DSI1, HDMI0",
521 VC4_ENCODER_TYPE_DPI,
522 VC4_ENCODER_TYPE_TXP0,
523 VC4_ENCODER_TYPE_DSI1,
524 VC4_ENCODER_TYPE_HDMI0),
525 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, TXP, DSI1, HDMI1",
526 VC4_ENCODER_TYPE_DPI,
527 VC4_ENCODER_TYPE_TXP0,
528 VC4_ENCODER_TYPE_DSI1,
529 VC4_ENCODER_TYPE_HDMI1),
530 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, TXP, HDMI0, HDMI1",
531 VC4_ENCODER_TYPE_DPI,
532 VC4_ENCODER_TYPE_TXP0,
533 VC4_ENCODER_TYPE_HDMI0,
534 VC4_ENCODER_TYPE_HDMI1),
535 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, DSI1, HDMI0, HDMI1",
536 VC4_ENCODER_TYPE_DPI,
537 VC4_ENCODER_TYPE_DSI1,
538 VC4_ENCODER_TYPE_HDMI0,
539 VC4_ENCODER_TYPE_HDMI1),
540 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, DSI1, HDMI0",
541 VC4_ENCODER_TYPE_DPI,
542 VC4_ENCODER_TYPE_VEC,
543 VC4_ENCODER_TYPE_TXP0,
544 VC4_ENCODER_TYPE_DSI1,
545 VC4_ENCODER_TYPE_HDMI0),
546 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, DSI1, HDMI1",
547 VC4_ENCODER_TYPE_DPI,
548 VC4_ENCODER_TYPE_VEC,
549 VC4_ENCODER_TYPE_TXP0,
550 VC4_ENCODER_TYPE_DSI1,
551 VC4_ENCODER_TYPE_HDMI1),
552 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, HDMI0, HDMI1",
553 VC4_ENCODER_TYPE_DPI,
554 VC4_ENCODER_TYPE_VEC,
555 VC4_ENCODER_TYPE_TXP0,
556 VC4_ENCODER_TYPE_HDMI0,
557 VC4_ENCODER_TYPE_HDMI1),
558 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, DSI1, HDMI0, HDMI1",
559 VC4_ENCODER_TYPE_DPI,
560 VC4_ENCODER_TYPE_VEC,
561 VC4_ENCODER_TYPE_DSI1,
562 VC4_ENCODER_TYPE_HDMI0,
563 VC4_ENCODER_TYPE_HDMI1),
564 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, TXP, DSI1, HDMI0, HDMI1",
565 VC4_ENCODER_TYPE_DPI,
566 VC4_ENCODER_TYPE_TXP0,
567 VC4_ENCODER_TYPE_DSI1,
568 VC4_ENCODER_TYPE_HDMI0,
569 VC4_ENCODER_TYPE_HDMI1),
570 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, DSI1",
571 VC4_ENCODER_TYPE_DSI0,
572 VC4_ENCODER_TYPE_VEC,
573 VC4_ENCODER_TYPE_TXP0,
574 VC4_ENCODER_TYPE_DSI1),
575 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, HDMI0",
576 VC4_ENCODER_TYPE_DSI0,
577 VC4_ENCODER_TYPE_VEC,
578 VC4_ENCODER_TYPE_TXP0,
579 VC4_ENCODER_TYPE_HDMI0),
580 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, HDMI1",
581 VC4_ENCODER_TYPE_DSI0,
582 VC4_ENCODER_TYPE_VEC,
583 VC4_ENCODER_TYPE_TXP0,
584 VC4_ENCODER_TYPE_HDMI1),
585 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, DSI1, HDMI0",
586 VC4_ENCODER_TYPE_DSI0,
587 VC4_ENCODER_TYPE_VEC,
588 VC4_ENCODER_TYPE_DSI1,
589 VC4_ENCODER_TYPE_HDMI0),
590 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, DSI1, HDMI1",
591 VC4_ENCODER_TYPE_DSI0,
592 VC4_ENCODER_TYPE_VEC,
593 VC4_ENCODER_TYPE_DSI1,
594 VC4_ENCODER_TYPE_HDMI1),
595 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, HDMI0, HDMI1",
596 VC4_ENCODER_TYPE_DSI0,
597 VC4_ENCODER_TYPE_VEC,
598 VC4_ENCODER_TYPE_HDMI0,
599 VC4_ENCODER_TYPE_HDMI1),
600 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, TXP, DSI1, HDMI0",
601 VC4_ENCODER_TYPE_DSI0,
602 VC4_ENCODER_TYPE_TXP0,
603 VC4_ENCODER_TYPE_DSI1,
604 VC4_ENCODER_TYPE_HDMI0),
605 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, TXP, DSI1, HDMI1",
606 VC4_ENCODER_TYPE_DSI0,
607 VC4_ENCODER_TYPE_TXP0,
608 VC4_ENCODER_TYPE_DSI1,
609 VC4_ENCODER_TYPE_HDMI1),
610 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, TXP, HDMI0, HDMI1",
611 VC4_ENCODER_TYPE_DSI0,
612 VC4_ENCODER_TYPE_TXP0,
613 VC4_ENCODER_TYPE_HDMI0,
614 VC4_ENCODER_TYPE_HDMI1),
615 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, DSI1, HDMI0, HDMI1",
616 VC4_ENCODER_TYPE_DSI0,
617 VC4_ENCODER_TYPE_DSI1,
618 VC4_ENCODER_TYPE_HDMI0,
619 VC4_ENCODER_TYPE_HDMI1),
620 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, DSI1, HDMI0",
621 VC4_ENCODER_TYPE_DSI0,
622 VC4_ENCODER_TYPE_VEC,
623 VC4_ENCODER_TYPE_TXP0,
624 VC4_ENCODER_TYPE_DSI1,
625 VC4_ENCODER_TYPE_HDMI0),
626 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, DSI1, HDMI1",
627 VC4_ENCODER_TYPE_DSI0,
628 VC4_ENCODER_TYPE_VEC,
629 VC4_ENCODER_TYPE_TXP0,
630 VC4_ENCODER_TYPE_DSI1,
631 VC4_ENCODER_TYPE_HDMI1),
632 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, HDMI0, HDMI1",
633 VC4_ENCODER_TYPE_DSI0,
634 VC4_ENCODER_TYPE_VEC,
635 VC4_ENCODER_TYPE_TXP0,
636 VC4_ENCODER_TYPE_HDMI0,
637 VC4_ENCODER_TYPE_HDMI1),
638 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, DSI1, HDMI0, HDMI1",
639 VC4_ENCODER_TYPE_DSI0,
640 VC4_ENCODER_TYPE_VEC,
641 VC4_ENCODER_TYPE_DSI1,
642 VC4_ENCODER_TYPE_HDMI0,
643 VC4_ENCODER_TYPE_HDMI1),
644 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, TXP, DSI1, HDMI0, HDMI1",
645 VC4_ENCODER_TYPE_DSI0,
646 VC4_ENCODER_TYPE_TXP0,
647 VC4_ENCODER_TYPE_DSI1,
648 VC4_ENCODER_TYPE_HDMI0,
649 VC4_ENCODER_TYPE_HDMI1),
650 VC5_PV_MUXING_TEST("More than 3 outputs: VEC, TXP, DSI1, HDMI0, HDMI1",
651 VC4_ENCODER_TYPE_VEC,
652 VC4_ENCODER_TYPE_TXP0,
653 VC4_ENCODER_TYPE_DSI1,
654 VC4_ENCODER_TYPE_HDMI0,
655 VC4_ENCODER_TYPE_HDMI1),
656 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, DSI1, HDMI0, HDMI1",
657 VC4_ENCODER_TYPE_DPI,
658 VC4_ENCODER_TYPE_VEC,
659 VC4_ENCODER_TYPE_TXP0,
660 VC4_ENCODER_TYPE_DSI1,
661 VC4_ENCODER_TYPE_HDMI0,
662 VC4_ENCODER_TYPE_HDMI1),
663 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, DSI1, HDMI0, HDMI1",
664 VC4_ENCODER_TYPE_DSI0,
665 VC4_ENCODER_TYPE_VEC,
666 VC4_ENCODER_TYPE_TXP0,
667 VC4_ENCODER_TYPE_DSI1,
668 VC4_ENCODER_TYPE_HDMI0,
669 VC4_ENCODER_TYPE_HDMI1),
672 KUNIT_ARRAY_PARAM(vc5_test_pv_muxing_invalid,
673 vc5_test_pv_muxing_invalid_params,
674 vc4_test_pv_muxing_desc);
676 static void drm_vc4_test_pv_muxing(struct kunit *test)
678 const struct pv_muxing_param *params = test->param_value;
679 const struct pv_muxing_priv *priv = test->priv;
680 struct drm_atomic_state *state = priv->state;
684 for (i = 0; i < params->nencoders; i++) {
685 struct vc4_dummy_output *output;
686 enum vc4_encoder_type enc_type = params->encoders[i];
688 output = vc4_mock_atomic_add_output(test, state, enc_type);
689 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, output);
692 ret = drm_atomic_check_only(state);
693 KUNIT_EXPECT_EQ(test, ret, 0);
695 KUNIT_EXPECT_TRUE(test,
696 check_fifo_conflict(test, state));
698 for (i = 0; i < params->nencoders; i++) {
699 enum vc4_encoder_type enc_type = params->encoders[i];
701 KUNIT_EXPECT_TRUE(test, check_channel_for_encoder(test, state, enc_type,
706 static void drm_vc4_test_pv_muxing_invalid(struct kunit *test)
708 const struct pv_muxing_param *params = test->param_value;
709 const struct pv_muxing_priv *priv = test->priv;
710 struct drm_atomic_state *state = priv->state;
714 for (i = 0; i < params->nencoders; i++) {
715 struct vc4_dummy_output *output;
716 enum vc4_encoder_type enc_type = params->encoders[i];
718 output = vc4_mock_atomic_add_output(test, state, enc_type);
719 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, output);
722 ret = drm_atomic_check_only(state);
723 KUNIT_EXPECT_LT(test, ret, 0);
726 static int vc4_pv_muxing_test_init(struct kunit *test)
728 const struct pv_muxing_param *params = test->param_value;
729 struct drm_modeset_acquire_ctx *ctx;
730 struct pv_muxing_priv *priv;
731 struct drm_device *drm;
734 priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
735 KUNIT_ASSERT_NOT_NULL(test, priv);
738 vc4 = params->mock_fn(test);
739 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
742 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
743 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
746 priv->state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
747 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->state);
752 static struct kunit_case vc4_pv_muxing_tests[] = {
753 KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing,
754 vc4_test_pv_muxing_gen_params),
755 KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing_invalid,
756 vc4_test_pv_muxing_invalid_gen_params),
760 static struct kunit_suite vc4_pv_muxing_test_suite = {
761 .name = "vc4-pv-muxing-combinations",
762 .init = vc4_pv_muxing_test_init,
763 .test_cases = vc4_pv_muxing_tests,
766 static struct kunit_case vc5_pv_muxing_tests[] = {
767 KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing,
768 vc5_test_pv_muxing_gen_params),
769 KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing_invalid,
770 vc5_test_pv_muxing_invalid_gen_params),
774 static struct kunit_suite vc5_pv_muxing_test_suite = {
775 .name = "vc5-pv-muxing-combinations",
776 .init = vc4_pv_muxing_test_init,
777 .test_cases = vc5_pv_muxing_tests,
781 * https://lore.kernel.org/all/3e113525-aa89-b1e2-56b7-ca55bd41d057@samsung.com/
783 * https://lore.kernel.org/dri-devel/20200917121623.42023-1-maxime@cerno.tech/
785 static void drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable(struct kunit *test)
787 struct drm_modeset_acquire_ctx *ctx;
788 struct drm_atomic_state *state;
789 struct vc4_dummy_output *output;
790 struct vc4_crtc_state *new_vc4_crtc_state;
791 struct vc4_hvs_state *new_hvs_state;
792 unsigned int hdmi0_channel;
793 unsigned int hdmi1_channel;
794 struct drm_device *drm;
798 vc4 = vc5_mock_device(test);
799 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
801 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
802 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
805 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
806 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
808 output = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI0);
809 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, output);
811 ret = drm_atomic_check_only(state);
812 KUNIT_ASSERT_EQ(test, ret, 0);
814 new_hvs_state = vc4_hvs_get_new_global_state(state);
815 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state);
817 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
818 VC4_ENCODER_TYPE_HDMI0);
819 KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state);
821 hdmi0_channel = new_vc4_crtc_state->assigned_channel;
822 KUNIT_ASSERT_NE(test, hdmi0_channel, VC4_HVS_CHANNEL_DISABLED);
823 KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[hdmi0_channel].in_use);
825 ret = drm_atomic_helper_swap_state(state, false);
826 KUNIT_ASSERT_EQ(test, ret, 0);
828 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
829 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
831 output = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI1);
832 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, output);
834 ret = drm_atomic_check_only(state);
835 KUNIT_ASSERT_EQ(test, ret, 0);
837 new_hvs_state = vc4_hvs_get_new_global_state(state);
838 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state);
840 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
841 VC4_ENCODER_TYPE_HDMI1);
842 KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state);
844 hdmi1_channel = new_vc4_crtc_state->assigned_channel;
845 KUNIT_ASSERT_NE(test, hdmi1_channel, VC4_HVS_CHANNEL_DISABLED);
846 KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[hdmi1_channel].in_use);
848 KUNIT_EXPECT_NE(test, hdmi0_channel, hdmi1_channel);
852 * This test makes sure that we never change the FIFO of an active HVS
853 * channel if we disable a FIFO with a lower index.
855 * Doing so would result in a FIFO stall and would disrupt an output
856 * supposed to be unaffected by the commit.
858 static void drm_test_vc5_pv_muxing_bugs_stable_fifo(struct kunit *test)
860 struct drm_modeset_acquire_ctx *ctx;
861 struct drm_atomic_state *state;
862 struct vc4_dummy_output *output;
863 struct vc4_crtc_state *new_vc4_crtc_state;
864 struct vc4_hvs_state *new_hvs_state;
865 unsigned int old_hdmi0_channel;
866 unsigned int old_hdmi1_channel;
867 struct drm_device *drm;
871 vc4 = vc5_mock_device(test);
872 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
874 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
875 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
878 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
879 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
881 output = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI0);
882 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, output);
884 output = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI1);
885 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, output);
887 ret = drm_atomic_check_only(state);
888 KUNIT_ASSERT_EQ(test, ret, 0);
890 new_hvs_state = vc4_hvs_get_new_global_state(state);
891 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state);
893 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
894 VC4_ENCODER_TYPE_HDMI0);
895 KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state);
897 old_hdmi0_channel = new_vc4_crtc_state->assigned_channel;
898 KUNIT_ASSERT_NE(test, old_hdmi0_channel, VC4_HVS_CHANNEL_DISABLED);
899 KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[old_hdmi0_channel].in_use);
901 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
902 VC4_ENCODER_TYPE_HDMI1);
903 KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state);
905 old_hdmi1_channel = new_vc4_crtc_state->assigned_channel;
906 KUNIT_ASSERT_NE(test, old_hdmi1_channel, VC4_HVS_CHANNEL_DISABLED);
907 KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[old_hdmi1_channel].in_use);
909 ret = drm_atomic_helper_swap_state(state, false);
910 KUNIT_ASSERT_EQ(test, ret, 0);
912 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
913 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
915 ret = vc4_mock_atomic_del_output(test, state, VC4_ENCODER_TYPE_HDMI0);
916 KUNIT_ASSERT_EQ(test, ret, 0);
918 ret = drm_atomic_check_only(state);
919 KUNIT_ASSERT_EQ(test, ret, 0);
921 new_hvs_state = vc4_hvs_get_new_global_state(state);
922 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state);
924 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
925 VC4_ENCODER_TYPE_HDMI1);
927 if (new_vc4_crtc_state) {
928 unsigned int hdmi1_channel;
930 hdmi1_channel = new_vc4_crtc_state->assigned_channel;
931 KUNIT_ASSERT_NE(test, hdmi1_channel, VC4_HVS_CHANNEL_DISABLED);
932 KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[hdmi1_channel].in_use);
934 KUNIT_EXPECT_EQ(test, old_hdmi1_channel, hdmi1_channel);
939 * Test that if we affect a single output, only the CRTC state of that
940 * output will be pulled in the global atomic state.
942 * This is relevant for two things:
944 * - If we don't have that state at all, we are unlikely to affect the
945 * FIFO muxing. This is somewhat redundant with
946 * drm_test_vc5_pv_muxing_bugs_stable_fifo()
948 * - KMS waits for page flips to occur on all the CRTC found in the
949 * CRTC state. Since the CRTC is unaffected, we would over-wait, but
950 * most importantly run into corner cases like waiting on an
951 * inactive CRTC that never completes.
954 drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable_too_many_crtc_state(struct kunit *test)
956 struct drm_modeset_acquire_ctx *ctx;
957 struct drm_atomic_state *state;
958 struct vc4_dummy_output *output;
959 struct vc4_crtc_state *new_vc4_crtc_state;
960 struct drm_device *drm;
964 vc4 = vc5_mock_device(test);
965 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
967 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
968 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
971 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
972 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
974 output = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI0);
975 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, output);
977 ret = drm_atomic_check_only(state);
978 KUNIT_ASSERT_EQ(test, ret, 0);
980 ret = drm_atomic_helper_swap_state(state, false);
981 KUNIT_ASSERT_EQ(test, ret, 0);
983 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
984 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
986 output = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI1);
987 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, output);
989 ret = drm_atomic_check_only(state);
990 KUNIT_ASSERT_EQ(test, ret, 0);
992 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
993 VC4_ENCODER_TYPE_HDMI0);
994 KUNIT_EXPECT_NULL(test, new_vc4_crtc_state);
997 static struct kunit_case vc5_pv_muxing_bugs_tests[] = {
998 KUNIT_CASE(drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable),
999 KUNIT_CASE(drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable_too_many_crtc_state),
1000 KUNIT_CASE(drm_test_vc5_pv_muxing_bugs_stable_fifo),
1004 static struct kunit_suite vc5_pv_muxing_bugs_test_suite = {
1005 .name = "vc5-pv-muxing-bugs",
1006 .test_cases = vc5_pv_muxing_bugs_tests,
1010 &vc4_pv_muxing_test_suite,
1011 &vc5_pv_muxing_test_suite,
1012 &vc5_pv_muxing_bugs_test_suite