]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
drm/nvc0/vm: handle bar tlb flushes internally
authorBen Skeggs <bskeggs@redhat.com>
Mon, 13 May 2013 12:07:16 +0000 (22:07 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Mon, 1 Jul 2013 03:44:57 +0000 (13:44 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/include/subdev/vm.h
drivers/gpu/drm/nouveau/core/subdev/bar/nvc0.c
drivers/gpu/drm/nouveau/core/subdev/vm/nvc0.c

index 7a0815c87bd2fc6b856ad3cde1d5150036c184e7..f2e87b105666f344c46e0c96c9870a062dd76340 100644 (file)
@@ -117,8 +117,6 @@ int  nv04_vm_create(struct nouveau_vmmgr *, u64, u64, u64,
                    struct nouveau_vm **);
 void nv04_vmmgr_dtor(struct nouveau_object *);
 
-void nvc0_vm_flush_engine(struct nouveau_subdev *, u64 addr, int type);
-
 /* nouveau_vm.c */
 int  nouveau_vm_create(struct nouveau_vmmgr *, u64 offset, u64 length,
                       u64 mm_offset, u32 block, struct nouveau_vm **);
index f8a44956dec1c1a5b3635e5ea9665d08c1f1903e..b2ec7411eb2eb7cb43e5434016cad756159c69d6 100644 (file)
@@ -51,7 +51,6 @@ nvc0_bar_kmap(struct nouveau_bar *bar, struct nouveau_mem *mem,
                return ret;
 
        nouveau_vm_map(vma, mem);
-       nvc0_vm_flush_engine(nv_subdev(bar), priv->bar[0].pgd->addr, 5);
        return 0;
 }
 
@@ -68,18 +67,13 @@ nvc0_bar_umap(struct nouveau_bar *bar, struct nouveau_mem *mem,
                return ret;
 
        nouveau_vm_map(vma, mem);
-       nvc0_vm_flush_engine(nv_subdev(bar), priv->bar[1].pgd->addr, 5);
        return 0;
 }
 
 static void
 nvc0_bar_unmap(struct nouveau_bar *bar, struct nouveau_vma *vma)
 {
-       struct nvc0_bar_priv *priv = (void *)bar;
-       int i = !(vma->vm == priv->bar[0].vm);
-
        nouveau_vm_unmap(vma);
-       nvc0_vm_flush_engine(nv_subdev(bar), priv->bar[i].pgd->addr, 5);
        nouveau_vm_put(vma);
 }
 
@@ -116,6 +110,8 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        if (ret)
                return ret;
 
+       atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
+
        ret = nouveau_gpuobj_new(nv_object(priv), NULL,
                                 (pci_resource_len(pdev, 3) >> 12) * 8,
                                 0x1000, NVOBJ_FLAG_ZERO_ALLOC,
@@ -150,6 +146,8 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
        if (ret)
                return ret;
 
+       atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
+
        ret = nouveau_vm_ref(vm, &priv->bar[1].vm, priv->bar[1].pgd);
        nouveau_vm_ref(NULL, &vm, NULL);
        if (ret)
index beb09743aafff3484f52f227ca41ec46e9ed558f..6c3aea55d50315d3e565e81b5593e649f5e21f22 100644 (file)
@@ -159,39 +159,37 @@ 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);
-
-       /* looks like maybe a "free flush slots" counter, the
-        * faster you write to 0x100cbc to more it decreases
-        */
-       mutex_lock(&nv_subdev(priv)->mutex);
-       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);
-       }
-       mutex_unlock(&nv_subdev(priv)->mutex);
-}
-
 static void
 nvc0_vm_flush(struct nouveau_vm *vm)
 {
+       struct nvc0_vmmgr_priv *priv = (void *)vm->vmm;
        struct nouveau_vm_pgd *vpgd;
+       u32 type;
 
+       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