diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2022-06-01 13:47:29 +0300 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2022-11-09 03:44:48 +0300 |
commit | c358f53871605a1a8d7ed6e544a05ea00e9c80cb (patch) | |
tree | 06a86e76b7cd8c8761f159558d450744eb7a9614 /drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c | |
parent | e43c872c03a9ad56f5cbc52149b4454601aa6904 (diff) | |
download | linux-c358f53871605a1a8d7ed6e544a05ea00e9c80cb.tar.xz |
drm/nouveau/fifo: add new channel lookup interfaces
- supports per-runlist CHIDs
- channel group lock held across reference, rather than global lock
v2:
- remove unnecessary parenthesis
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c index 0b75565bfbc1..e4984e1e7c65 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.c @@ -20,12 +20,59 @@ * OTHER DEALINGS IN THE SOFTWARE. */ #include "runl.h" +#include "cgrp.h" #include "chan.h" #include "chid.h" #include "priv.h" +#include <core/gpuobj.h> #include <subdev/top.h> +struct nvkm_chan * +nvkm_runl_chan_get_inst(struct nvkm_runl *runl, u64 inst, unsigned long *pirqflags) +{ + struct nvkm_chid *chid = runl->chid; + struct nvkm_chan *chan; + unsigned long flags; + int id; + + spin_lock_irqsave(&chid->lock, flags); + for_each_set_bit(id, chid->used, chid->nr) { + chan = chid->data[id]; + if (likely(chan)) { + if (chan->inst->addr == inst) { + spin_lock(&chan->cgrp->lock); + *pirqflags = flags; + spin_unlock(&chid->lock); + return chan; + } + } + } + spin_unlock_irqrestore(&chid->lock, flags); + return NULL; +} + +struct nvkm_chan * +nvkm_runl_chan_get_chid(struct nvkm_runl *runl, int id, unsigned long *pirqflags) +{ + struct nvkm_chid *chid = runl->chid; + struct nvkm_chan *chan; + unsigned long flags; + + spin_lock_irqsave(&chid->lock, flags); + if (!WARN_ON(id >= chid->nr)) { + chan = chid->data[id]; + if (likely(chan)) { + spin_lock(&chan->cgrp->lock); + *pirqflags = flags; + spin_unlock(&chid->lock); + return chan; + } + } + spin_unlock_irqrestore(&chid->lock, flags); + return NULL; +} + void nvkm_runl_del(struct nvkm_runl *runl) { |