aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoonyoung Shim <jy0922.shim@samsung.com>2013-06-28 14:24:54 +0900
committerDave Airlie <airlied@redhat.com>2013-07-05 15:44:49 +1000
commit78467dc5f70fb9bee4a32c0c3714c99b0b5465c7 (patch)
treefe5b399e17578e2a819083df5d7e0fee11df4027
parentdrm: add mmap function to prime helpers (diff)
downloadlinux-dev-78467dc5f70fb9bee4a32c0c3714c99b0b5465c7.tar.xz
linux-dev-78467dc5f70fb9bee4a32c0c3714c99b0b5465c7.zip
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>
-rw-r--r--drivers/gpu/drm/drm_gem_cma_helper.c79
-rw-r--r--include/drm/drm_gem_cma_helper.h9
2 files changed, 88 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);
diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h
index 6e17251e9b28..9d39d2a51906 100644
--- a/include/drm/drm_gem_cma_helper.h
+++ b/include/drm/drm_gem_cma_helper.h
@@ -54,4 +54,13 @@ struct dma_buf *drm_gem_cma_dmabuf_export(struct drm_device *drm_dev,
struct drm_gem_object *drm_gem_cma_dmabuf_import(struct drm_device *drm_dev,
struct dma_buf *dma_buf);
+struct sg_table *drm_gem_cma_prime_get_sg_table(struct drm_gem_object *obj);
+struct drm_gem_object *
+drm_gem_cma_prime_import_sg_table(struct drm_device *dev, size_t size,
+ struct sg_table *sgt);
+int drm_gem_cma_prime_mmap(struct drm_gem_object *obj,
+ struct vm_area_struct *vma);
+void *drm_gem_cma_prime_vmap(struct drm_gem_object *obj);
+void drm_gem_cma_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
+
#endif /* __DRM_GEM_CMA_HELPER_H__ */