diff options
Diffstat (limited to 'drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c')
| -rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 79 |
1 files changed, 39 insertions, 40 deletions
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c index 0566171f8df2..40a50c60dfff 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c @@ -3,49 +3,43 @@ * Copyright (C) 2014-2018 Etnaviv Project */ +#include <drm/drm_prime.h> #include <linux/dma-buf.h> +#include <linux/module.h> + #include "etnaviv_drv.h" #include "etnaviv_gem.h" +MODULE_IMPORT_NS("DMA_BUF"); + static struct lock_class_key etnaviv_prime_lock_class; struct sg_table *etnaviv_gem_prime_get_sg_table(struct drm_gem_object *obj) { struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj); - int npages = obj->size >> PAGE_SHIFT; + unsigned int npages = obj->size >> PAGE_SHIFT; if (WARN_ON(!etnaviv_obj->pages)) /* should have already pinned! */ - return NULL; - - return drm_prime_pages_to_sg(etnaviv_obj->pages, npages); -} - -void *etnaviv_gem_prime_vmap(struct drm_gem_object *obj) -{ - return etnaviv_gem_vmap(obj); -} + return ERR_PTR(-EINVAL); -void etnaviv_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr) -{ - /* TODO msm_gem_vunmap() */ + return drm_prime_pages_to_sg(obj->dev, etnaviv_obj->pages, npages); } -int etnaviv_gem_prime_mmap(struct drm_gem_object *obj, - struct vm_area_struct *vma) +int etnaviv_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map) { - struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj); - int ret; + void *vaddr; - ret = drm_gem_mmap_obj(obj, obj->size, vma); - if (ret < 0) - return ret; + vaddr = etnaviv_gem_vmap(obj); + if (!vaddr) + return -ENOMEM; + iosys_map_set_vaddr(map, vaddr); - return etnaviv_obj->ops->mmap(etnaviv_obj, vma); + return 0; } int etnaviv_gem_prime_pin(struct drm_gem_object *obj) { - if (!obj->import_attach) { + if (!drm_gem_is_imported(obj)) { struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj); mutex_lock(&etnaviv_obj->lock); @@ -57,7 +51,7 @@ int etnaviv_gem_prime_pin(struct drm_gem_object *obj) void etnaviv_gem_prime_unpin(struct drm_gem_object *obj) { - if (!obj->import_attach) { + if (!drm_gem_is_imported(obj)) { struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj); mutex_lock(&etnaviv_obj->lock); @@ -68,30 +62,44 @@ void etnaviv_gem_prime_unpin(struct drm_gem_object *obj) static void etnaviv_gem_prime_release(struct etnaviv_gem_object *etnaviv_obj) { + struct iosys_map map = IOSYS_MAP_INIT_VADDR(etnaviv_obj->vaddr); + if (etnaviv_obj->vaddr) - dma_buf_vunmap(etnaviv_obj->base.import_attach->dmabuf, - etnaviv_obj->vaddr); + dma_buf_vunmap_unlocked(etnaviv_obj->base.import_attach->dmabuf, &map); /* Don't drop the pages for imported dmabuf, as they are not * ours, just free the array we allocated: */ - if (etnaviv_obj->pages) - kvfree(etnaviv_obj->pages); + kvfree(etnaviv_obj->pages); drm_prime_gem_destroy(&etnaviv_obj->base, etnaviv_obj->sgt); } static void *etnaviv_gem_prime_vmap_impl(struct etnaviv_gem_object *etnaviv_obj) { + struct iosys_map map; + int ret; + lockdep_assert_held(&etnaviv_obj->lock); - return dma_buf_vmap(etnaviv_obj->base.import_attach->dmabuf); + ret = dma_buf_vmap(etnaviv_obj->base.import_attach->dmabuf, &map); + if (ret) + return NULL; + return map.vaddr; } static int etnaviv_gem_prime_mmap_obj(struct etnaviv_gem_object *etnaviv_obj, struct vm_area_struct *vma) { - return dma_buf_mmap(etnaviv_obj->base.dma_buf, vma, 0); + int ret; + + ret = dma_buf_mmap(etnaviv_obj->base.dma_buf, vma, 0); + if (!ret) { + /* Drop the reference acquired by drm_gem_mmap_obj(). */ + drm_gem_object_put(&etnaviv_obj->base); + } + + return ret; } static const struct etnaviv_gem_ops etnaviv_gem_prime_ops = { @@ -109,7 +117,6 @@ struct drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev, int ret, npages; ret = etnaviv_gem_new_private(dev, size, ETNA_BO_WC, - attach->dmabuf->resv, &etnaviv_gem_prime_ops, &etnaviv_obj); if (ret < 0) return ERR_PTR(ret); @@ -125,8 +132,7 @@ struct drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev, goto fail; } - ret = drm_prime_sg_to_page_addr_arrays(sgt, etnaviv_obj->pages, - NULL, npages); + ret = drm_prime_sg_to_page_array(sgt, etnaviv_obj->pages, npages); if (ret) goto fail; @@ -135,14 +141,7 @@ struct drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev, return &etnaviv_obj->base; fail: - drm_gem_object_put_unlocked(&etnaviv_obj->base); + drm_gem_object_put(&etnaviv_obj->base); return ERR_PTR(ret); } - -struct reservation_object *etnaviv_gem_prime_res_obj(struct drm_gem_object *obj) -{ - struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj); - - return etnaviv_obj->resv; -} |
