Lines Matching +full:smmu +full:- +full:v2
1 /* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
15 * 02110-1301, USA.
36 #include "msm_iommu_hw-8xxx.h"
38 #include "io-pgtable.h"
70 ret = clk_enable(iommu->pclk); in __enable_clocks()
74 if (iommu->clk) { in __enable_clocks()
75 ret = clk_enable(iommu->clk); in __enable_clocks()
77 clk_disable(iommu->pclk); in __enable_clocks()
85 if (iommu->clk) in __disable_clocks()
86 clk_disable(iommu->clk); in __disable_clocks()
87 clk_disable(iommu->pclk); in __disable_clocks()
136 list_for_each_entry(iommu, &priv->list_attached, dom_node) { in __flush_iotlb()
141 list_for_each_entry(master, &iommu->ctx_list, list) in __flush_iotlb()
142 SET_CTX_TLBIALL(iommu->base, master->num, 0); in __flush_iotlb()
159 list_for_each_entry(iommu, &priv->list_attached, dom_node) { in __flush_iotlb_range()
164 list_for_each_entry(master, &iommu->ctx_list, list) { in __flush_iotlb_range()
168 iova |= GET_CONTEXTIDR_ASID(iommu->base, in __flush_iotlb_range()
169 master->num); in __flush_iotlb_range()
170 SET_TLBIVA(iommu->base, master->num, iova); in __flush_iotlb_range()
172 } while (temp_size -= granule); in __flush_iotlb_range()
205 return -ENOSPC; in msm_iommu_alloc_ctx()
221 for (i = 0; i < master->num_mids; i++) { in config_mids()
222 mid = master->mids[i]; in config_mids()
223 ctx = master->num; in config_mids()
225 SET_M2VCBR_N(iommu->base, mid, 0); in config_mids()
226 SET_CBACR_N(iommu->base, ctx, 0); in config_mids()
229 SET_VMID(iommu->base, mid, 0); in config_mids()
232 SET_CBNDX(iommu->base, mid, ctx); in config_mids()
235 SET_CBVMID(iommu->base, ctx, 0); in config_mids()
238 SET_CONTEXTIDR_ASID(iommu->base, ctx, ctx); in config_mids()
240 /* Set security bit override to be Non-secure */ in config_mids()
241 SET_NSCFG(iommu->base, mid, 3); in config_mids()
283 SET_TTBCR(base, ctx, priv->cfg.arm_v7s_cfg.tcr); in __program_context()
284 SET_TTBR0(base, ctx, priv->cfg.arm_v7s_cfg.ttbr[0]); in __program_context()
285 SET_TTBR1(base, ctx, priv->cfg.arm_v7s_cfg.ttbr[1]); in __program_context()
288 SET_PRRR(base, ctx, priv->cfg.arm_v7s_cfg.prrr); in __program_context()
289 SET_NMRR(base, ctx, priv->cfg.arm_v7s_cfg.nmrr); in __program_context()
326 INIT_LIST_HEAD(&priv->list_attached); in msm_iommu_domain_alloc()
328 priv->domain.geometry.aperture_start = 0; in msm_iommu_domain_alloc()
329 priv->domain.geometry.aperture_end = (1ULL << 32) - 1; in msm_iommu_domain_alloc()
330 priv->domain.geometry.force_aperture = true; in msm_iommu_domain_alloc()
332 return &priv->domain; in msm_iommu_domain_alloc()
352 spin_lock_init(&priv->pgtlock); in msm_iommu_domain_config()
354 priv->cfg = (struct io_pgtable_cfg) { in msm_iommu_domain_config()
360 .iommu_dev = priv->dev, in msm_iommu_domain_config()
363 priv->iop = alloc_io_pgtable_ops(ARM_V7S, &priv->cfg, priv); in msm_iommu_domain_config()
364 if (!priv->iop) { in msm_iommu_domain_config()
365 dev_err(priv->dev, "Failed to allocate pgtable\n"); in msm_iommu_domain_config()
366 return -EINVAL; in msm_iommu_domain_config()
369 msm_iommu_ops.pgsize_bitmap = priv->cfg.pgsize_bitmap; in msm_iommu_domain_config()
381 master = list_first_entry(&iommu->ctx_list, in find_iommu_for_dev()
384 if (master->of_node == dev->of_node) { in find_iommu_for_dev()
404 iommu_device_link(&iommu->iommu, dev); in msm_iommu_add_device()
406 return -ENODEV; in msm_iommu_add_device()
427 iommu_device_unlink(&iommu->iommu, dev); in msm_iommu_remove_device()
440 priv->dev = dev; in msm_iommu_attach_dev()
445 master = list_first_entry(&iommu->ctx_list, in msm_iommu_attach_dev()
448 if (master->of_node == dev->of_node) { in msm_iommu_attach_dev()
453 list_for_each_entry(master, &iommu->ctx_list, list) { in msm_iommu_attach_dev()
454 if (master->num) { in msm_iommu_attach_dev()
456 ret = -EEXIST; in msm_iommu_attach_dev()
459 master->num = in msm_iommu_attach_dev()
460 msm_iommu_alloc_ctx(iommu->context_map, in msm_iommu_attach_dev()
461 0, iommu->ncb); in msm_iommu_attach_dev()
462 if (IS_ERR_VALUE(master->num)) { in msm_iommu_attach_dev()
463 ret = -ENODEV; in msm_iommu_attach_dev()
467 __program_context(iommu->base, master->num, in msm_iommu_attach_dev()
471 list_add(&iommu->dom_node, &priv->list_attached); in msm_iommu_attach_dev()
490 free_io_pgtable_ops(priv->iop); in msm_iommu_detach_dev()
493 list_for_each_entry(iommu, &priv->list_attached, dom_node) { in msm_iommu_detach_dev()
498 list_for_each_entry(master, &iommu->ctx_list, list) { in msm_iommu_detach_dev()
499 msm_iommu_free_ctx(iommu->context_map, master->num); in msm_iommu_detach_dev()
500 __reset_context(iommu->base, master->num); in msm_iommu_detach_dev()
515 spin_lock_irqsave(&priv->pgtlock, flags); in msm_iommu_map()
516 ret = priv->iop->map(priv->iop, iova, pa, len, prot); in msm_iommu_map()
517 spin_unlock_irqrestore(&priv->pgtlock, flags); in msm_iommu_map()
528 spin_lock_irqsave(&priv->pgtlock, flags); in msm_iommu_unmap()
529 len = priv->iop->unmap(priv->iop, iova, len); in msm_iommu_unmap()
530 spin_unlock_irqrestore(&priv->pgtlock, flags); in msm_iommu_unmap()
548 iommu = list_first_entry(&priv->list_attached, in msm_iommu_iova_to_phys()
551 if (list_empty(&iommu->ctx_list)) in msm_iommu_iova_to_phys()
554 master = list_first_entry(&iommu->ctx_list, in msm_iommu_iova_to_phys()
564 SET_CTX_TLBIALL(iommu->base, master->num, 0); in msm_iommu_iova_to_phys()
565 SET_V2PPR(iommu->base, master->num, va & V2Pxx_VA); in msm_iommu_iova_to_phys()
567 par = GET_PAR(iommu->base, master->num); in msm_iommu_iova_to_phys()
570 if (GET_NOFAULT_SS(iommu->base, master->num)) in msm_iommu_iova_to_phys()
575 if (GET_FAULT(iommu->base, master->num)) in msm_iommu_iova_to_phys()
618 struct msm_iommu_ctx_dev *master = dev->archdata.iommu; in insert_iommu_master()
621 if (list_empty(&(*iommu)->ctx_list)) { in insert_iommu_master()
623 master->of_node = dev->of_node; in insert_iommu_master()
624 list_add(&master->list, &(*iommu)->ctx_list); in insert_iommu_master()
625 dev->archdata.iommu = master; in insert_iommu_master()
628 for (sid = 0; sid < master->num_mids; sid++) in insert_iommu_master()
629 if (master->mids[sid] == spec->args[0]) { in insert_iommu_master()
635 master->mids[master->num_mids++] = spec->args[0]; in insert_iommu_master()
647 if (iommu->dev->of_node == spec->np) in qcom_iommu_of_xlate()
650 if (!iommu || iommu->dev->of_node != spec->np) { in qcom_iommu_of_xlate()
651 ret = -ENODEV; in qcom_iommu_of_xlate()
676 pr_err("base = %08x\n", (unsigned int)iommu->base); in msm_iommu_fault_handler()
682 for (i = 0; i < iommu->ncb; i++) { in msm_iommu_fault_handler()
683 fsr = GET_FSR(iommu->base, i); in msm_iommu_fault_handler()
687 print_ctx_regs(iommu->base, i); in msm_iommu_fault_handler()
688 SET_FSR(iommu->base, i, 0x4000000F); in msm_iommu_fault_handler()
720 iommu = devm_kzalloc(&pdev->dev, sizeof(*iommu), GFP_KERNEL); in msm_iommu_probe()
722 return -ENODEV; in msm_iommu_probe()
724 iommu->dev = &pdev->dev; in msm_iommu_probe()
725 INIT_LIST_HEAD(&iommu->ctx_list); in msm_iommu_probe()
727 iommu->pclk = devm_clk_get(iommu->dev, "smmu_pclk"); in msm_iommu_probe()
728 if (IS_ERR(iommu->pclk)) { in msm_iommu_probe()
729 dev_err(iommu->dev, "could not get smmu_pclk\n"); in msm_iommu_probe()
730 return PTR_ERR(iommu->pclk); in msm_iommu_probe()
733 ret = clk_prepare(iommu->pclk); in msm_iommu_probe()
735 dev_err(iommu->dev, "could not prepare smmu_pclk\n"); in msm_iommu_probe()
739 iommu->clk = devm_clk_get(iommu->dev, "iommu_clk"); in msm_iommu_probe()
740 if (IS_ERR(iommu->clk)) { in msm_iommu_probe()
741 dev_err(iommu->dev, "could not get iommu_clk\n"); in msm_iommu_probe()
742 clk_unprepare(iommu->pclk); in msm_iommu_probe()
743 return PTR_ERR(iommu->clk); in msm_iommu_probe()
746 ret = clk_prepare(iommu->clk); in msm_iommu_probe()
748 dev_err(iommu->dev, "could not prepare iommu_clk\n"); in msm_iommu_probe()
749 clk_unprepare(iommu->pclk); in msm_iommu_probe()
754 iommu->base = devm_ioremap_resource(iommu->dev, r); in msm_iommu_probe()
755 if (IS_ERR(iommu->base)) { in msm_iommu_probe()
756 dev_err(iommu->dev, "could not get iommu base\n"); in msm_iommu_probe()
757 ret = PTR_ERR(iommu->base); in msm_iommu_probe()
760 ioaddr = r->start; in msm_iommu_probe()
762 iommu->irq = platform_get_irq(pdev, 0); in msm_iommu_probe()
763 if (iommu->irq < 0) { in msm_iommu_probe()
764 dev_err(iommu->dev, "could not get iommu irq\n"); in msm_iommu_probe()
765 ret = -ENODEV; in msm_iommu_probe()
769 ret = of_property_read_u32(iommu->dev->of_node, "qcom,ncb", &val); in msm_iommu_probe()
771 dev_err(iommu->dev, "could not get ncb\n"); in msm_iommu_probe()
774 iommu->ncb = val; in msm_iommu_probe()
776 msm_iommu_reset(iommu->base, iommu->ncb); in msm_iommu_probe()
777 SET_M(iommu->base, 0, 1); in msm_iommu_probe()
778 SET_PAR(iommu->base, 0, 0); in msm_iommu_probe()
779 SET_V2PCFG(iommu->base, 0, 1); in msm_iommu_probe()
780 SET_V2PPR(iommu->base, 0, 0); in msm_iommu_probe()
781 par = GET_PAR(iommu->base, 0); in msm_iommu_probe()
782 SET_V2PCFG(iommu->base, 0, 0); in msm_iommu_probe()
783 SET_M(iommu->base, 0, 0); in msm_iommu_probe()
787 ret = -ENODEV; in msm_iommu_probe()
791 ret = devm_request_threaded_irq(iommu->dev, iommu->irq, NULL, in msm_iommu_probe()
797 pr_err("Request IRQ %d failed with ret=%d\n", iommu->irq, ret); in msm_iommu_probe()
801 list_add(&iommu->dev_node, &qcom_iommu_devices); in msm_iommu_probe()
803 ret = iommu_device_sysfs_add(&iommu->iommu, iommu->dev, NULL, in msm_iommu_probe()
804 "msm-smmu.%pa", &ioaddr); in msm_iommu_probe()
806 pr_err("Could not add msm-smmu at %pa to sysfs\n", &ioaddr); in msm_iommu_probe()
810 iommu_device_set_ops(&iommu->iommu, &msm_iommu_ops); in msm_iommu_probe()
811 iommu_device_set_fwnode(&iommu->iommu, &pdev->dev.of_node->fwnode); in msm_iommu_probe()
813 ret = iommu_device_register(&iommu->iommu); in msm_iommu_probe()
815 pr_err("Could not register msm-smmu at %pa\n", &ioaddr); in msm_iommu_probe()
822 iommu->base, iommu->irq, iommu->ncb); in msm_iommu_probe()
826 clk_unprepare(iommu->clk); in msm_iommu_probe()
827 clk_unprepare(iommu->pclk); in msm_iommu_probe()
832 { .compatible = "qcom,apq8064-iommu" },
840 clk_unprepare(iommu->clk); in msm_iommu_remove()
841 clk_unprepare(iommu->pclk); in msm_iommu_remove()
873 MODULE_LICENSE("GPL v2");