From d5316e251230c4e54a157349a362229c3d4daa32 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 21 Mar 2012 13:53:49 +1000 Subject: [PATCH] drm/nvc0-/disp: reimplement flip completion method as fifo method Removes need for M2MF subchannel usage on NVC0+. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_display.c | 14 +++++---- drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + drivers/gpu/drm/nouveau/nvc0_fifo.c | 36 ++++++++++++++++++++--- drivers/gpu/drm/nouveau/nvc0_graph.c | 9 ------ 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 35acc92f647b..ab447275da28 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -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); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index eaf9872f9ee2..3dd620fc7837 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -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 diff --git a/drivers/gpu/drm/nouveau/nvc0_fifo.c b/drivers/gpu/drm/nouveau/nvc0_fifo.c index dcbe0d5d0241..50d68a7a1379 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fifo.c +++ b/drivers/gpu/drm/nouveau/nvc0_fifo.c @@ -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); diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c index 8ee3963f9030..9066102d1159 100644 --- a/drivers/gpu/drm/nouveau/nvc0_graph.c +++ b/drivers/gpu/drm/nouveau/nvc0_graph.c @@ -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-) */ -- 2.20.1