diff options
author | Jordan Crouse <jcrouse@codeaurora.org> | 2018-11-07 15:35:48 -0700 |
---|---|---|
committer | Rob Clark <robdclark@gmail.com> | 2018-12-11 13:05:31 -0500 |
commit | c0ee9794693c1ff5bf540fc642fac954e39234a0 (patch) | |
tree | 1ca89be98fadad513d8abcf896abff892dd0879f /drivers/gpu/drm/msm/msm_gem_vma.c | |
parent | 70dc51b447f570ba3881e289b8134d364977a6f0 (diff) |
drm/msm: Split msm_gem_get_iova into two steps
Split the operation of msm_gem_get_iova into two operations:
1) allocate an iova and 2) map (pin) the backing memory int the
iommu. This is the first step toward allowing memory pinning
to occur independently of the iova management.
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/msm/msm_gem_vma.c')
-rw-r--r-- | drivers/gpu/drm/msm/msm_gem_vma.c | 44 |
1 files changed, 31 insertions, 13 deletions
diff --git a/drivers/gpu/drm/msm/msm_gem_vma.c b/drivers/gpu/drm/msm/msm_gem_vma.c index 704ae7e69500..c4c42bf0db0e 100644 --- a/drivers/gpu/drm/msm/msm_gem_vma.c +++ b/drivers/gpu/drm/msm/msm_gem_vma.c @@ -55,6 +55,7 @@ msm_gem_unmap_vma(struct msm_gem_address_space *aspace, spin_unlock(&aspace->lock); vma->iova = 0; + vma->mapped = false; msm_gem_address_space_put(aspace); } @@ -63,14 +64,37 @@ int msm_gem_map_vma(struct msm_gem_address_space *aspace, struct msm_gem_vma *vma, struct sg_table *sgt, int npages) { - int ret; + unsigned size = npages << PAGE_SHIFT; + int ret = 0; - spin_lock(&aspace->lock); - if (WARN_ON(drm_mm_node_allocated(&vma->node))) { - spin_unlock(&aspace->lock); + if (WARN_ON(!vma->iova)) + return -EINVAL; + + if (vma->mapped) return 0; - } + vma->mapped = true; + + if (aspace->mmu) + ret = aspace->mmu->funcs->map(aspace->mmu, vma->iova, sgt, + size, IOMMU_READ | IOMMU_WRITE); + + if (ret) + vma->mapped = false; + + return ret; +} + +/* Initialize a new vma and allocate an iova for it */ +int msm_gem_init_vma(struct msm_gem_address_space *aspace, + struct msm_gem_vma *vma, int npages) +{ + int ret; + + if (WARN_ON(vma->iova)) + return -EBUSY; + + spin_lock(&aspace->lock); ret = drm_mm_insert_node(&aspace->mm, &vma->node, npages); spin_unlock(&aspace->lock); @@ -78,17 +102,11 @@ msm_gem_map_vma(struct msm_gem_address_space *aspace, return ret; vma->iova = vma->node.start << PAGE_SHIFT; + vma->mapped = false; - if (aspace->mmu) { - unsigned size = npages << PAGE_SHIFT; - ret = aspace->mmu->funcs->map(aspace->mmu, vma->iova, sgt, - size, IOMMU_READ | IOMMU_WRITE); - } - - /* Get a reference to the aspace to keep it around */ kref_get(&aspace->kref); - return ret; + return 0; } struct msm_gem_address_space * |