summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/core/engine/fifo
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-02-22 12:44:23 +1000
committerBen Skeggs <bskeggs@redhat.com>2014-03-26 14:00:47 +1000
commit61fdf6209350d6d5c5b2472c4b9e242e98ca3680 (patch)
tree1144125557096390ceb189409deb55277266457b /drivers/gpu/drm/nouveau/core/engine/fifo
parent24e8341e4cd4c7e0fa90a452598a4e01ea267396 (diff)
downloadop-kernel-dev-61fdf6209350d6d5c5b2472c4b9e242e98ca3680.zip
op-kernel-dev-61fdf6209350d6d5c5b2472c4b9e242e98ca3680.tar.gz
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>
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/engine/fifo')
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
index 358926b..fa1e719 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
@@ -481,6 +481,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)
{
u32 intr = nv_rd32(priv, 0x00254c);
@@ -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
OpenPOWER on IntegriCloud