[PATCH 1/2] drm/exynos: fixed page align and code clean.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



1M section, 64k page count also should be rounded up so this patch
rounds up them and caculates page count of them properly and also
checks memory flags from user.

Signed-off-by: Inki Dae <inki.dae@xxxxxxxxxxx>
Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx>
---
 drivers/gpu/drm/exynos/exynos_drm_buf.c |   13 +++-----
 drivers/gpu/drm/exynos/exynos_drm_gem.c |   45 ++++++++++++++++++++++++------
 drivers/gpu/drm/exynos/exynos_drm_gem.h |    2 +
 include/drm/exynos_drm.h                |    3 +-
 4 files changed, 45 insertions(+), 18 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c
index 4a3a5f7..52d42cd 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
@@ -41,7 +41,7 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
 
 	DRM_DEBUG_KMS("%s\n", __FILE__);
 
-	if (flags & EXYNOS_BO_NONCONTIG) {
+	if (IS_NONCONTIG_BUFFER(flags)) {
 		DRM_DEBUG_KMS("not support allocation type.\n");
 		return -EINVAL;
 	}
@@ -52,13 +52,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
 	}
 
 	if (buf->size >= SZ_1M) {
-		npages = (buf->size >> SECTION_SHIFT) + 1;
+		npages = buf->size >> SECTION_SHIFT;
 		page_size = SECTION_SIZE;
 	} else if (buf->size >= SZ_64K) {
-		npages = (buf->size >> 16) + 1;
+		npages = buf->size >> 16;
 		page_size = SZ_64K;
 	} else {
-		npages = (buf->size >> PAGE_SHIFT) + 1;
+		npages = buf->size >> PAGE_SHIFT;
 		page_size = PAGE_SIZE;
 	}
 
@@ -119,9 +119,6 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
 
 	buf->pages[i] = phys_to_page(start_addr);
 
-	sgl = sg_next(sgl);
-	sg_set_page(sgl, buf->pages[i+1], end_addr - start_addr, 0);
-
 	DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n",
 			(unsigned long)buf->kvaddr,
 			(unsigned long)buf->dma_addr,
@@ -150,7 +147,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev,
 	 * non-continuous memory would be released by exynos
 	 * gem framework.
 	 */
-	if (flags & EXYNOS_BO_NONCONTIG) {
+	if (IS_NONCONTIG_BUFFER(flags)) {
 		DRM_DEBUG_KMS("not support allocation type.\n");
 		return;
 	}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index fa1aa94..26d5197 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -56,9 +56,28 @@ static unsigned int convert_to_vm_err_msg(int msg)
 	return out_msg;
 }
 
-static unsigned int mask_gem_flags(unsigned int flags)
+static int check_gem_flags(unsigned int flags)
 {
-	return flags &= EXYNOS_BO_NONCONTIG;
+	if (flags & ~(EXYNOS_BO_MASK)) {
+		DRM_ERROR("invalid flags.\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static unsigned long roundup_gem_size(unsigned long size, unsigned int flags)
+{
+	if (!IS_NONCONTIG_BUFFER(flags)) {
+		if (size >= SZ_1M)
+			return roundup(size, SECTION_SIZE);
+		else if (size >= SZ_64K)
+			return roundup(size, SZ_64K);
+		else
+			goto out;
+	}
+out:
+	return roundup(size, PAGE_SIZE);
 }
 
 static struct page **exynos_gem_get_pages(struct drm_gem_object *obj,
@@ -319,10 +338,17 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
 	struct exynos_drm_gem_buf *buf;
 	int ret;
 
-	size = roundup(size, PAGE_SIZE);
-	DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size);
+	if (!size) {
+		DRM_ERROR("invalid size.\n");
+		return ERR_PTR(-EINVAL);
+	}
 
-	flags = mask_gem_flags(flags);
+	size = roundup_gem_size(size, flags);
+	DRM_DEBUG_KMS("%s\n", __FILE__);
+
+	ret = check_gem_flags(flags);
+	if (ret)
+		return ERR_PTR(ret);
 
 	buf = exynos_drm_init_buf(dev, size);
 	if (!buf)
@@ -331,7 +357,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
 	exynos_gem_obj = exynos_drm_gem_init(dev, size);
 	if (!exynos_gem_obj) {
 		ret = -ENOMEM;
-		goto err;
+		goto err_fini_buf;
 	}
 
 	exynos_gem_obj->buffer = buf;
@@ -347,18 +373,19 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
 		ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base);
 		if (ret < 0) {
 			drm_gem_object_release(&exynos_gem_obj->base);
-			goto err;
+			goto err_fini_buf;
 		}
 	} else {
 		ret = exynos_drm_alloc_buf(dev, buf, flags);
 		if (ret < 0) {
 			drm_gem_object_release(&exynos_gem_obj->base);
-			goto err;
+			goto err_fini_buf;
 		}
 	}
 
 	return exynos_gem_obj;
-err:
+
+err_fini_buf:
 	exynos_drm_fini_buf(dev, buf);
 	return ERR_PTR(ret);
 }
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index e40fbad..4ed8420 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -29,6 +29,8 @@
 #define to_exynos_gem_obj(x)	container_of(x,\
 			struct exynos_drm_gem_obj, base)
 
+#define IS_NONCONTIG_BUFFER(f)		(f & EXYNOS_BO_NONCONTIG)
+
 /*
  * exynos drm gem buffer structure.
  *
diff --git a/include/drm/exynos_drm.h b/include/drm/exynos_drm.h
index 3963116..1bb2d47 100644
--- a/include/drm/exynos_drm.h
+++ b/include/drm/exynos_drm.h
@@ -96,7 +96,8 @@ struct drm_exynos_plane_set_zpos {
 /* memory type definitions. */
 enum e_drm_exynos_gem_mem_type {
 	/* Physically Non-Continuous memory. */
-	EXYNOS_BO_NONCONTIG	= 1 << 0
+	EXYNOS_BO_NONCONTIG	= 1 << 0,
+	EXYNOS_BO_MASK		= EXYNOS_BO_NONCONTIG
 };
 
 #define DRM_EXYNOS_GEM_CREATE		0x00
-- 
1.7.4.1

_______________________________________________
dri-devel mailing list
dri-devel@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[Index of Archives]     [Linux DRI Users]     [Linux Intel Graphics]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux