diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2022-06-01 20:47:31 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2022-11-09 10:44:48 +1000 |
commit | 3a6bc9c242e10c203a5b083af7823b50b5d63010 (patch) | |
tree | afb02468e4bed3900a9708c42c76605627e1ad32 /drivers | |
parent | 4a492fd5d26298c82c555f603fe4aa38cf512464 (diff) | |
download | linux-3a6bc9c242e10c203a5b083af7823b50b5d63010.tar.gz linux-3a6bc9c242e10c203a5b083af7823b50b5d63010.tar.bz2 linux-3a6bc9c242e10c203a5b083af7823b50b5d63010.zip |
drm/nouveau/fifo: add runlist block()/allow()
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c | 13 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c | 18 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c | 28 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c | 2 |
13 files changed, 95 insertions, 14 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c index f250b0f9e274..748f3f199b9f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c @@ -211,11 +211,24 @@ nvkm_fifo_chan_child_new(const struct nvkm_oclass *oclass, void *data, u32 size, void nvkm_chan_cctx_bind(struct nvkm_chan *chan, struct nvkm_oproxy *oproxy, struct nvkm_cctx *cctx) { + struct nvkm_cgrp *cgrp = chan->cgrp; + struct nvkm_runl *runl = cgrp->runl; + + /* Prevent any channel in channel group from being rescheduled, kick them + * off host and any engine(s) they're loaded on. + */ + if (cgrp->hw) + nvkm_runl_block(runl); + /* Update context pointer. */ if (cctx) nvkm_fifo_chan_child_init(nvkm_oproxy(oproxy->object)); else nvkm_fifo_chan_child_fini(nvkm_oproxy(oproxy->object), false); + + /* Resume normal operation. */ + if (cgrp->hw) + nvkm_runl_allow(runl); } void diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c index 70a2609479b9..fcfc241c8a99 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c @@ -115,6 +115,18 @@ gf100_runq = { .intr_0_names = gf100_runq_intr_0_names, }; +static void +gf100_runl_allow(struct nvkm_runl *runl, u32 engm) +{ + nvkm_mask(runl->fifo->engine.subdev.device, 0x002630, engm, 0x00000000); +} + +static void +gf100_runl_block(struct nvkm_runl *runl, u32 engm) +{ + nvkm_mask(runl->fifo->engine.subdev.device, 0x002630, engm, engm); +} + static bool gf100_runl_pending(struct nvkm_runl *runl) { @@ -181,6 +193,8 @@ static const struct nvkm_runl_func gf100_runl = { .wait = nv50_runl_wait, .pending = gf100_runl_pending, + .block = gf100_runl_block, + .allow = gf100_runl_allow, }; static void diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index c816654dc245..12aebf83f090 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -197,6 +197,18 @@ gk104_runq = { .intr_0_names = gk104_runq_intr_0_names, }; +void +gk104_runl_allow(struct nvkm_runl *runl, u32 engm) +{ + nvkm_mask(runl->fifo->engine.subdev.device, 0x002630, BIT(runl->id), 0x00000000); +} + +void +gk104_runl_block(struct nvkm_runl *runl, u32 engm) +{ + nvkm_mask(runl->fifo->engine.subdev.device, 0x002630, BIT(runl->id), BIT(runl->id)); +} + bool gk104_runl_pending(struct nvkm_runl *runl) { @@ -306,6 +318,8 @@ static const struct nvkm_runl_func gk104_runl = { .wait = nv50_runl_wait, .pending = gk104_runl_pending, + .block = gk104_runl_block, + .allow = gk104_runl_allow, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c index bcc78b35d4e2..134de3c71ad5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c @@ -62,6 +62,8 @@ const struct nvkm_runl_func gk110_runl = { .wait = nv50_runl_wait, .pending = gk104_runl_pending, + .block = gk104_runl_block, + .allow = gk104_runl_allow, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c index b6a2210f42c2..d3b2aa701f53 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c @@ -56,6 +56,8 @@ const struct nvkm_runl_func gm107_runl = { .wait = nv50_runl_wait, .pending = gk104_runl_pending, + .block = gk104_runl_block, + .allow = gk104_runl_allow, }; static const struct nvkm_enum diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c index b810175209d1..4dd3fb04d7e5 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c @@ -33,6 +33,8 @@ static const struct nvkm_runl_func gp100_runl = { .wait = nv50_runl_wait, .pending = gk104_runl_pending, + .block = gk104_runl_block, + .allow = gk104_runl_allow, }; static const struct nvkm_enum diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c index 34a8e792c0e8..6e74fdc0dc24 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c @@ -37,15 +37,12 @@ gv100_fifo_gpfifo_submit_token(struct nvkm_fifo_chan *chan) static int gv100_fifo_gpfifo_engine_valid(struct gk104_fifo_chan *chan, bool ce, bool valid) { - struct nvkm_subdev *subdev = &chan->base.fifo->engine.subdev; - struct nvkm_device *device = subdev->device; const u32 mask = ce ? 0x00020000 : 0x00010000; const u32 data = valid ? mask : 0x00000000; int ret; /* Block runlist to prevent the channel from being rescheduled. */ mutex_lock(&chan->fifo->base.mutex); - nvkm_mask(device, 0x002630, BIT(chan->runl), BIT(chan->runl)); /* Preempt the channel. */ ret = gk104_fifo_gpfifo_kick_locked(chan); @@ -57,7 +54,6 @@ gv100_fifo_gpfifo_engine_valid(struct gk104_fifo_chan *chan, bool ce, bool valid } /* Resume runlist. */ - nvkm_mask(device, 0x002630, BIT(chan->runl), 0); mutex_unlock(&chan->fifo->base.mutex); return ret; } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c index 7ad04e97a82d..c147c26b80ca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c @@ -86,6 +86,8 @@ static const struct nvkm_runl_func gv100_runl = { .wait = nv50_runl_wait, .pending = gk104_runl_pending, + .block = gk104_runl_block, + .allow = gk104_runl_allow, }; const struct nvkm_enum diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c index 85f22fce11ed..446e65dcb036 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c @@ -129,14 +129,13 @@ nv04_engn = { }; void -nv04_fifo_pause(struct nvkm_fifo *base, unsigned long *pflags) -__acquires(fifo->base.lock) +nv04_fifo_pause(struct nvkm_fifo *fifo, unsigned long *pflags) +__acquires(fifo->lock) { - struct nv04_fifo *fifo = nv04_fifo(base); - struct nvkm_device *device = fifo->base.engine.subdev.device; + struct nvkm_device *device = fifo->engine.subdev.device; unsigned long flags; - spin_lock_irqsave(&fifo->base.lock, flags); + spin_lock_irqsave(&fifo->lock, flags); *pflags = flags; nvkm_wr32(device, NV03_PFIFO_CACHES, 0x00000000); @@ -165,17 +164,16 @@ __acquires(fifo->base.lock) } void -nv04_fifo_start(struct nvkm_fifo *base, unsigned long *pflags) -__releases(fifo->base.lock) +nv04_fifo_start(struct nvkm_fifo *fifo, unsigned long *pflags) +__releases(fifo->lock) { - struct nv04_fifo *fifo = nv04_fifo(base); - struct nvkm_device *device = fifo->base.engine.subdev.device; + struct nvkm_device *device = fifo->engine.subdev.device; unsigned long flags = *pflags; nvkm_mask(device, NV04_PFIFO_CACHE1_PULL0, 0x00000001, 0x00000001); nvkm_wr32(device, NV03_PFIFO_CACHES, 0x00000001); - spin_unlock_irqrestore(&fifo->base.lock, flags); + spin_unlock_irqrestore(&fifo->lock, flags); } const struct nvkm_runl_func diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h index bab3cfbc5fcf..16fe77ee4c86 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h @@ -134,6 +134,8 @@ extern const struct nvkm_enum gk104_fifo_mmu_fault_gpcclient[]; void gk104_fifo_recover_chan(struct nvkm_fifo *, int); int gk104_fifo_engine_id(struct nvkm_fifo *, struct nvkm_engine *); bool gk104_runl_pending(struct nvkm_runl *); +void gk104_runl_block(struct nvkm_runl *, u32); +void gk104_runl_allow(struct nvkm_runl *, u32); extern const struct nvkm_runq_func gk104_runq; void gk104_runq_init(struct nvkm_runq *); bool gk104_runq_intr(struct nvkm_runq *, struct nvkm_runl *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c index 0e1d703456b6..438e884b8100 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c @@ -83,6 +83,34 @@ nvkm_runl_update_pending(struct nvkm_runl *runl) } void +nvkm_runl_allow(struct nvkm_runl *runl) +{ + struct nvkm_fifo *fifo = runl->fifo; + unsigned long flags; + + spin_lock_irqsave(&fifo->lock, flags); + if (!--runl->blocked) { + RUNL_TRACE(runl, "running"); + runl->func->allow(runl, ~0); + } + spin_unlock_irqrestore(&fifo->lock, flags); +} + +void +nvkm_runl_block(struct nvkm_runl *runl) +{ + struct nvkm_fifo *fifo = runl->fifo; + unsigned long flags; + + spin_lock_irqsave(&fifo->lock, flags); + if (!runl->blocked++) { + RUNL_TRACE(runl, "stopped"); + runl->func->block(runl, ~0); + } + spin_unlock_irqrestore(&fifo->lock, flags); +} + +void nvkm_runl_del(struct nvkm_runl *runl) { struct nvkm_engn *engn, *engt; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.h index 7682731c3af6..aebd8a750d38 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.h @@ -26,6 +26,8 @@ struct nvkm_runl { const struct nvkm_runl_func { int (*wait)(struct nvkm_runl *); bool (*pending)(struct nvkm_runl *); + void (*block)(struct nvkm_runl *, u32 engm); + void (*allow)(struct nvkm_runl *, u32 engm); } *func; struct nvkm_fifo *fifo; int id; @@ -44,6 +46,8 @@ struct nvkm_runl { int chan_nr; struct mutex mutex; + int blocked; + struct list_head head; }; @@ -52,6 +56,8 @@ struct nvkm_runl *nvkm_runl_get(struct nvkm_fifo *, int runi, u32 addr); struct nvkm_engn *nvkm_runl_add(struct nvkm_runl *, int engi, const struct nvkm_engn_func *, enum nvkm_subdev_type, int inst); void nvkm_runl_del(struct nvkm_runl *); +void nvkm_runl_block(struct nvkm_runl *); +void nvkm_runl_allow(struct nvkm_runl *); bool nvkm_runl_update_pending(struct nvkm_runl *); struct nvkm_chan *nvkm_runl_chan_get_chid(struct nvkm_runl *, int chid, unsigned long *irqflags); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c index f0564fa400b7..7d3c9d8e54a7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c @@ -68,6 +68,8 @@ static const struct nvkm_runl_func tu102_runl = { .wait = nv50_runl_wait, .pending = tu102_runl_pending, + .block = gk104_runl_block, + .allow = gk104_runl_allow, }; static const struct nvkm_enum |