Commit dcf9af82 authored by Inki Dae's avatar Inki Dae

drm/exynos: fixed page align and code clean.

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: default avatarInki Dae <inki.dae@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
parent 62fb376e
...@@ -41,7 +41,7 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, ...@@ -41,7 +41,7 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
DRM_DEBUG_KMS("%s\n", __FILE__); DRM_DEBUG_KMS("%s\n", __FILE__);
if (flags & EXYNOS_BO_NONCONTIG) { if (IS_NONCONTIG_BUFFER(flags)) {
DRM_DEBUG_KMS("not support allocation type.\n"); DRM_DEBUG_KMS("not support allocation type.\n");
return -EINVAL; return -EINVAL;
} }
...@@ -52,13 +52,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, ...@@ -52,13 +52,13 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
} }
if (buf->size >= SZ_1M) { if (buf->size >= SZ_1M) {
npages = (buf->size >> SECTION_SHIFT) + 1; npages = buf->size >> SECTION_SHIFT;
page_size = SECTION_SIZE; page_size = SECTION_SIZE;
} else if (buf->size >= SZ_64K) { } else if (buf->size >= SZ_64K) {
npages = (buf->size >> 16) + 1; npages = buf->size >> 16;
page_size = SZ_64K; page_size = SZ_64K;
} else { } else {
npages = (buf->size >> PAGE_SHIFT) + 1; npages = buf->size >> PAGE_SHIFT;
page_size = PAGE_SIZE; page_size = PAGE_SIZE;
} }
...@@ -119,9 +119,6 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, ...@@ -119,9 +119,6 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
buf->pages[i] = phys_to_page(start_addr); 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", DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n",
(unsigned long)buf->kvaddr, (unsigned long)buf->kvaddr,
(unsigned long)buf->dma_addr, (unsigned long)buf->dma_addr,
...@@ -150,7 +147,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev, ...@@ -150,7 +147,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev,
* non-continuous memory would be released by exynos * non-continuous memory would be released by exynos
* gem framework. * gem framework.
*/ */
if (flags & EXYNOS_BO_NONCONTIG) { if (IS_NONCONTIG_BUFFER(flags)) {
DRM_DEBUG_KMS("not support allocation type.\n"); DRM_DEBUG_KMS("not support allocation type.\n");
return; return;
} }
......
...@@ -56,9 +56,28 @@ static unsigned int convert_to_vm_err_msg(int msg) ...@@ -56,9 +56,28 @@ static unsigned int convert_to_vm_err_msg(int msg)
return out_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, 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, ...@@ -319,10 +338,17 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
struct exynos_drm_gem_buf *buf; struct exynos_drm_gem_buf *buf;
int ret; int ret;
size = roundup(size, PAGE_SIZE); if (!size) {
DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, 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); buf = exynos_drm_init_buf(dev, size);
if (!buf) if (!buf)
...@@ -331,7 +357,7 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, ...@@ -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); exynos_gem_obj = exynos_drm_gem_init(dev, size);
if (!exynos_gem_obj) { if (!exynos_gem_obj) {
ret = -ENOMEM; ret = -ENOMEM;
goto err; goto err_fini_buf;
} }
exynos_gem_obj->buffer = buf; exynos_gem_obj->buffer = buf;
...@@ -347,18 +373,19 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, ...@@ -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); ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base);
if (ret < 0) { if (ret < 0) {
drm_gem_object_release(&exynos_gem_obj->base); drm_gem_object_release(&exynos_gem_obj->base);
goto err; goto err_fini_buf;
} }
} else { } else {
ret = exynos_drm_alloc_buf(dev, buf, flags); ret = exynos_drm_alloc_buf(dev, buf, flags);
if (ret < 0) { if (ret < 0) {
drm_gem_object_release(&exynos_gem_obj->base); drm_gem_object_release(&exynos_gem_obj->base);
goto err; goto err_fini_buf;
} }
} }
return exynos_gem_obj; return exynos_gem_obj;
err:
err_fini_buf:
exynos_drm_fini_buf(dev, buf); exynos_drm_fini_buf(dev, buf);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
#define to_exynos_gem_obj(x) container_of(x,\ #define to_exynos_gem_obj(x) container_of(x,\
struct exynos_drm_gem_obj, base) struct exynos_drm_gem_obj, base)
#define IS_NONCONTIG_BUFFER(f) (f & EXYNOS_BO_NONCONTIG)
/* /*
* exynos drm gem buffer structure. * exynos drm gem buffer structure.
* *
......
...@@ -96,7 +96,8 @@ struct drm_exynos_plane_set_zpos { ...@@ -96,7 +96,8 @@ struct drm_exynos_plane_set_zpos {
/* memory type definitions. */ /* memory type definitions. */
enum e_drm_exynos_gem_mem_type { enum e_drm_exynos_gem_mem_type {
/* Physically Non-Continuous memory. */ /* 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 #define DRM_EXYNOS_GEM_CREATE 0x00
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment