mirror of https://gitee.com/openkylin/linux.git
drm/nvc0/fifo: attempt to recover from engine ctxsw timeouts
My test cases don't seem to trigger this on all Fermi boards, not sure if they're broken tests or it didn't work until later versions. GF119 definitely works. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
24e8341e4c
commit
61fdf62093
|
@ -480,6 +480,32 @@ nvc0_fifo_sched_reason[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static void
|
||||
nvc0_fifo_intr_sched_ctxsw(struct nvc0_fifo_priv *priv)
|
||||
{
|
||||
struct nouveau_engine *engine;
|
||||
struct nvc0_fifo_chan *chan;
|
||||
u32 engn;
|
||||
|
||||
for (engn = 0; engn < 6; engn++) {
|
||||
u32 stat = nv_rd32(priv, 0x002640 + (engn * 0x04));
|
||||
u32 busy = (stat & 0x80000000);
|
||||
u32 save = (stat & 0x00100000); /* maybe? */
|
||||
u32 unk0 = (stat & 0x00040000);
|
||||
u32 unk1 = (stat & 0x00001000);
|
||||
u32 chid = (stat & 0x0000007f);
|
||||
(void)save;
|
||||
|
||||
if (busy && unk0 && unk1) {
|
||||
if (!(chan = (void *)priv->base.channel[chid]))
|
||||
continue;
|
||||
if (!(engine = nvc0_fifo_engine(priv, engn)))
|
||||
continue;
|
||||
nvc0_fifo_recover(priv, engine, chan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nvc0_fifo_intr_sched(struct nvc0_fifo_priv *priv)
|
||||
{
|
||||
|
@ -493,6 +519,14 @@ nvc0_fifo_intr_sched(struct nvc0_fifo_priv *priv)
|
|||
snprintf(enunk, sizeof(enunk), "UNK%02x", code);
|
||||
|
||||
nv_error(priv, "SCHED_ERROR [ %s ]\n", en ? en->name : enunk);
|
||||
|
||||
switch (code) {
|
||||
case 0x0a:
|
||||
nvc0_fifo_intr_sched_ctxsw(priv);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct nouveau_enum
|
||||
|
|
Loading…
Reference in New Issue