On Thu, May 25, 2023 at 2:31 AM Ben Skeggs <skeggsb@xxxxxxxxx> wrote: > > From: Ben Skeggs <bskeggs@xxxxxxxxxx> > > We're adding better support for the non-stall interrupt, which will need > to fetch the interrupt vector from the runlist's primary engine. > > NVKM doesn't support all target engines (ie. NVDEC etc), and it wouldn't > be ideal to completely fail initialisation in this case. > > Instead. Remove runlists where we can't determine all the needed info. > > Signed-off-by: Ben Skeggs <bskeggs@xxxxxxxxxx> > --- > .../gpu/drm/nouveau/nvkm/engine/fifo/ga100.c | 46 ++++++++++++++----- > 1 file changed, 35 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga100.c > index 12a5d99d5e77..a729f8b7f0da 100644 > --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga100.c > +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga100.c > @@ -429,7 +429,9 @@ static int > ga100_runl_new(struct nvkm_fifo *fifo, int id, u32 addr, struct nvkm_runl **prunl) > { > struct nvkm_device *device = fifo->engine.subdev.device; > + struct nvkm_top_device *tdev; > struct nvkm_runl *runl; > + struct nvkm_engn *engn; > u32 chcfg = nvkm_rd32(device, addr + 0x004); > u32 chnum = 1 << (chcfg & 0x0000000f); > u32 chaddr = (chcfg & 0xfffffff0); > @@ -437,26 +439,50 @@ ga100_runl_new(struct nvkm_fifo *fifo, int id, u32 addr, struct nvkm_runl **prun > u32 vector = nvkm_rd32(device, addr + 0x160); > int i, ret; > > - runl = *prunl = nvkm_runl_new(fifo, id, addr, chnum); > + runl = nvkm_runl_new(fifo, id, addr, chnum); > if (IS_ERR(runl)) > return PTR_ERR(runl); > > + *prunl = runl; > + > for (i = 0; i < 2; i++) { > u32 pbcfg = nvkm_rd32(device, addr + 0x010 + (i * 0x04)); > if (pbcfg & 0x80000000) { > runl->runq[runl->runq_nr] = > nvkm_runq_new(fifo, ((pbcfg & 0x03fffc00) - 0x040000) / 0x800); > - if (!runl->runq[runl->runq_nr]) > + if (!runl->runq[runl->runq_nr]) { > + RUNL_ERROR(runl, "runq %d", runl->runq_nr); > return -ENOMEM; > + } > > runl->runq_nr++; > } > } > > + nvkm_list_foreach(tdev, &device->top->device, head, tdev->runlist == runl->addr) { > + if (tdev->engine < 0) { > + RUNL_DEBUG(runl, "engn !top"); > + return -EINVAL; > + } > + > + engn = nvkm_runl_add(runl, tdev->engine, (tdev->type == NVKM_ENGINE_CE) ? > + fifo->func->engn_ce : fifo->func->engn, > + tdev->type, tdev->inst); > + if (!engn) > + return -EINVAL; > + } > + > + if (list_empty(&runl->engns)) { > + RUNL_DEBUG(runl, "!engns"); > + return -EINVAL; > + } > + > ret = nvkm_inth_add(&device->vfn->intr, vector & 0x00000fff, NVKM_INTR_PRIO_NORMAL, > &fifo->engine.subdev, ga100_runl_intr, &runl->inth); > - if (ret) > + if (ret) { > + RUNL_ERROR(runl, "inth %d", ret); > return ret; > + } > > runl->chan = chaddr; > runl->doorbell = dbcfg >> 16; > @@ -514,15 +540,13 @@ ga100_fifo_runl_ctor(struct nvkm_fifo *fifo) > runl = nvkm_runl_get(fifo, -1, tdev->runlist); > if (!runl) { > ret = ga100_runl_new(fifo, id++, tdev->runlist, &runl); > - if (ret) > - return ret; > - } > - > - if (tdev->engine < 0) > - continue; > + if (ret) { > + if (runl) > + nvkm_runl_del(runl); > > - nvkm_runl_add(runl, tdev->engine, (tdev->type == NVKM_ENGINE_CE) ? > - fifo->func->engn_ce : fifo->func->engn, tdev->type, tdev->inst); > + continue; > + } > + } > } > > return 0; > -- > 2.40.1 > Reviewed-by: Karol Herbst <kherbst@xxxxxxxxxx>