aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/msm/msm_gem_vma.c
diff options
context:
space:
mode:
authorJordan Crouse <jcrouse@codeaurora.org>2018-11-07 15:35:48 -0700
committerRob Clark <robdclark@gmail.com>2018-12-11 13:05:31 -0500
commitc0ee9794693c1ff5bf540fc642fac954e39234a0 (patch)
tree1ca89be98fadad513d8abcf896abff892dd0879f /drivers/gpu/drm/msm/msm_gem_vma.c
parentdrm/msm: Remove sgt from the mmu unmap function (diff)
downloadlinux-dev-c0ee9794693c1ff5bf540fc642fac954e39234a0.tar.xz
linux-dev-c0ee9794693c1ff5bf540fc642fac954e39234a0.zip
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 '')
-rw-r--r--drivers/gpu/drm/msm/msm_gem_vma.c44
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 *