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_modeset_acquire_ctx ctx; 24 struct drm_atomic_state *state; 25 }; 26 27 static bool check_fifo_conflict(struct kunit *test, 28 const struct drm_atomic_state *state) 29 { 30 struct vc4_hvs_state *hvs_state; 31 unsigned int used_fifos = 0; 32 unsigned int i; 33 34 hvs_state = vc4_hvs_get_new_global_state(state); 35 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hvs_state); 36 37 for (i = 0; i < HVS_NUM_CHANNELS; i++) { 38 if (!hvs_state->fifo_state[i].in_use) 39 continue; 40 41 KUNIT_EXPECT_FALSE(test, used_fifos & BIT(i)); 42 used_fifos |= BIT(i); 43 } 44 45 return true; 46 } 47 48 struct encoder_constraint { 49 enum vc4_encoder_type type; 50 unsigned int *channels; 51 size_t nchannels; 52 }; 53 54 #define ENCODER_CONSTRAINT(_type, ...) \ 55 { \ 56 .type = _type, \ 57 .channels = (unsigned int[]) { __VA_ARGS__ }, \ 58 .nchannels = sizeof((unsigned int[]) { __VA_ARGS__ }) / \ 59 sizeof(unsigned int), \ 60 } 61 62 static bool __check_encoder_constraints(const struct encoder_constraint *constraints, 63 size_t nconstraints, 64 enum vc4_encoder_type type, 65 unsigned int channel) 66 { 67 unsigned int i; 68 69 for (i = 0; i < nconstraints; i++) { 70 const struct encoder_constraint *constraint = &constraints[i]; 71 unsigned int j; 72 73 if (constraint->type != type) 74 continue; 75 76 for (j = 0; j < constraint->nchannels; j++) { 77 unsigned int _channel = constraint->channels[j]; 78 79 if (channel != _channel) 80 continue; 81 82 return true; 83 } 84 } 85 86 return false; 87 } 88 89 static const struct encoder_constraint vc4_encoder_constraints[] = { 90 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_DPI, 0), 91 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_DSI0, 0), 92 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_HDMI0, 1), 93 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_VEC, 1), 94 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_TXP, 2), 95 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_DSI1, 2), 96 }; 97 98 static const struct encoder_constraint vc5_encoder_constraints[] = { 99 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_DPI, 0), 100 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_DSI0, 0), 101 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_VEC, 1), 102 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_TXP, 0, 2), 103 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_DSI1, 0, 1, 2), 104 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_HDMI0, 0, 1, 2), 105 ENCODER_CONSTRAINT(VC4_ENCODER_TYPE_HDMI1, 0, 1, 2), 106 }; 107 108 static bool check_vc4_encoder_constraints(enum vc4_encoder_type type, unsigned int channel) 109 { 110 return __check_encoder_constraints(vc4_encoder_constraints, 111 ARRAY_SIZE(vc4_encoder_constraints), 112 type, channel); 113 } 114 115 static bool check_vc5_encoder_constraints(enum vc4_encoder_type type, unsigned int channel) 116 { 117 return __check_encoder_constraints(vc5_encoder_constraints, 118 ARRAY_SIZE(vc5_encoder_constraints), 119 type, channel); 120 } 121 122 static struct vc4_crtc_state * 123 get_vc4_crtc_state_for_encoder(struct kunit *test, 124 const struct drm_atomic_state *state, 125 enum vc4_encoder_type type) 126 { 127 struct drm_device *drm = state->dev; 128 struct drm_crtc_state *new_crtc_state; 129 struct drm_encoder *encoder; 130 struct drm_crtc *crtc; 131 132 encoder = vc4_find_encoder_by_type(drm, type); 133 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, encoder); 134 135 crtc = vc4_find_crtc_for_encoder(test, drm, encoder); 136 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, crtc); 137 138 new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc); 139 if (!new_crtc_state) 140 return NULL; 141 142 return to_vc4_crtc_state(new_crtc_state); 143 } 144 145 static bool check_channel_for_encoder(struct kunit *test, 146 const struct drm_atomic_state *state, 147 enum vc4_encoder_type type, 148 bool (*check_fn)(enum vc4_encoder_type type, unsigned int channel)) 149 { 150 struct vc4_crtc_state *new_vc4_crtc_state; 151 struct vc4_hvs_state *new_hvs_state; 152 unsigned int channel; 153 154 new_hvs_state = vc4_hvs_get_new_global_state(state); 155 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state); 156 157 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state, type); 158 KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state); 159 160 channel = new_vc4_crtc_state->assigned_channel; 161 KUNIT_EXPECT_NE(test, channel, VC4_HVS_CHANNEL_DISABLED); 162 163 KUNIT_EXPECT_TRUE(test, new_hvs_state->fifo_state[channel].in_use); 164 165 KUNIT_EXPECT_TRUE(test, check_fn(type, channel)); 166 167 return true; 168 } 169 170 struct pv_muxing_param { 171 const char *name; 172 struct vc4_dev *(*mock_fn)(struct kunit *test); 173 bool (*check_fn)(enum vc4_encoder_type type, unsigned int channel); 174 enum vc4_encoder_type *encoders; 175 size_t nencoders; 176 }; 177 178 static void vc4_test_pv_muxing_desc(const struct pv_muxing_param *t, char *desc) 179 { 180 strscpy(desc, t->name, KUNIT_PARAM_DESC_SIZE); 181 } 182 183 #define PV_MUXING_TEST(_name, _mock_fn, _check_fn, ...) \ 184 { \ 185 .name = _name, \ 186 .mock_fn = &_mock_fn, \ 187 .check_fn = &_check_fn, \ 188 .encoders = (enum vc4_encoder_type[]) { __VA_ARGS__ }, \ 189 .nencoders = sizeof((enum vc4_encoder_type[]) { __VA_ARGS__ }) / \ 190 sizeof(enum vc4_encoder_type), \ 191 } 192 193 #define VC4_PV_MUXING_TEST(_name, ...) \ 194 PV_MUXING_TEST(_name, vc4_mock_device, check_vc4_encoder_constraints, __VA_ARGS__) 195 196 #define VC5_PV_MUXING_TEST(_name, ...) \ 197 PV_MUXING_TEST(_name, vc5_mock_device, check_vc5_encoder_constraints, __VA_ARGS__) 198 199 static const struct pv_muxing_param vc4_test_pv_muxing_params[] = { 200 VC4_PV_MUXING_TEST("1 output: DSI0", 201 VC4_ENCODER_TYPE_DSI0), 202 VC4_PV_MUXING_TEST("1 output: DPI", 203 VC4_ENCODER_TYPE_DPI), 204 VC4_PV_MUXING_TEST("1 output: HDMI0", 205 VC4_ENCODER_TYPE_HDMI0), 206 VC4_PV_MUXING_TEST("1 output: VEC", 207 VC4_ENCODER_TYPE_VEC), 208 VC4_PV_MUXING_TEST("1 output: DSI1", 209 VC4_ENCODER_TYPE_DSI1), 210 VC4_PV_MUXING_TEST("1 output: TXP", 211 VC4_ENCODER_TYPE_TXP), 212 VC4_PV_MUXING_TEST("2 outputs: DSI0, HDMI0", 213 VC4_ENCODER_TYPE_DSI0, 214 VC4_ENCODER_TYPE_HDMI0), 215 VC4_PV_MUXING_TEST("2 outputs: DSI0, VEC", 216 VC4_ENCODER_TYPE_DSI0, 217 VC4_ENCODER_TYPE_VEC), 218 VC4_PV_MUXING_TEST("2 outputs: DSI0, DSI1", 219 VC4_ENCODER_TYPE_DSI0, 220 VC4_ENCODER_TYPE_DSI1), 221 VC4_PV_MUXING_TEST("2 outputs: DSI0, TXP", 222 VC4_ENCODER_TYPE_DSI0, 223 VC4_ENCODER_TYPE_TXP), 224 VC4_PV_MUXING_TEST("2 outputs: DPI, HDMI0", 225 VC4_ENCODER_TYPE_DPI, 226 VC4_ENCODER_TYPE_HDMI0), 227 VC4_PV_MUXING_TEST("2 outputs: DPI, VEC", 228 VC4_ENCODER_TYPE_DPI, 229 VC4_ENCODER_TYPE_VEC), 230 VC4_PV_MUXING_TEST("2 outputs: DPI, DSI1", 231 VC4_ENCODER_TYPE_DPI, 232 VC4_ENCODER_TYPE_DSI1), 233 VC4_PV_MUXING_TEST("2 outputs: DPI, TXP", 234 VC4_ENCODER_TYPE_DPI, 235 VC4_ENCODER_TYPE_TXP), 236 VC4_PV_MUXING_TEST("2 outputs: HDMI0, DSI1", 237 VC4_ENCODER_TYPE_HDMI0, 238 VC4_ENCODER_TYPE_DSI1), 239 VC4_PV_MUXING_TEST("2 outputs: HDMI0, TXP", 240 VC4_ENCODER_TYPE_HDMI0, 241 VC4_ENCODER_TYPE_TXP), 242 VC4_PV_MUXING_TEST("2 outputs: VEC, DSI1", 243 VC4_ENCODER_TYPE_VEC, 244 VC4_ENCODER_TYPE_DSI1), 245 VC4_PV_MUXING_TEST("2 outputs: VEC, TXP", 246 VC4_ENCODER_TYPE_VEC, 247 VC4_ENCODER_TYPE_TXP), 248 VC4_PV_MUXING_TEST("3 outputs: DSI0, HDMI0, DSI1", 249 VC4_ENCODER_TYPE_DSI0, 250 VC4_ENCODER_TYPE_HDMI0, 251 VC4_ENCODER_TYPE_DSI1), 252 VC4_PV_MUXING_TEST("3 outputs: DSI0, HDMI0, TXP", 253 VC4_ENCODER_TYPE_DSI0, 254 VC4_ENCODER_TYPE_HDMI0, 255 VC4_ENCODER_TYPE_TXP), 256 VC4_PV_MUXING_TEST("3 outputs: DSI0, VEC, DSI1", 257 VC4_ENCODER_TYPE_DSI0, 258 VC4_ENCODER_TYPE_VEC, 259 VC4_ENCODER_TYPE_DSI1), 260 VC4_PV_MUXING_TEST("3 outputs: DSI0, VEC, TXP", 261 VC4_ENCODER_TYPE_DSI0, 262 VC4_ENCODER_TYPE_VEC, 263 VC4_ENCODER_TYPE_TXP), 264 VC4_PV_MUXING_TEST("3 outputs: DPI, HDMI0, DSI1", 265 VC4_ENCODER_TYPE_DPI, 266 VC4_ENCODER_TYPE_HDMI0, 267 VC4_ENCODER_TYPE_DSI1), 268 VC4_PV_MUXING_TEST("3 outputs: DPI, HDMI0, TXP", 269 VC4_ENCODER_TYPE_DPI, 270 VC4_ENCODER_TYPE_HDMI0, 271 VC4_ENCODER_TYPE_TXP), 272 VC4_PV_MUXING_TEST("3 outputs: DPI, VEC, DSI1", 273 VC4_ENCODER_TYPE_DPI, 274 VC4_ENCODER_TYPE_VEC, 275 VC4_ENCODER_TYPE_DSI1), 276 VC4_PV_MUXING_TEST("3 outputs: DPI, VEC, TXP", 277 VC4_ENCODER_TYPE_DPI, 278 VC4_ENCODER_TYPE_VEC, 279 VC4_ENCODER_TYPE_TXP), 280 }; 281 282 KUNIT_ARRAY_PARAM(vc4_test_pv_muxing, 283 vc4_test_pv_muxing_params, 284 vc4_test_pv_muxing_desc); 285 286 static const struct pv_muxing_param vc4_test_pv_muxing_invalid_params[] = { 287 VC4_PV_MUXING_TEST("DPI/DSI0 Conflict", 288 VC4_ENCODER_TYPE_DPI, 289 VC4_ENCODER_TYPE_DSI0), 290 VC4_PV_MUXING_TEST("TXP/DSI1 Conflict", 291 VC4_ENCODER_TYPE_TXP, 292 VC4_ENCODER_TYPE_DSI1), 293 VC4_PV_MUXING_TEST("HDMI0/VEC Conflict", 294 VC4_ENCODER_TYPE_HDMI0, 295 VC4_ENCODER_TYPE_VEC), 296 VC4_PV_MUXING_TEST("More than 3 outputs: DSI0, HDMI0, DSI1, TXP", 297 VC4_ENCODER_TYPE_DSI0, 298 VC4_ENCODER_TYPE_HDMI0, 299 VC4_ENCODER_TYPE_DSI1, 300 VC4_ENCODER_TYPE_TXP), 301 VC4_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, DSI1, TXP", 302 VC4_ENCODER_TYPE_DSI0, 303 VC4_ENCODER_TYPE_VEC, 304 VC4_ENCODER_TYPE_DSI1, 305 VC4_ENCODER_TYPE_TXP), 306 VC4_PV_MUXING_TEST("More than 3 outputs: DPI, HDMI0, DSI1, TXP", 307 VC4_ENCODER_TYPE_DPI, 308 VC4_ENCODER_TYPE_HDMI0, 309 VC4_ENCODER_TYPE_DSI1, 310 VC4_ENCODER_TYPE_TXP), 311 VC4_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, DSI1, TXP", 312 VC4_ENCODER_TYPE_DPI, 313 VC4_ENCODER_TYPE_VEC, 314 VC4_ENCODER_TYPE_DSI1, 315 VC4_ENCODER_TYPE_TXP), 316 }; 317 318 KUNIT_ARRAY_PARAM(vc4_test_pv_muxing_invalid, 319 vc4_test_pv_muxing_invalid_params, 320 vc4_test_pv_muxing_desc); 321 322 static const struct pv_muxing_param vc5_test_pv_muxing_params[] = { 323 VC5_PV_MUXING_TEST("1 output: DPI", 324 VC4_ENCODER_TYPE_DPI), 325 VC5_PV_MUXING_TEST("1 output: DSI0", 326 VC4_ENCODER_TYPE_DSI0), 327 VC5_PV_MUXING_TEST("1 output: DSI1", 328 VC4_ENCODER_TYPE_DSI1), 329 VC5_PV_MUXING_TEST("1 output: HDMI0", 330 VC4_ENCODER_TYPE_HDMI0), 331 VC5_PV_MUXING_TEST("1 output: HDMI1", 332 VC4_ENCODER_TYPE_HDMI1), 333 VC5_PV_MUXING_TEST("1 output: VEC", 334 VC4_ENCODER_TYPE_VEC), 335 VC5_PV_MUXING_TEST("2 outputs: DPI, DSI1", 336 VC4_ENCODER_TYPE_DPI, 337 VC4_ENCODER_TYPE_DSI1), 338 VC5_PV_MUXING_TEST("2 outputs: DPI, HDMI0", 339 VC4_ENCODER_TYPE_DPI, 340 VC4_ENCODER_TYPE_HDMI0), 341 VC5_PV_MUXING_TEST("2 outputs: DPI, HDMI1", 342 VC4_ENCODER_TYPE_DPI, 343 VC4_ENCODER_TYPE_HDMI1), 344 VC5_PV_MUXING_TEST("2 outputs: DPI, TXP", 345 VC4_ENCODER_TYPE_DPI, 346 VC4_ENCODER_TYPE_TXP), 347 VC5_PV_MUXING_TEST("2 outputs: DPI, VEC", 348 VC4_ENCODER_TYPE_DPI, 349 VC4_ENCODER_TYPE_VEC), 350 VC5_PV_MUXING_TEST("2 outputs: DPI, DSI1", 351 VC4_ENCODER_TYPE_DPI, 352 VC4_ENCODER_TYPE_DSI1), 353 VC5_PV_MUXING_TEST("2 outputs: DSI0, DSI1", 354 VC4_ENCODER_TYPE_DSI0, 355 VC4_ENCODER_TYPE_DSI1), 356 VC5_PV_MUXING_TEST("2 outputs: DSI0, HDMI0", 357 VC4_ENCODER_TYPE_DSI0, 358 VC4_ENCODER_TYPE_HDMI0), 359 VC5_PV_MUXING_TEST("2 outputs: DSI0, HDMI1", 360 VC4_ENCODER_TYPE_DSI0, 361 VC4_ENCODER_TYPE_HDMI1), 362 VC5_PV_MUXING_TEST("2 outputs: DSI0, TXP", 363 VC4_ENCODER_TYPE_DSI0, 364 VC4_ENCODER_TYPE_TXP), 365 VC5_PV_MUXING_TEST("2 outputs: DSI0, VEC", 366 VC4_ENCODER_TYPE_DSI0, 367 VC4_ENCODER_TYPE_VEC), 368 VC5_PV_MUXING_TEST("2 outputs: DSI0, DSI1", 369 VC4_ENCODER_TYPE_DSI0, 370 VC4_ENCODER_TYPE_DSI1), 371 VC5_PV_MUXING_TEST("2 outputs: DSI1, VEC", 372 VC4_ENCODER_TYPE_DSI1, 373 VC4_ENCODER_TYPE_VEC), 374 VC5_PV_MUXING_TEST("2 outputs: DSI1, TXP", 375 VC4_ENCODER_TYPE_DSI1, 376 VC4_ENCODER_TYPE_TXP), 377 VC5_PV_MUXING_TEST("2 outputs: DSI1, HDMI0", 378 VC4_ENCODER_TYPE_DSI1, 379 VC4_ENCODER_TYPE_HDMI0), 380 VC5_PV_MUXING_TEST("2 outputs: DSI1, HDMI1", 381 VC4_ENCODER_TYPE_DSI1, 382 VC4_ENCODER_TYPE_HDMI1), 383 VC5_PV_MUXING_TEST("2 outputs: HDMI0, VEC", 384 VC4_ENCODER_TYPE_HDMI0, 385 VC4_ENCODER_TYPE_VEC), 386 VC5_PV_MUXING_TEST("2 outputs: HDMI0, TXP", 387 VC4_ENCODER_TYPE_HDMI0, 388 VC4_ENCODER_TYPE_TXP), 389 VC5_PV_MUXING_TEST("2 outputs: HDMI0, HDMI1", 390 VC4_ENCODER_TYPE_HDMI0, 391 VC4_ENCODER_TYPE_HDMI1), 392 VC5_PV_MUXING_TEST("2 outputs: HDMI1, VEC", 393 VC4_ENCODER_TYPE_HDMI1, 394 VC4_ENCODER_TYPE_VEC), 395 VC5_PV_MUXING_TEST("2 outputs: HDMI1, TXP", 396 VC4_ENCODER_TYPE_HDMI1, 397 VC4_ENCODER_TYPE_TXP), 398 VC5_PV_MUXING_TEST("2 outputs: TXP, VEC", 399 VC4_ENCODER_TYPE_TXP, 400 VC4_ENCODER_TYPE_VEC), 401 VC5_PV_MUXING_TEST("3 outputs: DPI, VEC, TXP", 402 VC4_ENCODER_TYPE_DPI, 403 VC4_ENCODER_TYPE_VEC, 404 VC4_ENCODER_TYPE_TXP), 405 VC5_PV_MUXING_TEST("3 outputs: DPI, VEC, DSI1", 406 VC4_ENCODER_TYPE_DPI, 407 VC4_ENCODER_TYPE_VEC, 408 VC4_ENCODER_TYPE_DSI1), 409 VC5_PV_MUXING_TEST("3 outputs: DPI, VEC, HDMI0", 410 VC4_ENCODER_TYPE_DPI, 411 VC4_ENCODER_TYPE_VEC, 412 VC4_ENCODER_TYPE_HDMI0), 413 VC5_PV_MUXING_TEST("3 outputs: DPI, VEC, HDMI1", 414 VC4_ENCODER_TYPE_DPI, 415 VC4_ENCODER_TYPE_VEC, 416 VC4_ENCODER_TYPE_HDMI1), 417 VC5_PV_MUXING_TEST("3 outputs: DPI, TXP, DSI1", 418 VC4_ENCODER_TYPE_DPI, 419 VC4_ENCODER_TYPE_TXP, 420 VC4_ENCODER_TYPE_DSI1), 421 VC5_PV_MUXING_TEST("3 outputs: DPI, TXP, HDMI0", 422 VC4_ENCODER_TYPE_DPI, 423 VC4_ENCODER_TYPE_TXP, 424 VC4_ENCODER_TYPE_HDMI0), 425 VC5_PV_MUXING_TEST("3 outputs: DPI, TXP, HDMI1", 426 VC4_ENCODER_TYPE_DPI, 427 VC4_ENCODER_TYPE_TXP, 428 VC4_ENCODER_TYPE_HDMI1), 429 VC5_PV_MUXING_TEST("3 outputs: DPI, DSI1, HDMI0", 430 VC4_ENCODER_TYPE_DPI, 431 VC4_ENCODER_TYPE_DSI1, 432 VC4_ENCODER_TYPE_HDMI0), 433 VC5_PV_MUXING_TEST("3 outputs: DPI, DSI1, HDMI1", 434 VC4_ENCODER_TYPE_DPI, 435 VC4_ENCODER_TYPE_DSI1, 436 VC4_ENCODER_TYPE_HDMI1), 437 VC5_PV_MUXING_TEST("3 outputs: DPI, HDMI0, HDMI1", 438 VC4_ENCODER_TYPE_DPI, 439 VC4_ENCODER_TYPE_HDMI0, 440 VC4_ENCODER_TYPE_HDMI1), 441 VC5_PV_MUXING_TEST("3 outputs: DSI0, VEC, TXP", 442 VC4_ENCODER_TYPE_DSI0, 443 VC4_ENCODER_TYPE_VEC, 444 VC4_ENCODER_TYPE_TXP), 445 VC5_PV_MUXING_TEST("3 outputs: DSI0, VEC, DSI1", 446 VC4_ENCODER_TYPE_DSI0, 447 VC4_ENCODER_TYPE_VEC, 448 VC4_ENCODER_TYPE_DSI1), 449 VC5_PV_MUXING_TEST("3 outputs: DSI0, VEC, HDMI0", 450 VC4_ENCODER_TYPE_DSI0, 451 VC4_ENCODER_TYPE_VEC, 452 VC4_ENCODER_TYPE_HDMI0), 453 VC5_PV_MUXING_TEST("3 outputs: DSI0, VEC, HDMI1", 454 VC4_ENCODER_TYPE_DSI0, 455 VC4_ENCODER_TYPE_VEC, 456 VC4_ENCODER_TYPE_HDMI1), 457 VC5_PV_MUXING_TEST("3 outputs: DSI0, TXP, DSI1", 458 VC4_ENCODER_TYPE_DSI0, 459 VC4_ENCODER_TYPE_TXP, 460 VC4_ENCODER_TYPE_DSI1), 461 VC5_PV_MUXING_TEST("3 outputs: DSI0, TXP, HDMI0", 462 VC4_ENCODER_TYPE_DSI0, 463 VC4_ENCODER_TYPE_TXP, 464 VC4_ENCODER_TYPE_HDMI0), 465 VC5_PV_MUXING_TEST("3 outputs: DSI0, TXP, HDMI1", 466 VC4_ENCODER_TYPE_DSI0, 467 VC4_ENCODER_TYPE_TXP, 468 VC4_ENCODER_TYPE_HDMI1), 469 VC5_PV_MUXING_TEST("3 outputs: DSI0, DSI1, HDMI0", 470 VC4_ENCODER_TYPE_DSI0, 471 VC4_ENCODER_TYPE_DSI1, 472 VC4_ENCODER_TYPE_HDMI0), 473 VC5_PV_MUXING_TEST("3 outputs: DSI0, DSI1, HDMI1", 474 VC4_ENCODER_TYPE_DSI0, 475 VC4_ENCODER_TYPE_DSI1, 476 VC4_ENCODER_TYPE_HDMI1), 477 VC5_PV_MUXING_TEST("3 outputs: DSI0, HDMI0, HDMI1", 478 VC4_ENCODER_TYPE_DSI0, 479 VC4_ENCODER_TYPE_HDMI0, 480 VC4_ENCODER_TYPE_HDMI1), 481 }; 482 483 KUNIT_ARRAY_PARAM(vc5_test_pv_muxing, 484 vc5_test_pv_muxing_params, 485 vc4_test_pv_muxing_desc); 486 487 static const struct pv_muxing_param vc5_test_pv_muxing_invalid_params[] = { 488 VC5_PV_MUXING_TEST("DPI/DSI0 Conflict", 489 VC4_ENCODER_TYPE_DPI, 490 VC4_ENCODER_TYPE_DSI0), 491 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, DSI1", 492 VC4_ENCODER_TYPE_DPI, 493 VC4_ENCODER_TYPE_VEC, 494 VC4_ENCODER_TYPE_TXP, 495 VC4_ENCODER_TYPE_DSI1), 496 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, HDMI0", 497 VC4_ENCODER_TYPE_DPI, 498 VC4_ENCODER_TYPE_VEC, 499 VC4_ENCODER_TYPE_TXP, 500 VC4_ENCODER_TYPE_HDMI0), 501 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, HDMI1", 502 VC4_ENCODER_TYPE_DPI, 503 VC4_ENCODER_TYPE_VEC, 504 VC4_ENCODER_TYPE_TXP, 505 VC4_ENCODER_TYPE_HDMI1), 506 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, DSI1, HDMI0", 507 VC4_ENCODER_TYPE_DPI, 508 VC4_ENCODER_TYPE_VEC, 509 VC4_ENCODER_TYPE_DSI1, 510 VC4_ENCODER_TYPE_HDMI0), 511 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, DSI1, HDMI1", 512 VC4_ENCODER_TYPE_DPI, 513 VC4_ENCODER_TYPE_VEC, 514 VC4_ENCODER_TYPE_DSI1, 515 VC4_ENCODER_TYPE_HDMI1), 516 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, HDMI0, HDMI1", 517 VC4_ENCODER_TYPE_DPI, 518 VC4_ENCODER_TYPE_VEC, 519 VC4_ENCODER_TYPE_HDMI0, 520 VC4_ENCODER_TYPE_HDMI1), 521 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, TXP, DSI1, HDMI0", 522 VC4_ENCODER_TYPE_DPI, 523 VC4_ENCODER_TYPE_TXP, 524 VC4_ENCODER_TYPE_DSI1, 525 VC4_ENCODER_TYPE_HDMI0), 526 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, TXP, DSI1, HDMI1", 527 VC4_ENCODER_TYPE_DPI, 528 VC4_ENCODER_TYPE_TXP, 529 VC4_ENCODER_TYPE_DSI1, 530 VC4_ENCODER_TYPE_HDMI1), 531 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, TXP, HDMI0, HDMI1", 532 VC4_ENCODER_TYPE_DPI, 533 VC4_ENCODER_TYPE_TXP, 534 VC4_ENCODER_TYPE_HDMI0, 535 VC4_ENCODER_TYPE_HDMI1), 536 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, DSI1, HDMI0, HDMI1", 537 VC4_ENCODER_TYPE_DPI, 538 VC4_ENCODER_TYPE_DSI1, 539 VC4_ENCODER_TYPE_HDMI0, 540 VC4_ENCODER_TYPE_HDMI1), 541 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, DSI1, HDMI0", 542 VC4_ENCODER_TYPE_DPI, 543 VC4_ENCODER_TYPE_VEC, 544 VC4_ENCODER_TYPE_TXP, 545 VC4_ENCODER_TYPE_DSI1, 546 VC4_ENCODER_TYPE_HDMI0), 547 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, DSI1, HDMI1", 548 VC4_ENCODER_TYPE_DPI, 549 VC4_ENCODER_TYPE_VEC, 550 VC4_ENCODER_TYPE_TXP, 551 VC4_ENCODER_TYPE_DSI1, 552 VC4_ENCODER_TYPE_HDMI1), 553 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, HDMI0, HDMI1", 554 VC4_ENCODER_TYPE_DPI, 555 VC4_ENCODER_TYPE_VEC, 556 VC4_ENCODER_TYPE_TXP, 557 VC4_ENCODER_TYPE_HDMI0, 558 VC4_ENCODER_TYPE_HDMI1), 559 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, DSI1, HDMI0, HDMI1", 560 VC4_ENCODER_TYPE_DPI, 561 VC4_ENCODER_TYPE_VEC, 562 VC4_ENCODER_TYPE_DSI1, 563 VC4_ENCODER_TYPE_HDMI0, 564 VC4_ENCODER_TYPE_HDMI1), 565 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, TXP, DSI1, HDMI0, HDMI1", 566 VC4_ENCODER_TYPE_DPI, 567 VC4_ENCODER_TYPE_TXP, 568 VC4_ENCODER_TYPE_DSI1, 569 VC4_ENCODER_TYPE_HDMI0, 570 VC4_ENCODER_TYPE_HDMI1), 571 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, DSI1", 572 VC4_ENCODER_TYPE_DSI0, 573 VC4_ENCODER_TYPE_VEC, 574 VC4_ENCODER_TYPE_TXP, 575 VC4_ENCODER_TYPE_DSI1), 576 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, HDMI0", 577 VC4_ENCODER_TYPE_DSI0, 578 VC4_ENCODER_TYPE_VEC, 579 VC4_ENCODER_TYPE_TXP, 580 VC4_ENCODER_TYPE_HDMI0), 581 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, HDMI1", 582 VC4_ENCODER_TYPE_DSI0, 583 VC4_ENCODER_TYPE_VEC, 584 VC4_ENCODER_TYPE_TXP, 585 VC4_ENCODER_TYPE_HDMI1), 586 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, DSI1, HDMI0", 587 VC4_ENCODER_TYPE_DSI0, 588 VC4_ENCODER_TYPE_VEC, 589 VC4_ENCODER_TYPE_DSI1, 590 VC4_ENCODER_TYPE_HDMI0), 591 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, DSI1, HDMI1", 592 VC4_ENCODER_TYPE_DSI0, 593 VC4_ENCODER_TYPE_VEC, 594 VC4_ENCODER_TYPE_DSI1, 595 VC4_ENCODER_TYPE_HDMI1), 596 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, HDMI0, HDMI1", 597 VC4_ENCODER_TYPE_DSI0, 598 VC4_ENCODER_TYPE_VEC, 599 VC4_ENCODER_TYPE_HDMI0, 600 VC4_ENCODER_TYPE_HDMI1), 601 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, TXP, DSI1, HDMI0", 602 VC4_ENCODER_TYPE_DSI0, 603 VC4_ENCODER_TYPE_TXP, 604 VC4_ENCODER_TYPE_DSI1, 605 VC4_ENCODER_TYPE_HDMI0), 606 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, TXP, DSI1, HDMI1", 607 VC4_ENCODER_TYPE_DSI0, 608 VC4_ENCODER_TYPE_TXP, 609 VC4_ENCODER_TYPE_DSI1, 610 VC4_ENCODER_TYPE_HDMI1), 611 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, TXP, HDMI0, HDMI1", 612 VC4_ENCODER_TYPE_DSI0, 613 VC4_ENCODER_TYPE_TXP, 614 VC4_ENCODER_TYPE_HDMI0, 615 VC4_ENCODER_TYPE_HDMI1), 616 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, DSI1, HDMI0, HDMI1", 617 VC4_ENCODER_TYPE_DSI0, 618 VC4_ENCODER_TYPE_DSI1, 619 VC4_ENCODER_TYPE_HDMI0, 620 VC4_ENCODER_TYPE_HDMI1), 621 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, DSI1, HDMI0", 622 VC4_ENCODER_TYPE_DSI0, 623 VC4_ENCODER_TYPE_VEC, 624 VC4_ENCODER_TYPE_TXP, 625 VC4_ENCODER_TYPE_DSI1, 626 VC4_ENCODER_TYPE_HDMI0), 627 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, DSI1, HDMI1", 628 VC4_ENCODER_TYPE_DSI0, 629 VC4_ENCODER_TYPE_VEC, 630 VC4_ENCODER_TYPE_TXP, 631 VC4_ENCODER_TYPE_DSI1, 632 VC4_ENCODER_TYPE_HDMI1), 633 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, HDMI0, HDMI1", 634 VC4_ENCODER_TYPE_DSI0, 635 VC4_ENCODER_TYPE_VEC, 636 VC4_ENCODER_TYPE_TXP, 637 VC4_ENCODER_TYPE_HDMI0, 638 VC4_ENCODER_TYPE_HDMI1), 639 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, DSI1, HDMI0, HDMI1", 640 VC4_ENCODER_TYPE_DSI0, 641 VC4_ENCODER_TYPE_VEC, 642 VC4_ENCODER_TYPE_DSI1, 643 VC4_ENCODER_TYPE_HDMI0, 644 VC4_ENCODER_TYPE_HDMI1), 645 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, TXP, DSI1, HDMI0, HDMI1", 646 VC4_ENCODER_TYPE_DSI0, 647 VC4_ENCODER_TYPE_TXP, 648 VC4_ENCODER_TYPE_DSI1, 649 VC4_ENCODER_TYPE_HDMI0, 650 VC4_ENCODER_TYPE_HDMI1), 651 VC5_PV_MUXING_TEST("More than 3 outputs: VEC, TXP, DSI1, HDMI0, HDMI1", 652 VC4_ENCODER_TYPE_VEC, 653 VC4_ENCODER_TYPE_TXP, 654 VC4_ENCODER_TYPE_DSI1, 655 VC4_ENCODER_TYPE_HDMI0, 656 VC4_ENCODER_TYPE_HDMI1), 657 VC5_PV_MUXING_TEST("More than 3 outputs: DPI, VEC, TXP, DSI1, HDMI0, HDMI1", 658 VC4_ENCODER_TYPE_DPI, 659 VC4_ENCODER_TYPE_VEC, 660 VC4_ENCODER_TYPE_TXP, 661 VC4_ENCODER_TYPE_DSI1, 662 VC4_ENCODER_TYPE_HDMI0, 663 VC4_ENCODER_TYPE_HDMI1), 664 VC5_PV_MUXING_TEST("More than 3 outputs: DSI0, VEC, TXP, DSI1, HDMI0, HDMI1", 665 VC4_ENCODER_TYPE_DSI0, 666 VC4_ENCODER_TYPE_VEC, 667 VC4_ENCODER_TYPE_TXP, 668 VC4_ENCODER_TYPE_DSI1, 669 VC4_ENCODER_TYPE_HDMI0, 670 VC4_ENCODER_TYPE_HDMI1), 671 }; 672 673 KUNIT_ARRAY_PARAM(vc5_test_pv_muxing_invalid, 674 vc5_test_pv_muxing_invalid_params, 675 vc4_test_pv_muxing_desc); 676 677 static void drm_vc4_test_pv_muxing(struct kunit *test) 678 { 679 const struct pv_muxing_param *params = test->param_value; 680 const struct pv_muxing_priv *priv = test->priv; 681 struct drm_atomic_state *state = priv->state; 682 unsigned int i; 683 int ret; 684 685 for (i = 0; i < params->nencoders; i++) { 686 enum vc4_encoder_type enc_type = params->encoders[i]; 687 688 ret = vc4_mock_atomic_add_output(test, state, enc_type); 689 KUNIT_ASSERT_EQ(test, ret, 0); 690 } 691 692 ret = drm_atomic_check_only(state); 693 KUNIT_EXPECT_EQ(test, ret, 0); 694 695 KUNIT_EXPECT_TRUE(test, 696 check_fifo_conflict(test, state)); 697 698 for (i = 0; i < params->nencoders; i++) { 699 enum vc4_encoder_type enc_type = params->encoders[i]; 700 701 KUNIT_EXPECT_TRUE(test, check_channel_for_encoder(test, state, enc_type, 702 params->check_fn)); 703 } 704 } 705 706 static void drm_vc4_test_pv_muxing_invalid(struct kunit *test) 707 { 708 const struct pv_muxing_param *params = test->param_value; 709 const struct pv_muxing_priv *priv = test->priv; 710 struct drm_atomic_state *state = priv->state; 711 unsigned int i; 712 int ret; 713 714 for (i = 0; i < params->nencoders; i++) { 715 enum vc4_encoder_type enc_type = params->encoders[i]; 716 717 ret = vc4_mock_atomic_add_output(test, state, enc_type); 718 KUNIT_ASSERT_EQ(test, ret, 0); 719 } 720 721 ret = drm_atomic_check_only(state); 722 KUNIT_EXPECT_LT(test, ret, 0); 723 } 724 725 static int vc4_pv_muxing_test_init(struct kunit *test) 726 { 727 const struct pv_muxing_param *params = test->param_value; 728 struct drm_atomic_state *state; 729 struct pv_muxing_priv *priv; 730 struct drm_device *drm; 731 struct vc4_dev *vc4; 732 733 priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); 734 KUNIT_ASSERT_NOT_NULL(test, priv); 735 test->priv = priv; 736 737 vc4 = params->mock_fn(test); 738 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4); 739 priv->vc4 = vc4; 740 741 drm_modeset_acquire_init(&priv->ctx, 0); 742 743 drm = &vc4->base; 744 state = drm_atomic_state_alloc(drm); 745 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 746 747 state->acquire_ctx = &priv->ctx; 748 749 priv->state = state; 750 751 return 0; 752 } 753 754 static void vc4_pv_muxing_test_exit(struct kunit *test) 755 { 756 struct pv_muxing_priv *priv = test->priv; 757 struct vc4_dev *vc4 = priv->vc4; 758 struct drm_device *drm = &vc4->base; 759 struct drm_atomic_state *state = priv->state; 760 761 drm_atomic_state_put(state); 762 drm_modeset_drop_locks(&priv->ctx); 763 drm_modeset_acquire_fini(&priv->ctx); 764 drm_dev_unregister(drm); 765 drm_kunit_helper_free_device(test, vc4->dev); 766 } 767 768 static struct kunit_case vc4_pv_muxing_tests[] = { 769 KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing, 770 vc4_test_pv_muxing_gen_params), 771 KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing_invalid, 772 vc4_test_pv_muxing_invalid_gen_params), 773 {} 774 }; 775 776 static struct kunit_suite vc4_pv_muxing_test_suite = { 777 .name = "vc4-pv-muxing-combinations", 778 .init = vc4_pv_muxing_test_init, 779 .exit = vc4_pv_muxing_test_exit, 780 .test_cases = vc4_pv_muxing_tests, 781 }; 782 783 static struct kunit_case vc5_pv_muxing_tests[] = { 784 KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing, 785 vc5_test_pv_muxing_gen_params), 786 KUNIT_CASE_PARAM(drm_vc4_test_pv_muxing_invalid, 787 vc5_test_pv_muxing_invalid_gen_params), 788 {} 789 }; 790 791 static struct kunit_suite vc5_pv_muxing_test_suite = { 792 .name = "vc5-pv-muxing-combinations", 793 .init = vc4_pv_muxing_test_init, 794 .exit = vc4_pv_muxing_test_exit, 795 .test_cases = vc5_pv_muxing_tests, 796 }; 797 798 /* See 799 * https://lore.kernel.org/all/3e113525-aa89-b1e2-56b7-ca55bd41d057@samsung.com/ 800 * and 801 * https://lore.kernel.org/dri-devel/20200917121623.42023-1-maxime@cerno.tech/ 802 */ 803 static void drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable(struct kunit *test) 804 { 805 struct drm_modeset_acquire_ctx ctx; 806 struct drm_atomic_state *state; 807 struct vc4_crtc_state *new_vc4_crtc_state; 808 struct vc4_hvs_state *new_hvs_state; 809 unsigned int hdmi0_channel; 810 unsigned int hdmi1_channel; 811 struct drm_device *drm; 812 struct vc4_dev *vc4; 813 int ret; 814 815 vc4 = vc5_mock_device(test); 816 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4); 817 818 drm_modeset_acquire_init(&ctx, 0); 819 820 drm = &vc4->base; 821 state = drm_atomic_state_alloc(drm); 822 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 823 824 state->acquire_ctx = &ctx; 825 826 ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI0); 827 KUNIT_ASSERT_EQ(test, ret, 0); 828 829 ret = drm_atomic_check_only(state); 830 KUNIT_ASSERT_EQ(test, ret, 0); 831 832 new_hvs_state = vc4_hvs_get_new_global_state(state); 833 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state); 834 835 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state, 836 VC4_ENCODER_TYPE_HDMI0); 837 KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state); 838 839 hdmi0_channel = new_vc4_crtc_state->assigned_channel; 840 KUNIT_ASSERT_NE(test, hdmi0_channel, VC4_HVS_CHANNEL_DISABLED); 841 KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[hdmi0_channel].in_use); 842 843 ret = drm_atomic_helper_swap_state(state, false); 844 KUNIT_ASSERT_EQ(test, ret, 0); 845 846 drm_atomic_state_put(state); 847 848 state = drm_atomic_state_alloc(drm); 849 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 850 851 state->acquire_ctx = &ctx; 852 853 ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI1); 854 KUNIT_ASSERT_EQ(test, ret, 0); 855 856 ret = drm_atomic_check_only(state); 857 KUNIT_ASSERT_EQ(test, ret, 0); 858 859 new_hvs_state = vc4_hvs_get_new_global_state(state); 860 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state); 861 862 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state, 863 VC4_ENCODER_TYPE_HDMI1); 864 KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state); 865 866 hdmi1_channel = new_vc4_crtc_state->assigned_channel; 867 KUNIT_ASSERT_NE(test, hdmi1_channel, VC4_HVS_CHANNEL_DISABLED); 868 KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[hdmi1_channel].in_use); 869 870 KUNIT_EXPECT_NE(test, hdmi0_channel, hdmi1_channel); 871 872 drm_atomic_state_put(state); 873 drm_modeset_drop_locks(&ctx); 874 drm_modeset_acquire_fini(&ctx); 875 drm_dev_unregister(drm); 876 drm_kunit_helper_free_device(test, vc4->dev); 877 } 878 879 static void drm_test_vc5_pv_muxing_bugs_stable_fifo(struct kunit *test) 880 { 881 struct drm_modeset_acquire_ctx ctx; 882 struct drm_atomic_state *state; 883 struct vc4_crtc_state *new_vc4_crtc_state; 884 struct vc4_hvs_state *new_hvs_state; 885 unsigned int old_hdmi0_channel; 886 unsigned int old_hdmi1_channel; 887 struct drm_device *drm; 888 struct vc4_dev *vc4; 889 int ret; 890 891 vc4 = vc5_mock_device(test); 892 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4); 893 894 drm_modeset_acquire_init(&ctx, 0); 895 896 drm = &vc4->base; 897 state = drm_atomic_state_alloc(drm); 898 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 899 900 state->acquire_ctx = &ctx; 901 902 ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI0); 903 KUNIT_ASSERT_EQ(test, ret, 0); 904 905 ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI1); 906 KUNIT_ASSERT_EQ(test, ret, 0); 907 908 ret = drm_atomic_check_only(state); 909 KUNIT_ASSERT_EQ(test, ret, 0); 910 911 new_hvs_state = vc4_hvs_get_new_global_state(state); 912 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state); 913 914 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state, 915 VC4_ENCODER_TYPE_HDMI0); 916 KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state); 917 918 old_hdmi0_channel = new_vc4_crtc_state->assigned_channel; 919 KUNIT_ASSERT_NE(test, old_hdmi0_channel, VC4_HVS_CHANNEL_DISABLED); 920 KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[old_hdmi0_channel].in_use); 921 922 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state, 923 VC4_ENCODER_TYPE_HDMI1); 924 KUNIT_ASSERT_NOT_NULL(test, new_vc4_crtc_state); 925 926 old_hdmi1_channel = new_vc4_crtc_state->assigned_channel; 927 KUNIT_ASSERT_NE(test, old_hdmi1_channel, VC4_HVS_CHANNEL_DISABLED); 928 KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[old_hdmi1_channel].in_use); 929 930 ret = drm_atomic_helper_swap_state(state, false); 931 KUNIT_ASSERT_EQ(test, ret, 0); 932 933 drm_atomic_state_put(state); 934 935 state = drm_atomic_state_alloc(drm); 936 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 937 938 state->acquire_ctx = &ctx; 939 940 ret = vc4_mock_atomic_del_output(test, state, VC4_ENCODER_TYPE_HDMI0); 941 KUNIT_ASSERT_EQ(test, ret, 0); 942 943 ret = drm_atomic_check_only(state); 944 KUNIT_ASSERT_EQ(test, ret, 0); 945 946 new_hvs_state = vc4_hvs_get_new_global_state(state); 947 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_hvs_state); 948 949 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state, 950 VC4_ENCODER_TYPE_HDMI1); 951 952 if (new_vc4_crtc_state) { 953 unsigned int hdmi1_channel; 954 955 hdmi1_channel = new_vc4_crtc_state->assigned_channel; 956 KUNIT_ASSERT_NE(test, hdmi1_channel, VC4_HVS_CHANNEL_DISABLED); 957 KUNIT_ASSERT_TRUE(test, new_hvs_state->fifo_state[hdmi1_channel].in_use); 958 959 KUNIT_EXPECT_EQ(test, old_hdmi1_channel, hdmi1_channel); 960 } 961 962 drm_atomic_state_put(state); 963 drm_modeset_drop_locks(&ctx); 964 drm_modeset_acquire_fini(&ctx); 965 drm_dev_unregister(drm); 966 drm_kunit_helper_free_device(test, vc4->dev); 967 } 968 969 static void 970 drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable_too_many_crtc_state(struct kunit *test) 971 { 972 struct drm_modeset_acquire_ctx ctx; 973 struct drm_atomic_state *state; 974 struct vc4_crtc_state *new_vc4_crtc_state; 975 struct drm_device *drm; 976 struct vc4_dev *vc4; 977 int ret; 978 979 vc4 = vc5_mock_device(test); 980 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, vc4); 981 982 drm_modeset_acquire_init(&ctx, 0); 983 984 drm = &vc4->base; 985 state = drm_atomic_state_alloc(drm); 986 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 987 988 state->acquire_ctx = &ctx; 989 990 ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI0); 991 KUNIT_ASSERT_EQ(test, ret, 0); 992 993 ret = drm_atomic_check_only(state); 994 KUNIT_ASSERT_EQ(test, ret, 0); 995 996 ret = drm_atomic_helper_swap_state(state, false); 997 KUNIT_ASSERT_EQ(test, ret, 0); 998 999 drm_atomic_state_put(state); 1000 1001 state = drm_atomic_state_alloc(drm); 1002 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, state); 1003 1004 state->acquire_ctx = &ctx; 1005 1006 ret = vc4_mock_atomic_add_output(test, state, VC4_ENCODER_TYPE_HDMI1); 1007 KUNIT_ASSERT_EQ(test, ret, 0); 1008 1009 ret = drm_atomic_check_only(state); 1010 KUNIT_ASSERT_EQ(test, ret, 0); 1011 1012 new_vc4_crtc_state = get_vc4_crtc_state_for_encoder(test, state, 1013 VC4_ENCODER_TYPE_HDMI0); 1014 KUNIT_EXPECT_NULL(test, new_vc4_crtc_state); 1015 1016 drm_atomic_state_put(state); 1017 drm_modeset_drop_locks(&ctx); 1018 drm_modeset_acquire_fini(&ctx); 1019 drm_dev_unregister(drm); 1020 drm_kunit_helper_free_device(test, vc4->dev); 1021 } 1022 1023 static struct kunit_case vc5_pv_muxing_bugs_tests[] = { 1024 KUNIT_CASE(drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable), 1025 KUNIT_CASE(drm_test_vc5_pv_muxing_bugs_subsequent_crtc_enable_too_many_crtc_state), 1026 KUNIT_CASE(drm_test_vc5_pv_muxing_bugs_stable_fifo), 1027 {} 1028 }; 1029 1030 static struct kunit_suite vc5_pv_muxing_bugs_test_suite = { 1031 .name = "vc5-pv-muxing-bugs", 1032 .test_cases = vc5_pv_muxing_bugs_tests, 1033 }; 1034 1035 kunit_test_suites( 1036 &vc4_pv_muxing_test_suite, 1037 &vc5_pv_muxing_test_suite, 1038 &vc5_pv_muxing_bugs_test_suite 1039 ); 1040