summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/linux/dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/dma.c')
-rw-r--r--drivers/gpu/nvgpu/common/linux/dma.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/dma.c b/drivers/gpu/nvgpu/common/linux/dma.c
index c111d22b..53e54bc6 100644
--- a/drivers/gpu/nvgpu/common/linux/dma.c
+++ b/drivers/gpu/nvgpu/common/linux/dma.c
@@ -227,6 +227,16 @@ int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags,
227 } 227 }
228 228
229 /* 229 /*
230 * WAR for IO coherent chips: the DMA API does not seem to generate
231 * mappings that work correctly. Unclear why - Bug ID: 2040115.
232 *
233 * Basically we just tell the DMA API not to map with NO_KERNEL_MAPPING
234 * and then make a vmap() ourselves.
235 */
236 if (nvgpu_is_enabled(g, NVGPU_USE_COHERENT_SYSMEM))
237 flags |= NVGPU_DMA_NO_KERNEL_MAPPING;
238
239 /*
230 * Before the debug print so we see this in the total. But during 240 * Before the debug print so we see this in the total. But during
231 * cleanup in the fail path this has to be subtracted. 241 * cleanup in the fail path this has to be subtracted.
232 */ 242 */
@@ -260,7 +270,17 @@ int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags,
260 iova, size, flags); 270 iova, size, flags);
261 } 271 }
262 if (err) 272 if (err)
263 goto fail_free; 273 goto fail_free_dma;
274
275 if (nvgpu_is_enabled(g, NVGPU_USE_COHERENT_SYSMEM)) {
276 mem->cpu_va = vmap(mem->priv.pages,
277 size >> PAGE_SHIFT,
278 0, PAGE_KERNEL);
279 if (!mem->cpu_va) {
280 err = -ENOMEM;
281 goto fail_free_sgt;
282 }
283 }
264 284
265 mem->aligned_size = size; 285 mem->aligned_size = size;
266 mem->aperture = APERTURE_SYSMEM; 286 mem->aperture = APERTURE_SYSMEM;
@@ -270,12 +290,14 @@ int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags,
270 290
271 return 0; 291 return 0;
272 292
273fail_free: 293fail_free_sgt:
274 g->dma_memory_used -= mem->aligned_size; 294 nvgpu_free_sgtable(g, &mem->priv.sgt);
295fail_free_dma:
275 dma_free_attrs(d, size, alloc_ret, iova, NVGPU_DMA_ATTR(dma_attrs)); 296 dma_free_attrs(d, size, alloc_ret, iova, NVGPU_DMA_ATTR(dma_attrs));
276 mem->cpu_va = NULL; 297 mem->cpu_va = NULL;
277 mem->priv.sgt = NULL; 298 mem->priv.sgt = NULL;
278 mem->size = 0; 299 mem->size = 0;
300 g->dma_memory_used -= mem->aligned_size;
279 return err; 301 return err;
280} 302}
281 303
@@ -476,6 +498,12 @@ static void nvgpu_dma_free_sys(struct gk20a *g, struct nvgpu_mem *mem)
476 if (!(mem->mem_flags & NVGPU_MEM_FLAG_SHADOW_COPY) && 498 if (!(mem->mem_flags & NVGPU_MEM_FLAG_SHADOW_COPY) &&
477 !(mem->mem_flags & __NVGPU_MEM_FLAG_NO_DMA) && 499 !(mem->mem_flags & __NVGPU_MEM_FLAG_NO_DMA) &&
478 (mem->cpu_va || mem->priv.pages)) { 500 (mem->cpu_va || mem->priv.pages)) {
501 /*
502 * Free side of WAR for bug 2040115.
503 */
504 if (nvgpu_is_enabled(g, NVGPU_USE_COHERENT_SYSMEM))
505 vunmap(mem->cpu_va);
506
479 if (mem->priv.flags) { 507 if (mem->priv.flags) {
480 NVGPU_DEFINE_DMA_ATTRS(dma_attrs); 508 NVGPU_DEFINE_DMA_ATTRS(dma_attrs);
481 509