aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_buf.c16
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_dmabuf.c18
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.c14
3 files changed, 19 insertions, 29 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c
index 24994ba10e28..9260dfb3b7e5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
@@ -90,23 +90,12 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
90 } 90 }
91 } 91 }
92 92
93 buf->sgt = drm_prime_pages_to_sg(buf->pages, nr_pages);
94 if (IS_ERR(buf->sgt)) {
95 DRM_ERROR("failed to get sg table.\n");
96 ret = PTR_ERR(buf->sgt);
97 goto err_free_attrs;
98 }
99
100 DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n", 93 DRM_DEBUG_KMS("dma_addr(0x%lx), size(0x%lx)\n",
101 (unsigned long)buf->dma_addr, 94 (unsigned long)buf->dma_addr,
102 buf->size); 95 buf->size);
103 96
104 return ret; 97 return ret;
105 98
106err_free_attrs:
107 dma_free_attrs(dev->dev, buf->size, buf->pages,
108 (dma_addr_t)buf->dma_addr, &buf->dma_attrs);
109 buf->dma_addr = (dma_addr_t)NULL;
110err_free: 99err_free:
111 if (!is_drm_iommu_supported(dev)) 100 if (!is_drm_iommu_supported(dev))
112 drm_free_large(buf->pages); 101 drm_free_large(buf->pages);
@@ -126,11 +115,6 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev,
126 (unsigned long)buf->dma_addr, 115 (unsigned long)buf->dma_addr,
127 buf->size); 116 buf->size);
128 117
129 sg_free_table(buf->sgt);
130
131 kfree(buf->sgt);
132 buf->sgt = NULL;
133
134 if (!is_drm_iommu_supported(dev)) { 118 if (!is_drm_iommu_supported(dev)) {
135 dma_free_attrs(dev->dev, buf->size, buf->cookie, 119 dma_free_attrs(dev->dev, buf->size, buf->cookie,
136 (dma_addr_t)buf->dma_addr, &buf->dma_attrs); 120 (dma_addr_t)buf->dma_addr, &buf->dma_attrs);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
index cd485c091b30..d10f9b602bf7 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c
@@ -203,6 +203,7 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
203 struct scatterlist *sgl; 203 struct scatterlist *sgl;
204 struct exynos_drm_gem_obj *exynos_gem_obj; 204 struct exynos_drm_gem_obj *exynos_gem_obj;
205 struct exynos_drm_gem_buf *buffer; 205 struct exynos_drm_gem_buf *buffer;
206 int npages;
206 int ret; 207 int ret;
207 208
208 /* is this one of own objects? */ 209 /* is this one of own objects? */
@@ -251,6 +252,20 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
251 buffer->size = dma_buf->size; 252 buffer->size = dma_buf->size;
252 buffer->dma_addr = sg_dma_address(sgl); 253 buffer->dma_addr = sg_dma_address(sgl);
253 254
255 npages = dma_buf->size >> PAGE_SHIFT;
256 buffer->pages = drm_malloc_ab(npages, sizeof(struct page *));
257 if (!buffer->pages) {
258 ret = -ENOMEM;
259 goto err_free_gem;
260 }
261
262 ret = drm_prime_sg_to_page_addr_arrays(sgt, buffer->pages, NULL,
263 npages);
264 if (ret < 0) {
265 drm_free_large(buffer->pages);
266 goto err_free_gem;
267 }
268
254 if (sgt->nents == 1) { 269 if (sgt->nents == 1) {
255 /* always physically continuous memory if sgt->nents is 1. */ 270 /* always physically continuous memory if sgt->nents is 1. */
256 exynos_gem_obj->flags |= EXYNOS_BO_CONTIG; 271 exynos_gem_obj->flags |= EXYNOS_BO_CONTIG;
@@ -273,6 +288,9 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev,
273 288
274 return &exynos_gem_obj->base; 289 return &exynos_gem_obj->base;
275 290
291err_free_gem:
292 drm_gem_object_release(&exynos_gem_obj->base);
293 kfree(exynos_gem_obj);
276err_free_buffer: 294err_free_buffer:
277 kfree(buffer); 295 kfree(buffer);
278 buffer = NULL; 296 buffer = NULL;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 0d5b9698d384..d320acd20986 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -83,26 +83,14 @@ static int exynos_drm_gem_map_buf(struct drm_gem_object *obj,
83{ 83{
84 struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); 84 struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
85 struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer; 85 struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer;
86 struct scatterlist *sgl;
87 unsigned long pfn; 86 unsigned long pfn;
88 int i;
89
90 if (!buf->sgt)
91 return -EINTR;
92 87
93 if (page_offset >= (buf->size >> PAGE_SHIFT)) { 88 if (page_offset >= (buf->size >> PAGE_SHIFT)) {
94 DRM_ERROR("invalid page offset\n"); 89 DRM_ERROR("invalid page offset\n");
95 return -EINVAL; 90 return -EINVAL;
96 } 91 }
97 92
98 sgl = buf->sgt->sgl; 93 pfn = page_to_pfn(buf->pages[page_offset]);
99 for_each_sg(buf->sgt->sgl, sgl, buf->sgt->nents, i) {
100 if (page_offset < (sgl->length >> PAGE_SHIFT))
101 break;
102 page_offset -= (sgl->length >> PAGE_SHIFT);
103 }
104
105 pfn = __phys_to_pfn(sg_phys(sgl)) + page_offset;
106 94
107 return vm_insert_mixed(vma, f_vaddr, pfn); 95 return vm_insert_mixed(vma, f_vaddr, pfn);
108} 96}