Commit 62742b5e authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/fifo: add chan bind()/unbind()

- stops programming (non-existent) runl id field on bind(), from maxwell
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent 3a6bc9c2
...@@ -16,6 +16,9 @@ struct nvkm_cctx { ...@@ -16,6 +16,9 @@ struct nvkm_cctx {
}; };
struct nvkm_chan_func { struct nvkm_chan_func {
void (*bind)(struct nvkm_chan *);
void (*unbind)(struct nvkm_chan *);
void *(*dtor)(struct nvkm_fifo_chan *); void *(*dtor)(struct nvkm_fifo_chan *);
void (*init)(struct nvkm_fifo_chan *); void (*init)(struct nvkm_fifo_chan *);
void (*fini)(struct nvkm_fifo_chan *); void (*fini)(struct nvkm_fifo_chan *);
......
...@@ -166,23 +166,10 @@ g84_fifo_chan_object_ctor(struct nvkm_fifo_chan *base, ...@@ -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); 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 static const struct nvkm_fifo_chan_func
g84_fifo_chan_func = { g84_fifo_chan_func = {
.dtor = nv50_fifo_chan_dtor, .dtor = nv50_fifo_chan_dtor,
.init = g84_fifo_chan_init, .init = nv50_fifo_chan_init,
.fini = nv50_fifo_chan_fini, .fini = nv50_fifo_chan_fini,
.engine_ctor = g84_fifo_chan_engine_ctor, .engine_ctor = g84_fifo_chan_engine_ctor,
.engine_dtor = nv50_fifo_chan_engine_dtor, .engine_dtor = nv50_fifo_chan_engine_dtor,
......
...@@ -194,19 +194,17 @@ nv50_fifo_chan_fini(struct nvkm_fifo_chan *base) ...@@ -194,19 +194,17 @@ nv50_fifo_chan_fini(struct nvkm_fifo_chan *base)
/* remove channel from runlist, fifo will unload context */ /* remove channel from runlist, fifo will unload context */
nvkm_mask(device, 0x002600 + (chid * 4), 0x80000000, 0x00000000); nvkm_mask(device, 0x002600 + (chid * 4), 0x80000000, 0x00000000);
nv50_fifo_runlist_update(fifo); nv50_fifo_runlist_update(fifo);
nvkm_wr32(device, 0x002600 + (chid * 4), 0x00000000);
} }
static void void
nv50_fifo_chan_init(struct nvkm_fifo_chan *base) nv50_fifo_chan_init(struct nvkm_fifo_chan *base)
{ {
struct nv50_fifo_chan *chan = nv50_fifo_chan(base); struct nv50_fifo_chan *chan = nv50_fifo_chan(base);
struct nv50_fifo *fifo = chan->fifo; struct nv50_fifo *fifo = chan->fifo;
struct nvkm_device *device = fifo->base.engine.subdev.device; struct nvkm_device *device = fifo->base.engine.subdev.device;
u64 addr = chan->ramfc->addr >> 12;
u32 chid = chan->base.chid; 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); nv50_fifo_runlist_update(fifo);
} }
......
...@@ -40,6 +40,7 @@ struct nv50_fifo_chan { ...@@ -40,6 +40,7 @@ struct nv50_fifo_chan {
int nv50_fifo_chan_ctor(struct nv50_fifo *, u64 vmm, u64 push, int nv50_fifo_chan_ctor(struct nv50_fifo *, u64 vmm, u64 push,
const struct nvkm_oclass *, struct nv50_fifo_chan *); const struct nvkm_oclass *, struct nv50_fifo_chan *);
void *nv50_fifo_chan_dtor(struct nvkm_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 *); void nv50_fifo_chan_fini(struct nvkm_fifo_chan *);
struct nvkm_gpuobj **nv50_fifo_chan_engine(struct nv50_fifo_chan *, struct nvkm_engine *); 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 *); void nv50_fifo_chan_engine_dtor(struct nvkm_fifo_chan *, struct nvkm_engine *);
......
...@@ -21,16 +21,29 @@ ...@@ -21,16 +21,29 @@
* *
* Authors: Ben Skeggs * Authors: Ben Skeggs
*/ */
#include "cgrp.h"
#include "chan.h" #include "chan.h"
#include "runl.h" #include "runl.h"
#include <core/gpuobj.h>
#include "nv50.h" #include "nv50.h"
#include "channv50.h" #include "channv50.h"
#include <nvif/class.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 const struct nvkm_chan_func
g84_chan = { g84_chan = {
.bind = g84_chan_bind,
.unbind = nv50_chan_unbind,
}; };
const struct nvkm_engn_func const struct nvkm_engn_func
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
* *
* Authors: Ben Skeggs * Authors: Ben Skeggs
*/ */
#include "cgrp.h"
#include "chan.h" #include "chan.h"
#include "chid.h" #include "chid.h"
#include "runl.h" #include "runl.h"
...@@ -38,8 +39,32 @@ ...@@ -38,8 +39,32 @@
#include <nvif/class.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 static const struct nvkm_chan_func
gf100_chan = { gf100_chan = {
.bind = gf100_chan_bind,
.unbind = gf100_chan_unbind,
}; };
static const struct nvkm_engn_func static const struct nvkm_engn_func
...@@ -619,15 +644,15 @@ gf100_fifo_intr_engine_unit(struct nvkm_fifo *fifo, int engn) ...@@ -619,15 +644,15 @@ gf100_fifo_intr_engine_unit(struct nvkm_fifo *fifo, int engn)
} }
} }
void static void
gf100_fifo_intr_engine(struct gf100_fifo *fifo) 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); u32 mask = nvkm_rd32(device, 0x0025a4);
while (mask) { while (mask) {
u32 unit = __ffs(mask); u32 unit = __ffs(mask);
gf100_fifo_intr_engine_unit(&fifo->base, unit); gf100_fifo_intr_engine_unit(fifo, unit);
mask &= ~(1 << unit); mask &= ~(1 << unit);
} }
} }
...@@ -684,7 +709,7 @@ gf100_fifo_intr(struct nvkm_inth *inth) ...@@ -684,7 +709,7 @@ gf100_fifo_intr(struct nvkm_inth *inth)
} }
if (stat & 0x80000000) { if (stat & 0x80000000) {
gf100_fifo_intr_engine(gf100_fifo(fifo)); gf100_fifo_intr_engine(fifo);
stat &= ~0x80000000; stat &= ~0x80000000;
} }
......
...@@ -28,7 +28,6 @@ struct gf100_fifo { ...@@ -28,7 +28,6 @@ struct gf100_fifo {
} user; } 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_insert(struct gf100_fifo *, struct gf100_fifo_chan *);
void gf100_fifo_runlist_remove(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 *); void gf100_fifo_runlist_commit(struct gf100_fifo *);
......
...@@ -38,8 +38,36 @@ ...@@ -38,8 +38,36 @@
#include <nvif/class.h> #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 static const struct nvkm_chan_func
gk104_chan = { gk104_chan = {
.bind = gk104_chan_bind,
.unbind = gk104_chan_unbind,
}; };
void void
......
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
const struct nvkm_chan_func const struct nvkm_chan_func
gk110_chan = { gk110_chan = {
.bind = gk104_chan_bind,
.unbind = gk104_chan_unbind,
}; };
const struct nvkm_cgrp_func const struct nvkm_cgrp_func
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
const struct nvkm_chan_func const struct nvkm_chan_func
gm107_chan = { gm107_chan = {
.bind = gk104_chan_bind_inst,
.unbind = gk104_chan_unbind,
}; };
static void static void
......
...@@ -157,10 +157,6 @@ gf100_fifo_gpfifo_fini(struct nvkm_fifo_chan *base) ...@@ -157,10 +157,6 @@ gf100_fifo_gpfifo_fini(struct nvkm_fifo_chan *base)
nvkm_mask(device, 0x003004 + coff, 0x00000001, 0x00000000); nvkm_mask(device, 0x003004 + coff, 0x00000001, 0x00000000);
gf100_fifo_runlist_commit(fifo); gf100_fifo_runlist_commit(fifo);
} }
gf100_fifo_intr_engine(fifo);
nvkm_wr32(device, 0x003000 + coff, 0x00000000);
} }
static void static void
...@@ -169,11 +165,8 @@ gf100_fifo_gpfifo_init(struct nvkm_fifo_chan *base) ...@@ -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_chan *chan = gf100_fifo_chan(base);
struct gf100_fifo *fifo = chan->fifo; struct gf100_fifo *fifo = chan->fifo;
struct nvkm_device *device = fifo->base.engine.subdev.device; struct nvkm_device *device = fifo->base.engine.subdev.device;
u32 addr = chan->base.inst->addr >> 12;
u32 coff = chan->base.chid * 8; u32 coff = chan->base.chid * 8;
nvkm_wr32(device, 0x003000 + coff, 0xc0000000 | addr);
if (list_empty(&chan->head) && !chan->killed) { if (list_empty(&chan->head) && !chan->killed) {
gf100_fifo_runlist_insert(fifo, chan); gf100_fifo_runlist_insert(fifo, chan);
nvkm_wr32(device, 0x003004 + coff, 0x001f0001); nvkm_wr32(device, 0x003004 + coff, 0x001f0001);
......
...@@ -208,8 +208,6 @@ gk104_fifo_gpfifo_fini(struct nvkm_fifo_chan *base) ...@@ -208,8 +208,6 @@ gk104_fifo_gpfifo_fini(struct nvkm_fifo_chan *base)
gk104_fifo_gpfifo_kick(chan); gk104_fifo_gpfifo_kick(chan);
gk104_fifo_runlist_update(fifo, chan->runl); gk104_fifo_runlist_update(fifo, chan->runl);
} }
nvkm_wr32(device, 0x800000 + coff, 0x00000000);
} }
void void
...@@ -218,12 +216,8 @@ gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *base) ...@@ -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_chan *chan = gk104_fifo_chan(base);
struct gk104_fifo *fifo = chan->fifo; struct gk104_fifo *fifo = chan->fifo;
struct nvkm_device *device = fifo->base.engine.subdev.device; struct nvkm_device *device = fifo->base.engine.subdev.device;
u32 addr = chan->base.inst->addr >> 12;
u32 coff = chan->base.chid * 8; 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) { if (list_empty(&chan->head) && !chan->killed) {
gk104_fifo_runlist_insert(fifo, chan); gk104_fifo_runlist_insert(fifo, chan);
nvkm_mask(device, 0x800004 + coff, 0x00000400, 0x00000400); nvkm_mask(device, 0x800004 + coff, 0x00000400, 0x00000400);
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
static const struct nvkm_chan_func static const struct nvkm_chan_func
gv100_chan = { gv100_chan = {
.bind = gk104_chan_bind_inst,
.unbind = gk104_chan_unbind,
}; };
const struct nvkm_engn_func const struct nvkm_engn_func
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
* *
* Authors: Ben Skeggs * Authors: Ben Skeggs
*/ */
#include "cgrp.h"
#include "chan.h" #include "chan.h"
#include "chid.h" #include "chid.h"
#include "runl.h" #include "runl.h"
...@@ -33,8 +34,26 @@ ...@@ -33,8 +34,26 @@
#include <nvif/class.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 static const struct nvkm_chan_func
nv50_chan = { nv50_chan = {
.bind = nv50_chan_bind,
.unbind = nv50_chan_unbind,
}; };
static const struct nvkm_engn_func static const struct nvkm_engn_func
......
...@@ -103,6 +103,7 @@ int nv50_fifo_chid_ctor(struct nvkm_fifo *, int); ...@@ -103,6 +103,7 @@ int nv50_fifo_chid_ctor(struct nvkm_fifo *, int);
extern const struct nvkm_runl_func nv50_runl; extern const struct nvkm_runl_func nv50_runl;
int nv50_runl_wait(struct nvkm_runl *); int nv50_runl_wait(struct nvkm_runl *);
extern const struct nvkm_engn_func nv50_engn_sw; 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_event_func g84_fifo_nonstall;
extern const struct nvkm_engn_func g84_engn; extern const struct nvkm_engn_func g84_engn;
...@@ -142,6 +143,9 @@ bool gk104_runq_intr(struct nvkm_runq *, struct nvkm_runl *); ...@@ -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_bitfield gk104_runq_intr_0_names[];
extern const struct nvkm_engn_func gk104_engn; extern const struct nvkm_engn_func gk104_engn;
extern const struct nvkm_engn_func gk104_engn_ce; 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); int gk110_fifo_chid_ctor(struct nvkm_fifo *, int);
extern const struct nvkm_runl_func gk110_runl; extern const struct nvkm_runl_func gk110_runl;
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
static const struct nvkm_chan_func static const struct nvkm_chan_func
tu102_chan = { tu102_chan = {
.bind = gk104_chan_bind_inst,
.unbind = gk104_chan_unbind,
}; };
static bool static bool
......
...@@ -217,6 +217,9 @@ nvkm_uchan_fini(struct nvkm_object *object, bool suspend) ...@@ -217,6 +217,9 @@ nvkm_uchan_fini(struct nvkm_object *object, bool suspend)
if (ret && suspend) if (ret && suspend)
return ret; return ret;
if (chan->func->unbind)
chan->func->unbind(chan);
return 0; return 0;
} }
...@@ -225,6 +228,9 @@ nvkm_uchan_init(struct nvkm_object *object) ...@@ -225,6 +228,9 @@ nvkm_uchan_init(struct nvkm_object *object)
{ {
struct nvkm_chan *chan = nvkm_uchan(object)->chan; struct nvkm_chan *chan = nvkm_uchan(object)->chan;
if (chan->func->bind)
chan->func->bind(chan);
return chan->object.func->init(&chan->object); return chan->object.func->init(&chan->object);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment