Lines Matching +full:iommu +full:- +full:map
1 // SPDX-License-Identifier: GPL-2.0-only
7 #include <linux/adreno-smmu-priv.h>
8 #include <linux/io-pgtable.h>
33 /* based on iommu_pgsize() in iommu.c: */
44 pgsizes = pagetable->pgsize_bitmap & GENMASK(__fls(size), 0); in calc_pgsize()
60 pgsizes = pagetable->pgsize_bitmap & ~GENMASK(pgsize_idx, 0); in calc_pgsize()
71 if ((iova ^ paddr) & (pgsize_next - 1)) in calc_pgsize()
75 offset = pgsize_next - (addr_merge & (pgsize_next - 1)); in calc_pgsize()
93 struct io_pgtable_ops *ops = pagetable->pgtbl_ops; in msm_iommu_pagetable_unmap()
100 unmapped = ops->unmap_pages(ops, iova, pgsize, count, NULL); in msm_iommu_pagetable_unmap()
105 size -= unmapped; in msm_iommu_pagetable_unmap()
108 iommu_flush_iotlb_all(to_msm_iommu(pagetable->parent)->domain); in msm_iommu_pagetable_unmap()
110 return (size == 0) ? 0 : -EINVAL; in msm_iommu_pagetable_unmap()
117 struct io_pgtable_ops *ops = pagetable->pgtbl_ops; in msm_iommu_pagetable_map()
123 size_t size = sg->length; in msm_iommu_pagetable_map()
132 ret = ops->map_pages(ops, addr, phys, pgsize, count, in msm_iommu_pagetable_map()
140 size -= mapped; in msm_iommu_pagetable_map()
143 msm_iommu_pagetable_unmap(mmu, iova, addr - iova); in msm_iommu_pagetable_map()
144 return -EINVAL; in msm_iommu_pagetable_map()
155 struct msm_iommu *iommu = to_msm_iommu(pagetable->parent); in msm_iommu_pagetable_destroy() local
157 dev_get_drvdata(pagetable->parent->dev); in msm_iommu_pagetable_destroy()
161 * disable TTBR0 in the arm-smmu driver in msm_iommu_pagetable_destroy()
163 if (atomic_dec_return(&iommu->pagetables) == 0) in msm_iommu_pagetable_destroy()
164 adreno_smmu->set_ttbr0_cfg(adreno_smmu->cookie, NULL); in msm_iommu_pagetable_destroy()
166 free_io_pgtable_ops(pagetable->pgtbl_ops); in msm_iommu_pagetable_destroy()
175 if (mmu->type != MSM_MMU_IOMMU_PAGETABLE) in msm_iommu_pagetable_params()
176 return -EINVAL; in msm_iommu_pagetable_params()
181 *ttbr = pagetable->ttbr; in msm_iommu_pagetable_params()
184 *asid = pagetable->asid; in msm_iommu_pagetable_params()
190 .map = msm_iommu_pagetable_map,
220 struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(parent->dev); in msm_iommu_pagetable_create()
221 struct msm_iommu *iommu = to_msm_iommu(parent); in msm_iommu_pagetable_create() local
228 if (adreno_smmu->cookie) in msm_iommu_pagetable_create()
229 ttbr1_cfg = adreno_smmu->get_ttbr1_cfg(adreno_smmu->cookie); in msm_iommu_pagetable_create()
231 return ERR_PTR(-ENODEV); in msm_iommu_pagetable_create()
236 * the display's iommu in msm_iommu_pagetable_create()
238 iommu_set_fault_handler(iommu->domain, msm_fault_handler, iommu); in msm_iommu_pagetable_create()
242 return ERR_PTR(-ENOMEM); in msm_iommu_pagetable_create()
244 msm_mmu_init(&pagetable->base, parent->dev, &pagetable_funcs, in msm_iommu_pagetable_create()
254 pagetable->pgtbl_ops = alloc_io_pgtable_ops(ARM_64_LPAE_S1, in msm_iommu_pagetable_create()
255 &ttbr0_cfg, iommu->domain); in msm_iommu_pagetable_create()
257 if (!pagetable->pgtbl_ops) { in msm_iommu_pagetable_create()
259 return ERR_PTR(-ENOMEM); in msm_iommu_pagetable_create()
264 * the arm-smmu driver as a trigger to set up TTBR0 in msm_iommu_pagetable_create()
266 if (atomic_inc_return(&iommu->pagetables) == 1) { in msm_iommu_pagetable_create()
267 /* Enable stall on iommu fault: */ in msm_iommu_pagetable_create()
268 adreno_smmu->set_stall(adreno_smmu->cookie, true); in msm_iommu_pagetable_create()
270 ret = adreno_smmu->set_ttbr0_cfg(adreno_smmu->cookie, &ttbr0_cfg); in msm_iommu_pagetable_create()
272 free_io_pgtable_ops(pagetable->pgtbl_ops); in msm_iommu_pagetable_create()
279 pagetable->parent = parent; in msm_iommu_pagetable_create()
280 pagetable->pgsize_bitmap = ttbr0_cfg.pgsize_bitmap; in msm_iommu_pagetable_create()
281 pagetable->ttbr = ttbr0_cfg.arm_lpae_s1_cfg.ttbr; in msm_iommu_pagetable_create()
289 pagetable->asid = 0; in msm_iommu_pagetable_create()
291 return &pagetable->base; in msm_iommu_pagetable_create()
297 struct msm_iommu *iommu = arg; in msm_fault_handler() local
298 struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(iommu->base.dev); in msm_fault_handler()
301 if (adreno_smmu->get_fault_info) { in msm_fault_handler()
302 adreno_smmu->get_fault_info(adreno_smmu->cookie, &info); in msm_fault_handler()
306 if (iommu->base.handler) in msm_fault_handler()
307 return iommu->base.handler(iommu->base.arg, iova, flags, ptr); in msm_fault_handler()
315 struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(mmu->dev); in msm_iommu_resume_translation()
317 adreno_smmu->resume_translation(adreno_smmu->cookie, true); in msm_iommu_resume_translation()
322 struct msm_iommu *iommu = to_msm_iommu(mmu); in msm_iommu_detach() local
324 iommu_detach_device(iommu->domain, mmu->dev); in msm_iommu_detach()
330 struct msm_iommu *iommu = to_msm_iommu(mmu); in msm_iommu_map() local
333 /* The arm-smmu driver expects the addresses to be sign extended */ in msm_iommu_map()
337 ret = iommu_map_sgtable(iommu->domain, iova, sgt, prot); in msm_iommu_map()
340 return (ret == len) ? 0 : -EINVAL; in msm_iommu_map()
345 struct msm_iommu *iommu = to_msm_iommu(mmu); in msm_iommu_unmap() local
350 iommu_unmap(iommu->domain, iova, len); in msm_iommu_unmap()
357 struct msm_iommu *iommu = to_msm_iommu(mmu); in msm_iommu_destroy() local
358 iommu_domain_free(iommu->domain); in msm_iommu_destroy()
359 kfree(iommu); in msm_iommu_destroy()
364 .map = msm_iommu_map,
372 struct msm_iommu *iommu; in msm_iommu_new() local
376 return ERR_PTR(-ENODEV); in msm_iommu_new()
378 iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); in msm_iommu_new()
379 if (!iommu) in msm_iommu_new()
380 return ERR_PTR(-ENOMEM); in msm_iommu_new()
382 iommu->domain = domain; in msm_iommu_new()
383 msm_mmu_init(&iommu->base, dev, &funcs, MSM_MMU_IOMMU); in msm_iommu_new()
385 atomic_set(&iommu->pagetables, 0); in msm_iommu_new()
387 ret = iommu_attach_device(iommu->domain, dev); in msm_iommu_new()
389 kfree(iommu); in msm_iommu_new()
393 return &iommu->base; in msm_iommu_new()