mhi_controller.c 14 KB

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