mhi_controller.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932
  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 char *fw_image_paths[FAMILY_MAX] = {
  18. [FAMILY_AIC100] = "qcom/aic100/sbl.bin",
  19. [FAMILY_AIC200] = "qcom/aic200/sbl.bin",
  20. };
  21. static const struct mhi_channel_config aic100_channels[] = {
  22. {
  23. .name = "QAIC_LOOPBACK",
  24. .num = 0,
  25. .num_elements = 32,
  26. .local_elements = 0,
  27. .event_ring = 0,
  28. .dir = DMA_TO_DEVICE,
  29. .ee_mask = MHI_CH_EE_AMSS,
  30. .pollcfg = 0,
  31. .doorbell = MHI_DB_BRST_DISABLE,
  32. .lpm_notify = false,
  33. .offload_channel = false,
  34. .doorbell_mode_switch = false,
  35. .wake_capable = false,
  36. },
  37. {
  38. .name = "QAIC_LOOPBACK",
  39. .num = 1,
  40. .num_elements = 32,
  41. .local_elements = 0,
  42. .event_ring = 0,
  43. .dir = DMA_FROM_DEVICE,
  44. .ee_mask = MHI_CH_EE_AMSS,
  45. .pollcfg = 0,
  46. .doorbell = MHI_DB_BRST_DISABLE,
  47. .lpm_notify = false,
  48. .offload_channel = false,
  49. .doorbell_mode_switch = false,
  50. .wake_capable = false,
  51. },
  52. {
  53. .name = "QAIC_SAHARA",
  54. .num = 2,
  55. .num_elements = 32,
  56. .local_elements = 0,
  57. .event_ring = 0,
  58. .dir = DMA_TO_DEVICE,
  59. .ee_mask = MHI_CH_EE_SBL,
  60. .pollcfg = 0,
  61. .doorbell = MHI_DB_BRST_DISABLE,
  62. .lpm_notify = false,
  63. .offload_channel = false,
  64. .doorbell_mode_switch = false,
  65. .wake_capable = false,
  66. },
  67. {
  68. .name = "QAIC_SAHARA",
  69. .num = 3,
  70. .num_elements = 32,
  71. .local_elements = 0,
  72. .event_ring = 0,
  73. .dir = DMA_FROM_DEVICE,
  74. .ee_mask = MHI_CH_EE_SBL,
  75. .pollcfg = 0,
  76. .doorbell = MHI_DB_BRST_DISABLE,
  77. .lpm_notify = false,
  78. .offload_channel = false,
  79. .doorbell_mode_switch = 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. .wake_capable = false,
  96. },
  97. {
  98. .name = "QAIC_DIAG",
  99. .num = 5,
  100. .num_elements = 32,
  101. .local_elements = 0,
  102. .event_ring = 0,
  103. .dir = DMA_FROM_DEVICE,
  104. .ee_mask = MHI_CH_EE_AMSS,
  105. .pollcfg = 0,
  106. .doorbell = MHI_DB_BRST_DISABLE,
  107. .lpm_notify = false,
  108. .offload_channel = false,
  109. .doorbell_mode_switch = false,
  110. .wake_capable = false,
  111. },
  112. {
  113. .name = "QAIC_SSR",
  114. .num = 6,
  115. .num_elements = 32,
  116. .local_elements = 0,
  117. .event_ring = 0,
  118. .dir = DMA_TO_DEVICE,
  119. .ee_mask = MHI_CH_EE_AMSS,
  120. .pollcfg = 0,
  121. .doorbell = MHI_DB_BRST_DISABLE,
  122. .lpm_notify = false,
  123. .offload_channel = false,
  124. .doorbell_mode_switch = false,
  125. .wake_capable = false,
  126. },
  127. {
  128. .name = "QAIC_SSR",
  129. .num = 7,
  130. .num_elements = 32,
  131. .local_elements = 0,
  132. .event_ring = 0,
  133. .dir = DMA_FROM_DEVICE,
  134. .ee_mask = MHI_CH_EE_AMSS,
  135. .pollcfg = 0,
  136. .doorbell = MHI_DB_BRST_DISABLE,
  137. .lpm_notify = false,
  138. .offload_channel = false,
  139. .doorbell_mode_switch = false,
  140. .wake_capable = false,
  141. },
  142. {
  143. .name = "QAIC_QDSS",
  144. .num = 8,
  145. .num_elements = 32,
  146. .local_elements = 0,
  147. .event_ring = 0,
  148. .dir = DMA_TO_DEVICE,
  149. .ee_mask = MHI_CH_EE_AMSS,
  150. .pollcfg = 0,
  151. .doorbell = MHI_DB_BRST_DISABLE,
  152. .lpm_notify = false,
  153. .offload_channel = false,
  154. .doorbell_mode_switch = false,
  155. .wake_capable = false,
  156. },
  157. {
  158. .name = "QAIC_QDSS",
  159. .num = 9,
  160. .num_elements = 32,
  161. .local_elements = 0,
  162. .event_ring = 0,
  163. .dir = DMA_FROM_DEVICE,
  164. .ee_mask = MHI_CH_EE_AMSS,
  165. .pollcfg = 0,
  166. .doorbell = MHI_DB_BRST_DISABLE,
  167. .lpm_notify = false,
  168. .offload_channel = false,
  169. .doorbell_mode_switch = false,
  170. .wake_capable = false,
  171. },
  172. {
  173. .name = "QAIC_CONTROL",
  174. .num = 10,
  175. .num_elements = 128,
  176. .local_elements = 0,
  177. .event_ring = 0,
  178. .dir = DMA_TO_DEVICE,
  179. .ee_mask = MHI_CH_EE_AMSS,
  180. .pollcfg = 0,
  181. .doorbell = MHI_DB_BRST_DISABLE,
  182. .lpm_notify = false,
  183. .offload_channel = false,
  184. .doorbell_mode_switch = false,
  185. .wake_capable = false,
  186. },
  187. {
  188. .name = "QAIC_CONTROL",
  189. .num = 11,
  190. .num_elements = 128,
  191. .local_elements = 0,
  192. .event_ring = 0,
  193. .dir = DMA_FROM_DEVICE,
  194. .ee_mask = MHI_CH_EE_AMSS,
  195. .pollcfg = 0,
  196. .doorbell = MHI_DB_BRST_DISABLE,
  197. .lpm_notify = false,
  198. .offload_channel = false,
  199. .doorbell_mode_switch = false,
  200. .wake_capable = false,
  201. },
  202. {
  203. .name = "QAIC_LOGGING",
  204. .num = 12,
  205. .num_elements = 32,
  206. .local_elements = 0,
  207. .event_ring = 0,
  208. .dir = DMA_TO_DEVICE,
  209. .ee_mask = MHI_CH_EE_SBL,
  210. .pollcfg = 0,
  211. .doorbell = MHI_DB_BRST_DISABLE,
  212. .lpm_notify = false,
  213. .offload_channel = false,
  214. .doorbell_mode_switch = false,
  215. .wake_capable = false,
  216. },
  217. {
  218. .name = "QAIC_LOGGING",
  219. .num = 13,
  220. .num_elements = 32,
  221. .local_elements = 0,
  222. .event_ring = 0,
  223. .dir = DMA_FROM_DEVICE,
  224. .ee_mask = MHI_CH_EE_SBL,
  225. .pollcfg = 0,
  226. .doorbell = MHI_DB_BRST_DISABLE,
  227. .lpm_notify = false,
  228. .offload_channel = false,
  229. .doorbell_mode_switch = false,
  230. .wake_capable = false,
  231. },
  232. {
  233. .name = "QAIC_STATUS",
  234. .num = 14,
  235. .num_elements = 32,
  236. .local_elements = 0,
  237. .event_ring = 0,
  238. .dir = DMA_TO_DEVICE,
  239. .ee_mask = MHI_CH_EE_AMSS,
  240. .pollcfg = 0,
  241. .doorbell = MHI_DB_BRST_DISABLE,
  242. .lpm_notify = false,
  243. .offload_channel = false,
  244. .doorbell_mode_switch = false,
  245. .wake_capable = false,
  246. },
  247. {
  248. .name = "QAIC_STATUS",
  249. .num = 15,
  250. .num_elements = 32,
  251. .local_elements = 0,
  252. .event_ring = 0,
  253. .dir = DMA_FROM_DEVICE,
  254. .ee_mask = MHI_CH_EE_AMSS,
  255. .pollcfg = 0,
  256. .doorbell = MHI_DB_BRST_DISABLE,
  257. .lpm_notify = false,
  258. .offload_channel = false,
  259. .doorbell_mode_switch = false,
  260. .wake_capable = false,
  261. },
  262. {
  263. .name = "QAIC_TELEMETRY",
  264. .num = 16,
  265. .num_elements = 32,
  266. .local_elements = 0,
  267. .event_ring = 0,
  268. .dir = DMA_TO_DEVICE,
  269. .ee_mask = MHI_CH_EE_AMSS,
  270. .pollcfg = 0,
  271. .doorbell = MHI_DB_BRST_DISABLE,
  272. .lpm_notify = false,
  273. .offload_channel = false,
  274. .doorbell_mode_switch = false,
  275. .wake_capable = false,
  276. },
  277. {
  278. .name = "QAIC_TELEMETRY",
  279. .num = 17,
  280. .num_elements = 32,
  281. .local_elements = 0,
  282. .event_ring = 0,
  283. .dir = DMA_FROM_DEVICE,
  284. .ee_mask = MHI_CH_EE_AMSS,
  285. .pollcfg = 0,
  286. .doorbell = MHI_DB_BRST_DISABLE,
  287. .lpm_notify = false,
  288. .offload_channel = false,
  289. .doorbell_mode_switch = false,
  290. .wake_capable = false,
  291. },
  292. {
  293. .name = "QAIC_DEBUG",
  294. .num = 18,
  295. .num_elements = 32,
  296. .local_elements = 0,
  297. .event_ring = 0,
  298. .dir = DMA_TO_DEVICE,
  299. .ee_mask = MHI_CH_EE_AMSS,
  300. .pollcfg = 0,
  301. .doorbell = MHI_DB_BRST_DISABLE,
  302. .lpm_notify = false,
  303. .offload_channel = false,
  304. .doorbell_mode_switch = false,
  305. .wake_capable = false,
  306. },
  307. {
  308. .name = "QAIC_DEBUG",
  309. .num = 19,
  310. .num_elements = 32,
  311. .local_elements = 0,
  312. .event_ring = 0,
  313. .dir = DMA_FROM_DEVICE,
  314. .ee_mask = MHI_CH_EE_AMSS,
  315. .pollcfg = 0,
  316. .doorbell = MHI_DB_BRST_DISABLE,
  317. .lpm_notify = false,
  318. .offload_channel = false,
  319. .doorbell_mode_switch = false,
  320. .wake_capable = false,
  321. },
  322. {
  323. .name = "QAIC_TIMESYNC",
  324. .num = 20,
  325. .num_elements = 32,
  326. .local_elements = 0,
  327. .event_ring = 0,
  328. .dir = DMA_TO_DEVICE,
  329. .ee_mask = MHI_CH_EE_SBL,
  330. .pollcfg = 0,
  331. .doorbell = MHI_DB_BRST_DISABLE,
  332. .lpm_notify = false,
  333. .offload_channel = false,
  334. .doorbell_mode_switch = false,
  335. .wake_capable = false,
  336. },
  337. {
  338. .name = "QAIC_TIMESYNC",
  339. .num = 21,
  340. .num_elements = 32,
  341. .local_elements = 0,
  342. .event_ring = 0,
  343. .dir = DMA_FROM_DEVICE,
  344. .ee_mask = MHI_CH_EE_SBL,
  345. .pollcfg = 0,
  346. .doorbell = MHI_DB_BRST_DISABLE,
  347. .lpm_notify = false,
  348. .offload_channel = false,
  349. .doorbell_mode_switch = false,
  350. .wake_capable = false,
  351. },
  352. {
  353. .name = "QAIC_TIMESYNC_PERIODIC",
  354. .num = 22,
  355. .num_elements = 32,
  356. .local_elements = 0,
  357. .event_ring = 0,
  358. .dir = DMA_TO_DEVICE,
  359. .ee_mask = MHI_CH_EE_AMSS,
  360. .pollcfg = 0,
  361. .doorbell = MHI_DB_BRST_DISABLE,
  362. .lpm_notify = false,
  363. .offload_channel = false,
  364. .doorbell_mode_switch = false,
  365. .wake_capable = false,
  366. },
  367. {
  368. .name = "QAIC_TIMESYNC_PERIODIC",
  369. .num = 23,
  370. .num_elements = 32,
  371. .local_elements = 0,
  372. .event_ring = 0,
  373. .dir = DMA_FROM_DEVICE,
  374. .ee_mask = MHI_CH_EE_AMSS,
  375. .pollcfg = 0,
  376. .doorbell = MHI_DB_BRST_DISABLE,
  377. .lpm_notify = false,
  378. .offload_channel = false,
  379. .doorbell_mode_switch = false,
  380. .wake_capable = false,
  381. },
  382. {
  383. .name = "IPCR",
  384. .num = 24,
  385. .num_elements = 32,
  386. .local_elements = 0,
  387. .event_ring = 0,
  388. .dir = DMA_TO_DEVICE,
  389. .ee_mask = MHI_CH_EE_AMSS,
  390. .pollcfg = 0,
  391. .doorbell = MHI_DB_BRST_DISABLE,
  392. .lpm_notify = false,
  393. .offload_channel = false,
  394. .doorbell_mode_switch = false,
  395. .wake_capable = false,
  396. },
  397. {
  398. .name = "IPCR",
  399. .num = 25,
  400. .num_elements = 32,
  401. .local_elements = 0,
  402. .event_ring = 0,
  403. .dir = DMA_FROM_DEVICE,
  404. .ee_mask = MHI_CH_EE_AMSS,
  405. .pollcfg = 0,
  406. .doorbell = MHI_DB_BRST_DISABLE,
  407. .lpm_notify = false,
  408. .offload_channel = false,
  409. .doorbell_mode_switch = false,
  410. .wake_capable = false,
  411. },
  412. };
  413. static const struct mhi_channel_config aic200_channels[] = {
  414. {
  415. .name = "QAIC_LOOPBACK",
  416. .num = 0,
  417. .num_elements = 32,
  418. .local_elements = 0,
  419. .event_ring = 0,
  420. .dir = DMA_TO_DEVICE,
  421. .ee_mask = MHI_CH_EE_AMSS,
  422. .pollcfg = 0,
  423. .doorbell = MHI_DB_BRST_DISABLE,
  424. .lpm_notify = false,
  425. .offload_channel = false,
  426. .doorbell_mode_switch = false,
  427. .wake_capable = false,
  428. },
  429. {
  430. .name = "QAIC_LOOPBACK",
  431. .num = 1,
  432. .num_elements = 32,
  433. .local_elements = 0,
  434. .event_ring = 0,
  435. .dir = DMA_FROM_DEVICE,
  436. .ee_mask = MHI_CH_EE_AMSS,
  437. .pollcfg = 0,
  438. .doorbell = MHI_DB_BRST_DISABLE,
  439. .lpm_notify = false,
  440. .offload_channel = false,
  441. .doorbell_mode_switch = false,
  442. .wake_capable = false,
  443. },
  444. {
  445. .name = "QAIC_SAHARA",
  446. .num = 2,
  447. .num_elements = 32,
  448. .local_elements = 0,
  449. .event_ring = 0,
  450. .dir = DMA_TO_DEVICE,
  451. .ee_mask = MHI_CH_EE_SBL,
  452. .pollcfg = 0,
  453. .doorbell = MHI_DB_BRST_DISABLE,
  454. .lpm_notify = false,
  455. .offload_channel = false,
  456. .doorbell_mode_switch = false,
  457. .wake_capable = false,
  458. },
  459. {
  460. .name = "QAIC_SAHARA",
  461. .num = 3,
  462. .num_elements = 32,
  463. .local_elements = 0,
  464. .event_ring = 0,
  465. .dir = DMA_FROM_DEVICE,
  466. .ee_mask = MHI_CH_EE_SBL,
  467. .pollcfg = 0,
  468. .doorbell = MHI_DB_BRST_DISABLE,
  469. .lpm_notify = false,
  470. .offload_channel = false,
  471. .doorbell_mode_switch = false,
  472. .wake_capable = false,
  473. },
  474. {
  475. .name = "QAIC_SSR",
  476. .num = 6,
  477. .num_elements = 32,
  478. .local_elements = 0,
  479. .event_ring = 0,
  480. .dir = DMA_TO_DEVICE,
  481. .ee_mask = MHI_CH_EE_AMSS,
  482. .pollcfg = 0,
  483. .doorbell = MHI_DB_BRST_DISABLE,
  484. .lpm_notify = false,
  485. .offload_channel = false,
  486. .doorbell_mode_switch = false,
  487. .wake_capable = false,
  488. },
  489. {
  490. .name = "QAIC_SSR",
  491. .num = 7,
  492. .num_elements = 32,
  493. .local_elements = 0,
  494. .event_ring = 0,
  495. .dir = DMA_FROM_DEVICE,
  496. .ee_mask = MHI_CH_EE_AMSS,
  497. .pollcfg = 0,
  498. .doorbell = MHI_DB_BRST_DISABLE,
  499. .lpm_notify = false,
  500. .offload_channel = false,
  501. .doorbell_mode_switch = false,
  502. .wake_capable = false,
  503. },
  504. {
  505. .name = "QAIC_CONTROL",
  506. .num = 10,
  507. .num_elements = 128,
  508. .local_elements = 0,
  509. .event_ring = 0,
  510. .dir = DMA_TO_DEVICE,
  511. .ee_mask = MHI_CH_EE_AMSS,
  512. .pollcfg = 0,
  513. .doorbell = MHI_DB_BRST_DISABLE,
  514. .lpm_notify = false,
  515. .offload_channel = false,
  516. .doorbell_mode_switch = false,
  517. .wake_capable = false,
  518. },
  519. {
  520. .name = "QAIC_CONTROL",
  521. .num = 11,
  522. .num_elements = 128,
  523. .local_elements = 0,
  524. .event_ring = 0,
  525. .dir = DMA_FROM_DEVICE,
  526. .ee_mask = MHI_CH_EE_AMSS,
  527. .pollcfg = 0,
  528. .doorbell = MHI_DB_BRST_DISABLE,
  529. .lpm_notify = false,
  530. .offload_channel = false,
  531. .doorbell_mode_switch = false,
  532. .wake_capable = false,
  533. },
  534. {
  535. .name = "QAIC_LOGGING",
  536. .num = 12,
  537. .num_elements = 32,
  538. .local_elements = 0,
  539. .event_ring = 0,
  540. .dir = DMA_TO_DEVICE,
  541. .ee_mask = MHI_CH_EE_SBL,
  542. .pollcfg = 0,
  543. .doorbell = MHI_DB_BRST_DISABLE,
  544. .lpm_notify = false,
  545. .offload_channel = false,
  546. .doorbell_mode_switch = false,
  547. .wake_capable = false,
  548. },
  549. {
  550. .name = "QAIC_LOGGING",
  551. .num = 13,
  552. .num_elements = 32,
  553. .local_elements = 0,
  554. .event_ring = 0,
  555. .dir = DMA_FROM_DEVICE,
  556. .ee_mask = MHI_CH_EE_SBL,
  557. .pollcfg = 0,
  558. .doorbell = MHI_DB_BRST_DISABLE,
  559. .lpm_notify = false,
  560. .offload_channel = false,
  561. .doorbell_mode_switch = false,
  562. .wake_capable = false,
  563. },
  564. {
  565. .name = "QAIC_STATUS",
  566. .num = 14,
  567. .num_elements = 32,
  568. .local_elements = 0,
  569. .event_ring = 0,
  570. .dir = DMA_TO_DEVICE,
  571. .ee_mask = MHI_CH_EE_AMSS,
  572. .pollcfg = 0,
  573. .doorbell = MHI_DB_BRST_DISABLE,
  574. .lpm_notify = false,
  575. .offload_channel = false,
  576. .doorbell_mode_switch = false,
  577. .wake_capable = false,
  578. },
  579. {
  580. .name = "QAIC_STATUS",
  581. .num = 15,
  582. .num_elements = 32,
  583. .local_elements = 0,
  584. .event_ring = 0,
  585. .dir = DMA_FROM_DEVICE,
  586. .ee_mask = MHI_CH_EE_AMSS,
  587. .pollcfg = 0,
  588. .doorbell = MHI_DB_BRST_DISABLE,
  589. .lpm_notify = false,
  590. .offload_channel = false,
  591. .doorbell_mode_switch = false,
  592. .wake_capable = false,
  593. },
  594. {
  595. .name = "QAIC_TELEMETRY",
  596. .num = 16,
  597. .num_elements = 32,
  598. .local_elements = 0,
  599. .event_ring = 0,
  600. .dir = DMA_TO_DEVICE,
  601. .ee_mask = MHI_CH_EE_AMSS,
  602. .pollcfg = 0,
  603. .doorbell = MHI_DB_BRST_DISABLE,
  604. .lpm_notify = false,
  605. .offload_channel = false,
  606. .doorbell_mode_switch = false,
  607. .wake_capable = false,
  608. },
  609. {
  610. .name = "QAIC_TELEMETRY",
  611. .num = 17,
  612. .num_elements = 32,
  613. .local_elements = 0,
  614. .event_ring = 0,
  615. .dir = DMA_FROM_DEVICE,
  616. .ee_mask = MHI_CH_EE_AMSS,
  617. .pollcfg = 0,
  618. .doorbell = MHI_DB_BRST_DISABLE,
  619. .lpm_notify = false,
  620. .offload_channel = false,
  621. .doorbell_mode_switch = false,
  622. .wake_capable = false,
  623. },
  624. {
  625. .name = "QAIC_TIMESYNC_PERIODIC",
  626. .num = 22,
  627. .num_elements = 32,
  628. .local_elements = 0,
  629. .event_ring = 0,
  630. .dir = DMA_TO_DEVICE,
  631. .ee_mask = MHI_CH_EE_AMSS,
  632. .pollcfg = 0,
  633. .doorbell = MHI_DB_BRST_DISABLE,
  634. .lpm_notify = false,
  635. .offload_channel = false,
  636. .doorbell_mode_switch = false,
  637. .wake_capable = false,
  638. },
  639. {
  640. .name = "QAIC_TIMESYNC_PERIODIC",
  641. .num = 23,
  642. .num_elements = 32,
  643. .local_elements = 0,
  644. .event_ring = 0,
  645. .dir = DMA_FROM_DEVICE,
  646. .ee_mask = MHI_CH_EE_AMSS,
  647. .pollcfg = 0,
  648. .doorbell = MHI_DB_BRST_DISABLE,
  649. .lpm_notify = false,
  650. .offload_channel = false,
  651. .doorbell_mode_switch = false,
  652. .wake_capable = false,
  653. },
  654. {
  655. .name = "IPCR",
  656. .num = 24,
  657. .num_elements = 32,
  658. .local_elements = 0,
  659. .event_ring = 0,
  660. .dir = DMA_TO_DEVICE,
  661. .ee_mask = MHI_CH_EE_AMSS,
  662. .pollcfg = 0,
  663. .doorbell = MHI_DB_BRST_DISABLE,
  664. .lpm_notify = false,
  665. .offload_channel = false,
  666. .doorbell_mode_switch = false,
  667. .wake_capable = false,
  668. },
  669. {
  670. .name = "IPCR",
  671. .num = 25,
  672. .num_elements = 32,
  673. .local_elements = 0,
  674. .event_ring = 0,
  675. .dir = DMA_FROM_DEVICE,
  676. .ee_mask = MHI_CH_EE_AMSS,
  677. .pollcfg = 0,
  678. .doorbell = MHI_DB_BRST_DISABLE,
  679. .lpm_notify = false,
  680. .offload_channel = false,
  681. .doorbell_mode_switch = false,
  682. .wake_capable = false,
  683. },
  684. };
  685. static struct mhi_event_config aic100_events[] = {
  686. {
  687. .num_elements = 32,
  688. .irq_moderation_ms = 0,
  689. .irq = 0,
  690. .channel = U32_MAX,
  691. .priority = 1,
  692. .mode = MHI_DB_BRST_DISABLE,
  693. .data_type = MHI_ER_CTRL,
  694. .hardware_event = false,
  695. .client_managed = false,
  696. .offload_channel = false,
  697. },
  698. };
  699. static struct mhi_event_config aic200_events[] = {
  700. {
  701. .num_elements = 32,
  702. .irq_moderation_ms = 0,
  703. .irq = 0,
  704. .channel = U32_MAX,
  705. .priority = 1,
  706. .mode = MHI_DB_BRST_DISABLE,
  707. .data_type = MHI_ER_CTRL,
  708. .hardware_event = false,
  709. .client_managed = false,
  710. .offload_channel = false,
  711. },
  712. };
  713. static struct mhi_controller_config mhi_cntrl_configs[] = {
  714. [FAMILY_AIC100] = {
  715. .max_channels = 128,
  716. .timeout_ms = 0, /* controlled by mhi_timeout */
  717. .buf_len = 0,
  718. .num_channels = ARRAY_SIZE(aic100_channels),
  719. .ch_cfg = aic100_channels,
  720. .num_events = ARRAY_SIZE(aic100_events),
  721. .event_cfg = aic100_events,
  722. .use_bounce_buf = false,
  723. .m2_no_db = false,
  724. },
  725. [FAMILY_AIC200] = {
  726. .max_channels = 128,
  727. .timeout_ms = 0, /* controlled by mhi_timeout */
  728. .buf_len = 0,
  729. .num_channels = ARRAY_SIZE(aic200_channels),
  730. .ch_cfg = aic200_channels,
  731. .num_events = ARRAY_SIZE(aic200_events),
  732. .event_cfg = aic200_events,
  733. .use_bounce_buf = false,
  734. .m2_no_db = false,
  735. },
  736. };
  737. static int mhi_read_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 *out)
  738. {
  739. u32 tmp;
  740. /*
  741. * SOC_HW_VERSION quirk
  742. * The SOC_HW_VERSION register (offset 0x224) is not reliable and
  743. * may contain uninitialized values, including 0xFFFFFFFF. This could
  744. * cause a false positive link down error. Instead, intercept any
  745. * reads and provide the correct value of the register.
  746. */
  747. if (addr - mhi_cntrl->regs == 0x224) {
  748. *out = 0x60110200;
  749. return 0;
  750. }
  751. tmp = readl_relaxed(addr);
  752. if (tmp == U32_MAX)
  753. return -EIO;
  754. *out = tmp;
  755. return 0;
  756. }
  757. static void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *addr, u32 val)
  758. {
  759. writel_relaxed(val, addr);
  760. }
  761. static int mhi_runtime_get(struct mhi_controller *mhi_cntrl)
  762. {
  763. return 0;
  764. }
  765. static void mhi_runtime_put(struct mhi_controller *mhi_cntrl)
  766. {
  767. }
  768. static void mhi_status_cb(struct mhi_controller *mhi_cntrl, enum mhi_callback reason)
  769. {
  770. struct qaic_device *qdev = pci_get_drvdata(to_pci_dev(mhi_cntrl->cntrl_dev));
  771. /* this event occurs in atomic context */
  772. if (reason == MHI_CB_FATAL_ERROR)
  773. pci_err(qdev->pdev, "Fatal error received from device. Attempting to recover\n");
  774. /* this event occurs in non-atomic context */
  775. if (reason == MHI_CB_SYS_ERROR)
  776. qaic_dev_reset_clean_local_state(qdev);
  777. }
  778. static int mhi_reset_and_async_power_up(struct mhi_controller *mhi_cntrl)
  779. {
  780. u8 time_sec = 1;
  781. int current_ee;
  782. int ret;
  783. /* Reset the device to bring the device in PBL EE */
  784. mhi_soc_reset(mhi_cntrl);
  785. /*
  786. * Keep checking the execution environment(EE) after every 1 second
  787. * interval.
  788. */
  789. do {
  790. msleep(1000);
  791. current_ee = mhi_get_exec_env(mhi_cntrl);
  792. } while (current_ee != MHI_EE_PBL && time_sec++ <= MAX_RESET_TIME_SEC);
  793. /* If the device is in PBL EE retry power up */
  794. if (current_ee == MHI_EE_PBL)
  795. ret = mhi_async_power_up(mhi_cntrl);
  796. else
  797. ret = -EIO;
  798. return ret;
  799. }
  800. struct mhi_controller *qaic_mhi_register_controller(struct pci_dev *pci_dev, void __iomem *mhi_bar,
  801. int mhi_irq, bool shared_msi, int family)
  802. {
  803. struct mhi_controller_config mhi_config = mhi_cntrl_configs[family];
  804. struct mhi_controller *mhi_cntrl;
  805. int ret;
  806. mhi_cntrl = devm_kzalloc(&pci_dev->dev, sizeof(*mhi_cntrl), GFP_KERNEL);
  807. if (!mhi_cntrl)
  808. return ERR_PTR(-ENOMEM);
  809. mhi_cntrl->cntrl_dev = &pci_dev->dev;
  810. /*
  811. * Covers the entire possible physical ram region. Remote side is
  812. * going to calculate a size of this range, so subtract 1 to prevent
  813. * rollover.
  814. */
  815. mhi_cntrl->iova_start = 0;
  816. mhi_cntrl->iova_stop = PHYS_ADDR_MAX - 1;
  817. mhi_cntrl->status_cb = mhi_status_cb;
  818. mhi_cntrl->runtime_get = mhi_runtime_get;
  819. mhi_cntrl->runtime_put = mhi_runtime_put;
  820. mhi_cntrl->read_reg = mhi_read_reg;
  821. mhi_cntrl->write_reg = mhi_write_reg;
  822. mhi_cntrl->regs = mhi_bar;
  823. mhi_cntrl->reg_len = SZ_4K;
  824. mhi_cntrl->nr_irqs = 1;
  825. mhi_cntrl->irq = devm_kmalloc(&pci_dev->dev, sizeof(*mhi_cntrl->irq), GFP_KERNEL);
  826. if (!mhi_cntrl->irq)
  827. return ERR_PTR(-ENOMEM);
  828. mhi_cntrl->irq[0] = mhi_irq;
  829. if (shared_msi) /* MSI shared with data path, no IRQF_NO_SUSPEND */
  830. mhi_cntrl->irq_flags = IRQF_SHARED;
  831. mhi_cntrl->fw_image = fw_image_paths[family];
  832. if (family == FAMILY_AIC200) {
  833. mhi_cntrl->name = "AIC200";
  834. mhi_cntrl->seg_len = SZ_512K;
  835. } else {
  836. mhi_cntrl->name = "AIC100";
  837. }
  838. /* use latest configured timeout */
  839. mhi_config.timeout_ms = mhi_timeout_ms;
  840. ret = mhi_register_controller(mhi_cntrl, &mhi_config);
  841. if (ret) {
  842. pci_err(pci_dev, "mhi_register_controller failed %d\n", ret);
  843. return ERR_PTR(ret);
  844. }
  845. ret = mhi_prepare_for_power_up(mhi_cntrl);
  846. if (ret) {
  847. pci_err(pci_dev, "mhi_prepare_for_power_up failed %d\n", ret);
  848. goto prepare_power_up_fail;
  849. }
  850. ret = mhi_async_power_up(mhi_cntrl);
  851. /*
  852. * If EIO is returned it is possible that device is in SBL EE, which is
  853. * undesired. SOC reset the device and try to power up again.
  854. */
  855. if (ret == -EIO && MHI_EE_SBL == mhi_get_exec_env(mhi_cntrl)) {
  856. pci_err(pci_dev, "Found device in SBL at MHI init. Attempting a reset.\n");
  857. ret = mhi_reset_and_async_power_up(mhi_cntrl);
  858. }
  859. if (ret) {
  860. pci_err(pci_dev, "mhi_async_power_up failed %d\n", ret);
  861. goto power_up_fail;
  862. }
  863. return mhi_cntrl;
  864. power_up_fail:
  865. mhi_unprepare_after_power_down(mhi_cntrl);
  866. prepare_power_up_fail:
  867. mhi_unregister_controller(mhi_cntrl);
  868. return ERR_PTR(ret);
  869. }
  870. void qaic_mhi_free_controller(struct mhi_controller *mhi_cntrl, bool link_up)
  871. {
  872. mhi_power_down(mhi_cntrl, link_up);
  873. mhi_unprepare_after_power_down(mhi_cntrl);
  874. mhi_unregister_controller(mhi_cntrl);
  875. }
  876. void qaic_mhi_start_reset(struct mhi_controller *mhi_cntrl)
  877. {
  878. mhi_power_down(mhi_cntrl, true);
  879. }
  880. void qaic_mhi_reset_done(struct mhi_controller *mhi_cntrl)
  881. {
  882. struct pci_dev *pci_dev = container_of(mhi_cntrl->cntrl_dev, struct pci_dev, dev);
  883. int ret;
  884. ret = mhi_async_power_up(mhi_cntrl);
  885. if (ret)
  886. pci_err(pci_dev, "mhi_async_power_up failed after reset %d\n", ret);
  887. }