drm/nvc0-/disp: reimplement flip completion method as fifo method
authorBen Skeggs <bskeggs@redhat.com>
Wed, 21 Mar 2012 03:53:49 +0000 (13:53 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 22 Mar 2012 07:17:40 +0000 (17:17 +1000)
Removes need for M2MF subchannel usage on NVC0+.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nouveau_display.c
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nvc0_fifo.c
drivers/gpu/drm/nouveau/nvc0_graph.c

index 35acc92f647b5a2a6eed220697f0f61e0720dc30..ab447275da28618b52321e3426ebe1275b970f08 100644 (file)
@@ -438,15 +438,19 @@ nouveau_page_flip_emit(struct nouveau_channel *chan,
                goto fail;
 
        /* Emit the pageflip */
-       ret = RING_SPACE(chan, 2);
+       ret = RING_SPACE(chan, 3);
        if (ret)
                goto fail;
 
-       if (dev_priv->card_type < NV_C0)
+       if (dev_priv->card_type < NV_C0) {
                BEGIN_RING(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
-       else
-               BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0500, 1);
-       OUT_RING  (chan, 0);
+               OUT_RING  (chan, 0x00000000);
+               OUT_RING  (chan, 0x00000000);
+       } else {
+               BEGIN_NVC0(chan, 2, 0, NV10_SUBCHAN_REF_CNT, 1);
+               OUT_RING  (chan, ++chan->fence.sequence);
+               BEGIN_NVC0(chan, 8, 0, NVSW_SUBCHAN_PAGE_FLIP, 0x0000);
+       }
        FIRE_RING (chan);
 
        ret = nouveau_fence_new(chan, pfence, true);
index eaf9872f9ee2c91e8bb6854c2136a39a2f7bea24..3dd620fc7837b4776ec3256e8728aba023c6563b 100644 (file)
@@ -1775,6 +1775,7 @@ nv44_graph_class(struct drm_device *dev)
 #define NV84_SUBCHAN_NOTIFY_INTR                                     0x00000020
 #define NV84_SUBCHAN_WRCACHE_FLUSH                                   0x00000024
 #define NV10_SUBCHAN_REF_CNT                                         0x00000050
+#define NVSW_SUBCHAN_PAGE_FLIP                                       0x00000054
 #define NV11_SUBCHAN_DMA_SEMAPHORE                                   0x00000060
 #define NV11_SUBCHAN_SEMAPHORE_OFFSET                                0x00000064
 #define NV11_SUBCHAN_SEMAPHORE_ACQUIRE                               0x00000068
index dcbe0d5d0241362a6a97b0662c73b0f94cd76472..50d68a7a13798f50347d05afeedbddd51262c91c 100644 (file)
@@ -436,6 +436,24 @@ nvc0_fifo_isr_vm_fault(struct drm_device *dev, int unit)
        printk(" on channel 0x%010llx\n", (u64)inst << 12);
 }
 
+static int
+nvc0_fifo_page_flip(struct drm_device *dev, u32 chid)
+{
+       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 < dev_priv->engine.fifo.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
 nvc0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit)
 {
@@ -445,11 +463,21 @@ nvc0_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;
 
-       NV_INFO(dev, "PSUBFIFO %d:", unit);
-       nouveau_bitfield_print(nvc0_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 (stat & 0x00200000) {
+               if (mthd == 0x0054) {
+                       if (!nvc0_fifo_page_flip(dev, chid))
+                               show &= ~0x00200000;
+               }
+       }
+
+       if (show) {
+               NV_INFO(dev, "PFIFO%d:", unit);
+               nouveau_bitfield_print(nvc0_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);
index 8ee3963f903001a45e5061bfbc81a3efc3663c5f..9066102d11594c527e9beb54d581f8b891902967 100644 (file)
@@ -333,14 +333,6 @@ nvc0_graph_fini(struct drm_device *dev, int engine, bool suspend)
        return 0;
 }
 
-static int
-nvc0_graph_mthd_page_flip(struct nouveau_channel *chan,
-                         u32 class, u32 mthd, u32 data)
-{
-       nouveau_finish_page_flip(chan, NULL);
-       return 0;
-}
-
 static void
 nvc0_graph_init_obj418880(struct drm_device *dev)
 {
@@ -889,7 +881,6 @@ nvc0_graph_create(struct drm_device *dev)
 
        NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */
        NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */
-       NVOBJ_MTHD (dev, 0x9039, 0x0500, nvc0_graph_mthd_page_flip);
        NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */
        if (fermi >= 0x9197)
                NVOBJ_CLASS(dev, 0x9197, GR); /* 3D (NVC1-) */