diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c | 105 |
1 files changed, 85 insertions, 20 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c index 915278c7e012..a8ff21cf7712 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c @@ -21,47 +21,112 @@ * * Authors: Ben Skeggs */ -#include "gk104.h" +#include "priv.h" #include "cgrp.h" -#include "changk104.h" +#include "chan.h" +#include "chid.h" +#include "runl.h" #include <core/memory.h> +#include <subdev/timer.h> #include <nvif/class.h> void -gk110_fifo_runlist_cgrp(struct nvkm_fifo_cgrp *cgrp, - struct nvkm_memory *memory, u32 offset) +gk110_chan_preempt(struct nvkm_chan *chan) +{ + struct nvkm_cgrp *cgrp = chan->cgrp; + + if (cgrp->hw) { + cgrp->func->preempt(cgrp); + return; + } + + gf100_chan_preempt(chan); +} + +const struct nvkm_chan_func +gk110_chan = { + .inst = &gf100_chan_inst, + .userd = &gk104_chan_userd, + .ramfc = &gk104_chan_ramfc, + .bind = gk104_chan_bind, + .unbind = gk104_chan_unbind, + .start = gk104_chan_start, + .stop = gk104_chan_stop, + .preempt = gk110_chan_preempt, +}; + +static void +gk110_cgrp_preempt(struct nvkm_cgrp *cgrp) +{ + nvkm_wr32(cgrp->runl->fifo->engine.subdev.device, 0x002634, 0x01000000 | cgrp->id); +} + +const struct nvkm_cgrp_func +gk110_cgrp = { + .preempt = gk110_cgrp_preempt, +}; + +void +gk110_runl_insert_cgrp(struct nvkm_cgrp *cgrp, struct nvkm_memory *memory, u64 offset) { nvkm_wo32(memory, offset + 0, (cgrp->chan_nr << 26) | (128 << 18) | (3 << 14) | 0x00002000 | cgrp->id); nvkm_wo32(memory, offset + 4, 0x00000000); } -const struct gk104_fifo_runlist_func -gk110_fifo_runlist = { +const struct nvkm_runl_func +gk110_runl = { .size = 8, - .cgrp = gk110_fifo_runlist_cgrp, - .chan = gk104_fifo_runlist_chan, - .commit = gk104_fifo_runlist_commit, + .update = nv50_runl_update, + .insert_cgrp = gk110_runl_insert_cgrp, + .insert_chan = gk104_runl_insert_chan, + .commit = gk104_runl_commit, + .wait = nv50_runl_wait, + .pending = gk104_runl_pending, + .block = gk104_runl_block, + .allow = gk104_runl_allow, + .fault_clear = gk104_runl_fault_clear, + .preempt_pending = gf100_runl_preempt_pending, }; -static const struct gk104_fifo_func +int +gk110_fifo_chid_ctor(struct nvkm_fifo *fifo, int nr) +{ + int ret; + + ret = nvkm_chid_new(&nvkm_chan_event, &fifo->engine.subdev, nr, 0, nr, &fifo->cgid); + if (ret) + return ret; + + return gf100_fifo_chid_ctor(fifo, nr); +} + +static const struct nvkm_fifo_func gk110_fifo = { - .intr.fault = gf100_fifo_intr_fault, - .pbdma = &gk104_fifo_pbdma, - .fault.access = gk104_fifo_fault_access, - .fault.engine = gk104_fifo_fault_engine, - .fault.reason = gk104_fifo_fault_reason, - .fault.hubclient = gk104_fifo_fault_hubclient, - .fault.gpcclient = gk104_fifo_fault_gpcclient, - .runlist = &gk110_fifo_runlist, - .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_B}, gk104_fifo_gpfifo_new }, + .chid_nr = gk104_fifo_chid_nr, + .chid_ctor = gk110_fifo_chid_ctor, + .runq_nr = gf100_fifo_runq_nr, + .runl_ctor = gk104_fifo_runl_ctor, + .init = gk104_fifo_init, + .init_pbdmas = gk104_fifo_init_pbdmas, + .intr = gk104_fifo_intr, + .intr_mmu_fault_unit = gf100_fifo_intr_mmu_fault_unit, + .intr_ctxsw_timeout = gf100_fifo_intr_ctxsw_timeout, + .mmu_fault = &gk104_fifo_mmu_fault, + .nonstall = &gf100_fifo_nonstall, + .runl = &gk110_runl, + .runq = &gk104_runq, + .engn = &gk104_engn, + .engn_ce = &gk104_engn_ce, + .cgrp = {{ 0, 0, KEPLER_CHANNEL_GROUP_A }, &gk110_cgrp }, + .chan = {{ 0, 0, KEPLER_CHANNEL_GPFIFO_B }, &gk110_chan }, }; int gk110_fifo_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst, struct nvkm_fifo **pfifo) { - return gk104_fifo_new_(&gk110_fifo, device, type, inst, 4096, pfifo); + return nvkm_fifo_new_(&gk110_fifo, device, type, inst, pfifo); } |