1 // SPDX-License-Identifier: GPL-2.0-only
3 /* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved. */
4 /* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. */
6 #include <linux/delay.h>
8 #include <linux/memblock.h>
10 #include <linux/moduleparam.h>
11 #include <linux/pci.h>
12 #include <linux/sizes.h>
14 #include "mhi_controller.h"
17 #define MAX_RESET_TIME_SEC 25
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");
23 static const struct mhi_channel_config aic100_channels[] = {
25 .name = "QAIC_LOOPBACK",
31 .ee_mask = MHI_CH_EE_AMSS,
33 .doorbell = MHI_DB_BRST_DISABLE,
35 .offload_channel = false,
36 .doorbell_mode_switch = false,
38 .wake_capable = false,
41 .name = "QAIC_LOOPBACK",
46 .dir = DMA_FROM_DEVICE,
47 .ee_mask = MHI_CH_EE_AMSS,
49 .doorbell = MHI_DB_BRST_DISABLE,
51 .offload_channel = false,
52 .doorbell_mode_switch = false,
54 .wake_capable = false,
57 .name = "QAIC_SAHARA",
63 .ee_mask = MHI_CH_EE_SBL,
65 .doorbell = MHI_DB_BRST_DISABLE,
67 .offload_channel = false,
68 .doorbell_mode_switch = false,
70 .wake_capable = false,
73 .name = "QAIC_SAHARA",
78 .dir = DMA_FROM_DEVICE,
79 .ee_mask = MHI_CH_EE_SBL,
81 .doorbell = MHI_DB_BRST_DISABLE,
83 .offload_channel = false,
84 .doorbell_mode_switch = false,
86 .wake_capable = false,
95 .ee_mask = MHI_CH_EE_AMSS,
97 .doorbell = MHI_DB_BRST_DISABLE,
99 .offload_channel = false,
100 .doorbell_mode_switch = false,
102 .wake_capable = false,
110 .dir = DMA_FROM_DEVICE,
111 .ee_mask = MHI_CH_EE_AMSS,
113 .doorbell = MHI_DB_BRST_DISABLE,
115 .offload_channel = false,
116 .doorbell_mode_switch = false,
118 .wake_capable = false,
126 .dir = DMA_TO_DEVICE,
127 .ee_mask = MHI_CH_EE_AMSS,
129 .doorbell = MHI_DB_BRST_DISABLE,
131 .offload_channel = false,
132 .doorbell_mode_switch = false,
134 .wake_capable = false,
142 .dir = DMA_FROM_DEVICE,
143 .ee_mask = MHI_CH_EE_AMSS,
145 .doorbell = MHI_DB_BRST_DISABLE,
147 .offload_channel = false,
148 .doorbell_mode_switch = false,
150 .wake_capable = false,
158 .dir = DMA_TO_DEVICE,
159 .ee_mask = MHI_CH_EE_AMSS,
161 .doorbell = MHI_DB_BRST_DISABLE,
163 .offload_channel = false,
164 .doorbell_mode_switch = false,
166 .wake_capable = false,
174 .dir = DMA_FROM_DEVICE,
175 .ee_mask = MHI_CH_EE_AMSS,
177 .doorbell = MHI_DB_BRST_DISABLE,
179 .offload_channel = false,
180 .doorbell_mode_switch = false,
182 .wake_capable = false,
185 .name = "QAIC_CONTROL",
190 .dir = DMA_TO_DEVICE,
191 .ee_mask = MHI_CH_EE_AMSS,
193 .doorbell = MHI_DB_BRST_DISABLE,
195 .offload_channel = false,
196 .doorbell_mode_switch = false,
198 .wake_capable = false,
201 .name = "QAIC_CONTROL",
206 .dir = DMA_FROM_DEVICE,
207 .ee_mask = MHI_CH_EE_AMSS,
209 .doorbell = MHI_DB_BRST_DISABLE,
211 .offload_channel = false,
212 .doorbell_mode_switch = false,
214 .wake_capable = false,
217 .name = "QAIC_LOGGING",
222 .dir = DMA_TO_DEVICE,
223 .ee_mask = MHI_CH_EE_SBL,
225 .doorbell = MHI_DB_BRST_DISABLE,
227 .offload_channel = false,
228 .doorbell_mode_switch = false,
230 .wake_capable = false,
233 .name = "QAIC_LOGGING",
238 .dir = DMA_FROM_DEVICE,
239 .ee_mask = MHI_CH_EE_SBL,
241 .doorbell = MHI_DB_BRST_DISABLE,
243 .offload_channel = false,
244 .doorbell_mode_switch = false,
246 .wake_capable = false,
249 .name = "QAIC_STATUS",
254 .dir = DMA_TO_DEVICE,
255 .ee_mask = MHI_CH_EE_AMSS,
257 .doorbell = MHI_DB_BRST_DISABLE,
259 .offload_channel = false,
260 .doorbell_mode_switch = false,
262 .wake_capable = false,
265 .name = "QAIC_STATUS",
270 .dir = DMA_FROM_DEVICE,
271 .ee_mask = MHI_CH_EE_AMSS,
273 .doorbell = MHI_DB_BRST_DISABLE,
275 .offload_channel = false,
276 .doorbell_mode_switch = false,
278 .wake_capable = false,
281 .name = "QAIC_TELEMETRY",
286 .dir = DMA_TO_DEVICE,
287 .ee_mask = MHI_CH_EE_AMSS,
289 .doorbell = MHI_DB_BRST_DISABLE,
291 .offload_channel = false,
292 .doorbell_mode_switch = false,
294 .wake_capable = false,
297 .name = "QAIC_TELEMETRY",
302 .dir = DMA_FROM_DEVICE,
303 .ee_mask = MHI_CH_EE_AMSS,
305 .doorbell = MHI_DB_BRST_DISABLE,
307 .offload_channel = false,
308 .doorbell_mode_switch = false,
310 .wake_capable = false,
313 .name = "QAIC_DEBUG",
318 .dir = DMA_TO_DEVICE,
319 .ee_mask = MHI_CH_EE_AMSS,
321 .doorbell = MHI_DB_BRST_DISABLE,
323 .offload_channel = false,
324 .doorbell_mode_switch = false,
326 .wake_capable = false,
329 .name = "QAIC_DEBUG",
334 .dir = DMA_FROM_DEVICE,
335 .ee_mask = MHI_CH_EE_AMSS,
337 .doorbell = MHI_DB_BRST_DISABLE,
339 .offload_channel = false,
340 .doorbell_mode_switch = false,
342 .wake_capable = false,
345 .name = "QAIC_TIMESYNC",
350 .dir = DMA_TO_DEVICE,
351 .ee_mask = MHI_CH_EE_SBL,
353 .doorbell = MHI_DB_BRST_DISABLE,
355 .offload_channel = false,
356 .doorbell_mode_switch = false,
358 .wake_capable = false,
361 .name = "QAIC_TIMESYNC",
366 .dir = DMA_FROM_DEVICE,
367 .ee_mask = MHI_CH_EE_SBL,
369 .doorbell = MHI_DB_BRST_DISABLE,
371 .offload_channel = false,
372 .doorbell_mode_switch = false,
374 .wake_capable = false,
377 .name = "QAIC_TIMESYNC_PERIODIC",
382 .dir = DMA_TO_DEVICE,
383 .ee_mask = MHI_CH_EE_AMSS,
385 .doorbell = MHI_DB_BRST_DISABLE,
387 .offload_channel = false,
388 .doorbell_mode_switch = false,
390 .wake_capable = false,
393 .name = "QAIC_TIMESYNC_PERIODIC",
398 .dir = DMA_FROM_DEVICE,
399 .ee_mask = MHI_CH_EE_AMSS,
401 .doorbell = MHI_DB_BRST_DISABLE,
403 .offload_channel = false,
404 .doorbell_mode_switch = false,
406 .wake_capable = false,
414 .dir = DMA_TO_DEVICE,
415 .ee_mask = MHI_CH_EE_AMSS,
417 .doorbell = MHI_DB_BRST_DISABLE,
419 .offload_channel = false,
420 .doorbell_mode_switch = false,
422 .wake_capable = false,
430 .dir = DMA_FROM_DEVICE,
431 .ee_mask = MHI_CH_EE_AMSS,
433 .doorbell = MHI_DB_BRST_DISABLE,
435 .offload_channel = false,
436 .doorbell_mode_switch = false,
438 .wake_capable = false,
442 static struct mhi_event_config aic100_events[] = {
445 .irq_moderation_ms = 0,
449 .mode = MHI_DB_BRST_DISABLE,
450 .data_type = MHI_ER_CTRL,
451 .hardware_event = false,
452 .client_managed = false,
453 .offload_channel = false,
457 static struct mhi_controller_config aic100_config = {
459 .timeout_ms = 0, /* controlled by mhi_timeout */
461 .num_channels = ARRAY_SIZE(aic100_channels),
462 .ch_cfg = aic100_channels,
463 .num_events = ARRAY_SIZE(aic100_events),
464 .event_cfg = aic100_events,
465 .use_bounce_buf = false,
469 static int mhi_read_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 *out)
474 * SOC_HW_VERSION quirk
475 * The SOC_HW_VERSION register (offset 0x224) is not reliable and
476 * may contain uninitialized values, including 0xFFFFFFFF. This could
477 * cause a false positive link down error. Instead, intercept any
478 * reads and provide the correct value of the register.
480 if (addr - mhi_cntrl->regs == 0x224) {
485 tmp = readl_relaxed(addr);
494 static void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 val)
496 writel_relaxed(val, addr);
499 static int mhi_runtime_get(struct mhi_controller *mhi_cntrl)
504 static void mhi_runtime_put(struct mhi_controller *mhi_cntrl)
508 static void mhi_status_cb(struct mhi_controller *mhi_cntrl, enum mhi_callback reason)
510 struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(mhi_cntrl->cntrl_dev));
512 /* this event occurs in atomic context */
513 if (reason == MHI_CB_FATAL_ERROR)
514 pci_err(qdev->pdev, "Fatal error received from device. Attempting to recover\n");
515 /* this event occurs in non-atomic context */
516 if (reason == MHI_CB_SYS_ERROR)
517 qaic_dev_reset_clean_local_state(qdev);
520 static int mhi_reset_and_async_power_up(struct mhi_controller *mhi_cntrl)
526 /* Reset the device to bring the device in PBL EE */
527 mhi_soc_reset(mhi_cntrl);
530 * Keep checking the execution environment(EE) after every 1 second
535 current_ee = mhi_get_exec_env(mhi_cntrl);
536 } while (current_ee != MHI_EE_PBL && time_sec++ <= MAX_RESET_TIME_SEC);
538 /* If the device is in PBL EE retry power up */
539 if (current_ee == MHI_EE_PBL)
540 ret = mhi_async_power_up(mhi_cntrl);
547 struct mhi_controller *qaic_mhi_register_controller(struct pci_dev *pci_dev, void __iomem *mhi_bar,
548 int mhi_irq, bool shared_msi)
550 struct mhi_controller *mhi_cntrl;
553 mhi_cntrl = devm_kzalloc(&pci_dev->dev, sizeof(*mhi_cntrl), GFP_KERNEL);
555 return ERR_PTR(-ENOMEM);
557 mhi_cntrl->cntrl_dev = &pci_dev->dev;
560 * Covers the entire possible physical ram region. Remote side is
561 * going to calculate a size of this range, so subtract 1 to prevent
564 mhi_cntrl->iova_start = 0;
565 mhi_cntrl->iova_stop = PHYS_ADDR_MAX - 1;
566 mhi_cntrl->status_cb = mhi_status_cb;
567 mhi_cntrl->runtime_get = mhi_runtime_get;
568 mhi_cntrl->runtime_put = mhi_runtime_put;
569 mhi_cntrl->read_reg = mhi_read_reg;
570 mhi_cntrl->write_reg = mhi_write_reg;
571 mhi_cntrl->regs = mhi_bar;
572 mhi_cntrl->reg_len = SZ_4K;
573 mhi_cntrl->nr_irqs = 1;
574 mhi_cntrl->irq = devm_kmalloc(&pci_dev->dev, sizeof(*mhi_cntrl->irq), GFP_KERNEL);
577 return ERR_PTR(-ENOMEM);
579 mhi_cntrl->irq[0] = mhi_irq;
581 if (shared_msi) /* MSI shared with data path, no IRQF_NO_SUSPEND */
582 mhi_cntrl->irq_flags = IRQF_SHARED;
584 mhi_cntrl->fw_image = "qcom/aic100/sbl.bin";
586 /* use latest configured timeout */
587 aic100_config.timeout_ms = mhi_timeout_ms;
588 ret = mhi_register_controller(mhi_cntrl, &aic100_config);
590 pci_err(pci_dev, "mhi_register_controller failed %d\n", ret);
594 ret = mhi_prepare_for_power_up(mhi_cntrl);
596 pci_err(pci_dev, "mhi_prepare_for_power_up failed %d\n", ret);
597 goto prepare_power_up_fail;
600 ret = mhi_async_power_up(mhi_cntrl);
602 * If EIO is returned it is possible that device is in SBL EE, which is
603 * undesired. SOC reset the device and try to power up again.
605 if (ret == -EIO && MHI_EE_SBL == mhi_get_exec_env(mhi_cntrl)) {
606 pci_err(pci_dev, "Found device in SBL at MHI init. Attempting a reset.\n");
607 ret = mhi_reset_and_async_power_up(mhi_cntrl);
611 pci_err(pci_dev, "mhi_async_power_up failed %d\n", ret);
618 mhi_unprepare_after_power_down(mhi_cntrl);
619 prepare_power_up_fail:
620 mhi_unregister_controller(mhi_cntrl);
624 void qaic_mhi_free_controller(struct mhi_controller *mhi_cntrl, bool link_up)
626 mhi_power_down(mhi_cntrl, link_up);
627 mhi_unprepare_after_power_down(mhi_cntrl);
628 mhi_unregister_controller(mhi_cntrl);
631 void qaic_mhi_start_reset(struct mhi_controller *mhi_cntrl)
633 mhi_power_down(mhi_cntrl, true);
636 void qaic_mhi_reset_done(struct mhi_controller *mhi_cntrl)
638 struct pci_dev *pci_dev = container_of(mhi_cntrl->cntrl_dev, struct pci_dev, dev);
641 ret = mhi_async_power_up(mhi_cntrl);
643 pci_err(pci_dev, "mhi_async_power_up failed after reset %d\n", ret);