Merge tag 'x86-irq-2021-08-30' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
[linux-2.6-microblaze.git] / drivers / remoteproc / imx_rproc.c
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>");