drm/nouveau/fifo/gk104-: ACK SCHED_ERROR before attempting CTXSW_TIMEOUT recovery
authorBen Skeggs <bskeggs@redhat.com>
Wed, 18 Jan 2017 06:05:15 +0000 (16:05 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 17 Feb 2017 07:38:15 +0000 (17:38 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c

index 52aedd891e807a66a5f97aeee654a9058b40c4b4..e4e68f6fb1382cb8aa1e27f71da04a34108219f2 100644 (file)
@@ -338,10 +338,17 @@ gk104_fifo_sched_reason[] = {
 static void
 gk104_fifo_intr_sched_ctxsw(struct gk104_fifo *fifo)
 {
+       struct nvkm_device *device = fifo->base.engine.subdev.device;
        unsigned long flags, engm = 0;
        u32 engn;
 
+       /* We need to ACK the SCHED_ERROR here, and prevent it reasserting,
+        * as MMU_FAULT cannot be triggered while it's pending.
+        */
        spin_lock_irqsave(&fifo->base.lock, flags);
+       nvkm_mask(device, 0x002140, 0x00000100, 0x00000000);
+       nvkm_wr32(device, 0x002100, 0x00000100);
+
        for (engn = 0; engn < fifo->engine_nr; engn++) {
                struct gk104_fifo_engine_status status;
 
@@ -355,6 +362,7 @@ gk104_fifo_intr_sched_ctxsw(struct gk104_fifo *fifo)
        for_each_set_bit(engn, &engm, fifo->engine_nr)
                gk104_fifo_recover_engn(fifo, engn);
 
+       nvkm_mask(device, 0x002140, 0x00000100, 0x00000100);
        spin_unlock_irqrestore(&fifo->base.lock, flags);
 }