summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2022-06-01 20:47:31 +1000
committerBen Skeggs <bskeggs@redhat.com>2022-11-09 10:44:48 +1000
commit62742b5ef314c622ae9d848938223071ba360706 (patch)
tree90295c9f910287bbea6e791b392b39273d54d982
parent3a6bc9c242e10c203a5b083af7823b50b5d63010 (diff)
downloadlinux-62742b5ef314c622ae9d848938223071ba360706.tar.bz2
drm/nouveau/fifo: add chan bind()/unbind()
- 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>
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h3
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c15
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.c6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/channv50.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c35
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.h1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c28
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c19
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h4
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c6
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 <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
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 <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;
}
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 <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
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 <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
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);
}