drm/rockchip: Only alloc a kmap for fbdev gem object
authorDaniel Kurtz <djkurtz@chromium.org>
Mon, 12 Jan 2015 06:58:23 +0000 (14:58 +0800)
committerMark Yao <mark.yao@rock-chips.com>
Mon, 16 Mar 2015 02:07:12 +0000 (10:07 +0800)
In general, the data in drm/rockchip GEM objects is never accessed by
the kernel.  The objects are either accessed by a GPU, by display
controller DMA, or by mmap'ing them to user space.  Thus, these
buffers need not be mapped into kernel address space.

The only exception is the fbdev framebuffer(s), which may be written
in-kernel by fbcon.

Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
drivers/gpu/drm/rockchip/rockchip_drm_gem.c
drivers/gpu/drm/rockchip/rockchip_drm_gem.h

index a5d889a8716bd776274462af116d873163ac5f87..17d19542c8a9ec5c39f7ae4016050a3b2783b411 100644 (file)
@@ -71,7 +71,7 @@ static int rockchip_drm_fbdev_create(struct drm_fb_helper *helper,
 
        size = mode_cmd.pitches[0] * mode_cmd.height;
 
-       rk_obj = rockchip_gem_create_object(dev, size);
+       rk_obj = rockchip_gem_create_object(dev, size, true);
        if (IS_ERR(rk_obj))
                return -ENOMEM;
 
index 7ca8799ef78498ca84cc3a48f1265d2f1ce2f6c9..eb2282cc4a56507819a5ab638af504499157157a 100644 (file)
@@ -22,7 +22,8 @@
 #include "rockchip_drm_drv.h"
 #include "rockchip_drm_gem.h"
 
-static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj)
+static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj,
+                                 bool alloc_kmap)
 {
        struct drm_gem_object *obj = &rk_obj->base;
        struct drm_device *drm = obj->dev;
@@ -30,7 +31,9 @@ static int rockchip_gem_alloc_buf(struct rockchip_gem_object *rk_obj)
        init_dma_attrs(&rk_obj->dma_attrs);
        dma_set_attr(DMA_ATTR_WRITE_COMBINE, &rk_obj->dma_attrs);
 
-       /* TODO(djkurtz): Use DMA_ATTR_NO_KERNEL_MAPPING except for fbdev */
+       if (!alloc_kmap)
+               dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &rk_obj->dma_attrs);
+
        rk_obj->kvaddr = dma_alloc_attrs(drm->dev, obj->size,
                                         &rk_obj->dma_addr, GFP_KERNEL,
                                         &rk_obj->dma_attrs);
@@ -103,7 +106,8 @@ int rockchip_gem_mmap(struct file *filp, struct vm_area_struct *vma)
 }
 
 struct rockchip_gem_object *
-       rockchip_gem_create_object(struct drm_device *drm, unsigned int size)
+       rockchip_gem_create_object(struct drm_device *drm, unsigned int size,
+                                  bool alloc_kmap)
 {
        struct rockchip_gem_object *rk_obj;
        struct drm_gem_object *obj;
@@ -119,7 +123,7 @@ struct rockchip_gem_object *
 
        drm_gem_private_object_init(drm, obj, size);
 
-       ret = rockchip_gem_alloc_buf(rk_obj);
+       ret = rockchip_gem_alloc_buf(rk_obj, alloc_kmap);
        if (ret)
                goto err_free_rk_obj;
 
@@ -163,7 +167,7 @@ rockchip_gem_create_with_handle(struct drm_file *file_priv,
        struct drm_gem_object *obj;
        int ret;
 
-       rk_obj = rockchip_gem_create_object(drm, size);
+       rk_obj = rockchip_gem_create_object(drm, size, false);
        if (IS_ERR(rk_obj))
                return ERR_CAST(rk_obj);
 
@@ -282,6 +286,9 @@ void *rockchip_gem_prime_vmap(struct drm_gem_object *obj)
 {
        struct rockchip_gem_object *rk_obj = to_rockchip_obj(obj);
 
+       if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, &rk_obj->dma_attrs))
+               return NULL;
+
        return rk_obj->kvaddr;
 }
 
index 67bcebe90003dbf5674e752aadd86f9041d6844a..ad22618473a488b10a10e1155f85bc79e1c8870e 100644 (file)
@@ -41,7 +41,8 @@ int rockchip_gem_mmap_buf(struct drm_gem_object *obj,
                          struct vm_area_struct *vma);
 
 struct rockchip_gem_object *
-       rockchip_gem_create_object(struct drm_device *drm, unsigned int size);
+       rockchip_gem_create_object(struct drm_device *drm, unsigned int size,
+                                  bool alloc_kmap);
 
 void rockchip_gem_free_object(struct drm_gem_object *obj);