diff options
Diffstat (limited to 'drivers/gpu/drm/msm/msm_gem.c')
| -rw-r--r-- | drivers/gpu/drm/msm/msm_gem.c | 55 |
1 files changed, 37 insertions, 18 deletions
diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c index 5a6a79fbc9d6..38b0c0e1f83e 100644 --- a/drivers/gpu/drm/msm/msm_gem.c +++ b/drivers/gpu/drm/msm/msm_gem.c @@ -389,7 +389,8 @@ put_iova(struct drm_gem_object *obj) } static int msm_gem_get_iova_locked(struct drm_gem_object *obj, - struct msm_gem_address_space *aspace, uint64_t *iova) + struct msm_gem_address_space *aspace, uint64_t *iova, + u64 range_start, u64 range_end) { struct msm_gem_object *msm_obj = to_msm_bo(obj); struct msm_gem_vma *vma; @@ -404,7 +405,8 @@ static int msm_gem_get_iova_locked(struct drm_gem_object *obj, if (IS_ERR(vma)) return PTR_ERR(vma); - ret = msm_gem_init_vma(aspace, vma, obj->size >> PAGE_SHIFT); + ret = msm_gem_init_vma(aspace, vma, obj->size >> PAGE_SHIFT, + range_start, range_end); if (ret) { del_vma(vma); return ret; @@ -426,6 +428,9 @@ static int msm_gem_pin_iova(struct drm_gem_object *obj, if (!(msm_obj->flags & MSM_BO_GPU_READONLY)) prot |= IOMMU_WRITE; + if (msm_obj->flags & MSM_BO_MAP_PRIV) + prot |= IOMMU_PRIV; + WARN_ON(!mutex_is_locked(&msm_obj->lock)); if (WARN_ON(msm_obj->madv != MSM_MADV_WILLNEED)) @@ -443,9 +448,13 @@ static int msm_gem_pin_iova(struct drm_gem_object *obj, msm_obj->sgt, obj->size >> PAGE_SHIFT); } -/* get iova and pin it. Should have a matching put */ -int msm_gem_get_and_pin_iova(struct drm_gem_object *obj, - struct msm_gem_address_space *aspace, uint64_t *iova) +/* + * get iova and pin it. Should have a matching put + * limits iova to specified range (in pages) + */ +int msm_gem_get_and_pin_iova_range(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace, uint64_t *iova, + u64 range_start, u64 range_end) { struct msm_gem_object *msm_obj = to_msm_bo(obj); u64 local; @@ -453,7 +462,8 @@ int msm_gem_get_and_pin_iova(struct drm_gem_object *obj, mutex_lock(&msm_obj->lock); - ret = msm_gem_get_iova_locked(obj, aspace, &local); + ret = msm_gem_get_iova_locked(obj, aspace, &local, + range_start, range_end); if (!ret) ret = msm_gem_pin_iova(obj, aspace); @@ -465,6 +475,13 @@ int msm_gem_get_and_pin_iova(struct drm_gem_object *obj, return ret; } +/* get iova and pin it. Should have a matching put */ +int msm_gem_get_and_pin_iova(struct drm_gem_object *obj, + struct msm_gem_address_space *aspace, uint64_t *iova) +{ + return msm_gem_get_and_pin_iova_range(obj, aspace, iova, 0, U64_MAX); +} + /* * Get an iova but don't pin it. Doesn't need a put because iovas are currently * valid for the life of the object @@ -476,7 +493,7 @@ int msm_gem_get_iova(struct drm_gem_object *obj, int ret; mutex_lock(&msm_obj->lock); - ret = msm_gem_get_iova_locked(obj, aspace, iova); + ret = msm_gem_get_iova_locked(obj, aspace, iova, 0, U64_MAX); mutex_unlock(&msm_obj->lock); return ret; @@ -543,7 +560,7 @@ int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, *offset = msm_gem_mmap_offset(obj); - drm_gem_object_put_unlocked(obj); + drm_gem_object_put(obj); fail: return ret; @@ -554,6 +571,9 @@ static void *get_vaddr(struct drm_gem_object *obj, unsigned madv) struct msm_gem_object *msm_obj = to_msm_bo(obj); int ret = 0; + if (obj->import_attach) + return ERR_PTR(-ENODEV); + mutex_lock(&msm_obj->lock); if (WARN_ON(msm_obj->madv > madv)) { @@ -879,7 +899,7 @@ void msm_gem_describe_objects(struct list_head *list, struct seq_file *m) } #endif -/* don't call directly! Use drm_gem_object_put() and friends */ +/* don't call directly! Use drm_gem_object_put_locked() and friends */ void msm_gem_free_object(struct drm_gem_object *obj) { struct msm_gem_object *msm_obj = to_msm_bo(obj); @@ -907,8 +927,7 @@ static void free_object(struct msm_gem_object *msm_obj) put_iova(obj); if (obj->import_attach) { - if (msm_obj->vaddr) - dma_buf_vunmap(obj->import_attach->dmabuf, msm_obj->vaddr); + WARN_ON(msm_obj->vaddr); /* Don't drop the pages for imported dmabuf, as they are not * ours, just free the array we allocated: @@ -970,7 +989,7 @@ int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file, ret = drm_gem_handle_create(file, obj, handle); /* drop reference from allocate - handle holds it now */ - drm_gem_object_put_unlocked(obj); + drm_gem_object_put(obj); return ret; } @@ -1089,7 +1108,7 @@ static struct drm_gem_object *_msm_gem_new(struct drm_device *dev, return obj; fail: - drm_gem_object_put_unlocked(obj); + drm_gem_object_put(obj); return ERR_PTR(ret); } @@ -1149,7 +1168,7 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev, return obj; fail: - drm_gem_object_put_unlocked(obj); + drm_gem_object_put(obj); return ERR_PTR(ret); } @@ -1183,9 +1202,9 @@ static void *_msm_gem_kernel_new(struct drm_device *dev, uint32_t size, return vaddr; err: if (locked) - drm_gem_object_put(obj); + drm_gem_object_put_locked(obj); else - drm_gem_object_put_unlocked(obj); + drm_gem_object_put(obj); return ERR_PTR(ret); @@ -1215,9 +1234,9 @@ void msm_gem_kernel_put(struct drm_gem_object *bo, msm_gem_unpin_iova(bo, aspace); if (locked) - drm_gem_object_put(bo); + drm_gem_object_put_locked(bo); else - drm_gem_object_put_unlocked(bo); + drm_gem_object_put(bo); } void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...) |