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