1 // SPDX-License-Identifier: GPL-2.0-only 2 3 /* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. */ 4 /* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ 5 6 #include <linux/delay.h> 7 #include <linux/err.h> 8 #include <linux/memblock.h> 9 #include <linux/mhi.h> 10 #include <linux/moduleparam.h> 11 #include <linux/pci.h> 12 #include <linux/sizes.h> 13 14 #include "mhi_controller.h" 15 #include "qaic.h" 16 17 #define MAX_RESET_TIME_SEC 25 18 19 static unsigned int mhi_timeout_ms = 2000; /* 2 sec default */ 20 module_param(mhi_timeout_ms, uint, 0600); 21 MODULE_PARM_DESC(mhi_timeout_ms, "MHI controller timeout value"); 22 23 static const char *fw_image_paths[FAMILY_MAX] = { 24 [FAMILY_AIC100] = "qcom/aic100/sbl.bin", 25 [FAMILY_AIC200] = "qcom/aic200/sbl.bin", 26 }; 27 28 static const struct mhi_channel_config aic100_channels[] = { 29 { 30 .name = "QAIC_LOOPBACK", 31 .num = 0, 32 .num_elements = 32, 33 .local_elements = 0, 34 .event_ring = 0, 35 .dir = DMA_TO_DEVICE, 36 .ee_mask = MHI_CH_EE_AMSS, 37 .pollcfg = 0, 38 .doorbell = MHI_DB_BRST_DISABLE, 39 .lpm_notify = false, 40 .offload_channel = false, 41 .doorbell_mode_switch = false, 42 .wake_capable = false, 43 }, 44 { 45 .name = "QAIC_LOOPBACK", 46 .num = 1, 47 .num_elements = 32, 48 .local_elements = 0, 49 .event_ring = 0, 50 .dir = DMA_FROM_DEVICE, 51 .ee_mask = MHI_CH_EE_AMSS, 52 .pollcfg = 0, 53 .doorbell = MHI_DB_BRST_DISABLE, 54 .lpm_notify = false, 55 .offload_channel = false, 56 .doorbell_mode_switch = false, 57 .wake_capable = false, 58 }, 59 { 60 .name = "QAIC_SAHARA", 61 .num = 2, 62 .num_elements = 32, 63 .local_elements = 0, 64 .event_ring = 0, 65 .dir = DMA_TO_DEVICE, 66 .ee_mask = MHI_CH_EE_SBL, 67 .pollcfg = 0, 68 .doorbell = MHI_DB_BRST_DISABLE, 69 .lpm_notify = false, 70 .offload_channel = false, 71 .doorbell_mode_switch = false, 72 .wake_capable = false, 73 }, 74 { 75 .name = "QAIC_SAHARA", 76 .num = 3, 77 .num_elements = 32, 78 .local_elements = 0, 79 .event_ring = 0, 80 .dir = DMA_FROM_DEVICE, 81 .ee_mask = MHI_CH_EE_SBL, 82 .pollcfg = 0, 83 .doorbell = MHI_DB_BRST_DISABLE, 84 .lpm_notify = false, 85 .offload_channel = false, 86 .doorbell_mode_switch = false, 87 .wake_capable = false, 88 }, 89 { 90 .name = "QAIC_DIAG", 91 .num = 4, 92 .num_elements = 32, 93 .local_elements = 0, 94 .event_ring = 0, 95 .dir = DMA_TO_DEVICE, 96 .ee_mask = MHI_CH_EE_AMSS, 97 .pollcfg = 0, 98 .doorbell = MHI_DB_BRST_DISABLE, 99 .lpm_notify = false, 100 .offload_channel = false, 101 .doorbell_mode_switch = false, 102 .wake_capable = false, 103 }, 104 { 105 .name = "QAIC_DIAG", 106 .num = 5, 107 .num_elements = 32, 108 .local_elements = 0, 109 .event_ring = 0, 110 .dir = DMA_FROM_DEVICE, 111 .ee_mask = MHI_CH_EE_AMSS, 112 .pollcfg = 0, 113 .doorbell = MHI_DB_BRST_DISABLE, 114 .lpm_notify = false, 115 .offload_channel = false, 116 .doorbell_mode_switch = false, 117 .wake_capable = false, 118 }, 119 { 120 .name = "QAIC_SSR", 121 .num = 6, 122 .num_elements = 32, 123 .local_elements = 0, 124 .event_ring = 0, 125 .dir = DMA_TO_DEVICE, 126 .ee_mask = MHI_CH_EE_AMSS, 127 .pollcfg = 0, 128 .doorbell = MHI_DB_BRST_DISABLE, 129 .lpm_notify = false, 130 .offload_channel = false, 131 .doorbell_mode_switch = false, 132 .wake_capable = false, 133 }, 134 { 135 .name = "QAIC_SSR", 136 .num = 7, 137 .num_elements = 32, 138 .local_elements = 0, 139 .event_ring = 0, 140 .dir = DMA_FROM_DEVICE, 141 .ee_mask = MHI_CH_EE_AMSS, 142 .pollcfg = 0, 143 .doorbell = MHI_DB_BRST_DISABLE, 144 .lpm_notify = false, 145 .offload_channel = false, 146 .doorbell_mode_switch = false, 147 .wake_capable = false, 148 }, 149 { 150 .name = "QAIC_QDSS", 151 .num = 8, 152 .num_elements = 32, 153 .local_elements = 0, 154 .event_ring = 0, 155 .dir = DMA_TO_DEVICE, 156 .ee_mask = MHI_CH_EE_AMSS, 157 .pollcfg = 0, 158 .doorbell = MHI_DB_BRST_DISABLE, 159 .lpm_notify = false, 160 .offload_channel = false, 161 .doorbell_mode_switch = false, 162 .wake_capable = false, 163 }, 164 { 165 .name = "QAIC_QDSS", 166 .num = 9, 167 .num_elements = 32, 168 .local_elements = 0, 169 .event_ring = 0, 170 .dir = DMA_FROM_DEVICE, 171 .ee_mask = MHI_CH_EE_AMSS, 172 .pollcfg = 0, 173 .doorbell = MHI_DB_BRST_DISABLE, 174 .lpm_notify = false, 175 .offload_channel = false, 176 .doorbell_mode_switch = false, 177 .wake_capable = false, 178 }, 179 { 180 .name = "QAIC_CONTROL", 181 .num = 10, 182 .num_elements = 128, 183 .local_elements = 0, 184 .event_ring = 0, 185 .dir = DMA_TO_DEVICE, 186 .ee_mask = MHI_CH_EE_AMSS, 187 .pollcfg = 0, 188 .doorbell = MHI_DB_BRST_DISABLE, 189 .lpm_notify = false, 190 .offload_channel = false, 191 .doorbell_mode_switch = false, 192 .wake_capable = false, 193 }, 194 { 195 .name = "QAIC_CONTROL", 196 .num = 11, 197 .num_elements = 128, 198 .local_elements = 0, 199 .event_ring = 0, 200 .dir = DMA_FROM_DEVICE, 201 .ee_mask = MHI_CH_EE_AMSS, 202 .pollcfg = 0, 203 .doorbell = MHI_DB_BRST_DISABLE, 204 .lpm_notify = false, 205 .offload_channel = false, 206 .doorbell_mode_switch = false, 207 .wake_capable = false, 208 }, 209 { 210 .name = "QAIC_LOGGING", 211 .num = 12, 212 .num_elements = 32, 213 .local_elements = 0, 214 .event_ring = 0, 215 .dir = DMA_TO_DEVICE, 216 .ee_mask = MHI_CH_EE_SBL, 217 .pollcfg = 0, 218 .doorbell = MHI_DB_BRST_DISABLE, 219 .lpm_notify = false, 220 .offload_channel = false, 221 .doorbell_mode_switch = false, 222 .wake_capable = false, 223 }, 224 { 225 .name = "QAIC_LOGGING", 226 .num = 13, 227 .num_elements = 32, 228 .local_elements = 0, 229 .event_ring = 0, 230 .dir = DMA_FROM_DEVICE, 231 .ee_mask = MHI_CH_EE_SBL, 232 .pollcfg = 0, 233 .doorbell = MHI_DB_BRST_DISABLE, 234 .lpm_notify = false, 235 .offload_channel = false, 236 .doorbell_mode_switch = false, 237 .wake_capable = false, 238 }, 239 { 240 .name = "QAIC_STATUS", 241 .num = 14, 242 .num_elements = 32, 243 .local_elements = 0, 244 .event_ring = 0, 245 .dir = DMA_TO_DEVICE, 246 .ee_mask = MHI_CH_EE_AMSS, 247 .pollcfg = 0, 248 .doorbell = MHI_DB_BRST_DISABLE, 249 .lpm_notify = false, 250 .offload_channel = false, 251 .doorbell_mode_switch = false, 252 .wake_capable = false, 253 }, 254 { 255 .name = "QAIC_STATUS", 256 .num = 15, 257 .num_elements = 32, 258 .local_elements = 0, 259 .event_ring = 0, 260 .dir = DMA_FROM_DEVICE, 261 .ee_mask = MHI_CH_EE_AMSS, 262 .pollcfg = 0, 263 .doorbell = MHI_DB_BRST_DISABLE, 264 .lpm_notify = false, 265 .offload_channel = false, 266 .doorbell_mode_switch = false, 267 .wake_capable = false, 268 }, 269 { 270 .name = "QAIC_TELEMETRY", 271 .num = 16, 272 .num_elements = 32, 273 .local_elements = 0, 274 .event_ring = 0, 275 .dir = DMA_TO_DEVICE, 276 .ee_mask = MHI_CH_EE_AMSS, 277 .pollcfg = 0, 278 .doorbell = MHI_DB_BRST_DISABLE, 279 .lpm_notify = false, 280 .offload_channel = false, 281 .doorbell_mode_switch = false, 282 .wake_capable = false, 283 }, 284 { 285 .name = "QAIC_TELEMETRY", 286 .num = 17, 287 .num_elements = 32, 288 .local_elements = 0, 289 .event_ring = 0, 290 .dir = DMA_FROM_DEVICE, 291 .ee_mask = MHI_CH_EE_AMSS, 292 .pollcfg = 0, 293 .doorbell = MHI_DB_BRST_DISABLE, 294 .lpm_notify = false, 295 .offload_channel = false, 296 .doorbell_mode_switch = false, 297 .wake_capable = false, 298 }, 299 { 300 .name = "QAIC_DEBUG", 301 .num = 18, 302 .num_elements = 32, 303 .local_elements = 0, 304 .event_ring = 0, 305 .dir = DMA_TO_DEVICE, 306 .ee_mask = MHI_CH_EE_AMSS, 307 .pollcfg = 0, 308 .doorbell = MHI_DB_BRST_DISABLE, 309 .lpm_notify = false, 310 .offload_channel = false, 311 .doorbell_mode_switch = false, 312 .wake_capable = false, 313 }, 314 { 315 .name = "QAIC_DEBUG", 316 .num = 19, 317 .num_elements = 32, 318 .local_elements = 0, 319 .event_ring = 0, 320 .dir = DMA_FROM_DEVICE, 321 .ee_mask = MHI_CH_EE_AMSS, 322 .pollcfg = 0, 323 .doorbell = MHI_DB_BRST_DISABLE, 324 .lpm_notify = false, 325 .offload_channel = false, 326 .doorbell_mode_switch = false, 327 .wake_capable = false, 328 }, 329 { 330 .name = "QAIC_TIMESYNC", 331 .num = 20, 332 .num_elements = 32, 333 .local_elements = 0, 334 .event_ring = 0, 335 .dir = DMA_TO_DEVICE, 336 .ee_mask = MHI_CH_EE_SBL, 337 .pollcfg = 0, 338 .doorbell = MHI_DB_BRST_DISABLE, 339 .lpm_notify = false, 340 .offload_channel = false, 341 .doorbell_mode_switch = false, 342 .wake_capable = false, 343 }, 344 { 345 .name = "QAIC_TIMESYNC", 346 .num = 21, 347 .num_elements = 32, 348 .local_elements = 0, 349 .event_ring = 0, 350 .dir = DMA_FROM_DEVICE, 351 .ee_mask = MHI_CH_EE_SBL, 352 .pollcfg = 0, 353 .doorbell = MHI_DB_BRST_DISABLE, 354 .lpm_notify = false, 355 .offload_channel = false, 356 .doorbell_mode_switch = false, 357 .wake_capable = false, 358 }, 359 { 360 .name = "QAIC_TIMESYNC_PERIODIC", 361 .num = 22, 362 .num_elements = 32, 363 .local_elements = 0, 364 .event_ring = 0, 365 .dir = DMA_TO_DEVICE, 366 .ee_mask = MHI_CH_EE_AMSS, 367 .pollcfg = 0, 368 .doorbell = MHI_DB_BRST_DISABLE, 369 .lpm_notify = false, 370 .offload_channel = false, 371 .doorbell_mode_switch = false, 372 .wake_capable = false, 373 }, 374 { 375 .name = "QAIC_TIMESYNC_PERIODIC", 376 .num = 23, 377 .num_elements = 32, 378 .local_elements = 0, 379 .event_ring = 0, 380 .dir = DMA_FROM_DEVICE, 381 .ee_mask = MHI_CH_EE_AMSS, 382 .pollcfg = 0, 383 .doorbell = MHI_DB_BRST_DISABLE, 384 .lpm_notify = false, 385 .offload_channel = false, 386 .doorbell_mode_switch = false, 387 .wake_capable = false, 388 }, 389 { 390 .name = "IPCR", 391 .num = 24, 392 .num_elements = 32, 393 .local_elements = 0, 394 .event_ring = 0, 395 .dir = DMA_TO_DEVICE, 396 .ee_mask = MHI_CH_EE_AMSS, 397 .pollcfg = 0, 398 .doorbell = MHI_DB_BRST_DISABLE, 399 .lpm_notify = false, 400 .offload_channel = false, 401 .doorbell_mode_switch = false, 402 .wake_capable = false, 403 }, 404 { 405 .name = "IPCR", 406 .num = 25, 407 .num_elements = 32, 408 .local_elements = 0, 409 .event_ring = 0, 410 .dir = DMA_FROM_DEVICE, 411 .ee_mask = MHI_CH_EE_AMSS, 412 .pollcfg = 0, 413 .doorbell = MHI_DB_BRST_DISABLE, 414 .lpm_notify = false, 415 .offload_channel = false, 416 .doorbell_mode_switch = false, 417 .wake_capable = false, 418 }, 419 }; 420 421 static const struct mhi_channel_config aic200_channels[] = { 422 { 423 .name = "QAIC_LOOPBACK", 424 .num = 0, 425 .num_elements = 32, 426 .local_elements = 0, 427 .event_ring = 0, 428 .dir = DMA_TO_DEVICE, 429 .ee_mask = MHI_CH_EE_AMSS, 430 .pollcfg = 0, 431 .doorbell = MHI_DB_BRST_DISABLE, 432 .lpm_notify = false, 433 .offload_channel = false, 434 .doorbell_mode_switch = false, 435 .wake_capable = false, 436 }, 437 { 438 .name = "QAIC_LOOPBACK", 439 .num = 1, 440 .num_elements = 32, 441 .local_elements = 0, 442 .event_ring = 0, 443 .dir = DMA_FROM_DEVICE, 444 .ee_mask = MHI_CH_EE_AMSS, 445 .pollcfg = 0, 446 .doorbell = MHI_DB_BRST_DISABLE, 447 .lpm_notify = false, 448 .offload_channel = false, 449 .doorbell_mode_switch = false, 450 .wake_capable = false, 451 }, 452 { 453 .name = "QAIC_SAHARA", 454 .num = 2, 455 .num_elements = 32, 456 .local_elements = 0, 457 .event_ring = 0, 458 .dir = DMA_TO_DEVICE, 459 .ee_mask = MHI_CH_EE_SBL, 460 .pollcfg = 0, 461 .doorbell = MHI_DB_BRST_DISABLE, 462 .lpm_notify = false, 463 .offload_channel = false, 464 .doorbell_mode_switch = false, 465 .wake_capable = false, 466 }, 467 { 468 .name = "QAIC_SAHARA", 469 .num = 3, 470 .num_elements = 32, 471 .local_elements = 0, 472 .event_ring = 0, 473 .dir = DMA_FROM_DEVICE, 474 .ee_mask = MHI_CH_EE_SBL, 475 .pollcfg = 0, 476 .doorbell = MHI_DB_BRST_DISABLE, 477 .lpm_notify = false, 478 .offload_channel = false, 479 .doorbell_mode_switch = false, 480 .wake_capable = false, 481 }, 482 { 483 .name = "QAIC_SSR", 484 .num = 6, 485 .num_elements = 32, 486 .local_elements = 0, 487 .event_ring = 0, 488 .dir = DMA_TO_DEVICE, 489 .ee_mask = MHI_CH_EE_AMSS, 490 .pollcfg = 0, 491 .doorbell = MHI_DB_BRST_DISABLE, 492 .lpm_notify = false, 493 .offload_channel = false, 494 .doorbell_mode_switch = false, 495 .wake_capable = false, 496 }, 497 { 498 .name = "QAIC_SSR", 499 .num = 7, 500 .num_elements = 32, 501 .local_elements = 0, 502 .event_ring = 0, 503 .dir = DMA_FROM_DEVICE, 504 .ee_mask = MHI_CH_EE_AMSS, 505 .pollcfg = 0, 506 .doorbell = MHI_DB_BRST_DISABLE, 507 .lpm_notify = false, 508 .offload_channel = false, 509 .doorbell_mode_switch = false, 510 .wake_capable = false, 511 }, 512 { 513 .name = "QAIC_CONTROL", 514 .num = 10, 515 .num_elements = 128, 516 .local_elements = 0, 517 .event_ring = 0, 518 .dir = DMA_TO_DEVICE, 519 .ee_mask = MHI_CH_EE_AMSS, 520 .pollcfg = 0, 521 .doorbell = MHI_DB_BRST_DISABLE, 522 .lpm_notify = false, 523 .offload_channel = false, 524 .doorbell_mode_switch = false, 525 .wake_capable = false, 526 }, 527 { 528 .name = "QAIC_CONTROL", 529 .num = 11, 530 .num_elements = 128, 531 .local_elements = 0, 532 .event_ring = 0, 533 .dir = DMA_FROM_DEVICE, 534 .ee_mask = MHI_CH_EE_AMSS, 535 .pollcfg = 0, 536 .doorbell = MHI_DB_BRST_DISABLE, 537 .lpm_notify = false, 538 .offload_channel = false, 539 .doorbell_mode_switch = false, 540 .wake_capable = false, 541 }, 542 { 543 .name = "QAIC_LOGGING", 544 .num = 12, 545 .num_elements = 32, 546 .local_elements = 0, 547 .event_ring = 0, 548 .dir = DMA_TO_DEVICE, 549 .ee_mask = MHI_CH_EE_SBL, 550 .pollcfg = 0, 551 .doorbell = MHI_DB_BRST_DISABLE, 552 .lpm_notify = false, 553 .offload_channel = false, 554 .doorbell_mode_switch = false, 555 .wake_capable = false, 556 }, 557 { 558 .name = "QAIC_LOGGING", 559 .num = 13, 560 .num_elements = 32, 561 .local_elements = 0, 562 .event_ring = 0, 563 .dir = DMA_FROM_DEVICE, 564 .ee_mask = MHI_CH_EE_SBL, 565 .pollcfg = 0, 566 .doorbell = MHI_DB_BRST_DISABLE, 567 .lpm_notify = false, 568 .offload_channel = false, 569 .doorbell_mode_switch = false, 570 .wake_capable = false, 571 }, 572 { 573 .name = "QAIC_STATUS", 574 .num = 14, 575 .num_elements = 32, 576 .local_elements = 0, 577 .event_ring = 0, 578 .dir = DMA_TO_DEVICE, 579 .ee_mask = MHI_CH_EE_AMSS, 580 .pollcfg = 0, 581 .doorbell = MHI_DB_BRST_DISABLE, 582 .lpm_notify = false, 583 .offload_channel = false, 584 .doorbell_mode_switch = false, 585 .wake_capable = false, 586 }, 587 { 588 .name = "QAIC_STATUS", 589 .num = 15, 590 .num_elements = 32, 591 .local_elements = 0, 592 .event_ring = 0, 593 .dir = DMA_FROM_DEVICE, 594 .ee_mask = MHI_CH_EE_AMSS, 595 .pollcfg = 0, 596 .doorbell = MHI_DB_BRST_DISABLE, 597 .lpm_notify = false, 598 .offload_channel = false, 599 .doorbell_mode_switch = false, 600 .wake_capable = false, 601 }, 602 { 603 .name = "QAIC_TELEMETRY", 604 .num = 16, 605 .num_elements = 32, 606 .local_elements = 0, 607 .event_ring = 0, 608 .dir = DMA_TO_DEVICE, 609 .ee_mask = MHI_CH_EE_AMSS, 610 .pollcfg = 0, 611 .doorbell = MHI_DB_BRST_DISABLE, 612 .lpm_notify = false, 613 .offload_channel = false, 614 .doorbell_mode_switch = false, 615 .wake_capable = false, 616 }, 617 { 618 .name = "QAIC_TELEMETRY", 619 .num = 17, 620 .num_elements = 32, 621 .local_elements = 0, 622 .event_ring = 0, 623 .dir = DMA_FROM_DEVICE, 624 .ee_mask = MHI_CH_EE_AMSS, 625 .pollcfg = 0, 626 .doorbell = MHI_DB_BRST_DISABLE, 627 .lpm_notify = false, 628 .offload_channel = false, 629 .doorbell_mode_switch = false, 630 .wake_capable = false, 631 }, 632 { 633 .name = "QAIC_TIMESYNC_PERIODIC", 634 .num = 22, 635 .num_elements = 32, 636 .local_elements = 0, 637 .event_ring = 0, 638 .dir = DMA_TO_DEVICE, 639 .ee_mask = MHI_CH_EE_AMSS, 640 .pollcfg = 0, 641 .doorbell = MHI_DB_BRST_DISABLE, 642 .lpm_notify = false, 643 .offload_channel = false, 644 .doorbell_mode_switch = false, 645 .wake_capable = false, 646 }, 647 { 648 .name = "QAIC_TIMESYNC_PERIODIC", 649 .num = 23, 650 .num_elements = 32, 651 .local_elements = 0, 652 .event_ring = 0, 653 .dir = DMA_FROM_DEVICE, 654 .ee_mask = MHI_CH_EE_AMSS, 655 .pollcfg = 0, 656 .doorbell = MHI_DB_BRST_DISABLE, 657 .lpm_notify = false, 658 .offload_channel = false, 659 .doorbell_mode_switch = false, 660 .wake_capable = false, 661 }, 662 { 663 .name = "IPCR", 664 .num = 24, 665 .num_elements = 32, 666 .local_elements = 0, 667 .event_ring = 0, 668 .dir = DMA_TO_DEVICE, 669 .ee_mask = MHI_CH_EE_AMSS, 670 .pollcfg = 0, 671 .doorbell = MHI_DB_BRST_DISABLE, 672 .lpm_notify = false, 673 .offload_channel = false, 674 .doorbell_mode_switch = false, 675 .wake_capable = false, 676 }, 677 { 678 .name = "IPCR", 679 .num = 25, 680 .num_elements = 32, 681 .local_elements = 0, 682 .event_ring = 0, 683 .dir = DMA_FROM_DEVICE, 684 .ee_mask = MHI_CH_EE_AMSS, 685 .pollcfg = 0, 686 .doorbell = MHI_DB_BRST_DISABLE, 687 .lpm_notify = false, 688 .offload_channel = false, 689 .doorbell_mode_switch = false, 690 .wake_capable = false, 691 }, 692 }; 693 694 static struct mhi_event_config aic100_events[] = { 695 { 696 .num_elements = 32, 697 .irq_moderation_ms = 0, 698 .irq = 0, 699 .channel = U32_MAX, 700 .priority = 1, 701 .mode = MHI_DB_BRST_DISABLE, 702 .data_type = MHI_ER_CTRL, 703 .hardware_event = false, 704 .client_managed = false, 705 .offload_channel = false, 706 }, 707 }; 708 709 static struct mhi_event_config aic200_events[] = { 710 { 711 .num_elements = 32, 712 .irq_moderation_ms = 0, 713 .irq = 0, 714 .channel = U32_MAX, 715 .priority = 1, 716 .mode = MHI_DB_BRST_DISABLE, 717 .data_type = MHI_ER_CTRL, 718 .hardware_event = false, 719 .client_managed = false, 720 .offload_channel = false, 721 }, 722 }; 723 724 static struct mhi_controller_config mhi_cntrl_configs[] = { 725 [FAMILY_AIC100] = { 726 .max_channels = 128, 727 .timeout_ms = 0, /* controlled by mhi_timeout */ 728 .buf_len = 0, 729 .num_channels = ARRAY_SIZE(aic100_channels), 730 .ch_cfg = aic100_channels, 731 .num_events = ARRAY_SIZE(aic100_events), 732 .event_cfg = aic100_events, 733 .use_bounce_buf = false, 734 .m2_no_db = false, 735 }, 736 [FAMILY_AIC200] = { 737 .max_channels = 128, 738 .timeout_ms = 0, /* controlled by mhi_timeout */ 739 .buf_len = 0, 740 .num_channels = ARRAY_SIZE(aic200_channels), 741 .ch_cfg = aic200_channels, 742 .num_events = ARRAY_SIZE(aic200_events), 743 .event_cfg = aic200_events, 744 .use_bounce_buf = false, 745 .m2_no_db = false, 746 }, 747 }; 748 749 static int mhi_read_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 *out) 750 { 751 u32 tmp; 752 753 /* 754 * SOC_HW_VERSION quirk 755 * The SOC_HW_VERSION register (offset 0x224) is not reliable and 756 * may contain uninitialized values, including 0xFFFFFFFF. This could 757 * cause a false positive link down error. Instead, intercept any 758 * reads and provide the correct value of the register. 759 */ 760 if (addr - mhi_cntrl->regs == 0x224) { 761 *out = 0x60110200; 762 return 0; 763 } 764 765 tmp = readl_relaxed(addr); 766 if (tmp == U32_MAX) 767 return -EIO; 768 769 *out = tmp; 770 771 return 0; 772 } 773 774 static void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 val) 775 { 776 writel_relaxed(val, addr); 777 } 778 779 static int mhi_runtime_get(struct mhi_controller *mhi_cntrl) 780 { 781 return 0; 782 } 783 784 static void mhi_runtime_put(struct mhi_controller *mhi_cntrl) 785 { 786 } 787 788 static void mhi_status_cb(struct mhi_controller *mhi_cntrl, enum mhi_callback reason) 789 { 790 struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(mhi_cntrl->cntrl_dev)); 791 792 /* this event occurs in atomic context */ 793 if (reason == MHI_CB_FATAL_ERROR) 794 pci_err(qdev->pdev, "Fatal error received from device. Attempting to recover\n"); 795 /* this event occurs in non-atomic context */ 796 if (reason == MHI_CB_SYS_ERROR) 797 qaic_dev_reset_clean_local_state(qdev); 798 } 799 800 static int mhi_reset_and_async_power_up(struct mhi_controller *mhi_cntrl) 801 { 802 u8 time_sec = 1; 803 int current_ee; 804 int ret; 805 806 /* Reset the device to bring the device in PBL EE */ 807 mhi_soc_reset(mhi_cntrl); 808 809 /* 810 * Keep checking the execution environment(EE) after every 1 second 811 * interval. 812 */ 813 do { 814 msleep(1000); 815 current_ee = mhi_get_exec_env(mhi_cntrl); 816 } while (current_ee != MHI_EE_PBL && time_sec++ <= MAX_RESET_TIME_SEC); 817 818 /* If the device is in PBL EE retry power up */ 819 if (current_ee == MHI_EE_PBL) 820 ret = mhi_async_power_up(mhi_cntrl); 821 else 822 ret = -EIO; 823 824 return ret; 825 } 826 827 struct mhi_controller *qaic_mhi_register_controller(struct pci_dev *pci_dev, void __iomem *mhi_bar, 828 int mhi_irq, bool shared_msi, int family) 829 { 830 struct mhi_controller_config mhi_config = mhi_cntrl_configs[family]; 831 struct mhi_controller *mhi_cntrl; 832 int ret; 833 834 mhi_cntrl = devm_kzalloc(&pci_dev->dev, sizeof(*mhi_cntrl), GFP_KERNEL); 835 if (!mhi_cntrl) 836 return ERR_PTR(-ENOMEM); 837 838 mhi_cntrl->cntrl_dev = &pci_dev->dev; 839 840 /* 841 * Covers the entire possible physical ram region. Remote side is 842 * going to calculate a size of this range, so subtract 1 to prevent 843 * rollover. 844 */ 845 mhi_cntrl->iova_start = 0; 846 mhi_cntrl->iova_stop = PHYS_ADDR_MAX - 1; 847 mhi_cntrl->status_cb = mhi_status_cb; 848 mhi_cntrl->runtime_get = mhi_runtime_get; 849 mhi_cntrl->runtime_put = mhi_runtime_put; 850 mhi_cntrl->read_reg = mhi_read_reg; 851 mhi_cntrl->write_reg = mhi_write_reg; 852 mhi_cntrl->regs = mhi_bar; 853 mhi_cntrl->reg_len = SZ_4K; 854 mhi_cntrl->nr_irqs = 1; 855 mhi_cntrl->irq = devm_kmalloc(&pci_dev->dev, sizeof(*mhi_cntrl->irq), GFP_KERNEL); 856 857 if (!mhi_cntrl->irq) 858 return ERR_PTR(-ENOMEM); 859 860 mhi_cntrl->irq[0] = mhi_irq; 861 862 if (shared_msi) /* MSI shared with data path, no IRQF_NO_SUSPEND */ 863 mhi_cntrl->irq_flags = IRQF_SHARED; 864 865 mhi_cntrl->fw_image = fw_image_paths[family]; 866 867 if (family == FAMILY_AIC200) { 868 mhi_cntrl->name = "AIC200"; 869 mhi_cntrl->seg_len = SZ_512K; 870 } else { 871 mhi_cntrl->name = "AIC100"; 872 } 873 874 /* use latest configured timeout */ 875 mhi_config.timeout_ms = mhi_timeout_ms; 876 ret = mhi_register_controller(mhi_cntrl, &mhi_config); 877 if (ret) { 878 pci_err(pci_dev, "mhi_register_controller failed %d\n", ret); 879 return ERR_PTR(ret); 880 } 881 882 ret = mhi_prepare_for_power_up(mhi_cntrl); 883 if (ret) { 884 pci_err(pci_dev, "mhi_prepare_for_power_up failed %d\n", ret); 885 goto prepare_power_up_fail; 886 } 887 888 ret = mhi_async_power_up(mhi_cntrl); 889 /* 890 * If EIO is returned it is possible that device is in SBL EE, which is 891 * undesired. SOC reset the device and try to power up again. 892 */ 893 if (ret == -EIO && MHI_EE_SBL == mhi_get_exec_env(mhi_cntrl)) { 894 pci_err(pci_dev, "Found device in SBL at MHI init. Attempting a reset.\n"); 895 ret = mhi_reset_and_async_power_up(mhi_cntrl); 896 } 897 898 if (ret) { 899 pci_err(pci_dev, "mhi_async_power_up failed %d\n", ret); 900 goto power_up_fail; 901 } 902 903 return mhi_cntrl; 904 905 power_up_fail: 906 mhi_unprepare_after_power_down(mhi_cntrl); 907 prepare_power_up_fail: 908 mhi_unregister_controller(mhi_cntrl); 909 return ERR_PTR(ret); 910 } 911 912 void qaic_mhi_free_controller(struct mhi_controller *mhi_cntrl, bool link_up) 913 { 914 mhi_power_down(mhi_cntrl, link_up); 915 mhi_unprepare_after_power_down(mhi_cntrl); 916 mhi_unregister_controller(mhi_cntrl); 917 } 918 919 void qaic_mhi_start_reset(struct mhi_controller *mhi_cntrl) 920 { 921 mhi_power_down(mhi_cntrl, true); 922 } 923 924 void qaic_mhi_reset_done(struct mhi_controller *mhi_cntrl) 925 { 926 struct pci_dev *pci_dev = container_of(mhi_cntrl->cntrl_dev, struct pci_dev, dev); 927 int ret; 928 929 ret = mhi_async_power_up(mhi_cntrl); 930 if (ret) 931 pci_err(pci_dev, "mhi_async_power_up failed after reset %d\n", ret); 932 } 933