Merge tag 'thunderbolt-for-v5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[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 "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>");