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