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 c13dae8b..81aebb7d 100644
--- a/drivers/gpu/nvgpu/common/linux/dma.c
+++ b/drivers/gpu/nvgpu/common/linux/dma.c
@@ -222,6 +222,16 @@ int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags,
222 void *alloc_ret; 222 void *alloc_ret;
223 223
224 /* 224 /*
225 * WAR for IO coherent chips: the DMA API does not seem to generate
226 * mappings that work correctly. Unclear why - Bug ID: 2040115.
227 *
228 * Basically we just tell the DMA API not to map with NO_KERNEL_MAPPING
229 * and then make a vmap() ourselves.
230 */
231 if (nvgpu_is_enabled(g, NVGPU_USE_COHERENT_SYSMEM))
232 flags |= NVGPU_DMA_NO_KERNEL_MAPPING;
233
234 /*
225 * Before the debug print so we see this in the total. But during 235 * Before the debug print so we see this in the total. But during
226 * cleanup in the fail path this has to be subtracted. 236 * cleanup in the fail path this has to be subtracted.
227 */ 237 */
@@ -255,7 +265,17 @@ int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags,
255 iova, size, flags); 265 iova, size, flags);
256 } 266 }
257 if (err) 267 if (err)
258 goto fail_free; 268 goto fail_free_dma;
269
270 if (nvgpu_is_enabled(g, NVGPU_USE_COHERENT_SYSMEM)) {
271 mem->cpu_va = vmap(mem->priv.pages,
272 size >> PAGE_SHIFT,
273 0, PAGE_KERNEL);
274 if (!mem->cpu_va) {
275 err = -ENOMEM;
276 goto fail_free_sgt;
277 }
278 }
259 279
260 mem->aligned_size = size; 280 mem->aligned_size = size;
261 mem->aperture = APERTURE_SYSMEM; 281 mem->aperture = APERTURE_SYSMEM;
@@ -265,12 +285,14 @@ int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags,
265 285
266 return 0; 286 return 0;
267 287
268fail_free: 288fail_free_sgt:
269 g->dma_memory_used -= mem->aligned_size; 289 nvgpu_free_sgtable(g, &mem->priv.sgt);
290fail_free_dma:
270 dma_free_attrs(d, size, alloc_ret, iova, NVGPU_DMA_ATTR(dma_attrs)); 291 dma_free_attrs(d, size, alloc_ret, iova, NVGPU_DMA_ATTR(dma_attrs));
271 mem->cpu_va = NULL; 292 mem->cpu_va = NULL;
272 mem->priv.sgt = NULL; 293 mem->priv.sgt = NULL;
273 mem->size = 0; 294 mem->size = 0;
295 g->dma_memory_used -= mem->aligned_size;
274 return err; 296 return err;
275} 297}
276 298
@@ -466,6 +488,12 @@ static void nvgpu_dma_free_sys(struct gk20a *g, struct nvgpu_mem *mem)
466 if (!(mem->mem_flags & NVGPU_MEM_FLAG_SHADOW_COPY) && 488 if (!(mem->mem_flags & NVGPU_MEM_FLAG_SHADOW_COPY) &&
467 !(mem->mem_flags & __NVGPU_MEM_FLAG_NO_DMA) && 489 !(mem->mem_flags & __NVGPU_MEM_FLAG_NO_DMA) &&
468 (mem->cpu_va || mem->priv.pages)) { 490 (mem->cpu_va || mem->priv.pages)) {
491 /*
492 * Free side of WAR for bug 2040115.
493 */
494 if (nvgpu_is_enabled(g, NVGPU_USE_COHERENT_SYSMEM))
495 vunmap(mem->cpu_va);
496
469 if (mem->priv.flags) { 497 if (mem->priv.flags) {
470 NVGPU_DEFINE_DMA_ATTRS(dma_attrs); 498 NVGPU_DEFINE_DMA_ATTRS(dma_attrs);
471 499