diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2018-12-11 07:50:02 +0300 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2018-12-11 08:37:49 +0300 |
commit | a98a3c52f81d20d61b43d084ddb724ab55d32526 (patch) | |
tree | 4b2f856e2aae1d4920708062f928cd5fd4dde34e | |
parent | f7cc47e436c1238031548e0380eecc1ab66f24ba (diff) | |
download | linux-a98a3c52f81d20d61b43d084ddb724ab55d32526.tar.xz |
drm/nouveau/fifo/gv100: allocate method buffer
The GPU saves off some stuff to the address specified in this part of RAMFC
when the channel faults, so we should probably point it at a valid address.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c | 22 |
3 files changed, 22 insertions, 3 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h index 8e28ba6b2307..68df966205d0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h @@ -14,6 +14,8 @@ struct gk104_fifo_chan { struct list_head head; bool killed; + struct nvkm_memory *mthd; + struct { struct nvkm_gpuobj *inst; struct nvkm_vma *vma; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c index 6127e2cf5b93..728a1edbf98c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c @@ -222,6 +222,7 @@ void * gk104_fifo_gpfifo_dtor(struct nvkm_fifo_chan *base) { struct gk104_fifo_chan *chan = gk104_fifo_chan(base); + nvkm_memory_unref(&chan->mthd); kfree(chan->cgrp); return chan; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c index 65db8a1be943..ad5d119f6a36 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c @@ -118,11 +118,13 @@ gv100_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid, const struct nvkm_oclass *oclass, struct nvkm_object **pobject) { + struct nvkm_device *device = fifo->base.engine.subdev.device; struct gk104_fifo_chan *chan; int runlist = ffs(*runlists) -1, ret, i; unsigned long engm; u64 subdevs = 0; - u64 usermem; + u64 usermem, mthd; + u32 size; if (!vmm || runlist < 0 || runlist >= fifo->runlist_nr) return -EINVAL; @@ -174,6 +176,20 @@ gv100_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid, nvkm_done(fifo->user.mem); usermem = nvkm_memory_addr(fifo->user.mem) + usermem; + /* Allocate fault method buffer (magics come from nvgpu). */ + size = nvkm_rd32(device, 0x104028); /* NV_PCE_PCE_MAP */ + size = 27 * 5 * (((9 + 1 + 3) * hweight32(size)) + 2); + size = roundup(size, PAGE_SIZE); + + ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, size, 0x1000, true, + &chan->mthd); + if (ret) + return ret; + + mthd = nvkm_memory_bar2(chan->mthd); + if (mthd == ~0ULL) + return -EFAULT; + /* RAMFC */ nvkm_kmap(chan->base.inst); nvkm_wo32(chan->base.inst, 0x008, lower_32_bits(usermem)); @@ -190,8 +206,8 @@ gv100_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid, nvkm_wo32(chan->base.inst, 0x0f4, 0x00001000); nvkm_wo32(chan->base.inst, 0x0f8, 0x10003080); nvkm_mo32(chan->base.inst, 0x218, 0x00000000, 0x00000000); - nvkm_wo32(chan->base.inst, 0x220, 0x020a1000); - nvkm_wo32(chan->base.inst, 0x224, 0x00000000); + nvkm_wo32(chan->base.inst, 0x220, lower_32_bits(mthd)); + nvkm_wo32(chan->base.inst, 0x224, upper_32_bits(mthd)); nvkm_done(chan->base.inst); return gv100_fifo_gpfifo_engine_valid(chan, true, true); } |