drm/nouveau/fifo: expose runlist topology info on all chipsets
authorBen Skeggs <bskeggs@redhat.com>
Wed, 1 Jun 2022 10:47:25 +0000 (20:47 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 9 Nov 2022 00:44:47 +0000 (10:44 +1000)
Previously only available from Kepler onwards.

- also fixes the info() queries causing fifo init()/fini() unnecessarily

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
17 files changed:
drivers/gpu/drm/nouveau/nouveau_abi16.c
drivers/gpu/drm/nouveau/nouveau_chan.c
drivers/gpu/drm/nouveau/nouveau_chan.h
drivers/gpu/drm/nouveau/nouveau_drm.c
drivers/gpu/drm/nouveau/nvkm/core/engine.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c

index 5bee655..9237ef3 100644 (file)
@@ -253,7 +253,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
        struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
        struct nouveau_abi16_chan *chan;
        struct nvif_device *device;
-       u64 engine;
+       u64 engine, runm;
        int ret;
 
        if (unlikely(!abi16))
@@ -263,6 +263,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
                return nouveau_abi16_put(abi16, -ENODEV);
 
        device = &abi16->device;
+       engine = NV_DEVICE_HOST_RUNLIST_ENGINES_GR;
 
        /* hack to allow channel engine type specification on kepler */
        if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
@@ -276,19 +277,18 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
                        default:
                                return nouveau_abi16_put(abi16, -ENOSYS);
                        }
-               } else {
-                       engine = NV_DEVICE_HOST_RUNLIST_ENGINES_GR;
-               }
 
-               if (engine != NV_DEVICE_HOST_RUNLIST_ENGINES_CE)
-                       engine = nvif_fifo_runlist(device, engine);
-               else
-                       engine = nvif_fifo_runlist_ce(device);
-               init->fb_ctxdma_handle = engine;
-               init->tt_ctxdma_handle = 0;
+                       init->fb_ctxdma_handle = 0;
+                       init->tt_ctxdma_handle = 0;
+               }
        }
 
-       if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
+       if (engine != NV_DEVICE_HOST_RUNLIST_ENGINES_CE)
+               runm = nvif_fifo_runlist(device, engine);
+       else
+               runm = nvif_fifo_runlist_ce(device);
+
+       if (!runm || init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
                return nouveau_abi16_put(abi16, -EINVAL);
 
        /* allocate "abi16 channel" data and make up a handle for it */
@@ -300,8 +300,8 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
        list_add(&chan->head, &abi16->channels);
 
        /* create channel object and initialise dma and fence management */
-       ret = nouveau_channel_new(drm, device, init->fb_ctxdma_handle,
-                                 init->tt_ctxdma_handle, false, &chan->chan);
+       ret = nouveau_channel_new(drm, device, false, runm, init->fb_ctxdma_handle,
+                                 init->tt_ctxdma_handle, &chan->chan);
        if (ret)
                goto done;
 
index 497d889..3b5cbb6 100644 (file)
@@ -513,14 +513,13 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
 
 int
 nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
-                   u32 arg0, u32 arg1, bool priv,
-                   struct nouveau_channel **pchan)
+                   bool priv, u64 runm, u32 vram, u32 gart, struct nouveau_channel **pchan)
 {
        struct nouveau_cli *cli = (void *)device->object.client;
        int ret;
 
        /* hack until fencenv50 is fixed, and agp access relaxed */
-       ret = nouveau_channel_ind(drm, device, arg0, priv, pchan);
+       ret = nouveau_channel_ind(drm, device, runm, priv, pchan);
        if (ret) {
                NV_PRINTK(dbg, cli, "ib channel create, %d\n", ret);
                ret = nouveau_channel_dma(drm, device, pchan);
@@ -530,7 +529,7 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
                }
        }
 
-       ret = nouveau_channel_init(*pchan, arg0, arg1);
+       ret = nouveau_channel_init(*pchan, vram, gart);
        if (ret) {
                NV_PRINTK(err, cli, "channel failed to initialise, %d\n", ret);
                nouveau_channel_del(pchan);
index 195b38c..7ffee79 100644 (file)
@@ -56,9 +56,8 @@ struct nouveau_channel {
 
 int nouveau_channels_init(struct nouveau_drm *);
 
-int  nouveau_channel_new(struct nouveau_drm *, struct nvif_device *,
-                        u32 arg0, u32 arg1, bool priv,
-                        struct nouveau_channel **);
+int  nouveau_channel_new(struct nouveau_drm *, struct nvif_device *, bool priv, u64 runm,
+                        u32 vram, u32 gart, struct nouveau_channel **);
 void nouveau_channel_del(struct nouveau_channel **);
 int  nouveau_channel_idle(struct nouveau_channel *);
 
index 9df276b..1812ffd 100644 (file)
@@ -316,28 +316,19 @@ static void
 nouveau_accel_ce_init(struct nouveau_drm *drm)
 {
        struct nvif_device *device = &drm->client.device;
+       u64 runm;
        int ret = 0;
 
        /* Allocate channel that has access to a (preferably async) copy
         * engine, to use for TTM buffer moves.
         */
-       if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
-               ret = nouveau_channel_new(drm, device,
-                                         nvif_fifo_runlist_ce(device), 0,
-                                         true, &drm->cechan);
-       } else
-       if (device->info.chipset >= 0xa3 &&
-           device->info.chipset != 0xaa &&
-           device->info.chipset != 0xac) {
-               /* Prior to Kepler, there's only a single runlist, so all
-                * engines can be accessed from any channel.
-                *
-                * We still want to use a separate channel though.
-                */
-               ret = nouveau_channel_new(drm, device, NvDmaFB, NvDmaTT, false,
-                                         &drm->cechan);
+       runm = nvif_fifo_runlist_ce(device);
+       if (!runm) {
+               NV_DEBUG(drm, "no ce runlist\n");
+               return;
        }
 
+       ret = nouveau_channel_new(drm, device, false, runm, NvDmaFB, NvDmaTT, &drm->cechan);
        if (ret)
                NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
 }
@@ -355,23 +346,20 @@ static void
 nouveau_accel_gr_init(struct nouveau_drm *drm)
 {
        struct nvif_device *device = &drm->client.device;
-       u32 arg0, arg1;
+       u64 runm;
        int ret;
 
        if (device->info.family >= NV_DEVICE_INFO_V0_AMPERE)
                return;
 
        /* Allocate channel that has access to the graphics engine. */
-       if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
-               arg0 = nvif_fifo_runlist(device, NV_DEVICE_HOST_RUNLIST_ENGINES_GR);
-               arg1 = 1;
-       } else {
-               arg0 = NvDmaFB;
-               arg1 = NvDmaTT;
+       runm = nvif_fifo_runlist(device, NV_DEVICE_HOST_RUNLIST_ENGINES_GR);
+       if (!runm) {
+               NV_DEBUG(drm, "no gr runlist\n");
+               return;
        }
 
-       ret = nouveau_channel_new(drm, device, arg0, arg1, false,
-                                 &drm->channel);
+       ret = nouveau_channel_new(drm, device, false, runm, NvDmaFB, NvDmaTT, &drm->channel);
        if (ret) {
                NV_ERROR(drm, "failed to create kernel channel, %d\n", ret);
                nouveau_accel_gr_fini(drm);
index 558bd10..964615a 100644 (file)
@@ -80,14 +80,10 @@ static int
 nvkm_engine_info(struct nvkm_subdev *subdev, u64 mthd, u64 *data)
 {
        struct nvkm_engine *engine = nvkm_engine(subdev);
-       if (engine->func->info) {
-               if (!IS_ERR((engine = nvkm_engine_ref(engine)))) {
-                       int ret = engine->func->info(engine, mthd, data);
-                       nvkm_engine_unref(&engine);
-                       return ret;
-               }
-               return PTR_ERR(engine);
-       }
+
+       if (engine->func->info)
+               return engine->func->info(engine, mthd, data);
+
        return -ENOSYS;
 }
 
index 60d5cbb..2ccc0b3 100644 (file)
@@ -221,12 +221,57 @@ static int
 nvkm_fifo_info(struct nvkm_engine *engine, u64 mthd, u64 *data)
 {
        struct nvkm_fifo *fifo = nvkm_fifo(engine);
+       struct nvkm_runl *runl;
+       struct nvkm_engn *engn;
+       int ret;
+
+       ret = nvkm_subdev_oneinit(&fifo->engine.subdev);
+       if (ret)
+               return ret;
 
        switch (mthd) {
        case NV_DEVICE_HOST_CHANNELS: *data = fifo->chid ? fifo->chid->nr : 0; return 0;
+       case NV_DEVICE_HOST_RUNLISTS:
+               *data = 0;
+               nvkm_runl_foreach(runl, fifo)
+                       *data |= BIT(runl->id);
+               return 0;
+       case NV_DEVICE_HOST_RUNLIST_ENGINES:
+               runl = nvkm_runl_get(fifo, *data, 0);
+               if (runl) {
+                       *data = 0;
+                       nvkm_runl_foreach_engn(engn, runl) {
+#define CASE(n) case NVKM_ENGINE_##n: *data |= NV_DEVICE_HOST_RUNLIST_ENGINES_##n; break
+                               switch (engn->engine->subdev.type) {
+                               case NVKM_ENGINE_DMAOBJ:
+                                       break;
+                               CASE(SW    );
+                               CASE(GR    );
+                               CASE(MPEG  );
+                               CASE(ME    );
+                               CASE(CIPHER);
+                               CASE(BSP   );
+                               CASE(VP    );
+                               CASE(CE    );
+                               CASE(SEC   );
+                               CASE(MSVLD );
+                               CASE(MSPDEC);
+                               CASE(MSPPP );
+                               CASE(MSENC );
+                               CASE(VIC   );
+                               CASE(SEC2  );
+                               CASE(NVDEC );
+                               CASE(NVENC );
+                               default:
+                                       WARN_ON(1);
+                                       break;
+                               }
+#undef CASE
+                       }
+                       return 0;
+               }
+               return -EINVAL;
        default:
-               if (fifo->func->info)
-                       return fifo->func->info(fifo, mthd, data);
                break;
        }
 
index eaf61c0..b41481c 100644 (file)
@@ -39,7 +39,6 @@
 #include <engine/sw.h>
 
 #include <nvif/class.h>
-#include <nvif/cl0080.h>
 
 static const struct nvkm_chan_func
 gk104_chan = {
@@ -991,56 +990,6 @@ gk104_fifo_fini(struct nvkm_fifo *base)
        nvkm_mask(device, 0x002140, 0x10000000, 0x10000000);
 }
 
-int
-gk104_fifo_info(struct nvkm_fifo *base, u64 mthd, u64 *data)
-{
-       struct gk104_fifo *fifo = gk104_fifo(base);
-       switch (mthd) {
-       case NV_DEVICE_HOST_RUNLISTS:
-               *data = (1ULL << fifo->runlist_nr) - 1;
-               return 0;
-       case NV_DEVICE_HOST_RUNLIST_ENGINES: {
-               if (*data < fifo->runlist_nr) {
-                       unsigned long engm = fifo->runlist[*data].engm;
-                       struct nvkm_engine *engine;
-                       int engn;
-                       *data = 0;
-                       for_each_set_bit(engn, &engm, fifo->engine_nr) {
-                               if ((engine = fifo->engine[engn].engine)) {
-#define CASE(n) case NVKM_ENGINE_##n: *data |= NV_DEVICE_HOST_RUNLIST_ENGINES_##n; break
-                                       switch (engine->subdev.type) {
-                                       CASE(SW    );
-                                       CASE(GR    );
-                                       CASE(MPEG  );
-                                       CASE(ME    );
-                                       CASE(CIPHER);
-                                       CASE(BSP   );
-                                       CASE(VP    );
-                                       CASE(CE    );
-                                       CASE(SEC   );
-                                       CASE(MSVLD );
-                                       CASE(MSPDEC);
-                                       CASE(MSPPP );
-                                       CASE(MSENC );
-                                       CASE(VIC   );
-                                       CASE(SEC2  );
-                                       CASE(NVDEC );
-                                       CASE(NVENC );
-                                       default:
-                                               WARN_ON(1);
-                                               break;
-                                       }
-                               }
-                       }
-                       return 0;
-               }
-       }
-               return -EINVAL;
-       default:
-               return -EINVAL;
-       }
-}
-
 void
 gk104_fifo_init(struct nvkm_fifo *base)
 {
@@ -1225,7 +1174,6 @@ gk104_fifo = {
        .chid_ctor = gf100_fifo_chid_ctor,
        .runq_nr = gf100_fifo_runq_nr,
        .runl_ctor = gk104_fifo_runl_ctor,
-       .info = gk104_fifo_info,
        .init = gk104_fifo_init,
        .fini = gk104_fifo_fini,
        .intr = gk104_fifo_intr,
index 636091c..403560a 100644 (file)
@@ -75,7 +75,6 @@ void gk104_fifo_intr_runlist(struct gk104_fifo *fifo);
 void gk104_fifo_intr_engine(struct gk104_fifo *fifo);
 void *gk104_fifo_dtor(struct nvkm_fifo *base);
 int gk104_fifo_oneinit(struct nvkm_fifo *);
-int gk104_fifo_info(struct nvkm_fifo *base, u64 mthd, u64 *data);
 void gk104_fifo_init(struct nvkm_fifo *base);
 void gk104_fifo_fini(struct nvkm_fifo *base);
 void gk104_fifo_uevent_fini(struct nvkm_fifo *fifo);
index 08f5b06..64bdd3f 100644 (file)
@@ -82,7 +82,6 @@ gk110_fifo = {
        .chid_ctor = gk110_fifo_chid_ctor,
        .runq_nr = gf100_fifo_runq_nr,
        .runl_ctor = gk104_fifo_runl_ctor,
-       .info = gk104_fifo_info,
        .init = gk104_fifo_init,
        .fini = gk104_fifo_fini,
        .intr = gk104_fifo_intr,
index c58343b..3e074a9 100644 (file)
@@ -61,7 +61,6 @@ gk208_fifo = {
        .chid_ctor = gk110_fifo_chid_ctor,
        .runq_nr = gf100_fifo_runq_nr,
        .runl_ctor = gk104_fifo_runl_ctor,
-       .info = gk104_fifo_info,
        .init = gk104_fifo_init,
        .fini = gk104_fifo_fini,
        .intr = gk104_fifo_intr,
index 9a1c1ca..a494dac 100644 (file)
@@ -32,7 +32,6 @@ gk20a_fifo = {
        .chid_ctor = gk110_fifo_chid_ctor,
        .runq_nr = gf100_fifo_runq_nr,
        .runl_ctor = gk104_fifo_runl_ctor,
-       .info = gk104_fifo_info,
        .init = gk104_fifo_init,
        .fini = gk104_fifo_fini,
        .intr = gk104_fifo_intr,
index 44dbebf..c4a6972 100644 (file)
@@ -122,7 +122,6 @@ gm107_fifo = {
        .chid_ctor = gk110_fifo_chid_ctor,
        .runq_nr = gf100_fifo_runq_nr,
        .runl_ctor = gk104_fifo_runl_ctor,
-       .info = gk104_fifo_info,
        .init = gk104_fifo_init,
        .fini = gk104_fifo_fini,
        .intr = gk104_fifo_intr,
index e9f3c5f..bc9893c 100644 (file)
@@ -52,7 +52,6 @@ gm200_fifo = {
        .chid_ctor = gk110_fifo_chid_ctor,
        .runq_nr = gm200_fifo_runq_nr,
        .runl_ctor = gk104_fifo_runl_ctor,
-       .info = gk104_fifo_info,
        .init = gk104_fifo_init,
        .fini = gk104_fifo_fini,
        .intr = gk104_fifo_intr,
index 6fea0a5..4ac4afb 100644 (file)
@@ -94,7 +94,6 @@ gp100_fifo = {
        .chid_ctor = gk110_fifo_chid_ctor,
        .runq_nr = gm200_fifo_runq_nr,
        .runl_ctor = gk104_fifo_runl_ctor,
-       .info = gk104_fifo_info,
        .init = gk104_fifo_init,
        .fini = gk104_fifo_fini,
        .intr = gk104_fifo_intr,
index 21246a0..e1069c6 100644 (file)
@@ -322,7 +322,6 @@ gv100_fifo = {
        .chid_ctor = gk110_fifo_chid_ctor,
        .runq_nr = gm200_fifo_runq_nr,
        .runl_ctor = gk104_fifo_runl_ctor,
-       .info = gk104_fifo_info,
        .init = gk104_fifo_init,
        .fini = gk104_fifo_fini,
        .intr = gk104_fifo_intr,
index 93b8b72..b0fa9d1 100644 (file)
@@ -25,7 +25,6 @@ struct nvkm_fifo_func {
        int (*runq_nr)(struct nvkm_fifo *);
        int (*runl_ctor)(struct nvkm_fifo *);
 
-       int (*info)(struct nvkm_fifo *, u64 mthd, u64 *data);
        void (*init)(struct nvkm_fifo *);
        void (*fini)(struct nvkm_fifo *);
 
index ff13ae5..e5b9b1f 100644 (file)
@@ -449,7 +449,6 @@ tu102_fifo = {
        .chid_ctor = gk110_fifo_chid_ctor,
        .runq_nr = gm200_fifo_runq_nr,
        .runl_ctor = gk104_fifo_runl_ctor,
-       .info = gk104_fifo_info,
        .init = gk104_fifo_init,
        .fini = gk104_fifo_fini,
        .intr = tu102_fifo_intr,