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 | MHI_CH_EE_AMSS, 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 | MHI_CH_EE_AMSS, 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 378 static struct mhi_event_config aic100_events[] = { 379 { 380 .num_elements = 32, 381 .irq_moderation_ms = 0, 382 .irq = 0, 383 .channel = U32_MAX, 384 .priority = 1, 385 .mode = MHI_DB_BRST_DISABLE, 386 .data_type = MHI_ER_CTRL, 387 .hardware_event = false, 388 .client_managed = false, 389 .offload_channel = false, 390 }, 391 }; 392 393 static struct mhi_controller_config aic100_config = { 394 .max_channels = 128, 395 .timeout_ms = 0, /* controlled by mhi_timeout */ 396 .buf_len = 0, 397 .num_channels = ARRAY_SIZE(aic100_channels), 398 .ch_cfg = aic100_channels, 399 .num_events = ARRAY_SIZE(aic100_events), 400 .event_cfg = aic100_events, 401 .use_bounce_buf = false, 402 .m2_no_db = false, 403 }; 404 405 static int mhi_read_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 *out) 406 { 407 u32 tmp; 408 409 /* 410 * SOC_HW_VERSION quirk 411 * The SOC_HW_VERSION register (offset 0x224) is not reliable and 412 * may contain uninitialized values, including 0xFFFFFFFF. This could 413 * cause a false positive link down error. Instead, intercept any 414 * reads and provide the correct value of the register. 415 */ 416 if (addr - mhi_cntrl->regs == 0x224) { 417 *out = 0x60110200; 418 return 0; 419 } 420 421 tmp = readl_relaxed(addr); 422 if (tmp == U32_MAX) 423 return -EIO; 424 425 *out = tmp; 426 427 return 0; 428 } 429 430 static void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 val) 431 { 432 writel_relaxed(val, addr); 433 } 434 435 static int mhi_runtime_get(struct mhi_controller *mhi_cntrl) 436 { 437 return 0; 438 } 439 440 static void mhi_runtime_put(struct mhi_controller *mhi_cntrl) 441 { 442 } 443 444 static void mhi_status_cb(struct mhi_controller *mhi_cntrl, enum mhi_callback reason) 445 { 446 struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(mhi_cntrl->cntrl_dev)); 447 448 /* this event occurs in atomic context */ 449 if (reason == MHI_CB_FATAL_ERROR) 450 pci_err(qdev->pdev, "Fatal error received from device. Attempting to recover\n"); 451 /* this event occurs in non-atomic context */ 452 if (reason == MHI_CB_SYS_ERROR) 453 qaic_dev_reset_clean_local_state(qdev, true); 454 } 455 456 static int mhi_reset_and_async_power_up(struct mhi_controller *mhi_cntrl) 457 { 458 u8 time_sec = 1; 459 int current_ee; 460 int ret; 461 462 /* Reset the device to bring the device in PBL EE */ 463 mhi_soc_reset(mhi_cntrl); 464 465 /* 466 * Keep checking the execution environment(EE) after every 1 second 467 * interval. 468 */ 469 do { 470 msleep(1000); 471 current_ee = mhi_get_exec_env(mhi_cntrl); 472 } while (current_ee != MHI_EE_PBL && time_sec++ <= MAX_RESET_TIME_SEC); 473 474 /* If the device is in PBL EE retry power up */ 475 if (current_ee == MHI_EE_PBL) 476 ret = mhi_async_power_up(mhi_cntrl); 477 else 478 ret = -EIO; 479 480 return ret; 481 } 482 483 struct mhi_controller *qaic_mhi_register_controller(struct pci_dev *pci_dev, void __iomem *mhi_bar, 484 int mhi_irq) 485 { 486 struct mhi_controller *mhi_cntrl; 487 int ret; 488 489 mhi_cntrl = devm_kzalloc(&pci_dev->dev, sizeof(*mhi_cntrl), GFP_KERNEL); 490 if (!mhi_cntrl) 491 return ERR_PTR(-ENOMEM); 492 493 mhi_cntrl->cntrl_dev = &pci_dev->dev; 494 495 /* 496 * Covers the entire possible physical ram region. Remote side is 497 * going to calculate a size of this range, so subtract 1 to prevent 498 * rollover. 499 */ 500 mhi_cntrl->iova_start = 0; 501 mhi_cntrl->iova_stop = PHYS_ADDR_MAX - 1; 502 mhi_cntrl->status_cb = mhi_status_cb; 503 mhi_cntrl->runtime_get = mhi_runtime_get; 504 mhi_cntrl->runtime_put = mhi_runtime_put; 505 mhi_cntrl->read_reg = mhi_read_reg; 506 mhi_cntrl->write_reg = mhi_write_reg; 507 mhi_cntrl->regs = mhi_bar; 508 mhi_cntrl->reg_len = SZ_4K; 509 mhi_cntrl->nr_irqs = 1; 510 mhi_cntrl->irq = devm_kmalloc(&pci_dev->dev, sizeof(*mhi_cntrl->irq), GFP_KERNEL); 511 512 if (!mhi_cntrl->irq) 513 return ERR_PTR(-ENOMEM); 514 515 mhi_cntrl->irq[0] = mhi_irq; 516 mhi_cntrl->fw_image = "qcom/aic100/sbl.bin"; 517 518 /* use latest configured timeout */ 519 aic100_config.timeout_ms = mhi_timeout_ms; 520 ret = mhi_register_controller(mhi_cntrl, &aic100_config); 521 if (ret) { 522 pci_err(pci_dev, "mhi_register_controller failed %d\n", ret); 523 return ERR_PTR(ret); 524 } 525 526 ret = mhi_prepare_for_power_up(mhi_cntrl); 527 if (ret) { 528 pci_err(pci_dev, "mhi_prepare_for_power_up failed %d\n", ret); 529 goto prepare_power_up_fail; 530 } 531 532 ret = mhi_async_power_up(mhi_cntrl); 533 /* 534 * If EIO is returned it is possible that device is in SBL EE, which is 535 * undesired. SOC reset the device and try to power up again. 536 */ 537 if (ret == -EIO && MHI_EE_SBL == mhi_get_exec_env(mhi_cntrl)) { 538 pci_err(pci_dev, "Found device in SBL at MHI init. Attempting a reset.\n"); 539 ret = mhi_reset_and_async_power_up(mhi_cntrl); 540 } 541 542 if (ret) { 543 pci_err(pci_dev, "mhi_async_power_up failed %d\n", ret); 544 goto power_up_fail; 545 } 546 547 return mhi_cntrl; 548 549 power_up_fail: 550 mhi_unprepare_after_power_down(mhi_cntrl); 551 prepare_power_up_fail: 552 mhi_unregister_controller(mhi_cntrl); 553 return ERR_PTR(ret); 554 } 555 556 void qaic_mhi_free_controller(struct mhi_controller *mhi_cntrl, bool link_up) 557 { 558 mhi_power_down(mhi_cntrl, link_up); 559 mhi_unprepare_after_power_down(mhi_cntrl); 560 mhi_unregister_controller(mhi_cntrl); 561 } 562 563 void qaic_mhi_start_reset(struct mhi_controller *mhi_cntrl) 564 { 565 mhi_power_down(mhi_cntrl, true); 566 } 567 568 void qaic_mhi_reset_done(struct mhi_controller *mhi_cntrl) 569 { 570 struct pci_dev *pci_dev = container_of(mhi_cntrl->cntrl_dev, struct pci_dev, dev); 571 int ret; 572 573 ret = mhi_async_power_up(mhi_cntrl); 574 if (ret) 575 pci_err(pci_dev, "mhi_async_power_up failed after reset %d\n", ret); 576 } 577