Lines Matching +full:iommu +full:- +full:parent

1 // SPDX-License-Identifier: GPL-2.0-only
7 #include <linux/adreno-smmu-priv.h>
8 #include <linux/io-pgtable.h>
22 struct msm_mmu *parent; member
35 /* based on iommu_pgsize() in iommu.c: */
46 pgsizes = pagetable->pgsize_bitmap & GENMASK(__fls(size), 0); in calc_pgsize()
62 pgsizes = pagetable->pgsize_bitmap & ~GENMASK(pgsize_idx, 0); in calc_pgsize()
73 if ((iova ^ paddr) & (pgsize_next - 1)) in calc_pgsize()
77 offset = pgsize_next - (addr_merge & (pgsize_next - 1)); in calc_pgsize()
95 struct io_pgtable_ops *ops = pagetable->pgtbl_ops; in msm_iommu_pagetable_unmap()
102 unmapped = ops->unmap_pages(ops, iova, pgsize, count, NULL); in msm_iommu_pagetable_unmap()
107 size -= unmapped; in msm_iommu_pagetable_unmap()
110 iommu_flush_iotlb_all(to_msm_iommu(pagetable->parent)->domain); in msm_iommu_pagetable_unmap()
112 return (size == 0) ? 0 : -EINVAL; in msm_iommu_pagetable_unmap()
119 struct io_pgtable_ops *ops = pagetable->pgtbl_ops; in msm_iommu_pagetable_map()
125 size_t size = sg->length; in msm_iommu_pagetable_map()
134 ret = ops->map_pages(ops, addr, phys, pgsize, count, in msm_iommu_pagetable_map()
142 size -= mapped; in msm_iommu_pagetable_map()
145 msm_iommu_pagetable_unmap(mmu, iova, addr - iova); in msm_iommu_pagetable_map()
146 return -EINVAL; in msm_iommu_pagetable_map()
157 struct msm_iommu *iommu = to_msm_iommu(pagetable->parent); in msm_iommu_pagetable_destroy() local
159 dev_get_drvdata(pagetable->parent->dev); in msm_iommu_pagetable_destroy()
162 * If this is the last attached pagetable for the parent, in msm_iommu_pagetable_destroy()
163 * disable TTBR0 in the arm-smmu driver in msm_iommu_pagetable_destroy()
165 if (atomic_dec_return(&iommu->pagetables) == 0) in msm_iommu_pagetable_destroy()
166 adreno_smmu->set_ttbr0_cfg(adreno_smmu->cookie, NULL); in msm_iommu_pagetable_destroy()
168 free_io_pgtable_ops(pagetable->pgtbl_ops); in msm_iommu_pagetable_destroy()
177 if (mmu->type != MSM_MMU_IOMMU_PAGETABLE) in msm_iommu_pagetable_params()
178 return -EINVAL; in msm_iommu_pagetable_params()
183 *ttbr = pagetable->ttbr; in msm_iommu_pagetable_params()
186 *asid = pagetable->asid; in msm_iommu_pagetable_params()
193 struct msm_iommu *iommu = to_msm_iommu(mmu); in msm_iommu_get_geometry() local
195 return &iommu->domain->geometry; in msm_iommu_get_geometry()
209 if (!pm_runtime_get_if_in_use(pagetable->iommu_dev)) in msm_iommu_tlb_flush_all()
212 adreno_smmu = dev_get_drvdata(pagetable->parent->dev); in msm_iommu_tlb_flush_all()
214 pagetable->tlb->tlb_flush_all((void *)adreno_smmu->cookie); in msm_iommu_tlb_flush_all()
216 pm_runtime_put_autosuspend(pagetable->iommu_dev); in msm_iommu_tlb_flush_all()
225 if (!pm_runtime_get_if_in_use(pagetable->iommu_dev)) in msm_iommu_tlb_flush_walk()
228 adreno_smmu = dev_get_drvdata(pagetable->parent->dev); in msm_iommu_tlb_flush_walk()
230 pagetable->tlb->tlb_flush_walk(iova, size, granule, (void *)adreno_smmu->cookie); in msm_iommu_tlb_flush_walk()
232 pm_runtime_put_autosuspend(pagetable->iommu_dev); in msm_iommu_tlb_flush_walk()
249 struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent) in msm_iommu_pagetable_create() argument
251 struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(parent->dev); in msm_iommu_pagetable_create()
252 struct msm_iommu *iommu = to_msm_iommu(parent); in msm_iommu_pagetable_create() local
259 if (adreno_smmu->cookie) in msm_iommu_pagetable_create()
260 ttbr1_cfg = adreno_smmu->get_ttbr1_cfg(adreno_smmu->cookie); in msm_iommu_pagetable_create()
264 * qcom_smmu_impl_of_match[] in arm-smmu-qcom.c in msm_iommu_pagetable_create()
266 if (WARN_ONCE(!ttbr1_cfg, "No per-process page tables")) in msm_iommu_pagetable_create()
267 return ERR_PTR(-ENODEV); in msm_iommu_pagetable_create()
271 return ERR_PTR(-ENOMEM); in msm_iommu_pagetable_create()
273 msm_mmu_init(&pagetable->base, parent->dev, &pagetable_funcs, in msm_iommu_pagetable_create()
283 pagetable->pgtbl_ops = alloc_io_pgtable_ops(ARM_64_LPAE_S1, in msm_iommu_pagetable_create()
286 if (!pagetable->pgtbl_ops) { in msm_iommu_pagetable_create()
288 return ERR_PTR(-ENOMEM); in msm_iommu_pagetable_create()
293 * the arm-smmu driver as a trigger to set up TTBR0 in msm_iommu_pagetable_create()
295 if (atomic_inc_return(&iommu->pagetables) == 1) { in msm_iommu_pagetable_create()
296 ret = adreno_smmu->set_ttbr0_cfg(adreno_smmu->cookie, &ttbr0_cfg); in msm_iommu_pagetable_create()
298 free_io_pgtable_ops(pagetable->pgtbl_ops); in msm_iommu_pagetable_create()
305 pagetable->parent = parent; in msm_iommu_pagetable_create()
306 pagetable->tlb = ttbr1_cfg->tlb; in msm_iommu_pagetable_create()
307 pagetable->iommu_dev = ttbr1_cfg->iommu_dev; in msm_iommu_pagetable_create()
308 pagetable->pgsize_bitmap = ttbr0_cfg.pgsize_bitmap; in msm_iommu_pagetable_create()
309 pagetable->ttbr = ttbr0_cfg.arm_lpae_s1_cfg.ttbr; in msm_iommu_pagetable_create()
317 pagetable->asid = 0; in msm_iommu_pagetable_create()
319 return &pagetable->base; in msm_iommu_pagetable_create()
325 struct msm_iommu *iommu = arg; in msm_fault_handler() local
326 struct msm_mmu *mmu = &iommu->base; in msm_fault_handler()
327 struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(iommu->base.dev); in msm_fault_handler()
330 if (adreno_smmu->get_fault_info) { in msm_fault_handler()
331 adreno_smmu->get_fault_info(adreno_smmu->cookie, &info); in msm_fault_handler()
335 if (iommu->base.handler) in msm_fault_handler()
336 return iommu->base.handler(iommu->base.arg, iova, flags, ptr); in msm_fault_handler()
340 if (mmu->funcs->resume_translation) in msm_fault_handler()
341 mmu->funcs->resume_translation(mmu); in msm_fault_handler()
348 struct adreno_smmu_priv *adreno_smmu = dev_get_drvdata(mmu->dev); in msm_iommu_resume_translation()
350 if (adreno_smmu->resume_translation) in msm_iommu_resume_translation()
351 adreno_smmu->resume_translation(adreno_smmu->cookie, true); in msm_iommu_resume_translation()
356 struct msm_iommu *iommu = to_msm_iommu(mmu); in msm_iommu_detach() local
358 iommu_detach_device(iommu->domain, mmu->dev); in msm_iommu_detach()
364 struct msm_iommu *iommu = to_msm_iommu(mmu); in msm_iommu_map() local
367 /* The arm-smmu driver expects the addresses to be sign extended */ in msm_iommu_map()
371 ret = iommu_map_sgtable(iommu->domain, iova, sgt, prot); in msm_iommu_map()
374 return (ret == len) ? 0 : -EINVAL; in msm_iommu_map()
379 struct msm_iommu *iommu = to_msm_iommu(mmu); in msm_iommu_unmap() local
384 iommu_unmap(iommu->domain, iova, len); in msm_iommu_unmap()
391 struct msm_iommu *iommu = to_msm_iommu(mmu); in msm_iommu_destroy() local
392 iommu_domain_free(iommu->domain); in msm_iommu_destroy()
393 kfree(iommu); in msm_iommu_destroy()
407 struct msm_iommu *iommu; in msm_iommu_new() local
419 iommu = kzalloc(sizeof(*iommu), GFP_KERNEL); in msm_iommu_new()
420 if (!iommu) { in msm_iommu_new()
422 return ERR_PTR(-ENOMEM); in msm_iommu_new()
425 iommu->domain = domain; in msm_iommu_new()
426 msm_mmu_init(&iommu->base, dev, &funcs, MSM_MMU_IOMMU); in msm_iommu_new()
428 atomic_set(&iommu->pagetables, 0); in msm_iommu_new()
430 ret = iommu_attach_device(iommu->domain, dev); in msm_iommu_new()
433 kfree(iommu); in msm_iommu_new()
437 return &iommu->base; in msm_iommu_new()
443 struct msm_iommu *iommu; in msm_iommu_gpu_new() local
450 iommu = to_msm_iommu(mmu); in msm_iommu_gpu_new()
451 iommu_set_fault_handler(iommu->domain, msm_fault_handler, iommu); in msm_iommu_gpu_new()
453 /* Enable stall on iommu fault: */ in msm_iommu_gpu_new()
454 if (adreno_smmu->set_stall) in msm_iommu_gpu_new()
455 adreno_smmu->set_stall(adreno_smmu->cookie, true); in msm_iommu_gpu_new()