e1f095ef9e6a9df7e600f24738ee012b64cf41e1
[platform/kernel/linux-rpi.git] / drivers / gpu / drm / vc4 / tests / vc4_test_pv_muxing.c
1 // SPDX-License-Identifier: GPL-2.0
2
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>
14
15 #include <kunit/test.h>
16
17 #include "../vc4_drv.h"
18
19 #include "vc4_mock.h"
20
21 struct pv_muxing_priv {
22         struct vc4_dev *vc4;
23         struct drm_atomic_state *state;
24 };
25
26 static bool check_fifo_conflict(struct kunit *test,
27                                 const struct drm_atomic_state *state)
28 {
29         struct vc4_hvs_state *hvs_state;
30         unsigned int used_fifos = 0;
31         unsigned int i;
32
33         hvs_state = vc4_hvs_get_new_global_state(state);
34         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hvs_state);
35
36         for (i = 0; i < HVS_NUM_CHANNELS; i++) {
37                 if (!hvs_state->fifo_state[i].in_use)
38                         continue;
39
40                 KUNIT_EXPECT_FALSE(test, used_fifos & BIT(i));
41                 used_fifos |= BIT(i);
42         }
43
44         return true;
45 }
46
47 struct encoder_constraint {
48         enum vc4_encoder_type type;
49         unsigned int *channels;
50         size_t nchannels;
51 };
52
53 #define ENCODER_CONSTRAINT(_type, ...)                                  \
54         {                                                               \
55                 .type = _type,                                          \
56                 .channels = (unsigned int[]) { __VA_ARGS__ },           \
57                 .nchannels = sizeof((unsigned int[]) { __VA_ARGS__ }) / \
58                              sizeof(unsigned int),                      \
59         }
60
61 static bool __check_encoder_constraints(const struct encoder_constraint *constraints,
62                                         size_t nconstraints,
63                                         enum vc4_encoder_type type,
64                                         unsigned int channel)
65 {
66         unsigned int i;
67
68         for (i = 0; i < nconstraints; i++) {
69                 const struct encoder_constraint *constraint = &constraints[i];
70                 unsigned int j;
71
72                 if (constraint->type != type)
73                         continue;
74
75                 for (j = 0; j < constraint->nchannels; j++) {
76                         unsigned int _channel = constraint->channels[j];
77
78                         if (channel != _channel)
79                                 continue;
80
81                         return true;
82                 }
83         }
84
85         return false;
86 }
87
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),
95 };
96
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),
105 };
106
107 static bool check_vc4_encoder_constraints(enum vc4_encoder_type type, unsigned int channel)
108 {
109         return __check_encoder_constraints(vc4_encoder_constraints,
110                                            ARRAY_SIZE(vc4_encoder_constraints),
111                                            type, channel);
112 }
113
114 static bool check_vc5_encoder_constraints(enum vc4_encoder_type type, unsigned int channel)
115 {
116         return __check_encoder_constraints(vc5_encoder_constraints,
117                                            ARRAY_SIZE(vc5_encoder_constraints),
118                                            type, channel);
119 }
120
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)
125 {
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;
130
131         encoder = vc4_find_encoder_by_type(drm, type);
132         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder);
133
134         crtc = vc4_find_crtc_for_encoder(test, encoder);
135         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc);
136
137         new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
138         if (!new_crtc_state)
139                 return NULL;
140
141         return to_vc4_crtc_state(new_crtc_state);
142 }
143
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))
148 {
149         struct vc4_crtc_state *new_vc4_crtc_state;
150         struct vc4_hvs_state *new_hvs_state;
151         unsigned int channel;
152
153         new_hvs_state = vc4_hvs_get_new_global_state(state);
154         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state);
155
156         new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state, type);
157         KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state);
158
159         channel = new_vc4_crtc_state->assigned_channel;
160         KUNIT_EXPECT_NE(test, channel, VC4_HVS_CHANNEL_DISABLED);
161
162         KUNIT_EXPECT_TRUE(test, new_hvs_state->fifo_state[channel].in_use);
163
164         KUNIT_EXPECT_TRUE(test, check_fn(type, channel));
165
166         return true;
167 }
168
169 struct pv_muxing_param {
170         const char *name;
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;
174         size_t nencoders;
175 };
176
177 static void vc4_test_pv_muxing_desc(const struct pv_muxing_param *t, char *desc)
178 {
179         strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE);
180 }
181
182 #define PV_MUXING_TEST(_name, _mock_fn, _check_fn, ...)                                 \
183         {                                                                               \
184                 .name = _name,                                                          \
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),                             \
190         }
191
192 #define VC4_PV_MUXING_TEST(_name, ...)          \
193         PV_MUXING_TEST(_name, vc4_mock_device, check_vc4_encoder_constraints, __VA_ARGS__)
194
195 #define VC5_PV_MUXING_TEST(_name, ...)          \
196         PV_MUXING_TEST(_name, vc5_mock_device, check_vc5_encoder_constraints, __VA_ARGS__)
197
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),
279 };
280
281 KUNIT_ARRAY_PARAM(vc4_test_pv_muxing,
282                   vc4_test_pv_muxing_params,
283                   vc4_test_pv_muxing_desc);
284
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),
315 };
316
317 KUNIT_ARRAY_PARAM(vc4_test_pv_muxing_invalid,
318                   vc4_test_pv_muxing_invalid_params,
319                   vc4_test_pv_muxing_desc);
320
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),
480 };
481
482 KUNIT_ARRAY_PARAM(vc5_test_pv_muxing,
483                   vc5_test_pv_muxing_params,
484                   vc4_test_pv_muxing_desc);
485
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),
670 };
671
672 KUNIT_ARRAY_PARAM(vc5_test_pv_muxing_invalid,
673                   vc5_test_pv_muxing_invalid_params,
674                   vc4_test_pv_muxing_desc);
675
676 static void drm_vc4_test_pv_muxing(struct kunit *test)
677 {
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;
681         unsigned int i;
682         int ret;
683
684         for (i = 0; i < params->nencoders; i++) {
685                 enum vc4_encoder_type enc_type = params->encoders[i];
686
687                 ret = vc4_mock_atomic_add_output(test, state, enc_type);
688                 KUNIT_ASSERT_EQ(test, ret, 0);
689         }
690
691         ret = drm_atomic_check_only(state);
692         KUNIT_EXPECT_EQ(test, ret, 0);
693
694         KUNIT_EXPECT_TRUE(test,
695                           check_fifo_conflict(test, state));
696
697         for (i = 0; i < params->nencoders; i++) {
698                 enum vc4_encoder_type enc_type = params->encoders[i];
699
700                 KUNIT_EXPECT_TRUE(test, check_channel_for_encoder(test, state, enc_type,
701                                                                   params->check_fn));
702         }
703 }
704
705 static void drm_vc4_test_pv_muxing_invalid(struct kunit *test)
706 {
707         const struct pv_muxing_param *params = test->param_value;
708         const struct pv_muxing_priv *priv = test->priv;
709         struct drm_atomic_state *state = priv->state;
710         unsigned int i;
711         int ret;
712
713         for (i = 0; i < params->nencoders; i++) {
714                 enum vc4_encoder_type enc_type = params->encoders[i];
715
716                 ret = vc4_mock_atomic_add_output(test, state, enc_type);
717                 KUNIT_ASSERT_EQ(test, ret, 0);
718         }
719
720         ret = drm_atomic_check_only(state);
721         KUNIT_EXPECT_LT(test, ret, 0);
722 }
723
724 static int vc4_pv_muxing_test_init(struct kunit *test)
725 {
726         const struct pv_muxing_param *params = test->param_value;
727         struct drm_modeset_acquire_ctx *ctx;
728         struct pv_muxing_priv *priv;
729         struct drm_device *drm;
730         struct vc4_dev *vc4;
731
732         priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
733         KUNIT_ASSERT_NOT_NULL(test, priv);
734         test->priv = priv;
735
736         vc4 = params->mock_fn(test);
737         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
738         priv->vc4 = vc4;
739
740         ctx = drm_kunit_helper_acquire_ctx_alloc(test);
741         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
742
743         drm = &vc4->base;
744         priv->state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
745         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->state);
746
747         return 0;
748 }
749
750 static struct kunit_case vc4_pv_muxing_tests[] = {
751         KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing,
752                          vc4_test_pv_muxing_gen_params),
753         KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing_invalid,
754                          vc4_test_pv_muxing_invalid_gen_params),
755         {}
756 };
757
758 static struct kunit_suite vc4_pv_muxing_test_suite = {
759         .name = "vc4-pv-muxing-combinations",
760         .init = vc4_pv_muxing_test_init,
761         .test_cases = vc4_pv_muxing_tests,
762 };
763
764 static struct kunit_case vc5_pv_muxing_tests[] = {
765         KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing,
766                          vc5_test_pv_muxing_gen_params),
767         KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing_invalid,
768                          vc5_test_pv_muxing_invalid_gen_params),
769         {}
770 };
771
772 static struct kunit_suite vc5_pv_muxing_test_suite = {
773         .name = "vc5-pv-muxing-combinations",
774         .init = vc4_pv_muxing_test_init,
775         .test_cases = vc5_pv_muxing_tests,
776 };
777
778 /* See
779  * https://lore.kernel.org/all/3e113525-aa89-b1e2-56b7-ca55bd41d057@samsung.com/
780  * and
781  * https://lore.kernel.org/dri-devel/20200917121623.42023-1-maxime@cerno.tech/
782  */
783 static void drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable(struct kunit *test)
784 {
785         struct drm_modeset_acquire_ctx *ctx;
786         struct drm_atomic_state *state;
787         struct vc4_crtc_state *new_vc4_crtc_state;
788         struct vc4_hvs_state *new_hvs_state;
789         unsigned int hdmi0_channel;
790         unsigned int hdmi1_channel;
791         struct drm_device *drm;
792         struct vc4_dev *vc4;
793         int ret;
794
795         vc4 = vc5_mock_device(test);
796         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
797
798         ctx = drm_kunit_helper_acquire_ctx_alloc(test);
799         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
800
801         drm = &vc4->base;
802         state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
803         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
804
805         ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI0);
806         KUNIT_ASSERT_EQ(test, ret, 0);
807
808         ret = drm_atomic_check_only(state);
809         KUNIT_ASSERT_EQ(test, ret, 0);
810
811         new_hvs_state = vc4_hvs_get_new_global_state(state);
812         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state);
813
814         new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
815                                                             VC4_ENCODER_TYPE_HDMI0);
816         KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state);
817
818         hdmi0_channel = new_vc4_crtc_state->assigned_channel;
819         KUNIT_ASSERT_NE(test, hdmi0_channel, VC4_HVS_CHANNEL_DISABLED);
820         KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[hdmi0_channel].in_use);
821
822         ret = drm_atomic_helper_swap_state(state, false);
823         KUNIT_ASSERT_EQ(test, ret, 0);
824
825         state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
826         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
827
828         ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI1);
829         KUNIT_ASSERT_EQ(test, ret, 0);
830
831         ret = drm_atomic_check_only(state);
832         KUNIT_ASSERT_EQ(test, ret, 0);
833
834         new_hvs_state = vc4_hvs_get_new_global_state(state);
835         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state);
836
837         new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
838                                                             VC4_ENCODER_TYPE_HDMI1);
839         KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state);
840
841         hdmi1_channel = new_vc4_crtc_state->assigned_channel;
842         KUNIT_ASSERT_NE(test, hdmi1_channel, VC4_HVS_CHANNEL_DISABLED);
843         KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[hdmi1_channel].in_use);
844
845         KUNIT_EXPECT_NE(test, hdmi0_channel, hdmi1_channel);
846 }
847
848 /*
849  * This test makes sure that we never change the FIFO of an active HVS
850  * channel if we disable a FIFO with a lower index.
851  *
852  * Doing so would result in a FIFO stall and would disrupt an output
853  * supposed to be unaffected by the commit.
854  */
855 static void drm_test_vc5_pv_muxing_bugs_stable_fifo(struct kunit *test)
856 {
857         struct drm_modeset_acquire_ctx *ctx;
858         struct drm_atomic_state *state;
859         struct vc4_crtc_state *new_vc4_crtc_state;
860         struct vc4_hvs_state *new_hvs_state;
861         unsigned int old_hdmi0_channel;
862         unsigned int old_hdmi1_channel;
863         struct drm_device *drm;
864         struct vc4_dev *vc4;
865         int ret;
866
867         vc4 = vc5_mock_device(test);
868         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
869
870         ctx = drm_kunit_helper_acquire_ctx_alloc(test);
871         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
872
873         drm = &vc4->base;
874         state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
875         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
876
877         ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI0);
878         KUNIT_ASSERT_EQ(test, ret, 0);
879
880         ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI1);
881         KUNIT_ASSERT_EQ(test, ret, 0);
882
883         ret = drm_atomic_check_only(state);
884         KUNIT_ASSERT_EQ(test, ret, 0);
885
886         new_hvs_state = vc4_hvs_get_new_global_state(state);
887         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state);
888
889         new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
890                                                             VC4_ENCODER_TYPE_HDMI0);
891         KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state);
892
893         old_hdmi0_channel = new_vc4_crtc_state->assigned_channel;
894         KUNIT_ASSERT_NE(test, old_hdmi0_channel, VC4_HVS_CHANNEL_DISABLED);
895         KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[old_hdmi0_channel].in_use);
896
897         new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
898                                                             VC4_ENCODER_TYPE_HDMI1);
899         KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state);
900
901         old_hdmi1_channel = new_vc4_crtc_state->assigned_channel;
902         KUNIT_ASSERT_NE(test, old_hdmi1_channel, VC4_HVS_CHANNEL_DISABLED);
903         KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[old_hdmi1_channel].in_use);
904
905         ret = drm_atomic_helper_swap_state(state, false);
906         KUNIT_ASSERT_EQ(test, ret, 0);
907
908         state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
909         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
910
911         ret = vc4_mock_atomic_del_output(test, state, VC4_ENCODER_TYPE_HDMI0);
912         KUNIT_ASSERT_EQ(test, ret, 0);
913
914         ret = drm_atomic_check_only(state);
915         KUNIT_ASSERT_EQ(test, ret, 0);
916
917         new_hvs_state = vc4_hvs_get_new_global_state(state);
918         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state);
919
920         new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
921                                                             VC4_ENCODER_TYPE_HDMI1);
922
923         if (new_vc4_crtc_state) {
924                 unsigned int hdmi1_channel;
925
926                 hdmi1_channel = new_vc4_crtc_state->assigned_channel;
927                 KUNIT_ASSERT_NE(test, hdmi1_channel, VC4_HVS_CHANNEL_DISABLED);
928                 KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[hdmi1_channel].in_use);
929
930                 KUNIT_EXPECT_EQ(test, old_hdmi1_channel, hdmi1_channel);
931         }
932 }
933
934 /*
935  * Test that if we affect a single output, only the CRTC state of that
936  * output will be pulled in the global atomic state.
937  *
938  * This is relevant for two things:
939  *
940  *   - If we don't have that state at all, we are unlikely to affect the
941  *     FIFO muxing. This is somewhat redundant with
942  *     drm_test_vc5_pv_muxing_bugs_stable_fifo()
943  *
944  *   - KMS waits for page flips to occur on all the CRTC found in the
945  *     CRTC state. Since the CRTC is unaffected, we would over-wait, but
946  *     most importantly run into corner cases like waiting on an
947  *     inactive CRTC that never completes.
948  */
949 static void
950 drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable_too_many_crtc_state(struct kunit *test)
951 {
952         struct drm_modeset_acquire_ctx *ctx;
953         struct drm_atomic_state *state;
954         struct vc4_crtc_state *new_vc4_crtc_state;
955         struct drm_device *drm;
956         struct vc4_dev *vc4;
957         int ret;
958
959         vc4 = vc5_mock_device(test);
960         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4);
961
962         ctx = drm_kunit_helper_acquire_ctx_alloc(test);
963         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx);
964
965         drm = &vc4->base;
966         state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
967         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
968
969         ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI0);
970         KUNIT_ASSERT_EQ(test, ret, 0);
971
972         ret = drm_atomic_check_only(state);
973         KUNIT_ASSERT_EQ(test, ret, 0);
974
975         ret = drm_atomic_helper_swap_state(state, false);
976         KUNIT_ASSERT_EQ(test, ret, 0);
977
978         state = drm_kunit_helper_atomic_state_alloc(test, drm, ctx);
979         KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state);
980
981         ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI1);
982         KUNIT_ASSERT_EQ(test, ret, 0);
983
984         ret = drm_atomic_check_only(state);
985         KUNIT_ASSERT_EQ(test, ret, 0);
986
987         new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state,
988                                                             VC4_ENCODER_TYPE_HDMI0);
989         KUNIT_EXPECT_NULL(test, new_vc4_crtc_state);
990 }
991
992 static struct kunit_case vc5_pv_muxing_bugs_tests[] = {
993         KUNIT_CASE(drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable),
994         KUNIT_CASE(drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable_too_many_crtc_state),
995         KUNIT_CASE(drm_test_vc5_pv_muxing_bugs_stable_fifo),
996         {}
997 };
998
999 static struct kunit_suite vc5_pv_muxing_bugs_test_suite = {
1000         .name = "vc5-pv-muxing-bugs",
1001         .test_cases = vc5_pv_muxing_bugs_tests,
1002 };
1003
1004 kunit_test_suites(
1005         &vc4_pv_muxing_test_suite,
1006         &vc5_pv_muxing_test_suite,
1007         &vc5_pv_muxing_bugs_test_suite
1008 );