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