[Nouveau] [PATCH 07/10] drm/nouveau/fifo/ga100-: remove individual runlists rather than failing oneinit
Karol Herbst
kherbst at redhat.com
Tue Jun 13 21:35:07 UTC 2023
On Thu, May 25, 2023 at 2:31 AM Ben Skeggs <skeggsb at gmail.com> wrote:
>
> From: Ben Skeggs <bskeggs at redhat.com>
>
> 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 at redhat.com>
> ---
> .../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 at redhat.com>
More information about the Nouveau
mailing list