1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2017 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
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>
21 #include "remoteproc_internal.h"
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)
29 #define IMX7D_M4_RST_MASK (IMX7D_ENABLE_M4 | IMX7D_SW_M4P_RST \
31 | IMX7D_SW_M4C_NON_SCLR_RST)
33 #define IMX7D_M4_START (IMX7D_ENABLE_M4 | IMX7D_SW_M4P_RST \
35 #define IMX7D_M4_STOP IMX7D_SW_M4C_NON_SCLR_RST
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)
44 #define IMX6SX_M4_START (IMX6SX_ENABLE_M4 | IMX6SX_SW_M4P_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 \
51 #define IMX_RPROC_MEM_MAX 32
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
59 struct imx_rproc_mem {
60 void __iomem *cpu_addr;
66 /* M4 own area. Can be mapped at probe */
67 #define ATT_OWN BIT(1)
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 */
77 /* Remote core start/stop method */
78 enum imx_rproc_method {
80 /* Through syscon regmap */
82 /* Through ARM SMCCC */
86 struct imx_rproc_dcfg {
91 const struct imx_rproc_att *att;
93 enum imx_rproc_method method;
98 struct regmap *regmap;
100 const struct imx_rproc_dcfg *dcfg;
101 struct imx_rproc_mem mem[IMX_RPROC_MEM_MAX];
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;
111 static const struct imx_rproc_att imx_rproc_att_imx8mq[] = {
112 /* dev addr , sys addr , size , flags */
114 { 0x00000000, 0x007e0000, 0x00020000, 0 },
116 { 0x00180000, 0x00180000, 0x00008000, 0 },
118 { 0x00900000, 0x00900000, 0x00020000, 0 },
120 { 0x00920000, 0x00920000, 0x00020000, 0 },
121 /* QSPI Code - alias */
122 { 0x08000000, 0x08000000, 0x08000000, 0 },
123 /* DDR (Code) - alias */
124 { 0x10000000, 0x80000000, 0x0FFE0000, 0 },
126 { 0x1FFE0000, 0x007E0000, 0x00020000, ATT_OWN },
128 { 0x20000000, 0x00800000, 0x00020000, ATT_OWN },
130 { 0x20180000, 0x00180000, 0x00008000, ATT_OWN },
132 { 0x20200000, 0x00900000, 0x00020000, ATT_OWN },
134 { 0x20220000, 0x00920000, 0x00020000, ATT_OWN },
136 { 0x40000000, 0x40000000, 0x80000000, 0 },
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 },
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 },
152 { 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN },
153 /* DDR (Code) - alias, first part of DDR (Data) */
154 { 0x10000000, 0x80000000, 0x0FFF0000, 0 },
157 { 0x20000000, 0x00800000, 0x00008000, ATT_OWN },
159 { 0x20200000, 0x00900000, 0x00020000, 0 },
160 /* OCRAM_EPDC (Data) */
161 { 0x20220000, 0x00920000, 0x00020000, 0 },
162 /* OCRAM_PXP (Data) */
163 { 0x20240000, 0x00940000, 0x00008000, 0 },
165 { 0x80000000, 0x80000000, 0x60000000, 0 },
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 },
173 { 0x00180000, 0x008F8000, 0x00004000, 0 },
174 /* OCRAM_S (Code) - alias */
175 { 0x00180000, 0x008FC000, 0x00004000, 0 },
177 { 0x1FFF8000, 0x007F8000, 0x00008000, ATT_OWN },
178 /* DDR (Code) - alias, first part of DDR (Data) */
179 { 0x10000000, 0x80000000, 0x0FFF8000, 0 },
182 { 0x20000000, 0x00800000, 0x00008000, ATT_OWN },
183 /* OCRAM_S (Data) - alias? */
184 { 0x208F8000, 0x008F8000, 0x00004000, 0 },
186 { 0x80000000, 0x80000000, 0x60000000, 0 },
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,
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,
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,
219 static int imx_rproc_start(struct rproc *rproc)
221 struct imx_rproc *priv = rproc->priv;
222 const struct imx_rproc_dcfg *dcfg = priv->dcfg;
223 struct device *dev = priv->dev;
226 ret = regmap_update_bits(priv->regmap, dcfg->src_reg,
227 dcfg->src_mask, dcfg->src_start);
229 dev_err(dev, "Failed to enable M4!\n");
234 static int imx_rproc_stop(struct rproc *rproc)
236 struct imx_rproc *priv = rproc->priv;
237 const struct imx_rproc_dcfg *dcfg = priv->dcfg;
238 struct device *dev = priv->dev;
241 ret = regmap_update_bits(priv->regmap, dcfg->src_reg,
242 dcfg->src_mask, dcfg->src_stop);
244 dev_err(dev, "Failed to stop M4!\n");
249 static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da,
250 size_t len, u64 *sys)
252 const struct imx_rproc_dcfg *dcfg = priv->dcfg;
255 /* parse address translation table */
256 for (i = 0; i < dcfg->att_size; i++) {
257 const struct imx_rproc_att *att = &dcfg->att[i];
259 if (da >= att->da && da + len < att->da + att->size) {
260 unsigned int offset = da - att->da;
262 *sys = att->sa + offset;
267 dev_warn(priv->dev, "Translation failed: da = 0x%llx len = 0x%zx\n",
272 static void *imx_rproc_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
274 struct imx_rproc *priv = rproc->priv;
283 * On device side we have many aliases, so we need to convert device
284 * address (M4) to system bus address first.
286 if (imx_rproc_da_to_sys(priv, da, len, &sys))
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);
299 dev_dbg(&rproc->dev, "da = 0x%llx len = 0x%zx va = 0x%p\n",
305 static int imx_rproc_mem_alloc(struct rproc *rproc,
306 struct rproc_mem_entry *mem)
308 struct device *dev = rproc->dev.parent;
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);
319 /* Update memory entry va */
325 static int imx_rproc_mem_release(struct rproc *rproc,
326 struct rproc_mem_entry *mem)
328 dev_dbg(rproc->dev.parent, "unmap memory: %pa\n", &mem->dma);
334 static int imx_rproc_prepare(struct rproc *rproc)
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;
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) {
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.
350 if (!strcmp(it.node->name, "vdev0buffer"))
353 rmem = of_reserved_mem_lookup(it.node);
355 dev_err(priv->dev, "unable to acquire memory-region\n");
359 /* No need to translate pa to da, i.MX use same map */
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,
368 rproc_coredump_add_segment(rproc, da, rmem->size);
372 rproc_add_carveout(rproc, mem);
378 static int imx_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw)
382 ret = rproc_elf_load_rsc_table(rproc, fw);
384 dev_info(&rproc->dev, "No resource table in elf\n");
389 static void imx_rproc_kick(struct rproc *rproc, int vqid)
391 struct imx_rproc *priv = rproc->priv;
396 dev_err(priv->dev, "No initialized mbox tx channel\n");
401 * Send the index of the triggered virtqueue as the mu payload.
402 * Let remote processor know which virtqueue is used.
406 err = mbox_send_message(priv->tx_ch, (void *)&mmsg);
408 dev_err(priv->dev, "%s: failed (%d, err:%d)\n",
409 __func__, vqid, err);
412 static int imx_rproc_attach(struct rproc *rproc)
417 static struct resource_table *imx_rproc_get_loaded_rsc_table(struct rproc *rproc, size_t *table_sz)
419 struct imx_rproc *priv = rproc->priv;
421 /* The resource table has already been mapped in imx_rproc_addr_init */
422 if (!priv->rsc_table)
426 return (struct resource_table *)priv->rsc_table;
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,
444 static int imx_rproc_addr_init(struct imx_rproc *priv,
445 struct platform_device *pdev)
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;
452 /* remap required addresses */
453 for (a = 0; a < dcfg->att_size; a++) {
454 const struct imx_rproc_att *att = &dcfg->att[a];
456 if (!(att->flags & ATT_OWN))
459 if (b >= IMX_RPROC_MEM_MAX)
462 priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev,
464 if (!priv->mem[b].cpu_addr) {
465 dev_err(dev, "failed to remap %#x bytes from %#x\n", att->size, att->sa);
468 priv->mem[b].sys_addr = att->sa;
469 priv->mem[b].size = att->size;
473 /* memory-region is optional property */
474 nph = of_count_phandle_with_args(np, "memory-region", NULL);
478 /* remap optional addresses */
479 for (a = 0; a < nph; a++) {
480 struct device_node *node;
483 node = of_parse_phandle(np, "memory-region", a);
484 /* Not map vdev region */
485 if (!strcmp(node->name, "vdev"))
487 err = of_address_to_resource(node, 0, &res);
489 dev_err(dev, "unable to resolve memory region\n");
495 if (b >= IMX_RPROC_MEM_MAX)
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);
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;
514 static void imx_rproc_vq_work(struct work_struct *work)
516 struct imx_rproc *priv = container_of(work, struct imx_rproc,
519 rproc_vq_interrupt(priv->rproc, 0);
520 rproc_vq_interrupt(priv->rproc, 1);
523 static void imx_rproc_rx_callback(struct mbox_client *cl, void *msg)
525 struct rproc *rproc = dev_get_drvdata(cl->dev);
526 struct imx_rproc *priv = rproc->priv;
528 queue_work(priv->workqueue, &priv->rproc_work);
531 static int imx_rproc_xtr_mbox_init(struct rproc *rproc)
533 struct imx_rproc *priv = rproc->priv;
534 struct device *dev = priv->dev;
535 struct mbox_client *cl;
538 if (!of_get_property(dev->of_node, "mbox-names", NULL))
545 cl->knows_txdone = false;
546 cl->rx_callback = imx_rproc_rx_callback;
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);
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);
566 static void imx_rproc_free_mbox(struct rproc *rproc)
568 struct imx_rproc *priv = rproc->priv;
570 mbox_free_channel(priv->tx_ch);
571 mbox_free_channel(priv->rx_ch);
574 static int imx_rproc_detect_mode(struct imx_rproc *priv)
576 const struct imx_rproc_dcfg *dcfg = priv->dcfg;
577 struct device *dev = priv->dev;
581 ret = regmap_read(priv->regmap, dcfg->src_reg, &val);
583 dev_err(dev, "Failed to read src\n");
587 if (!(val & dcfg->src_stop))
588 priv->rproc->state = RPROC_DETACHED;
593 static int imx_rproc_probe(struct platform_device *pdev)
595 struct device *dev = &pdev->dev;
596 struct device_node *np = dev->of_node;
597 struct imx_rproc *priv;
599 struct regmap_config config = { .name = "imx-rproc" };
600 const struct imx_rproc_dcfg *dcfg;
601 struct regmap *regmap;
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);
609 regmap_attach_dev(dev, regmap, &config);
611 /* set some other name then imx */
612 rproc = rproc_alloc(dev, "imx-rproc", &imx_rproc_ops,
613 NULL, sizeof(*priv));
617 dcfg = of_device_get_match_data(dev);
625 priv->regmap = regmap;
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");
637 ret = imx_rproc_xtr_mbox_init(rproc);
641 ret = imx_rproc_addr_init(priv, pdev);
643 dev_err(dev, "failed on imx_rproc_addr_init\n");
647 ret = imx_rproc_detect_mode(priv);
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);
659 * clk for M4 block including memory. Should be
660 * enabled before .start for FW transfer.
662 ret = clk_prepare_enable(priv->clk);
664 dev_err(&rproc->dev, "Failed to enable clock\n");
668 INIT_WORK(&priv->rproc_work, imx_rproc_vq_work);
670 if (rproc->state != RPROC_DETACHED)
671 rproc->auto_boot = of_property_read_bool(np, "fsl,auto-boot");
673 ret = rproc_add(rproc);
675 dev_err(dev, "rproc_add failed\n");
682 clk_disable_unprepare(priv->clk);
684 imx_rproc_free_mbox(rproc);
686 destroy_workqueue(priv->workqueue);
693 static int imx_rproc_remove(struct platform_device *pdev)
695 struct rproc *rproc = platform_get_drvdata(pdev);
696 struct imx_rproc *priv = rproc->priv;
698 clk_disable_unprepare(priv->clk);
700 imx_rproc_free_mbox(rproc);
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 },
713 MODULE_DEVICE_TABLE(of, imx_rproc_of_match);
715 static struct platform_driver imx_rproc_driver = {
716 .probe = imx_rproc_probe,
717 .remove = imx_rproc_remove,
720 .of_match_table = imx_rproc_of_match,
724 module_platform_driver(imx_rproc_driver);
726 MODULE_LICENSE("GPL v2");
727 MODULE_DESCRIPTION("i.MX remote processor control driver");
728 MODULE_AUTHOR("Oleksij Rempel <o.rempel@pengutronix.de>");