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