Commit b88917fe authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/fifo/gk104-: separate out engine status parsing

We'll be wanting to reuse this logic in more places.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 21e6de29
......@@ -32,6 +32,47 @@
#include <nvif/class.h>
struct gk104_fifo_engine_status {
bool busy;
bool faulted;
bool chsw;
bool save;
bool load;
struct {
bool tsg;
u32 id;
} prev, next, *chan;
};
static void
gk104_fifo_engine_status(struct gk104_fifo *fifo, int engn,
struct gk104_fifo_engine_status *status)
{
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
struct nvkm_device *device = subdev->device;
u32 stat = nvkm_rd32(device, 0x002640 + (engn * 0x08));
status->busy = !!(stat & 0x80000000);
status->faulted = !!(stat & 0x40000000);
status->next.tsg = !!(stat & 0x10000000);
status->next.id = (stat & 0x0fff0000) >> 16;
status->chsw = !!(stat & 0x00008000);
status->save = !!(stat & 0x00004000);
status->load = !!(stat & 0x00002000);
status->prev.tsg = !!(stat & 0x00001000);
status->prev.id = (stat & 0x00000fff);
status->chan = status->load ? &status->next : &status->prev;
nvkm_debug(subdev, "engine %02d: busy %d faulted %d chsw %d "
"save %d load %d %sid %d%s-> %sid %d%s\n",
engn, status->busy, status->faulted,
status->chsw, status->save, status->load,
status->prev.tsg ? "tsg" : "ch", status->prev.id,
status->chan == &status->prev ? "*" : " ",
status->next.tsg ? "tsg" : "ch", status->next.id,
status->chan == &status->next ? "*" : " ");
}
static int
gk104_fifo_class_get(struct nvkm_fifo *base, int index,
const struct nvkm_fifo_chan_oclass **psclass)
......@@ -214,7 +255,6 @@ gk104_fifo_sched_reason[] = {
static void
gk104_fifo_intr_sched_ctxsw(struct gk104_fifo *fifo)
{
struct nvkm_device *device = fifo->base.engine.subdev.device;
struct gk104_fifo_chan *chan;
unsigned long flags;
u32 engn;
......@@ -223,21 +263,14 @@ gk104_fifo_intr_sched_ctxsw(struct gk104_fifo *fifo)
for (engn = 0; engn < fifo->engine_nr; engn++) {
struct nvkm_engine *engine = fifo->engine[engn].engine;
int runl = fifo->engine[engn].runl;
u32 stat = nvkm_rd32(device, 0x002640 + (engn * 0x08));
u32 busy = (stat & 0x80000000);
u32 next = (stat & 0x0fff0000) >> 16;
u32 chsw = (stat & 0x00008000);
u32 save = (stat & 0x00004000);
u32 load = (stat & 0x00002000);
u32 prev = (stat & 0x00000fff);
u32 chid = load ? next : prev;
(void)save;
if (!busy || !chsw)
struct gk104_fifo_engine_status status;
gk104_fifo_engine_status(fifo, engn, &status);
if (!status.busy || !status.chsw)
continue;
list_for_each_entry(chan, &fifo->runlist[runl].chan, head) {
if (chan->base.chid == chid && engine) {
if (chan->base.chid == status.chan->id && engine) {
gk104_fifo_recover(fifo, engine, chan);
break;
}
......
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