Lines Matching +full:mt2701 +full:- +full:larb +full:- +full:port

1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (c) 2015-2016 MediaTek Inc.
15 #include <linux/dma-mapping.h>
30 #include <asm/dma-iommu.h>
32 #include <dt-bindings/memory/mt2701-larb-port.h>
78 #define MT2701_M4U_TF_LARB(TF) (6 - (((TF) >> 13) & 0x7))
112 for (i = ARRAY_SIZE(mt2701_m4u_in_larb) - 1; i >= 0; i--) in mt2701_m4u_to_larb()
121 int larb = mt2701_m4u_to_larb(id); in mt2701_m4u_to_port() local
123 return id - mt2701_m4u_in_larb[larb]; in mt2701_m4u_to_port()
129 data->base + REG_MMU_INV_SEL); in mtk_iommu_tlb_flush_all()
130 writel_relaxed(F_ALL_INVLD, data->base + REG_MMU_INVALIDATE); in mtk_iommu_tlb_flush_all()
141 data->base + REG_MMU_INV_SEL); in mtk_iommu_tlb_flush_range()
143 data->base + REG_MMU_INVLD_START_A); in mtk_iommu_tlb_flush_range()
144 writel_relaxed((iova + size - 1) & F_MMU_FAULT_VA_MSK, in mtk_iommu_tlb_flush_range()
145 data->base + REG_MMU_INVLD_END_A); in mtk_iommu_tlb_flush_range()
146 writel_relaxed(F_MMU_INV_RANGE, data->base + REG_MMU_INVALIDATE); in mtk_iommu_tlb_flush_range()
148 ret = readl_poll_timeout_atomic(data->base + REG_MMU_CPE_DONE, in mtk_iommu_tlb_flush_range()
151 dev_warn(data->dev, in mtk_iommu_tlb_flush_range()
156 writel_relaxed(0, data->base + REG_MMU_CPE_DONE); in mtk_iommu_tlb_flush_range()
162 struct mtk_iommu_domain *dom = data->m4u_dom; in mtk_iommu_isr()
167 int_state = readl_relaxed(data->base + REG_MMU_FAULT_ST); in mtk_iommu_isr()
168 fault_iova = readl_relaxed(data->base + REG_MMU_FAULT_VA); in mtk_iommu_isr()
171 fault_pa = readl_relaxed(data->base + REG_MMU_INVLD_PA); in mtk_iommu_isr()
172 regval = readl_relaxed(data->base + REG_MMU_INT_ID); in mtk_iommu_isr()
180 if (report_iommu_fault(&dom->domain, data->dev, fault_iova, in mtk_iommu_isr()
182 dev_err_ratelimited(data->dev, in mtk_iommu_isr()
183 "fault type=0x%x iova=0x%x pa=0x%x larb=%d port=%d\n", in mtk_iommu_isr()
188 regval = readl_relaxed(data->base + REG_MMU_INT_CONTROL); in mtk_iommu_isr()
190 writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL); in mtk_iommu_isr()
205 for (i = 0; i < fwspec->num_ids; ++i) { in mtk_iommu_config()
206 larbid = mt2701_m4u_to_larb(fwspec->ids[i]); in mtk_iommu_config()
207 portid = mt2701_m4u_to_port(fwspec->ids[i]); in mtk_iommu_config()
208 larb_mmu = &data->larb_imu[larbid]; in mtk_iommu_config()
210 dev_dbg(dev, "%s iommu port: %d\n", in mtk_iommu_config()
214 larb_mmu->mmu |= MTK_SMI_MMU_EN(portid); in mtk_iommu_config()
216 larb_mmu->mmu &= ~MTK_SMI_MMU_EN(portid); in mtk_iommu_config()
222 struct mtk_iommu_domain *dom = data->m4u_dom; in mtk_iommu_domain_finalise()
224 spin_lock_init(&dom->pgtlock); in mtk_iommu_domain_finalise()
226 dom->pgt_va = dma_alloc_coherent(data->dev, M2701_IOMMU_PGT_SIZE, in mtk_iommu_domain_finalise()
227 &dom->pgt_pa, GFP_KERNEL); in mtk_iommu_domain_finalise()
228 if (!dom->pgt_va) in mtk_iommu_domain_finalise()
229 return -ENOMEM; in mtk_iommu_domain_finalise()
231 writel(dom->pgt_pa, data->base + REG_MMU_PT_BASE_ADDR); in mtk_iommu_domain_finalise()
233 dom->data = data; in mtk_iommu_domain_finalise()
249 return &dom->domain; in mtk_iommu_domain_alloc()
255 struct mtk_iommu_data *data = dom->data; in mtk_iommu_domain_free()
257 dma_free_coherent(data->dev, M2701_IOMMU_PGT_SIZE, in mtk_iommu_domain_free()
258 dom->pgt_va, dom->pgt_pa); in mtk_iommu_domain_free()
271 mtk_mapping = data->mapping; in mtk_iommu_attach_device()
272 if (mtk_mapping->domain != domain) in mtk_iommu_attach_device()
275 if (!data->m4u_dom) { in mtk_iommu_attach_device()
276 data->m4u_dom = dom; in mtk_iommu_attach_device()
279 data->m4u_dom = NULL; in mtk_iommu_attach_device()
303 u32 *pgt_base_iova = dom->pgt_va + (iova >> MT2701_IOMMU_PAGE_SHIFT); in mtk_iommu_map()
307 spin_lock_irqsave(&dom->pgtlock, flags); in mtk_iommu_map()
318 spin_unlock_irqrestore(&dom->pgtlock, flags); in mtk_iommu_map()
320 mtk_iommu_tlb_flush_range(dom->data, iova, size); in mtk_iommu_map()
322 return map_size == size ? 0 : -EEXIST; in mtk_iommu_map()
331 u32 *pgt_base_iova = dom->pgt_va + (iova >> MT2701_IOMMU_PAGE_SHIFT); in mtk_iommu_unmap()
334 spin_lock_irqsave(&dom->pgtlock, flags); in mtk_iommu_unmap()
336 spin_unlock_irqrestore(&dom->pgtlock, flags); in mtk_iommu_unmap()
338 mtk_iommu_tlb_flush_range(dom->data, iova, size); in mtk_iommu_unmap()
350 spin_lock_irqsave(&dom->pgtlock, flags); in mtk_iommu_iova_to_phys()
351 pa = *(dom->pgt_va + (iova >> MT2701_IOMMU_PAGE_SHIFT)); in mtk_iommu_iova_to_phys()
352 pa = pa & (~(MT2701_IOMMU_PAGE_SIZE - 1)); in mtk_iommu_iova_to_phys()
353 spin_unlock_irqrestore(&dom->pgtlock, flags); in mtk_iommu_iova_to_phys()
373 if (args->args_count != 1) { in mtk_iommu_create_mapping()
374 dev_err(dev, "invalid #iommu-cells(%d) property for IOMMU\n", in mtk_iommu_create_mapping()
375 args->args_count); in mtk_iommu_create_mapping()
376 return -EINVAL; in mtk_iommu_create_mapping()
380 ret = iommu_fwspec_init(dev, &args->np->fwnode, &mtk_iommu_ops); in mtk_iommu_create_mapping()
384 } else if (dev_iommu_fwspec_get(dev)->ops != &mtk_iommu_ops) { in mtk_iommu_create_mapping()
385 return -EINVAL; in mtk_iommu_create_mapping()
390 m4updev = of_find_device_by_node(args->np); in mtk_iommu_create_mapping()
392 return -EINVAL; in mtk_iommu_create_mapping()
397 ret = iommu_fwspec_add_ids(dev, args->args, 1); in mtk_iommu_create_mapping()
402 mtk_mapping = data->mapping; in mtk_iommu_create_mapping()
410 data->mapping = mtk_mapping; in mtk_iommu_create_mapping()
428 while (!of_parse_phandle_with_args(dev->of_node, "iommus", in mtk_iommu_probe_device()
429 "#iommu-cells", in mtk_iommu_probe_device()
437 /* dev->iommu_fwspec might have changed */ in mtk_iommu_probe_device()
442 if (!fwspec || fwspec->ops != &mtk_iommu_ops) in mtk_iommu_probe_device()
443 return ERR_PTR(-ENODEV); /* Not a iommu client device */ in mtk_iommu_probe_device()
447 return &data->iommu; in mtk_iommu_probe_device()
457 mtk_mapping = data->mapping; in mtk_iommu_probe_finalize()
461 dev_err(dev, "Can't create IOMMU mapping - DMA-OPS will not work\n"); in mtk_iommu_probe_finalize()
468 if (!fwspec || fwspec->ops != &mtk_iommu_ops) in mtk_iommu_release_device()
479 ret = clk_prepare_enable(data->bclk); in mtk_iommu_hw_init()
481 dev_err(data->dev, "Failed to enable iommu bclk(%d)\n", ret); in mtk_iommu_hw_init()
486 writel_relaxed(regval, data->base + REG_MMU_CTRL_REG); in mtk_iommu_hw_init()
496 writel_relaxed(regval, data->base + REG_MMU_INT_CONTROL); in mtk_iommu_hw_init()
499 writel_relaxed(data->protect_base, in mtk_iommu_hw_init()
500 data->base + REG_MMU_IVRP_PADDR); in mtk_iommu_hw_init()
502 writel_relaxed(F_MMU_DCM_ON, data->base + REG_MMU_DCM); in mtk_iommu_hw_init()
504 if (devm_request_irq(data->dev, data->irq, mtk_iommu_isr, 0, in mtk_iommu_hw_init()
505 dev_name(data->dev), (void *)data)) { in mtk_iommu_hw_init()
506 writel_relaxed(0, data->base + REG_MMU_PT_BASE_ADDR); in mtk_iommu_hw_init()
507 clk_disable_unprepare(data->bclk); in mtk_iommu_hw_init()
508 dev_err(data->dev, "Failed @ IRQ-%d Request\n", data->irq); in mtk_iommu_hw_init()
509 return -ENODEV; in mtk_iommu_hw_init()
533 { .compatible = "mediatek,mt2701-m4u", },
545 struct device *dev = &pdev->dev; in mtk_iommu_probe()
553 return -ENOMEM; in mtk_iommu_probe()
555 data->dev = dev; in mtk_iommu_probe()
561 return -ENOMEM; in mtk_iommu_probe()
562 data->protect_base = ALIGN(virt_to_phys(protect), MTK_PROTECT_PA_ALIGN); in mtk_iommu_probe()
565 data->base = devm_ioremap_resource(dev, res); in mtk_iommu_probe()
566 if (IS_ERR(data->base)) in mtk_iommu_probe()
567 return PTR_ERR(data->base); in mtk_iommu_probe()
569 data->irq = platform_get_irq(pdev, 0); in mtk_iommu_probe()
570 if (data->irq < 0) in mtk_iommu_probe()
571 return data->irq; in mtk_iommu_probe()
573 data->bclk = devm_clk_get(dev, "bclk"); in mtk_iommu_probe()
574 if (IS_ERR(data->bclk)) in mtk_iommu_probe()
575 return PTR_ERR(data->bclk); in mtk_iommu_probe()
577 larb_nr = of_count_phandle_with_args(dev->of_node, in mtk_iommu_probe()
586 larbnode = of_parse_phandle(dev->of_node, "mediatek,larbs", i); in mtk_iommu_probe()
588 return -EINVAL; in mtk_iommu_probe()
598 return -EPROBE_DEFER; in mtk_iommu_probe()
600 data->larb_imu[i].dev = &plarbdev->dev; in mtk_iommu_probe()
612 ret = iommu_device_sysfs_add(&data->iommu, &pdev->dev, NULL, in mtk_iommu_probe()
613 dev_name(&pdev->dev)); in mtk_iommu_probe()
617 ret = iommu_device_register(&data->iommu, &mtk_iommu_ops, dev); in mtk_iommu_probe()
635 iommu_device_unregister(&data->iommu); in mtk_iommu_probe()
637 iommu_device_sysfs_remove(&data->iommu); in mtk_iommu_probe()
645 iommu_device_sysfs_remove(&data->iommu); in mtk_iommu_remove()
646 iommu_device_unregister(&data->iommu); in mtk_iommu_remove()
651 clk_disable_unprepare(data->bclk); in mtk_iommu_remove()
652 devm_free_irq(&pdev->dev, data->irq, data); in mtk_iommu_remove()
653 component_master_del(&pdev->dev, &mtk_iommu_com_ops); in mtk_iommu_remove()
660 struct mtk_iommu_suspend_reg *reg = &data->reg; in mtk_iommu_suspend()
661 void __iomem *base = data->base; in mtk_iommu_suspend()
663 reg->standard_axi_mode = readl_relaxed(base + in mtk_iommu_suspend()
665 reg->dcm_dis = readl_relaxed(base + REG_MMU_DCM); in mtk_iommu_suspend()
666 reg->ctrl_reg = readl_relaxed(base + REG_MMU_CTRL_REG); in mtk_iommu_suspend()
667 reg->int_control0 = readl_relaxed(base + REG_MMU_INT_CONTROL); in mtk_iommu_suspend()
674 struct mtk_iommu_suspend_reg *reg = &data->reg; in mtk_iommu_resume()
675 void __iomem *base = data->base; in mtk_iommu_resume()
677 writel_relaxed(data->m4u_dom->pgt_pa, base + REG_MMU_PT_BASE_ADDR); in mtk_iommu_resume()
678 writel_relaxed(reg->standard_axi_mode, in mtk_iommu_resume()
680 writel_relaxed(reg->dcm_dis, base + REG_MMU_DCM); in mtk_iommu_resume()
681 writel_relaxed(reg->ctrl_reg, base + REG_MMU_CTRL_REG); in mtk_iommu_resume()
682 writel_relaxed(reg->int_control0, base + REG_MMU_INT_CONTROL); in mtk_iommu_resume()
683 writel_relaxed(data->protect_base, base + REG_MMU_IVRP_PADDR); in mtk_iommu_resume()
695 .name = "mtk-iommu-v1",