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 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 .num = 21, 362 .name = "QAIC_TIMESYNC", 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 .num = 23, 394 .name = "QAIC_TIMESYNC_PERIODIC", 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 = readl_relaxed(addr); 440 441 if (tmp == U32_MAX) 442 return -EIO; 443 444 *out = tmp; 445 446 return 0; 447 } 448 449 static void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 val) 450 { 451 writel_relaxed(val, addr); 452 } 453 454 static int mhi_runtime_get(struct mhi_controller *mhi_cntrl) 455 { 456 return 0; 457 } 458 459 static void mhi_runtime_put(struct mhi_controller *mhi_cntrl) 460 { 461 } 462 463 static void mhi_status_cb(struct mhi_controller *mhi_cntrl, enum mhi_callback reason) 464 { 465 struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(mhi_cntrl->cntrl_dev)); 466 467 /* this event occurs in atomic context */ 468 if (reason == MHI_CB_FATAL_ERROR) 469 pci_err(qdev->pdev, "Fatal error received from device. Attempting to recover\n"); 470 /* this event occurs in non-atomic context */ 471 if (reason == MHI_CB_SYS_ERROR) 472 qaic_dev_reset_clean_local_state(qdev); 473 } 474 475 static int mhi_reset_and_async_power_up(struct mhi_controller *mhi_cntrl) 476 { 477 u8 time_sec = 1; 478 int current_ee; 479 int ret; 480 481 /* Reset the device to bring the device in PBL EE */ 482 mhi_soc_reset(mhi_cntrl); 483 484 /* 485 * Keep checking the execution environment(EE) after every 1 second 486 * interval. 487 */ 488 do { 489 msleep(1000); 490 current_ee = mhi_get_exec_env(mhi_cntrl); 491 } while (current_ee != MHI_EE_PBL && time_sec++ <= MAX_RESET_TIME_SEC); 492 493 /* If the device is in PBL EE retry power up */ 494 if (current_ee == MHI_EE_PBL) 495 ret = mhi_async_power_up(mhi_cntrl); 496 else 497 ret = -EIO; 498 499 return ret; 500 } 501 502 struct mhi_controller *qaic_mhi_register_controller(struct pci_dev *pci_dev, void __iomem *mhi_bar, 503 int mhi_irq, bool shared_msi) 504 { 505 struct mhi_controller *mhi_cntrl; 506 int ret; 507 508 mhi_cntrl = devm_kzalloc(&pci_dev->dev, sizeof(*mhi_cntrl), GFP_KERNEL); 509 if (!mhi_cntrl) 510 return ERR_PTR(-ENOMEM); 511 512 mhi_cntrl->cntrl_dev = &pci_dev->dev; 513 514 /* 515 * Covers the entire possible physical ram region. Remote side is 516 * going to calculate a size of this range, so subtract 1 to prevent 517 * rollover. 518 */ 519 mhi_cntrl->iova_start = 0; 520 mhi_cntrl->iova_stop = PHYS_ADDR_MAX - 1; 521 mhi_cntrl->status_cb = mhi_status_cb; 522 mhi_cntrl->runtime_get = mhi_runtime_get; 523 mhi_cntrl->runtime_put = mhi_runtime_put; 524 mhi_cntrl->read_reg = mhi_read_reg; 525 mhi_cntrl->write_reg = mhi_write_reg; 526 mhi_cntrl->regs = mhi_bar; 527 mhi_cntrl->reg_len = SZ_4K; 528 mhi_cntrl->nr_irqs = 1; 529 mhi_cntrl->irq = devm_kmalloc(&pci_dev->dev, sizeof(*mhi_cntrl->irq), GFP_KERNEL); 530 531 if (!mhi_cntrl->irq) 532 return ERR_PTR(-ENOMEM); 533 534 mhi_cntrl->irq[0] = mhi_irq; 535 536 if (shared_msi) /* MSI shared with data path, no IRQF_NO_SUSPEND */ 537 mhi_cntrl->irq_flags = IRQF_SHARED; 538 539 mhi_cntrl->fw_image = "qcom/aic100/sbl.bin"; 540 541 /* use latest configured timeout */ 542 aic100_config.timeout_ms = mhi_timeout_ms; 543 ret = mhi_register_controller(mhi_cntrl, &aic100_config); 544 if (ret) { 545 pci_err(pci_dev, "mhi_register_controller failed %d\n", ret); 546 return ERR_PTR(ret); 547 } 548 549 ret = mhi_prepare_for_power_up(mhi_cntrl); 550 if (ret) { 551 pci_err(pci_dev, "mhi_prepare_for_power_up failed %d\n", ret); 552 goto prepare_power_up_fail; 553 } 554 555 ret = mhi_async_power_up(mhi_cntrl); 556 /* 557 * If EIO is returned it is possible that device is in SBL EE, which is 558 * undesired. SOC reset the device and try to power up again. 559 */ 560 if (ret == -EIO && MHI_EE_SBL == mhi_get_exec_env(mhi_cntrl)) { 561 pci_err(pci_dev, "Found device in SBL at MHI init. Attempting a reset.\n"); 562 ret = mhi_reset_and_async_power_up(mhi_cntrl); 563 } 564 565 if (ret) { 566 pci_err(pci_dev, "mhi_async_power_up failed %d\n", ret); 567 goto power_up_fail; 568 } 569 570 return mhi_cntrl; 571 572 power_up_fail: 573 mhi_unprepare_after_power_down(mhi_cntrl); 574 prepare_power_up_fail: 575 mhi_unregister_controller(mhi_cntrl); 576 return ERR_PTR(ret); 577 } 578 579 void qaic_mhi_free_controller(struct mhi_controller *mhi_cntrl, bool link_up) 580 { 581 mhi_power_down(mhi_cntrl, link_up); 582 mhi_unprepare_after_power_down(mhi_cntrl); 583 mhi_unregister_controller(mhi_cntrl); 584 } 585 586 void qaic_mhi_start_reset(struct mhi_controller *mhi_cntrl) 587 { 588 mhi_power_down(mhi_cntrl, true); 589 } 590 591 void qaic_mhi_reset_done(struct mhi_controller *mhi_cntrl) 592 { 593 struct pci_dev *pci_dev = container_of(mhi_cntrl->cntrl_dev, struct pci_dev, dev); 594 int ret; 595 596 ret = mhi_async_power_up(mhi_cntrl); 597 if (ret) 598 pci_err(pci_dev, "mhi_async_power_up failed after reset %d\n", ret); 599 } 600