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 const struct encoder_constraint vc6_encoder_constraints[] = {
108 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_HDMI0, 0),
109 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_HDMI1, 1),
110 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_TXP1, 1),
111 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_TXP0, 2),
114 static bool check_vc4_encoder_constraints(enum vc4_encoder_type type, unsigned int channel)
116 return __check_encoder_constraints(vc4_encoder_constraints,
117 ARRAY_SIZE(vc4_encoder_constraints),
121 static bool check_vc5_encoder_constraints(enum vc4_encoder_type type, unsigned int channel)
123 return __check_encoder_constraints(vc5_encoder_constraints,
124 ARRAY_SIZE(vc5_encoder_constraints),
128 static bool check_vc6_encoder_constraints(enum vc4_encoder_type type, unsigned int channel)
130 return __check_encoder_constraints(vc6_encoder_constraints,
131 ARRAY_SIZE(vc6_encoder_constraints),
135 static struct vc4_crtc_state *
136 get_vc4_crtc_state_for_encoder(struct kunit *test,
137 const struct drm_atomic_state *state,
138 enum vc4_encoder_type type)
140 struct drm_device *drm = state->dev;
141 struct drm_crtc_state *new_crtc_state;
142 struct drm_encoder *encoder;
143 struct drm_crtc *crtc;
145 encoder = vc4_find_encoder_by_type(drm, type);
146 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder);
148 crtc = vc4_find_crtc_for_encoder(test, encoder);
149 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc);
151 new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
155 return to_vc4_crtc_state(new_crtc_state);
158 static bool check_channel_for_encoder(struct kunit *test,
159 const struct drm_atomic_state *state,
160 enum vc4_encoder_type type,
161 bool (*check_fn)(enum vc4_encoder_type type, unsigned int channel))
163 struct vc4_crtc_state *new_vc4_crtc_state;
164 struct vc4_hvs_state *new_hvs_state;
165 unsigned int channel;
167 new_hvs_state = vc4_hvs_get_new_global_state(state);
168 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state);
170 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state, type);
171 KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state);
173 channel = new_vc4_crtc_state->assigned_channel;
174 KUNIT_EXPECT_NE(test, channel, VC4_HVS_CHANNEL_DISABLED);
176 KUNIT_EXPECT_TRUE(test, new_hvs_state->fifo_state[channel].in_use);
178 KUNIT_EXPECT_TRUE(test, check_fn(type, channel));
183 struct pv_muxing_param {
185 struct vc4_dev *(*mock_fn)(struct kunit *test);
186 bool (*check_fn)(enum vc4_encoder_type type, unsigned int channel);
187 enum vc4_encoder_type *encoders;
191 static void vc4_test_pv_muxing_desc(const struct pv_muxing_param *t, char *desc)
193 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
196 #define PV_MUXING_TEST(_name, _mock_fn, _check_fn, ...) \
199 .mock_fn = &_mock_fn, \
200 .check_fn = &_check_fn, \
201 .encoders = (enum vc4_encoder_type[]) { __VA_ARGS__ }, \
202 .nencoders = sizeof((enum vc4_encoder_type[]) { __VA_ARGS__ }) / \
203 sizeof(enum vc4_encoder_type), \
206 #define VC4_PV_MUXING_TEST(_name, ...) \
207 PV_MUXING_TEST(_name, vc4_mock_device, check_vc4_encoder_constraints, __VA_ARGS__)
209 #define VC5_PV_MUXING_TEST(_name, ...) \
210 PV_MUXING_TEST(_name, vc5_mock_device, check_vc5_encoder_constraints, __VA_ARGS__)
212 #define VC6_PV_MUXING_TEST(_name, ...) \
213 PV_MUXING_TEST(_name, vc6_mock_device, check_vc6_encoder_constraints, __VA_ARGS__)
215 static const struct pv_muxing_param vc4_test_pv_muxing_params[] = {
216 VC4_PV_MUXING_TEST("1 output: DSI0",
217 VC4_ENCODER_TYPE_DSI0),
218 VC4_PV_MUXING_TEST("1 output: DPI",
219 VC4_ENCODER_TYPE_DPI),
220 VC4_PV_MUXING_TEST("1 output: HDMI0",
221 VC4_ENCODER_TYPE_HDMI0),
222 VC4_PV_MUXING_TEST("1 output: VEC",
223 VC4_ENCODER_TYPE_VEC),
224 VC4_PV_MUXING_TEST("1 output: DSI1",
225 VC4_ENCODER_TYPE_DSI1),
226 VC4_PV_MUXING_TEST("1 output: TXP",
227 VC4_ENCODER_TYPE_TXP0),
228 VC4_PV_MUXING_TEST("2 outputs: DSI0, HDMI0",
229 VC4_ENCODER_TYPE_DSI0,
230 VC4_ENCODER_TYPE_HDMI0),
231 VC4_PV_MUXING_TEST("2 outputs: DSI0, VEC",
232 VC4_ENCODER_TYPE_DSI0,
233 VC4_ENCODER_TYPE_VEC),
234 VC4_PV_MUXING_TEST("2 outputs: DSI0, DSI1",
235 VC4_ENCODER_TYPE_DSI0,
236 VC4_ENCODER_TYPE_DSI1),
237 VC4_PV_MUXING_TEST("2 outputs: DSI0, TXP",
238 VC4_ENCODER_TYPE_DSI0,
239 VC4_ENCODER_TYPE_TXP0),
240 VC4_PV_MUXING_TEST("2 outputs: DPI, HDMI0",
241 VC4_ENCODER_TYPE_DPI,
242 VC4_ENCODER_TYPE_HDMI0),
243 VC4_PV_MUXING_TEST("2 outputs: DPI, VEC",
244 VC4_ENCODER_TYPE_DPI,
245 VC4_ENCODER_TYPE_VEC),
246 VC4_PV_MUXING_TEST("2 outputs: DPI, DSI1",
247 VC4_ENCODER_TYPE_DPI,
248 VC4_ENCODER_TYPE_DSI1),
249 VC4_PV_MUXING_TEST("2 outputs: DPI, TXP",
250 VC4_ENCODER_TYPE_DPI,
251 VC4_ENCODER_TYPE_TXP0),
252 VC4_PV_MUXING_TEST("2 outputs: HDMI0, DSI1",
253 VC4_ENCODER_TYPE_HDMI0,
254 VC4_ENCODER_TYPE_DSI1),
255 VC4_PV_MUXING_TEST("2 outputs: HDMI0, TXP",
256 VC4_ENCODER_TYPE_HDMI0,
257 VC4_ENCODER_TYPE_TXP0),
258 VC4_PV_MUXING_TEST("2 outputs: VEC, DSI1",
259 VC4_ENCODER_TYPE_VEC,
260 VC4_ENCODER_TYPE_DSI1),
261 VC4_PV_MUXING_TEST("2 outputs: VEC, TXP",
262 VC4_ENCODER_TYPE_VEC,
263 VC4_ENCODER_TYPE_TXP0),
264 VC4_PV_MUXING_TEST("3 outputs: DSI0, HDMI0, DSI1",
265 VC4_ENCODER_TYPE_DSI0,
266 VC4_ENCODER_TYPE_HDMI0,
267 VC4_ENCODER_TYPE_DSI1),
268 VC4_PV_MUXING_TEST("3 outputs: DSI0, HDMI0, TXP",
269 VC4_ENCODER_TYPE_DSI0,
270 VC4_ENCODER_TYPE_HDMI0,
271 VC4_ENCODER_TYPE_TXP0),
272 VC4_PV_MUXING_TEST("3 outputs: DSI0, VEC, DSI1",
273 VC4_ENCODER_TYPE_DSI0,
274 VC4_ENCODER_TYPE_VEC,
275 VC4_ENCODER_TYPE_DSI1),
276 VC4_PV_MUXING_TEST("3 outputs: DSI0, VEC, TXP",
277 VC4_ENCODER_TYPE_DSI0,
278 VC4_ENCODER_TYPE_VEC,
279 VC4_ENCODER_TYPE_TXP0),
280 VC4_PV_MUXING_TEST("3 outputs: DPI, HDMI0, DSI1",
281 VC4_ENCODER_TYPE_DPI,
282 VC4_ENCODER_TYPE_HDMI0,
283 VC4_ENCODER_TYPE_DSI1),
284 VC4_PV_MUXING_TEST("3 outputs: DPI, HDMI0, TXP",
285 VC4_ENCODER_TYPE_DPI,
286 VC4_ENCODER_TYPE_HDMI0,
287 VC4_ENCODER_TYPE_TXP0),
288 VC4_PV_MUXING_TEST("3 outputs: DPI, VEC, DSI1",
289 VC4_ENCODER_TYPE_DPI,
290 VC4_ENCODER_TYPE_VEC,
291 VC4_ENCODER_TYPE_DSI1),
292 VC4_PV_MUXING_TEST("3 outputs: DPI, VEC, TXP",
293 VC4_ENCODER_TYPE_DPI,
294 VC4_ENCODER_TYPE_VEC,
295 VC4_ENCODER_TYPE_TXP0),
298 KUNIT_ARRAY_PARAM(vc4_test_pv_muxing,
299 vc4_test_pv_muxing_params,
300 vc4_test_pv_muxing_desc);
302 static const struct pv_muxing_param vc4_test_pv_muxing_invalid_params[] = {
303 VC4_PV_MUXING_TEST("DPI/DSI0 Conflict",
304 VC4_ENCODER_TYPE_DPI,
305 VC4_ENCODER_TYPE_DSI0),
306 VC4_PV_MUXING_TEST("TXP/DSI1 Conflict",
307 VC4_ENCODER_TYPE_TXP0,
308 VC4_ENCODER_TYPE_DSI1),
309 VC4_PV_MUXING_TEST("HDMI0/VEC Conflict",
310 VC4_ENCODER_TYPE_HDMI0,
311 VC4_ENCODER_TYPE_VEC),
312 VC4_PV_MUXING_TEST("More than 3 outputs: DSI0, HDMI0, DSI1, TXP",
313 VC4_ENCODER_TYPE_DSI0,
314 VC4_ENCODER_TYPE_HDMI0,
315 VC4_ENCODER_TYPE_DSI1,
316 VC4_ENCODER_TYPE_TXP0),
317 VC4_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, DSI1, TXP",
318 VC4_ENCODER_TYPE_DSI0,
319 VC4_ENCODER_TYPE_VEC,
320 VC4_ENCODER_TYPE_DSI1,
321 VC4_ENCODER_TYPE_TXP0),
322 VC4_PV_MUXING_TEST("More than 3 outputs: DPI, HDMI0, DSI1, TXP",
323 VC4_ENCODER_TYPE_DPI,
324 VC4_ENCODER_TYPE_HDMI0,
325 VC4_ENCODER_TYPE_DSI1,
326 VC4_ENCODER_TYPE_TXP0),
327 VC4_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, DSI1, TXP",
328 VC4_ENCODER_TYPE_DPI,
329 VC4_ENCODER_TYPE_VEC,
330 VC4_ENCODER_TYPE_DSI1,
331 VC4_ENCODER_TYPE_TXP0),
334 KUNIT_ARRAY_PARAM(vc4_test_pv_muxing_invalid,
335 vc4_test_pv_muxing_invalid_params,
336 vc4_test_pv_muxing_desc);
338 static const struct pv_muxing_param vc5_test_pv_muxing_params[] = {
339 VC5_PV_MUXING_TEST("1 output: DPI",
340 VC4_ENCODER_TYPE_DPI),
341 VC5_PV_MUXING_TEST("1 output: DSI0",
342 VC4_ENCODER_TYPE_DSI0),
343 VC5_PV_MUXING_TEST("1 output: DSI1",
344 VC4_ENCODER_TYPE_DSI1),
345 VC5_PV_MUXING_TEST("1 output: HDMI0",
346 VC4_ENCODER_TYPE_HDMI0),
347 VC5_PV_MUXING_TEST("1 output: HDMI1",
348 VC4_ENCODER_TYPE_HDMI1),
349 VC5_PV_MUXING_TEST("1 output: VEC",
350 VC4_ENCODER_TYPE_VEC),
351 VC5_PV_MUXING_TEST("2 outputs: DPI, DSI1",
352 VC4_ENCODER_TYPE_DPI,
353 VC4_ENCODER_TYPE_DSI1),
354 VC5_PV_MUXING_TEST("2 outputs: DPI, HDMI0",
355 VC4_ENCODER_TYPE_DPI,
356 VC4_ENCODER_TYPE_HDMI0),
357 VC5_PV_MUXING_TEST("2 outputs: DPI, HDMI1",
358 VC4_ENCODER_TYPE_DPI,
359 VC4_ENCODER_TYPE_HDMI1),
360 VC5_PV_MUXING_TEST("2 outputs: DPI, TXP",
361 VC4_ENCODER_TYPE_DPI,
362 VC4_ENCODER_TYPE_TXP0),
363 VC5_PV_MUXING_TEST("2 outputs: DPI, VEC",
364 VC4_ENCODER_TYPE_DPI,
365 VC4_ENCODER_TYPE_VEC),
366 VC5_PV_MUXING_TEST("2 outputs: DPI, DSI1",
367 VC4_ENCODER_TYPE_DPI,
368 VC4_ENCODER_TYPE_DSI1),
369 VC5_PV_MUXING_TEST("2 outputs: DSI0, DSI1",
370 VC4_ENCODER_TYPE_DSI0,
371 VC4_ENCODER_TYPE_DSI1),
372 VC5_PV_MUXING_TEST("2 outputs: DSI0, HDMI0",
373 VC4_ENCODER_TYPE_DSI0,
374 VC4_ENCODER_TYPE_HDMI0),
375 VC5_PV_MUXING_TEST("2 outputs: DSI0, HDMI1",
376 VC4_ENCODER_TYPE_DSI0,
377 VC4_ENCODER_TYPE_HDMI1),
378 VC5_PV_MUXING_TEST("2 outputs: DSI0, TXP",
379 VC4_ENCODER_TYPE_DSI0,
380 VC4_ENCODER_TYPE_TXP0),
381 VC5_PV_MUXING_TEST("2 outputs: DSI0, VEC",
382 VC4_ENCODER_TYPE_DSI0,
383 VC4_ENCODER_TYPE_VEC),
384 VC5_PV_MUXING_TEST("2 outputs: DSI0, DSI1",
385 VC4_ENCODER_TYPE_DSI0,
386 VC4_ENCODER_TYPE_DSI1),
387 VC5_PV_MUXING_TEST("2 outputs: DSI1, VEC",
388 VC4_ENCODER_TYPE_DSI1,
389 VC4_ENCODER_TYPE_VEC),
390 VC5_PV_MUXING_TEST("2 outputs: DSI1, TXP",
391 VC4_ENCODER_TYPE_DSI1,
392 VC4_ENCODER_TYPE_TXP0),
393 VC5_PV_MUXING_TEST("2 outputs: DSI1, HDMI0",
394 VC4_ENCODER_TYPE_DSI1,
395 VC4_ENCODER_TYPE_HDMI0),
396 VC5_PV_MUXING_TEST("2 outputs: DSI1, HDMI1",
397 VC4_ENCODER_TYPE_DSI1,
398 VC4_ENCODER_TYPE_HDMI1),
399 VC5_PV_MUXING_TEST("2 outputs: HDMI0, VEC",
400 VC4_ENCODER_TYPE_HDMI0,
401 VC4_ENCODER_TYPE_VEC),
402 VC5_PV_MUXING_TEST("2 outputs: HDMI0, TXP",
403 VC4_ENCODER_TYPE_HDMI0,
404 VC4_ENCODER_TYPE_TXP0),
405 VC5_PV_MUXING_TEST("2 outputs: HDMI0, HDMI1",
406 VC4_ENCODER_TYPE_HDMI0,
407 VC4_ENCODER_TYPE_HDMI1),
408 VC5_PV_MUXING_TEST("2 outputs: HDMI1, VEC",
409 VC4_ENCODER_TYPE_HDMI1,
410 VC4_ENCODER_TYPE_VEC),
411 VC5_PV_MUXING_TEST("2 outputs: HDMI1, TXP",
412 VC4_ENCODER_TYPE_HDMI1,
413 VC4_ENCODER_TYPE_TXP0),
414 VC5_PV_MUXING_TEST("2 outputs: TXP, VEC",
415 VC4_ENCODER_TYPE_TXP0,
416 VC4_ENCODER_TYPE_VEC),
417 VC5_PV_MUXING_TEST("3 outputs: DPI, VEC, TXP",
418 VC4_ENCODER_TYPE_DPI,
419 VC4_ENCODER_TYPE_VEC,
420 VC4_ENCODER_TYPE_TXP0),
421 VC5_PV_MUXING_TEST("3 outputs: DPI, VEC, DSI1",
422 VC4_ENCODER_TYPE_DPI,
423 VC4_ENCODER_TYPE_VEC,
424 VC4_ENCODER_TYPE_DSI1),
425 VC5_PV_MUXING_TEST("3 outputs: DPI, VEC, HDMI0",
426 VC4_ENCODER_TYPE_DPI,
427 VC4_ENCODER_TYPE_VEC,
428 VC4_ENCODER_TYPE_HDMI0),
429 VC5_PV_MUXING_TEST("3 outputs: DPI, VEC, HDMI1",
430 VC4_ENCODER_TYPE_DPI,
431 VC4_ENCODER_TYPE_VEC,
432 VC4_ENCODER_TYPE_HDMI1),
433 VC5_PV_MUXING_TEST("3 outputs: DPI, TXP, DSI1",
434 VC4_ENCODER_TYPE_DPI,
435 VC4_ENCODER_TYPE_TXP0,
436 VC4_ENCODER_TYPE_DSI1),
437 VC5_PV_MUXING_TEST("3 outputs: DPI, TXP, HDMI0",
438 VC4_ENCODER_TYPE_DPI,
439 VC4_ENCODER_TYPE_TXP0,
440 VC4_ENCODER_TYPE_HDMI0),
441 VC5_PV_MUXING_TEST("3 outputs: DPI, TXP, HDMI1",
442 VC4_ENCODER_TYPE_DPI,
443 VC4_ENCODER_TYPE_TXP0,
444 VC4_ENCODER_TYPE_HDMI1),
445 VC5_PV_MUXING_TEST("3 outputs: DPI, DSI1, HDMI0",
446 VC4_ENCODER_TYPE_DPI,
447 VC4_ENCODER_TYPE_DSI1,
448 VC4_ENCODER_TYPE_HDMI0),
449 VC5_PV_MUXING_TEST("3 outputs: DPI, DSI1, HDMI1",
450 VC4_ENCODER_TYPE_DPI,
451 VC4_ENCODER_TYPE_DSI1,
452 VC4_ENCODER_TYPE_HDMI1),
453 VC5_PV_MUXING_TEST("3 outputs: DPI, HDMI0, HDMI1",
454 VC4_ENCODER_TYPE_DPI,
455 VC4_ENCODER_TYPE_HDMI0,
456 VC4_ENCODER_TYPE_HDMI1),
457 VC5_PV_MUXING_TEST("3 outputs: DSI0, VEC, TXP",
458 VC4_ENCODER_TYPE_DSI0,
459 VC4_ENCODER_TYPE_VEC,
460 VC4_ENCODER_TYPE_TXP0),
461 VC5_PV_MUXING_TEST("3 outputs: DSI0, VEC, DSI1",
462 VC4_ENCODER_TYPE_DSI0,
463 VC4_ENCODER_TYPE_VEC,
464 VC4_ENCODER_TYPE_DSI1),
465 VC5_PV_MUXING_TEST("3 outputs: DSI0, VEC, HDMI0",
466 VC4_ENCODER_TYPE_DSI0,
467 VC4_ENCODER_TYPE_VEC,
468 VC4_ENCODER_TYPE_HDMI0),
469 VC5_PV_MUXING_TEST("3 outputs: DSI0, VEC, HDMI1",
470 VC4_ENCODER_TYPE_DSI0,
471 VC4_ENCODER_TYPE_VEC,
472 VC4_ENCODER_TYPE_HDMI1),
473 VC5_PV_MUXING_TEST("3 outputs: DSI0, TXP, DSI1",
474 VC4_ENCODER_TYPE_DSI0,
475 VC4_ENCODER_TYPE_TXP0,
476 VC4_ENCODER_TYPE_DSI1),
477 VC5_PV_MUXING_TEST("3 outputs: DSI0, TXP, HDMI0",
478 VC4_ENCODER_TYPE_DSI0,
479 VC4_ENCODER_TYPE_TXP0,
480 VC4_ENCODER_TYPE_HDMI0),
481 VC5_PV_MUXING_TEST("3 outputs: DSI0, TXP, HDMI1",
482 VC4_ENCODER_TYPE_DSI0,
483 VC4_ENCODER_TYPE_TXP0,
484 VC4_ENCODER_TYPE_HDMI1),
485 VC5_PV_MUXING_TEST("3 outputs: DSI0, DSI1, HDMI0",
486 VC4_ENCODER_TYPE_DSI0,
487 VC4_ENCODER_TYPE_DSI1,
488 VC4_ENCODER_TYPE_HDMI0),
489 VC5_PV_MUXING_TEST("3 outputs: DSI0, DSI1, HDMI1",
490 VC4_ENCODER_TYPE_DSI0,
491 VC4_ENCODER_TYPE_DSI1,
492 VC4_ENCODER_TYPE_HDMI1),
493 VC5_PV_MUXING_TEST("3 outputs: DSI0, HDMI0, HDMI1",
494 VC4_ENCODER_TYPE_DSI0,
495 VC4_ENCODER_TYPE_HDMI0,
496 VC4_ENCODER_TYPE_HDMI1),
499 KUNIT_ARRAY_PARAM(vc5_test_pv_muxing,
500 vc5_test_pv_muxing_params,
501 vc4_test_pv_muxing_desc);
503 static const struct pv_muxing_param vc5_test_pv_muxing_invalid_params[] = {
504 VC5_PV_MUXING_TEST("DPI/DSI0 Conflict",
505 VC4_ENCODER_TYPE_DPI,
506 VC4_ENCODER_TYPE_DSI0),
507 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, DSI1",
508 VC4_ENCODER_TYPE_DPI,
509 VC4_ENCODER_TYPE_VEC,
510 VC4_ENCODER_TYPE_TXP0,
511 VC4_ENCODER_TYPE_DSI1),
512 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, HDMI0",
513 VC4_ENCODER_TYPE_DPI,
514 VC4_ENCODER_TYPE_VEC,
515 VC4_ENCODER_TYPE_TXP0,
516 VC4_ENCODER_TYPE_HDMI0),
517 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, HDMI1",
518 VC4_ENCODER_TYPE_DPI,
519 VC4_ENCODER_TYPE_VEC,
520 VC4_ENCODER_TYPE_TXP0,
521 VC4_ENCODER_TYPE_HDMI1),
522 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, DSI1, HDMI0",
523 VC4_ENCODER_TYPE_DPI,
524 VC4_ENCODER_TYPE_VEC,
525 VC4_ENCODER_TYPE_DSI1,
526 VC4_ENCODER_TYPE_HDMI0),
527 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, DSI1, HDMI1",
528 VC4_ENCODER_TYPE_DPI,
529 VC4_ENCODER_TYPE_VEC,
530 VC4_ENCODER_TYPE_DSI1,
531 VC4_ENCODER_TYPE_HDMI1),
532 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, HDMI0, HDMI1",
533 VC4_ENCODER_TYPE_DPI,
534 VC4_ENCODER_TYPE_VEC,
535 VC4_ENCODER_TYPE_HDMI0,
536 VC4_ENCODER_TYPE_HDMI1),
537 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, TXP, DSI1, HDMI0",
538 VC4_ENCODER_TYPE_DPI,
539 VC4_ENCODER_TYPE_TXP0,
540 VC4_ENCODER_TYPE_DSI1,
541 VC4_ENCODER_TYPE_HDMI0),
542 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, TXP, DSI1, HDMI1",
543 VC4_ENCODER_TYPE_DPI,
544 VC4_ENCODER_TYPE_TXP0,
545 VC4_ENCODER_TYPE_DSI1,
546 VC4_ENCODER_TYPE_HDMI1),
547 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, TXP, HDMI0, HDMI1",
548 VC4_ENCODER_TYPE_DPI,
549 VC4_ENCODER_TYPE_TXP0,
550 VC4_ENCODER_TYPE_HDMI0,
551 VC4_ENCODER_TYPE_HDMI1),
552 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, DSI1, HDMI0, HDMI1",
553 VC4_ENCODER_TYPE_DPI,
554 VC4_ENCODER_TYPE_DSI1,
555 VC4_ENCODER_TYPE_HDMI0,
556 VC4_ENCODER_TYPE_HDMI1),
557 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, DSI1, HDMI0",
558 VC4_ENCODER_TYPE_DPI,
559 VC4_ENCODER_TYPE_VEC,
560 VC4_ENCODER_TYPE_TXP0,
561 VC4_ENCODER_TYPE_DSI1,
562 VC4_ENCODER_TYPE_HDMI0),
563 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, DSI1, HDMI1",
564 VC4_ENCODER_TYPE_DPI,
565 VC4_ENCODER_TYPE_VEC,
566 VC4_ENCODER_TYPE_TXP0,
567 VC4_ENCODER_TYPE_DSI1,
568 VC4_ENCODER_TYPE_HDMI1),
569 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, HDMI0, HDMI1",
570 VC4_ENCODER_TYPE_DPI,
571 VC4_ENCODER_TYPE_VEC,
572 VC4_ENCODER_TYPE_TXP0,
573 VC4_ENCODER_TYPE_HDMI0,
574 VC4_ENCODER_TYPE_HDMI1),
575 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, DSI1, HDMI0, HDMI1",
576 VC4_ENCODER_TYPE_DPI,
577 VC4_ENCODER_TYPE_VEC,
578 VC4_ENCODER_TYPE_DSI1,
579 VC4_ENCODER_TYPE_HDMI0,
580 VC4_ENCODER_TYPE_HDMI1),
581 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, TXP, DSI1, HDMI0, HDMI1",
582 VC4_ENCODER_TYPE_DPI,
583 VC4_ENCODER_TYPE_TXP0,
584 VC4_ENCODER_TYPE_DSI1,
585 VC4_ENCODER_TYPE_HDMI0,
586 VC4_ENCODER_TYPE_HDMI1),
587 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, DSI1",
588 VC4_ENCODER_TYPE_DSI0,
589 VC4_ENCODER_TYPE_VEC,
590 VC4_ENCODER_TYPE_TXP0,
591 VC4_ENCODER_TYPE_DSI1),
592 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, HDMI0",
593 VC4_ENCODER_TYPE_DSI0,
594 VC4_ENCODER_TYPE_VEC,
595 VC4_ENCODER_TYPE_TXP0,
596 VC4_ENCODER_TYPE_HDMI0),
597 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, HDMI1",
598 VC4_ENCODER_TYPE_DSI0,
599 VC4_ENCODER_TYPE_VEC,
600 VC4_ENCODER_TYPE_TXP0,
601 VC4_ENCODER_TYPE_HDMI1),
602 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, DSI1, HDMI0",
603 VC4_ENCODER_TYPE_DSI0,
604 VC4_ENCODER_TYPE_VEC,
605 VC4_ENCODER_TYPE_DSI1,
606 VC4_ENCODER_TYPE_HDMI0),
607 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, DSI1, HDMI1",
608 VC4_ENCODER_TYPE_DSI0,
609 VC4_ENCODER_TYPE_VEC,
610 VC4_ENCODER_TYPE_DSI1,
611 VC4_ENCODER_TYPE_HDMI1),
612 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, HDMI0, HDMI1",
613 VC4_ENCODER_TYPE_DSI0,
614 VC4_ENCODER_TYPE_VEC,
615 VC4_ENCODER_TYPE_HDMI0,
616 VC4_ENCODER_TYPE_HDMI1),
617 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, TXP, DSI1, HDMI0",
618 VC4_ENCODER_TYPE_DSI0,
619 VC4_ENCODER_TYPE_TXP0,
620 VC4_ENCODER_TYPE_DSI1,
621 VC4_ENCODER_TYPE_HDMI0),
622 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, TXP, DSI1, HDMI1",
623 VC4_ENCODER_TYPE_DSI0,
624 VC4_ENCODER_TYPE_TXP0,
625 VC4_ENCODER_TYPE_DSI1,
626 VC4_ENCODER_TYPE_HDMI1),
627 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, TXP, HDMI0, HDMI1",
628 VC4_ENCODER_TYPE_DSI0,
629 VC4_ENCODER_TYPE_TXP0,
630 VC4_ENCODER_TYPE_HDMI0,
631 VC4_ENCODER_TYPE_HDMI1),
632 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, DSI1, HDMI0, HDMI1",
633 VC4_ENCODER_TYPE_DSI0,
634 VC4_ENCODER_TYPE_DSI1,
635 VC4_ENCODER_TYPE_HDMI0,
636 VC4_ENCODER_TYPE_HDMI1),
637 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, DSI1, HDMI0",
638 VC4_ENCODER_TYPE_DSI0,
639 VC4_ENCODER_TYPE_VEC,
640 VC4_ENCODER_TYPE_TXP0,
641 VC4_ENCODER_TYPE_DSI1,
642 VC4_ENCODER_TYPE_HDMI0),
643 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, DSI1, HDMI1",
644 VC4_ENCODER_TYPE_DSI0,
645 VC4_ENCODER_TYPE_VEC,
646 VC4_ENCODER_TYPE_TXP0,
647 VC4_ENCODER_TYPE_DSI1,
648 VC4_ENCODER_TYPE_HDMI1),
649 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, HDMI0, HDMI1",
650 VC4_ENCODER_TYPE_DSI0,
651 VC4_ENCODER_TYPE_VEC,
652 VC4_ENCODER_TYPE_TXP0,
653 VC4_ENCODER_TYPE_HDMI0,
654 VC4_ENCODER_TYPE_HDMI1),
655 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, DSI1, HDMI0, HDMI1",
656 VC4_ENCODER_TYPE_DSI0,
657 VC4_ENCODER_TYPE_VEC,
658 VC4_ENCODER_TYPE_DSI1,
659 VC4_ENCODER_TYPE_HDMI0,
660 VC4_ENCODER_TYPE_HDMI1),
661 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, TXP, DSI1, HDMI0, HDMI1",
662 VC4_ENCODER_TYPE_DSI0,
663 VC4_ENCODER_TYPE_TXP0,
664 VC4_ENCODER_TYPE_DSI1,
665 VC4_ENCODER_TYPE_HDMI0,
666 VC4_ENCODER_TYPE_HDMI1),
667 VC5_PV_MUXING_TEST("More than 3 outputs: VEC, TXP, DSI1, HDMI0, HDMI1",
668 VC4_ENCODER_TYPE_VEC,
669 VC4_ENCODER_TYPE_TXP0,
670 VC4_ENCODER_TYPE_DSI1,
671 VC4_ENCODER_TYPE_HDMI0,
672 VC4_ENCODER_TYPE_HDMI1),
673 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, DSI1, HDMI0, HDMI1",
674 VC4_ENCODER_TYPE_DPI,
675 VC4_ENCODER_TYPE_VEC,
676 VC4_ENCODER_TYPE_TXP0,
677 VC4_ENCODER_TYPE_DSI1,
678 VC4_ENCODER_TYPE_HDMI0,
679 VC4_ENCODER_TYPE_HDMI1),
680 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, DSI1, HDMI0, HDMI1",
681 VC4_ENCODER_TYPE_DSI0,
682 VC4_ENCODER_TYPE_VEC,
683 VC4_ENCODER_TYPE_TXP0,
684 VC4_ENCODER_TYPE_DSI1,
685 VC4_ENCODER_TYPE_HDMI0,
686 VC4_ENCODER_TYPE_HDMI1),
689 KUNIT_ARRAY_PARAM(vc5_test_pv_muxing_invalid,
690 vc5_test_pv_muxing_invalid_params,
691 vc4_test_pv_muxing_desc);
693 static const struct pv_muxing_param vc6_test_pv_muxing_params[] = {
694 VC6_PV_MUXING_TEST("1 output: HDMI0",
695 VC4_ENCODER_TYPE_HDMI0),
696 VC6_PV_MUXING_TEST("1 output: HDMI1",
697 VC4_ENCODER_TYPE_HDMI1),
698 VC6_PV_MUXING_TEST("1 output: MOPLET",
699 VC4_ENCODER_TYPE_TXP1),
700 VC6_PV_MUXING_TEST("1 output: MOP",
701 VC4_ENCODER_TYPE_TXP0),
702 VC6_PV_MUXING_TEST("2 outputs: HDMI0, HDMI1",
703 VC4_ENCODER_TYPE_HDMI0,
704 VC4_ENCODER_TYPE_HDMI1),
705 VC6_PV_MUXING_TEST("2 outputs: HDMI0, MOPLET",
706 VC4_ENCODER_TYPE_HDMI0,
707 VC4_ENCODER_TYPE_TXP1),
708 VC6_PV_MUXING_TEST("2 outputs: HDMI0, MOP",
709 VC4_ENCODER_TYPE_HDMI0,
710 VC4_ENCODER_TYPE_TXP0),
711 VC6_PV_MUXING_TEST("2 outputs: HDMI1, MOP",
712 VC4_ENCODER_TYPE_HDMI1,
713 VC4_ENCODER_TYPE_TXP0),
714 VC6_PV_MUXING_TEST("2 outputs: MOPLET, MOP",
715 VC4_ENCODER_TYPE_TXP1,
716 VC4_ENCODER_TYPE_TXP0),
717 VC6_PV_MUXING_TEST("3 outputs: HDMI0, HDMI1, MOP",
718 VC4_ENCODER_TYPE_HDMI0,
719 VC4_ENCODER_TYPE_HDMI1,
720 VC4_ENCODER_TYPE_TXP0),
721 VC6_PV_MUXING_TEST("3 outputs: HDMI0, MOPLET, MOP",
722 VC4_ENCODER_TYPE_HDMI0,
723 VC4_ENCODER_TYPE_TXP1,
724 VC4_ENCODER_TYPE_TXP0),
727 KUNIT_ARRAY_PARAM(vc6_test_pv_muxing,
728 vc6_test_pv_muxing_params,
729 vc4_test_pv_muxing_desc);
731 static const struct pv_muxing_param vc6_test_pv_muxing_invalid_params[] = {
732 VC6_PV_MUXING_TEST("HDMI1/MOPLET Conflict",
733 VC4_ENCODER_TYPE_HDMI1,
734 VC4_ENCODER_TYPE_TXP1),
737 KUNIT_ARRAY_PARAM(vc6_test_pv_muxing_invalid,
738 vc6_test_pv_muxing_invalid_params,
739 vc4_test_pv_muxing_desc);
741 static void drm_vc4_test_pv_muxing(struct kunit *test)
743 const struct pv_muxing_param *params = test->param_value;
744 const struct pv_muxing_priv *priv = test->priv;
745 struct drm_atomic_state *state = priv->state;
749 for (i = 0; i < params->nencoders; i++) {
750 struct vc4_dummy_output *output;
751 enum vc4_encoder_type enc_type = params->encoders[i];
753 output = vc4_mock_atomic_add_output(test, state, enc_type);
754 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, output);
757 ret = drm_atomic_check_only(state);
758 KUNIT_EXPECT_EQ(test, ret, 0);
760 KUNIT_EXPECT_TRUE(test,
761 check_fifo_conflict(test, state));
763 for (i = 0; i < params->nencoders; i++) {
764 enum vc4_encoder_type enc_type = params->encoders[i];
766 KUNIT_EXPECT_TRUE(test, check_channel_for_encoder(test, state, enc_type,
771 static void drm_vc4_test_pv_muxing_invalid(struct kunit *test)
773 const struct pv_muxing_param *params = test->param_value;
774 const struct pv_muxing_priv *priv = test->priv;
775 struct drm_atomic_state *state = priv->state;
779 for (i = 0; i < params->nencoders; i++) {
780 struct vc4_dummy_output *output;
781 enum vc4_encoder_type enc_type = params->encoders[i];
783 output = vc4_mock_atomic_add_output(test, state, enc_type);
784 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, output);
787 ret = drm_atomic_check_only(state);
788 KUNIT_EXPECT_LT(test, ret, 0);
791 static int vc4_pv_muxing_test_init(struct kunit *test)
793 const struct pv_muxing_param *params = test->param_value;
794 struct drm_modeset_acquire_ctx *ctx;
795 struct pv_muxing_priv *priv;
796 struct drm_device *drm;
799 priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
800 KUNIT_ASSERT_NOT_NULL(test, priv);
803 vc4 = params->mock_fn(test);
804 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
807 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
808 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
811 priv->state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
812 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->state);
817 static struct kunit_case vc4_pv_muxing_tests[] = {
818 KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing,
819 vc4_test_pv_muxing_gen_params),
820 KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing_invalid,
821 vc4_test_pv_muxing_invalid_gen_params),
825 static struct kunit_suite vc4_pv_muxing_test_suite = {
826 .name = "vc4-pv-muxing-combinations",
827 .init = vc4_pv_muxing_test_init,
828 .test_cases = vc4_pv_muxing_tests,
831 static struct kunit_case vc5_pv_muxing_tests[] = {
832 KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing,
833 vc5_test_pv_muxing_gen_params),
834 KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing_invalid,
835 vc5_test_pv_muxing_invalid_gen_params),
839 static struct kunit_suite vc5_pv_muxing_test_suite = {
840 .name = "vc5-pv-muxing-combinations",
841 .init = vc4_pv_muxing_test_init,
842 .test_cases = vc5_pv_muxing_tests,
845 static struct kunit_case vc6_pv_muxing_tests[] = {
846 KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing,
847 vc6_test_pv_muxing_gen_params),
848 KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing_invalid,
849 vc6_test_pv_muxing_invalid_gen_params),
853 static struct kunit_suite vc6_pv_muxing_test_suite = {
854 .name = "vc6-pv-muxing-combinations",
855 .init = vc4_pv_muxing_test_init,
856 .exit = vc4_pv_muxing_test_exit,
857 .test_cases = vc6_pv_muxing_tests,
861 * https://lore.kernel.org/all/3e113525-aa89-b1e2-56b7-ca55bd41d057@samsung.com/
863 * https://lore.kernel.org/dri-devel/20200917121623.42023-1-maxime@cerno.tech/
865 static void drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable(struct kunit *test)
867 struct drm_modeset_acquire_ctx *ctx;
868 struct drm_atomic_state *state;
869 struct vc4_dummy_output *output;
870 struct vc4_crtc_state *new_vc4_crtc_state;
871 struct vc4_hvs_state *new_hvs_state;
872 unsigned int hdmi0_channel;
873 unsigned int hdmi1_channel;
874 struct drm_device *drm;
878 vc4 = vc5_mock_device(test);
879 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
881 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
882 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
885 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
886 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
888 output = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI0);
889 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, output);
891 ret = drm_atomic_check_only(state);
892 KUNIT_ASSERT_EQ(test, ret, 0);
894 new_hvs_state = vc4_hvs_get_new_global_state(state);
895 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state);
897 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
898 VC4_ENCODER_TYPE_HDMI0);
899 KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state);
901 hdmi0_channel = new_vc4_crtc_state->assigned_channel;
902 KUNIT_ASSERT_NE(test, hdmi0_channel, VC4_HVS_CHANNEL_DISABLED);
903 KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[hdmi0_channel].in_use);
905 ret = drm_atomic_helper_swap_state(state, false);
906 KUNIT_ASSERT_EQ(test, ret, 0);
908 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
909 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
911 output = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI1);
912 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, output);
914 ret = drm_atomic_check_only(state);
915 KUNIT_ASSERT_EQ(test, ret, 0);
917 new_hvs_state = vc4_hvs_get_new_global_state(state);
918 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state);
920 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
921 VC4_ENCODER_TYPE_HDMI1);
922 KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state);
924 hdmi1_channel = new_vc4_crtc_state->assigned_channel;
925 KUNIT_ASSERT_NE(test, hdmi1_channel, VC4_HVS_CHANNEL_DISABLED);
926 KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[hdmi1_channel].in_use);
928 KUNIT_EXPECT_NE(test, hdmi0_channel, hdmi1_channel);
932 * This test makes sure that we never change the FIFO of an active HVS
933 * channel if we disable a FIFO with a lower index.
935 * Doing so would result in a FIFO stall and would disrupt an output
936 * supposed to be unaffected by the commit.
938 static void drm_test_vc5_pv_muxing_bugs_stable_fifo(struct kunit *test)
940 struct drm_modeset_acquire_ctx *ctx;
941 struct drm_atomic_state *state;
942 struct vc4_dummy_output *output;
943 struct vc4_crtc_state *new_vc4_crtc_state;
944 struct vc4_hvs_state *new_hvs_state;
945 unsigned int old_hdmi0_channel;
946 unsigned int old_hdmi1_channel;
947 struct drm_device *drm;
951 vc4 = vc5_mock_device(test);
952 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
954 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
955 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
958 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
959 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
961 output = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI0);
962 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, output);
964 output = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI1);
965 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, output);
967 ret = drm_atomic_check_only(state);
968 KUNIT_ASSERT_EQ(test, ret, 0);
970 new_hvs_state = vc4_hvs_get_new_global_state(state);
971 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state);
973 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
974 VC4_ENCODER_TYPE_HDMI0);
975 KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state);
977 old_hdmi0_channel = new_vc4_crtc_state->assigned_channel;
978 KUNIT_ASSERT_NE(test, old_hdmi0_channel, VC4_HVS_CHANNEL_DISABLED);
979 KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[old_hdmi0_channel].in_use);
981 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
982 VC4_ENCODER_TYPE_HDMI1);
983 KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state);
985 old_hdmi1_channel = new_vc4_crtc_state->assigned_channel;
986 KUNIT_ASSERT_NE(test, old_hdmi1_channel, VC4_HVS_CHANNEL_DISABLED);
987 KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[old_hdmi1_channel].in_use);
989 ret = drm_atomic_helper_swap_state(state, false);
990 KUNIT_ASSERT_EQ(test, ret, 0);
992 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
993 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
995 ret = vc4_mock_atomic_del_output(test, state, VC4_ENCODER_TYPE_HDMI0);
996 KUNIT_ASSERT_EQ(test, ret, 0);
998 ret = drm_atomic_check_only(state);
999 KUNIT_ASSERT_EQ(test, ret, 0);
1001 new_hvs_state = vc4_hvs_get_new_global_state(state);
1002 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state);
1004 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
1005 VC4_ENCODER_TYPE_HDMI1);
1007 if (new_vc4_crtc_state) {
1008 unsigned int hdmi1_channel;
1010 hdmi1_channel = new_vc4_crtc_state->assigned_channel;
1011 KUNIT_ASSERT_NE(test, hdmi1_channel, VC4_HVS_CHANNEL_DISABLED);
1012 KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[hdmi1_channel].in_use);
1014 KUNIT_EXPECT_EQ(test, old_hdmi1_channel, hdmi1_channel);
1019 * Test that if we affect a single output, only the CRTC state of that
1020 * output will be pulled in the global atomic state.
1022 * This is relevant for two things:
1024 * - If we don't have that state at all, we are unlikely to affect the
1025 * FIFO muxing. This is somewhat redundant with
1026 * drm_test_vc5_pv_muxing_bugs_stable_fifo()
1028 * - KMS waits for page flips to occur on all the CRTC found in the
1029 * CRTC state. Since the CRTC is unaffected, we would over-wait, but
1030 * most importantly run into corner cases like waiting on an
1031 * inactive CRTC that never completes.
1034 drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable_too_many_crtc_state(struct kunit *test)
1036 struct drm_modeset_acquire_ctx *ctx;
1037 struct drm_atomic_state *state;
1038 struct vc4_dummy_output *output;
1039 struct vc4_crtc_state *new_vc4_crtc_state;
1040 struct drm_device *drm;
1041 struct vc4_dev *vc4;
1044 vc4 = vc5_mock_device(test);
1045 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
1047 ctx = drm_kunit_helper_acquire_ctx_alloc(test);
1048 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
1051 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
1052 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
1054 output = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI0);
1055 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, output);
1057 ret = drm_atomic_check_only(state);
1058 KUNIT_ASSERT_EQ(test, ret, 0);
1060 ret = drm_atomic_helper_swap_state(state, false);
1061 KUNIT_ASSERT_EQ(test, ret, 0);
1063 state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
1064 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
1066 output = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI1);
1067 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, output);
1069 ret = drm_atomic_check_only(state);
1070 KUNIT_ASSERT_EQ(test, ret, 0);
1072 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
1073 VC4_ENCODER_TYPE_HDMI0);
1074 KUNIT_EXPECT_NULL(test, new_vc4_crtc_state);
1077 static struct kunit_case vc5_pv_muxing_bugs_tests[] = {
1078 KUNIT_CASE(drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable),
1079 KUNIT_CASE(drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable_too_many_crtc_state),
1080 KUNIT_CASE(drm_test_vc5_pv_muxing_bugs_stable_fifo),
1084 static struct kunit_suite vc5_pv_muxing_bugs_test_suite = {
1085 .name = "vc5-pv-muxing-bugs",
1086 .test_cases = vc5_pv_muxing_bugs_tests,
1090 &vc4_pv_muxing_test_suite,
1091 &vc5_pv_muxing_test_suite,
1092 &vc6_pv_muxing_test_suite,
1093 &vc5_pv_muxing_bugs_test_suite