From 62742b5ef314c622ae9d848938223071ba360706 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 1 Jun 2022 20:47:31 +1000 Subject: drm/nouveau/fifo: add chan bind()/unbind() - stops programming (non-existent) runl id field on bind(), from maxwell Signed-off-by: Ben Skeggs Reviewed-by: Lyude Paul --- drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h | 3 ++ drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c | 15 +--------- .../gpu/drm/nouveau/nvkm/engine/fifo/channv50.c | 6 ++-- .../gpu/drm/nouveau/nvkm/engine/fifo/channv50.h | 1 + drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c | 13 ++++++++ drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c | 35 ++++++++++++++++++---- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h | 1 - drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 28 +++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c | 2 ++ .../gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c | 7 ----- .../gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c | 6 ---- drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c | 19 ++++++++++++ drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h | 4 +++ drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c | 2 ++ drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c | 6 ++++ 17 files changed, 115 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h index bf1c3b580def..fe398ed544cf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h @@ -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 *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c index 903b54c07750..100631a44a85 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c @@ -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, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c index c44d7c81dd52..0fc97c4c341a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c @@ -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); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h index 3a95730d7ff5..5d5d9f3d9928 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h @@ -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 *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c index afaa2dea4ef8..2777f03ffc29 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c @@ -21,16 +21,29 @@ * * Authors: Ben Skeggs */ +#include "cgrp.h" #include "chan.h" #include "runl.h" +#include + #include "nv50.h" #include "channv50.h" #include +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 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c index fcfc241c8a99..50109f4f3860 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c @@ -21,6 +21,7 @@ * * Authors: Ben Skeggs */ +#include "cgrp.h" #include "chan.h" #include "chid.h" #include "runl.h" @@ -38,8 +39,32 @@ #include +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; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h index 8e0c1a5e3c57..16268e81077d 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h @@ -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 *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index 12aebf83f090..fafe9453ab0c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -38,8 +38,36 @@ #include +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 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c index 134de3c71ad5..1724937a2f5f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c @@ -35,6 +35,8 @@ const struct nvkm_chan_func gk110_chan = { + .bind = gk104_chan_bind, + .unbind = gk104_chan_unbind, }; const struct nvkm_cgrp_func diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c index d3b2aa701f53..742404bf8415 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c @@ -34,6 +34,8 @@ const struct nvkm_chan_func gm107_chan = { + .bind = gk104_chan_bind_inst, + .unbind = gk104_chan_unbind, }; static void diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c index 5d6e3a7b8f1e..93739b34bfcd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c @@ -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); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c index 6415e80a1fbf..c2b5eaa9cdea 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c @@ -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); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c index c147c26b80ca..eb59527544b2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c @@ -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 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c index 16e59d8ea325..d7adb057e4ca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c @@ -21,6 +21,7 @@ * * Authors: Ben Skeggs */ +#include "cgrp.h" #include "chan.h" #include "chid.h" #include "runl.h" @@ -33,8 +34,26 @@ #include +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 diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h index 16fe77ee4c86..f023aa0a559e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h @@ -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; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c index 7d3c9d8e54a7..b23fc330aa6c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c @@ -33,6 +33,8 @@ static const struct nvkm_chan_func tu102_chan = { + .bind = gk104_chan_bind_inst, + .unbind = gk104_chan_unbind, }; static bool diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c index 8681ff045887..c1d2035e00cf 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c @@ -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); } -- cgit v1.2.1