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 struct mhi_channel_config aic100_channels[] = { 24 { 25 .name = "QAIC_LOOPBACK", 26 .num = 0, 27 .num_elements = 32, 28 .local_elements = 0, 29 .event_ring = 0, 30 .dir = DMA_TO_DEVICE, 31 .ee_mask = MHI_CH_EE_AMSS, 32 .pollcfg = 0, 33 .doorbell = MHI_DB_BRST_DISABLE, 34 .lpm_notify = false, 35 .offload_channel = false, 36 .doorbell_mode_switch = false, 37 .auto_queue = false, 38 .wake_capable = false, 39 }, 40 { 41 .name = "QAIC_LOOPBACK", 42 .num = 1, 43 .num_elements = 32, 44 .local_elements = 0, 45 .event_ring = 0, 46 .dir = DMA_FROM_DEVICE, 47 .ee_mask = MHI_CH_EE_AMSS, 48 .pollcfg = 0, 49 .doorbell = MHI_DB_BRST_DISABLE, 50 .lpm_notify = false, 51 .offload_channel = false, 52 .doorbell_mode_switch = false, 53 .auto_queue = false, 54 .wake_capable = false, 55 }, 56 { 57 .name = "QAIC_SAHARA", 58 .num = 2, 59 .num_elements = 32, 60 .local_elements = 0, 61 .event_ring = 0, 62 .dir = DMA_TO_DEVICE, 63 .ee_mask = MHI_CH_EE_SBL, 64 .pollcfg = 0, 65 .doorbell = MHI_DB_BRST_DISABLE, 66 .lpm_notify = false, 67 .offload_channel = false, 68 .doorbell_mode_switch = false, 69 .auto_queue = false, 70 .wake_capable = false, 71 }, 72 { 73 .name = "QAIC_SAHARA", 74 .num = 3, 75 .num_elements = 32, 76 .local_elements = 0, 77 .event_ring = 0, 78 .dir = DMA_FROM_DEVICE, 79 .ee_mask = MHI_CH_EE_SBL, 80 .pollcfg = 0, 81 .doorbell = MHI_DB_BRST_DISABLE, 82 .lpm_notify = false, 83 .offload_channel = false, 84 .doorbell_mode_switch = false, 85 .auto_queue = false, 86 .wake_capable = false, 87 }, 88 { 89 .name = "QAIC_DIAG", 90 .num = 4, 91 .num_elements = 32, 92 .local_elements = 0, 93 .event_ring = 0, 94 .dir = DMA_TO_DEVICE, 95 .ee_mask = MHI_CH_EE_AMSS, 96 .pollcfg = 0, 97 .doorbell = MHI_DB_BRST_DISABLE, 98 .lpm_notify = false, 99 .offload_channel = false, 100 .doorbell_mode_switch = false, 101 .auto_queue = 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 .auto_queue = false, 118 .wake_capable = false, 119 }, 120 { 121 .name = "QAIC_SSR", 122 .num = 6, 123 .num_elements = 32, 124 .local_elements = 0, 125 .event_ring = 0, 126 .dir = DMA_TO_DEVICE, 127 .ee_mask = MHI_CH_EE_AMSS, 128 .pollcfg = 0, 129 .doorbell = MHI_DB_BRST_DISABLE, 130 .lpm_notify = false, 131 .offload_channel = false, 132 .doorbell_mode_switch = false, 133 .auto_queue = false, 134 .wake_capable = false, 135 }, 136 { 137 .name = "QAIC_SSR", 138 .num = 7, 139 .num_elements = 32, 140 .local_elements = 0, 141 .event_ring = 0, 142 .dir = DMA_FROM_DEVICE, 143 .ee_mask = MHI_CH_EE_AMSS, 144 .pollcfg = 0, 145 .doorbell = MHI_DB_BRST_DISABLE, 146 .lpm_notify = false, 147 .offload_channel = false, 148 .doorbell_mode_switch = false, 149 .auto_queue = false, 150 .wake_capable = false, 151 }, 152 { 153 .name = "QAIC_QDSS", 154 .num = 8, 155 .num_elements = 32, 156 .local_elements = 0, 157 .event_ring = 0, 158 .dir = DMA_TO_DEVICE, 159 .ee_mask = MHI_CH_EE_AMSS, 160 .pollcfg = 0, 161 .doorbell = MHI_DB_BRST_DISABLE, 162 .lpm_notify = false, 163 .offload_channel = false, 164 .doorbell_mode_switch = false, 165 .auto_queue = false, 166 .wake_capable = false, 167 }, 168 { 169 .name = "QAIC_QDSS", 170 .num = 9, 171 .num_elements = 32, 172 .local_elements = 0, 173 .event_ring = 0, 174 .dir = DMA_FROM_DEVICE, 175 .ee_mask = MHI_CH_EE_AMSS, 176 .pollcfg = 0, 177 .doorbell = MHI_DB_BRST_DISABLE, 178 .lpm_notify = false, 179 .offload_channel = false, 180 .doorbell_mode_switch = false, 181 .auto_queue = false, 182 .wake_capable = false, 183 }, 184 { 185 .name = "QAIC_CONTROL", 186 .num = 10, 187 .num_elements = 128, 188 .local_elements = 0, 189 .event_ring = 0, 190 .dir = DMA_TO_DEVICE, 191 .ee_mask = MHI_CH_EE_AMSS, 192 .pollcfg = 0, 193 .doorbell = MHI_DB_BRST_DISABLE, 194 .lpm_notify = false, 195 .offload_channel = false, 196 .doorbell_mode_switch = false, 197 .auto_queue = false, 198 .wake_capable = false, 199 }, 200 { 201 .name = "QAIC_CONTROL", 202 .num = 11, 203 .num_elements = 128, 204 .local_elements = 0, 205 .event_ring = 0, 206 .dir = DMA_FROM_DEVICE, 207 .ee_mask = MHI_CH_EE_AMSS, 208 .pollcfg = 0, 209 .doorbell = MHI_DB_BRST_DISABLE, 210 .lpm_notify = false, 211 .offload_channel = false, 212 .doorbell_mode_switch = false, 213 .auto_queue = false, 214 .wake_capable = false, 215 }, 216 { 217 .name = "QAIC_LOGGING", 218 .num = 12, 219 .num_elements = 32, 220 .local_elements = 0, 221 .event_ring = 0, 222 .dir = DMA_TO_DEVICE, 223 .ee_mask = MHI_CH_EE_SBL, 224 .pollcfg = 0, 225 .doorbell = MHI_DB_BRST_DISABLE, 226 .lpm_notify = false, 227 .offload_channel = false, 228 .doorbell_mode_switch = false, 229 .auto_queue = false, 230 .wake_capable = false, 231 }, 232 { 233 .name = "QAIC_LOGGING", 234 .num = 13, 235 .num_elements = 32, 236 .local_elements = 0, 237 .event_ring = 0, 238 .dir = DMA_FROM_DEVICE, 239 .ee_mask = MHI_CH_EE_SBL, 240 .pollcfg = 0, 241 .doorbell = MHI_DB_BRST_DISABLE, 242 .lpm_notify = false, 243 .offload_channel = false, 244 .doorbell_mode_switch = false, 245 .auto_queue = false, 246 .wake_capable = false, 247 }, 248 { 249 .name = "QAIC_STATUS", 250 .num = 14, 251 .num_elements = 32, 252 .local_elements = 0, 253 .event_ring = 0, 254 .dir = DMA_TO_DEVICE, 255 .ee_mask = MHI_CH_EE_AMSS, 256 .pollcfg = 0, 257 .doorbell = MHI_DB_BRST_DISABLE, 258 .lpm_notify = false, 259 .offload_channel = false, 260 .doorbell_mode_switch = false, 261 .auto_queue = false, 262 .wake_capable = false, 263 }, 264 { 265 .name = "QAIC_STATUS", 266 .num = 15, 267 .num_elements = 32, 268 .local_elements = 0, 269 .event_ring = 0, 270 .dir = DMA_FROM_DEVICE, 271 .ee_mask = MHI_CH_EE_AMSS, 272 .pollcfg = 0, 273 .doorbell = MHI_DB_BRST_DISABLE, 274 .lpm_notify = false, 275 .offload_channel = false, 276 .doorbell_mode_switch = false, 277 .auto_queue = false, 278 .wake_capable = false, 279 }, 280 { 281 .name = "QAIC_TELEMETRY", 282 .num = 16, 283 .num_elements = 32, 284 .local_elements = 0, 285 .event_ring = 0, 286 .dir = DMA_TO_DEVICE, 287 .ee_mask = MHI_CH_EE_AMSS, 288 .pollcfg = 0, 289 .doorbell = MHI_DB_BRST_DISABLE, 290 .lpm_notify = false, 291 .offload_channel = false, 292 .doorbell_mode_switch = false, 293 .auto_queue = false, 294 .wake_capable = false, 295 }, 296 { 297 .name = "QAIC_TELEMETRY", 298 .num = 17, 299 .num_elements = 32, 300 .local_elements = 0, 301 .event_ring = 0, 302 .dir = DMA_FROM_DEVICE, 303 .ee_mask = MHI_CH_EE_AMSS, 304 .pollcfg = 0, 305 .doorbell = MHI_DB_BRST_DISABLE, 306 .lpm_notify = false, 307 .offload_channel = false, 308 .doorbell_mode_switch = false, 309 .auto_queue = false, 310 .wake_capable = false, 311 }, 312 { 313 .name = "QAIC_DEBUG", 314 .num = 18, 315 .num_elements = 32, 316 .local_elements = 0, 317 .event_ring = 0, 318 .dir = DMA_TO_DEVICE, 319 .ee_mask = MHI_CH_EE_AMSS, 320 .pollcfg = 0, 321 .doorbell = MHI_DB_BRST_DISABLE, 322 .lpm_notify = false, 323 .offload_channel = false, 324 .doorbell_mode_switch = false, 325 .auto_queue = false, 326 .wake_capable = false, 327 }, 328 { 329 .name = "QAIC_DEBUG", 330 .num = 19, 331 .num_elements = 32, 332 .local_elements = 0, 333 .event_ring = 0, 334 .dir = DMA_FROM_DEVICE, 335 .ee_mask = MHI_CH_EE_AMSS, 336 .pollcfg = 0, 337 .doorbell = MHI_DB_BRST_DISABLE, 338 .lpm_notify = false, 339 .offload_channel = false, 340 .doorbell_mode_switch = false, 341 .auto_queue = false, 342 .wake_capable = false, 343 }, 344 { 345 .name = "QAIC_TIMESYNC", 346 .num = 20, 347 .num_elements = 32, 348 .local_elements = 0, 349 .event_ring = 0, 350 .dir = DMA_TO_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 .auto_queue = false, 358 .wake_capable = false, 359 }, 360 { 361 .name = "QAIC_TIMESYNC", 362 .num = 21, 363 .num_elements = 32, 364 .local_elements = 0, 365 .event_ring = 0, 366 .dir = DMA_FROM_DEVICE, 367 .ee_mask = MHI_CH_EE_SBL, 368 .pollcfg = 0, 369 .doorbell = MHI_DB_BRST_DISABLE, 370 .lpm_notify = false, 371 .offload_channel = false, 372 .doorbell_mode_switch = false, 373 .auto_queue = false, 374 .wake_capable = false, 375 }, 376 { 377 .name = "QAIC_TIMESYNC_PERIODIC", 378 .num = 22, 379 .num_elements = 32, 380 .local_elements = 0, 381 .event_ring = 0, 382 .dir = DMA_TO_DEVICE, 383 .ee_mask = MHI_CH_EE_AMSS, 384 .pollcfg = 0, 385 .doorbell = MHI_DB_BRST_DISABLE, 386 .lpm_notify = false, 387 .offload_channel = false, 388 .doorbell_mode_switch = false, 389 .auto_queue = false, 390 .wake_capable = false, 391 }, 392 { 393 .name = "QAIC_TIMESYNC_PERIODIC", 394 .num = 23, 395 .num_elements = 32, 396 .local_elements = 0, 397 .event_ring = 0, 398 .dir = DMA_FROM_DEVICE, 399 .ee_mask = MHI_CH_EE_AMSS, 400 .pollcfg = 0, 401 .doorbell = MHI_DB_BRST_DISABLE, 402 .lpm_notify = false, 403 .offload_channel = false, 404 .doorbell_mode_switch = false, 405 .auto_queue = false, 406 .wake_capable = false, 407 }, 408 }; 409 410 static struct mhi_event_config aic100_events[] = { 411 { 412 .num_elements = 32, 413 .irq_moderation_ms = 0, 414 .irq = 0, 415 .channel = U32_MAX, 416 .priority = 1, 417 .mode = MHI_DB_BRST_DISABLE, 418 .data_type = MHI_ER_CTRL, 419 .hardware_event = false, 420 .client_managed = false, 421 .offload_channel = false, 422 }, 423 }; 424 425 static struct mhi_controller_config aic100_config = { 426 .max_channels = 128, 427 .timeout_ms = 0, /* controlled by mhi_timeout */ 428 .buf_len = 0, 429 .num_channels = ARRAY_SIZE(aic100_channels), 430 .ch_cfg = aic100_channels, 431 .num_events = ARRAY_SIZE(aic100_events), 432 .event_cfg = aic100_events, 433 .use_bounce_buf = false, 434 .m2_no_db = false, 435 }; 436 437 static int mhi_read_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 *out) 438 { 439 u32 tmp; 440 441 /* 442 * SOC_HW_VERSION quirk 443 * The SOC_HW_VERSION register (offset 0x224) is not reliable and 444 * may contain uninitialized values, including 0xFFFFFFFF. This could 445 * cause a false positive link down error. Instead, intercept any 446 * reads and provide the correct value of the register. 447 */ 448 if (addr - mhi_cntrl->regs == 0x224) { 449 *out = 0x60110200; 450 return 0; 451 } 452 453 tmp = readl_relaxed(addr); 454 if (tmp == U32_MAX) 455 return -EIO; 456 457 *out = tmp; 458 459 return 0; 460 } 461 462 static void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 val) 463 { 464 writel_relaxed(val, addr); 465 } 466 467 static int mhi_runtime_get(struct mhi_controller *mhi_cntrl) 468 { 469 return 0; 470 } 471 472 static void mhi_runtime_put(struct mhi_controller *mhi_cntrl) 473 { 474 } 475 476 static void mhi_status_cb(struct mhi_controller *mhi_cntrl, enum mhi_callback reason) 477 { 478 struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(mhi_cntrl->cntrl_dev)); 479 480 /* this event occurs in atomic context */ 481 if (reason == MHI_CB_FATAL_ERROR) 482 pci_err(qdev->pdev, "Fatal error received from device. Attempting to recover\n"); 483 /* this event occurs in non-atomic context */ 484 if (reason == MHI_CB_SYS_ERROR) 485 qaic_dev_reset_clean_local_state(qdev); 486 } 487 488 static int mhi_reset_and_async_power_up(struct mhi_controller *mhi_cntrl) 489 { 490 u8 time_sec = 1; 491 int current_ee; 492 int ret; 493 494 /* Reset the device to bring the device in PBL EE */ 495 mhi_soc_reset(mhi_cntrl); 496 497 /* 498 * Keep checking the execution environment(EE) after every 1 second 499 * interval. 500 */ 501 do { 502 msleep(1000); 503 current_ee = mhi_get_exec_env(mhi_cntrl); 504 } while (current_ee != MHI_EE_PBL && time_sec++ <= MAX_RESET_TIME_SEC); 505 506 /* If the device is in PBL EE retry power up */ 507 if (current_ee == MHI_EE_PBL) 508 ret = mhi_async_power_up(mhi_cntrl); 509 else 510 ret = -EIO; 511 512 return ret; 513 } 514 515 struct mhi_controller *qaic_mhi_register_controller(struct pci_dev *pci_dev, void __iomem *mhi_bar, 516 int mhi_irq, bool shared_msi) 517 { 518 struct mhi_controller *mhi_cntrl; 519 int ret; 520 521 mhi_cntrl = devm_kzalloc(&pci_dev->dev, sizeof(*mhi_cntrl), GFP_KERNEL); 522 if (!mhi_cntrl) 523 return ERR_PTR(-ENOMEM); 524 525 mhi_cntrl->cntrl_dev = &pci_dev->dev; 526 527 /* 528 * Covers the entire possible physical ram region. Remote side is 529 * going to calculate a size of this range, so subtract 1 to prevent 530 * rollover. 531 */ 532 mhi_cntrl->iova_start = 0; 533 mhi_cntrl->iova_stop = PHYS_ADDR_MAX - 1; 534 mhi_cntrl->status_cb = mhi_status_cb; 535 mhi_cntrl->runtime_get = mhi_runtime_get; 536 mhi_cntrl->runtime_put = mhi_runtime_put; 537 mhi_cntrl->read_reg = mhi_read_reg; 538 mhi_cntrl->write_reg = mhi_write_reg; 539 mhi_cntrl->regs = mhi_bar; 540 mhi_cntrl->reg_len = SZ_4K; 541 mhi_cntrl->nr_irqs = 1; 542 mhi_cntrl->irq = devm_kmalloc(&pci_dev->dev, sizeof(*mhi_cntrl->irq), GFP_KERNEL); 543 544 if (!mhi_cntrl->irq) 545 return ERR_PTR(-ENOMEM); 546 547 mhi_cntrl->irq[0] = mhi_irq; 548 549 if (shared_msi) /* MSI shared with data path, no IRQF_NO_SUSPEND */ 550 mhi_cntrl->irq_flags = IRQF_SHARED; 551 552 mhi_cntrl->fw_image = "qcom/aic100/sbl.bin"; 553 554 /* use latest configured timeout */ 555 aic100_config.timeout_ms = mhi_timeout_ms; 556 ret = mhi_register_controller(mhi_cntrl, &aic100_config); 557 if (ret) { 558 pci_err(pci_dev, "mhi_register_controller failed %d\n", ret); 559 return ERR_PTR(ret); 560 } 561 562 ret = mhi_prepare_for_power_up(mhi_cntrl); 563 if (ret) { 564 pci_err(pci_dev, "mhi_prepare_for_power_up failed %d\n", ret); 565 goto prepare_power_up_fail; 566 } 567 568 ret = mhi_async_power_up(mhi_cntrl); 569 /* 570 * If EIO is returned it is possible that device is in SBL EE, which is 571 * undesired. SOC reset the device and try to power up again. 572 */ 573 if (ret == -EIO && MHI_EE_SBL == mhi_get_exec_env(mhi_cntrl)) { 574 pci_err(pci_dev, "Found device in SBL at MHI init. Attempting a reset.\n"); 575 ret = mhi_reset_and_async_power_up(mhi_cntrl); 576 } 577 578 if (ret) { 579 pci_err(pci_dev, "mhi_async_power_up failed %d\n", ret); 580 goto power_up_fail; 581 } 582 583 return mhi_cntrl; 584 585 power_up_fail: 586 mhi_unprepare_after_power_down(mhi_cntrl); 587 prepare_power_up_fail: 588 mhi_unregister_controller(mhi_cntrl); 589 return ERR_PTR(ret); 590 } 591 592 void qaic_mhi_free_controller(struct mhi_controller *mhi_cntrl, bool link_up) 593 { 594 mhi_power_down(mhi_cntrl, link_up); 595 mhi_unprepare_after_power_down(mhi_cntrl); 596 mhi_unregister_controller(mhi_cntrl); 597 } 598 599 void qaic_mhi_start_reset(struct mhi_controller *mhi_cntrl) 600 { 601 mhi_power_down(mhi_cntrl, true); 602 } 603 604 void qaic_mhi_reset_done(struct mhi_controller *mhi_cntrl) 605 { 606 struct pci_dev *pci_dev = container_of(mhi_cntrl->cntrl_dev, struct pci_dev, dev); 607 int ret; 608 609 ret = mhi_async_power_up(mhi_cntrl); 610 if (ret) 611 pci_err(pci_dev, "mhi_async_power_up failed after reset %d\n", ret); 612 } 613