aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2014-10-27 05:49:19 -0400
committerBen Skeggs <bskeggs@redhat.com>2014-12-02 00:44:00 -0500
commitb22870ba6a5c7bd4380f224eeabf335b1f8792b3 (patch)
treeb967fb75ea6f4e9500a02297246bdf95c116f19f /drivers/gpu/drm/nouveau
parenta81349a7b27adc66cc318ac0bc0f657b0b73a5af (diff)
drm/nouveau: synchronize BOs when required
On architectures for which access to GPU memory is non-coherent, caches need to be flushed and invalidated explicitly when BO control changes between CPU and GPU. This patch adds buffer synchronization functions which invokes the correct API (PCI or DMA) to ensure synchronization is effective. Based on the TTM DMA cache helper patches by Lucas Stach. Signed-off-by: Lucas Stach <dev@lynxeye.de> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c42
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_gem.c12
3 files changed, 56 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index ed9a6946f6d6..d2a4768e3efd 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -426,6 +426,46 @@ nouveau_bo_unmap(struct nouveau_bo *nvbo)
426 ttm_bo_kunmap(&nvbo->kmap); 426 ttm_bo_kunmap(&nvbo->kmap);
427} 427}
428 428
429void
430nouveau_bo_sync_for_device(struct nouveau_bo *nvbo)
431{
432 struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
433 struct nouveau_device *device = nvkm_device(&drm->device);
434 struct ttm_dma_tt *ttm_dma = (struct ttm_dma_tt *)nvbo->bo.ttm;
435 int i;
436
437 if (!ttm_dma)
438 return;
439
440 /* Don't waste time looping if the object is coherent */
441 if (nvbo->force_coherent)
442 return;
443
444 for (i = 0; i < ttm_dma->ttm.num_pages; i++)
445 dma_sync_single_for_device(nv_device_base(device),
446 ttm_dma->dma_address[i], PAGE_SIZE, DMA_TO_DEVICE);
447}
448
449void
450nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo)
451{
452 struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
453 struct nouveau_device *device = nvkm_device(&drm->device);
454 struct ttm_dma_tt *ttm_dma = (struct ttm_dma_tt *)nvbo->bo.ttm;
455 int i;
456
457 if (!ttm_dma)
458 return;
459
460 /* Don't waste time looping if the object is coherent */
461 if (nvbo->force_coherent)
462 return;
463
464 for (i = 0; i < ttm_dma->ttm.num_pages; i++)
465 dma_sync_single_for_cpu(nv_device_base(device),
466 ttm_dma->dma_address[i], PAGE_SIZE, DMA_FROM_DEVICE);
467}
468
429int 469int
430nouveau_bo_validate(struct nouveau_bo *nvbo, bool interruptible, 470nouveau_bo_validate(struct nouveau_bo *nvbo, bool interruptible,
431 bool no_wait_gpu) 471 bool no_wait_gpu)
@@ -437,6 +477,8 @@ nouveau_bo_validate(struct nouveau_bo *nvbo, bool interruptible,
437 if (ret) 477 if (ret)
438 return ret; 478 return ret;
439 479
480 nouveau_bo_sync_for_device(nvbo);
481
440 return 0; 482 return 0;
441} 483}
442 484
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h
index 0f8bbd48a0b9..c827f233e41d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.h
@@ -85,6 +85,8 @@ void nouveau_bo_wr32(struct nouveau_bo *, unsigned index, u32 val);
85void nouveau_bo_fence(struct nouveau_bo *, struct nouveau_fence *, bool exclusive); 85void nouveau_bo_fence(struct nouveau_bo *, struct nouveau_fence *, bool exclusive);
86int nouveau_bo_validate(struct nouveau_bo *, bool interruptible, 86int nouveau_bo_validate(struct nouveau_bo *, bool interruptible,
87 bool no_wait_gpu); 87 bool no_wait_gpu);
88void nouveau_bo_sync_for_device(struct nouveau_bo *nvbo);
89void nouveau_bo_sync_for_cpu(struct nouveau_bo *nvbo);
88 90
89struct nouveau_vma * 91struct nouveau_vma *
90nouveau_bo_vma_find(struct nouveau_bo *, struct nouveau_vm *); 92nouveau_bo_vma_find(struct nouveau_bo *, struct nouveau_vm *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c
index ebba9deb0d04..28d51a22a4bf 100644
--- a/drivers/gpu/drm/nouveau/nouveau_gem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_gem.c
@@ -870,6 +870,7 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data,
870 else 870 else
871 ret = lret; 871 ret = lret;
872 } 872 }
873 nouveau_bo_sync_for_cpu(nvbo);
873 drm_gem_object_unreference_unlocked(gem); 874 drm_gem_object_unreference_unlocked(gem);
874 875
875 return ret; 876 return ret;
@@ -879,6 +880,17 @@ int
879nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data, 880nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data,
880 struct drm_file *file_priv) 881 struct drm_file *file_priv)
881{ 882{
883 struct drm_nouveau_gem_cpu_fini *req = data;
884 struct drm_gem_object *gem;
885 struct nouveau_bo *nvbo;
886
887 gem = drm_gem_object_lookup(dev, file_priv, req->handle);
888 if (!gem)
889 return -ENOENT;
890 nvbo = nouveau_gem_object(gem);
891
892 nouveau_bo_sync_for_device(nvbo);
893 drm_gem_object_unreference_unlocked(gem);
882 return 0; 894 return 0;
883} 895}
884 896