drm/nouveau/fifo: add chan bind()/unbind()
authorBen Skeggs <bskeggs@redhat.com>
Wed, 1 Jun 2022 10:47:31 +0000 (20:47 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 9 Nov 2022 00:44:48 +0000 (10:44 +1000)
- stops programming (non-existent) runl id field on bind(), from maxwell

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
17 files changed:
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/g84.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h
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/gpfifogf100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.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
drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c

index bf1c3b580defd101549e2d231b91baa20f0ea3f1..fe398ed544cf02db940a012760f76127961f4d54 100644 (file)
@@ -16,6 +16,9 @@ struct nvkm_cctx {
 };
 
 struct nvkm_chan_func {
+       void (*bind)(struct nvkm_chan *);
+       void (*unbind)(struct nvkm_chan *);
+
        void *(*dtor)(struct nvkm_fifo_chan *);
        void (*init)(struct nvkm_fifo_chan *);
        void (*fini)(struct nvkm_fifo_chan *);
index 903b54c07750e27ffaf8cd659a30c922dd762fd6..100631a44a85ee66b0ce3a75be79eba23457a004 100644 (file)
@@ -166,23 +166,10 @@ g84_fifo_chan_object_ctor(struct nvkm_fifo_chan *base,
        return nvkm_ramht_insert(chan->ramht, object, 0, 4, handle, context);
 }
 
-static void
-g84_fifo_chan_init(struct nvkm_fifo_chan *base)
-{
-       struct nv50_fifo_chan *chan = nv50_fifo_chan(base);
-       struct nv50_fifo *fifo = chan->fifo;
-       struct nvkm_device *device = fifo->base.engine.subdev.device;
-       u64 addr = chan->ramfc->addr >> 8;
-       u32 chid = chan->base.chid;
-
-       nvkm_wr32(device, 0x002600 + (chid * 4), 0x80000000 | addr);
-       nv50_fifo_runlist_update(fifo);
-}
-
 static const struct nvkm_fifo_chan_func
 g84_fifo_chan_func = {
        .dtor = nv50_fifo_chan_dtor,
-       .init = g84_fifo_chan_init,
+       .init = nv50_fifo_chan_init,
        .fini = nv50_fifo_chan_fini,
        .engine_ctor = g84_fifo_chan_engine_ctor,
        .engine_dtor = nv50_fifo_chan_engine_dtor,
index c44d7c81dd52a531d5f4fd323ab1056d39f1c43f..0fc97c4c341ad85cf7ec739c2aa533eb210257ca 100644 (file)
@@ -194,19 +194,17 @@ nv50_fifo_chan_fini(struct nvkm_fifo_chan *base)
        /* remove channel from runlist, fifo will unload context */
        nvkm_mask(device, 0x002600 + (chid * 4), 0x80000000, 0x00000000);
        nv50_fifo_runlist_update(fifo);
-       nvkm_wr32(device, 0x002600 + (chid * 4), 0x00000000);
 }
 
-static void
+void
 nv50_fifo_chan_init(struct nvkm_fifo_chan *base)
 {
        struct nv50_fifo_chan *chan = nv50_fifo_chan(base);
        struct nv50_fifo *fifo = chan->fifo;
        struct nvkm_device *device = fifo->base.engine.subdev.device;
-       u64 addr = chan->ramfc->addr >> 12;
        u32 chid = chan->base.chid;
 
-       nvkm_wr32(device, 0x002600 + (chid * 4), 0x80000000 | addr);
+       nvkm_mask(device, 0x002600 + (chid * 4), 0x80000000, 0x80000000);
        nv50_fifo_runlist_update(fifo);
 }
 
index 3a95730d7ff506390ed3746312a9cb958520a922..5d5d9f3d99280876dc776fdcc8299d17152fc227 100644 (file)
@@ -40,6 +40,7 @@ struct nv50_fifo_chan {
 int nv50_fifo_chan_ctor(struct nv50_fifo *, u64 vmm, u64 push,
                        const struct nvkm_oclass *, struct nv50_fifo_chan *);
 void *nv50_fifo_chan_dtor(struct nvkm_fifo_chan *);
+void nv50_fifo_chan_init(struct nvkm_fifo_chan *);
 void nv50_fifo_chan_fini(struct nvkm_fifo_chan *);
 struct nvkm_gpuobj **nv50_fifo_chan_engine(struct nv50_fifo_chan *, struct nvkm_engine *);
 void nv50_fifo_chan_engine_dtor(struct nvkm_fifo_chan *, struct nvkm_engine *);
index afaa2dea4ef844ba807f270410217b6be6fb9ef4..2777f03ffc29912c7f47a551aad836c0142b5515 100644 (file)
  *
  * Authors: Ben Skeggs
  */
+#include "cgrp.h"
 #include "chan.h"
 #include "runl.h"
 
+#include <core/gpuobj.h>
+
 #include "nv50.h"
 #include "channv50.h"
 
 #include <nvif/class.h>
 
+static void
+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);
+}
+
 const struct nvkm_chan_func
 g84_chan = {
+       .bind = g84_chan_bind,
+       .unbind = nv50_chan_unbind,
 };
 
 const struct nvkm_engn_func
index fcfc241c8a993f539cc3b3b5918d840cbf2f3d86..50109f4f3860d2ec23af12c4b63fb6e570db0772 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 void gf100_fifo_intr_engine(struct nvkm_fifo *);
+
+static void
+gf100_chan_unbind(struct nvkm_chan *chan)
+{
+       struct nvkm_fifo *fifo = chan->cgrp->runl->fifo;
+       struct nvkm_device *device = fifo->engine.subdev.device;
+
+       /*TODO: Is this cargo-culted, or necessary? RM does *something* here... Why? */
+       gf100_fifo_intr_engine(fifo);
+
+       nvkm_wr32(device, 0x003000 + (chan->id * 8), 0x00000000);
+}
+
+static void
+gf100_chan_bind(struct nvkm_chan *chan)
+{
+       struct nvkm_device *device = chan->cgrp->runl->fifo->engine.subdev.device;
+
+       nvkm_wr32(device, 0x003000 + (chan->id * 8), 0xc0000000 | chan->inst->addr >> 12);
+}
+
 static const struct nvkm_chan_func
 gf100_chan = {
+       .bind = gf100_chan_bind,
+       .unbind = gf100_chan_unbind,
 };
 
 static const struct nvkm_engn_func
@@ -619,15 +644,15 @@ gf100_fifo_intr_engine_unit(struct nvkm_fifo *fifo, int engn)
        }
 }
 
-void
-gf100_fifo_intr_engine(struct gf100_fifo *fifo)
+static void
+gf100_fifo_intr_engine(struct nvkm_fifo *fifo)
 {
-       struct nvkm_device *device = fifo->base.engine.subdev.device;
+       struct nvkm_device *device = fifo->engine.subdev.device;
        u32 mask = nvkm_rd32(device, 0x0025a4);
 
        while (mask) {
                u32 unit = __ffs(mask);
-               gf100_fifo_intr_engine_unit(&fifo->base, unit);
+               gf100_fifo_intr_engine_unit(fifo, unit);
                mask &= ~(1 << unit);
        }
 }
@@ -684,7 +709,7 @@ gf100_fifo_intr(struct nvkm_inth *inth)
        }
 
        if (stat & 0x80000000) {
-               gf100_fifo_intr_engine(gf100_fifo(fifo));
+               gf100_fifo_intr_engine(fifo);
                stat &= ~0x80000000;
        }
 
index 8e0c1a5e3c5784e4cd4e0fc1df7eca9e7de6882f..16268e81077d7853285a158da0f8a4dfae97398c 100644 (file)
@@ -28,7 +28,6 @@ struct gf100_fifo {
        } user;
 };
 
-void gf100_fifo_intr_engine(struct gf100_fifo *);
 void gf100_fifo_runlist_insert(struct gf100_fifo *, struct gf100_fifo_chan *);
 void gf100_fifo_runlist_remove(struct gf100_fifo *, struct gf100_fifo_chan *);
 void gf100_fifo_runlist_commit(struct gf100_fifo *);
index 12aebf83f0909a94657f420b56327aa63a288a0b..fafe9453ab0c30c5c6c013e4fe32fac595118a99 100644 (file)
 
 #include <nvif/class.h>
 
+void
+gk104_chan_unbind(struct nvkm_chan *chan)
+{
+       struct nvkm_device *device = chan->cgrp->runl->fifo->engine.subdev.device;
+
+       nvkm_wr32(device, 0x800000 + (chan->id * 8), 0x00000000);
+}
+
+void
+gk104_chan_bind_inst(struct nvkm_chan *chan)
+{
+       struct nvkm_device *device = chan->cgrp->runl->fifo->engine.subdev.device;
+
+       nvkm_wr32(device, 0x800000 + (chan->id * 8), 0x80000000 | chan->inst->addr >> 12);
+}
+
+void
+gk104_chan_bind(struct nvkm_chan *chan)
+{
+       struct nvkm_runl *runl = chan->cgrp->runl;
+       struct nvkm_device *device = runl->fifo->engine.subdev.device;
+
+       nvkm_mask(device, 0x800004 + (chan->id * 8), 0x000f0000, runl->id << 16);
+       gk104_chan_bind_inst(chan);
+}
+
 static const struct nvkm_chan_func
 gk104_chan = {
+       .bind = gk104_chan_bind,
+       .unbind = gk104_chan_unbind,
 };
 
 void
index 134de3c71ad59a5769f407b3b600ba4097c40f22..1724937a2f5fbada1d23d293b7d363d16555b847 100644 (file)
@@ -35,6 +35,8 @@
 
 const struct nvkm_chan_func
 gk110_chan = {
+       .bind = gk104_chan_bind,
+       .unbind = gk104_chan_unbind,
 };
 
 const struct nvkm_cgrp_func
index d3b2aa701f5323a57f19c54e2eec9c6d6e92a1cf..742404bf8415275f5b3a993d83afbe69967d6522 100644 (file)
@@ -34,6 +34,8 @@
 
 const struct nvkm_chan_func
 gm107_chan = {
+       .bind = gk104_chan_bind_inst,
+       .unbind = gk104_chan_unbind,
 };
 
 static void
index 5d6e3a7b8f1e498751a6c495d6025ae01df4187a..93739b34bfcdced209d5d997f65d2123702f0186 100644 (file)
@@ -157,10 +157,6 @@ gf100_fifo_gpfifo_fini(struct nvkm_fifo_chan *base)
                nvkm_mask(device, 0x003004 + coff, 0x00000001, 0x00000000);
                gf100_fifo_runlist_commit(fifo);
        }
-
-       gf100_fifo_intr_engine(fifo);
-
-       nvkm_wr32(device, 0x003000 + coff, 0x00000000);
 }
 
 static void
@@ -169,11 +165,8 @@ gf100_fifo_gpfifo_init(struct nvkm_fifo_chan *base)
        struct gf100_fifo_chan *chan = gf100_fifo_chan(base);
        struct gf100_fifo *fifo = chan->fifo;
        struct nvkm_device *device = fifo->base.engine.subdev.device;
-       u32 addr = chan->base.inst->addr >> 12;
        u32 coff = chan->base.chid * 8;
 
-       nvkm_wr32(device, 0x003000 + coff, 0xc0000000 | addr);
-
        if (list_empty(&chan->head) && !chan->killed) {
                gf100_fifo_runlist_insert(fifo, chan);
                nvkm_wr32(device, 0x003004 + coff, 0x001f0001);
index 6415e80a1fbf18c23125933056f2f9f6d901fac2..c2b5eaa9cdea441e21d6a7f8397569d36392d31f 100644 (file)
@@ -208,8 +208,6 @@ gk104_fifo_gpfifo_fini(struct nvkm_fifo_chan *base)
                gk104_fifo_gpfifo_kick(chan);
                gk104_fifo_runlist_update(fifo, chan->runl);
        }
-
-       nvkm_wr32(device, 0x800000 + coff, 0x00000000);
 }
 
 void
@@ -218,12 +216,8 @@ gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *base)
        struct gk104_fifo_chan *chan = gk104_fifo_chan(base);
        struct gk104_fifo *fifo = chan->fifo;
        struct nvkm_device *device = fifo->base.engine.subdev.device;
-       u32 addr = chan->base.inst->addr >> 12;
        u32 coff = chan->base.chid * 8;
 
-       nvkm_mask(device, 0x800004 + coff, 0x000f0000, chan->runl << 16);
-       nvkm_wr32(device, 0x800000 + coff, 0x80000000 | addr);
-
        if (list_empty(&chan->head) && !chan->killed) {
                gk104_fifo_runlist_insert(fifo, chan);
                nvkm_mask(device, 0x800004 + coff, 0x00000400, 0x00000400);
index c147c26b80ca887ce8ec994bab6b091a59d7ef27..eb59527544b28e65586a906a95ce9594a7d9ddbc 100644 (file)
@@ -33,6 +33,8 @@
 
 static const struct nvkm_chan_func
 gv100_chan = {
+       .bind = gk104_chan_bind_inst,
+       .unbind = gk104_chan_unbind,
 };
 
 const struct nvkm_engn_func
index 16e59d8ea3256a078b7a04b5365d609916e6ad9d..d7adb057e4ca8865c7bec99f4fa3879a7fdbd90f 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>
 
+void
+nv50_chan_unbind(struct nvkm_chan *chan)
+{
+       struct nvkm_device *device = chan->cgrp->runl->fifo->engine.subdev.device;
+
+       nvkm_wr32(device, 0x002600 + (chan->id * 4), 0x00000000);
+}
+
+static void
+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);
+}
+
 static const struct nvkm_chan_func
 nv50_chan = {
+       .bind = nv50_chan_bind,
+       .unbind = nv50_chan_unbind,
 };
 
 static const struct nvkm_engn_func
index 16fe77ee4c867733762ca108a9a9921c244e63d7..f023aa0a559e3cf162256af980fa1f0224879e03 100644 (file)
@@ -103,6 +103,7 @@ int nv50_fifo_chid_ctor(struct nvkm_fifo *, int);
 extern const struct nvkm_runl_func nv50_runl;
 int nv50_runl_wait(struct nvkm_runl *);
 extern const struct nvkm_engn_func nv50_engn_sw;
+void nv50_chan_unbind(struct nvkm_chan *);
 
 extern const struct nvkm_event_func g84_fifo_nonstall;
 extern const struct nvkm_engn_func g84_engn;
@@ -142,6 +143,9 @@ bool gk104_runq_intr(struct nvkm_runq *, struct nvkm_runl *);
 extern const struct nvkm_bitfield gk104_runq_intr_0_names[];
 extern const struct nvkm_engn_func gk104_engn;
 extern const struct nvkm_engn_func gk104_engn_ce;
+void gk104_chan_bind(struct nvkm_chan *);
+void gk104_chan_bind_inst(struct nvkm_chan *);
+void gk104_chan_unbind(struct nvkm_chan *);
 
 int gk110_fifo_chid_ctor(struct nvkm_fifo *, int);
 extern const struct nvkm_runl_func gk110_runl;
index 7d3c9d8e54a74ed04e5052e0fe596d54bd705a9e..b23fc330aa6cbb80a78b2552a37fd6e7b3d236fc 100644 (file)
@@ -33,6 +33,8 @@
 
 static const struct nvkm_chan_func
 tu102_chan = {
+       .bind = gk104_chan_bind_inst,
+       .unbind = gk104_chan_unbind,
 };
 
 static bool
index 8681ff0458877ddfe5d1807b181838509bd57d4a..c1d2035e00cf2726e14fae893d0e7b0624f0716c 100644 (file)
@@ -217,6 +217,9 @@ nvkm_uchan_fini(struct nvkm_object *object, bool suspend)
        if (ret && suspend)
                return ret;
 
+       if (chan->func->unbind)
+               chan->func->unbind(chan);
+
        return 0;
 }
 
@@ -225,6 +228,9 @@ nvkm_uchan_init(struct nvkm_object *object)
 {
        struct nvkm_chan *chan = nvkm_uchan(object)->chan;
 
+       if (chan->func->bind)
+               chan->func->bind(chan);
+
        return chan->object.func->init(&chan->object);
 }