drm/nouveau/fifo: add RAMFC info to nvkm_chan_func
authorBen Skeggs <bskeggs@redhat.com>
Wed, 1 Jun 2022 10:47:36 +0000 (20:47 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 9 Nov 2022 00:44:49 +0000 (10:44 +1000)
- adds support for specifying SUBDEVICE_ID for channel
- rounds non-power-of-two GPFIFO sizes down, rather than up

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
29 files changed:
drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv04.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv10.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv17.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/dmanv40.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifog84.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifonv50.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c

index 95cb33b..1616a32 100644 (file)
@@ -28,6 +28,13 @@ struct nvkm_chan {
                u32 base;
        } userd;
 
+       u32 ramfc_offset;
+       struct nvkm_gpuobj *ramfc;
+       struct nvkm_gpuobj *cache;
+       struct nvkm_gpuobj *eng;
+       struct nvkm_gpuobj *pgd;
+       struct nvkm_ramht *ramht;
+
        spinlock_t lock;
        atomic_t blocked;
        atomic_t errored;
index 0df089b..00680b3 100644 (file)
@@ -29,8 +29,8 @@
 #include "priv.h"
 
 #include <core/client.h>
-#include <core/gpuobj.h>
 #include <core/oproxy.h>
+#include <core/ramht.h>
 #include <subdev/mmu.h>
 #include <engine/dma.h>
 
@@ -434,6 +434,15 @@ nvkm_chan_del(struct nvkm_chan **pchan)
        if (!chan)
                return;
 
+       if (chan->func->ramfc->clear)
+               chan->func->ramfc->clear(chan);
+
+       nvkm_ramht_del(&chan->ramht);
+       nvkm_gpuobj_del(&chan->pgd);
+       nvkm_gpuobj_del(&chan->eng);
+       nvkm_gpuobj_del(&chan->cache);
+       nvkm_gpuobj_del(&chan->ramfc);
+
        nvkm_memory_unref(&chan->userd.mem);
 
        if (chan->cgrp) {
@@ -618,16 +627,17 @@ nvkm_fifo_chan_ctor(const struct nvkm_fifo_chan_func *fn,
                chan->vmm = nvkm_vmm_ref(vmm);
        }
 
-       /* allocate push buffer ctxdma instance */
-       if (push) {
+       /* Allocate HW ctxdma for push buffer. */
+       if (func->ramfc->ctxdma) {
                dmaobj = nvkm_dmaobj_search(client, push);
                if (IS_ERR(dmaobj))
                        return PTR_ERR(dmaobj);
 
-               ret = nvkm_object_bind(&dmaobj->object, chan->inst, -16,
-                                      &chan->push);
-               if (ret)
+               ret = nvkm_object_bind(&dmaobj->object, chan->inst, -16, &chan->push);
+               if (ret) {
+                       RUNL_DEBUG(runl, "bind %d", ret);
                        return ret;
+               }
        }
 
        /* Allocate channel ID. */
index 54ef137..6e41eba 100644 (file)
@@ -29,6 +29,21 @@ struct nvkm_chan_func {
                void (*clear)(struct nvkm_chan *);
        } *userd;
 
+       const struct nvkm_chan_func_ramfc {
+               const struct nvkm_ramfc_layout {
+                       unsigned bits:6;
+                       unsigned ctxs:5;
+                       unsigned ctxp:8;
+                       unsigned regs:5;
+                       unsigned regp;
+               } *layout;
+               int (*write)(struct nvkm_chan *, u64 offset, u64 length, u32 devm, bool priv);
+               void (*clear)(struct nvkm_chan *);
+               bool ctxdma;
+               u32 devm;
+               bool priv;
+       } *ramfc;
+
        void (*bind)(struct nvkm_chan *);
        void (*unbind)(struct nvkm_chan *);
        void (*start)(struct nvkm_chan *);
index 64566b5..f5e3557 100644 (file)
@@ -182,7 +182,6 @@ g84_fifo_chan_ctor(struct nv50_fifo *fifo, u64 vmm, u64 push,
                   const struct nvkm_oclass *oclass,
                   struct nv50_fifo_chan *chan)
 {
-       struct nvkm_device *device = fifo->base.engine.subdev.device;
        int ret;
 
        if (!vmm)
@@ -206,28 +205,5 @@ g84_fifo_chan_ctor(struct nv50_fifo *fifo, u64 vmm, u64 push,
                                  BIT(G84_FIFO_ENGN_DMA),
                                  0, 0xc00000, 0x2000, oclass, &chan->base);
        chan->fifo = fifo;
-       if (ret)
-               return ret;
-
-       ret = nvkm_gpuobj_new(device, 0x0200, 0, true, chan->base.inst,
-                             &chan->eng);
-       if (ret)
-               return ret;
-
-       ret = nvkm_gpuobj_new(device, 0x4000, 0, false, chan->base.inst,
-                             &chan->pgd);
-       if (ret)
-               return ret;
-
-       ret = nvkm_gpuobj_new(device, 0x1000, 0x400, true, chan->base.inst,
-                             &chan->cache);
-       if (ret)
-               return ret;
-
-       ret = nvkm_gpuobj_new(device, 0x100, 0x100, true, chan->base.inst,
-                             &chan->ramfc);
-       if (ret)
-               return ret;
-
-       return nvkm_ramht_new(device, 0x8000, 16, chan->base.inst, &chan->ramht);
+       return ret;
 }
index 5d6f822..0bf59c4 100644 (file)
@@ -187,11 +187,6 @@ void *
 nv50_fifo_chan_dtor(struct nvkm_fifo_chan *base)
 {
        struct nv50_fifo_chan *chan = nv50_fifo_chan(base);
-       nvkm_ramht_del(&chan->ramht);
-       nvkm_gpuobj_del(&chan->pgd);
-       nvkm_gpuobj_del(&chan->eng);
-       nvkm_gpuobj_del(&chan->cache);
-       nvkm_gpuobj_del(&chan->ramfc);
        return chan;
 }
 
@@ -211,7 +206,6 @@ nv50_fifo_chan_ctor(struct nv50_fifo *fifo, u64 vmm, u64 push,
                    const struct nvkm_oclass *oclass,
                    struct nv50_fifo_chan *chan)
 {
-       struct nvkm_device *device = fifo->base.engine.subdev.device;
        int ret;
 
        if (!vmm)
@@ -225,23 +219,5 @@ nv50_fifo_chan_ctor(struct nv50_fifo *fifo, u64 vmm, u64 push,
                                  BIT(NV50_FIFO_ENGN_DMA),
                                  0, 0xc00000, 0x2000, oclass, &chan->base);
        chan->fifo = fifo;
-       if (ret)
-               return ret;
-
-       ret = nvkm_gpuobj_new(device, 0x0200, 0x1000, true, chan->base.inst,
-                             &chan->ramfc);
-       if (ret)
-               return ret;
-
-       ret = nvkm_gpuobj_new(device, 0x1200, 0, true, chan->base.inst,
-                             &chan->eng);
-       if (ret)
-               return ret;
-
-       ret = nvkm_gpuobj_new(device, 0x4000, 0, false, chan->base.inst,
-                             &chan->pgd);
-       if (ret)
-               return ret;
-
-       return nvkm_ramht_new(device, 0x8000, 16, chan->base.inst, &chan->ramht);
+       return ret;
 }
index ce7d61e..343356a 100644 (file)
@@ -9,10 +9,7 @@ struct nv50_fifo_chan {
        struct nv50_fifo *fifo;
        struct nvkm_fifo_chan base;
 
-       struct nvkm_gpuobj *ramfc;
-       struct nvkm_gpuobj *cache;
        struct nvkm_gpuobj *eng;
-       struct nvkm_gpuobj *pgd;
        struct nvkm_ramht *ramht;
 
 #define NV50_FIFO_ENGN_SW   0
index d515cf0..4220120 100644 (file)
@@ -73,15 +73,6 @@ void *
 nv04_fifo_dma_dtor(struct nvkm_fifo_chan *base)
 {
        struct nv04_fifo_chan *chan = nv04_fifo_chan(base);
-       struct nv04_fifo *fifo = chan->fifo;
-       struct nvkm_instmem *imem = fifo->base.engine.subdev.device->imem;
-       const struct nv04_fifo_ramfc *c = fifo->ramfc;
-
-       nvkm_kmap(imem->ramfc);
-       do {
-               nvkm_wo32(imem->ramfc, chan->ramfc + c->ctxp, 0x00000000);
-       } while ((++c)->bits);
-       nvkm_done(imem->ramfc);
        return chan;
 }
 
@@ -102,8 +93,6 @@ nv04_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
        } *args = data;
        struct nv04_fifo *fifo = nv04_fifo(base);
        struct nv04_fifo_chan *chan = NULL;
-       struct nvkm_device *device = fifo->base.engine.subdev.device;
-       struct nvkm_instmem *imem = device->imem;
        int ret = -ENOSYS;
 
        nvif_ioctl(parent, "create channel dma size %d\n", size);
@@ -131,20 +120,8 @@ nv04_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
                return ret;
 
        args->v0.chid = chan->base.chid;
-       chan->ramfc = chan->base.chid * 32;
-
-       nvkm_kmap(imem->ramfc);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x00, args->v0.offset);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x04, args->v0.offset);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x08, chan->base.push->addr >> 4);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x10,
-                              NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
-                              NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
-#ifdef __BIG_ENDIAN
-                              NV_PFIFO_CACHE1_BIG_ENDIAN |
-#endif
-                              NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
-       nvkm_done(imem->ramfc);
+
+       chan->base.func->ramfc->write(&chan->base, args->v0.offset, 0, BIT(0), false);
        return 0;
 }
 
index f456550..aa5893c 100644 (file)
@@ -41,8 +41,6 @@ nv10_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
        } *args = data;
        struct nv04_fifo *fifo = nv04_fifo(base);
        struct nv04_fifo_chan *chan = NULL;
-       struct nvkm_device *device = fifo->base.engine.subdev.device;
-       struct nvkm_instmem *imem = device->imem;
        int ret = -ENOSYS;
 
        nvif_ioctl(parent, "create channel dma size %d\n", size);
@@ -70,20 +68,8 @@ nv10_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
                return ret;
 
        args->v0.chid = chan->base.chid;
-       chan->ramfc = chan->base.chid * 32;
 
-       nvkm_kmap(imem->ramfc);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x00, args->v0.offset);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x04, args->v0.offset);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x0c, chan->base.push->addr >> 4);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x14,
-                              NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
-                              NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
-#ifdef __BIG_ENDIAN
-                              NV_PFIFO_CACHE1_BIG_ENDIAN |
-#endif
-                              NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
-       nvkm_done(imem->ramfc);
+       chan->base.func->ramfc->write(&chan->base, args->v0.offset, 0, BIT(0), false);
        return 0;
 }
 
index cd3f9f8..0a7d145 100644 (file)
@@ -41,8 +41,6 @@ nv17_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
        } *args = data;
        struct nv04_fifo *fifo = nv04_fifo(base);
        struct nv04_fifo_chan *chan = NULL;
-       struct nvkm_device *device = fifo->base.engine.subdev.device;
-       struct nvkm_instmem *imem = device->imem;
        int ret = -ENOSYS;
 
        nvif_ioctl(parent, "create channel dma size %d\n", size);
@@ -71,20 +69,8 @@ nv17_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
                return ret;
 
        args->v0.chid = chan->base.chid;
-       chan->ramfc = chan->base.chid * 64;
 
-       nvkm_kmap(imem->ramfc);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x00, args->v0.offset);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x04, args->v0.offset);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x0c, chan->base.push->addr >> 4);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x14,
-                              NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
-                              NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
-#ifdef __BIG_ENDIAN
-                              NV_PFIFO_CACHE1_BIG_ENDIAN |
-#endif
-                              NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
-       nvkm_done(imem->ramfc);
+       chan->base.func->ramfc->write(&chan->base, args->v0.offset, 0, BIT(0), false);
        return 0;
 }
 
index 2f0dcea..5e71044 100644 (file)
@@ -194,8 +194,6 @@ nv40_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
        } *args = data;
        struct nv04_fifo *fifo = nv04_fifo(base);
        struct nv04_fifo_chan *chan = NULL;
-       struct nvkm_device *device = fifo->base.engine.subdev.device;
-       struct nvkm_instmem *imem = device->imem;
        int ret = -ENOSYS;
 
        nvif_ioctl(parent, "create channel dma size %d\n", size);
@@ -224,21 +222,8 @@ nv40_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
                return ret;
 
        args->v0.chid = chan->base.chid;
-       chan->ramfc = chan->base.chid * 128;
 
-       nvkm_kmap(imem->ramfc);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x00, args->v0.offset);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x04, args->v0.offset);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x0c, chan->base.push->addr >> 4);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x18, 0x30000000 |
-                              NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
-                              NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
-#ifdef __BIG_ENDIAN
-                              NV_PFIFO_CACHE1_BIG_ENDIAN |
-#endif
-                              NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
-       nvkm_wo32(imem->ramfc, chan->ramfc + 0x3c, 0x0001ffff);
-       nvkm_done(imem->ramfc);
+       chan->base.func->ramfc->write(&chan->base, args->v0.offset, 0, BIT(0), false);
        return 0;
 }
 
index 76ba98b..6f3f5ca 100644 (file)
@@ -25,7 +25,7 @@
 #include "chan.h"
 #include "runl.h"
 
-#include <core/gpuobj.h>
+#include <core/ramht.h>
 
 #include "nv50.h"
 #include "channv50.h"
@@ -37,13 +37,69 @@ g84_chan_bind(struct nvkm_chan *chan)
 {
        struct nvkm_device *device = chan->cgrp->runl->fifo->engine.subdev.device;
 
-       nvkm_wr32(device, 0x002600 + (chan->id * 4), nv50_fifo_chan(chan)->ramfc->addr >> 8);
+       nvkm_wr32(device, 0x002600 + (chan->id * 4), chan->ramfc->addr >> 8);
 }
 
+static int
+g84_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, bool priv)
+{
+       struct nvkm_device *device = chan->cgrp->runl->fifo->engine.subdev.device;
+       const u32 limit2 = ilog2(length / 8);
+       int ret;
+
+       ret = nvkm_gpuobj_new(device, 0x0200, 0, true, chan->inst, &chan->eng);
+       if (ret)
+               return ret;
+
+       ret = nvkm_gpuobj_new(device, 0x4000, 0, false, chan->inst, &chan->pgd);
+       if (ret)
+               return ret;
+
+       ret = nvkm_gpuobj_new(device, 0x1000, 0x400, true, chan->inst, &chan->cache);
+       if (ret)
+               return ret;
+
+       ret = nvkm_gpuobj_new(device, 0x100, 0x100, true, chan->inst, &chan->ramfc);
+       if (ret)
+               return ret;
+
+       ret = nvkm_ramht_new(device, 0x8000, 16, chan->inst, &chan->ramht);
+       if (ret)
+               return ret;
+
+       nv50_fifo_chan(chan)->eng = chan->eng;
+       nv50_fifo_chan(chan)->ramht = chan->ramht;
+
+       nvkm_kmap(chan->ramfc);
+       nvkm_wo32(chan->ramfc, 0x3c, 0x403f6078);
+       nvkm_wo32(chan->ramfc, 0x44, 0x01003fff);
+       nvkm_wo32(chan->ramfc, 0x48, chan->push->node->offset >> 4);
+       nvkm_wo32(chan->ramfc, 0x50, lower_32_bits(offset));
+       nvkm_wo32(chan->ramfc, 0x54, upper_32_bits(offset) | (limit2 << 16));
+       nvkm_wo32(chan->ramfc, 0x60, 0x7fffffff);
+       nvkm_wo32(chan->ramfc, 0x78, 0x00000000);
+       nvkm_wo32(chan->ramfc, 0x7c, 0x30000000 | devm);
+       nvkm_wo32(chan->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
+                                    (4 << 24) /* SEARCH_FULL */ |
+                                    (chan->ramht->gpuobj->node->offset >> 4));
+       nvkm_wo32(chan->ramfc, 0x88, chan->cache->addr >> 10);
+       nvkm_wo32(chan->ramfc, 0x98, chan->inst->addr >> 12);
+       nvkm_done(chan->ramfc);
+       return 0;
+}
+
+static const struct nvkm_chan_func_ramfc
+g84_chan_ramfc = {
+       .write = g84_chan_ramfc_write,
+       .ctxdma = true,
+       .devm = 0xfff,
+};
+
 const struct nvkm_chan_func
 g84_chan = {
        .inst = &nv50_chan_inst,
        .userd = &nv50_chan_userd,
+       .ramfc = &g84_chan_ramfc,
        .bind = g84_chan_bind,
        .unbind = nv50_chan_unbind,
        .start = nv50_chan_start,
index afee424..351b35d 100644 (file)
@@ -82,6 +82,39 @@ gf100_chan_bind(struct nvkm_chan *chan)
        nvkm_wr32(device, 0x003000 + (chan->id * 8), 0xc0000000 | chan->inst->addr >> 12);
 }
 
+static int
+gf100_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, bool priv)
+{
+       const u64 userd = nvkm_memory_addr(chan->userd.mem) + chan->userd.base;
+       const u32 limit2 = ilog2(length / 8);
+
+       nvkm_kmap(chan->inst);
+       nvkm_wo32(chan->inst, 0x08, lower_32_bits(userd));
+       nvkm_wo32(chan->inst, 0x0c, upper_32_bits(userd));
+       nvkm_wo32(chan->inst, 0x10, 0x0000face);
+       nvkm_wo32(chan->inst, 0x30, 0xfffff902);
+       nvkm_wo32(chan->inst, 0x48, lower_32_bits(offset));
+       nvkm_wo32(chan->inst, 0x4c, upper_32_bits(offset) | (limit2 << 16));
+       nvkm_wo32(chan->inst, 0x54, 0x00000002);
+       nvkm_wo32(chan->inst, 0x84, 0x20400000);
+       nvkm_wo32(chan->inst, 0x94, 0x30000000 | devm);
+       nvkm_wo32(chan->inst, 0x9c, 0x00000100);
+       nvkm_wo32(chan->inst, 0xa4, 0x1f1f1f1f);
+       nvkm_wo32(chan->inst, 0xa8, 0x1f1f1f1f);
+       nvkm_wo32(chan->inst, 0xac, 0x0000001f);
+       nvkm_wo32(chan->inst, 0xb8, 0xf8000000);
+       nvkm_wo32(chan->inst, 0xf8, 0x10003080); /* 0x002310 */
+       nvkm_wo32(chan->inst, 0xfc, 0x10000010); /* 0x002350 */
+       nvkm_done(chan->inst);
+       return 0;
+}
+
+static const struct nvkm_chan_func_ramfc
+gf100_chan_ramfc = {
+       .write = gf100_chan_ramfc_write,
+       .devm = 0xfff,
+};
+
 void
 gf100_chan_userd_clear(struct nvkm_chan *chan)
 {
@@ -117,6 +150,7 @@ static const struct nvkm_chan_func
 gf100_chan = {
        .inst = &gf100_chan_inst,
        .userd = &gf100_chan_userd,
+       .ramfc = &gf100_chan_ramfc,
        .bind = gf100_chan_bind,
        .unbind = gf100_chan_unbind,
        .start = gf100_chan_start,
index 61966d4..b75e3d0 100644 (file)
@@ -78,6 +78,39 @@ gk104_chan_bind(struct nvkm_chan *chan)
        gk104_chan_bind_inst(chan);
 }
 
+static int
+gk104_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, bool priv)
+{
+       const u64 userd = nvkm_memory_addr(chan->userd.mem) + chan->userd.base;
+       const u32 limit2 = ilog2(length / 8);
+
+       nvkm_kmap(chan->inst);
+       nvkm_wo32(chan->inst, 0x08, lower_32_bits(userd));
+       nvkm_wo32(chan->inst, 0x0c, upper_32_bits(userd));
+       nvkm_wo32(chan->inst, 0x10, 0x0000face);
+       nvkm_wo32(chan->inst, 0x30, 0xfffff902);
+       nvkm_wo32(chan->inst, 0x48, lower_32_bits(offset));
+       nvkm_wo32(chan->inst, 0x4c, upper_32_bits(offset) | (limit2 << 16));
+       nvkm_wo32(chan->inst, 0x84, 0x20400000);
+       nvkm_wo32(chan->inst, 0x94, 0x30000000 | devm);
+       nvkm_wo32(chan->inst, 0x9c, 0x00000100);
+       nvkm_wo32(chan->inst, 0xac, 0x0000001f);
+       nvkm_wo32(chan->inst, 0xe4, priv ? 0x00000020 : 0x00000000);
+       nvkm_wo32(chan->inst, 0xe8, chan->id);
+       nvkm_wo32(chan->inst, 0xb8, 0xf8000000);
+       nvkm_wo32(chan->inst, 0xf8, 0x10003080); /* 0x002310 */
+       nvkm_wo32(chan->inst, 0xfc, 0x10000010); /* 0x002350 */
+       nvkm_done(chan->inst);
+       return 0;
+}
+
+const struct nvkm_chan_func_ramfc
+gk104_chan_ramfc = {
+       .write = gk104_chan_ramfc_write,
+       .devm = 0xfff,
+       .priv = true,
+};
+
 const struct nvkm_chan_func_userd
 gk104_chan_userd = {
        .bar = 1,
@@ -89,6 +122,7 @@ static const struct nvkm_chan_func
 gk104_chan = {
        .inst = &gf100_chan_inst,
        .userd = &gk104_chan_userd,
+       .ramfc = &gk104_chan_ramfc,
        .bind = gk104_chan_bind,
        .unbind = gk104_chan_unbind,
        .start = gk104_chan_start,
index 7ff7a43..2a61721 100644 (file)
@@ -51,6 +51,7 @@ const struct nvkm_chan_func
 gk110_chan = {
        .inst = &gf100_chan_inst,
        .userd = &gk104_chan_userd,
+       .ramfc = &gk104_chan_ramfc,
        .bind = gk104_chan_bind,
        .unbind = gk104_chan_unbind,
        .start = gk104_chan_start,
index cc26380..3764245 100644 (file)
@@ -36,6 +36,7 @@ const struct nvkm_chan_func
 gm107_chan = {
        .inst = &gf100_chan_inst,
        .userd = &gk104_chan_userd,
+       .ramfc = &gk104_chan_ramfc,
        .bind = gk104_chan_bind_inst,
        .unbind = gk104_chan_unbind,
        .start = gk104_chan_start,
index 3157a76..3102244 100644 (file)
@@ -65,23 +65,9 @@ g84_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
 
        args->v0.chid = chan->base.chid;
        ioffset = args->v0.ioffset;
-       ilength = order_base_2(args->v0.ilength / 8);
+       ilength = args->v0.ilength;
 
-       nvkm_kmap(chan->ramfc);
-       nvkm_wo32(chan->ramfc, 0x3c, 0x403f6078);
-       nvkm_wo32(chan->ramfc, 0x44, 0x01003fff);
-       nvkm_wo32(chan->ramfc, 0x48, chan->base.push->node->offset >> 4);
-       nvkm_wo32(chan->ramfc, 0x50, lower_32_bits(ioffset));
-       nvkm_wo32(chan->ramfc, 0x54, upper_32_bits(ioffset) | (ilength << 16));
-       nvkm_wo32(chan->ramfc, 0x60, 0x7fffffff);
-       nvkm_wo32(chan->ramfc, 0x78, 0x00000000);
-       nvkm_wo32(chan->ramfc, 0x7c, 0x30000001);
-       nvkm_wo32(chan->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
-                                    (4 << 24) /* SEARCH_FULL */ |
-                                    (chan->ramht->gpuobj->node->offset >> 4));
-       nvkm_wo32(chan->ramfc, 0x88, chan->cache->addr >> 10);
-       nvkm_wo32(chan->ramfc, 0x98, chan->base.inst->addr >> 12);
-       nvkm_done(chan->ramfc);
+       chan->base.func->ramfc->write(&chan->base, ioffset, ilength, BIT(0), false);
        return 0;
 }
 
index 1e459af..c43cd0c 100644 (file)
@@ -190,28 +190,9 @@ gf100_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
 
        usermem = nvkm_memory_addr(chan->base.userd.mem) + chan->base.userd.base;
        ioffset = args->v0.ioffset;
-       ilength = order_base_2(args->v0.ilength / 8);
-
-       /* RAMFC */
-       nvkm_kmap(chan->base.inst);
-       nvkm_wo32(chan->base.inst, 0x08, lower_32_bits(usermem));
-       nvkm_wo32(chan->base.inst, 0x0c, upper_32_bits(usermem));
-       nvkm_wo32(chan->base.inst, 0x10, 0x0000face);
-       nvkm_wo32(chan->base.inst, 0x30, 0xfffff902);
-       nvkm_wo32(chan->base.inst, 0x48, lower_32_bits(ioffset));
-       nvkm_wo32(chan->base.inst, 0x4c, upper_32_bits(ioffset) |
-                                        (ilength << 16));
-       nvkm_wo32(chan->base.inst, 0x54, 0x00000002);
-       nvkm_wo32(chan->base.inst, 0x84, 0x20400000);
-       nvkm_wo32(chan->base.inst, 0x94, 0x30000001);
-       nvkm_wo32(chan->base.inst, 0x9c, 0x00000100);
-       nvkm_wo32(chan->base.inst, 0xa4, 0x1f1f1f1f);
-       nvkm_wo32(chan->base.inst, 0xa8, 0x1f1f1f1f);
-       nvkm_wo32(chan->base.inst, 0xac, 0x0000001f);
-       nvkm_wo32(chan->base.inst, 0xb8, 0xf8000000);
-       nvkm_wo32(chan->base.inst, 0xf8, 0x10003080); /* 0x002310 */
-       nvkm_wo32(chan->base.inst, 0xfc, 0x10000010); /* 0x002350 */
-       nvkm_done(chan->base.inst);
+       ilength = args->v0.ilength;
+
+       chan->base.func->ramfc->write(&chan->base, ioffset, ilength, BIT(0), false);
        return 0;
 }
 
index b02ec7c..77de170 100644 (file)
@@ -176,7 +176,6 @@ gk104_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
 {
        struct gk104_fifo_chan *chan;
        int runlist = ffs(*runlists) -1, ret;
-       u64 usermem;
 
        if (!vmm || runlist < 0 || runlist >= fifo->runlist_nr)
                return -EINVAL;
@@ -199,28 +198,7 @@ gk104_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
        *chid = chan->base.chid;
        *inst = chan->base.inst->addr;
 
-       usermem = nvkm_memory_addr(chan->base.userd.mem) + chan->base.userd.base;
-       ilength = order_base_2(ilength / 8);
-
-       /* RAMFC */
-       nvkm_kmap(chan->base.inst);
-       nvkm_wo32(chan->base.inst, 0x08, lower_32_bits(usermem));
-       nvkm_wo32(chan->base.inst, 0x0c, upper_32_bits(usermem));
-       nvkm_wo32(chan->base.inst, 0x10, 0x0000face);
-       nvkm_wo32(chan->base.inst, 0x30, 0xfffff902);
-       nvkm_wo32(chan->base.inst, 0x48, lower_32_bits(ioffset));
-       nvkm_wo32(chan->base.inst, 0x4c, upper_32_bits(ioffset) |
-                                        (ilength << 16));
-       nvkm_wo32(chan->base.inst, 0x84, 0x20400000);
-       nvkm_wo32(chan->base.inst, 0x94, 0x30000001);
-       nvkm_wo32(chan->base.inst, 0x9c, 0x00000100);
-       nvkm_wo32(chan->base.inst, 0xac, 0x0000001f);
-       nvkm_wo32(chan->base.inst, 0xe4, priv ? 0x00000020 : 0x00000000);
-       nvkm_wo32(chan->base.inst, 0xe8, chan->base.chid);
-       nvkm_wo32(chan->base.inst, 0xb8, 0xf8000000);
-       nvkm_wo32(chan->base.inst, 0xf8, 0x10003080); /* 0x002310 */
-       nvkm_wo32(chan->base.inst, 0xfc, 0x10000010); /* 0x002350 */
-       nvkm_done(chan->base.inst);
+       chan->base.func->ramfc->write(&chan->base, ioffset, ilength, BIT(0), priv);
        return 0;
 }
 
index 3177879..9a2308b 100644 (file)
@@ -120,7 +120,6 @@ gv100_fifo_gpfifo_new_(const struct nvkm_fifo_chan_func *func,
 {
        struct gk104_fifo_chan *chan;
        int runlist = ffs(*runlists) -1, ret;
-       u64 usermem;
 
        if (!vmm || runlist < 0 || runlist >= fifo->runlist_nr)
                return -EINVAL;
@@ -143,27 +142,7 @@ gv100_fifo_gpfifo_new_(const struct nvkm_fifo_chan_func *func,
        *inst = chan->base.inst->addr;
        *token = chan->base.func->doorbell_handle(&chan->base);
 
-       /* Clear channel control registers. */
-       usermem = nvkm_memory_addr(chan->base.userd.mem) + chan->base.userd.base;
-       ilength = order_base_2(ilength / 8);
-
-       /* RAMFC */
-       nvkm_kmap(chan->base.inst);
-       nvkm_wo32(chan->base.inst, 0x008, lower_32_bits(usermem));
-       nvkm_wo32(chan->base.inst, 0x00c, upper_32_bits(usermem));
-       nvkm_wo32(chan->base.inst, 0x010, 0x0000face);
-       nvkm_wo32(chan->base.inst, 0x030, 0x7ffff902);
-       nvkm_wo32(chan->base.inst, 0x048, lower_32_bits(ioffset));
-       nvkm_wo32(chan->base.inst, 0x04c, upper_32_bits(ioffset) |
-                                         (ilength << 16));
-       nvkm_wo32(chan->base.inst, 0x084, 0x20400000);
-       nvkm_wo32(chan->base.inst, 0x094, 0x30000001);
-       nvkm_wo32(chan->base.inst, 0x0e4, priv ? 0x00000020 : 0x00000000);
-       nvkm_wo32(chan->base.inst, 0x0e8, chan->base.chid);
-       nvkm_wo32(chan->base.inst, 0x0f4, 0x00001000);
-       nvkm_wo32(chan->base.inst, 0x0f8, 0x10003080);
-       nvkm_mo32(chan->base.inst, 0x218, 0x00000000, 0x00000000);
-       nvkm_done(chan->base.inst);
+       chan->base.func->ramfc->write(&chan->base, ioffset, ilength, BIT(0), priv);
        return 0;
 }
 
index 410fc9e..88ea7c2 100644 (file)
@@ -65,21 +65,9 @@ nv50_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
 
        args->v0.chid = chan->base.chid;
        ioffset = args->v0.ioffset;
-       ilength = order_base_2(args->v0.ilength / 8);
+       ilength = args->v0.ilength;
 
-       nvkm_kmap(chan->ramfc);
-       nvkm_wo32(chan->ramfc, 0x3c, 0x403f6078);
-       nvkm_wo32(chan->ramfc, 0x44, 0x01003fff);
-       nvkm_wo32(chan->ramfc, 0x48, chan->base.push->node->offset >> 4);
-       nvkm_wo32(chan->ramfc, 0x50, lower_32_bits(ioffset));
-       nvkm_wo32(chan->ramfc, 0x54, upper_32_bits(ioffset) | (ilength << 16));
-       nvkm_wo32(chan->ramfc, 0x60, 0x7fffffff);
-       nvkm_wo32(chan->ramfc, 0x78, 0x00000000);
-       nvkm_wo32(chan->ramfc, 0x7c, 0x30000001);
-       nvkm_wo32(chan->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
-                                    (4 << 24) /* SEARCH_FULL */ |
-                                    (chan->ramht->gpuobj->node->offset >> 4));
-       nvkm_done(chan->ramfc);
+       chan->base.func->ramfc->write(&chan->base, ioffset, ilength, BIT(0), false);
        return 0;
 }
 
index 9611bd7..ffca153 100644 (file)
@@ -38,6 +38,37 @@ gv100_chan_doorbell_handle(struct nvkm_chan *chan)
        return chan->id;
 }
 
+static int
+gv100_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, bool priv)
+{
+       const u64 userd = nvkm_memory_addr(chan->userd.mem) + chan->userd.base;
+       const u32 limit2 = ilog2(length / 8);
+
+       nvkm_kmap(chan->inst);
+       nvkm_wo32(chan->inst, 0x008, lower_32_bits(userd));
+       nvkm_wo32(chan->inst, 0x00c, upper_32_bits(userd));
+       nvkm_wo32(chan->inst, 0x010, 0x0000face);
+       nvkm_wo32(chan->inst, 0x030, 0x7ffff902);
+       nvkm_wo32(chan->inst, 0x048, lower_32_bits(offset));
+       nvkm_wo32(chan->inst, 0x04c, upper_32_bits(offset) | (limit2 << 16));
+       nvkm_wo32(chan->inst, 0x084, 0x20400000);
+       nvkm_wo32(chan->inst, 0x094, 0x30000000 | devm);
+       nvkm_wo32(chan->inst, 0x0e4, priv ? 0x00000020 : 0x00000000);
+       nvkm_wo32(chan->inst, 0x0e8, chan->id);
+       nvkm_wo32(chan->inst, 0x0f4, 0x00001000 | (priv ? 0x00000100 : 0x00000000));
+       nvkm_wo32(chan->inst, 0x0f8, 0x10003080);
+       nvkm_mo32(chan->inst, 0x218, 0x00000000, 0x00000000);
+       nvkm_done(chan->inst);
+       return 0;
+}
+
+const struct nvkm_chan_func_ramfc
+gv100_chan_ramfc = {
+       .write = gv100_chan_ramfc_write,
+       .devm = 0xfff,
+       .priv = true,
+};
+
 const struct nvkm_chan_func_userd
 gv100_chan_userd = {
        .bar = 1, /*FIXME: hw doesn't have poller, flip to user-allocated in uapi commit. */
@@ -49,6 +80,7 @@ static const struct nvkm_chan_func
 gv100_chan = {
        .inst = &gf100_chan_inst,
        .userd = &gv100_chan_userd,
+       .ramfc = &gv100_chan_ramfc,
        .bind = gk104_chan_bind_inst,
        .unbind = gk104_chan_unbind,
        .start = gk104_chan_start,
index f420710..cf8369b 100644 (file)
 
 #include <nvif/class.h>
 
-static const struct nv04_fifo_ramfc
-nv04_fifo_ramfc[] = {
-       { 32,  0, 0x00,  0, NV04_PFIFO_CACHE1_DMA_PUT },
-       { 32,  0, 0x04,  0, NV04_PFIFO_CACHE1_DMA_GET },
-       { 16,  0, 0x08,  0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
-       { 16, 16, 0x08,  0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
-       { 32,  0, 0x0c,  0, NV04_PFIFO_CACHE1_DMA_STATE },
-       { 32,  0, 0x10,  0, NV04_PFIFO_CACHE1_DMA_FETCH },
-       { 32,  0, 0x14,  0, NV04_PFIFO_CACHE1_ENGINE },
-       { 32,  0, 0x18,  0, NV04_PFIFO_CACHE1_PULL1 },
-       {}
-};
-
 void
 nv04_chan_stop(struct nvkm_chan *chan)
 {
-       struct nv04_fifo *fifo = nv04_fifo(chan->cgrp->runl->fifo);
-       struct nvkm_device *device = fifo->base.engine.subdev.device;
+       struct nvkm_fifo *fifo = chan->cgrp->runl->fifo;
+       struct nvkm_device *device = fifo->engine.subdev.device;
        struct nvkm_memory *fctx = device->imem->ramfc;
-       const struct nv04_fifo_ramfc *c;
+       const struct nvkm_ramfc_layout *c;
        unsigned long flags;
-       u32 data = nv04_fifo_chan(chan)->ramfc;
+       u32 data = chan->ramfc_offset;
        u32 chid;
 
        /* prevent fifo context switches */
-       spin_lock_irqsave(&fifo->base.lock, flags);
+       spin_lock_irqsave(&fifo->lock, flags);
        nvkm_wr32(device, NV03_PFIFO_CACHES, 0);
 
        /* if this channel is active, replace it with a null context */
-       chid = nvkm_rd32(device, NV03_PFIFO_CACHE1_PUSH1) & fifo->base.chid->mask;
+       chid = nvkm_rd32(device, NV03_PFIFO_CACHE1_PUSH1) & fifo->chid->mask;
        if (chid == chan->id) {
                nvkm_mask(device, NV04_PFIFO_CACHE1_DMA_PUSH, 0x00000001, 0);
                nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH0, 0);
                nvkm_mask(device, NV04_PFIFO_CACHE1_PULL0, 0x00000001, 0);
 
-               c = fifo->ramfc;
+               c = chan->func->ramfc->layout;
                nvkm_kmap(fctx);
                do {
                        u32 rm = ((1ULL << c->bits) - 1) << c->regs;
@@ -84,14 +71,14 @@ nv04_chan_stop(struct nvkm_chan *chan)
                } while ((++c)->bits);
                nvkm_done(fctx);
 
-               c = fifo->ramfc;
+               c = chan->func->ramfc->layout;
                do {
                        nvkm_wr32(device, c->regp, 0x00000000);
                } while ((++c)->bits);
 
                nvkm_wr32(device, NV03_PFIFO_CACHE1_GET, 0);
                nvkm_wr32(device, NV03_PFIFO_CACHE1_PUT, 0);
-               nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH1, fifo->base.chid->mask);
+               nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH1, fifo->chid->mask);
                nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH0, 1);
                nvkm_wr32(device, NV04_PFIFO_CACHE1_PULL0, 1);
        }
@@ -99,7 +86,7 @@ nv04_chan_stop(struct nvkm_chan *chan)
        /* restore normal operation, after disabling dma mode */
        nvkm_mask(device, NV04_PFIFO_MODE, BIT(chan->id), 0);
        nvkm_wr32(device, NV03_PFIFO_CACHES, 1);
-       spin_unlock_irqrestore(&fifo->base.lock, flags);
+       spin_unlock_irqrestore(&fifo->lock, flags);
 }
 
 void
@@ -113,6 +100,59 @@ nv04_chan_start(struct nvkm_chan *chan)
        spin_unlock_irqrestore(&fifo->lock, flags);
 }
 
+void
+nv04_chan_ramfc_clear(struct nvkm_chan *chan)
+{
+       struct nvkm_memory *ramfc = chan->cgrp->runl->fifo->engine.subdev.device->imem->ramfc;
+       const struct nvkm_ramfc_layout *c = chan->func->ramfc->layout;
+
+       nvkm_kmap(ramfc);
+       do {
+               nvkm_wo32(ramfc, chan->ramfc_offset + c->ctxp, 0x00000000);
+       } while ((++c)->bits);
+       nvkm_done(ramfc);
+}
+
+static int
+nv04_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, bool priv)
+{
+       struct nvkm_memory *ramfc = chan->cgrp->runl->fifo->engine.subdev.device->imem->ramfc;
+       const u32 base = chan->id * 32;
+
+       chan->ramfc_offset = base;
+
+       nvkm_kmap(ramfc);
+       nvkm_wo32(ramfc, base + 0x00, offset);
+       nvkm_wo32(ramfc, base + 0x04, offset);
+       nvkm_wo32(ramfc, base + 0x08, chan->push->addr >> 4);
+       nvkm_wo32(ramfc, base + 0x10, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
+                                     NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
+#ifdef __BIG_ENDIAN
+                                     NV_PFIFO_CACHE1_BIG_ENDIAN |
+#endif
+                                     NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
+       nvkm_done(ramfc);
+       return 0;
+}
+
+static const struct nvkm_chan_func_ramfc
+nv04_chan_ramfc = {
+       .layout = (const struct nvkm_ramfc_layout[]) {
+               { 32,  0, 0x00,  0, NV04_PFIFO_CACHE1_DMA_PUT },
+               { 32,  0, 0x04,  0, NV04_PFIFO_CACHE1_DMA_GET },
+               { 16,  0, 0x08,  0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
+               { 16, 16, 0x08,  0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
+               { 32,  0, 0x0c,  0, NV04_PFIFO_CACHE1_DMA_STATE },
+               { 32,  0, 0x10,  0, NV04_PFIFO_CACHE1_DMA_FETCH },
+               { 32,  0, 0x14,  0, NV04_PFIFO_CACHE1_ENGINE },
+               { 32,  0, 0x18,  0, NV04_PFIFO_CACHE1_PULL1 },
+               {}
+       },
+       .write = nv04_chan_ramfc_write,
+       .clear = nv04_chan_ramfc_clear,
+       .ctxdma = true,
+};
+
 const struct nvkm_chan_func_userd
 nv04_chan_userd = {
        .bar = 0,
@@ -129,6 +169,7 @@ static const struct nvkm_chan_func
 nv04_chan = {
        .inst = &nv04_chan_inst,
        .userd = &nv04_chan_userd,
+       .ramfc = &nv04_chan_ramfc,
        .start = nv04_chan_start,
        .stop = nv04_chan_stop,
 };
@@ -476,7 +517,6 @@ nv04_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device,
 
        if (!(fifo = kzalloc(sizeof(*fifo), GFP_KERNEL)))
                return -ENOMEM;
-       fifo->ramfc = ramfc;
        *pfifo = &fifo->base;
 
        ret = nvkm_fifo_ctor(func, device, type, inst, &fifo->base);
@@ -507,5 +547,5 @@ int
 nv04_fifo_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
              struct nvkm_fifo **pfifo)
 {
-       return nv04_fifo_new_(&nv04_fifo, device, type, inst, 16, nv04_fifo_ramfc, pfifo);
+       return nv04_fifo_new_(&nv04_fifo, device, type, inst, 0, NULL, pfifo);
 }
index 879c686..93248ab 100644 (file)
@@ -4,17 +4,10 @@
 #define nv04_fifo(p) container_of((p), struct nv04_fifo, base)
 #include "priv.h"
 
-struct nv04_fifo_ramfc {
-       unsigned bits:6;
-       unsigned ctxs:5;
-       unsigned ctxp:8;
-       unsigned regs:5;
-       unsigned regp;
-};
+#define nv04_fifo_ramfc nvkm_ramfc_layout
 
 struct nv04_fifo {
        struct nvkm_fifo base;
-       const struct nv04_fifo_ramfc *ramfc;
 };
 
 int nv04_fifo_new_(const struct nvkm_fifo_func *, struct nvkm_device *, enum nvkm_subdev_type, int,
index bbad5ff..c7dbcd2 100644 (file)
  *
  * Authors: Ben Skeggs
  */
+#include "cgrp.h"
 #include "chan.h"
+#include "runl.h"
+
+#include <core/gpuobj.h>
+#include <subdev/instmem.h>
 
 #include "nv04.h"
 #include "channv04.h"
 
 #include <nvif/class.h>
 
-static const struct nv04_fifo_ramfc
-nv10_fifo_ramfc[] = {
-       { 32,  0, 0x00,  0, NV04_PFIFO_CACHE1_DMA_PUT },
-       { 32,  0, 0x04,  0, NV04_PFIFO_CACHE1_DMA_GET },
-       { 32,  0, 0x08,  0, NV10_PFIFO_CACHE1_REF_CNT },
-       { 16,  0, 0x0c,  0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
-       { 16, 16, 0x0c,  0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
-       { 32,  0, 0x10,  0, NV04_PFIFO_CACHE1_DMA_STATE },
-       { 32,  0, 0x14,  0, NV04_PFIFO_CACHE1_DMA_FETCH },
-       { 32,  0, 0x18,  0, NV04_PFIFO_CACHE1_ENGINE },
-       { 32,  0, 0x1c,  0, NV04_PFIFO_CACHE1_PULL1 },
-       {}
+static int
+nv10_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, bool priv)
+{
+       struct nvkm_memory *ramfc = chan->cgrp->runl->fifo->engine.subdev.device->imem->ramfc;
+       const u32 base = chan->id * 32;
+
+       chan->ramfc_offset = base;
+
+       nvkm_kmap(ramfc);
+       nvkm_wo32(ramfc, base + 0x00, offset);
+       nvkm_wo32(ramfc, base + 0x04, offset);
+       nvkm_wo32(ramfc, base + 0x0c, chan->push->addr >> 4);
+       nvkm_wo32(ramfc, base + 0x14, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
+                                     NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
+#ifdef __BIG_ENDIAN
+                                     NV_PFIFO_CACHE1_BIG_ENDIAN |
+#endif
+                                     NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
+       nvkm_done(ramfc);
+       return 0;
+}
+
+static const struct nvkm_chan_func_ramfc
+nv10_chan_ramfc = {
+       .layout = (const struct nvkm_ramfc_layout[]) {
+               { 32,  0, 0x00,  0, NV04_PFIFO_CACHE1_DMA_PUT },
+               { 32,  0, 0x04,  0, NV04_PFIFO_CACHE1_DMA_GET },
+               { 32,  0, 0x08,  0, NV10_PFIFO_CACHE1_REF_CNT },
+               { 16,  0, 0x0c,  0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
+               { 16, 16, 0x0c,  0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
+               { 32,  0, 0x10,  0, NV04_PFIFO_CACHE1_DMA_STATE },
+               { 32,  0, 0x14,  0, NV04_PFIFO_CACHE1_DMA_FETCH },
+               { 32,  0, 0x18,  0, NV04_PFIFO_CACHE1_ENGINE },
+               { 32,  0, 0x1c,  0, NV04_PFIFO_CACHE1_PULL1 },
+               {}
+       },
+       .write = nv10_chan_ramfc_write,
+       .clear = nv04_chan_ramfc_clear,
+       .ctxdma = true,
 };
 
 static const struct nvkm_chan_func
 nv10_chan = {
        .inst = &nv04_chan_inst,
        .userd = &nv04_chan_userd,
+       .ramfc = &nv10_chan_ramfc,
        .start = nv04_chan_start,
        .stop = nv04_chan_stop,
 };
@@ -78,5 +111,5 @@ int
 nv10_fifo_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
              struct nvkm_fifo **pfifo)
 {
-       return nv04_fifo_new_(&nv10_fifo, device, type, inst, 32, nv10_fifo_ramfc, pfifo);
+       return nv04_fifo_new_(&nv10_fifo, device, type, inst, 0, NULL, pfifo);
 }
index b0dfa6f..a829b0b 100644 (file)
  *
  * Authors: Ben Skeggs
  */
+#include "cgrp.h"
 #include "chan.h"
 #include "chid.h"
+#include "runl.h"
 
 #include "nv04.h"
 #include "channv04.h"
 
 #include <nvif/class.h>
 
-static const struct nv04_fifo_ramfc
-nv17_fifo_ramfc[] = {
-       { 32,  0, 0x00,  0, NV04_PFIFO_CACHE1_DMA_PUT },
-       { 32,  0, 0x04,  0, NV04_PFIFO_CACHE1_DMA_GET },
-       { 32,  0, 0x08,  0, NV10_PFIFO_CACHE1_REF_CNT },
-       { 16,  0, 0x0c,  0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
-       { 16, 16, 0x0c,  0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
-       { 32,  0, 0x10,  0, NV04_PFIFO_CACHE1_DMA_STATE },
-       { 32,  0, 0x14,  0, NV04_PFIFO_CACHE1_DMA_FETCH },
-       { 32,  0, 0x18,  0, NV04_PFIFO_CACHE1_ENGINE },
-       { 32,  0, 0x1c,  0, NV04_PFIFO_CACHE1_PULL1 },
-       { 32,  0, 0x20,  0, NV10_PFIFO_CACHE1_ACQUIRE_VALUE },
-       { 32,  0, 0x24,  0, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP },
-       { 32,  0, 0x28,  0, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT },
-       { 32,  0, 0x2c,  0, NV10_PFIFO_CACHE1_SEMAPHORE },
-       { 32,  0, 0x30,  0, NV10_PFIFO_CACHE1_DMA_SUBROUTINE },
-       {}
+static int
+nv17_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, bool priv)
+{
+       struct nvkm_memory *ramfc = chan->cgrp->runl->fifo->engine.subdev.device->imem->ramfc;
+       const u32 base = chan->id * 64;
+
+       chan->ramfc_offset = base;
+
+       nvkm_kmap(ramfc);
+       nvkm_wo32(ramfc, base + 0x00, offset);
+       nvkm_wo32(ramfc, base + 0x04, offset);
+       nvkm_wo32(ramfc, base + 0x0c, chan->push->addr >> 4);
+       nvkm_wo32(ramfc, base + 0x14, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
+                                     NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
+#ifdef __BIG_ENDIAN
+                                     NV_PFIFO_CACHE1_BIG_ENDIAN |
+#endif
+                                     NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
+       nvkm_done(ramfc);
+       return 0;
+}
+
+static const struct nvkm_chan_func_ramfc
+nv17_chan_ramfc = {
+       .layout = (const struct nvkm_ramfc_layout[]) {
+               { 32,  0, 0x00,  0, NV04_PFIFO_CACHE1_DMA_PUT },
+               { 32,  0, 0x04,  0, NV04_PFIFO_CACHE1_DMA_GET },
+               { 32,  0, 0x08,  0, NV10_PFIFO_CACHE1_REF_CNT },
+               { 16,  0, 0x0c,  0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
+               { 16, 16, 0x0c,  0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
+               { 32,  0, 0x10,  0, NV04_PFIFO_CACHE1_DMA_STATE },
+               { 32,  0, 0x14,  0, NV04_PFIFO_CACHE1_DMA_FETCH },
+               { 32,  0, 0x18,  0, NV04_PFIFO_CACHE1_ENGINE },
+               { 32,  0, 0x1c,  0, NV04_PFIFO_CACHE1_PULL1 },
+               { 32,  0, 0x20,  0, NV10_PFIFO_CACHE1_ACQUIRE_VALUE },
+               { 32,  0, 0x24,  0, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP },
+               { 32,  0, 0x28,  0, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT },
+               { 32,  0, 0x2c,  0, NV10_PFIFO_CACHE1_SEMAPHORE },
+               { 32,  0, 0x30,  0, NV10_PFIFO_CACHE1_DMA_SUBROUTINE },
+               {}
+       },
+       .write = nv17_chan_ramfc_write,
+       .clear = nv04_chan_ramfc_clear,
+       .ctxdma = true,
 };
 
 static const struct nvkm_chan_func
 nv17_chan = {
        .inst = &nv04_chan_inst,
        .userd = &nv04_chan_userd,
+       .ramfc = &nv17_chan_ramfc,
        .start = nv04_chan_start,
        .stop = nv04_chan_stop,
 };
@@ -110,5 +140,5 @@ int
 nv17_fifo_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
              struct nvkm_fifo **pfifo)
 {
-       return nv04_fifo_new_(&nv17_fifo, device, type, inst, 32, nv17_fifo_ramfc, pfifo);
+       return nv04_fifo_new_(&nv17_fifo, device, type, inst, 0, NULL, pfifo);
 }
index c2dc2d7..faf19ec 100644 (file)
@@ -21,6 +21,7 @@
  *
  * Authors: Ben Skeggs
  */
+#include "cgrp.h"
 #include "chan.h"
 #include "chid.h"
 #include "runl.h"
 
 #include <nvif/class.h>
 
-static const struct nv04_fifo_ramfc
-nv40_fifo_ramfc[] = {
-       { 32,  0, 0x00,  0, NV04_PFIFO_CACHE1_DMA_PUT },
-       { 32,  0, 0x04,  0, NV04_PFIFO_CACHE1_DMA_GET },
-       { 32,  0, 0x08,  0, NV10_PFIFO_CACHE1_REF_CNT },
-       { 32,  0, 0x0c,  0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
-       { 32,  0, 0x10,  0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
-       { 32,  0, 0x14,  0, NV04_PFIFO_CACHE1_DMA_STATE },
-       { 28,  0, 0x18,  0, NV04_PFIFO_CACHE1_DMA_FETCH },
-       {  2, 28, 0x18, 28, 0x002058 },
-       { 32,  0, 0x1c,  0, NV04_PFIFO_CACHE1_ENGINE },
-       { 32,  0, 0x20,  0, NV04_PFIFO_CACHE1_PULL1 },
-       { 32,  0, 0x24,  0, NV10_PFIFO_CACHE1_ACQUIRE_VALUE },
-       { 32,  0, 0x28,  0, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP },
-       { 32,  0, 0x2c,  0, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT },
-       { 32,  0, 0x30,  0, NV10_PFIFO_CACHE1_SEMAPHORE },
-       { 32,  0, 0x34,  0, NV10_PFIFO_CACHE1_DMA_SUBROUTINE },
-       { 32,  0, 0x38,  0, NV40_PFIFO_GRCTX_INSTANCE },
-       { 17,  0, 0x3c,  0, NV04_PFIFO_DMA_TIMESLICE },
-       { 32,  0, 0x40,  0, 0x0032e4 },
-       { 32,  0, 0x44,  0, 0x0032e8 },
-       { 32,  0, 0x4c,  0, 0x002088 },
-       { 32,  0, 0x50,  0, 0x003300 },
-       { 32,  0, 0x54,  0, 0x00330c },
-       {}
+static int
+nv40_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, bool priv)
+{
+       struct nvkm_memory *ramfc = chan->cgrp->runl->fifo->engine.subdev.device->imem->ramfc;
+       const u32 base = chan->id * 128;
+
+       chan->ramfc_offset = base;
+       nv04_fifo_chan(chan)->ramfc = base;
+
+       nvkm_kmap(ramfc);
+       nvkm_wo32(ramfc, base + 0x00, offset);
+       nvkm_wo32(ramfc, base + 0x04, offset);
+       nvkm_wo32(ramfc, base + 0x0c, chan->push->addr >> 4);
+       nvkm_wo32(ramfc, base + 0x18, 0x30000000 |
+                                     NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
+                                     NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES |
+#ifdef __BIG_ENDIAN
+                                     NV_PFIFO_CACHE1_BIG_ENDIAN |
+#endif
+                                     NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8);
+       nvkm_wo32(ramfc, base + 0x3c, 0x0001ffff);
+       nvkm_done(ramfc);
+       return 0;
+}
+
+static const struct nvkm_chan_func_ramfc
+nv40_chan_ramfc = {
+       .layout = (const struct nvkm_ramfc_layout[]) {
+               { 32,  0, 0x00,  0, NV04_PFIFO_CACHE1_DMA_PUT },
+               { 32,  0, 0x04,  0, NV04_PFIFO_CACHE1_DMA_GET },
+               { 32,  0, 0x08,  0, NV10_PFIFO_CACHE1_REF_CNT },
+               { 32,  0, 0x0c,  0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
+               { 32,  0, 0x10,  0, NV04_PFIFO_CACHE1_DMA_DCOUNT },
+               { 32,  0, 0x14,  0, NV04_PFIFO_CACHE1_DMA_STATE },
+               { 28,  0, 0x18,  0, NV04_PFIFO_CACHE1_DMA_FETCH },
+               {  2, 28, 0x18, 28, 0x002058 },
+               { 32,  0, 0x1c,  0, NV04_PFIFO_CACHE1_ENGINE },
+               { 32,  0, 0x20,  0, NV04_PFIFO_CACHE1_PULL1 },
+               { 32,  0, 0x24,  0, NV10_PFIFO_CACHE1_ACQUIRE_VALUE },
+               { 32,  0, 0x28,  0, NV10_PFIFO_CACHE1_ACQUIRE_TIMESTAMP },
+               { 32,  0, 0x2c,  0, NV10_PFIFO_CACHE1_ACQUIRE_TIMEOUT },
+               { 32,  0, 0x30,  0, NV10_PFIFO_CACHE1_SEMAPHORE },
+               { 32,  0, 0x34,  0, NV10_PFIFO_CACHE1_DMA_SUBROUTINE },
+               { 32,  0, 0x38,  0, NV40_PFIFO_GRCTX_INSTANCE },
+               { 17,  0, 0x3c,  0, NV04_PFIFO_DMA_TIMESLICE },
+               { 32,  0, 0x40,  0, 0x0032e4 },
+               { 32,  0, 0x44,  0, 0x0032e8 },
+               { 32,  0, 0x4c,  0, 0x002088 },
+               { 32,  0, 0x50,  0, 0x003300 },
+               { 32,  0, 0x54,  0, 0x00330c },
+               {}
+       },
+       .write = nv40_chan_ramfc_write,
+       .clear = nv04_chan_ramfc_clear,
+       .ctxdma = true,
 };
 
 static const struct nvkm_chan_func_userd
@@ -73,6 +104,7 @@ static const struct nvkm_chan_func
 nv40_chan = {
        .inst = &nv04_chan_inst,
        .userd = &nv40_chan_userd,
+       .ramfc = &nv40_chan_ramfc,
        .start = nv04_chan_start,
        .stop = nv04_chan_stop,
 };
@@ -157,5 +189,5 @@ int
 nv40_fifo_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
              struct nvkm_fifo **pfifo)
 {
-       return nv04_fifo_new_(&nv40_fifo, device, type, inst, 32, nv40_fifo_ramfc, pfifo);
+       return nv04_fifo_new_(&nv40_fifo, device, type, inst, 0, NULL, pfifo);
 }
index 24b4580..7d5c0d0 100644 (file)
@@ -26,7 +26,7 @@
 #include "chid.h"
 #include "runl.h"
 
-#include <core/gpuobj.h>
+#include <core/ramht.h>
 #include <subdev/timer.h>
 
 #include "nv50.h"
@@ -63,9 +63,58 @@ nv50_chan_bind(struct nvkm_chan *chan)
 {
        struct nvkm_device *device = chan->cgrp->runl->fifo->engine.subdev.device;
 
-       nvkm_wr32(device, 0x002600 + (chan->id * 4), nv50_fifo_chan(chan)->ramfc->addr >> 12);
+       nvkm_wr32(device, 0x002600 + (chan->id * 4), chan->ramfc->addr >> 12);
 }
 
+static int
+nv50_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, bool priv)
+{
+       struct nvkm_device *device = chan->cgrp->runl->fifo->engine.subdev.device;
+       const u32 limit2 = ilog2(length / 8);
+       int ret;
+
+       ret = nvkm_gpuobj_new(device, 0x0200, 0x1000, true, chan->inst, &chan->ramfc);
+       if (ret)
+               return ret;
+
+       ret = nvkm_gpuobj_new(device, 0x1200, 0, true, chan->inst, &chan->eng);
+       if (ret)
+               return ret;
+
+       ret = nvkm_gpuobj_new(device, 0x4000, 0, false, chan->inst, &chan->pgd);
+       if (ret)
+               return ret;
+
+       ret = nvkm_ramht_new(device, 0x8000, 16, chan->inst, &chan->ramht);
+       if (ret)
+               return ret;
+
+       nv50_fifo_chan(chan)->eng = chan->eng;
+       nv50_fifo_chan(chan)->ramht = chan->ramht;
+
+       nvkm_kmap(chan->ramfc);
+       nvkm_wo32(chan->ramfc, 0x3c, 0x403f6078);
+       nvkm_wo32(chan->ramfc, 0x44, 0x01003fff);
+       nvkm_wo32(chan->ramfc, 0x48, chan->push->node->offset >> 4);
+       nvkm_wo32(chan->ramfc, 0x50, lower_32_bits(offset));
+       nvkm_wo32(chan->ramfc, 0x54, upper_32_bits(offset) | (limit2 << 16));
+       nvkm_wo32(chan->ramfc, 0x60, 0x7fffffff);
+       nvkm_wo32(chan->ramfc, 0x78, 0x00000000);
+       nvkm_wo32(chan->ramfc, 0x7c, 0x30000000 | devm);
+       nvkm_wo32(chan->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
+                                    (4 << 24) /* SEARCH_FULL */ |
+                                    (chan->ramht->gpuobj->node->offset >> 4));
+       nvkm_done(chan->ramfc);
+       return 0;
+}
+
+static const struct nvkm_chan_func_ramfc
+nv50_chan_ramfc = {
+       .write = nv50_chan_ramfc_write,
+       .ctxdma = true,
+       .devm = 0xfff,
+};
+
 const struct nvkm_chan_func_userd
 nv50_chan_userd = {
        .bar = 0,
@@ -83,6 +132,7 @@ static const struct nvkm_chan_func
 nv50_chan = {
        .inst = &nv50_chan_inst,
        .userd = &nv50_chan_userd,
+       .ramfc = &nv50_chan_ramfc,
        .bind = nv50_chan_bind,
        .unbind = nv50_chan_unbind,
        .start = nv50_chan_start,
index c56deb7..43f248a 100644 (file)
@@ -82,6 +82,7 @@ extern const struct nvkm_engn_func nv04_engn;
 extern const struct nvkm_cgrp_func nv04_cgrp;
 extern const struct nvkm_chan_func_inst nv04_chan_inst;
 extern const struct nvkm_chan_func_userd nv04_chan_userd;
+void nv04_chan_ramfc_clear(struct nvkm_chan *);
 void nv04_chan_start(struct nvkm_chan *);
 void nv04_chan_stop(struct nvkm_chan *);
 
@@ -154,6 +155,7 @@ bool gk104_engn_chsw(struct nvkm_engn *);
 int gk104_engn_cxid(struct nvkm_engn *, bool *cgid);
 extern const struct nvkm_engn_func gk104_engn_ce;
 extern const struct nvkm_chan_func_userd gk104_chan_userd;
+extern const struct nvkm_chan_func_ramfc gk104_chan_ramfc;
 void gk104_chan_bind(struct nvkm_chan *);
 void gk104_chan_bind_inst(struct nvkm_chan *);
 void gk104_chan_unbind(struct nvkm_chan *);
@@ -189,6 +191,7 @@ extern const struct nvkm_runq_func gv100_runq;
 extern const struct nvkm_engn_func gv100_engn;
 extern const struct nvkm_engn_func gv100_engn_ce;
 extern const struct nvkm_chan_func_userd gv100_chan_userd;
+extern const struct nvkm_chan_func_ramfc gv100_chan_ramfc;
 
 void tu102_fifo_intr_ctxsw_timeout_info(struct nvkm_engn *, u32 info);
 extern const struct nvkm_fifo_func_mmu_fault tu102_fifo_mmu_fault;
index 42d2975..a8452ee 100644 (file)
@@ -51,6 +51,7 @@ static const struct nvkm_chan_func
 tu102_chan = {
        .inst = &gf100_chan_inst,
        .userd = &gv100_chan_userd,
+       .ramfc = &gv100_chan_ramfc,
        .bind = gk104_chan_bind_inst,
        .unbind = gk104_chan_unbind,
        .start = tu102_chan_start,