summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c')
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c57
1 files changed, 28 insertions, 29 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
index 4c3b0a23b9d6..668cf964e4a9 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c
@@ -29,10 +29,10 @@
#include <subdev/fb.h>
#include <subdev/vm.h>
#include <subdev/ltcg.h>
+#include <subdev/bar.h>
struct nvc0_vmmgr_priv {
struct nouveau_vmmgr base;
- spinlock_t lock;
};
@@ -160,40 +160,40 @@ nvc0_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt)
}
}
-void
-nvc0_vm_flush_engine(struct nouveau_subdev *subdev, u64 addr, int type)
-{
- struct nvc0_vmmgr_priv *priv = (void *)nouveau_vmmgr(subdev);
- unsigned long flags;
-
- /* looks like maybe a "free flush slots" counter, the
- * faster you write to 0x100cbc to more it decreases
- */
- spin_lock_irqsave(&priv->lock, flags);
- if (!nv_wait_ne(subdev, 0x100c80, 0x00ff0000, 0x00000000)) {
- nv_error(subdev, "vm timeout 0: 0x%08x %d\n",
- nv_rd32(subdev, 0x100c80), type);
- }
-
- nv_wr32(subdev, 0x100cb8, addr >> 8);
- nv_wr32(subdev, 0x100cbc, 0x80000000 | type);
-
- /* wait for flush to be queued? */
- if (!nv_wait(subdev, 0x100c80, 0x00008000, 0x00008000)) {
- nv_error(subdev, "vm timeout 1: 0x%08x %d\n",
- nv_rd32(subdev, 0x100c80), type);
- }
- spin_unlock_irqrestore(&priv->lock, flags);
-}
-
static void
nvc0_vm_flush(struct nouveau_vm *vm)
{
+ struct nvc0_vmmgr_priv *priv = (void *)vm->vmm;
+ struct nouveau_bar *bar = nouveau_bar(priv);
struct nouveau_vm_pgd *vpgd;
+ u32 type;
+
+ bar->flush(bar);
+
+ type = 0x00000001; /* PAGE_ALL */
+ if (atomic_read(&vm->engref[NVDEV_SUBDEV_BAR]))
+ type |= 0x00000004; /* HUB_ONLY */
+ mutex_lock(&nv_subdev(priv)->mutex);
list_for_each_entry(vpgd, &vm->pgd_list, head) {
- nvc0_vm_flush_engine(nv_subdev(vm->vmm), vpgd->obj->addr, 1);
+ /* looks like maybe a "free flush slots" counter, the
+ * faster you write to 0x100cbc to more it decreases
+ */
+ if (!nv_wait_ne(priv, 0x100c80, 0x00ff0000, 0x00000000)) {
+ nv_error(priv, "vm timeout 0: 0x%08x %d\n",
+ nv_rd32(priv, 0x100c80), type);
+ }
+
+ nv_wr32(priv, 0x100cb8, vpgd->obj->addr >> 8);
+ nv_wr32(priv, 0x100cbc, 0x80000000 | type);
+
+ /* wait for flush to be queued? */
+ if (!nv_wait(priv, 0x100c80, 0x00008000, 0x00008000)) {
+ nv_error(priv, "vm timeout 1: 0x%08x %d\n",
+ nv_rd32(priv, 0x100c80), type);
+ }
}
+ mutex_unlock(&nv_subdev(priv)->mutex);
}
static int
@@ -227,7 +227,6 @@ nvc0_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
priv->base.map_sg = nvc0_vm_map_sg;
priv->base.unmap = nvc0_vm_unmap;
priv->base.flush = nvc0_vm_flush;
- spin_lock_init(&priv->lock);
return 0;
}