diff options
| author | Joonyoung Shim <jy0922.shim@samsung.com> | 2015-07-28 04:53:20 -0400 |
|---|---|---|
| committer | Inki Dae <inki.dae@samsung.com> | 2015-08-16 00:33:44 -0400 |
| commit | 67e93c808b486817193dbd1ff93ee03adb9eef28 (patch) | |
| tree | 2bf9929e0b5a8200dbd836d25dc162dddfc768f2 /drivers/gpu | |
| parent | 0e9a2ee3bc1ee24be519312453ef93288b545ad3 (diff) | |
drm/exynos: stop copying sg table
Already struct exynos_drm_gem_buf has pages of the buffer, so we don't
need to copy from sg table of the buffer to sg table of dma-buf
attachment, just can make sg table from pages of the buffer.
Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 55 | ||||
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_gem.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_gem.h | 2 |
3 files changed, 20 insertions, 40 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index d10f9b602bf7..619ecddf35fa 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | #include <linux/dma-buf.h> | 18 | #include <linux/dma-buf.h> |
| 19 | 19 | ||
| 20 | struct exynos_drm_dmabuf_attachment { | 20 | struct exynos_drm_dmabuf_attachment { |
| 21 | struct sg_table sgt; | 21 | struct sg_table *sgt; |
| 22 | enum dma_data_direction dir; | 22 | enum dma_data_direction dir; |
| 23 | bool is_mapped; | 23 | bool is_mapped; |
| 24 | }; | 24 | }; |
| @@ -53,13 +53,15 @@ static void exynos_gem_detach_dma_buf(struct dma_buf *dmabuf, | |||
| 53 | if (!exynos_attach) | 53 | if (!exynos_attach) |
| 54 | return; | 54 | return; |
| 55 | 55 | ||
| 56 | sgt = &exynos_attach->sgt; | 56 | sgt = exynos_attach->sgt; |
| 57 | 57 | if (sgt) { | |
| 58 | if (exynos_attach->dir != DMA_NONE) | 58 | if (exynos_attach->dir != DMA_NONE) |
| 59 | dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, | 59 | dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, |
| 60 | exynos_attach->dir); | 60 | exynos_attach->dir); |
| 61 | sg_free_table(sgt); | ||
| 62 | } | ||
| 61 | 63 | ||
| 62 | sg_free_table(sgt); | 64 | kfree(sgt); |
| 63 | kfree(exynos_attach); | 65 | kfree(exynos_attach); |
| 64 | attach->priv = NULL; | 66 | attach->priv = NULL; |
| 65 | } | 67 | } |
| @@ -70,16 +72,13 @@ static struct sg_table * | |||
| 70 | { | 72 | { |
| 71 | struct exynos_drm_dmabuf_attachment *exynos_attach = attach->priv; | 73 | struct exynos_drm_dmabuf_attachment *exynos_attach = attach->priv; |
| 72 | struct exynos_drm_gem_obj *gem_obj = dma_buf_to_obj(attach->dmabuf); | 74 | struct exynos_drm_gem_obj *gem_obj = dma_buf_to_obj(attach->dmabuf); |
| 73 | struct drm_device *dev = gem_obj->base.dev; | ||
| 74 | struct exynos_drm_gem_buf *buf; | 75 | struct exynos_drm_gem_buf *buf; |
| 75 | struct scatterlist *rd, *wr; | 76 | struct sg_table *sgt; |
| 76 | struct sg_table *sgt = NULL; | 77 | int npages; |
| 77 | unsigned int i; | ||
| 78 | int nents, ret; | ||
| 79 | 78 | ||
| 80 | /* just return current sgt if already requested. */ | 79 | /* just return current sgt if already requested. */ |
| 81 | if (exynos_attach->dir == dir && exynos_attach->is_mapped) | 80 | if (exynos_attach->dir == dir && exynos_attach->is_mapped) |
| 82 | return &exynos_attach->sgt; | 81 | return exynos_attach->sgt; |
| 83 | 82 | ||
| 84 | buf = gem_obj->buffer; | 83 | buf = gem_obj->buffer; |
| 85 | if (!buf) { | 84 | if (!buf) { |
| @@ -87,42 +86,29 @@ static struct sg_table * | |||
| 87 | return ERR_PTR(-ENOMEM); | 86 | return ERR_PTR(-ENOMEM); |
| 88 | } | 87 | } |
| 89 | 88 | ||
| 90 | sgt = &exynos_attach->sgt; | 89 | npages = buf->size >> PAGE_SHIFT; |
| 91 | 90 | ||
| 92 | ret = sg_alloc_table(sgt, buf->sgt->orig_nents, GFP_KERNEL); | 91 | sgt = drm_prime_pages_to_sg(buf->pages, npages); |
| 93 | if (ret) { | 92 | if (IS_ERR(sgt)) |
| 94 | DRM_ERROR("failed to alloc sgt.\n"); | 93 | goto err; |
| 95 | return ERR_PTR(-ENOMEM); | ||
| 96 | } | ||
| 97 | |||
| 98 | mutex_lock(&dev->struct_mutex); | ||
| 99 | |||
| 100 | rd = buf->sgt->sgl; | ||
| 101 | wr = sgt->sgl; | ||
| 102 | for (i = 0; i < sgt->orig_nents; ++i) { | ||
| 103 | sg_set_page(wr, sg_page(rd), rd->length, rd->offset); | ||
| 104 | rd = sg_next(rd); | ||
| 105 | wr = sg_next(wr); | ||
| 106 | } | ||
| 107 | 94 | ||
| 108 | if (dir != DMA_NONE) { | 95 | if (dir != DMA_NONE) { |
| 109 | nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir); | 96 | if (!dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir)) { |
| 110 | if (!nents) { | ||
| 111 | DRM_ERROR("failed to map sgl with iommu.\n"); | 97 | DRM_ERROR("failed to map sgl with iommu.\n"); |
| 112 | sg_free_table(sgt); | 98 | sg_free_table(sgt); |
| 113 | sgt = ERR_PTR(-EIO); | 99 | sgt = ERR_PTR(-EIO); |
| 114 | goto err_unlock; | 100 | goto err; |
| 115 | } | 101 | } |
| 116 | } | 102 | } |
| 117 | 103 | ||
| 118 | exynos_attach->is_mapped = true; | 104 | exynos_attach->is_mapped = true; |
| 105 | exynos_attach->sgt = sgt; | ||
| 119 | exynos_attach->dir = dir; | 106 | exynos_attach->dir = dir; |
| 120 | attach->priv = exynos_attach; | 107 | attach->priv = exynos_attach; |
| 121 | 108 | ||
| 122 | DRM_DEBUG_PRIME("buffer size = 0x%lx\n", buf->size); | 109 | DRM_DEBUG_PRIME("buffer size = 0x%lx\n", buf->size); |
| 123 | 110 | ||
| 124 | err_unlock: | 111 | err: |
| 125 | mutex_unlock(&dev->struct_mutex); | ||
| 126 | return sgt; | 112 | return sgt; |
| 127 | } | 113 | } |
| 128 | 114 | ||
| @@ -280,7 +266,6 @@ struct drm_gem_object *exynos_dmabuf_prime_import(struct drm_device *drm_dev, | |||
| 280 | } | 266 | } |
| 281 | 267 | ||
| 282 | exynos_gem_obj->buffer = buffer; | 268 | exynos_gem_obj->buffer = buffer; |
| 283 | buffer->sgt = sgt; | ||
| 284 | exynos_gem_obj->base.import_attach = attach; | 269 | exynos_gem_obj->base.import_attach = attach; |
| 285 | 270 | ||
| 286 | DRM_DEBUG_PRIME("dma_addr = %pad, size = 0x%lx\n", &buffer->dma_addr, | 271 | DRM_DEBUG_PRIME("dma_addr = %pad, size = 0x%lx\n", &buffer->dma_addr, |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 4d9a09907607..fa04b9add09a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c | |||
| @@ -455,9 +455,6 @@ void exynos_drm_gem_free_object(struct drm_gem_object *obj) | |||
| 455 | exynos_gem_obj = to_exynos_gem_obj(obj); | 455 | exynos_gem_obj = to_exynos_gem_obj(obj); |
| 456 | buf = exynos_gem_obj->buffer; | 456 | buf = exynos_gem_obj->buffer; |
| 457 | 457 | ||
| 458 | if (obj->import_attach) | ||
| 459 | drm_prime_gem_destroy(obj, buf->sgt); | ||
| 460 | |||
| 461 | exynos_drm_gem_destroy(to_exynos_gem_obj(obj)); | 458 | exynos_drm_gem_destroy(to_exynos_gem_obj(obj)); |
| 462 | } | 459 | } |
| 463 | 460 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index 6f42e2248288..5979f22828d4 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h | |||
| @@ -30,7 +30,6 @@ | |||
| 30 | * device address with IOMMU. | 30 | * device address with IOMMU. |
| 31 | * @write: whether pages will be written to by the caller. | 31 | * @write: whether pages will be written to by the caller. |
| 32 | * @pages: Array of backing pages. | 32 | * @pages: Array of backing pages. |
| 33 | * @sgt: sg table to transfer page data. | ||
| 34 | * @size: size of allocated memory region. | 33 | * @size: size of allocated memory region. |
| 35 | * @pfnmap: indicate whether memory region from userptr is mmaped with | 34 | * @pfnmap: indicate whether memory region from userptr is mmaped with |
| 36 | * VM_PFNMAP or not. | 35 | * VM_PFNMAP or not. |
| @@ -43,7 +42,6 @@ struct exynos_drm_gem_buf { | |||
| 43 | struct dma_attrs dma_attrs; | 42 | struct dma_attrs dma_attrs; |
| 44 | unsigned int write; | 43 | unsigned int write; |
| 45 | struct page **pages; | 44 | struct page **pages; |
| 46 | struct sg_table *sgt; | ||
| 47 | unsigned long size; | 45 | unsigned long size; |
| 48 | bool pfnmap; | 46 | bool pfnmap; |
| 49 | }; | 47 | }; |
