imx_rproc.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2017 Pengutronix, Oleksij Rempel <[email protected]>
  4. */
  5. #include <linux/arm-smccc.h>
  6. #include <linux/clk.h>
  7. #include <linux/err.h>
  8. #include <linux/interrupt.h>
  9. #include <linux/kernel.h>
  10. #include <linux/mailbox_client.h>
  11. #include <linux/mfd/syscon.h>
  12. #include <linux/module.h>
  13. #include <linux/of_address.h>
  14. #include <linux/of_reserved_mem.h>
  15. #include <linux/of_device.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/regmap.h>
  18. #include <linux/remoteproc.h>
  19. #include <linux/workqueue.h>
  20. #include "imx_rproc.h"
  21. #include "remoteproc_internal.h"
  22. #define IMX7D_SRC_SCR 0x0C
  23. #define IMX7D_ENABLE_M4 BIT(3)
  24. #define IMX7D_SW_M4P_RST BIT(2)
  25. #define IMX7D_SW_M4C_RST BIT(1)
  26. #define IMX7D_SW_M4C_NON_SCLR_RST BIT(0)
  27. #define IMX7D_M4_RST_MASK (IMX7D_ENABLE_M4 | IMX7D_SW_M4P_RST \
  28. | IMX7D_SW_M4C_RST \
  29. | IMX7D_SW_M4C_NON_SCLR_RST)
  30. #define IMX7D_M4_START (IMX7D_ENABLE_M4 | IMX7D_SW_M4P_RST \
  31. | IMX7D_SW_M4C_RST)
  32. #define IMX7D_M4_STOP (IMX7D_ENABLE_M4 | IMX7D_SW_M4C_RST | \
  33. IMX7D_SW_M4C_NON_SCLR_RST)
  34. /* Address: 0x020D8000 */
  35. #define IMX6SX_SRC_SCR 0x00
  36. #define IMX6SX_ENABLE_M4 BIT(22)
  37. #define IMX6SX_SW_M4P_RST BIT(12)
  38. #define IMX6SX_SW_M4C_NON_SCLR_RST BIT(4)
  39. #define IMX6SX_SW_M4C_RST BIT(3)
  40. #define IMX6SX_M4_START (IMX6SX_ENABLE_M4 | IMX6SX_SW_M4P_RST \
  41. | IMX6SX_SW_M4C_RST)
  42. #define IMX6SX_M4_STOP (IMX6SX_ENABLE_M4 | IMX6SX_SW_M4C_RST | \
  43. IMX6SX_SW_M4C_NON_SCLR_RST)
  44. #define IMX6SX_M4_RST_MASK (IMX6SX_ENABLE_M4 | IMX6SX_SW_M4P_RST \
  45. | IMX6SX_SW_M4C_NON_SCLR_RST \
  46. | IMX6SX_SW_M4C_RST)
  47. #define IMX_RPROC_MEM_MAX 32
  48. #define IMX_SIP_RPROC 0xC2000005
  49. #define IMX_SIP_RPROC_START 0x00
  50. #define IMX_SIP_RPROC_STARTED 0x01
  51. #define IMX_SIP_RPROC_STOP 0x02
  52. /**
  53. * struct imx_rproc_mem - slim internal memory structure
  54. * @cpu_addr: MPU virtual address of the memory region
  55. * @sys_addr: Bus address used to access the memory region
  56. * @size: Size of the memory region
  57. */
  58. struct imx_rproc_mem {
  59. void __iomem *cpu_addr;
  60. phys_addr_t sys_addr;
  61. size_t size;
  62. };
  63. /* att flags */
  64. /* M4 own area. Can be mapped at probe */
  65. #define ATT_OWN BIT(1)
  66. #define ATT_IOMEM BIT(2)
  67. struct imx_rproc {
  68. struct device *dev;
  69. struct regmap *regmap;
  70. struct rproc *rproc;
  71. const struct imx_rproc_dcfg *dcfg;
  72. struct imx_rproc_mem mem[IMX_RPROC_MEM_MAX];
  73. struct clk *clk;
  74. struct mbox_client cl;
  75. struct mbox_chan *tx_ch;
  76. struct mbox_chan *rx_ch;
  77. struct work_struct rproc_work;
  78. struct workqueue_struct *workqueue;
  79. void __iomem *rsc_table;
  80. };
  81. static const struct imx_rproc_att imx_rproc_att_imx93[] = {
  82. /* dev addr , sys addr , size , flags */
  83. /* TCM CODE NON-SECURE */
  84. { 0x0FFC0000, 0x201C0000, 0x00020000, ATT_OWN | ATT_IOMEM },
  85. { 0x0FFE0000, 0x201E0000, 0x00020000, ATT_OWN | ATT_IOMEM },
  86. /* TCM CODE SECURE */
  87. { 0x1FFC0000, 0x201C0000, 0x00020000, ATT_OWN | ATT_IOMEM },
  88. { 0x1FFE0000, 0x201E0000, 0x00020000, ATT_OWN | ATT_IOMEM },
  89. /* TCM SYS NON-SECURE*/
  90. { 0x20000000, 0x20200000, 0x00020000, ATT_OWN | ATT_IOMEM },
  91. { 0x20020000, 0x20220000, 0x00020000, ATT_OWN | ATT_IOMEM },
  92. /* TCM SYS SECURE*/
  93. { 0x30000000, 0x20200000, 0x00020000, ATT_OWN | ATT_IOMEM },
  94. { 0x30020000, 0x20220000, 0x00020000, ATT_OWN | ATT_IOMEM },
  95. /* DDR */
  96. { 0x80000000, 0x80000000, 0x10000000, 0 },
  97. { 0x90000000, 0x80000000, 0x10000000, 0 },
  98. { 0xC0000000, 0xC0000000, 0x10000000, 0 },
  99. { 0xD0000000, 0xC0000000, 0x10000000, 0 },
  100. };
  101. static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
  102. /* dev addr , sys addr , size , flags */
  103. /* ITCM */
  104. { 0x00000000, 0x007E0000, 0x00020000, ATT_OWN | ATT_IOMEM },
  105. /* OCRAM_S */
  106. { 0x00180000, 0x00180000, 0x00009000, 0 },
  107. /* OCRAM */
  108. { 0x00900000, 0x00900000, 0x00020000, 0 },
  109. /* OCRAM */
  110. { 0x00920000, 0x00920000, 0x00020000, 0 },
  111. /* OCRAM */
  112. { 0x00940000, 0x00940000, 0x00050000, 0 },
  113. /* QSPI Code - alias */
  114. { 0x08000000, 0x08000000, 0x08000000, 0 },
  115. /* DDR (Code) - alias */
  116. { 0x10000000, 0x40000000, 0x0FFE0000, 0 },
  117. /* DTCM */
  118. { 0x20000000, 0x00800000, 0x00020000, ATT_OWN | ATT_IOMEM },
  119. /* OCRAM_S - alias */
  120. { 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
  121. /* OCRAM */
  122. { 0x20200000, 0x00900000, 0x00020000, ATT_OWN },
  123. /* OCRAM */
  124. { 0x20220000, 0x00920000, 0x00020000, ATT_OWN },
  125. /* OCRAM */
  126. { 0x20240000, 0x00940000, 0x00040000, ATT_OWN },
  127. /* DDR (Data) */
  128. { 0x40000000, 0x40000000, 0x80000000, 0 },
  129. };
  130. static const struct imx_rproc_att imx_rproc_att_imx8mq[] = {
  131. /* dev addr , sys addr , size , flags */
  132. /* TCML - alias */
  133. { 0x00000000, 0x007e0000, 0x00020000, ATT_IOMEM},
  134. /* OCRAM_S */
  135. { 0x00180000, 0x00180000, 0x00008000, 0 },
  136. /* OCRAM */
  137. { 0x00900000, 0x00900000, 0x00020000, 0 },
  138. /* OCRAM */
  139. { 0x00920000, 0x00920000, 0x00020000, 0 },
  140. /* QSPI Code - alias */
  141. { 0x08000000, 0x08000000, 0x08000000, 0 },
  142. /* DDR (Code) - alias */
  143. { 0x10000000, 0x80000000, 0x0FFE0000, 0 },
  144. /* TCML */
  145. { 0x1FFE0000, 0x007E0000, 0x00020000, ATT_OWN | ATT_IOMEM},
  146. /* TCMU */
  147. { 0x20000000, 0x00800000, 0x00020000, ATT_OWN | ATT_IOMEM},
  148. /* OCRAM_S */
  149. { 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
  150. /* OCRAM */
  151. { 0x20200000, 0x00900000, 0x00020000, ATT_OWN },
  152. /* OCRAM */
  153. { 0x20220000, 0x00920000, 0x00020000, ATT_OWN },
  154. /* DDR (Data) */
  155. { 0x40000000, 0x40000000, 0x80000000, 0 },
  156. };
  157. static const struct imx_rproc_att imx_rproc_att_imx8ulp[] = {
  158. {0x1FFC0000, 0x1FFC0000, 0xC0000, ATT_OWN},
  159. {0x21000000, 0x21000000, 0x10000, ATT_OWN},
  160. {0x80000000, 0x80000000, 0x60000000, 0}
  161. };
  162. static const struct imx_rproc_att imx_rproc_att_imx7ulp[] = {
  163. {0x1FFD0000, 0x1FFD0000, 0x30000, ATT_OWN},
  164. {0x20000000, 0x20000000, 0x10000, ATT_OWN},
  165. {0x2F000000, 0x2F000000, 0x20000, ATT_OWN},
  166. {0x2F020000, 0x2F020000, 0x20000, ATT_OWN},
  167. {0x60000000, 0x60000000, 0x40000000, 0}
  168. };
  169. static const struct imx_rproc_att imx_rproc_att_imx7d[] = {
  170. /* dev addr , sys addr , size , flags */
  171. /* OCRAM_S (M4 Boot code) - alias */
  172. { 0x00000000, 0x00180000, 0x00008000, 0 },
  173. /* OCRAM_S (Code) */
  174. { 0x00180000, 0x00180000, 0x00008000, ATT_OWN },
  175. /* OCRAM (Code) - alias */
  176. { 0x00900000, 0x00900000, 0x00020000, 0 },
  177. /* OCRAM_EPDC (Code) - alias */
  178. { 0x00920000, 0x00920000, 0x00020000, 0 },
  179. /* OCRAM_PXP (Code) - alias */
  180. { 0x00940000, 0x00940000, 0x00008000, 0 },
  181. /* TCML (Code) */
  182. { 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN | ATT_IOMEM },
  183. /* DDR (Code) - alias, first part of DDR (Data) */
  184. { 0x10000000, 0x80000000, 0x0FFF0000, 0 },
  185. /* TCMU (Data) */
  186. { 0x20000000, 0x00800000, 0x00008000, ATT_OWN | ATT_IOMEM },
  187. /* OCRAM (Data) */
  188. { 0x20200000, 0x00900000, 0x00020000, 0 },
  189. /* OCRAM_EPDC (Data) */
  190. { 0x20220000, 0x00920000, 0x00020000, 0 },
  191. /* OCRAM_PXP (Data) */
  192. { 0x20240000, 0x00940000, 0x00008000, 0 },
  193. /* DDR (Data) */
  194. { 0x80000000, 0x80000000, 0x60000000, 0 },
  195. };
  196. static const struct imx_rproc_att imx_rproc_att_imx6sx[] = {
  197. /* dev addr , sys addr , size , flags */
  198. /* TCML (M4 Boot Code) - alias */
  199. { 0x00000000, 0x007F8000, 0x00008000, ATT_IOMEM },
  200. /* OCRAM_S (Code) */
  201. { 0x00180000, 0x008F8000, 0x00004000, 0 },
  202. /* OCRAM_S (Code) - alias */
  203. { 0x00180000, 0x008FC000, 0x00004000, 0 },
  204. /* TCML (Code) */
  205. { 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN | ATT_IOMEM },
  206. /* DDR (Code) - alias, first part of DDR (Data) */
  207. { 0x10000000, 0x80000000, 0x0FFF8000, 0 },
  208. /* TCMU (Data) */
  209. { 0x20000000, 0x00800000, 0x00008000, ATT_OWN | ATT_IOMEM },
  210. /* OCRAM_S (Data) - alias? */
  211. { 0x208F8000, 0x008F8000, 0x00004000, 0 },
  212. /* DDR (Data) */
  213. { 0x80000000, 0x80000000, 0x60000000, 0 },
  214. };
  215. static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn = {
  216. .att = imx_rproc_att_imx8mn,
  217. .att_size = ARRAY_SIZE(imx_rproc_att_imx8mn),
  218. .method = IMX_RPROC_SMC,
  219. };
  220. static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = {
  221. .src_reg = IMX7D_SRC_SCR,
  222. .src_mask = IMX7D_M4_RST_MASK,
  223. .src_start = IMX7D_M4_START,
  224. .src_stop = IMX7D_M4_STOP,
  225. .att = imx_rproc_att_imx8mq,
  226. .att_size = ARRAY_SIZE(imx_rproc_att_imx8mq),
  227. .method = IMX_RPROC_MMIO,
  228. };
  229. static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = {
  230. .att = imx_rproc_att_imx8ulp,
  231. .att_size = ARRAY_SIZE(imx_rproc_att_imx8ulp),
  232. .method = IMX_RPROC_NONE,
  233. };
  234. static const struct imx_rproc_dcfg imx_rproc_cfg_imx7ulp = {
  235. .att = imx_rproc_att_imx7ulp,
  236. .att_size = ARRAY_SIZE(imx_rproc_att_imx7ulp),
  237. .method = IMX_RPROC_NONE,
  238. };
  239. static const struct imx_rproc_dcfg imx_rproc_cfg_imx7d = {
  240. .src_reg = IMX7D_SRC_SCR,
  241. .src_mask = IMX7D_M4_RST_MASK,
  242. .src_start = IMX7D_M4_START,
  243. .src_stop = IMX7D_M4_STOP,
  244. .att = imx_rproc_att_imx7d,
  245. .att_size = ARRAY_SIZE(imx_rproc_att_imx7d),
  246. .method = IMX_RPROC_MMIO,
  247. };
  248. static const struct imx_rproc_dcfg imx_rproc_cfg_imx6sx = {
  249. .src_reg = IMX6SX_SRC_SCR,
  250. .src_mask = IMX6SX_M4_RST_MASK,
  251. .src_start = IMX6SX_M4_START,
  252. .src_stop = IMX6SX_M4_STOP,
  253. .att = imx_rproc_att_imx6sx,
  254. .att_size = ARRAY_SIZE(imx_rproc_att_imx6sx),
  255. .method = IMX_RPROC_MMIO,
  256. };
  257. static const struct imx_rproc_dcfg imx_rproc_cfg_imx93 = {
  258. .att = imx_rproc_att_imx93,
  259. .att_size = ARRAY_SIZE(imx_rproc_att_imx93),
  260. .method = IMX_RPROC_SMC,
  261. };
  262. static int imx_rproc_start(struct rproc *rproc)
  263. {
  264. struct imx_rproc *priv = rproc->priv;
  265. const struct imx_rproc_dcfg *dcfg = priv->dcfg;
  266. struct device *dev = priv->dev;
  267. struct arm_smccc_res res;
  268. int ret;
  269. switch (dcfg->method) {
  270. case IMX_RPROC_MMIO:
  271. ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
  272. dcfg->src_start);
  273. break;
  274. case IMX_RPROC_SMC:
  275. arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_START, 0, 0, 0, 0, 0, 0, &res);
  276. ret = res.a0;
  277. break;
  278. default:
  279. return -EOPNOTSUPP;
  280. }
  281. if (ret)
  282. dev_err(dev, "Failed to enable remote core!\n");
  283. return ret;
  284. }
  285. static int imx_rproc_stop(struct rproc *rproc)
  286. {
  287. struct imx_rproc *priv = rproc->priv;
  288. const struct imx_rproc_dcfg *dcfg = priv->dcfg;
  289. struct device *dev = priv->dev;
  290. struct arm_smccc_res res;
  291. int ret;
  292. switch (dcfg->method) {
  293. case IMX_RPROC_MMIO:
  294. ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
  295. dcfg->src_stop);
  296. break;
  297. case IMX_RPROC_SMC:
  298. arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STOP, 0, 0, 0, 0, 0, 0, &res);
  299. ret = res.a0;
  300. if (res.a1)
  301. dev_info(dev, "Not in wfi, force stopped\n");
  302. break;
  303. default:
  304. return -EOPNOTSUPP;
  305. }
  306. if (ret)
  307. dev_err(dev, "Failed to stop remote core\n");
  308. return ret;
  309. }
  310. static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da,
  311. size_t len, u64 *sys, bool *is_iomem)
  312. {
  313. const struct imx_rproc_dcfg *dcfg = priv->dcfg;
  314. int i;
  315. /* parse address translation table */
  316. for (i = 0; i < dcfg->att_size; i++) {
  317. const struct imx_rproc_att *att = &dcfg->att[i];
  318. if (da >= att->da && da + len < att->da + att->size) {
  319. unsigned int offset = da - att->da;
  320. *sys = att->sa + offset;
  321. if (is_iomem)
  322. *is_iomem = att->flags & ATT_IOMEM;
  323. return 0;
  324. }
  325. }
  326. dev_warn(priv->dev, "Translation failed: da = 0x%llx len = 0x%zx\n",
  327. da, len);
  328. return -ENOENT;
  329. }
  330. static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
  331. {
  332. struct imx_rproc *priv = rproc->priv;
  333. void *va = NULL;
  334. u64 sys;
  335. int i;
  336. if (len == 0)
  337. return NULL;
  338. /*
  339. * On device side we have many aliases, so we need to convert device
  340. * address (M4) to system bus address first.
  341. */
  342. if (imx_rproc_da_to_sys(priv, da, len, &sys, is_iomem))
  343. return NULL;
  344. for (i = 0; i < IMX_RPROC_MEM_MAX; i++) {
  345. if (sys >= priv->mem[i].sys_addr && sys + len <
  346. priv->mem[i].sys_addr + priv->mem[i].size) {
  347. unsigned int offset = sys - priv->mem[i].sys_addr;
  348. /* __force to make sparse happy with type conversion */
  349. va = (__force void *)(priv->mem[i].cpu_addr + offset);
  350. break;
  351. }
  352. }
  353. dev_dbg(&rproc->dev, "da = 0x%llx len = 0x%zx va = 0x%p\n",
  354. da, len, va);
  355. return va;
  356. }
  357. static int imx_rproc_mem_alloc(struct rproc *rproc,
  358. struct rproc_mem_entry *mem)
  359. {
  360. struct device *dev = rproc->dev.parent;
  361. void *va;
  362. dev_dbg(dev, "map memory: %p+%zx\n", &mem->dma, mem->len);
  363. va = ioremap_wc(mem->dma, mem->len);
  364. if (IS_ERR_OR_NULL(va)) {
  365. dev_err(dev, "Unable to map memory region: %p+%zx\n",
  366. &mem->dma, mem->len);
  367. return -ENOMEM;
  368. }
  369. /* Update memory entry va */
  370. mem->va = va;
  371. return 0;
  372. }
  373. static int imx_rproc_mem_release(struct rproc *rproc,
  374. struct rproc_mem_entry *mem)
  375. {
  376. dev_dbg(rproc->dev.parent, "unmap memory: %pa\n", &mem->dma);
  377. iounmap(mem->va);
  378. return 0;
  379. }
  380. static int imx_rproc_prepare(struct rproc *rproc)
  381. {
  382. struct imx_rproc *priv = rproc->priv;
  383. struct device_node *np = priv->dev->of_node;
  384. struct of_phandle_iterator it;
  385. struct rproc_mem_entry *mem;
  386. struct reserved_mem *rmem;
  387. u32 da;
  388. /* Register associated reserved memory regions */
  389. of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
  390. while (of_phandle_iterator_next(&it) == 0) {
  391. /*
  392. * Ignore the first memory region which will be used vdev buffer.
  393. * No need to do extra handlings, rproc_add_virtio_dev will handle it.
  394. */
  395. if (!strcmp(it.node->name, "vdev0buffer"))
  396. continue;
  397. if (!strcmp(it.node->name, "rsc-table"))
  398. continue;
  399. rmem = of_reserved_mem_lookup(it.node);
  400. if (!rmem) {
  401. of_node_put(it.node);
  402. dev_err(priv->dev, "unable to acquire memory-region\n");
  403. return -EINVAL;
  404. }
  405. /* No need to translate pa to da, i.MX use same map */
  406. da = rmem->base;
  407. /* Register memory region */
  408. mem = rproc_mem_entry_init(priv->dev, NULL, (dma_addr_t)rmem->base, rmem->size, da,
  409. imx_rproc_mem_alloc, imx_rproc_mem_release,
  410. it.node->name);
  411. if (mem) {
  412. rproc_coredump_add_segment(rproc, da, rmem->size);
  413. } else {
  414. of_node_put(it.node);
  415. return -ENOMEM;
  416. }
  417. rproc_add_carveout(rproc, mem);
  418. }
  419. return 0;
  420. }
  421. static int imx_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
  422. {
  423. int ret;
  424. ret = rproc_elf_load_rsc_table(rproc, fw);
  425. if (ret)
  426. dev_info(&rproc->dev, "No resource table in elf\n");
  427. return 0;
  428. }
  429. static void imx_rproc_kick(struct rproc *rproc, int vqid)
  430. {
  431. struct imx_rproc *priv = rproc->priv;
  432. int err;
  433. __u32 mmsg;
  434. if (!priv->tx_ch) {
  435. dev_err(priv->dev, "No initialized mbox tx channel\n");
  436. return;
  437. }
  438. /*
  439. * Send the index of the triggered virtqueue as the mu payload.
  440. * Let remote processor know which virtqueue is used.
  441. */
  442. mmsg = vqid << 16;
  443. err = mbox_send_message(priv->tx_ch, (void *)&mmsg);
  444. if (err < 0)
  445. dev_err(priv->dev, "%s: failed (%d, err:%d)\n",
  446. __func__, vqid, err);
  447. }
  448. static int imx_rproc_attach(struct rproc *rproc)
  449. {
  450. return 0;
  451. }
  452. static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
  453. {
  454. struct imx_rproc *priv = rproc->priv;
  455. /* The resource table has already been mapped in imx_rproc_addr_init */
  456. if (!priv->rsc_table)
  457. return NULL;
  458. *table_sz = SZ_1K;
  459. return (struct resource_table *)priv->rsc_table;
  460. }
  461. static const struct rproc_ops imx_rproc_ops = {
  462. .prepare = imx_rproc_prepare,
  463. .attach = imx_rproc_attach,
  464. .start = imx_rproc_start,
  465. .stop = imx_rproc_stop,
  466. .kick = imx_rproc_kick,
  467. .da_to_va = imx_rproc_da_to_va,
  468. .load = rproc_elf_load_segments,
  469. .parse_fw = imx_rproc_parse_fw,
  470. .find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
  471. .get_loaded_rsc_table = imx_rproc_get_loaded_rsc_table,
  472. .sanity_check = rproc_elf_sanity_check,
  473. .get_boot_addr = rproc_elf_get_boot_addr,
  474. };
  475. static int imx_rproc_addr_init(struct imx_rproc *priv,
  476. struct platform_device *pdev)
  477. {
  478. const struct imx_rproc_dcfg *dcfg = priv->dcfg;
  479. struct device *dev = &pdev->dev;
  480. struct device_node *np = dev->of_node;
  481. int a, b = 0, err, nph;
  482. /* remap required addresses */
  483. for (a = 0; a < dcfg->att_size; a++) {
  484. const struct imx_rproc_att *att = &dcfg->att[a];
  485. if (!(att->flags & ATT_OWN))
  486. continue;
  487. if (b >= IMX_RPROC_MEM_MAX)
  488. break;
  489. if (att->flags & ATT_IOMEM)
  490. priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev,
  491. att->sa, att->size);
  492. else
  493. priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev,
  494. att->sa, att->size);
  495. if (!priv->mem[b].cpu_addr) {
  496. dev_err(dev, "failed to remap %#x bytes from %#x\n", att->size, att->sa);
  497. return -ENOMEM;
  498. }
  499. priv->mem[b].sys_addr = att->sa;
  500. priv->mem[b].size = att->size;
  501. b++;
  502. }
  503. /* memory-region is optional property */
  504. nph = of_count_phandle_with_args(np, "memory-region", NULL);
  505. if (nph <= 0)
  506. return 0;
  507. /* remap optional addresses */
  508. for (a = 0; a < nph; a++) {
  509. struct device_node *node;
  510. struct resource res;
  511. node = of_parse_phandle(np, "memory-region", a);
  512. /* Not map vdevbuffer, vdevring region */
  513. if (!strncmp(node->name, "vdev", strlen("vdev"))) {
  514. of_node_put(node);
  515. continue;
  516. }
  517. err = of_address_to_resource(node, 0, &res);
  518. of_node_put(node);
  519. if (err) {
  520. dev_err(dev, "unable to resolve memory region\n");
  521. return err;
  522. }
  523. if (b >= IMX_RPROC_MEM_MAX)
  524. break;
  525. /* Not use resource version, because we might share region */
  526. priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev, res.start, resource_size(&res));
  527. if (!priv->mem[b].cpu_addr) {
  528. dev_err(dev, "failed to remap %pr\n", &res);
  529. return -ENOMEM;
  530. }
  531. priv->mem[b].sys_addr = res.start;
  532. priv->mem[b].size = resource_size(&res);
  533. if (!strcmp(node->name, "rsc-table"))
  534. priv->rsc_table = priv->mem[b].cpu_addr;
  535. b++;
  536. }
  537. return 0;
  538. }
  539. static void imx_rproc_vq_work(struct work_struct *work)
  540. {
  541. struct imx_rproc *priv = container_of(work, struct imx_rproc,
  542. rproc_work);
  543. rproc_vq_interrupt(priv->rproc, 0);
  544. rproc_vq_interrupt(priv->rproc, 1);
  545. }
  546. static void imx_rproc_rx_callback(struct mbox_client *cl, void *msg)
  547. {
  548. struct rproc *rproc = dev_get_drvdata(cl->dev);
  549. struct imx_rproc *priv = rproc->priv;
  550. queue_work(priv->workqueue, &priv->rproc_work);
  551. }
  552. static int imx_rproc_xtr_mbox_init(struct rproc *rproc)
  553. {
  554. struct imx_rproc *priv = rproc->priv;
  555. struct device *dev = priv->dev;
  556. struct mbox_client *cl;
  557. if (!of_get_property(dev->of_node, "mbox-names", NULL))
  558. return 0;
  559. cl = &priv->cl;
  560. cl->dev = dev;
  561. cl->tx_block = true;
  562. cl->tx_tout = 100;
  563. cl->knows_txdone = false;
  564. cl->rx_callback = imx_rproc_rx_callback;
  565. priv->tx_ch = mbox_request_channel_byname(cl, "tx");
  566. if (IS_ERR(priv->tx_ch))
  567. return dev_err_probe(cl->dev, PTR_ERR(priv->tx_ch),
  568. "failed to request tx mailbox channel\n");
  569. priv->rx_ch = mbox_request_channel_byname(cl, "rx");
  570. if (IS_ERR(priv->rx_ch)) {
  571. mbox_free_channel(priv->tx_ch);
  572. return dev_err_probe(cl->dev, PTR_ERR(priv->rx_ch),
  573. "failed to request rx mailbox channel\n");
  574. }
  575. return 0;
  576. }
  577. static void imx_rproc_free_mbox(struct rproc *rproc)
  578. {
  579. struct imx_rproc *priv = rproc->priv;
  580. mbox_free_channel(priv->tx_ch);
  581. mbox_free_channel(priv->rx_ch);
  582. }
  583. static int imx_rproc_detect_mode(struct imx_rproc *priv)
  584. {
  585. struct regmap_config config = { .name = "imx-rproc" };
  586. const struct imx_rproc_dcfg *dcfg = priv->dcfg;
  587. struct device *dev = priv->dev;
  588. struct regmap *regmap;
  589. struct arm_smccc_res res;
  590. int ret;
  591. u32 val;
  592. switch (dcfg->method) {
  593. case IMX_RPROC_NONE:
  594. priv->rproc->state = RPROC_DETACHED;
  595. return 0;
  596. case IMX_RPROC_SMC:
  597. arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STARTED, 0, 0, 0, 0, 0, 0, &res);
  598. if (res.a0)
  599. priv->rproc->state = RPROC_DETACHED;
  600. return 0;
  601. default:
  602. break;
  603. }
  604. regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
  605. if (IS_ERR(regmap)) {
  606. dev_err(dev, "failed to find syscon\n");
  607. return PTR_ERR(regmap);
  608. }
  609. priv->regmap = regmap;
  610. regmap_attach_dev(dev, regmap, &config);
  611. ret = regmap_read(regmap, dcfg->src_reg, &val);
  612. if (ret) {
  613. dev_err(dev, "Failed to read src\n");
  614. return ret;
  615. }
  616. if ((val & dcfg->src_mask) != dcfg->src_stop)
  617. priv->rproc->state = RPROC_DETACHED;
  618. return 0;
  619. }
  620. static int imx_rproc_clk_enable(struct imx_rproc *priv)
  621. {
  622. const struct imx_rproc_dcfg *dcfg = priv->dcfg;
  623. struct device *dev = priv->dev;
  624. int ret;
  625. /* Remote core is not under control of Linux */
  626. if (dcfg->method == IMX_RPROC_NONE)
  627. return 0;
  628. priv->clk = devm_clk_get(dev, NULL);
  629. if (IS_ERR(priv->clk)) {
  630. dev_err(dev, "Failed to get clock\n");
  631. return PTR_ERR(priv->clk);
  632. }
  633. /*
  634. * clk for M4 block including memory. Should be
  635. * enabled before .start for FW transfer.
  636. */
  637. ret = clk_prepare_enable(priv->clk);
  638. if (ret) {
  639. dev_err(dev, "Failed to enable clock\n");
  640. return ret;
  641. }
  642. return 0;
  643. }
  644. static int imx_rproc_probe(struct platform_device *pdev)
  645. {
  646. struct device *dev = &pdev->dev;
  647. struct device_node *np = dev->of_node;
  648. struct imx_rproc *priv;
  649. struct rproc *rproc;
  650. const struct imx_rproc_dcfg *dcfg;
  651. int ret;
  652. /* set some other name then imx */
  653. rproc = rproc_alloc(dev, "imx-rproc", &imx_rproc_ops,
  654. NULL, sizeof(*priv));
  655. if (!rproc)
  656. return -ENOMEM;
  657. dcfg = of_device_get_match_data(dev);
  658. if (!dcfg) {
  659. ret = -EINVAL;
  660. goto err_put_rproc;
  661. }
  662. priv = rproc->priv;
  663. priv->rproc = rproc;
  664. priv->dcfg = dcfg;
  665. priv->dev = dev;
  666. dev_set_drvdata(dev, rproc);
  667. priv->workqueue = create_workqueue(dev_name(dev));
  668. if (!priv->workqueue) {
  669. dev_err(dev, "cannot create workqueue\n");
  670. ret = -ENOMEM;
  671. goto err_put_rproc;
  672. }
  673. ret = imx_rproc_xtr_mbox_init(rproc);
  674. if (ret)
  675. goto err_put_wkq;
  676. ret = imx_rproc_addr_init(priv, pdev);
  677. if (ret) {
  678. dev_err(dev, "failed on imx_rproc_addr_init\n");
  679. goto err_put_mbox;
  680. }
  681. ret = imx_rproc_detect_mode(priv);
  682. if (ret)
  683. goto err_put_mbox;
  684. ret = imx_rproc_clk_enable(priv);
  685. if (ret)
  686. goto err_put_mbox;
  687. INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
  688. if (rproc->state != RPROC_DETACHED)
  689. rproc->auto_boot = of_property_read_bool(np, "fsl,auto-boot");
  690. ret = rproc_add(rproc);
  691. if (ret) {
  692. dev_err(dev, "rproc_add failed\n");
  693. goto err_put_clk;
  694. }
  695. return 0;
  696. err_put_clk:
  697. clk_disable_unprepare(priv->clk);
  698. err_put_mbox:
  699. imx_rproc_free_mbox(rproc);
  700. err_put_wkq:
  701. destroy_workqueue(priv->workqueue);
  702. err_put_rproc:
  703. rproc_free(rproc);
  704. return ret;
  705. }
  706. static int imx_rproc_remove(struct platform_device *pdev)
  707. {
  708. struct rproc *rproc = platform_get_drvdata(pdev);
  709. struct imx_rproc *priv = rproc->priv;
  710. clk_disable_unprepare(priv->clk);
  711. rproc_del(rproc);
  712. imx_rproc_free_mbox(rproc);
  713. destroy_workqueue(priv->workqueue);
  714. rproc_free(rproc);
  715. return 0;
  716. }
  717. static const struct of_device_id imx_rproc_of_match[] = {
  718. { .compatible = "fsl,imx7ulp-cm4", .data = &imx_rproc_cfg_imx7ulp },
  719. { .compatible = "fsl,imx7d-cm4", .data = &imx_rproc_cfg_imx7d },
  720. { .compatible = "fsl,imx6sx-cm4", .data = &imx_rproc_cfg_imx6sx },
  721. { .compatible = "fsl,imx8mq-cm4", .data = &imx_rproc_cfg_imx8mq },
  722. { .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq },
  723. { .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
  724. { .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
  725. { .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
  726. { .compatible = "fsl,imx93-cm33", .data = &imx_rproc_cfg_imx93 },
  727. {},
  728. };
  729. MODULE_DEVICE_TABLE(of, imx_rproc_of_match);
  730. static struct platform_driver imx_rproc_driver = {
  731. .probe = imx_rproc_probe,
  732. .remove = imx_rproc_remove,
  733. .driver = {
  734. .name = "imx-rproc",
  735. .of_match_table = imx_rproc_of_match,
  736. },
  737. };
  738. module_platform_driver(imx_rproc_driver);
  739. MODULE_LICENSE("GPL v2");
  740. MODULE_DESCRIPTION("i.MX remote processor control driver");
  741. MODULE_AUTHOR("Oleksij Rempel <[email protected]>");