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

Reply via email to