Commit 55e1a599 authored by Ben Skeggs's avatar Ben Skeggs Committed by Karol Herbst

drm/nouveau/fifo/ga100-: add per-runlist nonstall intr handling

GSP-RM will enforce this, so implement on HW too so we can share code.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarKarol Herbst <kherbst@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
Signed-off-by: default avatarKarol Herbst <kherbst@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230525003106.3853741-8-skeggsb@gmail.com
parent 84ab065e
...@@ -22,6 +22,7 @@ struct nvkm_engine_func { ...@@ -22,6 +22,7 @@ struct nvkm_engine_func {
int (*init)(struct nvkm_engine *); int (*init)(struct nvkm_engine *);
int (*fini)(struct nvkm_engine *, bool suspend); int (*fini)(struct nvkm_engine *, bool suspend);
int (*reset)(struct nvkm_engine *); int (*reset)(struct nvkm_engine *);
int (*nonstall)(struct nvkm_engine *);
void (*intr)(struct nvkm_engine *); void (*intr)(struct nvkm_engine *);
void (*tile)(struct nvkm_engine *, int region, struct nvkm_fb_tile *); void (*tile)(struct nvkm_engine *, int region, struct nvkm_fb_tile *);
bool (*chsw_load)(struct nvkm_engine *); bool (*chsw_load)(struct nvkm_engine *);
......
...@@ -35,6 +35,15 @@ ga100_ce_intr(struct nvkm_inth *inth) ...@@ -35,6 +35,15 @@ ga100_ce_intr(struct nvkm_inth *inth)
return IRQ_NONE; return IRQ_NONE;
} }
int
ga100_ce_nonstall(struct nvkm_engine *engine)
{
struct nvkm_subdev *subdev = &engine->subdev;
struct nvkm_device *device = subdev->device;
return nvkm_rd32(device, 0x104424 + (subdev->inst * 0x80)) & 0x00000fff;
}
int int
ga100_ce_fini(struct nvkm_engine *engine, bool suspend) ga100_ce_fini(struct nvkm_engine *engine, bool suspend)
{ {
...@@ -67,6 +76,7 @@ ga100_ce = { ...@@ -67,6 +76,7 @@ ga100_ce = {
.oneinit = ga100_ce_oneinit, .oneinit = ga100_ce_oneinit,
.init = ga100_ce_init, .init = ga100_ce_init,
.fini = ga100_ce_fini, .fini = ga100_ce_fini,
.nonstall = ga100_ce_nonstall,
.cclass = &gv100_ce_cclass, .cclass = &gv100_ce_cclass,
.sclass = { .sclass = {
{ -1, -1, AMPERE_DMA_COPY_A }, { -1, -1, AMPERE_DMA_COPY_A },
......
...@@ -28,6 +28,7 @@ ga102_ce = { ...@@ -28,6 +28,7 @@ ga102_ce = {
.oneinit = ga100_ce_oneinit, .oneinit = ga100_ce_oneinit,
.init = ga100_ce_init, .init = ga100_ce_init,
.fini = ga100_ce_fini, .fini = ga100_ce_fini,
.nonstall = ga100_ce_nonstall,
.cclass = &gv100_ce_cclass, .cclass = &gv100_ce_cclass,
.sclass = { .sclass = {
{ -1, -1, AMPERE_DMA_COPY_A }, { -1, -1, AMPERE_DMA_COPY_A },
......
...@@ -12,4 +12,5 @@ extern const struct nvkm_object_func gv100_ce_cclass; ...@@ -12,4 +12,5 @@ extern const struct nvkm_object_func gv100_ce_cclass;
int ga100_ce_oneinit(struct nvkm_engine *); int ga100_ce_oneinit(struct nvkm_engine *);
int ga100_ce_init(struct nvkm_engine *); int ga100_ce_init(struct nvkm_engine *);
int ga100_ce_fini(struct nvkm_engine *, bool); int ga100_ce_fini(struct nvkm_engine *, bool);
int ga100_ce_nonstall(struct nvkm_engine *);
#endif #endif
...@@ -283,11 +283,21 @@ nvkm_fifo_oneinit(struct nvkm_engine *engine) ...@@ -283,11 +283,21 @@ nvkm_fifo_oneinit(struct nvkm_engine *engine)
} }
/* Initialise non-stall intr handling. */ /* Initialise non-stall intr handling. */
if (fifo->func->nonstall) {
if (fifo->func->nonstall_ctor) { if (fifo->func->nonstall_ctor) {
ret = fifo->func->nonstall_ctor(fifo); ret = fifo->func->nonstall_ctor(fifo);
if (ret) { if (ret < 0) {
nvkm_error(subdev, "nonstall %d\n", ret); nvkm_error(subdev, "nonstall %d\n", ret);
return ret;
} }
} else {
ret = 1;
}
ret = nvkm_event_init(fifo->func->nonstall, &fifo->engine.subdev, 1, ret,
&fifo->nonstall.event);
if (ret)
return ret;
} }
/* Allocate USERD + BAR1 polling area. */ /* Allocate USERD + BAR1 polling area. */
...@@ -358,7 +368,6 @@ nvkm_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device, ...@@ -358,7 +368,6 @@ nvkm_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device,
enum nvkm_subdev_type type, int inst, struct nvkm_fifo **pfifo) enum nvkm_subdev_type type, int inst, struct nvkm_fifo **pfifo)
{ {
struct nvkm_fifo *fifo; struct nvkm_fifo *fifo;
int ret;
if (!(fifo = *pfifo = kzalloc(sizeof(*fifo), GFP_KERNEL))) if (!(fifo = *pfifo = kzalloc(sizeof(*fifo), GFP_KERNEL)))
return -ENOMEM; return -ENOMEM;
...@@ -374,16 +383,5 @@ nvkm_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device, ...@@ -374,16 +383,5 @@ nvkm_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device,
spin_lock_init(&fifo->lock); spin_lock_init(&fifo->lock);
mutex_init(&fifo->mutex); mutex_init(&fifo->mutex);
ret = nvkm_engine_ctor(&nvkm_fifo, device, type, inst, true, &fifo->engine); return nvkm_engine_ctor(&nvkm_fifo, device, type, inst, true, &fifo->engine);
if (ret)
return ret;
if (func->nonstall) {
ret = nvkm_event_init(func->nonstall, &fifo->engine.subdev, 1, 1,
&fifo->nonstall.event);
if (ret)
return ret;
}
return 0;
} }
...@@ -32,9 +32,6 @@ ...@@ -32,9 +32,6 @@
#include <nvif/class.h> #include <nvif/class.h>
/*TODO: allocate? */
#define GA100_FIFO_NONSTALL_VECTOR 0
static u32 static u32
ga100_chan_doorbell_handle(struct nvkm_chan *chan) ga100_chan_doorbell_handle(struct nvkm_chan *chan)
{ {
...@@ -83,7 +80,7 @@ ga100_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm, ...@@ -83,7 +80,7 @@ ga100_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm,
nvkm_wo32(chan->inst, 0x0e4, priv ? 0x00000020 : 0x00000000); nvkm_wo32(chan->inst, 0x0e4, priv ? 0x00000020 : 0x00000000);
nvkm_wo32(chan->inst, 0x0e8, chan->id); nvkm_wo32(chan->inst, 0x0e8, chan->id);
nvkm_wo32(chan->inst, 0x0f4, 0x00001000 | (priv ? 0x00000100 : 0x00000000)); nvkm_wo32(chan->inst, 0x0f4, 0x00001000 | (priv ? 0x00000100 : 0x00000000));
nvkm_wo32(chan->inst, 0x0f8, 0x80000000 | GA100_FIFO_NONSTALL_VECTOR); nvkm_wo32(chan->inst, 0x0f8, 0x80000000 | chan->cgrp->runl->nonstall.vector);
nvkm_mo32(chan->inst, 0x218, 0x00000000, 0x00000000); nvkm_mo32(chan->inst, 0x218, 0x00000000, 0x00000000);
nvkm_done(chan->inst); nvkm_done(chan->inst);
return 0; return 0;
...@@ -148,8 +145,20 @@ ga100_engn_cxid(struct nvkm_engn *engn, bool *cgid) ...@@ -148,8 +145,20 @@ ga100_engn_cxid(struct nvkm_engn *engn, bool *cgid)
return -ENODEV; return -ENODEV;
} }
static int
ga100_engn_nonstall(struct nvkm_engn *engn)
{
struct nvkm_engine *engine = engn->engine;
if (WARN_ON(!engine->func->nonstall))
return -EINVAL;
return engine->func->nonstall(engine);
}
const struct nvkm_engn_func const struct nvkm_engn_func
ga100_engn = { ga100_engn = {
.nonstall = ga100_engn_nonstall,
.cxid = ga100_engn_cxid, .cxid = ga100_engn_cxid,
.ctor = gk104_ectx_ctor, .ctor = gk104_ectx_ctor,
.bind = gv100_ectx_bind, .bind = gv100_ectx_bind,
...@@ -157,6 +166,7 @@ ga100_engn = { ...@@ -157,6 +166,7 @@ ga100_engn = {
const struct nvkm_engn_func const struct nvkm_engn_func
ga100_engn_ce = { ga100_engn_ce = {
.nonstall = ga100_engn_nonstall,
.cxid = ga100_engn_cxid, .cxid = ga100_engn_cxid,
.ctor = gv100_ectx_ce_ctor, .ctor = gv100_ectx_ce_ctor,
.bind = gv100_ectx_ce_bind, .bind = gv100_ectx_ce_bind,
...@@ -470,6 +480,11 @@ ga100_runl_new(struct nvkm_fifo *fifo, int id, u32 addr, struct nvkm_runl **prun ...@@ -470,6 +480,11 @@ ga100_runl_new(struct nvkm_fifo *fifo, int id, u32 addr, struct nvkm_runl **prun
tdev->type, tdev->inst); tdev->type, tdev->inst);
if (!engn) if (!engn)
return -EINVAL; return -EINVAL;
if (!engn->engine->func->nonstall) {
RUNL_DEBUG(runl, "engn %s !nonstall", engn->engine->subdev.name);
return -EINVAL;
}
} }
if (list_empty(&runl->engns)) { if (list_empty(&runl->engns)) {
...@@ -492,9 +507,9 @@ ga100_runl_new(struct nvkm_fifo *fifo, int id, u32 addr, struct nvkm_runl **prun ...@@ -492,9 +507,9 @@ ga100_runl_new(struct nvkm_fifo *fifo, int id, u32 addr, struct nvkm_runl **prun
static irqreturn_t static irqreturn_t
ga100_fifo_nonstall_intr(struct nvkm_inth *inth) ga100_fifo_nonstall_intr(struct nvkm_inth *inth)
{ {
struct nvkm_fifo *fifo = container_of(inth, typeof(*fifo), nonstall.intr); struct nvkm_runl *runl = container_of(inth, typeof(*runl), nonstall.inth);
nvkm_event_ntfy(&fifo->nonstall.event, 0, NVKM_FIFO_NONSTALL_EVENT); nvkm_event_ntfy(&runl->fifo->nonstall.event, runl->id, NVKM_FIFO_NONSTALL_EVENT);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -502,16 +517,18 @@ static void ...@@ -502,16 +517,18 @@ static void
ga100_fifo_nonstall_block(struct nvkm_event *event, int type, int index) ga100_fifo_nonstall_block(struct nvkm_event *event, int type, int index)
{ {
struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), nonstall.event); struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), nonstall.event);
struct nvkm_runl *runl = nvkm_runl_get(fifo, index, 0);
nvkm_inth_block(&fifo->nonstall.intr); nvkm_inth_block(&runl->nonstall.inth);
} }
static void static void
ga100_fifo_nonstall_allow(struct nvkm_event *event, int type, int index) ga100_fifo_nonstall_allow(struct nvkm_event *event, int type, int index)
{ {
struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), nonstall.event); struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), nonstall.event);
struct nvkm_runl *runl = nvkm_runl_get(fifo, index, 0);
nvkm_inth_allow(&fifo->nonstall.intr); nvkm_inth_allow(&runl->nonstall.inth);
} }
const struct nvkm_event_func const struct nvkm_event_func
...@@ -523,9 +540,29 @@ ga100_fifo_nonstall = { ...@@ -523,9 +540,29 @@ ga100_fifo_nonstall = {
int int
ga100_fifo_nonstall_ctor(struct nvkm_fifo *fifo) ga100_fifo_nonstall_ctor(struct nvkm_fifo *fifo)
{ {
return nvkm_inth_add(&fifo->engine.subdev.device->vfn->intr, GA100_FIFO_NONSTALL_VECTOR, struct nvkm_subdev *subdev = &fifo->engine.subdev;
NVKM_INTR_PRIO_NORMAL, &fifo->engine.subdev, ga100_fifo_nonstall_intr, struct nvkm_vfn *vfn = subdev->device->vfn;
&fifo->nonstall.intr); struct nvkm_runl *runl;
int ret, nr = 0;
nvkm_runl_foreach(runl, fifo) {
struct nvkm_engn *engn = list_first_entry(&runl->engns, typeof(*engn), head);
runl->nonstall.vector = engn->func->nonstall(engn);
if (runl->nonstall.vector < 0) {
RUNL_ERROR(runl, "nonstall %d", runl->nonstall.vector);
return runl->nonstall.vector;
}
ret = nvkm_inth_add(&vfn->intr, runl->nonstall.vector, NVKM_INTR_PRIO_NORMAL,
subdev, ga100_fifo_nonstall_intr, &runl->nonstall.inth);
if (ret)
return ret;
nr = max(nr, runl->id + 1);
}
return nr;
} }
int int
......
...@@ -11,6 +11,7 @@ enum nvkm_subdev_type; ...@@ -11,6 +11,7 @@ enum nvkm_subdev_type;
struct nvkm_engn { struct nvkm_engn {
const struct nvkm_engn_func { const struct nvkm_engn_func {
int (*nonstall)(struct nvkm_engn *);
bool (*chsw)(struct nvkm_engn *); bool (*chsw)(struct nvkm_engn *);
int (*cxid)(struct nvkm_engn *, bool *cgid); int (*cxid)(struct nvkm_engn *, bool *cgid);
void (*mmu_fault_trigger)(struct nvkm_engn *); void (*mmu_fault_trigger)(struct nvkm_engn *);
...@@ -69,6 +70,11 @@ struct nvkm_runl { ...@@ -69,6 +70,11 @@ struct nvkm_runl {
struct nvkm_inth inth; struct nvkm_inth inth;
struct {
int vector;
struct nvkm_inth inth;
} nonstall;
struct list_head cgrps; struct list_head cgrps;
int cgrp_nr; int cgrp_nr;
int chan_nr; int chan_nr;
......
...@@ -52,7 +52,7 @@ nvkm_uchan_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_ ...@@ -52,7 +52,7 @@ nvkm_uchan_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_
switch (args->v0.type) { switch (args->v0.type) {
case NVIF_CHAN_EVENT_V0_NON_STALL_INTR: case NVIF_CHAN_EVENT_V0_NON_STALL_INTR:
return nvkm_uevent_add(uevent, &runl->fifo->nonstall.event, 0, return nvkm_uevent_add(uevent, &runl->fifo->nonstall.event, runl->id,
NVKM_FIFO_NONSTALL_EVENT, NULL); NVKM_FIFO_NONSTALL_EVENT, NULL);
case NVIF_CHAN_EVENT_V0_KILLED: case NVIF_CHAN_EVENT_V0_KILLED:
return nvkm_uevent_add(uevent, &runl->chid->event, chan->id, return nvkm_uevent_add(uevent, &runl->chid->event, chan->id,
......
...@@ -125,6 +125,17 @@ nvkm_gr_intr(struct nvkm_engine *engine) ...@@ -125,6 +125,17 @@ nvkm_gr_intr(struct nvkm_engine *engine)
gr->func->intr(gr); gr->func->intr(gr);
} }
static int
nvkm_gr_nonstall(struct nvkm_engine *engine)
{
struct nvkm_gr *gr = nvkm_gr(engine);
if (gr->func->nonstall)
return gr->func->nonstall(gr);
return -EINVAL;
}
static int static int
nvkm_gr_oneinit(struct nvkm_engine *engine) nvkm_gr_oneinit(struct nvkm_engine *engine)
{ {
...@@ -177,6 +188,7 @@ nvkm_gr = { ...@@ -177,6 +188,7 @@ nvkm_gr = {
.init = nvkm_gr_init, .init = nvkm_gr_init,
.fini = nvkm_gr_fini, .fini = nvkm_gr_fini,
.reset = nvkm_gr_reset, .reset = nvkm_gr_reset,
.nonstall = nvkm_gr_nonstall,
.intr = nvkm_gr_intr, .intr = nvkm_gr_intr,
.tile = nvkm_gr_tile, .tile = nvkm_gr_tile,
.chsw_load = nvkm_gr_chsw_load, .chsw_load = nvkm_gr_chsw_load,
......
...@@ -137,8 +137,15 @@ ga102_gr_oneinit_intr(struct gf100_gr *gr, enum nvkm_intr_type *pvector) ...@@ -137,8 +137,15 @@ ga102_gr_oneinit_intr(struct gf100_gr *gr, enum nvkm_intr_type *pvector)
return &device->vfn->intr; return &device->vfn->intr;
} }
static int
ga102_gr_nonstall(struct gf100_gr *gr)
{
return nvkm_rd32(gr->base.engine.subdev.device, 0x400160) & 0x00000fff;
}
static const struct gf100_gr_func static const struct gf100_gr_func
ga102_gr = { ga102_gr = {
.nonstall = ga102_gr_nonstall,
.oneinit_intr = ga102_gr_oneinit_intr, .oneinit_intr = ga102_gr_oneinit_intr,
.oneinit_tiles = gm200_gr_oneinit_tiles, .oneinit_tiles = gm200_gr_oneinit_tiles,
.oneinit_sm_id = gv100_gr_oneinit_sm_id, .oneinit_sm_id = gv100_gr_oneinit_sm_id,
......
...@@ -2494,12 +2494,24 @@ gf100_gr_gpccs_ucode = { ...@@ -2494,12 +2494,24 @@ gf100_gr_gpccs_ucode = {
.data.size = sizeof(gf100_grgpc_data), .data.size = sizeof(gf100_grgpc_data),
}; };
static int
gf100_gr_nonstall(struct nvkm_gr *base)
{
struct gf100_gr *gr = gf100_gr(base);
if (gr->func->nonstall)
return gr->func->nonstall(gr);
return -EINVAL;
}
static const struct nvkm_gr_func static const struct nvkm_gr_func
gf100_gr_ = { gf100_gr_ = {
.dtor = gf100_gr_dtor, .dtor = gf100_gr_dtor,
.oneinit = gf100_gr_oneinit, .oneinit = gf100_gr_oneinit,
.init = gf100_gr_init_, .init = gf100_gr_init_,
.fini = gf100_gr_fini, .fini = gf100_gr_fini,
.nonstall = gf100_gr_nonstall,
.reset = gf100_gr_reset, .reset = gf100_gr_reset,
.units = gf100_gr_units, .units = gf100_gr_units,
.chan_new = gf100_gr_chan_new, .chan_new = gf100_gr_chan_new,
......
...@@ -147,6 +147,7 @@ struct gf100_gr_func_zbc { ...@@ -147,6 +147,7 @@ struct gf100_gr_func_zbc {
}; };
struct gf100_gr_func { struct gf100_gr_func {
int (*nonstall)(struct gf100_gr *);
struct nvkm_intr *(*oneinit_intr)(struct gf100_gr *, enum nvkm_intr_type *); struct nvkm_intr *(*oneinit_intr)(struct gf100_gr *, enum nvkm_intr_type *);
void (*oneinit_tiles)(struct gf100_gr *); void (*oneinit_tiles)(struct gf100_gr *);
int (*oneinit_sm_id)(struct gf100_gr *); int (*oneinit_sm_id)(struct gf100_gr *);
......
...@@ -18,6 +18,7 @@ struct nvkm_gr_func { ...@@ -18,6 +18,7 @@ struct nvkm_gr_func {
int (*init)(struct nvkm_gr *); int (*init)(struct nvkm_gr *);
int (*fini)(struct nvkm_gr *, bool); int (*fini)(struct nvkm_gr *, bool);
int (*reset)(struct nvkm_gr *); int (*reset)(struct nvkm_gr *);
int (*nonstall)(struct nvkm_gr *);
void (*intr)(struct nvkm_gr *); void (*intr)(struct nvkm_gr *);
void (*tile)(struct nvkm_gr *, int region, struct nvkm_fb_tile *); void (*tile)(struct nvkm_gr *, int region, struct nvkm_fb_tile *);
int (*tlb_flush)(struct nvkm_gr *); int (*tlb_flush)(struct nvkm_gr *);
......
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