Lines Matching +full:cortex +full:- +full:m4
1 // SPDX-License-Identifier: GPL-2.0-only
6 #include <linux/arm-smccc.h>
60 * struct imx_rproc_mem - slim internal memory structure
72 /* M4 own area. Can be mapped at probe */
77 u32 da; /* device address (From Cortex M4 view)*/
129 /* QSPI Code - alias */
131 /* DDR (Code) - alias */
135 /* OCRAM_S - alias */
149 /* TCML - alias */
157 /* QSPI Code - alias */
159 /* DDR (Code) - alias */
191 /* OCRAM_S (M4 Boot code) - alias */
195 /* OCRAM (Code) - alias */
197 /* OCRAM_EPDC (Code) - alias */
199 /* OCRAM_PXP (Code) - alias */
203 /* DDR (Code) - alias, first part of DDR (Data) */
220 /* TCML (M4 Boot Code) - alias */
224 /* OCRAM_S (Code) - alias */
228 /* DDR (Code) - alias, first part of DDR (Data) */
233 /* OCRAM_S (Data) - alias? */
289 struct imx_rproc *priv = rproc->priv; in imx_rproc_start()
290 const struct imx_rproc_dcfg *dcfg = priv->dcfg; in imx_rproc_start()
291 struct device *dev = priv->dev; in imx_rproc_start()
295 switch (dcfg->method) { in imx_rproc_start()
297 ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask, in imx_rproc_start()
298 dcfg->src_start); in imx_rproc_start()
305 return -EOPNOTSUPP; in imx_rproc_start()
316 struct imx_rproc *priv = rproc->priv; in imx_rproc_stop()
317 const struct imx_rproc_dcfg *dcfg = priv->dcfg; in imx_rproc_stop()
318 struct device *dev = priv->dev; in imx_rproc_stop()
322 switch (dcfg->method) { in imx_rproc_stop()
324 ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask, in imx_rproc_stop()
325 dcfg->src_stop); in imx_rproc_stop()
334 return -EOPNOTSUPP; in imx_rproc_stop()
346 const struct imx_rproc_dcfg *dcfg = priv->dcfg; in imx_rproc_da_to_sys()
350 for (i = 0; i < dcfg->att_size; i++) { in imx_rproc_da_to_sys()
351 const struct imx_rproc_att *att = &dcfg->att[i]; in imx_rproc_da_to_sys()
353 if (da >= att->da && da + len < att->da + att->size) { in imx_rproc_da_to_sys()
354 unsigned int offset = da - att->da; in imx_rproc_da_to_sys()
356 *sys = att->sa + offset; in imx_rproc_da_to_sys()
361 dev_warn(priv->dev, "Translation failed: da = 0x%llx len = 0x%zx\n", in imx_rproc_da_to_sys()
363 return -ENOENT; in imx_rproc_da_to_sys()
368 struct imx_rproc *priv = rproc->priv; in imx_rproc_da_to_va()
378 * address (M4) to system bus address first. in imx_rproc_da_to_va()
384 if (sys >= priv->mem[i].sys_addr && sys + len < in imx_rproc_da_to_va()
385 priv->mem[i].sys_addr + priv->mem[i].size) { in imx_rproc_da_to_va()
386 unsigned int offset = sys - priv->mem[i].sys_addr; in imx_rproc_da_to_va()
388 va = (__force void *)(priv->mem[i].cpu_addr + offset); in imx_rproc_da_to_va()
393 dev_dbg(&rproc->dev, "da = 0x%llx len = 0x%zx va = 0x%p\n", in imx_rproc_da_to_va()
402 struct device *dev = rproc->dev.parent; in imx_rproc_mem_alloc()
405 dev_dbg(dev, "map memory: %p+%zx\n", &mem->dma, mem->len); in imx_rproc_mem_alloc()
406 va = ioremap_wc(mem->dma, mem->len); in imx_rproc_mem_alloc()
409 &mem->dma, mem->len); in imx_rproc_mem_alloc()
410 return -ENOMEM; in imx_rproc_mem_alloc()
414 mem->va = va; in imx_rproc_mem_alloc()
422 dev_dbg(rproc->dev.parent, "unmap memory: %pa\n", &mem->dma); in imx_rproc_mem_release()
423 iounmap(mem->va); in imx_rproc_mem_release()
430 struct imx_rproc *priv = rproc->priv; in imx_rproc_prepare()
431 struct device_node *np = priv->dev->of_node; in imx_rproc_prepare()
438 of_phandle_iterator_init(&it, np, "memory-region", NULL, 0); in imx_rproc_prepare()
444 if (!strcmp(it.node->name, "vdev0buffer")) in imx_rproc_prepare()
449 dev_err(priv->dev, "unable to acquire memory-region\n"); in imx_rproc_prepare()
450 return -EINVAL; in imx_rproc_prepare()
454 da = rmem->base; in imx_rproc_prepare()
457 mem = rproc_mem_entry_init(priv->dev, NULL, (dma_addr_t)rmem->base, rmem->size, da, in imx_rproc_prepare()
459 it.node->name); in imx_rproc_prepare()
462 rproc_coredump_add_segment(rproc, da, rmem->size); in imx_rproc_prepare()
464 return -ENOMEM; in imx_rproc_prepare()
478 dev_info(&rproc->dev, "No resource table in elf\n"); in imx_rproc_parse_fw()
485 struct imx_rproc *priv = rproc->priv; in imx_rproc_kick()
489 if (!priv->tx_ch) { in imx_rproc_kick()
490 dev_err(priv->dev, "No initialized mbox tx channel\n"); in imx_rproc_kick()
500 err = mbox_send_message(priv->tx_ch, (void *)&mmsg); in imx_rproc_kick()
502 dev_err(priv->dev, "%s: failed (%d, err:%d)\n", in imx_rproc_kick()
513 struct imx_rproc *priv = rproc->priv; in imx_rproc_get_loaded_rsc_table()
516 if (!priv->rsc_table) in imx_rproc_get_loaded_rsc_table()
520 return (struct resource_table *)priv->rsc_table; in imx_rproc_get_loaded_rsc_table()
541 const struct imx_rproc_dcfg *dcfg = priv->dcfg; in imx_rproc_addr_init()
542 struct device *dev = &pdev->dev; in imx_rproc_addr_init()
543 struct device_node *np = dev->of_node; in imx_rproc_addr_init()
547 for (a = 0; a < dcfg->att_size; a++) { in imx_rproc_addr_init()
548 const struct imx_rproc_att *att = &dcfg->att[a]; in imx_rproc_addr_init()
550 if (!(att->flags & ATT_OWN)) in imx_rproc_addr_init()
556 priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev, in imx_rproc_addr_init()
557 att->sa, att->size); in imx_rproc_addr_init()
558 if (!priv->mem[b].cpu_addr) { in imx_rproc_addr_init()
559 dev_err(dev, "failed to remap %#x bytes from %#x\n", att->size, att->sa); in imx_rproc_addr_init()
560 return -ENOMEM; in imx_rproc_addr_init()
562 priv->mem[b].sys_addr = att->sa; in imx_rproc_addr_init()
563 priv->mem[b].size = att->size; in imx_rproc_addr_init()
567 /* memory-region is optional property */ in imx_rproc_addr_init()
568 nph = of_count_phandle_with_args(np, "memory-region", NULL); in imx_rproc_addr_init()
577 node = of_parse_phandle(np, "memory-region", a); in imx_rproc_addr_init()
579 if (!strcmp(node->name, "vdev")) in imx_rproc_addr_init()
593 priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev, res.start, resource_size(&res)); in imx_rproc_addr_init()
594 if (!priv->mem[b].cpu_addr) { in imx_rproc_addr_init()
596 return -ENOMEM; in imx_rproc_addr_init()
598 priv->mem[b].sys_addr = res.start; in imx_rproc_addr_init()
599 priv->mem[b].size = resource_size(&res); in imx_rproc_addr_init()
600 if (!strcmp(node->name, "rsc_table")) in imx_rproc_addr_init()
601 priv->rsc_table = priv->mem[b].cpu_addr; in imx_rproc_addr_init()
613 rproc_vq_interrupt(priv->rproc, 0); in imx_rproc_vq_work()
614 rproc_vq_interrupt(priv->rproc, 1); in imx_rproc_vq_work()
619 struct rproc *rproc = dev_get_drvdata(cl->dev); in imx_rproc_rx_callback()
620 struct imx_rproc *priv = rproc->priv; in imx_rproc_rx_callback()
622 queue_work(priv->workqueue, &priv->rproc_work); in imx_rproc_rx_callback()
627 struct imx_rproc *priv = rproc->priv; in imx_rproc_xtr_mbox_init()
628 struct device *dev = priv->dev; in imx_rproc_xtr_mbox_init()
632 if (!of_get_property(dev->of_node, "mbox-names", NULL)) in imx_rproc_xtr_mbox_init()
635 cl = &priv->cl; in imx_rproc_xtr_mbox_init()
636 cl->dev = dev; in imx_rproc_xtr_mbox_init()
637 cl->tx_block = true; in imx_rproc_xtr_mbox_init()
638 cl->tx_tout = 100; in imx_rproc_xtr_mbox_init()
639 cl->knows_txdone = false; in imx_rproc_xtr_mbox_init()
640 cl->rx_callback = imx_rproc_rx_callback; in imx_rproc_xtr_mbox_init()
642 priv->tx_ch = mbox_request_channel_byname(cl, "tx"); in imx_rproc_xtr_mbox_init()
643 if (IS_ERR(priv->tx_ch)) { in imx_rproc_xtr_mbox_init()
644 ret = PTR_ERR(priv->tx_ch); in imx_rproc_xtr_mbox_init()
645 return dev_err_probe(cl->dev, ret, in imx_rproc_xtr_mbox_init()
649 priv->rx_ch = mbox_request_channel_byname(cl, "rx"); in imx_rproc_xtr_mbox_init()
650 if (IS_ERR(priv->rx_ch)) { in imx_rproc_xtr_mbox_init()
651 mbox_free_channel(priv->tx_ch); in imx_rproc_xtr_mbox_init()
652 ret = PTR_ERR(priv->rx_ch); in imx_rproc_xtr_mbox_init()
653 return dev_err_probe(cl->dev, ret, in imx_rproc_xtr_mbox_init()
662 struct imx_rproc *priv = rproc->priv; in imx_rproc_free_mbox()
664 mbox_free_channel(priv->tx_ch); in imx_rproc_free_mbox()
665 mbox_free_channel(priv->rx_ch); in imx_rproc_free_mbox()
670 struct regmap_config config = { .name = "imx-rproc" }; in imx_rproc_detect_mode()
671 const struct imx_rproc_dcfg *dcfg = priv->dcfg; in imx_rproc_detect_mode()
672 struct device *dev = priv->dev; in imx_rproc_detect_mode()
678 switch (dcfg->method) { in imx_rproc_detect_mode()
680 priv->rproc->state = RPROC_DETACHED; in imx_rproc_detect_mode()
685 priv->rproc->state = RPROC_DETACHED; in imx_rproc_detect_mode()
691 regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); in imx_rproc_detect_mode()
697 priv->regmap = regmap; in imx_rproc_detect_mode()
700 ret = regmap_read(regmap, dcfg->src_reg, &val); in imx_rproc_detect_mode()
706 if (!(val & dcfg->src_stop)) in imx_rproc_detect_mode()
707 priv->rproc->state = RPROC_DETACHED; in imx_rproc_detect_mode()
714 const struct imx_rproc_dcfg *dcfg = priv->dcfg; in imx_rproc_clk_enable()
715 struct device *dev = priv->dev; in imx_rproc_clk_enable()
719 if (dcfg->method == IMX_RPROC_NONE) in imx_rproc_clk_enable()
722 priv->clk = devm_clk_get(dev, NULL); in imx_rproc_clk_enable()
723 if (IS_ERR(priv->clk)) { in imx_rproc_clk_enable()
725 return PTR_ERR(priv->clk); in imx_rproc_clk_enable()
729 * clk for M4 block including memory. Should be in imx_rproc_clk_enable()
732 ret = clk_prepare_enable(priv->clk); in imx_rproc_clk_enable()
743 struct device *dev = &pdev->dev; in imx_rproc_probe()
744 struct device_node *np = dev->of_node; in imx_rproc_probe()
751 rproc = rproc_alloc(dev, "imx-rproc", &imx_rproc_ops, in imx_rproc_probe()
754 return -ENOMEM; in imx_rproc_probe()
758 ret = -EINVAL; in imx_rproc_probe()
762 priv = rproc->priv; in imx_rproc_probe()
763 priv->rproc = rproc; in imx_rproc_probe()
764 priv->dcfg = dcfg; in imx_rproc_probe()
765 priv->dev = dev; in imx_rproc_probe()
768 priv->workqueue = create_workqueue(dev_name(dev)); in imx_rproc_probe()
769 if (!priv->workqueue) { in imx_rproc_probe()
771 ret = -ENOMEM; in imx_rproc_probe()
793 INIT_WORK(&priv->rproc_work, imx_rproc_vq_work); in imx_rproc_probe()
795 if (rproc->state != RPROC_DETACHED) in imx_rproc_probe()
796 rproc->auto_boot = of_property_read_bool(np, "fsl,auto-boot"); in imx_rproc_probe()
807 clk_disable_unprepare(priv->clk); in imx_rproc_probe()
811 destroy_workqueue(priv->workqueue); in imx_rproc_probe()
821 struct imx_rproc *priv = rproc->priv; in imx_rproc_remove()
823 clk_disable_unprepare(priv->clk); in imx_rproc_remove()
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 },
848 .name = "imx-rproc",