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_TXP, 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_TXP, 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, drm, 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_TXP), 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_TXP), 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_TXP), 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_TXP), 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_TXP), 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_TXP), 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_TXP), 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_TXP), 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_TXP), 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_TXP, 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_TXP), 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_TXP), 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_TXP), 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_TXP), 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_TXP), 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_TXP), 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_TXP), 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_TXP), 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_TXP), 397 VC5_PV_MUXING_TEST("2 outputs: TXP, VEC", 398 VC4_ENCODER_TYPE_TXP, 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_TXP), 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_TXP, 419 VC4_ENCODER_TYPE_DSI1), 420 VC5_PV_MUXING_TEST("3 outputs: DPI, TXP, HDMI0", 421 VC4_ENCODER_TYPE_DPI, 422 VC4_ENCODER_TYPE_TXP, 423 VC4_ENCODER_TYPE_HDMI0), 424 VC5_PV_MUXING_TEST("3 outputs: DPI, TXP, HDMI1", 425 VC4_ENCODER_TYPE_DPI, 426 VC4_ENCODER_TYPE_TXP, 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_TXP), 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_TXP, 459 VC4_ENCODER_TYPE_DSI1), 460 VC5_PV_MUXING_TEST("3 outputs: DSI0, TXP, HDMI0", 461 VC4_ENCODER_TYPE_DSI0, 462 VC4_ENCODER_TYPE_TXP, 463 VC4_ENCODER_TYPE_HDMI0), 464 VC5_PV_MUXING_TEST("3 outputs: DSI0, TXP, HDMI1", 465 VC4_ENCODER_TYPE_DSI0, 466 VC4_ENCODER_TYPE_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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_TXP, 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 ); 1009