[Nouveau] [PATCH 08/10] drm/nouveau/fifo/ga100-: add per-runlist nonstall intr handling

Karol Herbst kherbst at redhat.com
Tue Jun 13 21:41:59 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>
>
> GSP-RM will enforce this, so implement on HW too so we can share code.
>
> Signed-off-by: Ben Skeggs <bskeggs at redhat.com>
> ---
>  .../drm/nouveau/include/nvkm/core/engine.h    |  1 +
>  .../gpu/drm/nouveau/nvkm/engine/ce/ga100.c    | 10 ++++
>  .../gpu/drm/nouveau/nvkm/engine/ce/ga102.c    |  1 +
>  drivers/gpu/drm/nouveau/nvkm/engine/ce/priv.h |  1 +
>  .../gpu/drm/nouveau/nvkm/engine/fifo/base.c   | 32 +++++-----
>  .../gpu/drm/nouveau/nvkm/engine/fifo/ga100.c  | 59 +++++++++++++++----
>  .../gpu/drm/nouveau/nvkm/engine/fifo/runl.h   |  6 ++
>  .../gpu/drm/nouveau/nvkm/engine/fifo/uchan.c  |  2 +-
>  drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c | 12 ++++
>  .../gpu/drm/nouveau/nvkm/engine/gr/ga102.c    |  7 +++
>  .../gpu/drm/nouveau/nvkm/engine/gr/gf100.c    | 12 ++++
>  .../gpu/drm/nouveau/nvkm/engine/gr/gf100.h    |  1 +
>  drivers/gpu/drm/nouveau/nvkm/engine/gr/priv.h |  1 +
>  13 files changed, 116 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h b/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h
> index 8041fe03237e..738899fcf30b 100644
> --- a/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h
> +++ b/drivers/gpu/drm/nouveau/include/nvkm/core/engine.h
> @@ -22,6 +22,7 @@ struct nvkm_engine_func {
>         int (*init)(struct nvkm_engine *);
>         int (*fini)(struct nvkm_engine *, bool suspend);
>         int (*reset)(struct nvkm_engine *);
> +       int (*nonstall)(struct nvkm_engine *);
>         void (*intr)(struct nvkm_engine *);
>         void (*tile)(struct nvkm_engine *, int region, struct nvkm_fb_tile *);
>         bool (*chsw_load)(struct nvkm_engine *);
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga100.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga100.c
> index 6648ed62daa6..315a69f7fdd1 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga100.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga100.c
> @@ -35,6 +35,15 @@ ga100_ce_intr(struct nvkm_inth *inth)
>         return IRQ_NONE;
>  }
>
> +int
> +ga100_ce_nonstall(struct nvkm_engine *engine)
> +{
> +       struct nvkm_subdev *subdev = &engine->subdev;
> +       struct nvkm_device *device = subdev->device;
> +
> +       return nvkm_rd32(device, 0x104424 + (subdev->inst * 0x80)) & 0x00000fff;
> +}
> +
>  int
>  ga100_ce_fini(struct nvkm_engine *engine, bool suspend)
>  {
> @@ -67,6 +76,7 @@ ga100_ce = {
>         .oneinit = ga100_ce_oneinit,
>         .init = ga100_ce_init,
>         .fini = ga100_ce_fini,
> +       .nonstall = ga100_ce_nonstall,
>         .cclass = &gv100_ce_cclass,
>         .sclass = {
>                 { -1, -1, AMPERE_DMA_COPY_A },
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga102.c
> index 9f3448ad625f..461b73c7e2e0 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga102.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/ga102.c
> @@ -28,6 +28,7 @@ ga102_ce = {
>         .oneinit = ga100_ce_oneinit,
>         .init = ga100_ce_init,
>         .fini = ga100_ce_fini,
> +       .nonstall = ga100_ce_nonstall,
>         .cclass = &gv100_ce_cclass,
>         .sclass = {
>                 { -1, -1, AMPERE_DMA_COPY_A },
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/ce/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/ce/priv.h
> index 53ba2abe0bf5..0be72c463b21 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/ce/priv.h
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/ce/priv.h
> @@ -12,4 +12,5 @@ extern const struct nvkm_object_func gv100_ce_cclass;
>  int ga100_ce_oneinit(struct nvkm_engine *);
>  int ga100_ce_init(struct nvkm_engine *);
>  int ga100_ce_fini(struct nvkm_engine *, bool);
> +int ga100_ce_nonstall(struct nvkm_engine *);
>  #endif
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
> index 5ea9a2ff0663..5db37247dc29 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
> @@ -283,11 +283,21 @@ nvkm_fifo_oneinit(struct nvkm_engine *engine)
>         }
>
>         /* Initialise non-stall intr handling. */
> -       if (fifo->func->nonstall_ctor) {
> -               ret = fifo->func->nonstall_ctor(fifo);
> -               if (ret) {
> -                       nvkm_error(subdev, "nonstall %d\n", ret);
> +       if (fifo->func->nonstall) {
> +               if (fifo->func->nonstall_ctor) {
> +                       ret = fifo->func->nonstall_ctor(fifo);
> +                       if (ret < 0) {
> +                               nvkm_error(subdev, "nonstall %d\n", ret);
> +                               return ret;
> +                       }
> +               } else {
> +                       ret = 1;
>                 }
> +
> +               ret = nvkm_event_init(fifo->func->nonstall, &fifo->engine.subdev, 1, ret,
> +                                     &fifo->nonstall.event);
> +               if (ret)
> +                       return ret;
>         }
>
>         /* Allocate USERD + BAR1 polling area. */
> @@ -358,7 +368,6 @@ nvkm_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device,
>                enum nvkm_subdev_type type, int inst, struct nvkm_fifo **pfifo)
>  {
>         struct nvkm_fifo *fifo;
> -       int ret;
>
>         if (!(fifo = *pfifo = kzalloc(sizeof(*fifo), GFP_KERNEL)))
>                 return -ENOMEM;
> @@ -374,16 +383,5 @@ nvkm_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device,
>         spin_lock_init(&fifo->lock);
>         mutex_init(&fifo->mutex);
>
> -       ret = nvkm_engine_ctor(&nvkm_fifo, device, type, inst, true, &fifo->engine);
> -       if (ret)
> -               return ret;
> -
> -       if (func->nonstall) {
> -               ret = nvkm_event_init(func->nonstall, &fifo->engine.subdev, 1, 1,
> -                                     &fifo->nonstall.event);
> -               if (ret)
> -                       return ret;
> -       }
> -
> -       return 0;
> +       return nvkm_engine_ctor(&nvkm_fifo, device, type, inst, true, &fifo->engine);
>  }
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga100.c
> index a729f8b7f0da..c56d2a839efb 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga100.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/ga100.c
> @@ -32,9 +32,6 @@
>
>  #include <nvif/class.h>
>
> -/*TODO: allocate? */
> -#define GA100_FIFO_NONSTALL_VECTOR 0
> -
>  static u32
>  ga100_chan_doorbell_handle(struct nvkm_chan *chan)
>  {
> @@ -83,7 +80,7 @@ ga100_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm,
>         nvkm_wo32(chan->inst, 0x0e4, priv ? 0x00000020 : 0x00000000);
>         nvkm_wo32(chan->inst, 0x0e8, chan->id);
>         nvkm_wo32(chan->inst, 0x0f4, 0x00001000 | (priv ? 0x00000100 : 0x00000000));
> -       nvkm_wo32(chan->inst, 0x0f8, 0x80000000 | GA100_FIFO_NONSTALL_VECTOR);
> +       nvkm_wo32(chan->inst, 0x0f8, 0x80000000 | chan->cgrp->runl->nonstall.vector);
>         nvkm_mo32(chan->inst, 0x218, 0x00000000, 0x00000000);
>         nvkm_done(chan->inst);
>         return 0;
> @@ -148,8 +145,20 @@ ga100_engn_cxid(struct nvkm_engn *engn, bool *cgid)
>         return -ENODEV;
>  }
>
> +static int
> +ga100_engn_nonstall(struct nvkm_engn *engn)
> +{
> +       struct nvkm_engine *engine = engn->engine;
> +
> +       if (WARN_ON(!engine->func->nonstall))
> +               return -EINVAL;
> +
> +       return engine->func->nonstall(engine);
> +}
> +
>  const struct nvkm_engn_func
>  ga100_engn = {
> +       .nonstall = ga100_engn_nonstall,
>         .cxid = ga100_engn_cxid,
>         .ctor = gk104_ectx_ctor,
>         .bind = gv100_ectx_bind,
> @@ -157,6 +166,7 @@ ga100_engn = {
>
>  const struct nvkm_engn_func
>  ga100_engn_ce = {
> +       .nonstall = ga100_engn_nonstall,
>         .cxid = ga100_engn_cxid,
>         .ctor = gv100_ectx_ce_ctor,
>         .bind = gv100_ectx_ce_bind,
> @@ -470,6 +480,11 @@ ga100_runl_new(struct nvkm_fifo *fifo, int id, u32 addr, struct nvkm_runl **prun
>                                      tdev->type, tdev->inst);
>                 if (!engn)
>                         return -EINVAL;
> +
> +               if (!engn->engine->func->nonstall) {
> +                       RUNL_DEBUG(runl, "engn %s !nonstall", engn->engine->subdev.name);
> +                       return -EINVAL;
> +               }
>         }
>
>         if (list_empty(&runl->engns)) {
> @@ -492,9 +507,9 @@ ga100_runl_new(struct nvkm_fifo *fifo, int id, u32 addr, struct nvkm_runl **prun
>  static irqreturn_t
>  ga100_fifo_nonstall_intr(struct nvkm_inth *inth)
>  {
> -       struct nvkm_fifo *fifo = container_of(inth, typeof(*fifo), nonstall.intr);
> +       struct nvkm_runl *runl = container_of(inth, typeof(*runl), nonstall.inth);
>
> -       nvkm_event_ntfy(&fifo->nonstall.event, 0, NVKM_FIFO_NONSTALL_EVENT);
> +       nvkm_event_ntfy(&runl->fifo->nonstall.event, runl->id, NVKM_FIFO_NONSTALL_EVENT);
>         return IRQ_HANDLED;
>  }
>
> @@ -502,16 +517,18 @@ static void
>  ga100_fifo_nonstall_block(struct nvkm_event *event, int type, int index)
>  {
>         struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), nonstall.event);
> +       struct nvkm_runl *runl = nvkm_runl_get(fifo, index, 0);
>
> -       nvkm_inth_block(&fifo->nonstall.intr);
> +       nvkm_inth_block(&runl->nonstall.inth);
>  }
>
>  static void
>  ga100_fifo_nonstall_allow(struct nvkm_event *event, int type, int index)
>  {
>         struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), nonstall.event);
> +       struct nvkm_runl *runl = nvkm_runl_get(fifo, index, 0);
>
> -       nvkm_inth_allow(&fifo->nonstall.intr);
> +       nvkm_inth_allow(&runl->nonstall.inth);
>  }
>
>  const struct nvkm_event_func
> @@ -523,9 +540,29 @@ ga100_fifo_nonstall = {
>  int
>  ga100_fifo_nonstall_ctor(struct nvkm_fifo *fifo)
>  {
> -       return nvkm_inth_add(&fifo->engine.subdev.device->vfn->intr, GA100_FIFO_NONSTALL_VECTOR,
> -                            NVKM_INTR_PRIO_NORMAL, &fifo->engine.subdev, ga100_fifo_nonstall_intr,
> -                            &fifo->nonstall.intr);
> +       struct nvkm_subdev *subdev = &fifo->engine.subdev;
> +       struct nvkm_vfn *vfn = subdev->device->vfn;
> +       struct nvkm_runl *runl;
> +       int ret, nr = 0;
> +
> +       nvkm_runl_foreach(runl, fifo) {
> +               struct nvkm_engn *engn = list_first_entry(&runl->engns, typeof(*engn), head);
> +
> +               runl->nonstall.vector = engn->func->nonstall(engn);
> +               if (runl->nonstall.vector < 0) {
> +                       RUNL_ERROR(runl, "nonstall %d", runl->nonstall.vector);
> +                       return runl->nonstall.vector;
> +               }
> +
> +               ret = nvkm_inth_add(&vfn->intr, runl->nonstall.vector, NVKM_INTR_PRIO_NORMAL,
> +                                   subdev, ga100_fifo_nonstall_intr, &runl->nonstall.inth);
> +               if (ret)
> +                       return ret;
> +
> +               nr = max(nr, runl->id + 1);
> +       }
> +
> +       return nr;
>  }
>
>  int
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.h
> index c93d21bb7bd5..5421321f8e85 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.h
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/runl.h
> @@ -11,6 +11,7 @@ enum nvkm_subdev_type;
>
>  struct nvkm_engn {
>         const struct nvkm_engn_func {
> +               int (*nonstall)(struct nvkm_engn *);
>                 bool (*chsw)(struct nvkm_engn *);
>                 int (*cxid)(struct nvkm_engn *, bool *cgid);
>                 void (*mmu_fault_trigger)(struct nvkm_engn *);
> @@ -69,6 +70,11 @@ struct nvkm_runl {
>
>         struct nvkm_inth inth;
>
> +       struct {
> +               int vector;
> +               struct nvkm_inth inth;
> +       } nonstall;
> +
>         struct list_head cgrps;
>         int cgrp_nr;
>         int chan_nr;
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c
> index 1dac95ae7b43..04140e0110be 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/uchan.c
> @@ -52,7 +52,7 @@ nvkm_uchan_uevent(struct nvkm_object *object, void *argv, u32 argc, struct nvkm_
>
>         switch (args->v0.type) {
>         case NVIF_CHAN_EVENT_V0_NON_STALL_INTR:
> -               return nvkm_uevent_add(uevent, &runl->fifo->nonstall.event, 0,
> +               return nvkm_uevent_add(uevent, &runl->fifo->nonstall.event, runl->id,
>                                        NVKM_FIFO_NONSTALL_EVENT, NULL);
>         case NVIF_CHAN_EVENT_V0_KILLED:
>                 return nvkm_uevent_add(uevent, &runl->chid->event, chan->id,
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c
> index 5653fbf785e1..0096ad401b15 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/base.c
> @@ -125,6 +125,17 @@ nvkm_gr_intr(struct nvkm_engine *engine)
>         gr->func->intr(gr);
>  }
>
> +static int
> +nvkm_gr_nonstall(struct nvkm_engine *engine)
> +{
> +       struct nvkm_gr *gr = nvkm_gr(engine);
> +
> +       if (gr->func->nonstall)
> +               return gr->func->nonstall(gr);
> +
> +       return -EINVAL;
> +}
> +
>  static int
>  nvkm_gr_oneinit(struct nvkm_engine *engine)
>  {
> @@ -177,6 +188,7 @@ nvkm_gr = {
>         .init = nvkm_gr_init,
>         .fini = nvkm_gr_fini,
>         .reset = nvkm_gr_reset,
> +       .nonstall = nvkm_gr_nonstall,
>         .intr = nvkm_gr_intr,
>         .tile = nvkm_gr_tile,
>         .chsw_load = nvkm_gr_chsw_load,
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ga102.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ga102.c
> index a5b5ac2755a2..00cd70abad67 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/ga102.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/ga102.c
> @@ -137,8 +137,15 @@ ga102_gr_oneinit_intr(struct gf100_gr *gr, enum nvkm_intr_type *pvector)
>         return &device->vfn->intr;
>  }
>
> +static int
> +ga102_gr_nonstall(struct gf100_gr *gr)
> +{
> +       return nvkm_rd32(gr->base.engine.subdev.device, 0x400160) & 0x00000fff;
> +}
> +
>  static const struct gf100_gr_func
>  ga102_gr = {
> +       .nonstall = ga102_gr_nonstall,
>         .oneinit_intr = ga102_gr_oneinit_intr,
>         .oneinit_tiles = gm200_gr_oneinit_tiles,
>         .oneinit_sm_id = gv100_gr_oneinit_sm_id,
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
> index 29afec9a55bf..3648868bb9fc 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
> @@ -2494,12 +2494,24 @@ gf100_gr_gpccs_ucode = {
>         .data.size = sizeof(gf100_grgpc_data),
>  };
>
> +static int
> +gf100_gr_nonstall(struct nvkm_gr *base)
> +{
> +       struct gf100_gr *gr = gf100_gr(base);
> +
> +       if (gr->func->nonstall)
> +               return gr->func->nonstall(gr);
> +
> +       return -EINVAL;
> +}
> +
>  static const struct nvkm_gr_func
>  gf100_gr_ = {
>         .dtor = gf100_gr_dtor,
>         .oneinit = gf100_gr_oneinit,
>         .init = gf100_gr_init_,
>         .fini = gf100_gr_fini,
> +       .nonstall = gf100_gr_nonstall,
>         .reset = gf100_gr_reset,
>         .units = gf100_gr_units,
>         .chan_new = gf100_gr_chan_new,
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
> index 94ca7ac16acf..54f686ba39ac 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.h
> @@ -147,6 +147,7 @@ struct gf100_gr_func_zbc {
>  };
>
>  struct gf100_gr_func {
> +       int (*nonstall)(struct gf100_gr *);
>         struct nvkm_intr *(*oneinit_intr)(struct gf100_gr *, enum nvkm_intr_type *);
>         void (*oneinit_tiles)(struct gf100_gr *);
>         int (*oneinit_sm_id)(struct gf100_gr *);
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/gr/priv.h
> index 6ec8b94854c0..0884abc73a9d 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/priv.h
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/priv.h
> @@ -18,6 +18,7 @@ struct nvkm_gr_func {
>         int (*init)(struct nvkm_gr *);
>         int (*fini)(struct nvkm_gr *, bool);
>         int (*reset)(struct nvkm_gr *);
> +       int (*nonstall)(struct nvkm_gr *);
>         void (*intr)(struct nvkm_gr *);
>         void (*tile)(struct nvkm_gr *, int region, struct nvkm_fb_tile *);
>         int (*tlb_flush)(struct nvkm_gr *);
> --
> 2.40.1
>

Reviewed-by: Karol Herbst <kherbst at redhat.com>



More information about the Nouveau mailing list