[PATCH 5/9] drm/exynos: introduce buffer allocation using drm_gem_get/put_pages()

Joonyoung Shim jy0922.shim at samsung.com
Tue Oct 13 00:00:50 PDT 2015


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



More information about the dri-devel mailing list