diff options
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_buf.c | 31 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fb.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_gem.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_gem.h | 2 |
5 files changed, 32 insertions, 25 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c index 72bf97b96ba0..9732043d91ec 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_buf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c | |||
@@ -35,6 +35,7 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, | |||
35 | { | 35 | { |
36 | int ret = 0; | 36 | int ret = 0; |
37 | enum dma_attr attr = DMA_ATTR_FORCE_CONTIGUOUS; | 37 | enum dma_attr attr = DMA_ATTR_FORCE_CONTIGUOUS; |
38 | unsigned int nr_pages; | ||
38 | 39 | ||
39 | DRM_DEBUG_KMS("%s\n", __FILE__); | 40 | DRM_DEBUG_KMS("%s\n", __FILE__); |
40 | 41 | ||
@@ -49,40 +50,31 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, | |||
49 | attr = DMA_ATTR_WRITE_COMBINE; | 50 | attr = DMA_ATTR_WRITE_COMBINE; |
50 | 51 | ||
51 | dma_set_attr(attr, &buf->dma_attrs); | 52 | dma_set_attr(attr, &buf->dma_attrs); |
53 | dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &buf->dma_attrs); | ||
52 | 54 | ||
53 | buf->kvaddr = dma_alloc_attrs(dev->dev, buf->size, | 55 | buf->pages = dma_alloc_attrs(dev->dev, buf->size, |
54 | &buf->dma_addr, GFP_KERNEL, &buf->dma_attrs); | 56 | &buf->dma_addr, GFP_KERNEL, &buf->dma_attrs); |
55 | if (!buf->kvaddr) { | 57 | if (!buf->pages) { |
56 | DRM_ERROR("failed to allocate buffer.\n"); | 58 | DRM_ERROR("failed to allocate buffer.\n"); |
57 | return -ENOMEM; | 59 | return -ENOMEM; |
58 | } | 60 | } |
59 | 61 | ||
60 | buf->sgt = kzalloc(sizeof(struct sg_table), GFP_KERNEL); | 62 | nr_pages = buf->size >> PAGE_SHIFT; |
63 | buf->sgt = drm_prime_pages_to_sg(buf->pages, nr_pages); | ||
61 | if (!buf->sgt) { | 64 | if (!buf->sgt) { |
62 | DRM_ERROR("failed to allocate sg table.\n"); | 65 | DRM_ERROR("failed to get sg table.\n"); |
63 | ret = -ENOMEM; | 66 | ret = -ENOMEM; |
64 | goto err_free_attrs; | 67 | goto err_free_attrs; |
65 | } | 68 | } |
66 | 69 | ||
67 | ret = dma_get_sgtable(dev->dev, buf->sgt, buf->kvaddr, buf->dma_addr, | 70 | DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n", |
68 | buf->size); | ||
69 | if (ret < 0) { | ||
70 | DRM_ERROR("failed to get sgtable.\n"); | ||
71 | goto err_free_sgt; | ||
72 | } | ||
73 | |||
74 | DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", | ||
75 | (unsigned long)buf->kvaddr, | ||
76 | (unsigned long)buf->dma_addr, | 71 | (unsigned long)buf->dma_addr, |
77 | buf->size); | 72 | buf->size); |
78 | 73 | ||
79 | return ret; | 74 | return ret; |
80 | 75 | ||
81 | err_free_sgt: | ||
82 | kfree(buf->sgt); | ||
83 | buf->sgt = NULL; | ||
84 | err_free_attrs: | 76 | err_free_attrs: |
85 | dma_free_attrs(dev->dev, buf->size, buf->kvaddr, | 77 | dma_free_attrs(dev->dev, buf->size, buf->pages, |
86 | (dma_addr_t)buf->dma_addr, &buf->dma_attrs); | 78 | (dma_addr_t)buf->dma_addr, &buf->dma_attrs); |
87 | buf->dma_addr = (dma_addr_t)NULL; | 79 | buf->dma_addr = (dma_addr_t)NULL; |
88 | 80 | ||
@@ -99,8 +91,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev, | |||
99 | return; | 91 | return; |
100 | } | 92 | } |
101 | 93 | ||
102 | DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", | 94 | DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n", |
103 | (unsigned long)buf->kvaddr, | ||
104 | (unsigned long)buf->dma_addr, | 95 | (unsigned long)buf->dma_addr, |
105 | buf->size); | 96 | buf->size); |
106 | 97 | ||
@@ -109,7 +100,7 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev, | |||
109 | kfree(buf->sgt); | 100 | kfree(buf->sgt); |
110 | buf->sgt = NULL; | 101 | buf->sgt = NULL; |
111 | 102 | ||
112 | dma_free_attrs(dev->dev, buf->size, buf->kvaddr, | 103 | dma_free_attrs(dev->dev, buf->size, buf->pages, |
113 | (dma_addr_t)buf->dma_addr, &buf->dma_attrs); | 104 | (dma_addr_t)buf->dma_addr, &buf->dma_attrs); |
114 | buf->dma_addr = (dma_addr_t)NULL; | 105 | buf->dma_addr = (dma_addr_t)NULL; |
115 | } | 106 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index 7413f4b729b0..764571c9625a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c | |||
@@ -297,9 +297,7 @@ struct exynos_drm_gem_buf *exynos_drm_fb_buffer(struct drm_framebuffer *fb, | |||
297 | if (!buffer) | 297 | if (!buffer) |
298 | return NULL; | 298 | return NULL; |
299 | 299 | ||
300 | DRM_DEBUG_KMS("vaddr = 0x%lx, dma_addr = 0x%lx\n", | 300 | DRM_DEBUG_KMS("dma_addr = 0x%lx\n", (unsigned long)buffer->dma_addr); |
301 | (unsigned long)buffer->kvaddr, | ||
302 | (unsigned long)buffer->dma_addr); | ||
303 | 301 | ||
304 | return buffer; | 302 | return buffer; |
305 | } | 303 | } |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 885ef235d59c..f433eb7533a9 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c | |||
@@ -65,7 +65,7 @@ static int exynos_drm_fb_mmap(struct fb_info *info, | |||
65 | if (vm_size > buffer->size) | 65 | if (vm_size > buffer->size) |
66 | return -EINVAL; | 66 | return -EINVAL; |
67 | 67 | ||
68 | ret = dma_mmap_attrs(helper->dev->dev, vma, buffer->kvaddr, | 68 | ret = dma_mmap_attrs(helper->dev->dev, vma, buffer->pages, |
69 | buffer->dma_addr, buffer->size, &buffer->dma_attrs); | 69 | buffer->dma_addr, buffer->size, &buffer->dma_attrs); |
70 | if (ret < 0) { | 70 | if (ret < 0) { |
71 | DRM_ERROR("failed to mmap.\n"); | 71 | DRM_ERROR("failed to mmap.\n"); |
@@ -109,6 +109,17 @@ static int exynos_drm_fbdev_update(struct drm_fb_helper *helper, | |||
109 | return -EFAULT; | 109 | return -EFAULT; |
110 | } | 110 | } |
111 | 111 | ||
112 | /* map pages with kernel virtual space. */ | ||
113 | if (!buffer->kvaddr) { | ||
114 | unsigned int nr_pages = buffer->size >> PAGE_SHIFT; | ||
115 | buffer->kvaddr = vmap(buffer->pages, nr_pages, VM_MAP, | ||
116 | pgprot_writecombine(PAGE_KERNEL)); | ||
117 | if (!buffer->kvaddr) { | ||
118 | DRM_ERROR("failed to map pages to kernel space.\n"); | ||
119 | return -EIO; | ||
120 | } | ||
121 | } | ||
122 | |||
112 | /* buffer count to framebuffer always is 1 at booting time. */ | 123 | /* buffer count to framebuffer always is 1 at booting time. */ |
113 | exynos_drm_fb_set_buf_cnt(fb, 1); | 124 | exynos_drm_fb_set_buf_cnt(fb, 1); |
114 | 125 | ||
@@ -305,8 +316,13 @@ err_init: | |||
305 | static void exynos_drm_fbdev_destroy(struct drm_device *dev, | 316 | static void exynos_drm_fbdev_destroy(struct drm_device *dev, |
306 | struct drm_fb_helper *fb_helper) | 317 | struct drm_fb_helper *fb_helper) |
307 | { | 318 | { |
319 | struct exynos_drm_fbdev *exynos_fbd = to_exynos_fbdev(fb_helper); | ||
320 | struct exynos_drm_gem_obj *exynos_gem_obj = exynos_fbd->exynos_gem_obj; | ||
308 | struct drm_framebuffer *fb; | 321 | struct drm_framebuffer *fb; |
309 | 322 | ||
323 | if (exynos_gem_obj->buffer->kvaddr) | ||
324 | vunmap(exynos_gem_obj->buffer->kvaddr); | ||
325 | |||
310 | /* release drm framebuffer and real buffer */ | 326 | /* release drm framebuffer and real buffer */ |
311 | if (fb_helper->fb && fb_helper->fb->funcs) { | 327 | if (fb_helper->fb && fb_helper->fb->funcs) { |
312 | fb = fb_helper->fb; | 328 | fb = fb_helper->fb; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 99227246ce82..d48183e7e056 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c | |||
@@ -400,7 +400,7 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp, | |||
400 | if (vm_size > buffer->size) | 400 | if (vm_size > buffer->size) |
401 | return -EINVAL; | 401 | return -EINVAL; |
402 | 402 | ||
403 | ret = dma_mmap_attrs(drm_dev->dev, vma, buffer->kvaddr, | 403 | ret = dma_mmap_attrs(drm_dev->dev, vma, buffer->pages, |
404 | buffer->dma_addr, buffer->size, | 404 | buffer->dma_addr, buffer->size, |
405 | &buffer->dma_attrs); | 405 | &buffer->dma_attrs); |
406 | if (ret < 0) { | 406 | if (ret < 0) { |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index d3ea106a9a77..f11f2afd5bfc 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h | |||
@@ -40,6 +40,7 @@ | |||
40 | * - this address could be physical address without IOMMU and | 40 | * - this address could be physical address without IOMMU and |
41 | * device address with IOMMU. | 41 | * device address with IOMMU. |
42 | * @write: whether pages will be written to by the caller. | 42 | * @write: whether pages will be written to by the caller. |
43 | * @pages: Array of backing pages. | ||
43 | * @sgt: sg table to transfer page data. | 44 | * @sgt: sg table to transfer page data. |
44 | * @size: size of allocated memory region. | 45 | * @size: size of allocated memory region. |
45 | * @pfnmap: indicate whether memory region from userptr is mmaped with | 46 | * @pfnmap: indicate whether memory region from userptr is mmaped with |
@@ -51,6 +52,7 @@ struct exynos_drm_gem_buf { | |||
51 | dma_addr_t dma_addr; | 52 | dma_addr_t dma_addr; |
52 | struct dma_attrs dma_attrs; | 53 | struct dma_attrs dma_attrs; |
53 | unsigned int write; | 54 | unsigned int write; |
55 | struct page **pages; | ||
54 | struct sg_table *sgt; | 56 | struct sg_table *sgt; |
55 | unsigned long size; | 57 | unsigned long size; |
56 | bool pfnmap; | 58 | bool pfnmap; |