Lines Matching +full:imx6sx +full:- +full:mu

1 // SPDX-License-Identifier: GPL-2.0-only
6 #include <dt-bindings/firmware/imx/rsrc.h>
7 #include <linux/arm-smccc.h>
75 * struct imx_rproc_mem - slim internal memory structure
122 /* TCM CODE NON-SECURE */
128 /* TCM SYS NON-SECURE*/
179 /* QSPI Code - alias */
181 /* DDR (Code) - alias */
185 /* OCRAM_S - alias */
199 /* TCML - alias */
207 /* QSPI Code - alias */
209 /* DDR (Code) - alias */
239 /* OCRAM_S (M4 Boot code) - alias */
243 /* OCRAM (Code) - alias */
245 /* OCRAM_EPDC (Code) - alias */
247 /* OCRAM_PXP (Code) - alias */
251 /* DDR (Code) - alias, first part of DDR (Data) */
268 /* TCML (M4 Boot Code) - alias */
272 /* OCRAM_S (Code) - alias */
276 /* DDR (Code) - alias, first part of DDR (Data) */
281 /* OCRAM_S (Data) - alias? */
368 struct imx_rproc *priv = rproc->priv; in imx_rproc_start()
369 const struct imx_rproc_dcfg *dcfg = priv->dcfg; in imx_rproc_start()
370 struct device *dev = priv->dev; in imx_rproc_start()
378 switch (dcfg->method) { in imx_rproc_start()
380 if (priv->gpr) { in imx_rproc_start()
381 ret = regmap_clear_bits(priv->gpr, dcfg->gpr_reg, in imx_rproc_start()
382 dcfg->gpr_wait); in imx_rproc_start()
384 ret = regmap_update_bits(priv->regmap, dcfg->src_reg, in imx_rproc_start()
385 dcfg->src_mask, in imx_rproc_start()
386 dcfg->src_start); in imx_rproc_start()
394 ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, true, priv->entry); in imx_rproc_start()
397 return -EOPNOTSUPP; in imx_rproc_start()
408 struct imx_rproc *priv = rproc->priv; in imx_rproc_stop()
409 const struct imx_rproc_dcfg *dcfg = priv->dcfg; in imx_rproc_stop()
410 struct device *dev = priv->dev; in imx_rproc_stop()
414 switch (dcfg->method) { in imx_rproc_stop()
416 if (priv->gpr) { in imx_rproc_stop()
417 ret = regmap_set_bits(priv->gpr, dcfg->gpr_reg, in imx_rproc_stop()
418 dcfg->gpr_wait); in imx_rproc_stop()
420 dev_err(priv->dev, in imx_rproc_stop()
426 ret = regmap_update_bits(priv->regmap, dcfg->src_reg, dcfg->src_mask, in imx_rproc_stop()
427 dcfg->src_stop); in imx_rproc_stop()
436 ret = imx_sc_pm_cpu_start(priv->ipc_handle, priv->rsrc_id, false, priv->entry); in imx_rproc_stop()
439 return -EOPNOTSUPP; in imx_rproc_stop()
453 const struct imx_rproc_dcfg *dcfg = priv->dcfg; in imx_rproc_da_to_sys()
457 for (i = 0; i < dcfg->att_size; i++) { in imx_rproc_da_to_sys()
458 const struct imx_rproc_att *att = &dcfg->att[i]; in imx_rproc_da_to_sys()
466 if (att->flags & ATT_CORE_MASK) { in imx_rproc_da_to_sys()
467 if (!((BIT(priv->core_index)) & (att->flags & ATT_CORE_MASK))) in imx_rproc_da_to_sys()
471 if (da >= att->da && da + len < att->da + att->size) { in imx_rproc_da_to_sys()
472 unsigned int offset = da - att->da; in imx_rproc_da_to_sys()
474 *sys = att->sa + offset; in imx_rproc_da_to_sys()
476 *is_iomem = att->flags & ATT_IOMEM; in imx_rproc_da_to_sys()
481 dev_warn(priv->dev, "Translation failed: da = 0x%llx len = 0x%zx\n", in imx_rproc_da_to_sys()
483 return -ENOENT; in imx_rproc_da_to_sys()
488 struct imx_rproc *priv = rproc->priv; in imx_rproc_da_to_va()
504 if (sys >= priv->mem[i].sys_addr && sys + len < in imx_rproc_da_to_va()
505 priv->mem[i].sys_addr + priv->mem[i].size) { in imx_rproc_da_to_va()
506 unsigned int offset = sys - priv->mem[i].sys_addr; in imx_rproc_da_to_va()
508 va = (__force void *)(priv->mem[i].cpu_addr + offset); in imx_rproc_da_to_va()
513 dev_dbg(&rproc->dev, "da = 0x%llx len = 0x%zx va = 0x%p\n", in imx_rproc_da_to_va()
522 struct device *dev = rproc->dev.parent; in imx_rproc_mem_alloc()
525 dev_dbg(dev, "map memory: %p+%zx\n", &mem->dma, mem->len); in imx_rproc_mem_alloc()
526 va = ioremap_wc(mem->dma, mem->len); in imx_rproc_mem_alloc()
529 &mem->dma, mem->len); in imx_rproc_mem_alloc()
530 return -ENOMEM; in imx_rproc_mem_alloc()
534 mem->va = va; in imx_rproc_mem_alloc()
542 dev_dbg(rproc->dev.parent, "unmap memory: %pa\n", &mem->dma); in imx_rproc_mem_release()
543 iounmap(mem->va); in imx_rproc_mem_release()
550 struct imx_rproc *priv = rproc->priv; in imx_rproc_prepare()
551 struct device_node *np = priv->dev->of_node; in imx_rproc_prepare()
558 of_phandle_iterator_init(&it, np, "memory-region", NULL, 0); in imx_rproc_prepare()
564 if (!strcmp(it.node->name, "vdev0buffer")) in imx_rproc_prepare()
567 if (!strcmp(it.node->name, "rsc-table")) in imx_rproc_prepare()
573 dev_err(priv->dev, "unable to acquire memory-region\n"); in imx_rproc_prepare()
574 return -EINVAL; in imx_rproc_prepare()
578 da = rmem->base; in imx_rproc_prepare()
581 mem = rproc_mem_entry_init(priv->dev, NULL, (dma_addr_t)rmem->base, rmem->size, da, in imx_rproc_prepare()
583 it.node->name); in imx_rproc_prepare()
586 rproc_coredump_add_segment(rproc, da, rmem->size); in imx_rproc_prepare()
589 return -ENOMEM; in imx_rproc_prepare()
604 dev_info(&rproc->dev, "No resource table in elf\n"); in imx_rproc_parse_fw()
611 struct imx_rproc *priv = rproc->priv; in imx_rproc_kick()
615 if (!priv->tx_ch) { in imx_rproc_kick()
616 dev_err(priv->dev, "No initialized mbox tx channel\n"); in imx_rproc_kick()
621 * Send the index of the triggered virtqueue as the mu payload. in imx_rproc_kick()
626 err = mbox_send_message(priv->tx_ch, (void *)&mmsg); in imx_rproc_kick()
628 dev_err(priv->dev, "%s: failed (%d, err:%d)\n", in imx_rproc_kick()
639 struct imx_rproc *priv = rproc->priv; in imx_rproc_detach()
640 const struct imx_rproc_dcfg *dcfg = priv->dcfg; in imx_rproc_detach()
642 if (dcfg->method != IMX_RPROC_SCU_API) in imx_rproc_detach()
643 return -EOPNOTSUPP; in imx_rproc_detach()
645 if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) in imx_rproc_detach()
646 return -EOPNOTSUPP; in imx_rproc_detach()
655 struct imx_rproc *priv = rproc->priv; in imx_rproc_get_loaded_rsc_table()
658 if (!priv->rsc_table) in imx_rproc_get_loaded_rsc_table()
662 return (struct resource_table *)priv->rsc_table; in imx_rproc_get_loaded_rsc_table()
668 struct imx_rproc *priv = rproc->priv; in imx_rproc_elf_find_loaded_rsc_table()
670 if (priv->rsc_table) in imx_rproc_elf_find_loaded_rsc_table()
671 return (struct resource_table *)priv->rsc_table; in imx_rproc_elf_find_loaded_rsc_table()
695 const struct imx_rproc_dcfg *dcfg = priv->dcfg; in imx_rproc_addr_init()
696 struct device *dev = &pdev->dev; in imx_rproc_addr_init()
697 struct device_node *np = dev->of_node; in imx_rproc_addr_init()
701 for (a = 0; a < dcfg->att_size; a++) { in imx_rproc_addr_init()
702 const struct imx_rproc_att *att = &dcfg->att[a]; in imx_rproc_addr_init()
704 if (!(att->flags & ATT_OWN)) in imx_rproc_addr_init()
710 if (att->flags & ATT_IOMEM) in imx_rproc_addr_init()
711 priv->mem[b].cpu_addr = devm_ioremap(&pdev->dev, in imx_rproc_addr_init()
712 att->sa, att->size); in imx_rproc_addr_init()
714 priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev, in imx_rproc_addr_init()
715 att->sa, att->size); in imx_rproc_addr_init()
716 if (!priv->mem[b].cpu_addr) { in imx_rproc_addr_init()
717 dev_err(dev, "failed to remap %#x bytes from %#x\n", att->size, att->sa); in imx_rproc_addr_init()
718 return -ENOMEM; in imx_rproc_addr_init()
720 priv->mem[b].sys_addr = att->sa; in imx_rproc_addr_init()
721 priv->mem[b].size = att->size; in imx_rproc_addr_init()
725 /* memory-region is optional property */ in imx_rproc_addr_init()
726 nph = of_count_phandle_with_args(np, "memory-region", NULL); in imx_rproc_addr_init()
735 node = of_parse_phandle(np, "memory-region", a); in imx_rproc_addr_init()
739 if (!strncmp(node->name, "vdev", strlen("vdev"))) { in imx_rproc_addr_init()
756 priv->mem[b].cpu_addr = devm_ioremap_wc(&pdev->dev, res.start, resource_size(&res)); in imx_rproc_addr_init()
757 if (!priv->mem[b].cpu_addr) { in imx_rproc_addr_init()
760 return -ENOMEM; in imx_rproc_addr_init()
762 priv->mem[b].sys_addr = res.start; in imx_rproc_addr_init()
763 priv->mem[b].size = resource_size(&res); in imx_rproc_addr_init()
764 if (!strcmp(node->name, "rsc-table")) in imx_rproc_addr_init()
765 priv->rsc_table = priv->mem[b].cpu_addr; in imx_rproc_addr_init()
786 struct rproc *rproc = priv->rproc; in imx_rproc_vq_work()
788 idr_for_each(&rproc->notifyids, imx_rproc_notified_idr_cb, rproc); in imx_rproc_vq_work()
793 struct rproc *rproc = dev_get_drvdata(cl->dev); in imx_rproc_rx_callback()
794 struct imx_rproc *priv = rproc->priv; in imx_rproc_rx_callback()
796 queue_work(priv->workqueue, &priv->rproc_work); in imx_rproc_rx_callback()
801 struct imx_rproc *priv = rproc->priv; in imx_rproc_xtr_mbox_init()
802 struct device *dev = priv->dev; in imx_rproc_xtr_mbox_init()
814 if (priv->tx_ch && priv->rx_ch) in imx_rproc_xtr_mbox_init()
817 if (!of_property_present(dev->of_node, "mbox-names")) in imx_rproc_xtr_mbox_init()
820 cl = &priv->cl; in imx_rproc_xtr_mbox_init()
821 cl->dev = dev; in imx_rproc_xtr_mbox_init()
822 cl->tx_block = tx_block; in imx_rproc_xtr_mbox_init()
823 cl->tx_tout = 100; in imx_rproc_xtr_mbox_init()
824 cl->knows_txdone = false; in imx_rproc_xtr_mbox_init()
825 cl->rx_callback = imx_rproc_rx_callback; in imx_rproc_xtr_mbox_init()
827 priv->tx_ch = mbox_request_channel_byname(cl, "tx"); in imx_rproc_xtr_mbox_init()
828 if (IS_ERR(priv->tx_ch)) in imx_rproc_xtr_mbox_init()
829 return dev_err_probe(cl->dev, PTR_ERR(priv->tx_ch), in imx_rproc_xtr_mbox_init()
832 priv->rx_ch = mbox_request_channel_byname(cl, "rx"); in imx_rproc_xtr_mbox_init()
833 if (IS_ERR(priv->rx_ch)) { in imx_rproc_xtr_mbox_init()
834 mbox_free_channel(priv->tx_ch); in imx_rproc_xtr_mbox_init()
835 return dev_err_probe(cl->dev, PTR_ERR(priv->rx_ch), in imx_rproc_xtr_mbox_init()
844 struct imx_rproc *priv = rproc->priv; in imx_rproc_free_mbox()
846 if (priv->tx_ch) { in imx_rproc_free_mbox()
847 mbox_free_channel(priv->tx_ch); in imx_rproc_free_mbox()
848 priv->tx_ch = NULL; in imx_rproc_free_mbox()
851 if (priv->rx_ch) { in imx_rproc_free_mbox()
852 mbox_free_channel(priv->rx_ch); in imx_rproc_free_mbox()
853 priv->rx_ch = NULL; in imx_rproc_free_mbox()
859 struct imx_rproc *priv = rproc->priv; in imx_rproc_put_scu()
860 const struct imx_rproc_dcfg *dcfg = priv->dcfg; in imx_rproc_put_scu()
862 if (dcfg->method != IMX_RPROC_SCU_API) in imx_rproc_put_scu()
865 if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) { in imx_rproc_put_scu()
866 dev_pm_domain_detach_list(priv->pd_list); in imx_rproc_put_scu()
870 imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED, BIT(priv->rproc_pt), false); in imx_rproc_put_scu()
871 imx_scu_irq_unregister_notifier(&priv->rproc_nb); in imx_rproc_put_scu()
880 if (!((event & BIT(priv->rproc_pt)) && (*(u8 *)group == IMX_SC_IRQ_GROUP_REBOOTED))) in imx_rproc_partition_notify()
883 rproc_report_crash(priv->rproc, RPROC_WATCHDOG); in imx_rproc_partition_notify()
885 pr_info("Partition%d reset!\n", priv->rproc_pt); in imx_rproc_partition_notify()
892 struct device *dev = priv->dev; in imx_rproc_attach_pd()
899 * If there is only one power-domain entry, the platform driver framework in imx_rproc_attach_pd()
902 if (dev->pm_domain) in imx_rproc_attach_pd()
905 ret = dev_pm_domain_attach_list(dev, &pd_data, &priv->pd_list); in imx_rproc_attach_pd()
911 struct regmap_config config = { .name = "imx-rproc" }; in imx_rproc_detect_mode()
912 const struct imx_rproc_dcfg *dcfg = priv->dcfg; in imx_rproc_detect_mode()
913 struct device *dev = priv->dev; in imx_rproc_detect_mode()
920 switch (dcfg->method) { in imx_rproc_detect_mode()
922 priv->rproc->state = RPROC_DETACHED; in imx_rproc_detect_mode()
927 priv->rproc->state = RPROC_DETACHED; in imx_rproc_detect_mode()
930 ret = imx_scu_get_handle(&priv->ipc_handle); in imx_rproc_detect_mode()
933 ret = of_property_read_u32(dev->of_node, "fsl,resource-id", &priv->rsrc_id); in imx_rproc_detect_mode()
935 dev_err(dev, "No fsl,resource-id property\n"); in imx_rproc_detect_mode()
939 if (priv->rsrc_id == IMX_SC_R_M4_1_PID0) in imx_rproc_detect_mode()
940 priv->core_index = 1; in imx_rproc_detect_mode()
942 priv->core_index = 0; in imx_rproc_detect_mode()
948 if (imx_sc_rm_is_resource_owned(priv->ipc_handle, priv->rsrc_id)) { in imx_rproc_detect_mode()
949 if (of_property_read_u32(dev->of_node, "fsl,entry-address", &priv->entry)) in imx_rproc_detect_mode()
950 return -EINVAL; in imx_rproc_detect_mode()
955 priv->rproc->state = RPROC_DETACHED; in imx_rproc_detect_mode()
956 priv->rproc->recovery_disabled = false; in imx_rproc_detect_mode()
957 rproc_set_feature(priv->rproc, RPROC_FEAT_ATTACH_ON_RECOVERY); in imx_rproc_detect_mode()
960 ret = imx_sc_rm_get_resource_owner(priv->ipc_handle, priv->rsrc_id, &pt); in imx_rproc_detect_mode()
966 priv->rproc_pt = pt; in imx_rproc_detect_mode()
967 priv->rproc_nb.notifier_call = imx_rproc_partition_notify; in imx_rproc_detect_mode()
969 ret = imx_scu_irq_register_notifier(&priv->rproc_nb); in imx_rproc_detect_mode()
975 ret = imx_scu_irq_group_enable(IMX_SC_IRQ_GROUP_REBOOTED, BIT(priv->rproc_pt), in imx_rproc_detect_mode()
978 imx_scu_irq_unregister_notifier(&priv->rproc_nb); in imx_rproc_detect_mode()
988 priv->gpr = syscon_regmap_lookup_by_phandle(dev->of_node, "fsl,iomuxc-gpr"); in imx_rproc_detect_mode()
989 if (IS_ERR(priv->gpr)) in imx_rproc_detect_mode()
990 priv->gpr = NULL; in imx_rproc_detect_mode()
992 regmap = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); in imx_rproc_detect_mode()
998 priv->regmap = regmap; in imx_rproc_detect_mode()
1001 if (priv->gpr) { in imx_rproc_detect_mode()
1002 ret = regmap_read(priv->gpr, dcfg->gpr_reg, &val); in imx_rproc_detect_mode()
1003 if (val & dcfg->gpr_wait) { in imx_rproc_detect_mode()
1009 imx_rproc_stop(priv->rproc); in imx_rproc_detect_mode()
1014 ret = regmap_read(regmap, dcfg->src_reg, &val); in imx_rproc_detect_mode()
1020 if ((val & dcfg->src_mask) != dcfg->src_stop) in imx_rproc_detect_mode()
1021 priv->rproc->state = RPROC_DETACHED; in imx_rproc_detect_mode()
1028 const struct imx_rproc_dcfg *dcfg = priv->dcfg; in imx_rproc_clk_enable()
1029 struct device *dev = priv->dev; in imx_rproc_clk_enable()
1033 if (dcfg->method == IMX_RPROC_NONE) in imx_rproc_clk_enable()
1036 priv->clk = devm_clk_get(dev, NULL); in imx_rproc_clk_enable()
1037 if (IS_ERR(priv->clk)) { in imx_rproc_clk_enable()
1039 return PTR_ERR(priv->clk); in imx_rproc_clk_enable()
1046 ret = clk_prepare_enable(priv->clk); in imx_rproc_clk_enable()
1057 struct rproc *rproc = data->cb_data; in imx_rproc_sys_off_handler()
1064 dev_err(&rproc->dev, "Failed to request non-blocking mbox\n"); in imx_rproc_sys_off_handler()
1073 struct device *dev = &pdev->dev; in imx_rproc_probe()
1074 struct device_node *np = dev->of_node; in imx_rproc_probe()
1081 rproc = devm_rproc_alloc(dev, "imx-rproc", &imx_rproc_ops, in imx_rproc_probe()
1084 return -ENOMEM; in imx_rproc_probe()
1088 return -EINVAL; in imx_rproc_probe()
1090 priv = rproc->priv; in imx_rproc_probe()
1091 priv->rproc = rproc; in imx_rproc_probe()
1092 priv->dcfg = dcfg; in imx_rproc_probe()
1093 priv->dev = dev; in imx_rproc_probe()
1096 priv->workqueue = create_workqueue(dev_name(dev)); in imx_rproc_probe()
1097 if (!priv->workqueue) { in imx_rproc_probe()
1099 return -ENOMEM; in imx_rproc_probe()
1102 INIT_WORK(&priv->rproc_work, imx_rproc_vq_work); in imx_rproc_probe()
1122 if (rproc->state != RPROC_DETACHED) in imx_rproc_probe()
1123 rproc->auto_boot = of_property_read_bool(np, "fsl,auto-boot"); in imx_rproc_probe()
1125 if (dcfg->flags & IMX_RPROC_NEED_SYSTEM_OFF) { in imx_rproc_probe()
1127 * setup mailbox to non-blocking mode in in imx_rproc_probe()
1158 clk_disable_unprepare(priv->clk); in imx_rproc_probe()
1164 destroy_workqueue(priv->workqueue); in imx_rproc_probe()
1172 struct imx_rproc *priv = rproc->priv; in imx_rproc_remove()
1174 clk_disable_unprepare(priv->clk); in imx_rproc_remove()
1178 destroy_workqueue(priv->workqueue); in imx_rproc_remove()
1182 { .compatible = "fsl,imx7ulp-cm4", .data = &imx_rproc_cfg_imx7ulp },
1183 { .compatible = "fsl,imx7d-cm4", .data = &imx_rproc_cfg_imx7d },
1184 { .compatible = "fsl,imx6sx-cm4", .data = &imx_rproc_cfg_imx6sx },
1185 { .compatible = "fsl,imx8mq-cm4", .data = &imx_rproc_cfg_imx8mq },
1186 { .compatible = "fsl,imx8mm-cm4", .data = &imx_rproc_cfg_imx8mq },
1187 { .compatible = "fsl,imx8mn-cm7", .data = &imx_rproc_cfg_imx8mn },
1188 { .compatible = "fsl,imx8mp-cm7", .data = &imx_rproc_cfg_imx8mn },
1189 { .compatible = "fsl,imx8mn-cm7-mmio", .data = &imx_rproc_cfg_imx8mn_mmio },
1190 { .compatible = "fsl,imx8mp-cm7-mmio", .data = &imx_rproc_cfg_imx8mn_mmio },
1191 { .compatible = "fsl,imx8qxp-cm4", .data = &imx_rproc_cfg_imx8qxp },
1192 { .compatible = "fsl,imx8qm-cm4", .data = &imx_rproc_cfg_imx8qm },
1193 { .compatible = "fsl,imx8ulp-cm33", .data = &imx_rproc_cfg_imx8ulp },
1194 { .compatible = "fsl,imx93-cm33", .data = &imx_rproc_cfg_imx93 },
1203 .name = "imx-rproc",