imx_rproc.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2017 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
  4. */
  5. #include <dt-bindings/firmware/imx/rsrc.h>
  6. #include <linux/arm-smccc.h>
  7. #include <linux/clk.h>
  8. #include <linux/err.h>
  9. #include <linux/firmware/imx/sci.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/kernel.h>
  12. #include <linux/mailbox_client.h>
  13. #include <linux/mfd/syscon.h>
  14. #include <linux/module.h>
  15. #include <linux/of.h>
  16. #include <linux/of_address.h>
  17. #include <linux/of_reserved_mem.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/pm_domain.h>
  20. #include <linux/reboot.h>
  21. #include <linux/regmap.h>
  22. #include <linux/remoteproc.h>
  23. #include <linux/workqueue.h>
  24. #include "imx_rproc.h"
  25. #include "remoteproc_internal.h"
  26. #define IMX7D_SRC_SCR 0x0C
  27. #define IMX7D_ENABLE_M4 BIT(3)
  28. #define IMX7D_SW_M4P_RST BIT(2)
  29. #define IMX7D_SW_M4C_RST BIT(1)
  30. #define IMX7D_SW_M4C_NON_SCLR_RST BIT(0)
  31. #define IMX7D_M4_RST_MASK (IMX7D_ENABLE_M4 | IMX7D_SW_M4P_RST \
  32. | IMX7D_SW_M4C_RST \
  33. | IMX7D_SW_M4C_NON_SCLR_RST)
  34. #define IMX7D_M4_START (IMX7D_ENABLE_M4 | IMX7D_SW_M4P_RST \
  35. | IMX7D_SW_M4C_RST)
  36. #define IMX7D_M4_STOP (IMX7D_ENABLE_M4 | IMX7D_SW_M4C_RST | \
  37. IMX7D_SW_M4C_NON_SCLR_RST)
  38. #define IMX8M_M7_STOP (IMX7D_ENABLE_M4 | IMX7D_SW_M4C_RST)
  39. #define IMX8M_M7_POLL IMX7D_ENABLE_M4
  40. #define IMX8M_GPR22 0x58
  41. #define IMX8M_GPR22_CM7_CPUWAIT BIT(0)
  42. /* Address: 0x020D8000 */
  43. #define IMX6SX_SRC_SCR 0x00
  44. #define IMX6SX_ENABLE_M4 BIT(22)
  45. #define IMX6SX_SW_M4P_RST BIT(12)
  46. #define IMX6SX_SW_M4C_NON_SCLR_RST BIT(4)
  47. #define IMX6SX_SW_M4C_RST BIT(3)
  48. #define IMX6SX_M4_START (IMX6SX_ENABLE_M4 | IMX6SX_SW_M4P_RST \
  49. | IMX6SX_SW_M4C_RST)
  50. #define IMX6SX_M4_STOP (IMX6SX_ENABLE_M4 | IMX6SX_SW_M4C_RST | \
  51. IMX6SX_SW_M4C_NON_SCLR_RST)
  52. #define IMX6SX_M4_RST_MASK (IMX6SX_ENABLE_M4 | IMX6SX_SW_M4P_RST \
  53. | IMX6SX_SW_M4C_NON_SCLR_RST \
  54. | IMX6SX_SW_M4C_RST)
  55. #define IMX_RPROC_MEM_MAX 32
  56. #define IMX_SIP_RPROC 0xC2000005
  57. #define IMX_SIP_RPROC_START 0x00
  58. #define IMX_SIP_RPROC_STARTED 0x01
  59. #define IMX_SIP_RPROC_STOP 0x02
  60. #define IMX_SC_IRQ_GROUP_REBOOTED 5
  61. /**
  62. * struct imx_rproc_mem - slim internal memory structure
  63. * @cpu_addr: MPU virtual address of the memory region
  64. * @sys_addr: Bus address used to access the memory region
  65. * @size: Size of the memory region
  66. */
  67. struct imx_rproc_mem {
  68. void __iomem *cpu_addr;
  69. phys_addr_t sys_addr;
  70. size_t size;
  71. };
  72. /* att flags: lower 16 bits specifying core, higher 16 bits for flags */
  73. /* M4 own area. Can be mapped at probe */
  74. #define ATT_OWN BIT(31)
  75. #define ATT_IOMEM BIT(30)
  76. #define ATT_CORE_MASK 0xffff
  77. #define ATT_CORE(I) BIT((I))
  78. static int imx_rproc_xtr_mbox_init(struct rproc *rproc, bool tx_block);
  79. static void imx_rproc_free_mbox(struct rproc *rproc);
  80. struct imx_rproc {
  81. struct device *dev;
  82. struct regmap *regmap;
  83. struct regmap *gpr;
  84. struct rproc *rproc;
  85. const struct imx_rproc_dcfg *dcfg;
  86. struct imx_rproc_mem mem[IMX_RPROC_MEM_MAX];
  87. struct clk *clk;
  88. struct mbox_client cl;
  89. struct mbox_chan *tx_ch;
  90. struct mbox_chan *rx_ch;
  91. struct work_struct rproc_work;
  92. struct workqueue_struct *workqueue;
  93. void __iomem *rsc_table;
  94. struct imx_sc_ipc *ipc_handle;
  95. struct notifier_block rproc_nb;
  96. u32 rproc_pt; /* partition id */
  97. u32 rsrc_id; /* resource id */
  98. u32 entry; /* cpu start address */
  99. u32 core_index;
  100. struct dev_pm_domain_list *pd_list;
  101. };
  102. static const struct imx_rproc_att imx_rproc_att_imx93[] = {
  103. /* dev addr , sys addr , size , flags */
  104. /* TCM CODE NON-SECURE */
  105. { 0x0FFC0000, 0x201C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
  106. /* TCM CODE SECURE */
  107. { 0x1FFC0000, 0x201C0000, 0x00040000, ATT_OWN | ATT_IOMEM },
  108. /* TCM SYS NON-SECURE*/
  109. { 0x20000000, 0x20200000, 0x00040000, ATT_OWN | ATT_IOMEM },
  110. /* TCM SYS SECURE*/
  111. { 0x30000000, 0x20200000, 0x00040000, ATT_OWN | ATT_IOMEM },
  112. /* DDR */
  113. { 0x80000000, 0x80000000, 0x10000000, 0 },
  114. { 0x90000000, 0x80000000, 0x10000000, 0 },
  115. { 0xC0000000, 0xC0000000, 0x10000000, 0 },
  116. { 0xD0000000, 0xC0000000, 0x10000000, 0 },
  117. };
  118. static const struct imx_rproc_att imx_rproc_att_imx8qm[] = {
  119. /* dev addr , sys addr , size , flags */
  120. { 0x08000000, 0x08000000, 0x10000000, 0},
  121. /* TCML */
  122. { 0x1FFE0000, 0x34FE0000, 0x00020000, ATT_OWN | ATT_IOMEM | ATT_CORE(0)},
  123. { 0x1FFE0000, 0x38FE0000, 0x00020000, ATT_OWN | ATT_IOMEM | ATT_CORE(1)},
  124. /* TCMU */
  125. { 0x20000000, 0x35000000, 0x00020000, ATT_OWN | ATT_IOMEM | ATT_CORE(0)},
  126. { 0x20000000, 0x39000000, 0x00020000, ATT_OWN | ATT_IOMEM | ATT_CORE(1)},
  127. /* DDR (Data) */
  128. { 0x80000000, 0x80000000, 0x60000000, 0 },
  129. };
  130. static const struct imx_rproc_att imx_rproc_att_imx8qxp[] = {
  131. { 0x08000000, 0x08000000, 0x10000000, 0 },
  132. /* TCML/U */
  133. { 0x1FFE0000, 0x34FE0000, 0x00040000, ATT_OWN | ATT_IOMEM },
  134. /* OCRAM(Low 96KB) */
  135. { 0x21000000, 0x00100000, 0x00018000, 0 },
  136. /* OCRAM */
  137. { 0x21100000, 0x00100000, 0x00040000, 0 },
  138. /* DDR (Data) */
  139. { 0x80000000, 0x80000000, 0x60000000, 0 },
  140. };
  141. static const struct imx_rproc_att imx_rproc_att_imx8mn[] = {
  142. /* dev addr , sys addr , size , flags */
  143. /* ITCM */
  144. { 0x00000000, 0x007E0000, 0x00020000, ATT_OWN | ATT_IOMEM },
  145. /* OCRAM_S */
  146. { 0x00180000, 0x00180000, 0x00009000, 0 },
  147. /* OCRAM */
  148. { 0x00900000, 0x00900000, 0x00020000, 0 },
  149. /* OCRAM */
  150. { 0x00920000, 0x00920000, 0x00020000, 0 },
  151. /* OCRAM */
  152. { 0x00940000, 0x00940000, 0x00050000, 0 },
  153. /* QSPI Code - alias */
  154. { 0x08000000, 0x08000000, 0x08000000, 0 },
  155. /* DDR (Code) - alias */
  156. { 0x10000000, 0x40000000, 0x0FFE0000, 0 },
  157. /* DTCM */
  158. { 0x20000000, 0x00800000, 0x00020000, ATT_OWN | ATT_IOMEM },
  159. /* OCRAM_S - alias */
  160. { 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
  161. /* OCRAM */
  162. { 0x20200000, 0x00900000, 0x00020000, ATT_OWN },
  163. /* OCRAM */
  164. { 0x20220000, 0x00920000, 0x00020000, ATT_OWN },
  165. /* OCRAM */
  166. { 0x20240000, 0x00940000, 0x00040000, ATT_OWN },
  167. /* DDR (Data) */
  168. { 0x40000000, 0x40000000, 0x80000000, 0 },
  169. };
  170. static const struct imx_rproc_att imx_rproc_att_imx8mq[] = {
  171. /* dev addr , sys addr , size , flags */
  172. /* TCML - alias */
  173. { 0x00000000, 0x007e0000, 0x00020000, ATT_IOMEM},
  174. /* OCRAM_S */
  175. { 0x00180000, 0x00180000, 0x00008000, 0 },
  176. /* OCRAM */
  177. { 0x00900000, 0x00900000, 0x00020000, 0 },
  178. /* OCRAM */
  179. { 0x00920000, 0x00920000, 0x00020000, 0 },
  180. /* QSPI Code - alias */
  181. { 0x08000000, 0x08000000, 0x08000000, 0 },
  182. /* DDR (Code) - alias */
  183. { 0x10000000, 0x40000000, 0x0FFE0000, 0 },
  184. /* TCML/U */
  185. { 0x1FFE0000, 0x007E0000, 0x00040000, ATT_OWN | ATT_IOMEM},
  186. /* OCRAM_S */
  187. { 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
  188. /* OCRAM */
  189. { 0x20200000, 0x00900000, 0x00020000, ATT_OWN },
  190. /* OCRAM */
  191. { 0x20220000, 0x00920000, 0x00020000, ATT_OWN },
  192. /* DDR (Data) */
  193. { 0x40000000, 0x40000000, 0x80000000, 0 },
  194. };
  195. static const struct imx_rproc_att imx_rproc_att_imx8ulp[] = {
  196. {0x1FFC0000, 0x1FFC0000, 0xC0000, ATT_OWN},
  197. {0x21000000, 0x21000000, 0x10000, ATT_OWN},
  198. {0x80000000, 0x80000000, 0x60000000, 0}
  199. };
  200. static const struct imx_rproc_att imx_rproc_att_imx7ulp[] = {
  201. {0x1FFD0000, 0x1FFD0000, 0x30000, ATT_OWN},
  202. {0x20000000, 0x20000000, 0x10000, ATT_OWN},
  203. {0x2F000000, 0x2F000000, 0x20000, ATT_OWN},
  204. {0x2F020000, 0x2F020000, 0x20000, ATT_OWN},
  205. {0x60000000, 0x60000000, 0x40000000, 0}
  206. };
  207. static const struct imx_rproc_att imx_rproc_att_imx7d[] = {
  208. /* dev addr , sys addr , size , flags */
  209. /* OCRAM_S (M4 Boot code) - alias */
  210. { 0x00000000, 0x00180000, 0x00008000, 0 },
  211. /* OCRAM_S (Code) */
  212. { 0x00180000, 0x00180000, 0x00008000, ATT_OWN },
  213. /* OCRAM (Code) - alias */
  214. { 0x00900000, 0x00900000, 0x00020000, 0 },
  215. /* OCRAM_EPDC (Code) - alias */
  216. { 0x00920000, 0x00920000, 0x00020000, 0 },
  217. /* OCRAM_PXP (Code) - alias */
  218. { 0x00940000, 0x00940000, 0x00008000, 0 },
  219. /* TCML (Code) */
  220. { 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN | ATT_IOMEM },
  221. /* DDR (Code) - alias, first part of DDR (Data) */
  222. { 0x10000000, 0x80000000, 0x0FFF0000, 0 },
  223. /* TCMU (Data) */
  224. { 0x20000000, 0x00800000, 0x00008000, ATT_OWN | ATT_IOMEM },
  225. /* OCRAM (Data) */
  226. { 0x20200000, 0x00900000, 0x00020000, 0 },
  227. /* OCRAM_EPDC (Data) */
  228. { 0x20220000, 0x00920000, 0x00020000, 0 },
  229. /* OCRAM_PXP (Data) */
  230. { 0x20240000, 0x00940000, 0x00008000, 0 },
  231. /* DDR (Data) */
  232. { 0x80000000, 0x80000000, 0x60000000, 0 },
  233. };
  234. static const struct imx_rproc_att imx_rproc_att_imx6sx[] = {
  235. /* dev addr , sys addr , size , flags */
  236. /* TCML (M4 Boot Code) - alias */
  237. { 0x00000000, 0x007F8000, 0x00008000, ATT_IOMEM },
  238. /* OCRAM_S (Code) */
  239. { 0x00180000, 0x008F8000, 0x00004000, 0 },
  240. /* OCRAM_S (Code) - alias */
  241. { 0x00180000, 0x008FC000, 0x00004000, 0 },
  242. /* TCML (Code) */
  243. { 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN | ATT_IOMEM },
  244. /* DDR (Code) - alias, first part of DDR (Data) */
  245. { 0x10000000, 0x80000000, 0x0FFF8000, 0 },
  246. /* TCMU (Data) */
  247. { 0x20000000, 0x00800000, 0x00008000, ATT_OWN | ATT_IOMEM },
  248. /* OCRAM_S (Data) - alias? */
  249. { 0x208F8000, 0x008F8000, 0x00004000, 0 },
  250. /* DDR (Data) */
  251. { 0x80000000, 0x80000000, 0x60000000, 0 },
  252. };
  253. static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn_mmio = {
  254. .src_reg = IMX7D_SRC_SCR,
  255. .src_mask = IMX7D_M4_RST_MASK,
  256. .src_start = IMX7D_M4_START,
  257. .src_stop = IMX8M_M7_STOP,
  258. .gpr_reg = IMX8M_GPR22,
  259. .gpr_wait = IMX8M_GPR22_CM7_CPUWAIT,
  260. .att = imx_rproc_att_imx8mn,
  261. .att_size = ARRAY_SIZE(imx_rproc_att_imx8mn),
  262. .method = IMX_RPROC_MMIO,
  263. };
  264. static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mn = {
  265. .att = imx_rproc_att_imx8mn,
  266. .att_size = ARRAY_SIZE(imx_rproc_att_imx8mn),
  267. .method = IMX_RPROC_SMC,
  268. };
  269. static const struct imx_rproc_dcfg imx_rproc_cfg_imx8mq = {
  270. .src_reg = IMX7D_SRC_SCR,
  271. .src_mask = IMX7D_M4_RST_MASK,
  272. .src_start = IMX7D_M4_START,
  273. .src_stop = IMX7D_M4_STOP,
  274. .att = imx_rproc_att_imx8mq,
  275. .att_size = ARRAY_SIZE(imx_rproc_att_imx8mq),
  276. .method = IMX_RPROC_MMIO,
  277. };
  278. static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qm = {
  279. .att = imx_rproc_att_imx8qm,
  280. .att_size = ARRAY_SIZE(imx_rproc_att_imx8qm),
  281. .method = IMX_RPROC_SCU_API,
  282. };
  283. static const struct imx_rproc_dcfg imx_rproc_cfg_imx8qxp = {
  284. .att = imx_rproc_att_imx8qxp,
  285. .att_size = ARRAY_SIZE(imx_rproc_att_imx8qxp),
  286. .method = IMX_RPROC_SCU_API,
  287. };
  288. static const struct imx_rproc_dcfg imx_rproc_cfg_imx8ulp = {
  289. .att = imx_rproc_att_imx8ulp,
  290. .att_size = ARRAY_SIZE(imx_rproc_att_imx8ulp),
  291. .method = IMX_RPROC_NONE,
  292. };
  293. static const struct imx_rproc_dcfg imx_rproc_cfg_imx7ulp = {
  294. .att = imx_rproc_att_imx7ulp,
  295. .att_size = ARRAY_SIZE(imx_rproc_att_imx7ulp),
  296. .method = IMX_RPROC_NONE,
  297. .flags = IMX_RPROC_NEED_SYSTEM_OFF,
  298. };
  299. static const struct imx_rproc_dcfg imx_rproc_cfg_imx7d = {
  300. .src_reg = IMX7D_SRC_SCR,
  301. .src_mask = IMX7D_M4_RST_MASK,
  302. .src_start = IMX7D_M4_START,
  303. .src_stop = IMX7D_M4_STOP,
  304. .att = imx_rproc_att_imx7d,
  305. .att_size = ARRAY_SIZE(imx_rproc_att_imx7d),
  306. .method = IMX_RPROC_MMIO,
  307. };
  308. static const struct imx_rproc_dcfg imx_rproc_cfg_imx6sx = {
  309. .src_reg = IMX6SX_SRC_SCR,
  310. .src_mask = IMX6SX_M4_RST_MASK,
  311. .src_start = IMX6SX_M4_START,
  312. .src_stop = IMX6SX_M4_STOP,
  313. .att = imx_rproc_att_imx6sx,
  314. .att_size = ARRAY_SIZE(imx_rproc_att_imx6sx),
  315. .method = IMX_RPROC_MMIO,
  316. };
  317. static const struct imx_rproc_dcfg imx_rproc_cfg_imx93 = {
  318. .att = imx_rproc_att_imx93,
  319. .att_size = ARRAY_SIZE(imx_rproc_att_imx93),
  320. .method = IMX_RPROC_SMC,
  321. };
  322. static int imx_rproc_start(struct rproc *rproc)
  323. {
  324. struct imx_rproc *priv = rproc->priv;
  325. const struct imx_rproc_dcfg *dcfg = priv->dcfg;
  326. struct device *dev = priv->dev;
  327. struct arm_smccc_res res;
  328. int ret;
  329. ret = imx_rproc_xtr_mbox_init(rproc, true);
  330. if (ret)
  331. return ret;
  332. switch (dcfg->method) {
  333. case IMX_RPROC_MMIO:
  334. if (priv->gpr) {
  335. ret = regmap_clear_bits(priv->gpr, dcfg->gpr_reg,
  336. dcfg->gpr_wait);
  337. } else {
  338. ret = regmap_update_bits(priv->regmap, dcfg->src_reg,
  339. dcfg->src_mask,
  340. dcfg->src_start);
  341. }
  342. break;
  343. case IMX_RPROC_SMC:
  344. arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_START, 0, 0, 0, 0, 0, 0, &res);
  345. ret = res.a0;
  346. break;
  347. case IMX_RPROC_SCU_API:
  348. ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, true, priv->entry);
  349. break;
  350. default:
  351. return -EOPNOTSUPP;
  352. }
  353. if (ret)
  354. dev_err(dev, "Failed to enable remote core!\n");
  355. return ret;
  356. }
  357. static int imx_rproc_stop(struct rproc *rproc)
  358. {
  359. struct imx_rproc *priv = rproc->priv;
  360. const struct imx_rproc_dcfg *dcfg = priv->dcfg;
  361. struct device *dev = priv->dev;
  362. struct arm_smccc_res res;
  363. int ret;
  364. switch (dcfg->method) {
  365. case IMX_RPROC_MMIO:
  366. if (priv->gpr) {
  367. ret = regmap_set_bits(priv->gpr, dcfg->gpr_reg,
  368. dcfg->gpr_wait);
  369. if (ret) {
  370. dev_err(priv->dev,
  371. "Failed to quiescence M4 platform!\n");
  372. return ret;
  373. }
  374. }
  375. ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask,
  376. dcfg->src_stop);
  377. break;
  378. case IMX_RPROC_SMC:
  379. arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STOP, 0, 0, 0, 0, 0, 0, &res);
  380. ret = res.a0;
  381. if (res.a1)
  382. dev_info(dev, "Not in wfi, force stopped\n");
  383. break;
  384. case IMX_RPROC_SCU_API:
  385. ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, false, priv->entry);
  386. break;
  387. default:
  388. return -EOPNOTSUPP;
  389. }
  390. if (ret)
  391. dev_err(dev, "Failed to stop remote core\n");
  392. else
  393. imx_rproc_free_mbox(rproc);
  394. return ret;
  395. }
  396. static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da,
  397. size_t len, u64 *sys, bool *is_iomem)
  398. {
  399. const struct imx_rproc_dcfg *dcfg = priv->dcfg;
  400. int i;
  401. /* parse address translation table */
  402. for (i = 0; i < dcfg->att_size; i++) {
  403. const struct imx_rproc_att *att = &dcfg->att[i];
  404. /*
  405. * Ignore entries not belong to current core:
  406. * i.MX8QM has dual general M4_[0,1] cores, M4_0's own entries
  407. * has "ATT_CORE(0) & BIT(0)" true, M4_1's own entries has
  408. * "ATT_CORE(1) & BIT(1)" true.
  409. */
  410. if (att->flags & ATT_CORE_MASK) {
  411. if (!((BIT(priv->core_index)) & (att->flags & ATT_CORE_MASK)))
  412. continue;
  413. }
  414. if (da >= att->da && da + len < att->da + att->size) {
  415. unsigned int offset = da - att->da;
  416. *sys = att->sa + offset;
  417. if (is_iomem)
  418. *is_iomem = att->flags & ATT_IOMEM;
  419. return 0;
  420. }
  421. }
  422. dev_warn(priv->dev, "Translation failed: da = 0x%llx len = 0x%zx\n",
  423. da, len);
  424. return -ENOENT;
  425. }
  426. static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
  427. {
  428. struct imx_rproc *priv = rproc->priv;
  429. void *va = NULL;
  430. u64 sys;
  431. int i;
  432. if (len == 0)
  433. return NULL;
  434. /*
  435. * On device side we have many aliases, so we need to convert device
  436. * address (M4) to system bus address first.
  437. */
  438. if (imx_rproc_da_to_sys(priv, da, len, &sys, is_iomem))
  439. return NULL;
  440. for (i = 0; i < IMX_RPROC_MEM_MAX; i++) {
  441. if (sys >= priv->mem[i].sys_addr && sys + len <
  442. priv->mem[i].sys_addr + priv->mem[i].size) {
  443. unsigned int offset = sys - priv->mem[i].sys_addr;
  444. /* __force to make sparse happy with type conversion */
  445. va = (__force void *)(priv->mem[i].cpu_addr + offset);
  446. break;
  447. }
  448. }
  449. dev_dbg(&rproc->dev, "da = 0x%llx len = 0x%zx va = 0x%p\n",
  450. da, len, va);
  451. return va;
  452. }
  453. static int imx_rproc_mem_alloc(struct rproc *rproc,
  454. struct rproc_mem_entry *mem)
  455. {
  456. struct device *dev = rproc->dev.parent;
  457. void *va;
  458. dev_dbg(dev, "map memory: %p+%zx\n", &mem->dma, mem->len);
  459. va = ioremap_wc(mem->dma, mem->len);
  460. if (IS_ERR_OR_NULL(va)) {
  461. dev_err(dev, "Unable to map memory region: %p+%zx\n",
  462. &mem->dma, mem->len);
  463. return -ENOMEM;
  464. }
  465. /* Update memory entry va */
  466. mem->va = va;
  467. return 0;
  468. }
  469. static int imx_rproc_mem_release(struct rproc *rproc,
  470. struct rproc_mem_entry *mem)
  471. {
  472. dev_dbg(rproc->dev.parent, "unmap memory: %pa\n", &mem->dma);
  473. iounmap(mem->va);
  474. return 0;
  475. }
  476. static int imx_rproc_prepare(struct rproc *rproc)
  477. {
  478. struct imx_rproc *priv = rproc->priv;
  479. struct device_node *np = priv->dev->of_node;
  480. struct of_phandle_iterator it;
  481. struct rproc_mem_entry *mem;
  482. struct reserved_mem *rmem;
  483. u32 da;
  484. /* Register associated reserved memory regions */
  485. of_phandle_iterator_init(&it, np, "memory-region", NULL, 0);
  486. while (of_phandle_iterator_next(&it) == 0) {
  487. /*
  488. * Ignore the first memory region which will be used vdev buffer.
  489. * No need to do extra handlings, rproc_add_virtio_dev will handle it.
  490. */
  491. if (!strcmp(it.node->name, "vdev0buffer"))
  492. continue;
  493. if (!strcmp(it.node->name, "rsc-table"))
  494. continue;
  495. rmem = of_reserved_mem_lookup(it.node);
  496. if (!rmem) {
  497. of_node_put(it.node);
  498. dev_err(priv->dev, "unable to acquire memory-region\n");
  499. return -EINVAL;
  500. }
  501. /* No need to translate pa to da, i.MX use same map */
  502. da = rmem->base;
  503. /* Register memory region */
  504. mem = rproc_mem_entry_init(priv->dev, NULL, (dma_addr_t)rmem->base, rmem->size, da,
  505. imx_rproc_mem_alloc, imx_rproc_mem_release,
  506. it.node->name);
  507. if (mem) {
  508. rproc_coredump_add_segment(rproc, da, rmem->size);
  509. } else {
  510. of_node_put(it.node);
  511. return -ENOMEM;
  512. }
  513. rproc_add_carveout(rproc, mem);
  514. }
  515. return 0;
  516. }
  517. static int imx_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
  518. {
  519. int ret;
  520. ret = rproc_elf_load_rsc_table(rproc, fw);
  521. if (ret)
  522. dev_info(&rproc->dev, "No resource table in elf\n");
  523. return 0;
  524. }
  525. static void imx_rproc_kick(struct rproc *rproc, int vqid)
  526. {
  527. struct imx_rproc *priv = rproc->priv;
  528. int err;
  529. __u32 mmsg;
  530. if (!priv->tx_ch) {
  531. dev_err(priv->dev, "No initialized mbox tx channel\n");
  532. return;
  533. }
  534. /*
  535. * Send the index of the triggered virtqueue as the mu payload.
  536. * Let remote processor know which virtqueue is used.
  537. */
  538. mmsg = vqid << 16;
  539. err = mbox_send_message(priv->tx_ch, (void *)&mmsg);
  540. if (err < 0)
  541. dev_err(priv->dev, "%s: failed (%d, err:%d)\n",
  542. __func__, vqid, err);
  543. }
  544. static int imx_rproc_attach(struct rproc *rproc)
  545. {
  546. return imx_rproc_xtr_mbox_init(rproc, true);
  547. }
  548. static int imx_rproc_detach(struct rproc *rproc)
  549. {
  550. struct imx_rproc *priv = rproc->priv;
  551. const struct imx_rproc_dcfg *dcfg = priv->dcfg;
  552. if (dcfg->method != IMX_RPROC_SCU_API)
  553. return -EOPNOTSUPP;
  554. if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id))
  555. return -EOPNOTSUPP;
  556. imx_rproc_free_mbox(rproc);
  557. return 0;
  558. }
  559. static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
  560. {
  561. struct imx_rproc *priv = rproc->priv;
  562. /* The resource table has already been mapped in imx_rproc_addr_init */
  563. if (!priv->rsc_table)
  564. return NULL;
  565. *table_sz = SZ_1K;
  566. return (struct resource_table *)priv->rsc_table;
  567. }
  568. static struct resource_table *
  569. imx_rproc_elf_find_loaded_rsc_table(struct rproc *rproc, const struct firmware *fw)
  570. {
  571. struct imx_rproc *priv = rproc->priv;
  572. if (priv->rsc_table)
  573. return (struct resource_table *)priv->rsc_table;
  574. return rproc_elf_find_loaded_rsc_table(rproc, fw);
  575. }
  576. static const struct rproc_ops imx_rproc_ops = {
  577. .prepare = imx_rproc_prepare,
  578. .attach = imx_rproc_attach,
  579. .detach = imx_rproc_detach,
  580. .start = imx_rproc_start,
  581. .stop = imx_rproc_stop,
  582. .kick = imx_rproc_kick,
  583. .da_to_va = imx_rproc_da_to_va,
  584. .load = rproc_elf_load_segments,
  585. .parse_fw = imx_rproc_parse_fw,
  586. .find_loaded_rsc_table = imx_rproc_elf_find_loaded_rsc_table,
  587. .get_loaded_rsc_table = imx_rproc_get_loaded_rsc_table,
  588. .sanity_check = rproc_elf_sanity_check,
  589. .get_boot_addr = rproc_elf_get_boot_addr,
  590. };
  591. static int imx_rproc_addr_init(struct imx_rproc *priv,
  592. struct platform_device *pdev)
  593. {
  594. const struct imx_rproc_dcfg *dcfg = priv->dcfg;
  595. struct device *dev = &pdev->dev;
  596. struct device_node *np = dev->of_node;
  597. int a, b = 0, err, nph;
  598. /* remap required addresses */
  599. for (a = 0; a < dcfg->att_size; a++) {
  600. const struct imx_rproc_att *att = &dcfg->att[a];
  601. if (!(att->flags & ATT_OWN))
  602. continue;
  603. if (b >= IMX_RPROC_MEM_MAX)
  604. break;
  605. if (att->flags & ATT_IOMEM)
  606. priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev,
  607. att->sa, att->size);
  608. else
  609. priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev,
  610. att->sa, att->size);
  611. if (!priv->mem[b].cpu_addr) {
  612. dev_err(dev, "failed to remap %#x bytes from %#x\n", att->size, att->sa);
  613. return -ENOMEM;
  614. }
  615. priv->mem[b].sys_addr = att->sa;
  616. priv->mem[b].size = att->size;
  617. b++;
  618. }
  619. /* memory-region is optional property */
  620. nph = of_count_phandle_with_args(np, "memory-region", NULL);
  621. if (nph <= 0)
  622. return 0;
  623. /* remap optional addresses */
  624. for (a = 0; a < nph; a++) {
  625. struct device_node *node;
  626. struct resource res;
  627. node = of_parse_phandle(np, "memory-region", a);
  628. if (!node)
  629. continue;
  630. /* Not map vdevbuffer, vdevring region */
  631. if (!strncmp(node->name, "vdev", strlen("vdev"))) {
  632. of_node_put(node);
  633. continue;
  634. }
  635. err = of_address_to_resource(node, 0, &res);
  636. if (err) {
  637. dev_err(dev, "unable to resolve memory region\n");
  638. of_node_put(node);
  639. return err;
  640. }
  641. if (b >= IMX_RPROC_MEM_MAX) {
  642. of_node_put(node);
  643. break;
  644. }
  645. /* Not use resource version, because we might share region */
  646. priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev, res.start, resource_size(&res));
  647. if (!priv->mem[b].cpu_addr) {
  648. dev_err(dev, "failed to remap %pr\n", &res);
  649. of_node_put(node);
  650. return -ENOMEM;
  651. }
  652. priv->mem[b].sys_addr = res.start;
  653. priv->mem[b].size = resource_size(&res);
  654. if (!strcmp(node->name, "rsc-table"))
  655. priv->rsc_table = priv->mem[b].cpu_addr;
  656. of_node_put(node);
  657. b++;
  658. }
  659. return 0;
  660. }
  661. static int imx_rproc_notified_idr_cb(int id, void *ptr, void *data)
  662. {
  663. struct rproc *rproc = data;
  664. rproc_vq_interrupt(rproc, id);
  665. return 0;
  666. }
  667. static void imx_rproc_vq_work(struct work_struct *work)
  668. {
  669. struct imx_rproc *priv = container_of(work, struct imx_rproc,
  670. rproc_work);
  671. struct rproc *rproc = priv->rproc;
  672. idr_for_each(&rproc->notifyids, imx_rproc_notified_idr_cb, rproc);
  673. }
  674. static void imx_rproc_rx_callback(struct mbox_client *cl, void *msg)
  675. {
  676. struct rproc *rproc = dev_get_drvdata(cl->dev);
  677. struct imx_rproc *priv = rproc->priv;
  678. queue_work(priv->workqueue, &priv->rproc_work);
  679. }
  680. static int imx_rproc_xtr_mbox_init(struct rproc *rproc, bool tx_block)
  681. {
  682. struct imx_rproc *priv = rproc->priv;
  683. struct device *dev = priv->dev;
  684. struct mbox_client *cl;
  685. /*
  686. * stop() and detach() will free the mbox channels, so need
  687. * to request mbox channels in start() and attach().
  688. *
  689. * Because start() and attach() not able to handle mbox defer
  690. * probe, imx_rproc_xtr_mbox_init is also called in probe().
  691. * The check is to avoid request mbox again when start() or
  692. * attach() after probe() returns success.
  693. */
  694. if (priv->tx_ch && priv->rx_ch)
  695. return 0;
  696. if (!of_property_present(dev->of_node, "mbox-names"))
  697. return 0;
  698. cl = &priv->cl;
  699. cl->dev = dev;
  700. cl->tx_block = tx_block;
  701. cl->tx_tout = 100;
  702. cl->knows_txdone = false;
  703. cl->rx_callback = imx_rproc_rx_callback;
  704. priv->tx_ch = mbox_request_channel_byname(cl, "tx");
  705. if (IS_ERR(priv->tx_ch))
  706. return dev_err_probe(cl->dev, PTR_ERR(priv->tx_ch),
  707. "failed to request tx mailbox channel\n");
  708. priv->rx_ch = mbox_request_channel_byname(cl, "rx");
  709. if (IS_ERR(priv->rx_ch)) {
  710. mbox_free_channel(priv->tx_ch);
  711. return dev_err_probe(cl->dev, PTR_ERR(priv->rx_ch),
  712. "failed to request rx mailbox channel\n");
  713. }
  714. return 0;
  715. }
  716. static void imx_rproc_free_mbox(struct rproc *rproc)
  717. {
  718. struct imx_rproc *priv = rproc->priv;
  719. if (priv->tx_ch) {
  720. mbox_free_channel(priv->tx_ch);
  721. priv->tx_ch = NULL;
  722. }
  723. if (priv->rx_ch) {
  724. mbox_free_channel(priv->rx_ch);
  725. priv->rx_ch = NULL;
  726. }
  727. }
  728. static void imx_rproc_put_scu(struct rproc *rproc)
  729. {
  730. struct imx_rproc *priv = rproc->priv;
  731. const struct imx_rproc_dcfg *dcfg = priv->dcfg;
  732. if (dcfg->method != IMX_RPROC_SCU_API)
  733. return;
  734. if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) {
  735. dev_pm_domain_detach_list(priv->pd_list);
  736. return;
  737. }
  738. imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED, BIT(priv->rproc_pt), false);
  739. imx_scu_irq_unregister_notifier(&priv->rproc_nb);
  740. }
  741. static int imx_rproc_partition_notify(struct notifier_block *nb,
  742. unsigned long event, void *group)
  743. {
  744. struct imx_rproc *priv = container_of(nb, struct imx_rproc, rproc_nb);
  745. /* Ignore other irqs */
  746. if (!((event & BIT(priv->rproc_pt)) && (*(u8 *)group == IMX_SC_IRQ_GROUP_REBOOTED)))
  747. return 0;
  748. rproc_report_crash(priv->rproc, RPROC_WATCHDOG);
  749. pr_info("Partition%d reset!\n", priv->rproc_pt);
  750. return 0;
  751. }
  752. static int imx_rproc_attach_pd(struct imx_rproc *priv)
  753. {
  754. struct device *dev = priv->dev;
  755. int ret;
  756. struct dev_pm_domain_attach_data pd_data = {
  757. .pd_flags = PD_FLAG_DEV_LINK_ON,
  758. };
  759. /*
  760. * If there is only one power-domain entry, the platform driver framework
  761. * will handle it, no need handle it in this driver.
  762. */
  763. if (dev->pm_domain)
  764. return 0;
  765. ret = dev_pm_domain_attach_list(dev, &pd_data, &priv->pd_list);
  766. return ret < 0 ? ret : 0;
  767. }
  768. static int imx_rproc_detect_mode(struct imx_rproc *priv)
  769. {
  770. struct regmap_config config = { .name = "imx-rproc" };
  771. const struct imx_rproc_dcfg *dcfg = priv->dcfg;
  772. struct device *dev = priv->dev;
  773. struct regmap *regmap;
  774. struct arm_smccc_res res;
  775. int ret;
  776. u32 val;
  777. u8 pt;
  778. switch (dcfg->method) {
  779. case IMX_RPROC_NONE:
  780. priv->rproc->state = RPROC_DETACHED;
  781. return 0;
  782. case IMX_RPROC_SMC:
  783. arm_smccc_smc(IMX_SIP_RPROC, IMX_SIP_RPROC_STARTED, 0, 0, 0, 0, 0, 0, &res);
  784. if (res.a0)
  785. priv->rproc->state = RPROC_DETACHED;
  786. return 0;
  787. case IMX_RPROC_SCU_API:
  788. ret = imx_scu_get_handle(&priv->ipc_handle);
  789. if (ret)
  790. return ret;
  791. ret = of_property_read_u32(dev->of_node, "fsl,resource-id", &priv->rsrc_id);
  792. if (ret) {
  793. dev_err(dev, "No fsl,resource-id property\n");
  794. return ret;
  795. }
  796. if (priv->rsrc_id == IMX_SC_R_M4_1_PID0)
  797. priv->core_index = 1;
  798. else
  799. priv->core_index = 0;
  800. /*
  801. * If Mcore resource is not owned by Acore partition, It is kicked by ROM,
  802. * and Linux could only do IPC with Mcore and nothing else.
  803. */
  804. if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) {
  805. if (of_property_read_u32(dev->of_node, "fsl,entry-address", &priv->entry))
  806. return -EINVAL;
  807. return imx_rproc_attach_pd(priv);
  808. }
  809. priv->rproc->state = RPROC_DETACHED;
  810. priv->rproc->recovery_disabled = false;
  811. rproc_set_feature(priv->rproc, RPROC_FEAT_ATTACH_ON_RECOVERY);
  812. /* Get partition id and enable irq in SCFW */
  813. ret = imx_sc_rm_get_resource_owner(priv->ipc_handle, priv->rsrc_id, &pt);
  814. if (ret) {
  815. dev_err(dev, "not able to get resource owner\n");
  816. return ret;
  817. }
  818. priv->rproc_pt = pt;
  819. priv->rproc_nb.notifier_call = imx_rproc_partition_notify;
  820. ret = imx_scu_irq_register_notifier(&priv->rproc_nb);
  821. if (ret) {
  822. dev_err(dev, "register scu notifier failed, %d\n", ret);
  823. return ret;
  824. }
  825. ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED, BIT(priv->rproc_pt),
  826. true);
  827. if (ret) {
  828. imx_scu_irq_unregister_notifier(&priv->rproc_nb);
  829. dev_err(dev, "Enable irq failed, %d\n", ret);
  830. return ret;
  831. }
  832. return 0;
  833. default:
  834. break;
  835. }
  836. priv->gpr = syscon_regmap_lookup_by_phandle(dev->of_node, "fsl,iomuxc-gpr");
  837. if (IS_ERR(priv->gpr))
  838. priv->gpr = NULL;
  839. regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon");
  840. if (IS_ERR(regmap)) {
  841. dev_err(dev, "failed to find syscon\n");
  842. return PTR_ERR(regmap);
  843. }
  844. priv->regmap = regmap;
  845. regmap_attach_dev(dev, regmap, &config);
  846. if (priv->gpr) {
  847. ret = regmap_read(priv->gpr, dcfg->gpr_reg, &val);
  848. if (val & dcfg->gpr_wait) {
  849. /*
  850. * After cold boot, the CM indicates its in wait
  851. * state, but not fully powered off. Power it off
  852. * fully so firmware can be loaded into it.
  853. */
  854. imx_rproc_stop(priv->rproc);
  855. return 0;
  856. }
  857. }
  858. ret = regmap_read(regmap, dcfg->src_reg, &val);
  859. if (ret) {
  860. dev_err(dev, "Failed to read src\n");
  861. return ret;
  862. }
  863. if ((val & dcfg->src_mask) != dcfg->src_stop)
  864. priv->rproc->state = RPROC_DETACHED;
  865. return 0;
  866. }
  867. static int imx_rproc_clk_enable(struct imx_rproc *priv)
  868. {
  869. const struct imx_rproc_dcfg *dcfg = priv->dcfg;
  870. struct device *dev = priv->dev;
  871. int ret;
  872. /* Remote core is not under control of Linux or it is managed by SCU API */
  873. if (dcfg->method == IMX_RPROC_NONE || dcfg->method == IMX_RPROC_SCU_API)
  874. return 0;
  875. priv->clk = devm_clk_get(dev, NULL);
  876. if (IS_ERR(priv->clk)) {
  877. dev_err(dev, "Failed to get clock\n");
  878. return PTR_ERR(priv->clk);
  879. }
  880. /*
  881. * clk for M4 block including memory. Should be
  882. * enabled before .start for FW transfer.
  883. */
  884. ret = clk_prepare_enable(priv->clk);
  885. if (ret) {
  886. dev_err(dev, "Failed to enable clock\n");
  887. return ret;
  888. }
  889. return 0;
  890. }
  891. static int imx_rproc_sys_off_handler(struct sys_off_data *data)
  892. {
  893. struct rproc *rproc = data->cb_data;
  894. int ret;
  895. imx_rproc_free_mbox(rproc);
  896. ret = imx_rproc_xtr_mbox_init(rproc, false);
  897. if (ret) {
  898. dev_err(&rproc->dev, "Failed to request non-blocking mbox\n");
  899. return NOTIFY_BAD;
  900. }
  901. return NOTIFY_DONE;
  902. }
  903. static int imx_rproc_probe(struct platform_device *pdev)
  904. {
  905. struct device *dev = &pdev->dev;
  906. struct device_node *np = dev->of_node;
  907. struct imx_rproc *priv;
  908. struct rproc *rproc;
  909. const struct imx_rproc_dcfg *dcfg;
  910. int ret;
  911. /* set some other name then imx */
  912. rproc = devm_rproc_alloc(dev, "imx-rproc", &imx_rproc_ops,
  913. NULL, sizeof(*priv));
  914. if (!rproc)
  915. return -ENOMEM;
  916. dcfg = of_device_get_match_data(dev);
  917. if (!dcfg)
  918. return -EINVAL;
  919. priv = rproc->priv;
  920. priv->rproc = rproc;
  921. priv->dcfg = dcfg;
  922. priv->dev = dev;
  923. dev_set_drvdata(dev, rproc);
  924. priv->workqueue = create_workqueue(dev_name(dev));
  925. if (!priv->workqueue) {
  926. dev_err(dev, "cannot create workqueue\n");
  927. return -ENOMEM;
  928. }
  929. INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
  930. ret = imx_rproc_xtr_mbox_init(rproc, true);
  931. if (ret)
  932. goto err_put_wkq;
  933. ret = imx_rproc_addr_init(priv, pdev);
  934. if (ret) {
  935. dev_err(dev, "failed on imx_rproc_addr_init\n");
  936. goto err_put_mbox;
  937. }
  938. ret = imx_rproc_detect_mode(priv);
  939. if (ret)
  940. goto err_put_mbox;
  941. ret = imx_rproc_clk_enable(priv);
  942. if (ret)
  943. goto err_put_scu;
  944. if (rproc->state != RPROC_DETACHED)
  945. rproc->auto_boot = of_property_read_bool(np, "fsl,auto-boot");
  946. if (dcfg->flags & IMX_RPROC_NEED_SYSTEM_OFF) {
  947. /*
  948. * setup mailbox to non-blocking mode in
  949. * [SYS_OFF_MODE_POWER_OFF_PREPARE, SYS_OFF_MODE_RESTART_PREPARE]
  950. * phase before invoking [SYS_OFF_MODE_POWER_OFF, SYS_OFF_MODE_RESTART]
  951. * atomic chain, see kernel/reboot.c.
  952. */
  953. ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_POWER_OFF_PREPARE,
  954. SYS_OFF_PRIO_DEFAULT,
  955. imx_rproc_sys_off_handler, rproc);
  956. if (ret) {
  957. dev_err(dev, "register power off handler failure\n");
  958. goto err_put_clk;
  959. }
  960. ret = devm_register_sys_off_handler(dev, SYS_OFF_MODE_RESTART_PREPARE,
  961. SYS_OFF_PRIO_DEFAULT,
  962. imx_rproc_sys_off_handler, rproc);
  963. if (ret) {
  964. dev_err(dev, "register restart handler failure\n");
  965. goto err_put_clk;
  966. }
  967. }
  968. ret = rproc_add(rproc);
  969. if (ret) {
  970. dev_err(dev, "rproc_add failed\n");
  971. goto err_put_clk;
  972. }
  973. return 0;
  974. err_put_clk:
  975. clk_disable_unprepare(priv->clk);
  976. err_put_scu:
  977. imx_rproc_put_scu(rproc);
  978. err_put_mbox:
  979. imx_rproc_free_mbox(rproc);
  980. err_put_wkq:
  981. destroy_workqueue(priv->workqueue);
  982. return ret;
  983. }
  984. static void imx_rproc_remove(struct platform_device *pdev)
  985. {
  986. struct rproc *rproc = platform_get_drvdata(pdev);
  987. struct imx_rproc *priv = rproc->priv;
  988. clk_disable_unprepare(priv->clk);
  989. rproc_del(rproc);
  990. imx_rproc_put_scu(rproc);
  991. imx_rproc_free_mbox(rproc);
  992. destroy_workqueue(priv->workqueue);
  993. }
  994. static const struct of_device_id imx_rproc_of_match[] = {
  995. { .compatible = "fsl,imx7ulp-cm4", .data = &imx_rproc_cfg_imx7ulp },
  996. { .compatible = "fsl,imx7d-cm4", .data = &imx_rproc_cfg_imx7d },
  997. { .compatible = "fsl,imx6sx-cm4", .data = &imx_rproc_cfg_imx6sx },
  998. { .compatible = "fsl,imx8mq-cm4", .data = &imx_rproc_cfg_imx8mq },
  999. { .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq },
  1000. { .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
  1001. { .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
  1002. { .compatible = "fsl,imx8mn-cm7-mmio", .data = &imx_rproc_cfg_imx8mn_mmio },
  1003. { .compatible = "fsl,imx8mp-cm7-mmio", .data = &imx_rproc_cfg_imx8mn_mmio },
  1004. { .compatible = "fsl,imx8qxp-cm4", .data = &imx_rproc_cfg_imx8qxp },
  1005. { .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm },
  1006. { .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
  1007. { .compatible = "fsl,imx93-cm33", .data = &imx_rproc_cfg_imx93 },
  1008. {},
  1009. };
  1010. MODULE_DEVICE_TABLE(of, imx_rproc_of_match);
  1011. static struct platform_driver imx_rproc_driver = {
  1012. .probe = imx_rproc_probe,
  1013. .remove_new = imx_rproc_remove,
  1014. .driver = {
  1015. .name = "imx-rproc",
  1016. .of_match_table = imx_rproc_of_match,
  1017. },
  1018. };
  1019. module_platform_driver(imx_rproc_driver);
  1020. MODULE_LICENSE("GPL v2");
  1021. MODULE_DESCRIPTION("i.MX remote processor control driver");
  1022. MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");