Commit e43c872c authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/fifo: merge mmu fault handlers together

After updating GF100 implementation from the GK104/TU102 ones, and using
the new runlist/engine topology info, all three handlers become (almost)
identical.

- there's a temporary kludge to call through to the HW-specific recovery
- engine fault mapping info determined at load time, not on every fault
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent 923f1ff5
...@@ -295,7 +295,7 @@ gf100_fifo_recover(struct gf100_fifo *fifo, struct nvkm_engine *engine, ...@@ -295,7 +295,7 @@ gf100_fifo_recover(struct gf100_fifo *fifo, struct nvkm_engine *engine,
} }
static const struct nvkm_enum static const struct nvkm_enum
gf100_fifo_fault_engine[] = { gf100_fifo_mmu_fault_engine[] = {
{ 0x00, "PGRAPH", NULL, NVKM_ENGINE_GR }, { 0x00, "PGRAPH", NULL, NVKM_ENGINE_GR },
{ 0x03, "PEEPHOLE", NULL, NVKM_ENGINE_IFB }, { 0x03, "PEEPHOLE", NULL, NVKM_ENGINE_IFB },
{ 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR }, { 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR },
...@@ -312,7 +312,7 @@ gf100_fifo_fault_engine[] = { ...@@ -312,7 +312,7 @@ gf100_fifo_fault_engine[] = {
}; };
static const struct nvkm_enum static const struct nvkm_enum
gf100_fifo_fault_reason[] = { gf100_fifo_mmu_fault_reason[] = {
{ 0x00, "PT_NOT_PRESENT" }, { 0x00, "PT_NOT_PRESENT" },
{ 0x01, "PT_TOO_SHORT" }, { 0x01, "PT_TOO_SHORT" },
{ 0x02, "PAGE_NOT_PRESENT" }, { 0x02, "PAGE_NOT_PRESENT" },
...@@ -326,7 +326,7 @@ gf100_fifo_fault_reason[] = { ...@@ -326,7 +326,7 @@ gf100_fifo_fault_reason[] = {
}; };
static const struct nvkm_enum static const struct nvkm_enum
gf100_fifo_fault_hubclient[] = { gf100_fifo_mmu_fault_hubclient[] = {
{ 0x01, "PCOPY0" }, { 0x01, "PCOPY0" },
{ 0x02, "PCOPY1" }, { 0x02, "PCOPY1" },
{ 0x04, "DISPATCH" }, { 0x04, "DISPATCH" },
...@@ -345,7 +345,7 @@ gf100_fifo_fault_hubclient[] = { ...@@ -345,7 +345,7 @@ gf100_fifo_fault_hubclient[] = {
}; };
static const struct nvkm_enum static const struct nvkm_enum
gf100_fifo_fault_gpcclient[] = { gf100_fifo_mmu_fault_gpcclient[] = {
{ 0x01, "TEX" }, { 0x01, "TEX" },
{ 0x0c, "ESETUP" }, { 0x0c, "ESETUP" },
{ 0x0e, "CTXCTL" }, { 0x0e, "CTXCTL" },
...@@ -353,29 +353,48 @@ gf100_fifo_fault_gpcclient[] = { ...@@ -353,29 +353,48 @@ gf100_fifo_fault_gpcclient[] = {
{} {}
}; };
static void const struct nvkm_enum
gf100_fifo_fault(struct nvkm_fifo *base, struct nvkm_fault_data *info) gf100_fifo_mmu_fault_access[] = {
{ 0x00, "READ" },
{ 0x01, "WRITE" },
{}
};
void
gf100_fifo_mmu_fault_recover(struct nvkm_fifo *fifo, struct nvkm_fault_data *info)
{ {
struct gf100_fifo *fifo = gf100_fifo(base); struct nvkm_subdev *subdev = &fifo->engine.subdev;
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
struct nvkm_device *device = subdev->device; struct nvkm_device *device = subdev->device;
const struct nvkm_enum *er, *eu, *ec; const struct nvkm_enum *er, *ee, *ec, *ea;
struct nvkm_engine *engine = NULL; struct nvkm_engine *engine = NULL;
struct nvkm_fifo_chan *chan; struct nvkm_fifo_chan *chan;
struct nvkm_runl *runl;
struct nvkm_engn *engn;
unsigned long flags; unsigned long flags;
char gpcid[8] = ""; char ct[8] = "HUB/";
/* Lookup engine by MMU fault ID. */
nvkm_runl_foreach(runl, fifo) {
engn = nvkm_runl_find_engn(engn, runl, engn->fault == info->engine);
if (engn) {
engine = engn->engine;
break;
}
}
er = nvkm_enum_find(gf100_fifo_fault_reason, info->reason); er = nvkm_enum_find(fifo->func->mmu_fault->reason, info->reason);
eu = nvkm_enum_find(gf100_fifo_fault_engine, info->engine); ee = nvkm_enum_find(fifo->func->mmu_fault->engine, info->engine);
if (info->hub) { if (info->hub) {
ec = nvkm_enum_find(gf100_fifo_fault_hubclient, info->client); ec = nvkm_enum_find(fifo->func->mmu_fault->hubclient, info->client);
} else { } else {
ec = nvkm_enum_find(gf100_fifo_fault_gpcclient, info->client); ec = nvkm_enum_find(fifo->func->mmu_fault->gpcclient, info->client);
snprintf(gpcid, sizeof(gpcid), "GPC%d/", info->gpc); snprintf(ct, sizeof(ct), "GPC%d/", info->gpc);
} }
ea = nvkm_enum_find(fifo->func->mmu_fault->access, info->access);
if (eu && eu->data2) { /* Handle BAR faults. */
switch (eu->data2) { if (ee && ee->data2) {
switch (ee->data2) {
case NVKM_SUBDEV_BAR: case NVKM_SUBDEV_BAR:
nvkm_bar_bar1_reset(device); nvkm_bar_bar1_reset(device);
break; break;
...@@ -386,30 +405,39 @@ gf100_fifo_fault(struct nvkm_fifo *base, struct nvkm_fault_data *info) ...@@ -386,30 +405,39 @@ gf100_fifo_fault(struct nvkm_fifo *base, struct nvkm_fault_data *info)
nvkm_mask(device, 0x001718, 0x00000000, 0x00000000); nvkm_mask(device, 0x001718, 0x00000000, 0x00000000);
break; break;
default: default:
engine = nvkm_device_engine(device, eu->data2, eu->inst);
break; break;
} }
} }
chan = nvkm_fifo_chan_inst(&fifo->base, info->inst, &flags); chan = nvkm_fifo_chan_inst(fifo, info->inst, &flags);
nvkm_error(subdev, nvkm_error(subdev,
"%s fault at %010llx engine %02x [%s] client %02x [%s%s] " "fault %02x [%s] at %016llx engine %02x [%s] client %02x "
"reason %02x [%s] on channel %d [%010llx %s]\n", "[%s%s] reason %02x [%s] on channel %d [%010llx %s]\n",
info->access ? "write" : "read", info->addr, info->access, ea ? ea->name : "", info->addr,
info->engine, eu ? eu->name : "", info->engine, ee ? ee->name : engine ? engine->subdev.name : "",
info->client, gpcid, ec ? ec->name : "", info->client, ct, ec ? ec->name : "",
info->reason, er ? er->name : "", chan ? chan->chid : -1, info->reason, er ? er->name : "",
info->inst, chan ? chan->object.client->name : "unknown"); chan ? chan->id : -1, info->inst, chan ? chan->name : "unknown");
/* Handle host/engine faults. */
if (fifo->func->recover_chan && chan)
fifo->func->recover_chan(fifo, chan->id);
else
if (engine && chan) if (engine && chan)
gf100_fifo_recover(fifo, engine, (void *)chan); gf100_fifo_recover(gf100_fifo(fifo), engine, (void *)chan);
nvkm_fifo_chan_put(&fifo->base, flags, &chan);
nvkm_fifo_chan_put(fifo, flags, &chan);
} }
static const struct nvkm_fifo_func_mmu_fault static const struct nvkm_fifo_func_mmu_fault
gf100_fifo_mmu_fault = { gf100_fifo_mmu_fault = {
.recover = gf100_fifo_fault, .recover = gf100_fifo_mmu_fault_recover,
.access = gf100_fifo_mmu_fault_access,
.engine = gf100_fifo_mmu_fault_engine,
.reason = gf100_fifo_mmu_fault_reason,
.hubclient = gf100_fifo_mmu_fault_hubclient,
.gpcclient = gf100_fifo_mmu_fault_gpcclient,
}; };
static const struct nvkm_enum static const struct nvkm_enum
...@@ -498,6 +526,19 @@ gf100_fifo_intr_mmu_fault_unit(struct nvkm_fifo *fifo, int unit) ...@@ -498,6 +526,19 @@ gf100_fifo_intr_mmu_fault_unit(struct nvkm_fifo *fifo, int unit)
nvkm_fifo_fault(fifo, &info); nvkm_fifo_fault(fifo, &info);
} }
void
gf100_fifo_intr_mmu_fault(struct nvkm_fifo *fifo)
{
struct nvkm_device *device = fifo->engine.subdev.device;
unsigned long mask = nvkm_rd32(device, 0x00259c);
int unit;
for_each_set_bit(unit, &mask, 32) {
fifo->func->intr_mmu_fault_unit(fifo, unit);
nvkm_wr32(device, 0x00259c, BIT(unit));
}
}
bool bool
gf100_fifo_intr_pbdma(struct nvkm_fifo *fifo) gf100_fifo_intr_pbdma(struct nvkm_fifo *fifo)
{ {
...@@ -609,13 +650,7 @@ gf100_fifo_intr(struct nvkm_inth *inth) ...@@ -609,13 +650,7 @@ gf100_fifo_intr(struct nvkm_inth *inth)
} }
if (stat & 0x10000000) { if (stat & 0x10000000) {
u32 mask = nvkm_rd32(device, 0x00259c); gf100_fifo_intr_mmu_fault(fifo);
while (mask) {
u32 unit = __ffs(mask);
gf100_fifo_intr_mmu_fault_unit(fifo, unit);
nvkm_wr32(device, 0x00259c, (1 << unit));
mask &= ~(1 << unit);
}
stat &= ~0x10000000; stat &= ~0x10000000;
} }
...@@ -783,6 +818,7 @@ gf100_fifo = { ...@@ -783,6 +818,7 @@ gf100_fifo = {
.init_pbdmas = gf100_fifo_init_pbdmas, .init_pbdmas = gf100_fifo_init_pbdmas,
.fini = gf100_fifo_fini, .fini = gf100_fifo_fini,
.intr = gf100_fifo_intr, .intr = gf100_fifo_intr,
.intr_mmu_fault_unit = gf100_fifo_intr_mmu_fault_unit,
.mmu_fault = &gf100_fifo_mmu_fault, .mmu_fault = &gf100_fifo_mmu_fault,
.engine_id = gf100_fifo_engine_id, .engine_id = gf100_fifo_engine_id,
.nonstall = &gf100_fifo_nonstall, .nonstall = &gf100_fifo_nonstall,
......
...@@ -30,10 +30,8 @@ ...@@ -30,10 +30,8 @@
#include "cgrp.h" #include "cgrp.h"
#include "changk104.h" #include "changk104.h"
#include <core/client.h>
#include <core/gpuobj.h> #include <core/gpuobj.h>
#include <subdev/bar.h> #include <subdev/bar.h>
#include <subdev/fault.h>
#include <subdev/mc.h> #include <subdev/mc.h>
#include <subdev/timer.h> #include <subdev/timer.h>
#include <subdev/top.h> #include <subdev/top.h>
...@@ -474,7 +472,7 @@ gk104_fifo_recover_engn(struct gk104_fifo *fifo, int engn) ...@@ -474,7 +472,7 @@ gk104_fifo_recover_engn(struct gk104_fifo *fifo, int engn)
if (!status.faulted && engine) { if (!status.faulted && engine) {
mmui = nvkm_top_fault_id(device, engine->subdev.type, engine->subdev.inst); mmui = nvkm_top_fault_id(device, engine->subdev.type, engine->subdev.inst);
if (mmui < 0) { if (mmui < 0) {
const struct nvkm_enum *en = fifo->func->fault.engine; const struct nvkm_enum *en = fifo->func->mmu_fault->engine;
for (; en && en->name; en++) { for (; en && en->name; en++) {
if (en->data2 == engine->subdev.type && if (en->data2 == engine->subdev.type &&
en->inst == engine->subdev.inst) { en->inst == engine->subdev.inst) {
...@@ -512,15 +510,8 @@ gk104_fifo_recover_engn(struct gk104_fifo *fifo, int engn) ...@@ -512,15 +510,8 @@ gk104_fifo_recover_engn(struct gk104_fifo *fifo, int engn)
schedule_work(&fifo->recover.work); schedule_work(&fifo->recover.work);
} }
const struct nvkm_enum static const struct nvkm_enum
gk104_fifo_fault_access[] = { gk104_fifo_mmu_fault_engine[] = {
{ 0x0, "READ" },
{ 0x1, "WRITE" },
{}
};
const struct nvkm_enum
gk104_fifo_fault_engine[] = {
{ 0x00, "GR", NULL, NVKM_ENGINE_GR }, { 0x00, "GR", NULL, NVKM_ENGINE_GR },
{ 0x01, "DISPLAY" }, { 0x01, "DISPLAY" },
{ 0x02, "CAPTURE" }, { 0x02, "CAPTURE" },
...@@ -528,14 +519,14 @@ gk104_fifo_fault_engine[] = { ...@@ -528,14 +519,14 @@ gk104_fifo_fault_engine[] = {
{ 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR }, { 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR },
{ 0x05, "BAR2", NULL, NVKM_SUBDEV_INSTMEM }, { 0x05, "BAR2", NULL, NVKM_SUBDEV_INSTMEM },
{ 0x06, "SCHED" }, { 0x06, "SCHED" },
{ 0x07, "HOST0", NULL, NVKM_ENGINE_FIFO }, { 0x07, "HOST0" },
{ 0x08, "HOST1", NULL, NVKM_ENGINE_FIFO }, { 0x08, "HOST1" },
{ 0x09, "HOST2", NULL, NVKM_ENGINE_FIFO }, { 0x09, "HOST2" },
{ 0x0a, "HOST3", NULL, NVKM_ENGINE_FIFO }, { 0x0a, "HOST3" },
{ 0x0b, "HOST4", NULL, NVKM_ENGINE_FIFO }, { 0x0b, "HOST4" },
{ 0x0c, "HOST5", NULL, NVKM_ENGINE_FIFO }, { 0x0c, "HOST5" },
{ 0x0d, "HOST6", NULL, NVKM_ENGINE_FIFO }, { 0x0d, "HOST6" },
{ 0x0e, "HOST7", NULL, NVKM_ENGINE_FIFO }, { 0x0e, "HOST7" },
{ 0x0f, "HOSTSR" }, { 0x0f, "HOSTSR" },
{ 0x10, "MSVLD", NULL, NVKM_ENGINE_MSVLD }, { 0x10, "MSVLD", NULL, NVKM_ENGINE_MSVLD },
{ 0x11, "MSPPP", NULL, NVKM_ENGINE_MSPPP }, { 0x11, "MSPPP", NULL, NVKM_ENGINE_MSPPP },
...@@ -551,7 +542,7 @@ gk104_fifo_fault_engine[] = { ...@@ -551,7 +542,7 @@ gk104_fifo_fault_engine[] = {
}; };
const struct nvkm_enum const struct nvkm_enum
gk104_fifo_fault_reason[] = { gk104_fifo_mmu_fault_reason[] = {
{ 0x00, "PDE" }, { 0x00, "PDE" },
{ 0x01, "PDE_SIZE" }, { 0x01, "PDE_SIZE" },
{ 0x02, "PTE" }, { 0x02, "PTE" },
...@@ -572,7 +563,7 @@ gk104_fifo_fault_reason[] = { ...@@ -572,7 +563,7 @@ gk104_fifo_fault_reason[] = {
}; };
const struct nvkm_enum const struct nvkm_enum
gk104_fifo_fault_hubclient[] = { gk104_fifo_mmu_fault_hubclient[] = {
{ 0x00, "VIP" }, { 0x00, "VIP" },
{ 0x01, "CE0" }, { 0x01, "CE0" },
{ 0x02, "CE1" }, { 0x02, "CE1" },
...@@ -609,7 +600,7 @@ gk104_fifo_fault_hubclient[] = { ...@@ -609,7 +600,7 @@ gk104_fifo_fault_hubclient[] = {
}; };
const struct nvkm_enum const struct nvkm_enum
gk104_fifo_fault_gpcclient[] = { gk104_fifo_mmu_fault_gpcclient[] = {
{ 0x00, "L1_0" }, { 0x01, "T1_0" }, { 0x02, "PE_0" }, { 0x00, "L1_0" }, { 0x01, "T1_0" }, { 0x02, "PE_0" },
{ 0x03, "L1_1" }, { 0x04, "T1_1" }, { 0x05, "PE_1" }, { 0x03, "L1_1" }, { 0x04, "T1_1" }, { 0x05, "PE_1" },
{ 0x06, "L1_2" }, { 0x07, "T1_2" }, { 0x08, "PE_2" }, { 0x06, "L1_2" }, { 0x07, "T1_2" }, { 0x08, "PE_2" },
...@@ -634,89 +625,14 @@ gk104_fifo_fault_gpcclient[] = { ...@@ -634,89 +625,14 @@ gk104_fifo_fault_gpcclient[] = {
{} {}
}; };
void
gk104_fifo_fault(struct nvkm_fifo *base, struct nvkm_fault_data *info)
{
struct gk104_fifo *fifo = gk104_fifo(base);
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
struct nvkm_device *device = subdev->device;
const struct nvkm_enum *er, *ee, *ec, *ea;
struct nvkm_engine *engine = NULL;
struct nvkm_fifo_chan *chan;
unsigned long flags;
const char *en = "";
char ct[8] = "HUB/";
er = nvkm_enum_find(fifo->func->fault.reason, info->reason);
ee = nvkm_enum_find(fifo->func->fault.engine, info->engine);
if (info->hub) {
ec = nvkm_enum_find(fifo->func->fault.hubclient, info->client);
} else {
ec = nvkm_enum_find(fifo->func->fault.gpcclient, info->client);
snprintf(ct, sizeof(ct), "GPC%d/", info->gpc);
}
ea = nvkm_enum_find(fifo->func->fault.access, info->access);
if (ee && ee->data2) {
switch (ee->data2) {
case NVKM_SUBDEV_BAR:
nvkm_bar_bar1_reset(device);
break;
case NVKM_SUBDEV_INSTMEM:
nvkm_bar_bar2_reset(device);
break;
case NVKM_ENGINE_IFB:
nvkm_mask(device, 0x001718, 0x00000000, 0x00000000);
break;
default:
engine = nvkm_device_engine(device, ee->data2, 0);
break;
}
}
if (ee == NULL) {
struct nvkm_subdev *subdev = nvkm_top_fault(device, info->engine);
if (subdev) {
if (subdev->func == &nvkm_engine)
engine = container_of(subdev, typeof(*engine), subdev);
en = engine->subdev.name;
}
} else {
en = ee->name;
}
spin_lock_irqsave(&fifo->base.lock, flags);
chan = nvkm_fifo_chan_inst_locked(&fifo->base, info->inst);
nvkm_error(subdev,
"fault %02x [%s] at %016llx engine %02x [%s] client %02x "
"[%s%s] reason %02x [%s] on channel %d [%010llx %s]\n",
info->access, ea ? ea->name : "", info->addr,
info->engine, ee ? ee->name : en,
info->client, ct, ec ? ec->name : "",
info->reason, er ? er->name : "", chan ? chan->chid : -1,
info->inst, chan ? chan->object.client->name : "unknown");
/* Kill the channel that caused the fault. */
if (chan)
gk104_fifo_recover_chan(&fifo->base, chan->chid);
/* Channel recovery will probably have already done this for the
* correct engine(s), but just in case we can't find the channel
* information...
*/
if (engine) {
int engn = fifo->base.func->engine_id(&fifo->base, engine);
if (engn >= 0 && engn != GK104_FIFO_ENGN_SW)
gk104_fifo_recover_engn(fifo, engn);
}
spin_unlock_irqrestore(&fifo->base.lock, flags);
}
const struct nvkm_fifo_func_mmu_fault const struct nvkm_fifo_func_mmu_fault
gk104_fifo_mmu_fault = { gk104_fifo_mmu_fault = {
.recover = gk104_fifo_fault, .recover = gf100_fifo_mmu_fault_recover,
.access = gf100_fifo_mmu_fault_access,
.engine = gk104_fifo_mmu_fault_engine,
.reason = gk104_fifo_mmu_fault_reason,
.hubclient = gk104_fifo_mmu_fault_hubclient,
.gpcclient = gk104_fifo_mmu_fault_gpcclient,
}; };
static const struct nvkm_enum static const struct nvkm_enum
...@@ -884,13 +800,7 @@ gk104_fifo_intr(struct nvkm_inth *inth) ...@@ -884,13 +800,7 @@ gk104_fifo_intr(struct nvkm_inth *inth)
} }
if (stat & 0x10000000) { if (stat & 0x10000000) {
u32 mask = nvkm_rd32(device, 0x00259c); gf100_fifo_intr_mmu_fault(fifo);
while (mask) {
u32 unit = __ffs(mask);
fifo->func->intr_mmu_fault_unit(fifo, unit);
nvkm_wr32(device, 0x00259c, (1 << unit));
mask &= ~(1 << unit);
}
stat &= ~0x10000000; stat &= ~0x10000000;
} }
...@@ -1105,11 +1015,6 @@ gk104_fifo = { ...@@ -1105,11 +1015,6 @@ gk104_fifo = {
.intr = gk104_fifo_intr, .intr = gk104_fifo_intr,
.intr_mmu_fault_unit = gf100_fifo_intr_mmu_fault_unit, .intr_mmu_fault_unit = gf100_fifo_intr_mmu_fault_unit,
.mmu_fault = &gk104_fifo_mmu_fault, .mmu_fault = &gk104_fifo_mmu_fault,
.fault.access = gk104_fifo_fault_access,
.fault.engine = gk104_fifo_fault_engine,
.fault.reason = gk104_fifo_fault_reason,
.fault.hubclient = gk104_fifo_fault_hubclient,
.fault.gpcclient = gk104_fifo_fault_gpcclient,
.engine_id = gk104_fifo_engine_id, .engine_id = gk104_fifo_engine_id,
.recover_chan = gk104_fifo_recover_chan, .recover_chan = gk104_fifo_recover_chan,
.runlist = &gk104_fifo_runlist, .runlist = &gk104_fifo_runlist,
......
...@@ -69,11 +69,6 @@ int gk104_fifo_oneinit(struct nvkm_fifo *); ...@@ -69,11 +69,6 @@ int gk104_fifo_oneinit(struct nvkm_fifo *);
void gk104_fifo_init(struct nvkm_fifo *base); void gk104_fifo_init(struct nvkm_fifo *base);
void gk104_fifo_fini(struct nvkm_fifo *base); void gk104_fifo_fini(struct nvkm_fifo *base);
extern const struct nvkm_enum gk104_fifo_fault_access[];
extern const struct nvkm_enum gk104_fifo_fault_engine[];
extern const struct nvkm_enum gk104_fifo_fault_reason[];
extern const struct nvkm_enum gk104_fifo_fault_hubclient[];
extern const struct nvkm_enum gk104_fifo_fault_gpcclient[];
extern const struct gk104_fifo_runlist_func gk104_fifo_runlist; extern const struct gk104_fifo_runlist_func gk104_fifo_runlist;
void gk104_fifo_runlist_chan(struct gk104_fifo_chan *, void gk104_fifo_runlist_chan(struct gk104_fifo_chan *,
struct nvkm_memory *, u32); struct nvkm_memory *, u32);
...@@ -84,17 +79,8 @@ extern const struct gk104_fifo_runlist_func gk110_fifo_runlist; ...@@ -84,17 +79,8 @@ extern const struct gk104_fifo_runlist_func gk110_fifo_runlist;
void gk110_fifo_runlist_cgrp(struct nvkm_fifo_cgrp *, void gk110_fifo_runlist_cgrp(struct nvkm_fifo_cgrp *,
struct nvkm_memory *, u32); struct nvkm_memory *, u32);
void gk208_fifo_pbdma_init_timeout(struct gk104_fifo *);
extern const struct nvkm_enum gm107_fifo_fault_engine[];
extern const struct gk104_fifo_runlist_func gm107_fifo_runlist; extern const struct gk104_fifo_runlist_func gm107_fifo_runlist;
extern const struct nvkm_enum gp100_fifo_fault_engine[];
extern const struct nvkm_enum gv100_fifo_fault_access[];
extern const struct nvkm_enum gv100_fifo_fault_reason[];
extern const struct nvkm_enum gv100_fifo_fault_hubclient[];
extern const struct nvkm_enum gv100_fifo_fault_gpcclient[];
void gv100_fifo_runlist_cgrp(struct nvkm_fifo_cgrp *, void gv100_fifo_runlist_cgrp(struct nvkm_fifo_cgrp *,
struct nvkm_memory *, u32); struct nvkm_memory *, u32);
void gv100_fifo_runlist_chan(struct gk104_fifo_chan *, void gv100_fifo_runlist_chan(struct gk104_fifo_chan *,
......
...@@ -88,11 +88,6 @@ gk110_fifo = { ...@@ -88,11 +88,6 @@ gk110_fifo = {
.intr = gk104_fifo_intr, .intr = gk104_fifo_intr,
.intr_mmu_fault_unit = gf100_fifo_intr_mmu_fault_unit, .intr_mmu_fault_unit = gf100_fifo_intr_mmu_fault_unit,
.mmu_fault = &gk104_fifo_mmu_fault, .mmu_fault = &gk104_fifo_mmu_fault,
.fault.access = gk104_fifo_fault_access,
.fault.engine = gk104_fifo_fault_engine,
.fault.reason = gk104_fifo_fault_reason,
.fault.hubclient = gk104_fifo_fault_hubclient,
.fault.gpcclient = gk104_fifo_fault_gpcclient,
.engine_id = gk104_fifo_engine_id, .engine_id = gk104_fifo_engine_id,
.recover_chan = gk104_fifo_recover_chan, .recover_chan = gk104_fifo_recover_chan,
.runlist = &gk110_fifo_runlist, .runlist = &gk110_fifo_runlist,
......
...@@ -62,11 +62,6 @@ gk208_fifo = { ...@@ -62,11 +62,6 @@ gk208_fifo = {
.intr = gk104_fifo_intr, .intr = gk104_fifo_intr,
.intr_mmu_fault_unit = gf100_fifo_intr_mmu_fault_unit, .intr_mmu_fault_unit = gf100_fifo_intr_mmu_fault_unit,
.mmu_fault = &gk104_fifo_mmu_fault, .mmu_fault = &gk104_fifo_mmu_fault,
.fault.access = gk104_fifo_fault_access,
.fault.engine = gk104_fifo_fault_engine,
.fault.reason = gk104_fifo_fault_reason,
.fault.hubclient = gk104_fifo_fault_hubclient,
.fault.gpcclient = gk104_fifo_fault_gpcclient,
.engine_id = gk104_fifo_engine_id, .engine_id = gk104_fifo_engine_id,
.recover_chan = gk104_fifo_recover_chan, .recover_chan = gk104_fifo_recover_chan,
.runlist = &gk110_fifo_runlist, .runlist = &gk110_fifo_runlist,
......
...@@ -38,11 +38,6 @@ gk20a_fifo = { ...@@ -38,11 +38,6 @@ gk20a_fifo = {
.intr = gk104_fifo_intr, .intr = gk104_fifo_intr,
.intr_mmu_fault_unit = gf100_fifo_intr_mmu_fault_unit, .intr_mmu_fault_unit = gf100_fifo_intr_mmu_fault_unit,
.mmu_fault = &gk104_fifo_mmu_fault, .mmu_fault = &gk104_fifo_mmu_fault,
.fault.access = gk104_fifo_fault_access,
.fault.engine = gk104_fifo_fault_engine,
.fault.reason = gk104_fifo_fault_reason,
.fault.hubclient = gk104_fifo_fault_hubclient,
.fault.gpcclient = gk104_fifo_fault_gpcclient,
.engine_id = gk104_fifo_engine_id, .engine_id = gk104_fifo_engine_id,
.recover_chan = gk104_fifo_recover_chan, .recover_chan = gk104_fifo_recover_chan,
.runlist = &gk110_fifo_runlist, .runlist = &gk110_fifo_runlist,
......
...@@ -56,22 +56,22 @@ const struct nvkm_runl_func ...@@ -56,22 +56,22 @@ const struct nvkm_runl_func
gm107_runl = { gm107_runl = {
}; };
const struct nvkm_enum static const struct nvkm_enum
gm107_fifo_fault_engine[] = { gm107_fifo_mmu_fault_engine[] = {
{ 0x01, "DISPLAY" }, { 0x01, "DISPLAY" },
{ 0x02, "CAPTURE" }, { 0x02, "CAPTURE" },
{ 0x03, "IFB", NULL, NVKM_ENGINE_IFB }, { 0x03, "IFB", NULL, NVKM_ENGINE_IFB },
{ 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR }, { 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR },
{ 0x05, "BAR2", NULL, NVKM_SUBDEV_INSTMEM }, { 0x05, "BAR2", NULL, NVKM_SUBDEV_INSTMEM },
{ 0x06, "SCHED" }, { 0x06, "SCHED" },
{ 0x07, "HOST0", NULL, NVKM_ENGINE_FIFO }, { 0x07, "HOST0" },
{ 0x08, "HOST1", NULL, NVKM_ENGINE_FIFO }, { 0x08, "HOST1" },
{ 0x09, "HOST2", NULL, NVKM_ENGINE_FIFO }, { 0x09, "HOST2" },
{ 0x0a, "HOST3", NULL, NVKM_ENGINE_FIFO }, { 0x0a, "HOST3" },
{ 0x0b, "HOST4", NULL, NVKM_ENGINE_FIFO }, { 0x0b, "HOST4" },
{ 0x0c, "HOST5", NULL, NVKM_ENGINE_FIFO }, { 0x0c, "HOST5" },
{ 0x0d, "HOST6", NULL, NVKM_ENGINE_FIFO }, { 0x0d, "HOST6" },
{ 0x0e, "HOST7", NULL, NVKM_ENGINE_FIFO }, { 0x0e, "HOST7" },
{ 0x0f, "HOSTSR" }, { 0x0f, "HOSTSR" },
{ 0x13, "PERF" }, { 0x13, "PERF" },
{ 0x17, "PMU" }, { 0x17, "PMU" },
...@@ -81,7 +81,12 @@ gm107_fifo_fault_engine[] = { ...@@ -81,7 +81,12 @@ gm107_fifo_fault_engine[] = {
const struct nvkm_fifo_func_mmu_fault const struct nvkm_fifo_func_mmu_fault
gm107_fifo_mmu_fault = { gm107_fifo_mmu_fault = {
.recover = gk104_fifo_fault, .recover = gf100_fifo_mmu_fault_recover,
.access = gf100_fifo_mmu_fault_access,
.engine = gm107_fifo_mmu_fault_engine,
.reason = gk104_fifo_mmu_fault_reason,
.hubclient = gk104_fifo_mmu_fault_hubclient,
.gpcclient = gk104_fifo_mmu_fault_gpcclient,
}; };
void void
...@@ -128,11 +133,6 @@ gm107_fifo = { ...@@ -128,11 +133,6 @@ gm107_fifo = {
.intr = gk104_fifo_intr, .intr = gk104_fifo_intr,
.intr_mmu_fault_unit = gm107_fifo_intr_mmu_fault_unit, .intr_mmu_fault_unit = gm107_fifo_intr_mmu_fault_unit,
.mmu_fault = &gm107_fifo_mmu_fault, .mmu_fault = &gm107_fifo_mmu_fault,
.fault.access = gk104_fifo_fault_access,
.fault.engine = gm107_fifo_fault_engine,
.fault.reason = gk104_fifo_fault_reason,
.fault.hubclient = gk104_fifo_fault_hubclient,
.fault.gpcclient = gk104_fifo_fault_gpcclient,
.engine_id = gk104_fifo_engine_id, .engine_id = gk104_fifo_engine_id,
.recover_chan = gk104_fifo_recover_chan, .recover_chan = gk104_fifo_recover_chan,
.runlist = &gm107_fifo_runlist, .runlist = &gm107_fifo_runlist,
......
...@@ -52,11 +52,6 @@ gm200_fifo = { ...@@ -52,11 +52,6 @@ gm200_fifo = {
.intr = gk104_fifo_intr, .intr = gk104_fifo_intr,
.intr_mmu_fault_unit = gm107_fifo_intr_mmu_fault_unit, .intr_mmu_fault_unit = gm107_fifo_intr_mmu_fault_unit,
.mmu_fault = &gm107_fifo_mmu_fault, .mmu_fault = &gm107_fifo_mmu_fault,
.fault.access = gk104_fifo_fault_access,
.fault.engine = gm107_fifo_fault_engine,
.fault.reason = gk104_fifo_fault_reason,
.fault.hubclient = gk104_fifo_fault_hubclient,
.fault.gpcclient = gk104_fifo_fault_gpcclient,
.engine_id = gk104_fifo_engine_id, .engine_id = gk104_fifo_engine_id,
.recover_chan = gk104_fifo_recover_chan, .recover_chan = gk104_fifo_recover_chan,
.runlist = &gm107_fifo_runlist, .runlist = &gm107_fifo_runlist,
......
...@@ -33,23 +33,23 @@ static const struct nvkm_runl_func ...@@ -33,23 +33,23 @@ static const struct nvkm_runl_func
gp100_runl = { gp100_runl = {
}; };
const struct nvkm_enum static const struct nvkm_enum
gp100_fifo_fault_engine[] = { gp100_fifo_mmu_fault_engine[] = {
{ 0x01, "DISPLAY" }, { 0x01, "DISPLAY" },
{ 0x03, "IFB", NULL, NVKM_ENGINE_IFB }, { 0x03, "IFB", NULL, NVKM_ENGINE_IFB },
{ 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR }, { 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR },
{ 0x05, "BAR2", NULL, NVKM_SUBDEV_INSTMEM }, { 0x05, "BAR2", NULL, NVKM_SUBDEV_INSTMEM },
{ 0x06, "HOST0", NULL, NVKM_ENGINE_FIFO }, { 0x06, "HOST0" },
{ 0x07, "HOST1", NULL, NVKM_ENGINE_FIFO }, { 0x07, "HOST1" },
{ 0x08, "HOST2", NULL, NVKM_ENGINE_FIFO }, { 0x08, "HOST2" },
{ 0x09, "HOST3", NULL, NVKM_ENGINE_FIFO }, { 0x09, "HOST3" },
{ 0x0a, "HOST4", NULL, NVKM_ENGINE_FIFO }, { 0x0a, "HOST4" },
{ 0x0b, "HOST5", NULL, NVKM_ENGINE_FIFO }, { 0x0b, "HOST5" },
{ 0x0c, "HOST6", NULL, NVKM_ENGINE_FIFO }, { 0x0c, "HOST6" },
{ 0x0d, "HOST7", NULL, NVKM_ENGINE_FIFO }, { 0x0d, "HOST7" },
{ 0x0e, "HOST8", NULL, NVKM_ENGINE_FIFO }, { 0x0e, "HOST8" },
{ 0x0f, "HOST9", NULL, NVKM_ENGINE_FIFO }, { 0x0f, "HOST9" },
{ 0x10, "HOST10", NULL, NVKM_ENGINE_FIFO }, { 0x10, "HOST10" },
{ 0x13, "PERF" }, { 0x13, "PERF" },
{ 0x17, "PMU" }, { 0x17, "PMU" },
{ 0x18, "PTP" }, { 0x18, "PTP" },
...@@ -59,10 +59,15 @@ gp100_fifo_fault_engine[] = { ...@@ -59,10 +59,15 @@ gp100_fifo_fault_engine[] = {
static const struct nvkm_fifo_func_mmu_fault static const struct nvkm_fifo_func_mmu_fault
gp100_fifo_mmu_fault = { gp100_fifo_mmu_fault = {
.recover = gk104_fifo_fault, .recover = gf100_fifo_mmu_fault_recover,
.access = gf100_fifo_mmu_fault_access,
.engine = gp100_fifo_mmu_fault_engine,
.reason = gk104_fifo_mmu_fault_reason,
.hubclient = gk104_fifo_mmu_fault_hubclient,
.gpcclient = gk104_fifo_mmu_fault_gpcclient,
}; };
void static void
gp100_fifo_intr_mmu_fault_unit(struct nvkm_fifo *fifo, int unit) gp100_fifo_intr_mmu_fault_unit(struct nvkm_fifo *fifo, int unit)
{ {
struct nvkm_device *device = fifo->engine.subdev.device; struct nvkm_device *device = fifo->engine.subdev.device;
...@@ -100,11 +105,6 @@ gp100_fifo = { ...@@ -100,11 +105,6 @@ gp100_fifo = {
.intr = gk104_fifo_intr, .intr = gk104_fifo_intr,
.intr_mmu_fault_unit = gp100_fifo_intr_mmu_fault_unit, .intr_mmu_fault_unit = gp100_fifo_intr_mmu_fault_unit,
.mmu_fault = &gp100_fifo_mmu_fault, .mmu_fault = &gp100_fifo_mmu_fault,
.fault.access = gk104_fifo_fault_access,
.fault.engine = gp100_fifo_fault_engine,
.fault.reason = gk104_fifo_fault_reason,
.fault.hubclient = gk104_fifo_fault_hubclient,
.fault.gpcclient = gk104_fifo_fault_gpcclient,
.engine_id = gk104_fifo_engine_id, .engine_id = gk104_fifo_engine_id,
.recover_chan = gk104_fifo_recover_chan, .recover_chan = gk104_fifo_recover_chan,
.runlist = &gm107_fifo_runlist, .runlist = &gm107_fifo_runlist,
......
...@@ -87,7 +87,7 @@ gv100_runl = { ...@@ -87,7 +87,7 @@ gv100_runl = {
}; };
const struct nvkm_enum const struct nvkm_enum
gv100_fifo_fault_gpcclient[] = { gv100_fifo_mmu_fault_gpcclient[] = {
{ 0x00, "T1_0" }, { 0x00, "T1_0" },
{ 0x01, "T1_1" }, { 0x01, "T1_1" },
{ 0x02, "T1_2" }, { 0x02, "T1_2" },
...@@ -189,7 +189,7 @@ gv100_fifo_fault_gpcclient[] = { ...@@ -189,7 +189,7 @@ gv100_fifo_fault_gpcclient[] = {
}; };
const struct nvkm_enum const struct nvkm_enum
gv100_fifo_fault_hubclient[] = { gv100_fifo_mmu_fault_hubclient[] = {
{ 0x00, "VIP" }, { 0x00, "VIP" },
{ 0x01, "CE0" }, { 0x01, "CE0" },
{ 0x02, "CE1" }, { 0x02, "CE1" },
...@@ -251,7 +251,7 @@ gv100_fifo_fault_hubclient[] = { ...@@ -251,7 +251,7 @@ gv100_fifo_fault_hubclient[] = {
}; };
const struct nvkm_enum const struct nvkm_enum
gv100_fifo_fault_reason[] = { gv100_fifo_mmu_fault_reason[] = {
{ 0x00, "PDE" }, { 0x00, "PDE" },
{ 0x01, "PDE_SIZE" }, { 0x01, "PDE_SIZE" },
{ 0x02, "PTE" }, { 0x02, "PTE" },
...@@ -272,7 +272,7 @@ gv100_fifo_fault_reason[] = { ...@@ -272,7 +272,7 @@ gv100_fifo_fault_reason[] = {
}; };
static const struct nvkm_enum static const struct nvkm_enum
gv100_fifo_fault_engine[] = { gv100_fifo_mmu_fault_engine[] = {
{ 0x01, "DISPLAY" }, { 0x01, "DISPLAY" },
{ 0x03, "PTP" }, { 0x03, "PTP" },
{ 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR }, { 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR },
...@@ -299,7 +299,7 @@ gv100_fifo_fault_engine[] = { ...@@ -299,7 +299,7 @@ gv100_fifo_fault_engine[] = {
}; };
const struct nvkm_enum const struct nvkm_enum
gv100_fifo_fault_access[] = { gv100_fifo_mmu_fault_access[] = {
{ 0x0, "VIRT_READ" }, { 0x0, "VIRT_READ" },
{ 0x1, "VIRT_WRITE" }, { 0x1, "VIRT_WRITE" },
{ 0x2, "VIRT_ATOMIC" }, { 0x2, "VIRT_ATOMIC" },
...@@ -314,7 +314,12 @@ gv100_fifo_fault_access[] = { ...@@ -314,7 +314,12 @@ gv100_fifo_fault_access[] = {
static const struct nvkm_fifo_func_mmu_fault static const struct nvkm_fifo_func_mmu_fault
gv100_fifo_mmu_fault = { gv100_fifo_mmu_fault = {
.recover = gk104_fifo_fault, .recover = gf100_fifo_mmu_fault_recover,
.access = gv100_fifo_mmu_fault_access,
.engine = gv100_fifo_mmu_fault_engine,
.reason = gv100_fifo_mmu_fault_reason,
.hubclient = gv100_fifo_mmu_fault_hubclient,
.gpcclient = gv100_fifo_mmu_fault_gpcclient,
}; };
static const struct nvkm_fifo_func static const struct nvkm_fifo_func
...@@ -330,11 +335,6 @@ gv100_fifo = { ...@@ -330,11 +335,6 @@ gv100_fifo = {
.fini = gk104_fifo_fini, .fini = gk104_fifo_fini,
.intr = gk104_fifo_intr, .intr = gk104_fifo_intr,
.mmu_fault = &gv100_fifo_mmu_fault, .mmu_fault = &gv100_fifo_mmu_fault,
.fault.access = gv100_fifo_fault_access,
.fault.engine = gv100_fifo_fault_engine,
.fault.reason = gv100_fifo_fault_reason,
.fault.hubclient = gv100_fifo_fault_hubclient,
.fault.gpcclient = gv100_fifo_fault_gpcclient,
.engine_id = gk104_fifo_engine_id, .engine_id = gk104_fifo_engine_id,
.recover_chan = gk104_fifo_recover_chan, .recover_chan = gk104_fifo_recover_chan,
.runlist = &gv100_fifo_runlist, .runlist = &gv100_fifo_runlist,
......
...@@ -37,15 +37,12 @@ struct nvkm_fifo_func { ...@@ -37,15 +37,12 @@ struct nvkm_fifo_func {
const struct nvkm_fifo_func_mmu_fault { const struct nvkm_fifo_func_mmu_fault {
void (*recover)(struct nvkm_fifo *, struct nvkm_fault_data *); void (*recover)(struct nvkm_fifo *, struct nvkm_fault_data *);
} *mmu_fault;
struct {
const struct nvkm_enum *access; const struct nvkm_enum *access;
const struct nvkm_enum *engine; const struct nvkm_enum *engine;
const struct nvkm_enum *reason; const struct nvkm_enum *reason;
const struct nvkm_enum *hubclient; const struct nvkm_enum *hubclient;
const struct nvkm_enum *gpcclient; const struct nvkm_enum *gpcclient;
} fault; } *mmu_fault;
int (*engine_id)(struct nvkm_fifo *, struct nvkm_engine *); int (*engine_id)(struct nvkm_fifo *, struct nvkm_engine *);
void (*pause)(struct nvkm_fifo *, unsigned long *); void (*pause)(struct nvkm_fifo *, unsigned long *);
...@@ -116,7 +113,10 @@ extern const struct nvkm_chan_func g84_chan; ...@@ -116,7 +113,10 @@ extern const struct nvkm_chan_func g84_chan;
int gf100_fifo_chid_ctor(struct nvkm_fifo *, int); int gf100_fifo_chid_ctor(struct nvkm_fifo *, int);
int gf100_fifo_runq_nr(struct nvkm_fifo *); int gf100_fifo_runq_nr(struct nvkm_fifo *);
bool gf100_fifo_intr_pbdma(struct nvkm_fifo *); bool gf100_fifo_intr_pbdma(struct nvkm_fifo *);
void gf100_fifo_intr_mmu_fault(struct nvkm_fifo *);
void gf100_fifo_intr_mmu_fault_unit(struct nvkm_fifo *, int); void gf100_fifo_intr_mmu_fault_unit(struct nvkm_fifo *, int);
void gf100_fifo_mmu_fault_recover(struct nvkm_fifo *, struct nvkm_fault_data *);
extern const struct nvkm_enum gf100_fifo_mmu_fault_access[];
extern const struct nvkm_event_func gf100_fifo_nonstall; extern const struct nvkm_event_func gf100_fifo_nonstall;
void gf100_runq_init(struct nvkm_runq *); void gf100_runq_init(struct nvkm_runq *);
bool gf100_runq_intr(struct nvkm_runq *, struct nvkm_runl *); bool gf100_runq_intr(struct nvkm_runq *, struct nvkm_runl *);
...@@ -129,7 +129,9 @@ irqreturn_t gk104_fifo_intr(struct nvkm_inth *); ...@@ -129,7 +129,9 @@ irqreturn_t gk104_fifo_intr(struct nvkm_inth *);
void gk104_fifo_intr_chsw(struct nvkm_fifo *); void gk104_fifo_intr_chsw(struct nvkm_fifo *);
void gk104_fifo_intr_bind(struct nvkm_fifo *); void gk104_fifo_intr_bind(struct nvkm_fifo *);
extern const struct nvkm_fifo_func_mmu_fault gk104_fifo_mmu_fault; extern const struct nvkm_fifo_func_mmu_fault gk104_fifo_mmu_fault;
void gk104_fifo_fault(struct nvkm_fifo *, struct nvkm_fault_data *); extern const struct nvkm_enum gk104_fifo_mmu_fault_reason[];
extern const struct nvkm_enum gk104_fifo_mmu_fault_hubclient[];
extern const struct nvkm_enum gk104_fifo_mmu_fault_gpcclient[];
void gk104_fifo_recover_chan(struct nvkm_fifo *, int); void gk104_fifo_recover_chan(struct nvkm_fifo *, int);
int gk104_fifo_engine_id(struct nvkm_fifo *, struct nvkm_engine *); int gk104_fifo_engine_id(struct nvkm_fifo *, struct nvkm_engine *);
extern const struct nvkm_runq_func gk104_runq; extern const struct nvkm_runq_func gk104_runq;
...@@ -155,8 +157,10 @@ extern const struct nvkm_chan_func gm107_chan; ...@@ -155,8 +157,10 @@ extern const struct nvkm_chan_func gm107_chan;
int gm200_fifo_chid_nr(struct nvkm_fifo *); int gm200_fifo_chid_nr(struct nvkm_fifo *);
int gm200_fifo_runq_nr(struct nvkm_fifo *); int gm200_fifo_runq_nr(struct nvkm_fifo *);
void gp100_fifo_intr_mmu_fault_unit(struct nvkm_fifo *, int); extern const struct nvkm_enum gv100_fifo_mmu_fault_access[];
extern const struct nvkm_enum gv100_fifo_mmu_fault_reason[];
extern const struct nvkm_enum gv100_fifo_mmu_fault_hubclient[];
extern const struct nvkm_enum gv100_fifo_mmu_fault_gpcclient[];
extern const struct nvkm_runq_func gv100_runq; extern const struct nvkm_runq_func gv100_runq;
extern const struct nvkm_engn_func gv100_engn; extern const struct nvkm_engn_func gv100_engn;
extern const struct nvkm_engn_func gv100_engn_ce; extern const struct nvkm_engn_func gv100_engn_ce;
......
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
#include "chid.h" #include "chid.h"
#include "priv.h" #include "priv.h"
#include <subdev/top.h>
void void
nvkm_runl_del(struct nvkm_runl *runl) nvkm_runl_del(struct nvkm_runl *runl)
{ {
...@@ -46,7 +48,8 @@ struct nvkm_engn * ...@@ -46,7 +48,8 @@ struct nvkm_engn *
nvkm_runl_add(struct nvkm_runl *runl, int engi, const struct nvkm_engn_func *func, nvkm_runl_add(struct nvkm_runl *runl, int engi, const struct nvkm_engn_func *func,
enum nvkm_subdev_type type, int inst) enum nvkm_subdev_type type, int inst)
{ {
struct nvkm_device *device = runl->fifo->engine.subdev.device; struct nvkm_fifo *fifo = runl->fifo;
struct nvkm_device *device = fifo->engine.subdev.device;
struct nvkm_engine *engine; struct nvkm_engine *engine;
struct nvkm_engn *engn; struct nvkm_engn *engn;
...@@ -63,7 +66,25 @@ nvkm_runl_add(struct nvkm_runl *runl, int engi, const struct nvkm_engn_func *fun ...@@ -63,7 +66,25 @@ nvkm_runl_add(struct nvkm_runl *runl, int engi, const struct nvkm_engn_func *fun
engn->runl = runl; engn->runl = runl;
engn->id = engi; engn->id = engi;
engn->engine = engine; engn->engine = engine;
engn->fault = -1;
list_add_tail(&engn->head, &runl->engns); list_add_tail(&engn->head, &runl->engns);
/* Lookup MMU engine ID for fault handling. */
if (device->top)
engn->fault = nvkm_top_fault_id(device, engine->subdev.type, engine->subdev.inst);
if (engn->fault < 0 && fifo->func->mmu_fault) {
const struct nvkm_enum *map = fifo->func->mmu_fault->engine;
while (map->name) {
if (map->data2 == engine->subdev.type && map->inst == engine->subdev.inst) {
engn->fault = map->value;
break;
}
map++;
}
}
return engn; return engn;
} }
......
...@@ -13,6 +13,8 @@ struct nvkm_engn { ...@@ -13,6 +13,8 @@ struct nvkm_engn {
struct nvkm_engine *engine; struct nvkm_engine *engine;
int fault;
struct list_head head; struct list_head head;
}; };
......
...@@ -26,12 +26,8 @@ ...@@ -26,12 +26,8 @@
#include "cgrp.h" #include "cgrp.h"
#include "changk104.h" #include "changk104.h"
#include <core/client.h>
#include <core/memory.h> #include <core/memory.h>
#include <subdev/bar.h>
#include <subdev/fault.h>
#include <subdev/mc.h> #include <subdev/mc.h>
#include <subdev/top.h>
#include <nvif/class.h> #include <nvif/class.h>
...@@ -67,7 +63,7 @@ tu102_runl = { ...@@ -67,7 +63,7 @@ tu102_runl = {
}; };
static const struct nvkm_enum static const struct nvkm_enum
tu102_fifo_fault_engine[] = { tu102_fifo_mmu_fault_engine[] = {
{ 0x01, "DISPLAY" }, { 0x01, "DISPLAY" },
{ 0x03, "PTP" }, { 0x03, "PTP" },
{ 0x06, "PWR_PMU" }, { 0x06, "PWR_PMU" },
...@@ -247,91 +243,14 @@ tu102_fifo_recover_engn(struct gk104_fifo *fifo, int engn) ...@@ -247,91 +243,14 @@ tu102_fifo_recover_engn(struct gk104_fifo *fifo, int engn)
schedule_work(&fifo->recover.work); schedule_work(&fifo->recover.work);
} }
static void
tu102_fifo_fault(struct nvkm_fifo *base, struct nvkm_fault_data *info)
{
struct gk104_fifo *fifo = gk104_fifo(base);
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
struct nvkm_device *device = subdev->device;
const struct nvkm_enum *er, *ee, *ec, *ea;
struct nvkm_engine *engine = NULL;
struct nvkm_fifo_chan *chan;
unsigned long flags;
const char *en = "";
char ct[8] = "HUB/";
int engn;
er = nvkm_enum_find(fifo->func->fault.reason, info->reason);
ee = nvkm_enum_find(fifo->func->fault.engine, info->engine);
if (info->hub) {
ec = nvkm_enum_find(fifo->func->fault.hubclient, info->client);
} else {
ec = nvkm_enum_find(fifo->func->fault.gpcclient, info->client);
snprintf(ct, sizeof(ct), "GPC%d/", info->gpc);
}
ea = nvkm_enum_find(fifo->func->fault.access, info->access);
if (ee && ee->data2) {
switch (ee->data2) {
case NVKM_SUBDEV_BAR:
nvkm_bar_bar1_reset(device);
break;
case NVKM_SUBDEV_INSTMEM:
nvkm_bar_bar2_reset(device);
break;
case NVKM_ENGINE_IFB:
nvkm_mask(device, 0x001718, 0x00000000, 0x00000000);
break;
default:
engine = nvkm_device_engine(device, ee->data2, 0);
break;
}
}
if (ee == NULL) {
struct nvkm_subdev *subdev = nvkm_top_fault(device, info->engine);
if (subdev) {
if (subdev->func == &nvkm_engine)
engine = container_of(subdev, typeof(*engine), subdev);
en = engine->subdev.name;
}
} else {
en = ee->name;
}
spin_lock_irqsave(&fifo->base.lock, flags);
chan = nvkm_fifo_chan_inst_locked(&fifo->base, info->inst);
nvkm_error(subdev,
"fault %02x [%s] at %016llx engine %02x [%s] client %02x "
"[%s%s] reason %02x [%s] on channel %d [%010llx %s]\n",
info->access, ea ? ea->name : "", info->addr,
info->engine, ee ? ee->name : en,
info->client, ct, ec ? ec->name : "",
info->reason, er ? er->name : "", chan ? chan->chid : -1,
info->inst, chan ? chan->object.client->name : "unknown");
/* Kill the channel that caused the fault. */
if (chan)
tu102_fifo_recover_chan(&fifo->base, chan->chid);
/* Channel recovery will probably have already done this for the
* correct engine(s), but just in case we can't find the channel
* information...
*/
for (engn = 0; engn < fifo->engine_nr && engine; engn++) {
if (fifo->engine[engn].engine == engine) {
tu102_fifo_recover_engn(fifo, engn);
break;
}
}
spin_unlock_irqrestore(&fifo->base.lock, flags);
}
const struct nvkm_fifo_func_mmu_fault const struct nvkm_fifo_func_mmu_fault
tu102_fifo_mmu_fault = { tu102_fifo_mmu_fault = {
.recover = tu102_fifo_fault, .recover = gf100_fifo_mmu_fault_recover,
.access = gv100_fifo_mmu_fault_access,
.engine = tu102_fifo_mmu_fault_engine,
.reason = gv100_fifo_mmu_fault_reason,
.hubclient = gv100_fifo_mmu_fault_hubclient,
.gpcclient = gv100_fifo_mmu_fault_gpcclient,
}; };
static void static void
...@@ -441,11 +360,6 @@ tu102_fifo = { ...@@ -441,11 +360,6 @@ tu102_fifo = {
.fini = gk104_fifo_fini, .fini = gk104_fifo_fini,
.intr = tu102_fifo_intr, .intr = tu102_fifo_intr,
.mmu_fault = &tu102_fifo_mmu_fault, .mmu_fault = &tu102_fifo_mmu_fault,
.fault.access = gv100_fifo_fault_access,
.fault.engine = tu102_fifo_fault_engine,
.fault.reason = gv100_fifo_fault_reason,
.fault.hubclient = gv100_fifo_fault_hubclient,
.fault.gpcclient = gv100_fifo_fault_gpcclient,
.engine_id = gk104_fifo_engine_id, .engine_id = gk104_fifo_engine_id,
.recover_chan = tu102_fifo_recover_chan, .recover_chan = tu102_fifo_recover_chan,
.runlist = &tu102_fifo_runlist, .runlist = &tu102_fifo_runlist,
......
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