drm/nv50: add more 0x100c80 flushy magic
authorBen Skeggs <bskeggs@redhat.com>
Mon, 15 Mar 2010 06:43:47 +0000 (16:43 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 9 Apr 2010 00:11:45 +0000 (10:11 +1000)
Fixes the !vbo_fifo path in the 3D driver on certain chipsets.  Still not
really any good idea of what exactly the magic achieves, but it makes
things work.

While we're at it, in the PCIEGART path, flush on unbinding also.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_mem.c
drivers/gpu/drm/nouveau/nouveau_sgdma.c

index 2dc09dbd817d06d178343bf7280f7187115dd555..a4d5ecc6ed5a682861a9f1a019772c3a9c684465 100644 (file)
@@ -347,6 +347,20 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
                return -EBUSY;
        }
 
+       nv_wr32(dev, 0x100c80, 0x00040001);
+       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+               return -EBUSY;
+       }
+
+       nv_wr32(dev, 0x100c80, 0x00060001);
+       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+               return -EBUSY;
+       }
+
        return 0;
 }
 
@@ -384,6 +398,20 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
        }
 
        nv_wr32(dev, 0x100c80, 0x00000001);
+       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+               return;
+       }
+
+       nv_wr32(dev, 0x100c80, 0x00040001);
+       if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+               NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+               NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
+               return;
+       }
+
+       nv_wr32(dev, 0x100c80, 0x00060001);
        if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
                NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
                NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
index ed1590577b6c0d73d425be296718b440f756895b..554fb45730c186e7a84021cb5148dd440060a271 100644 (file)
@@ -171,6 +171,24 @@ nouveau_sgdma_unbind(struct ttm_backend *be)
        }
        dev_priv->engine.instmem.finish_access(nvbe->dev);
 
+       if (dev_priv->card_type == NV_50) {
+               nv_wr32(dev, 0x100c80, 0x00050001);
+               if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+                       NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+                       NV_ERROR(dev, "0x100c80 = 0x%08x\n",
+                                               nv_rd32(dev, 0x100c80));
+                       return -EBUSY;
+               }
+
+               nv_wr32(dev, 0x100c80, 0x00000001);
+               if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
+                       NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
+                       NV_ERROR(dev, "0x100c80 = 0x%08x\n",
+                                               nv_rd32(dev, 0x100c80));
+                       return -EBUSY;
+               }
+       }
+
        nvbe->bound = false;
        return 0;
 }