Loading drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h +1 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ struct gk104_fifo_chan { struct nvkm_fifo_chan base; struct gk104_fifo *fifo; int engine; int runl; struct list_head head; bool killed; Loading drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +35 −32 Original line number Diff line number Diff line Loading @@ -47,38 +47,41 @@ gk104_fifo_uevent_init(struct nvkm_fifo *fifo) } void gk104_fifo_runlist_commit(struct gk104_fifo *fifo, u32 engine) gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl) { struct gk104_fifo_engn *engn = &fifo->engine[engine]; struct gk104_fifo_chan *chan; struct nvkm_subdev *subdev = &fifo->base.engine.subdev; struct nvkm_device *device = subdev->device; struct nvkm_memory *cur; struct nvkm_memory *mem; int nr = 0; int target; mutex_lock(&subdev->mutex); cur = engn->runlist[engn->cur_runlist]; engn->cur_runlist = !engn->cur_runlist; mem = fifo->runlist[runl].mem[fifo->runlist[runl].next]; fifo->runlist[runl].next = !fifo->runlist[runl].next; nvkm_kmap(cur); list_for_each_entry(chan, &engn->chan, head) { nvkm_wo32(cur, (nr * 8) + 0, chan->base.chid); nvkm_wo32(cur, (nr * 8) + 4, 0x00000000); nvkm_kmap(mem); list_for_each_entry(chan, &fifo->runlist[runl].chan, head) { nvkm_wo32(mem, (nr * 8) + 0, chan->base.chid); nvkm_wo32(mem, (nr * 8) + 4, 0x00000000); nr++; } nvkm_done(cur); nvkm_done(mem); target = (nvkm_memory_target(cur) == NVKM_MEM_TARGET_HOST) ? 0x3 : 0x0; if (nvkm_memory_target(mem) == NVKM_MEM_TARGET_VRAM) target = 0; else target = 3; nvkm_wr32(device, 0x002270, (nvkm_memory_addr(cur) >> 12) | nvkm_wr32(device, 0x002270, (nvkm_memory_addr(mem) >> 12) | (target << 28)); nvkm_wr32(device, 0x002274, (engine << 20) | nr); nvkm_wr32(device, 0x002274, (runl << 20) | nr); if (wait_event_timeout(engn->wait, !(nvkm_rd32(device, 0x002284 + (engine * 0x08)) & 0x00100000), if (wait_event_timeout(fifo->runlist[runl].wait, !(nvkm_rd32(device, 0x002284 + (runl * 0x08)) & 0x00100000), msecs_to_jiffies(2000)) == 0) nvkm_error(subdev, "runlist %d update timeout\n", engine); nvkm_error(subdev, "runlist %d update timeout\n", runl); mutex_unlock(&subdev->mutex); } Loading @@ -94,7 +97,7 @@ void gk104_fifo_runlist_insert(struct gk104_fifo *fifo, struct gk104_fifo_chan *chan) { mutex_lock(&fifo->base.engine.subdev.mutex); list_add_tail(&chan->head, &fifo->engine[chan->engine].chan); list_add_tail(&chan->head, &fifo->runlist[chan->runl].chan); mutex_unlock(&fifo->base.engine.subdev.mutex); } Loading Loading @@ -199,7 +202,7 @@ gk104_fifo_intr_sched_ctxsw(struct gk104_fifo *fifo) u32 engn; spin_lock_irqsave(&fifo->base.lock, flags); for (engn = 0; engn < ARRAY_SIZE(fifo->engine); engn++) { for (engn = 0; engn < ARRAY_SIZE(fifo->runlist); engn++) { u32 stat = nvkm_rd32(device, 0x002640 + (engn * 0x08)); u32 busy = (stat & 0x80000000); u32 next = (stat & 0x0fff0000) >> 16; Loading @@ -211,7 +214,7 @@ gk104_fifo_intr_sched_ctxsw(struct gk104_fifo *fifo) (void)save; if (busy && chsw) { list_for_each_entry(chan, &fifo->engine[engn].chan, head) { list_for_each_entry(chan, &fifo->runlist[engn].chan, head) { if (chan->base.chid == chid) { engine = gk104_fifo_engine(fifo, engn); if (!engine) Loading Loading @@ -541,10 +544,10 @@ gk104_fifo_intr_runlist(struct gk104_fifo *fifo) struct nvkm_device *device = fifo->base.engine.subdev.device; u32 mask = nvkm_rd32(device, 0x002a00); while (mask) { u32 engn = __ffs(mask); wake_up(&fifo->engine[engn].wait); nvkm_wr32(device, 0x002a00, 1 << engn); mask &= ~(1 << engn); int runl = __ffs(mask); wake_up(&fifo->runlist[runl].wait); nvkm_wr32(device, 0x002a00, 1 << runl); mask &= ~(1 << runl); } } Loading Loading @@ -669,21 +672,21 @@ gk104_fifo_oneinit(struct nvkm_fifo *base) fifo->pbdma_nr = hweight32(nvkm_rd32(device, 0x000204)); nvkm_debug(subdev, "%d PBDMA(s)\n", fifo->pbdma_nr); for (i = 0; i < ARRAY_SIZE(fifo->engine); i++) { for (i = 0; i < ARRAY_SIZE(fifo->runlist); i++) { ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x8000, 0x1000, false, &fifo->engine[i].runlist[0]); &fifo->runlist[i].mem[0]); if (ret) return ret; ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x8000, 0x1000, false, &fifo->engine[i].runlist[1]); &fifo->runlist[i].mem[1]); if (ret) return ret; init_waitqueue_head(&fifo->engine[i].wait); INIT_LIST_HEAD(&fifo->engine[i].chan); init_waitqueue_head(&fifo->runlist[i].wait); INIT_LIST_HEAD(&fifo->runlist[i].chan); } ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, Loading Loading @@ -739,9 +742,9 @@ gk104_fifo_dtor(struct nvkm_fifo *base) nvkm_vm_put(&fifo->user.bar); nvkm_memory_del(&fifo->user.mem); for (i = 0; i < ARRAY_SIZE(fifo->engine); i++) { nvkm_memory_del(&fifo->engine[i].runlist[1]); nvkm_memory_del(&fifo->engine[i].runlist[0]); for (i = 0; i < ARRAY_SIZE(fifo->runlist); i++) { nvkm_memory_del(&fifo->runlist[i].mem[1]); nvkm_memory_del(&fifo->runlist[i].mem[0]); } return fifo; Loading drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h +8 −9 Original line number Diff line number Diff line Loading @@ -6,13 +6,6 @@ #include <subdev/mmu.h> struct gk104_fifo_chan; struct gk104_fifo_engn { struct nvkm_memory *runlist[2]; int cur_runlist; wait_queue_head_t wait; struct list_head chan; }; struct gk104_fifo { struct nvkm_fifo base; Loading @@ -23,7 +16,13 @@ struct gk104_fifo { int pbdma_nr; struct gk104_fifo_engn engine[7]; struct { struct nvkm_memory *mem[2]; int next; wait_queue_head_t wait; struct list_head chan; } runlist[7]; struct { struct nvkm_memory *mem; struct nvkm_vma bar; Loading @@ -41,7 +40,7 @@ void gk104_fifo_uevent_init(struct nvkm_fifo *); void gk104_fifo_uevent_fini(struct nvkm_fifo *); void gk104_fifo_runlist_insert(struct gk104_fifo *, struct gk104_fifo_chan *); void gk104_fifo_runlist_remove(struct gk104_fifo *, struct gk104_fifo_chan *); void gk104_fifo_runlist_commit(struct gk104_fifo *, u32 engine); void gk104_fifo_runlist_commit(struct gk104_fifo *, int runl); static inline u64 gk104_fifo_engine_subdev(int engine) Loading drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +6 −6 Original line number Diff line number Diff line Loading @@ -155,7 +155,7 @@ gk104_fifo_gpfifo_fini(struct nvkm_fifo_chan *base) gk104_fifo_runlist_remove(fifo, chan); nvkm_mask(device, 0x800004 + coff, 0x00000800, 0x00000800); gk104_fifo_gpfifo_kick(chan); gk104_fifo_runlist_commit(fifo, chan->engine); gk104_fifo_runlist_commit(fifo, chan->runl); } nvkm_wr32(device, 0x800000 + coff, 0x00000000); Loading @@ -170,13 +170,13 @@ gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *base) u32 addr = chan->base.inst->addr >> 12; u32 coff = chan->base.chid * 8; nvkm_mask(device, 0x800004 + coff, 0x000f0000, chan->engine << 16); nvkm_mask(device, 0x800004 + coff, 0x000f0000, chan->runl << 16); nvkm_wr32(device, 0x800000 + coff, 0x80000000 | addr); if (list_empty(&chan->head) && !chan->killed) { gk104_fifo_runlist_insert(fifo, chan); nvkm_mask(device, 0x800004 + coff, 0x00000400, 0x00000400); gk104_fifo_runlist_commit(fifo, chan->engine); gk104_fifo_runlist_commit(fifo, chan->runl); nvkm_mask(device, 0x800004 + coff, 0x00000400, 0x00000400); } } Loading Loading @@ -227,7 +227,7 @@ gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, return ret; /* determine which downstream engines are present */ for (i = 0, engines = 0; i < ARRAY_SIZE(fifo->engine); i++) { for (i = 0, engines = 0; i < ARRAY_SIZE(fifo->runlist); i++) { u64 subdevs = gk104_fifo_engine_subdev(i); if (!nvkm_device_engine(device, __ffs64(subdevs))) continue; Loading Loading @@ -255,12 +255,12 @@ gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, return -ENOMEM; *pobject = &chan->base.object; chan->fifo = fifo; chan->engine = __ffs(args->v0.engine); chan->runl = __ffs(args->v0.engine); INIT_LIST_HEAD(&chan->head); ret = nvkm_fifo_chan_ctor(&gk104_fifo_gpfifo_func, &fifo->base, 0x1000, 0x1000, true, args->v0.vm, 0, gk104_fifo_engine_subdev(chan->engine), gk104_fifo_engine_subdev(chan->runl), 1, fifo->user.bar.offset, 0x200, oclass, &chan->base); if (ret) Loading Loading
drivers/gpu/drm/nouveau/nvkm/engine/fifo/changk104.h +1 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ struct gk104_fifo_chan { struct nvkm_fifo_chan base; struct gk104_fifo *fifo; int engine; int runl; struct list_head head; bool killed; Loading
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +35 −32 Original line number Diff line number Diff line Loading @@ -47,38 +47,41 @@ gk104_fifo_uevent_init(struct nvkm_fifo *fifo) } void gk104_fifo_runlist_commit(struct gk104_fifo *fifo, u32 engine) gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl) { struct gk104_fifo_engn *engn = &fifo->engine[engine]; struct gk104_fifo_chan *chan; struct nvkm_subdev *subdev = &fifo->base.engine.subdev; struct nvkm_device *device = subdev->device; struct nvkm_memory *cur; struct nvkm_memory *mem; int nr = 0; int target; mutex_lock(&subdev->mutex); cur = engn->runlist[engn->cur_runlist]; engn->cur_runlist = !engn->cur_runlist; mem = fifo->runlist[runl].mem[fifo->runlist[runl].next]; fifo->runlist[runl].next = !fifo->runlist[runl].next; nvkm_kmap(cur); list_for_each_entry(chan, &engn->chan, head) { nvkm_wo32(cur, (nr * 8) + 0, chan->base.chid); nvkm_wo32(cur, (nr * 8) + 4, 0x00000000); nvkm_kmap(mem); list_for_each_entry(chan, &fifo->runlist[runl].chan, head) { nvkm_wo32(mem, (nr * 8) + 0, chan->base.chid); nvkm_wo32(mem, (nr * 8) + 4, 0x00000000); nr++; } nvkm_done(cur); nvkm_done(mem); target = (nvkm_memory_target(cur) == NVKM_MEM_TARGET_HOST) ? 0x3 : 0x0; if (nvkm_memory_target(mem) == NVKM_MEM_TARGET_VRAM) target = 0; else target = 3; nvkm_wr32(device, 0x002270, (nvkm_memory_addr(cur) >> 12) | nvkm_wr32(device, 0x002270, (nvkm_memory_addr(mem) >> 12) | (target << 28)); nvkm_wr32(device, 0x002274, (engine << 20) | nr); nvkm_wr32(device, 0x002274, (runl << 20) | nr); if (wait_event_timeout(engn->wait, !(nvkm_rd32(device, 0x002284 + (engine * 0x08)) & 0x00100000), if (wait_event_timeout(fifo->runlist[runl].wait, !(nvkm_rd32(device, 0x002284 + (runl * 0x08)) & 0x00100000), msecs_to_jiffies(2000)) == 0) nvkm_error(subdev, "runlist %d update timeout\n", engine); nvkm_error(subdev, "runlist %d update timeout\n", runl); mutex_unlock(&subdev->mutex); } Loading @@ -94,7 +97,7 @@ void gk104_fifo_runlist_insert(struct gk104_fifo *fifo, struct gk104_fifo_chan *chan) { mutex_lock(&fifo->base.engine.subdev.mutex); list_add_tail(&chan->head, &fifo->engine[chan->engine].chan); list_add_tail(&chan->head, &fifo->runlist[chan->runl].chan); mutex_unlock(&fifo->base.engine.subdev.mutex); } Loading Loading @@ -199,7 +202,7 @@ gk104_fifo_intr_sched_ctxsw(struct gk104_fifo *fifo) u32 engn; spin_lock_irqsave(&fifo->base.lock, flags); for (engn = 0; engn < ARRAY_SIZE(fifo->engine); engn++) { for (engn = 0; engn < ARRAY_SIZE(fifo->runlist); engn++) { u32 stat = nvkm_rd32(device, 0x002640 + (engn * 0x08)); u32 busy = (stat & 0x80000000); u32 next = (stat & 0x0fff0000) >> 16; Loading @@ -211,7 +214,7 @@ gk104_fifo_intr_sched_ctxsw(struct gk104_fifo *fifo) (void)save; if (busy && chsw) { list_for_each_entry(chan, &fifo->engine[engn].chan, head) { list_for_each_entry(chan, &fifo->runlist[engn].chan, head) { if (chan->base.chid == chid) { engine = gk104_fifo_engine(fifo, engn); if (!engine) Loading Loading @@ -541,10 +544,10 @@ gk104_fifo_intr_runlist(struct gk104_fifo *fifo) struct nvkm_device *device = fifo->base.engine.subdev.device; u32 mask = nvkm_rd32(device, 0x002a00); while (mask) { u32 engn = __ffs(mask); wake_up(&fifo->engine[engn].wait); nvkm_wr32(device, 0x002a00, 1 << engn); mask &= ~(1 << engn); int runl = __ffs(mask); wake_up(&fifo->runlist[runl].wait); nvkm_wr32(device, 0x002a00, 1 << runl); mask &= ~(1 << runl); } } Loading Loading @@ -669,21 +672,21 @@ gk104_fifo_oneinit(struct nvkm_fifo *base) fifo->pbdma_nr = hweight32(nvkm_rd32(device, 0x000204)); nvkm_debug(subdev, "%d PBDMA(s)\n", fifo->pbdma_nr); for (i = 0; i < ARRAY_SIZE(fifo->engine); i++) { for (i = 0; i < ARRAY_SIZE(fifo->runlist); i++) { ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x8000, 0x1000, false, &fifo->engine[i].runlist[0]); &fifo->runlist[i].mem[0]); if (ret) return ret; ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x8000, 0x1000, false, &fifo->engine[i].runlist[1]); &fifo->runlist[i].mem[1]); if (ret) return ret; init_waitqueue_head(&fifo->engine[i].wait); INIT_LIST_HEAD(&fifo->engine[i].chan); init_waitqueue_head(&fifo->runlist[i].wait); INIT_LIST_HEAD(&fifo->runlist[i].chan); } ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, Loading Loading @@ -739,9 +742,9 @@ gk104_fifo_dtor(struct nvkm_fifo *base) nvkm_vm_put(&fifo->user.bar); nvkm_memory_del(&fifo->user.mem); for (i = 0; i < ARRAY_SIZE(fifo->engine); i++) { nvkm_memory_del(&fifo->engine[i].runlist[1]); nvkm_memory_del(&fifo->engine[i].runlist[0]); for (i = 0; i < ARRAY_SIZE(fifo->runlist); i++) { nvkm_memory_del(&fifo->runlist[i].mem[1]); nvkm_memory_del(&fifo->runlist[i].mem[0]); } return fifo; Loading
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h +8 −9 Original line number Diff line number Diff line Loading @@ -6,13 +6,6 @@ #include <subdev/mmu.h> struct gk104_fifo_chan; struct gk104_fifo_engn { struct nvkm_memory *runlist[2]; int cur_runlist; wait_queue_head_t wait; struct list_head chan; }; struct gk104_fifo { struct nvkm_fifo base; Loading @@ -23,7 +16,13 @@ struct gk104_fifo { int pbdma_nr; struct gk104_fifo_engn engine[7]; struct { struct nvkm_memory *mem[2]; int next; wait_queue_head_t wait; struct list_head chan; } runlist[7]; struct { struct nvkm_memory *mem; struct nvkm_vma bar; Loading @@ -41,7 +40,7 @@ void gk104_fifo_uevent_init(struct nvkm_fifo *); void gk104_fifo_uevent_fini(struct nvkm_fifo *); void gk104_fifo_runlist_insert(struct gk104_fifo *, struct gk104_fifo_chan *); void gk104_fifo_runlist_remove(struct gk104_fifo *, struct gk104_fifo_chan *); void gk104_fifo_runlist_commit(struct gk104_fifo *, u32 engine); void gk104_fifo_runlist_commit(struct gk104_fifo *, int runl); static inline u64 gk104_fifo_engine_subdev(int engine) Loading
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +6 −6 Original line number Diff line number Diff line Loading @@ -155,7 +155,7 @@ gk104_fifo_gpfifo_fini(struct nvkm_fifo_chan *base) gk104_fifo_runlist_remove(fifo, chan); nvkm_mask(device, 0x800004 + coff, 0x00000800, 0x00000800); gk104_fifo_gpfifo_kick(chan); gk104_fifo_runlist_commit(fifo, chan->engine); gk104_fifo_runlist_commit(fifo, chan->runl); } nvkm_wr32(device, 0x800000 + coff, 0x00000000); Loading @@ -170,13 +170,13 @@ gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *base) u32 addr = chan->base.inst->addr >> 12; u32 coff = chan->base.chid * 8; nvkm_mask(device, 0x800004 + coff, 0x000f0000, chan->engine << 16); nvkm_mask(device, 0x800004 + coff, 0x000f0000, chan->runl << 16); nvkm_wr32(device, 0x800000 + coff, 0x80000000 | addr); if (list_empty(&chan->head) && !chan->killed) { gk104_fifo_runlist_insert(fifo, chan); nvkm_mask(device, 0x800004 + coff, 0x00000400, 0x00000400); gk104_fifo_runlist_commit(fifo, chan->engine); gk104_fifo_runlist_commit(fifo, chan->runl); nvkm_mask(device, 0x800004 + coff, 0x00000400, 0x00000400); } } Loading Loading @@ -227,7 +227,7 @@ gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, return ret; /* determine which downstream engines are present */ for (i = 0, engines = 0; i < ARRAY_SIZE(fifo->engine); i++) { for (i = 0, engines = 0; i < ARRAY_SIZE(fifo->runlist); i++) { u64 subdevs = gk104_fifo_engine_subdev(i); if (!nvkm_device_engine(device, __ffs64(subdevs))) continue; Loading Loading @@ -255,12 +255,12 @@ gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, return -ENOMEM; *pobject = &chan->base.object; chan->fifo = fifo; chan->engine = __ffs(args->v0.engine); chan->runl = __ffs(args->v0.engine); INIT_LIST_HEAD(&chan->head); ret = nvkm_fifo_chan_ctor(&gk104_fifo_gpfifo_func, &fifo->base, 0x1000, 0x1000, true, args->v0.vm, 0, gk104_fifo_engine_subdev(chan->engine), gk104_fifo_engine_subdev(chan->runl), 1, fifo->user.bar.offset, 0x200, oclass, &chan->base); if (ret) Loading