summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/exynos/exynos_drm_gem.c
diff options
context:
space:
mode:
authorJoonyoung Shim <jy0922.shim@samsung.com>2015-08-16 14:33:08 +0900
committerInki Dae <inki.dae@samsung.com>2015-08-16 14:33:45 +0900
commit01ed50ddbd6f7b4fafcf366994949d5a1a8356c0 (patch)
treeba25bf996d9c28544f2864d60092e462ad6246af /drivers/gpu/drm/exynos/exynos_drm_gem.c
parenteb57da880b00b6c68f971e077ff3e4db9ef0deae (diff)
drm/exynos: use prime helpers
The dma-buf codes of exynos drm is almost same with prime helpers. A difference is that consider DMA_NONE when import dma-buf, but it's wrong and we don't consider it any more, so we can use prime interface. Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_gem.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.c79
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 2c9a0752298c..768a632dfa2a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -13,6 +13,7 @@
#include <drm/drm_vma_manager.h>
#include <linux/shmem_fs.h>
+#include <linux/dma-buf.h>
#include <drm/exynos_drm.h>
#include "exynos_drm_drv.h"
@@ -577,3 +578,81 @@ err_close_vm:
return ret;
}
+
+/* low-level interface prime helpers */
+struct sg_table *exynos_drm_gem_prime_get_sg_table(struct drm_gem_object *obj)
+{
+ struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
+ struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer;
+ int npages;
+
+ npages = buf->size >> PAGE_SHIFT;
+
+ return drm_prime_pages_to_sg(buf->pages, npages);
+}
+
+struct drm_gem_object *
+exynos_drm_gem_prime_import_sg_table(struct drm_device *dev,
+ struct dma_buf_attachment *attach,
+ struct sg_table *sgt)
+{
+ struct exynos_drm_gem_obj *exynos_gem_obj;
+ struct exynos_drm_gem_buf *buf;
+ int npages;
+ int ret;
+
+ buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+ if (!buf)
+ return ERR_PTR(-ENOMEM);
+
+ buf->size = attach->dmabuf->size;
+ buf->dma_addr = sg_dma_address(sgt->sgl);
+
+ npages = buf->size >> PAGE_SHIFT;
+ buf->pages = drm_malloc_ab(npages, sizeof(struct page *));
+ if (!buf->pages) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ ret = drm_prime_sg_to_page_addr_arrays(sgt, buf->pages, NULL, npages);
+ if (ret < 0)
+ goto err_free_large;
+
+ exynos_gem_obj = exynos_drm_gem_init(dev, buf->size);
+ if (IS_ERR(exynos_gem_obj)) {
+ ret = PTR_ERR(exynos_gem_obj);
+ goto err;
+ }
+
+ if (sgt->nents == 1) {
+ /* always physically continuous memory if sgt->nents is 1. */
+ exynos_gem_obj->flags |= EXYNOS_BO_CONTIG;
+ } else {
+ /*
+ * this case could be CONTIG or NONCONTIG type but for now
+ * sets NONCONTIG.
+ * TODO. we have to find a way that exporter can notify
+ * the type of its own buffer to importer.
+ */
+ exynos_gem_obj->flags |= EXYNOS_BO_NONCONTIG;
+ }
+
+ return &exynos_gem_obj->base;
+
+err_free_large:
+ drm_free_large(buf->pages);
+err:
+ kfree(buf);
+ return ERR_PTR(ret);
+}
+
+void *exynos_drm_gem_prime_vmap(struct drm_gem_object *obj)
+{
+ return NULL;
+}
+
+void exynos_drm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
+{
+ /* Nothing to do */
+}