aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/exynos/exynos_drm_buf.c
diff options
context:
space:
mode:
authorInki Dae <inki.dae@samsung.com>2012-10-20 10:53:42 -0400
committerInki Dae <daeinki@gmail.com>2012-11-29 06:30:35 -0500
commit0519f9a12d0113caab78980c48a7902d2bd40c2c (patch)
tree77d49f8f1e637edf253b6688a2366d8c9e933bfd /drivers/gpu/drm/exynos/exynos_drm_buf.c
parent549a17e447d72bab648c783abbba98f3bd5b4dd5 (diff)
drm/exynos: add iommu support for exynos drm framework
Changelog v4: - fix condition to drm_iommu_detach_device funtion. Changelog v3: - add dma_parms->max_segment_size setting of drm_device->dev. - use devm_kzalloc instead of kzalloc. Changelog v2: - fix iommu attach condition. . check archdata.dma_ops of drm device instead of subdrv device's one. - code clean to exynos_drm_iommu.c file. . remove '#ifdef CONFIG_ARM_DMA_USE_IOMMU' from exynos_drm_iommu.c and add it to driver/gpu/drm/exynos/Kconfig. Changelog v1: This patch adds iommu support for exynos drm framework with dma mapping api. In this patch, we used dma mapping api to allocate physical memory and maps it with iommu table and removed some existing codes and added new some codes for iommu support. GEM allocation requires one device object to use dma mapping api so this patch uses one iommu mapping for all sub drivers. In other words, all sub drivers have same iommu mapping. Signed-off-by: Inki Dae <inki.dae@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_buf.c')
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_buf.c88
1 files changed, 32 insertions, 56 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c
index 118c117b3226..48c589661cbe 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
@@ -33,71 +33,58 @@
33static int lowlevel_buffer_allocate(struct drm_device *dev, 33static int lowlevel_buffer_allocate(struct drm_device *dev,
34 unsigned int flags, struct exynos_drm_gem_buf *buf) 34 unsigned int flags, struct exynos_drm_gem_buf *buf)
35{ 35{
36 dma_addr_t start_addr; 36 int ret = 0;
37 unsigned int npages, i = 0; 37 unsigned int npages, i = 0;
38 struct scatterlist *sgl; 38 struct scatterlist *sgl;
39 int ret = 0; 39 enum dma_attr attr = DMA_ATTR_FORCE_CONTIGUOUS;
40 40
41 DRM_DEBUG_KMS("%s\n", __FILE__); 41 DRM_DEBUG_KMS("%s\n", __FILE__);
42 42
43 if (IS_NONCONTIG_BUFFER(flags)) {
44 DRM_DEBUG_KMS("not support allocation type.\n");
45 return -EINVAL;
46 }
47
48 if (buf->dma_addr) { 43 if (buf->dma_addr) {
49 DRM_DEBUG_KMS("already allocated.\n"); 44 DRM_DEBUG_KMS("already allocated.\n");
50 return 0; 45 return 0;
51 } 46 }
52 47
53 if (buf->size >= SZ_1M) { 48 init_dma_attrs(&buf->dma_attrs);
54 npages = buf->size >> SECTION_SHIFT; 49
55 buf->page_size = SECTION_SIZE; 50 if (flags & EXYNOS_BO_NONCONTIG)
56 } else if (buf->size >= SZ_64K) { 51 attr = DMA_ATTR_WRITE_COMBINE;
57 npages = buf->size >> 16; 52
58 buf->page_size = SZ_64K; 53 dma_set_attr(attr, &buf->dma_attrs);
59 } else { 54
60 npages = buf->size >> PAGE_SHIFT; 55 buf->kvaddr = dma_alloc_attrs(dev->dev, buf->size,
61 buf->page_size = PAGE_SIZE; 56 &buf->dma_addr, GFP_KERNEL, &buf->dma_attrs);
57 if (!buf->kvaddr) {
58 DRM_ERROR("failed to allocate buffer.\n");
59 return -ENOMEM;
62 } 60 }
63 61
64 buf->sgt = kzalloc(sizeof(struct sg_table), GFP_KERNEL); 62 buf->sgt = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
65 if (!buf->sgt) { 63 if (!buf->sgt) {
66 DRM_ERROR("failed to allocate sg table.\n"); 64 DRM_ERROR("failed to allocate sg table.\n");
67 return -ENOMEM; 65 ret = -ENOMEM;
66 goto err_free_attrs;
68 } 67 }
69 68
70 ret = sg_alloc_table(buf->sgt, npages, GFP_KERNEL); 69 ret = dma_get_sgtable(dev->dev, buf->sgt, buf->kvaddr, buf->dma_addr,
70 buf->size);
71 if (ret < 0) { 71 if (ret < 0) {
72 DRM_ERROR("failed to initialize sg table.\n"); 72 DRM_ERROR("failed to get sgtable.\n");
73 kfree(buf->sgt); 73 goto err_free_sgt;
74 buf->sgt = NULL;
75 return -ENOMEM;
76 } 74 }
77 75
78 buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size, 76 npages = buf->sgt->nents;
79 &buf->dma_addr, GFP_KERNEL);
80 if (!buf->kvaddr) {
81 DRM_ERROR("failed to allocate buffer.\n");
82 ret = -ENOMEM;
83 goto err1;
84 }
85 77
86 buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL); 78 buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL);
87 if (!buf->pages) { 79 if (!buf->pages) {
88 DRM_ERROR("failed to allocate pages.\n"); 80 DRM_ERROR("failed to allocate pages.\n");
89 ret = -ENOMEM; 81 ret = -ENOMEM;
90 goto err2; 82 goto err_free_table;
91 } 83 }
92 84
93 sgl = buf->sgt->sgl; 85 sgl = buf->sgt->sgl;
94 start_addr = buf->dma_addr;
95
96 while (i < npages) { 86 while (i < npages) {
97 buf->pages[i] = phys_to_page(start_addr); 87 buf->pages[i] = sg_page(sgl);
98 sg_set_page(sgl, buf->pages[i], buf->page_size, 0);
99 sg_dma_address(sgl) = start_addr;
100 start_addr += buf->page_size;
101 sgl = sg_next(sgl); 88 sgl = sg_next(sgl);
102 i++; 89 i++;
103 } 90 }
@@ -108,14 +95,16 @@ static int lowlevel_buffer_allocate(struct drm_device *dev,
108 buf->size); 95 buf->size);
109 96
110 return ret; 97 return ret;
111err2: 98
112 dma_free_writecombine(dev->dev, buf->size, buf->kvaddr, 99err_free_table:
113 (dma_addr_t)buf->dma_addr);
114 buf->dma_addr = (dma_addr_t)NULL;
115err1:
116 sg_free_table(buf->sgt); 100 sg_free_table(buf->sgt);
101err_free_sgt:
117 kfree(buf->sgt); 102 kfree(buf->sgt);
118 buf->sgt = NULL; 103 buf->sgt = NULL;
104err_free_attrs:
105 dma_free_attrs(dev->dev, buf->size, buf->kvaddr,
106 (dma_addr_t)buf->dma_addr, &buf->dma_attrs);
107 buf->dma_addr = (dma_addr_t)NULL;
119 108
120 return ret; 109 return ret;
121} 110}
@@ -125,16 +114,6 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev,
125{ 114{
126 DRM_DEBUG_KMS("%s.\n", __FILE__); 115 DRM_DEBUG_KMS("%s.\n", __FILE__);
127 116
128 /*
129 * release only physically continuous memory and
130 * non-continuous memory would be released by exynos
131 * gem framework.
132 */
133 if (IS_NONCONTIG_BUFFER(flags)) {
134 DRM_DEBUG_KMS("not support allocation type.\n");
135 return;
136 }
137
138 if (!buf->dma_addr) { 117 if (!buf->dma_addr) {
139 DRM_DEBUG_KMS("dma_addr is invalid.\n"); 118 DRM_DEBUG_KMS("dma_addr is invalid.\n");
140 return; 119 return;
@@ -150,11 +129,8 @@ static void lowlevel_buffer_deallocate(struct drm_device *dev,
150 kfree(buf->sgt); 129 kfree(buf->sgt);
151 buf->sgt = NULL; 130 buf->sgt = NULL;
152 131
153 kfree(buf->pages); 132 dma_free_attrs(dev->dev, buf->size, buf->kvaddr,
154 buf->pages = NULL; 133 (dma_addr_t)buf->dma_addr, &buf->dma_attrs);
155
156 dma_free_writecombine(dev->dev, buf->size, buf->kvaddr,
157 (dma_addr_t)buf->dma_addr);
158 buf->dma_addr = (dma_addr_t)NULL; 134 buf->dma_addr = (dma_addr_t)NULL;
159} 135}
160 136