diff options
author | Ben Skeggs | 2017-01-18 15:35:16 +1000 |
---|---|---|
committer | Ben Skeggs | 2017-02-17 17:38:13 +1000 |
commit | eaa5ed65eebb3ee9679a5f7b597c34a6207843c2 (patch) | |
tree | ff51f5d5e2197bdcd45aef543a412cdc5b8ed11f /drivers/gpu | |
parent | 0faaa47d440df5302132c47f8f84b3f61d9fc424 (diff) |
drm/nouveau/fifo/gk104-: reset all engines a killed channel is still active on
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index c45f732366b4..4f174470c02b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -243,6 +243,7 @@ gk104_fifo_recover_chan(struct nvkm_fifo *base, int chid) const u32 stat = nvkm_rd32(device, 0x800004 + (chid * 0x08)); const u32 runl = (stat & 0x000f0000) >> 16; const bool used = (stat & 0x00000001); + unsigned long engn, engm = fifo->runlist[runl].engm; struct gk104_fifo_chan *chan; assert_spin_locked(&fifo->base.lock); @@ -262,6 +263,18 @@ gk104_fifo_recover_chan(struct nvkm_fifo *base, int chid) /* Disable channel. */ nvkm_wr32(device, 0x800004 + (chid * 0x08), stat | 0x00000800); nvkm_warn(subdev, "channel %d: killed\n", chid); + + /* Block channel assignments from changing during recovery. */ + gk104_fifo_recover_runl(fifo, runl); + + /* Schedule recovery for any engines the channel is on. */ + for_each_set_bit(engn, &engm, fifo->engine_nr) { + struct gk104_fifo_engine_status status; + gk104_fifo_engine_status(fifo, engn, &status); + if (!status.chan || status.chan->id != chid) + continue; + gk104_fifo_recover_engn(fifo, engn); + } } static void |