mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-16 10:54:09 +08:00
drm/nouveau/fifo/gf1xx: convert to using nvkm_fault_data
Would like to be able to reuse gf100_fifo_intr_fault() for (some of) the later chipsets too, as it's identical. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
9f9b450752
commit
cf9518b50a
@ -28,6 +28,7 @@
|
||||
#include <core/enum.h>
|
||||
#include <core/gpuobj.h>
|
||||
#include <subdev/bar.h>
|
||||
#include <subdev/fault.h>
|
||||
#include <engine/sw.h>
|
||||
|
||||
#include <nvif/class.h>
|
||||
@ -193,6 +194,119 @@ gf100_fifo_recover(struct gf100_fifo *fifo, struct nvkm_engine *engine,
|
||||
nvkm_fifo_kevent(&fifo->base, chid);
|
||||
}
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_fault_engine[] = {
|
||||
{ 0x00, "PGRAPH", NULL, NVKM_ENGINE_GR },
|
||||
{ 0x03, "PEEPHOLE", NULL, NVKM_ENGINE_IFB },
|
||||
{ 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR },
|
||||
{ 0x05, "BAR3", NULL, NVKM_SUBDEV_INSTMEM },
|
||||
{ 0x07, "PFIFO", NULL, NVKM_ENGINE_FIFO },
|
||||
{ 0x10, "PMSVLD", NULL, NVKM_ENGINE_MSVLD },
|
||||
{ 0x11, "PMSPPP", NULL, NVKM_ENGINE_MSPPP },
|
||||
{ 0x13, "PCOUNTER" },
|
||||
{ 0x14, "PMSPDEC", NULL, NVKM_ENGINE_MSPDEC },
|
||||
{ 0x15, "PCE0", NULL, NVKM_ENGINE_CE0 },
|
||||
{ 0x16, "PCE1", NULL, NVKM_ENGINE_CE1 },
|
||||
{ 0x17, "PMU" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_fault_reason[] = {
|
||||
{ 0x00, "PT_NOT_PRESENT" },
|
||||
{ 0x01, "PT_TOO_SHORT" },
|
||||
{ 0x02, "PAGE_NOT_PRESENT" },
|
||||
{ 0x03, "VM_LIMIT_EXCEEDED" },
|
||||
{ 0x04, "NO_CHANNEL" },
|
||||
{ 0x05, "PAGE_SYSTEM_ONLY" },
|
||||
{ 0x06, "PAGE_READ_ONLY" },
|
||||
{ 0x0a, "COMPRESSED_SYSRAM" },
|
||||
{ 0x0c, "INVALID_STORAGE_TYPE" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_fault_hubclient[] = {
|
||||
{ 0x01, "PCOPY0" },
|
||||
{ 0x02, "PCOPY1" },
|
||||
{ 0x04, "DISPATCH" },
|
||||
{ 0x05, "CTXCTL" },
|
||||
{ 0x06, "PFIFO" },
|
||||
{ 0x07, "BAR_READ" },
|
||||
{ 0x08, "BAR_WRITE" },
|
||||
{ 0x0b, "PVP" },
|
||||
{ 0x0c, "PMSPPP" },
|
||||
{ 0x0d, "PMSVLD" },
|
||||
{ 0x11, "PCOUNTER" },
|
||||
{ 0x12, "PMU" },
|
||||
{ 0x14, "CCACHE" },
|
||||
{ 0x15, "CCACHE_POST" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_fault_gpcclient[] = {
|
||||
{ 0x01, "TEX" },
|
||||
{ 0x0c, "ESETUP" },
|
||||
{ 0x0e, "CTXCTL" },
|
||||
{ 0x0f, "PROP" },
|
||||
{}
|
||||
};
|
||||
|
||||
static void
|
||||
gf100_fifo_fault(struct nvkm_fifo *base, struct nvkm_fault_data *info)
|
||||
{
|
||||
struct gf100_fifo *fifo = gf100_fifo(base);
|
||||
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
const struct nvkm_enum *er, *eu, *ec;
|
||||
struct nvkm_engine *engine = NULL;
|
||||
struct nvkm_fifo_chan *chan;
|
||||
unsigned long flags;
|
||||
char gpcid[8] = "";
|
||||
|
||||
er = nvkm_enum_find(gf100_fifo_fault_reason, info->reason);
|
||||
eu = nvkm_enum_find(gf100_fifo_fault_engine, info->engine);
|
||||
if (info->hub) {
|
||||
ec = nvkm_enum_find(gf100_fifo_fault_hubclient, info->client);
|
||||
} else {
|
||||
ec = nvkm_enum_find(gf100_fifo_fault_gpcclient, info->client);
|
||||
snprintf(gpcid, sizeof(gpcid), "GPC%d/", info->gpc);
|
||||
}
|
||||
|
||||
if (eu && eu->data2) {
|
||||
switch (eu->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, eu->data2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
chan = nvkm_fifo_chan_inst(&fifo->base, info->inst, &flags);
|
||||
|
||||
nvkm_error(subdev,
|
||||
"%s fault at %010llx engine %02x [%s] client %02x [%s%s] "
|
||||
"reason %02x [%s] on channel %d [%010llx %s]\n",
|
||||
info->access ? "write" : "read", info->addr,
|
||||
info->engine, eu ? eu->name : "",
|
||||
info->client, gpcid, ec ? ec->name : "",
|
||||
info->reason, er ? er->name : "", chan ? chan->chid : -1,
|
||||
info->inst, chan ? chan->object.client->name : "unknown");
|
||||
|
||||
if (engine && chan)
|
||||
gf100_fifo_recover(fifo, engine, (void *)chan);
|
||||
nvkm_fifo_chan_put(&fifo->base, flags, &chan);
|
||||
}
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_sched_reason[] = {
|
||||
{ 0x0a, "CTXSW_TIMEOUT" },
|
||||
@ -255,125 +369,28 @@ gf100_fifo_intr_sched(struct gf100_fifo *fifo)
|
||||
}
|
||||
}
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_fault_engine[] = {
|
||||
{ 0x00, "PGRAPH", NULL, NVKM_ENGINE_GR },
|
||||
{ 0x03, "PEEPHOLE", NULL, NVKM_ENGINE_IFB },
|
||||
{ 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR },
|
||||
{ 0x05, "BAR3", NULL, NVKM_SUBDEV_INSTMEM },
|
||||
{ 0x07, "PFIFO", NULL, NVKM_ENGINE_FIFO },
|
||||
{ 0x10, "PMSVLD", NULL, NVKM_ENGINE_MSVLD },
|
||||
{ 0x11, "PMSPPP", NULL, NVKM_ENGINE_MSPPP },
|
||||
{ 0x13, "PCOUNTER" },
|
||||
{ 0x14, "PMSPDEC", NULL, NVKM_ENGINE_MSPDEC },
|
||||
{ 0x15, "PCE0", NULL, NVKM_ENGINE_CE0 },
|
||||
{ 0x16, "PCE1", NULL, NVKM_ENGINE_CE1 },
|
||||
{ 0x17, "PMU" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_fault_reason[] = {
|
||||
{ 0x00, "PT_NOT_PRESENT" },
|
||||
{ 0x01, "PT_TOO_SHORT" },
|
||||
{ 0x02, "PAGE_NOT_PRESENT" },
|
||||
{ 0x03, "VM_LIMIT_EXCEEDED" },
|
||||
{ 0x04, "NO_CHANNEL" },
|
||||
{ 0x05, "PAGE_SYSTEM_ONLY" },
|
||||
{ 0x06, "PAGE_READ_ONLY" },
|
||||
{ 0x0a, "COMPRESSED_SYSRAM" },
|
||||
{ 0x0c, "INVALID_STORAGE_TYPE" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_fault_hubclient[] = {
|
||||
{ 0x01, "PCOPY0" },
|
||||
{ 0x02, "PCOPY1" },
|
||||
{ 0x04, "DISPATCH" },
|
||||
{ 0x05, "CTXCTL" },
|
||||
{ 0x06, "PFIFO" },
|
||||
{ 0x07, "BAR_READ" },
|
||||
{ 0x08, "BAR_WRITE" },
|
||||
{ 0x0b, "PVP" },
|
||||
{ 0x0c, "PMSPPP" },
|
||||
{ 0x0d, "PMSVLD" },
|
||||
{ 0x11, "PCOUNTER" },
|
||||
{ 0x12, "PMU" },
|
||||
{ 0x14, "CCACHE" },
|
||||
{ 0x15, "CCACHE_POST" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_fault_gpcclient[] = {
|
||||
{ 0x01, "TEX" },
|
||||
{ 0x0c, "ESETUP" },
|
||||
{ 0x0e, "CTXCTL" },
|
||||
{ 0x0f, "PROP" },
|
||||
{}
|
||||
};
|
||||
|
||||
static void
|
||||
gf100_fifo_intr_fault(struct gf100_fifo *fifo, int unit)
|
||||
void
|
||||
gf100_fifo_intr_fault(struct nvkm_fifo *fifo, int unit)
|
||||
{
|
||||
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
struct nvkm_device *device = fifo->engine.subdev.device;
|
||||
u32 inst = nvkm_rd32(device, 0x002800 + (unit * 0x10));
|
||||
u32 valo = nvkm_rd32(device, 0x002804 + (unit * 0x10));
|
||||
u32 vahi = nvkm_rd32(device, 0x002808 + (unit * 0x10));
|
||||
u32 stat = nvkm_rd32(device, 0x00280c + (unit * 0x10));
|
||||
u32 gpc = (stat & 0x1f000000) >> 24;
|
||||
u32 client = (stat & 0x00001f00) >> 8;
|
||||
u32 write = (stat & 0x00000080);
|
||||
u32 hub = (stat & 0x00000040);
|
||||
u32 reason = (stat & 0x0000000f);
|
||||
const struct nvkm_enum *er, *eu, *ec;
|
||||
struct nvkm_engine *engine = NULL;
|
||||
struct nvkm_fifo_chan *chan;
|
||||
unsigned long flags;
|
||||
char gpcid[8] = "";
|
||||
u32 type = nvkm_rd32(device, 0x00280c + (unit * 0x10));
|
||||
struct nvkm_fault_data info;
|
||||
|
||||
er = nvkm_enum_find(gf100_fifo_fault_reason, reason);
|
||||
eu = nvkm_enum_find(gf100_fifo_fault_engine, unit);
|
||||
if (hub) {
|
||||
ec = nvkm_enum_find(gf100_fifo_fault_hubclient, client);
|
||||
} else {
|
||||
ec = nvkm_enum_find(gf100_fifo_fault_gpcclient, client);
|
||||
snprintf(gpcid, sizeof(gpcid), "GPC%d/", gpc);
|
||||
}
|
||||
info.inst = (u64)inst << 12;
|
||||
info.addr = ((u64)vahi << 32) | valo;
|
||||
info.time = 0;
|
||||
info.engine = unit;
|
||||
info.valid = 1;
|
||||
info.gpc = (type & 0x1f000000) >> 24;
|
||||
info.client = (type & 0x00001f00) >> 8;
|
||||
info.access = (type & 0x00000080) >> 7;
|
||||
info.hub = (type & 0x00000040) >> 6;
|
||||
info.reason = (type & 0x0000000f);
|
||||
|
||||
if (eu && eu->data2) {
|
||||
switch (eu->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, eu->data2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
chan = nvkm_fifo_chan_inst(&fifo->base, (u64)inst << 12, &flags);
|
||||
|
||||
nvkm_error(subdev,
|
||||
"%s fault at %010llx engine %02x [%s] client %02x [%s%s] "
|
||||
"reason %02x [%s] on channel %d [%010llx %s]\n",
|
||||
write ? "write" : "read", (u64)vahi << 32 | valo,
|
||||
unit, eu ? eu->name : "", client, gpcid, ec ? ec->name : "",
|
||||
reason, er ? er->name : "", chan ? chan->chid : -1,
|
||||
(u64)inst << 12,
|
||||
chan ? chan->object.client->name : "unknown");
|
||||
|
||||
if (engine && chan)
|
||||
gf100_fifo_recover(fifo, engine, (void *)chan);
|
||||
nvkm_fifo_chan_put(&fifo->base, flags, &chan);
|
||||
nvkm_fifo_fault(fifo, &info);
|
||||
}
|
||||
|
||||
static const struct nvkm_bitfield
|
||||
@ -518,7 +535,7 @@ gf100_fifo_intr(struct nvkm_fifo *base)
|
||||
u32 mask = nvkm_rd32(device, 0x00259c);
|
||||
while (mask) {
|
||||
u32 unit = __ffs(mask);
|
||||
gf100_fifo_intr_fault(fifo, unit);
|
||||
gf100_fifo_intr_fault(&fifo->base, unit);
|
||||
nvkm_wr32(device, 0x00259c, (1 << unit));
|
||||
mask &= ~(1 << unit);
|
||||
}
|
||||
@ -655,6 +672,7 @@ gf100_fifo = {
|
||||
.init = gf100_fifo_init,
|
||||
.fini = gf100_fifo_fini,
|
||||
.intr = gf100_fifo_intr,
|
||||
.fault = gf100_fifo_fault,
|
||||
.uevent_init = gf100_fifo_uevent_init,
|
||||
.uevent_fini = gf100_fifo_uevent_fini,
|
||||
.chan = {
|
||||
|
@ -666,7 +666,7 @@ gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit)
|
||||
info.client = (type & 0x00001f00) >> 8;
|
||||
info.access = (type & 0x00000080) >> 7;
|
||||
info.hub = (type & 0x00000040) >> 6;
|
||||
info.reason = (type & 0x000000ff);
|
||||
info.reason = (type & 0x0000001f);
|
||||
|
||||
nvkm_fifo_fault(&fifo->base, &info);
|
||||
}
|
||||
|
@ -37,4 +37,6 @@ struct nvkm_fifo_func {
|
||||
void nv04_fifo_intr(struct nvkm_fifo *);
|
||||
void nv04_fifo_pause(struct nvkm_fifo *, unsigned long *);
|
||||
void nv04_fifo_start(struct nvkm_fifo *, unsigned long *);
|
||||
|
||||
void gf100_fifo_intr_fault(struct nvkm_fifo *, int);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user