Lines Matching +full:syscon +full:- +full:sa +full:- +full:cfg
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2015-2016 MediaTek Inc.
10 #include <linux/dma-iommu.h>
17 #include <linux/mfd/syscon.h>
63 #define F_MMU_VLD_PA_RNG(EA, SA) (((EA) << 8) | (SA)) argument
124 ((((pdata)->flags) & (_x)) == (_x))
127 struct io_pgtable_cfg cfg; member
142 * |---A---|---B---|---C---|---D---|---E---|
143 * +--I/O--+------------Memory-------------+
149 * |---E---|---B---|---C---|---D---|
150 * +------------Memory-------------+
191 data->base + data->plat_data->inv_sel_reg); in mtk_iommu_tlb_flush_all()
192 writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE); in mtk_iommu_tlb_flush_all()
206 spin_lock_irqsave(&data->tlb_lock, flags); in mtk_iommu_tlb_flush_range_sync()
208 data->base + data->plat_data->inv_sel_reg); in mtk_iommu_tlb_flush_range_sync()
210 writel_relaxed(iova, data->base + REG_MMU_INVLD_START_A); in mtk_iommu_tlb_flush_range_sync()
211 writel_relaxed(iova + size - 1, in mtk_iommu_tlb_flush_range_sync()
212 data->base + REG_MMU_INVLD_END_A); in mtk_iommu_tlb_flush_range_sync()
214 data->base + REG_MMU_INVALIDATE); in mtk_iommu_tlb_flush_range_sync()
217 ret = readl_poll_timeout_atomic(data->base + REG_MMU_CPE_DONE, in mtk_iommu_tlb_flush_range_sync()
220 dev_warn(data->dev, in mtk_iommu_tlb_flush_range_sync()
225 writel_relaxed(0, data->base + REG_MMU_CPE_DONE); in mtk_iommu_tlb_flush_range_sync()
226 spin_unlock_irqrestore(&data->tlb_lock, flags); in mtk_iommu_tlb_flush_range_sync()
235 struct iommu_domain *domain = &data->m4u_dom->domain; in mtk_iommu_tlb_flush_page_nosync()
250 struct mtk_iommu_domain *dom = data->m4u_dom; in mtk_iommu_isr()
256 int_state = readl_relaxed(data->base + REG_MMU_FAULT_ST1); in mtk_iommu_isr()
258 regval = readl_relaxed(data->base + REG_MMU0_INT_ID); in mtk_iommu_isr()
259 fault_iova = readl_relaxed(data->base + REG_MMU0_FAULT_VA); in mtk_iommu_isr()
260 fault_pa = readl_relaxed(data->base + REG_MMU0_INVLD_PA); in mtk_iommu_isr()
262 regval = readl_relaxed(data->base + REG_MMU1_INT_ID); in mtk_iommu_isr()
263 fault_iova = readl_relaxed(data->base + REG_MMU1_FAULT_VA); in mtk_iommu_isr()
264 fault_pa = readl_relaxed(data->base + REG_MMU1_INVLD_PA); in mtk_iommu_isr()
269 if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_SUB_COMM)) { in mtk_iommu_isr()
275 fault_larb = data->plat_data->larbid_remap[fault_larb][sub_comm]; in mtk_iommu_isr()
277 if (report_iommu_fault(&dom->domain, data->dev, fault_iova, in mtk_iommu_isr()
280 data->dev, in mtk_iommu_isr()
287 regval = readl_relaxed(data->base + REG_MMU_INT_CONTROL0); in mtk_iommu_isr()
289 writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0); in mtk_iommu_isr()
304 for (i = 0; i < fwspec->num_ids; ++i) { in mtk_iommu_config()
305 larbid = MTK_M4U_TO_LARB(fwspec->ids[i]); in mtk_iommu_config()
306 portid = MTK_M4U_TO_PORT(fwspec->ids[i]); in mtk_iommu_config()
307 larb_mmu = &data->larb_imu[larbid]; in mtk_iommu_config()
313 larb_mmu->mmu |= MTK_SMI_MMU_EN(portid); in mtk_iommu_config()
315 larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid); in mtk_iommu_config()
323 dom->cfg = (struct io_pgtable_cfg) { in mtk_iommu_domain_finalise()
332 .iommu_dev = data->dev, in mtk_iommu_domain_finalise()
335 dom->iop = alloc_io_pgtable_ops(ARM_V7S, &dom->cfg, data); in mtk_iommu_domain_finalise()
336 if (!dom->iop) { in mtk_iommu_domain_finalise()
337 dev_err(data->dev, "Failed to alloc io pgtable\n"); in mtk_iommu_domain_finalise()
338 return -EINVAL; in mtk_iommu_domain_finalise()
342 dom->domain.pgsize_bitmap = dom->cfg.pgsize_bitmap; in mtk_iommu_domain_finalise()
357 if (iommu_get_dma_cookie(&dom->domain)) in mtk_iommu_domain_alloc()
363 dom->domain.geometry.aperture_start = 0; in mtk_iommu_domain_alloc()
364 dom->domain.geometry.aperture_end = DMA_BIT_MASK(32); in mtk_iommu_domain_alloc()
365 dom->domain.geometry.force_aperture = true; in mtk_iommu_domain_alloc()
367 return &dom->domain; in mtk_iommu_domain_alloc()
370 iommu_put_dma_cookie(&dom->domain); in mtk_iommu_domain_alloc()
380 free_io_pgtable_ops(dom->iop); in mtk_iommu_domain_free()
392 return -ENODEV; in mtk_iommu_attach_device()
395 if (!data->m4u_dom) { in mtk_iommu_attach_device()
396 data->m4u_dom = dom; in mtk_iommu_attach_device()
397 writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, in mtk_iommu_attach_device()
398 data->base + REG_MMU_PT_BASE_ADDR); in mtk_iommu_attach_device()
423 if (data->enable_4GB) in mtk_iommu_map()
427 return dom->iop->map(dom->iop, iova, paddr, size, prot, gfp); in mtk_iommu_map()
436 return dom->iop->unmap(dom->iop, iova, size, gather); in mtk_iommu_unmap()
448 size_t length = gather->end - gather->start + 1; in mtk_iommu_iotlb_sync()
450 if (gather->start == ULONG_MAX) in mtk_iommu_iotlb_sync()
453 mtk_iommu_tlb_flush_range_sync(gather->start, length, gather->pgsize, in mtk_iommu_iotlb_sync()
464 pa = dom->iop->iova_to_phys(dom->iop, iova); in mtk_iommu_iova_to_phys()
465 if (data->enable_4GB && pa >= MTK_IOMMU_4GB_MODE_REMAP_BASE) in mtk_iommu_iova_to_phys()
476 if (!fwspec || fwspec->ops != &mtk_iommu_ops) in mtk_iommu_probe_device()
477 return ERR_PTR(-ENODEV); /* Not a iommu client device */ in mtk_iommu_probe_device()
481 return &data->iommu; in mtk_iommu_probe_device()
488 if (!fwspec || fwspec->ops != &mtk_iommu_ops) in mtk_iommu_release_device()
499 return ERR_PTR(-ENODEV); in mtk_iommu_device_group()
501 /* All the client devices are in the same m4u iommu-group */ in mtk_iommu_device_group()
502 if (!data->m4u_group) { in mtk_iommu_device_group()
503 data->m4u_group = iommu_group_alloc(); in mtk_iommu_device_group()
504 if (IS_ERR(data->m4u_group)) in mtk_iommu_device_group()
507 iommu_group_ref_get(data->m4u_group); in mtk_iommu_device_group()
509 return data->m4u_group; in mtk_iommu_device_group()
516 if (args->args_count != 1) { in mtk_iommu_of_xlate()
517 dev_err(dev, "invalid #iommu-cells(%d) property for IOMMU\n", in mtk_iommu_of_xlate()
518 args->args_count); in mtk_iommu_of_xlate()
519 return -EINVAL; in mtk_iommu_of_xlate()
524 m4updev = of_find_device_by_node(args->np); in mtk_iommu_of_xlate()
526 return -EINVAL; in mtk_iommu_of_xlate()
531 return iommu_fwspec_add_ids(dev, args->args, 1); in mtk_iommu_of_xlate()
556 ret = clk_prepare_enable(data->bclk); in mtk_iommu_hw_init()
558 dev_err(data->dev, "Failed to enable iommu bclk(%d)\n", ret); in mtk_iommu_hw_init()
562 if (data->plat_data->m4u_plat == M4U_MT8173) { in mtk_iommu_hw_init()
566 regval = readl_relaxed(data->base + REG_MMU_CTRL_REG); in mtk_iommu_hw_init()
569 writel_relaxed(regval, data->base + REG_MMU_CTRL_REG); in mtk_iommu_hw_init()
577 writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL0); in mtk_iommu_hw_init()
586 writel_relaxed(regval, data->base + REG_MMU_INT_MAIN_CONTROL); in mtk_iommu_hw_init()
588 if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_LEGACY_IVRP_PADDR)) in mtk_iommu_hw_init()
589 regval = (data->protect_base >> 1) | (data->enable_4GB << 31); in mtk_iommu_hw_init()
591 regval = lower_32_bits(data->protect_base) | in mtk_iommu_hw_init()
592 upper_32_bits(data->protect_base); in mtk_iommu_hw_init()
593 writel_relaxed(regval, data->base + REG_MMU_IVRP_PADDR); in mtk_iommu_hw_init()
595 if (data->enable_4GB && in mtk_iommu_hw_init()
596 MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_VLD_PA_RNG)) { in mtk_iommu_hw_init()
602 writel_relaxed(regval, data->base + REG_MMU_VLD_PA_RNG); in mtk_iommu_hw_init()
604 writel_relaxed(0, data->base + REG_MMU_DCM_DIS); in mtk_iommu_hw_init()
605 if (MTK_IOMMU_HAS_FLAG(data->plat_data, WR_THROT_EN)) { in mtk_iommu_hw_init()
607 regval = readl_relaxed(data->base + REG_MMU_WR_LEN_CTRL); in mtk_iommu_hw_init()
609 writel_relaxed(regval, data->base + REG_MMU_WR_LEN_CTRL); in mtk_iommu_hw_init()
612 if (MTK_IOMMU_HAS_FLAG(data->plat_data, RESET_AXI)) { in mtk_iommu_hw_init()
616 regval = readl_relaxed(data->base + REG_MMU_MISC_CTRL); in mtk_iommu_hw_init()
618 if (MTK_IOMMU_HAS_FLAG(data->plat_data, OUT_ORDER_WR_EN)) in mtk_iommu_hw_init()
621 writel_relaxed(regval, data->base + REG_MMU_MISC_CTRL); in mtk_iommu_hw_init()
623 if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0, in mtk_iommu_hw_init()
624 dev_name(data->dev), (void *)data)) { in mtk_iommu_hw_init()
625 writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR); in mtk_iommu_hw_init()
626 clk_disable_unprepare(data->bclk); in mtk_iommu_hw_init()
627 dev_err(data->dev, "Failed @ IRQ-%d Request\n", data->irq); in mtk_iommu_hw_init()
628 return -ENODEV; in mtk_iommu_hw_init()
642 struct device *dev = &pdev->dev; in mtk_iommu_probe()
654 return -ENOMEM; in mtk_iommu_probe()
655 data->dev = dev; in mtk_iommu_probe()
656 data->plat_data = of_device_get_match_data(dev); in mtk_iommu_probe()
661 return -ENOMEM; in mtk_iommu_probe()
662 data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN); in mtk_iommu_probe()
664 if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_4GB_MODE)) { in mtk_iommu_probe()
665 switch (data->plat_data->m4u_plat) { in mtk_iommu_probe()
667 p = "mediatek,mt2712-infracfg"; in mtk_iommu_probe()
670 p = "mediatek,mt8173-infracfg"; in mtk_iommu_probe()
684 data->enable_4GB = !!(val & F_DDR_4GB_SUPPORT_EN); in mtk_iommu_probe()
688 data->base = devm_ioremap_resource(dev, res); in mtk_iommu_probe()
689 if (IS_ERR(data->base)) in mtk_iommu_probe()
690 return PTR_ERR(data->base); in mtk_iommu_probe()
691 ioaddr = res->start; in mtk_iommu_probe()
693 data->irq = platform_get_irq(pdev, 0); in mtk_iommu_probe()
694 if (data->irq < 0) in mtk_iommu_probe()
695 return data->irq; in mtk_iommu_probe()
697 if (MTK_IOMMU_HAS_FLAG(data->plat_data, HAS_BCLK)) { in mtk_iommu_probe()
698 data->bclk = devm_clk_get(dev, "bclk"); in mtk_iommu_probe()
699 if (IS_ERR(data->bclk)) in mtk_iommu_probe()
700 return PTR_ERR(data->bclk); in mtk_iommu_probe()
703 larb_nr = of_count_phandle_with_args(dev->of_node, in mtk_iommu_probe()
713 larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i); in mtk_iommu_probe()
715 return -EINVAL; in mtk_iommu_probe()
722 ret = of_property_read_u32(larbnode, "mediatek,larb-id", &id); in mtk_iommu_probe()
729 return -EPROBE_DEFER; in mtk_iommu_probe()
731 data->larb_imu[id].dev = &plarbdev->dev; in mtk_iommu_probe()
743 ret = iommu_device_sysfs_add(&data->iommu, dev, NULL, in mtk_iommu_probe()
744 "mtk-iommu.%pa", &ioaddr); in mtk_iommu_probe()
748 iommu_device_set_ops(&data->iommu, &mtk_iommu_ops); in mtk_iommu_probe()
749 iommu_device_set_fwnode(&data->iommu, &pdev->dev.of_node->fwnode); in mtk_iommu_probe()
751 ret = iommu_device_register(&data->iommu); in mtk_iommu_probe()
755 spin_lock_init(&data->tlb_lock); in mtk_iommu_probe()
756 list_add_tail(&data->list, &m4ulist); in mtk_iommu_probe()
768 iommu_device_sysfs_remove(&data->iommu); in mtk_iommu_remove()
769 iommu_device_unregister(&data->iommu); in mtk_iommu_remove()
771 list_del(&data->list); in mtk_iommu_remove()
773 clk_disable_unprepare(data->bclk); in mtk_iommu_remove()
774 devm_free_irq(&pdev->dev, data->irq, data); in mtk_iommu_remove()
775 component_master_del(&pdev->dev, &mtk_iommu_com_ops); in mtk_iommu_remove()
782 struct mtk_iommu_suspend_reg *reg = &data->reg; in mtk_iommu_suspend()
783 void __iomem *base = data->base; in mtk_iommu_suspend()
785 reg->wr_len_ctrl = readl_relaxed(base + REG_MMU_WR_LEN_CTRL); in mtk_iommu_suspend()
786 reg->misc_ctrl = readl_relaxed(base + REG_MMU_MISC_CTRL); in mtk_iommu_suspend()
787 reg->dcm_dis = readl_relaxed(base + REG_MMU_DCM_DIS); in mtk_iommu_suspend()
788 reg->ctrl_reg = readl_relaxed(base + REG_MMU_CTRL_REG); in mtk_iommu_suspend()
789 reg->int_control0 = readl_relaxed(base + REG_MMU_INT_CONTROL0); in mtk_iommu_suspend()
790 reg->int_main_control = readl_relaxed(base + REG_MMU_INT_MAIN_CONTROL); in mtk_iommu_suspend()
791 reg->ivrp_paddr = readl_relaxed(base + REG_MMU_IVRP_PADDR); in mtk_iommu_suspend()
792 reg->vld_pa_rng = readl_relaxed(base + REG_MMU_VLD_PA_RNG); in mtk_iommu_suspend()
793 clk_disable_unprepare(data->bclk); in mtk_iommu_suspend()
800 struct mtk_iommu_suspend_reg *reg = &data->reg; in mtk_iommu_resume()
801 struct mtk_iommu_domain *m4u_dom = data->m4u_dom; in mtk_iommu_resume()
802 void __iomem *base = data->base; in mtk_iommu_resume()
805 ret = clk_prepare_enable(data->bclk); in mtk_iommu_resume()
807 dev_err(data->dev, "Failed to enable clk(%d) in resume\n", ret); in mtk_iommu_resume()
810 writel_relaxed(reg->wr_len_ctrl, base + REG_MMU_WR_LEN_CTRL); in mtk_iommu_resume()
811 writel_relaxed(reg->misc_ctrl, base + REG_MMU_MISC_CTRL); in mtk_iommu_resume()
812 writel_relaxed(reg->dcm_dis, base + REG_MMU_DCM_DIS); in mtk_iommu_resume()
813 writel_relaxed(reg->ctrl_reg, base + REG_MMU_CTRL_REG); in mtk_iommu_resume()
814 writel_relaxed(reg->int_control0, base + REG_MMU_INT_CONTROL0); in mtk_iommu_resume()
815 writel_relaxed(reg->int_main_control, base + REG_MMU_INT_MAIN_CONTROL); in mtk_iommu_resume()
816 writel_relaxed(reg->ivrp_paddr, base + REG_MMU_IVRP_PADDR); in mtk_iommu_resume()
817 writel_relaxed(reg->vld_pa_rng, base + REG_MMU_VLD_PA_RNG); in mtk_iommu_resume()
819 writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK, in mtk_iommu_resume()
865 { .compatible = "mediatek,mt2712-m4u", .data = &mt2712_data},
866 { .compatible = "mediatek,mt6779-m4u", .data = &mt6779_data},
867 { .compatible = "mediatek,mt8167-m4u", .data = &mt8167_data},
868 { .compatible = "mediatek,mt8173-m4u", .data = &mt8173_data},
869 { .compatible = "mediatek,mt8183-m4u", .data = &mt8183_data},
877 .name = "mtk-iommu",