This introduces new functions to allocate/free buffer using
drm_gem_get/put_pages() instead of DMA mapping API. They also use sg
list to manage pages.

Signed-off-by: Joonyoung Shim <jy0922.shim at samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_gem.c | 48 +++++++++++++++++++++++++++++++++
 drivers/gpu/drm/exynos/exynos_drm_gem.h |  2 +-
 2 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c 
b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 88196edd4ade..d982d46b04da 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -20,6 +20,54 @@
 #include "exynos_drm_gem.h"
 #include "exynos_drm_iommu.h"

+static int exynos_drm_get_pages(struct exynos_drm_gem *exynos_gem)
+{
+       struct drm_device *dev = exynos_gem->base.dev;
+       struct page **pages;
+       struct sg_table *sgt;
+       int ret;
+
+       pages = drm_gem_get_pages(&exynos_gem->base);
+       if (IS_ERR(pages))
+               return PTR_ERR(pages);
+
+       sgt = drm_prime_pages_to_sg(pages, exynos_gem->size >> PAGE_SHIFT);
+       if (IS_ERR(sgt)) {
+               ret = PTR_ERR(sgt);
+               goto err;
+       }
+
+       if (!dma_map_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL)) {
+               sg_free_table(sgt);
+               kfree(sgt);
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       exynos_gem->dma_addr = sg_dma_address(sgt->sgl);
+       exynos_gem->sgt = sgt;
+       exynos_gem->pages = pages;
+
+       return 0;
+
+err:
+       drm_gem_put_pages(&exynos_gem->base, pages, false, false);
+       return ret;
+}
+
+static void exynos_drm_put_pages(struct exynos_drm_gem *exynos_gem)
+{
+       struct drm_device *dev = exynos_gem->base.dev;
+       struct sg_table *sgt = exynos_gem->sgt;
+
+       dma_unmap_sg(dev->dev, sgt->sgl, sgt->nents, DMA_BIDIRECTIONAL);
+
+       sg_free_table(sgt);
+       kfree(sgt);
+
+       drm_gem_put_pages(&exynos_gem->base, exynos_gem->pages, false, false);
+}
+
 static int exynos_drm_alloc_dma(struct exynos_drm_gem *exynos_gem)
 {
        struct drm_device *dev = exynos_gem->base.dev;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h 
b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index c1df26877b76..f47daec776e6 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -38,7 +38,7 @@
  *     - this address could be physical address without IOMMU and
  *     device address with IOMMU.
  * @pages: Array of backing pages.
- * @sgt: Imported sg_table.
+ * @sgt: Converted sg_table of pages or imported sg_table.
  *
  * P.S. this object would be transferred to user as kms_bo.handle so
  *     user can access the buffer through kms_bo.handle.
-- 
1.9.1

Reply via email to