diff options
author | Joonyoung Shim <jy0922.shim@samsung.com> | 2013-06-28 14:24:54 +0900 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-07-05 15:44:49 +1000 |
commit | 78467dc5f70fb9bee4a32c0c3714c99b0b5465c7 (patch) | |
tree | fe5b399e17578e2a819083df5d7e0fee11df4027 /drivers/gpu | |
parent | 7c397cd97b8f46659698396b420bd48c3e6703e6 (diff) |
drm/cma: add low-level hook functions to use prime helpers
Instead of using the dma_buf functionality for GEM CMA, we can use prime
helpers if we can provide low-level hook functions for GEM CMA.
Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/drm_gem_cma_helper.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c index ce063970d68c..83a45e5cf04e 100644 --- a/drivers/gpu/drm/drm_gem_cma_helper.c +++ b/drivers/gpu/drm/drm_gem_cma_helper.c @@ -602,3 +602,82 @@ error_gem_free: return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(drm_gem_cma_dmabuf_import); + +/* low-level interface prime helpers */ +struct sg_table *drm_gem_cma_prime_get_sg_table(struct drm_gem_object *obj) +{ + struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(obj); + struct sg_table *sgt; + int ret; + + sgt = kzalloc(sizeof(*sgt), GFP_KERNEL); + if (!sgt) + return NULL; + + ret = dma_get_sgtable(obj->dev->dev, sgt, cma_obj->vaddr, + cma_obj->paddr, obj->size); + if (ret < 0) + goto out; + + return sgt; + +out: + kfree(sgt); + return NULL; +} +EXPORT_SYMBOL_GPL(drm_gem_cma_prime_get_sg_table); + +struct drm_gem_object * +drm_gem_cma_prime_import_sg_table(struct drm_device *dev, size_t size, + struct sg_table *sgt) +{ + struct drm_gem_cma_object *cma_obj; + + if (sgt->nents != 1) + return ERR_PTR(-EINVAL); + + /* Create a CMA GEM buffer. */ + cma_obj = __drm_gem_cma_create(dev, size); + if (IS_ERR(cma_obj)) + return ERR_PTR(PTR_ERR(cma_obj)); + + cma_obj->paddr = sg_dma_address(sgt->sgl); + cma_obj->sgt = sgt; + + DRM_DEBUG_PRIME("dma_addr = 0x%x, size = %zu\n", cma_obj->paddr, size); + + return &cma_obj->base; +} +EXPORT_SYMBOL_GPL(drm_gem_cma_prime_import_sg_table); + +int drm_gem_cma_prime_mmap(struct drm_gem_object *obj, + struct vm_area_struct *vma) +{ + struct drm_gem_cma_object *cma_obj; + struct drm_device *dev = obj->dev; + int ret; + + mutex_lock(&dev->struct_mutex); + ret = drm_gem_mmap_obj(obj, obj->size, vma); + mutex_unlock(&dev->struct_mutex); + if (ret < 0) + return ret; + + cma_obj = to_drm_gem_cma_obj(obj); + return drm_gem_cma_mmap_obj(cma_obj, vma); +} +EXPORT_SYMBOL_GPL(drm_gem_cma_prime_mmap); + +void *drm_gem_cma_prime_vmap(struct drm_gem_object *obj) +{ + struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(obj); + + return cma_obj->vaddr; +} +EXPORT_SYMBOL_GPL(drm_gem_cma_prime_vmap); + +void drm_gem_cma_prime_vunmap(struct drm_gem_object *obj, void *vaddr) +{ + /* Nothing to do */ +} +EXPORT_SYMBOL_GPL(drm_gem_cma_prime_vunmap); |