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