drm/nve0/fifo: add support for the flip completion swmthd
authorBen Skeggs <bskeggs@redhat.com>
Thu, 26 Jul 2012 21:53:02 +0000 (07:53 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 3 Aug 2012 05:40:24 +0000 (15:40 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nve0_fifo.c

index 1855ecbd843b81161245cfd15ccb1f4e7f8e2343..e98d144e6eb9df766fc458e03bdd35acef349ce4 100644 (file)
@@ -294,6 +294,25 @@ nve0_fifo_isr_vm_fault(struct drm_device *dev, int unit)
        printk(" on channel 0x%010llx\n", (u64)inst << 12);
 }
 
+static int
+nve0_fifo_page_flip(struct drm_device *dev, u32 chid)
+{
+       struct nve0_fifo_priv *priv = nv_engine(dev, NVOBJ_ENGINE_FIFO);
+       struct drm_nouveau_private *dev_priv = dev->dev_private;
+       struct nouveau_channel *chan = NULL;
+       unsigned long flags;
+       int ret = -EINVAL;
+
+       spin_lock_irqsave(&dev_priv->channels.lock, flags);
+       if (likely(chid >= 0 && chid < priv->base.channels)) {
+               chan = dev_priv->channels.ptr[chid];
+               if (likely(chan))
+                       ret = nouveau_finish_page_flip(chan, NULL);
+       }
+       spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
+       return ret;
+}
+
 static void
 nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
 {
@@ -303,11 +322,21 @@ nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
        u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f;
        u32 subc = (addr & 0x00070000);
        u32 mthd = (addr & 0x00003ffc);
+       u32 show = stat;
+
+       if (stat & 0x00200000) {
+               if (mthd == 0x0054) {
+                       if (!nve0_fifo_page_flip(dev, chid))
+                               show &= ~0x00200000;
+               }
+       }
 
-       NV_INFO(dev, "PSUBFIFO %d:", unit);
-       nouveau_bitfield_print(nve0_fifo_subfifo_intr, stat);
-       NV_INFO(dev, "PSUBFIFO %d: ch %d subc %d mthd 0x%04x data 0x%08x\n",
-               unit, chid, subc, mthd, data);
+       if (show) {
+               NV_INFO(dev, "PFIFO%d:", unit);
+               nouveau_bitfield_print(nve0_fifo_subfifo_intr, show);
+               NV_INFO(dev, "PFIFO%d: ch %d subc %d mthd 0x%04x data 0x%08x\n",
+                       unit, chid, subc, mthd, data);
+       }
 
        nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008);
        nv_wr32(dev, 0x040108 + (unit * 0x2000), stat);