[PATCH 7/9] drm/exynos: always use EXYNOS_BO_CONTIG flag on iommu

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


It doesn't care whether memory is continuous physically if iommu is
supported but we will always use EXYNOS_BO_CONTIG flag on iommu, so it
can mean that the memory is continuous memory for device.

Signed-off-by: Joonyoung Shim <jy0922.shim at samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_fb.c    | 32 ++++---------------------------
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 14 +-------------
 drivers/gpu/drm/exynos/exynos_drm_gem.c   | 31 ++++++++++++++----------------
 drivers/gpu/drm/exynos/exynos_drm_gem.h   |  2 --
 include/uapi/drm/exynos_drm.h             |  5 ++++-
 5 files changed, 23 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index fcea28bdbc42..8fbae903c7ed 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -39,32 +39,6 @@ struct exynos_drm_fb {
 	struct exynos_drm_gem	*exynos_gem[MAX_FB_BUFFER];
 };
 
-static int check_fb_gem_memory_type(struct drm_device *drm_dev,
-				    struct exynos_drm_gem *exynos_gem)
-{
-	unsigned int flags;
-
-	/*
-	 * if exynos drm driver supports iommu then framebuffer can use
-	 * all the buffer types.
-	 */
-	if (is_drm_iommu_supported(drm_dev))
-		return 0;
-
-	flags = exynos_gem->flags;
-
-	/*
-	 * without iommu support, not support physically non-continuous memory
-	 * for framebuffer.
-	 */
-	if (IS_NONCONTIG_BUFFER(flags)) {
-		DRM_ERROR("cannot use this gem memory type for fb.\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
 static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
 {
 	struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
@@ -130,9 +104,11 @@ exynos_drm_framebuffer_init(struct drm_device *dev,
 		return ERR_PTR(-ENOMEM);
 
 	for (i = 0; i < count; i++) {
-		ret = check_fb_gem_memory_type(dev, exynos_gem[i]);
-		if (ret < 0)
+		/* Not support physically non-continuous memory for FB */
+		if (exynos_gem[i]->flags & EXYNOS_BO_NONCONTIG) {
+			ret = -EINVAL;
 			goto err;
+		}
 
 		exynos_fb->exynos_gem[i] = exynos_gem[i];
 	}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index f6118baa8e3e..fcbe43a580c1 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -124,7 +124,6 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
 	struct exynos_drm_gem *exynos_gem;
 	struct drm_device *dev = helper->dev;
 	struct drm_mode_fb_cmd2 mode_cmd = { 0 };
-	struct platform_device *pdev = dev->platformdev;
 	unsigned long size;
 	int ret;
 
@@ -142,18 +141,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
 
 	size = mode_cmd.pitches[0] * mode_cmd.height;
 
-	exynos_gem = exynos_drm_gem_create(dev, EXYNOS_BO_CONTIG, size);
-	/*
-	 * If physically contiguous memory allocation fails and if IOMMU is
-	 * supported then try to get buffer from non physically contiguous
-	 * memory area.
-	 */
-	if (IS_ERR(exynos_gem) && is_drm_iommu_supported(dev)) {
-		dev_warn(&pdev->dev, "contiguous FB allocation failed, falling back to non-contiguous\n");
-		exynos_gem = exynos_drm_gem_create(dev, EXYNOS_BO_NONCONTIG,
-						   size);
-	}
-
+	exynos_gem = exynos_drm_gem_create(dev, 0, size);
 	if (IS_ERR(exynos_gem)) {
 		ret = PTR_ERR(exynos_gem);
 		goto out;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 163d113df1ab..96a69468283b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -135,6 +135,8 @@ static int exynos_drm_alloc_buf(struct exynos_drm_gem *exynos_gem)
 	if (!is_drm_iommu_supported(dev)) {
 		if (!(exynos_gem->flags & EXYNOS_BO_NONCONTIG))
 			return exynos_drm_alloc_dma(exynos_gem);
+	} else {
+		exynos_gem->flags &= ~EXYNOS_BO_NONCONTIG;
 	}
 
 	ret = exynos_drm_get_pages(exynos_gem);
@@ -440,10 +442,7 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
 	args->pitch = args->width * ((args->bpp + 7) / 8);
 	args->size = args->pitch * args->height;
 
-	if (is_drm_iommu_supported(dev))
-		flags = EXYNOS_BO_NONCONTIG | EXYNOS_BO_WC;
-	else
-		flags = EXYNOS_BO_CONTIG | EXYNOS_BO_WC;
+	flags = EXYNOS_BO_WC;
 
 	exynos_gem = exynos_drm_gem_create(dev, flags, args->size);
 	if (IS_ERR(exynos_gem)) {
@@ -597,6 +596,17 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device *dev,
 
 	exynos_gem->dma_addr = sg_dma_address(sgt->sgl);
 
+	/*
+	 * Always physically continuous memory if sgt->nents is 1. It
+	 * doesn't care if IOMMU is supported but EXYNOS_BO_NONCONTIG
+	 * flag will be cleared. It will mean the memory is continuous
+	 * for device. EXYNOS_BO_NONCONTIG flag will be set if not both.
+	 */
+	if (sgt->nents == 1 || is_drm_iommu_supported(dev))
+		exynos_gem->flags &= ~EXYNOS_BO_NONCONTIG;
+	else
+		exynos_gem->flags |= EXYNOS_BO_NONCONTIG;
+
 	npages = exynos_gem->size >> PAGE_SHIFT;
 	exynos_gem->pages = drm_malloc_ab(npages, sizeof(struct page *));
 	if (!exynos_gem->pages) {
@@ -611,19 +621,6 @@ exynos_drm_gem_prime_import_sg_table(struct drm_device *dev,
 
 	exynos_gem->sgt = sgt;
 
-	if (sgt->nents == 1) {
-		/* always physically continuous memory if sgt->nents is 1. */
-		exynos_gem->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->flags |= EXYNOS_BO_NONCONTIG;
-	}
-
 	return &exynos_gem->base;
 
 err_free_large:
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index f47daec776e6..e9eb5631f322 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -16,8 +16,6 @@
 
 #define to_exynos_gem(x)	container_of(x, struct exynos_drm_gem, base)
 
-#define IS_NONCONTIG_BUFFER(f)		(f & EXYNOS_BO_NONCONTIG)
-
 /*
  * exynos drm buffer structure.
  *
diff --git a/include/uapi/drm/exynos_drm.h b/include/uapi/drm/exynos_drm.h
index 18f0601f84d1..1d7c80734e43 100644
--- a/include/uapi/drm/exynos_drm.h
+++ b/include/uapi/drm/exynos_drm.h
@@ -76,7 +76,10 @@ struct drm_exynos_vidi_connection {
 
 /* memory type definitions. */
 enum e_drm_exynos_gem_mem_type {
-	/* Physically Continuous memory and used as default. */
+	/*
+	 * Physically Continuous memory or Continuous memory for device
+	 * on IOMMU. Used as default.
+	 */
 	EXYNOS_BO_CONTIG	= 0 << 0,
 	/* Physically Non-Continuous memory. */
 	EXYNOS_BO_NONCONTIG	= 1 << 0,
-- 
1.9.1



More information about the dri-devel mailing list