Commit 6de12538 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/fifo: expose runlist topology info on all chipsets

Previously only available from Kepler onwards.

- also fixes the info() queries causing fifo init()/fini() unnecessarily
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
Reviewed-by: default avatarLyude Paul <lyude@redhat.com>
parent d94470e9
...@@ -253,7 +253,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) ...@@ -253,7 +253,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv); struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
struct nouveau_abi16_chan *chan; struct nouveau_abi16_chan *chan;
struct nvif_device *device; struct nvif_device *device;
u64 engine; u64 engine, runm;
int ret; int ret;
if (unlikely(!abi16)) if (unlikely(!abi16))
...@@ -263,6 +263,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) ...@@ -263,6 +263,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
return nouveau_abi16_put(abi16, -ENODEV); return nouveau_abi16_put(abi16, -ENODEV);
device = &abi16->device; device = &abi16->device;
engine = NV_DEVICE_HOST_RUNLIST_ENGINES_GR;
/* hack to allow channel engine type specification on kepler */ /* hack to allow channel engine type specification on kepler */
if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) { if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
...@@ -276,19 +277,18 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) ...@@ -276,19 +277,18 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
default: default:
return nouveau_abi16_put(abi16, -ENOSYS); return nouveau_abi16_put(abi16, -ENOSYS);
} }
} else {
engine = NV_DEVICE_HOST_RUNLIST_ENGINES_GR;
}
if (engine != NV_DEVICE_HOST_RUNLIST_ENGINES_CE) init->fb_ctxdma_handle = 0;
engine = nvif_fifo_runlist(device, engine); init->tt_ctxdma_handle = 0;
else }
engine = nvif_fifo_runlist_ce(device);
init->fb_ctxdma_handle = engine;
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); return nouveau_abi16_put(abi16, -EINVAL);
/* allocate "abi16 channel" data and make up a handle for it */ /* allocate "abi16 channel" data and make up a handle for it */
...@@ -300,8 +300,8 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) ...@@ -300,8 +300,8 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
list_add(&chan->head, &abi16->channels); list_add(&chan->head, &abi16->channels);
/* create channel object and initialise dma and fence management */ /* create channel object and initialise dma and fence management */
ret = nouveau_channel_new(drm, device, init->fb_ctxdma_handle, ret = nouveau_channel_new(drm, device, false, runm, init->fb_ctxdma_handle,
init->tt_ctxdma_handle, false, &chan->chan); init->tt_ctxdma_handle, &chan->chan);
if (ret) if (ret)
goto done; goto done;
......
...@@ -513,14 +513,13 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) ...@@ -513,14 +513,13 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
int int
nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device, nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
u32 arg0, u32 arg1, bool priv, bool priv, u64 runm, u32 vram, u32 gart, struct nouveau_channel **pchan)
struct nouveau_channel **pchan)
{ {
struct nouveau_cli *cli = (void *)device->object.client; struct nouveau_cli *cli = (void *)device->object.client;
int ret; int ret;
/* hack until fencenv50 is fixed, and agp access relaxed */ /* 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) { if (ret) {
NV_PRINTK(dbg, cli, "ib channel create, %d\n", ret); NV_PRINTK(dbg, cli, "ib channel create, %d\n", ret);
ret = nouveau_channel_dma(drm, device, pchan); ret = nouveau_channel_dma(drm, device, pchan);
...@@ -530,7 +529,7 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -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) { if (ret) {
NV_PRINTK(err, cli, "channel failed to initialise, %d\n", ret); NV_PRINTK(err, cli, "channel failed to initialise, %d\n", ret);
nouveau_channel_del(pchan); nouveau_channel_del(pchan);
......
...@@ -56,9 +56,8 @@ struct nouveau_channel { ...@@ -56,9 +56,8 @@ struct nouveau_channel {
int nouveau_channels_init(struct nouveau_drm *); int nouveau_channels_init(struct nouveau_drm *);
int nouveau_channel_new(struct nouveau_drm *, struct nvif_device *, int nouveau_channel_new(struct nouveau_drm *, struct nvif_device *, bool priv, u64 runm,
u32 arg0, u32 arg1, bool priv, u32 vram, u32 gart, struct nouveau_channel **);
struct nouveau_channel **);
void nouveau_channel_del(struct nouveau_channel **); void nouveau_channel_del(struct nouveau_channel **);
int nouveau_channel_idle(struct nouveau_channel *); int nouveau_channel_idle(struct nouveau_channel *);
......
...@@ -316,28 +316,19 @@ static void ...@@ -316,28 +316,19 @@ static void
nouveau_accel_ce_init(struct nouveau_drm *drm) nouveau_accel_ce_init(struct nouveau_drm *drm)
{ {
struct nvif_device *device = &drm->client.device; struct nvif_device *device = &drm->client.device;
u64 runm;
int ret = 0; int ret = 0;
/* Allocate channel that has access to a (preferably async) copy /* Allocate channel that has access to a (preferably async) copy
* engine, to use for TTM buffer moves. * engine, to use for TTM buffer moves.
*/ */
if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) { runm = nvif_fifo_runlist_ce(device);
ret = nouveau_channel_new(drm, device, if (!runm) {
nvif_fifo_runlist_ce(device), 0, NV_DEBUG(drm, "no ce runlist\n");
true, &drm->cechan); return;
} 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);
} }
ret = nouveau_channel_new(drm, device, false, runm, NvDmaFB, NvDmaTT, &drm->cechan);
if (ret) if (ret)
NV_ERROR(drm, "failed to create ce channel, %d\n", ret); NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
} }
...@@ -355,23 +346,20 @@ static void ...@@ -355,23 +346,20 @@ static void
nouveau_accel_gr_init(struct nouveau_drm *drm) nouveau_accel_gr_init(struct nouveau_drm *drm)
{ {
struct nvif_device *device = &drm->client.device; struct nvif_device *device = &drm->client.device;
u32 arg0, arg1; u64 runm;
int ret; int ret;
if (device->info.family >= NV_DEVICE_INFO_V0_AMPERE) if (device->info.family >= NV_DEVICE_INFO_V0_AMPERE)
return; return;
/* Allocate channel that has access to the graphics engine. */ /* Allocate channel that has access to the graphics engine. */
if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) { runm = nvif_fifo_runlist(device, NV_DEVICE_HOST_RUNLIST_ENGINES_GR);
arg0 = nvif_fifo_runlist(device, NV_DEVICE_HOST_RUNLIST_ENGINES_GR); if (!runm) {
arg1 = 1; NV_DEBUG(drm, "no gr runlist\n");
} else { return;
arg0 = NvDmaFB;
arg1 = NvDmaTT;
} }
ret = nouveau_channel_new(drm, device, arg0, arg1, false, ret = nouveau_channel_new(drm, device, false, runm, NvDmaFB, NvDmaTT, &drm->channel);
&drm->channel);
if (ret) { if (ret) {
NV_ERROR(drm, "failed to create kernel channel, %d\n", ret); NV_ERROR(drm, "failed to create kernel channel, %d\n", ret);
nouveau_accel_gr_fini(drm); nouveau_accel_gr_fini(drm);
......
...@@ -80,14 +80,10 @@ static int ...@@ -80,14 +80,10 @@ static int
nvkm_engine_info(struct nvkm_subdev *subdev, u64 mthd, u64 *data) nvkm_engine_info(struct nvkm_subdev *subdev, u64 mthd, u64 *data)
{ {
struct nvkm_engine *engine = nvkm_engine(subdev); struct nvkm_engine *engine = nvkm_engine(subdev);
if (engine->func->info) {
if (!IS_ERR((engine = nvkm_engine_ref(engine)))) { if (engine->func->info)
int ret = engine->func->info(engine, mthd, data); return engine->func->info(engine, mthd, data);
nvkm_engine_unref(&engine);
return ret;
}
return PTR_ERR(engine);
}
return -ENOSYS; return -ENOSYS;
} }
......
...@@ -221,12 +221,57 @@ static int ...@@ -221,12 +221,57 @@ static int
nvkm_fifo_info(struct nvkm_engine *engine, u64 mthd, u64 *data) nvkm_fifo_info(struct nvkm_engine *engine, u64 mthd, u64 *data)
{ {
struct nvkm_fifo *fifo = nvkm_fifo(engine); 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) { switch (mthd) {
case NV_DEVICE_HOST_CHANNELS: *data = fifo->chid ? fifo->chid->nr : 0; return 0; 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: default:
if (fifo->func->info)
return fifo->func->info(fifo, mthd, data);
break; break;
} }
......
...@@ -39,7 +39,6 @@ ...@@ -39,7 +39,6 @@
#include <engine/sw.h> #include <engine/sw.h>
#include <nvif/class.h> #include <nvif/class.h>
#include <nvif/cl0080.h>
static const struct nvkm_chan_func static const struct nvkm_chan_func
gk104_chan = { gk104_chan = {
...@@ -991,56 +990,6 @@ gk104_fifo_fini(struct nvkm_fifo *base) ...@@ -991,56 +990,6 @@ gk104_fifo_fini(struct nvkm_fifo *base)
nvkm_mask(device, 0x002140, 0x10000000, 0x10000000); 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 void
gk104_fifo_init(struct nvkm_fifo *base) gk104_fifo_init(struct nvkm_fifo *base)
{ {
...@@ -1225,7 +1174,6 @@ gk104_fifo = { ...@@ -1225,7 +1174,6 @@ gk104_fifo = {
.chid_ctor = gf100_fifo_chid_ctor, .chid_ctor = gf100_fifo_chid_ctor,
.runq_nr = gf100_fifo_runq_nr, .runq_nr = gf100_fifo_runq_nr,
.runl_ctor = gk104_fifo_runl_ctor, .runl_ctor = gk104_fifo_runl_ctor,
.info = gk104_fifo_info,
.init = gk104_fifo_init, .init = gk104_fifo_init,
.fini = gk104_fifo_fini, .fini = gk104_fifo_fini,
.intr = gk104_fifo_intr, .intr = gk104_fifo_intr,
......
...@@ -75,7 +75,6 @@ void gk104_fifo_intr_runlist(struct gk104_fifo *fifo); ...@@ -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_intr_engine(struct gk104_fifo *fifo);
void *gk104_fifo_dtor(struct nvkm_fifo *base); void *gk104_fifo_dtor(struct nvkm_fifo *base);
int gk104_fifo_oneinit(struct nvkm_fifo *); 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_init(struct nvkm_fifo *base);
void gk104_fifo_fini(struct nvkm_fifo *base); void gk104_fifo_fini(struct nvkm_fifo *base);
void gk104_fifo_uevent_fini(struct nvkm_fifo *fifo); void gk104_fifo_uevent_fini(struct nvkm_fifo *fifo);
......
...@@ -82,7 +82,6 @@ gk110_fifo = { ...@@ -82,7 +82,6 @@ gk110_fifo = {
.chid_ctor = gk110_fifo_chid_ctor, .chid_ctor = gk110_fifo_chid_ctor,
.runq_nr = gf100_fifo_runq_nr, .runq_nr = gf100_fifo_runq_nr,
.runl_ctor = gk104_fifo_runl_ctor, .runl_ctor = gk104_fifo_runl_ctor,
.info = gk104_fifo_info,
.init = gk104_fifo_init, .init = gk104_fifo_init,
.fini = gk104_fifo_fini, .fini = gk104_fifo_fini,
.intr = gk104_fifo_intr, .intr = gk104_fifo_intr,
......
...@@ -61,7 +61,6 @@ gk208_fifo = { ...@@ -61,7 +61,6 @@ gk208_fifo = {
.chid_ctor = gk110_fifo_chid_ctor, .chid_ctor = gk110_fifo_chid_ctor,
.runq_nr = gf100_fifo_runq_nr, .runq_nr = gf100_fifo_runq_nr,
.runl_ctor = gk104_fifo_runl_ctor, .runl_ctor = gk104_fifo_runl_ctor,
.info = gk104_fifo_info,
.init = gk104_fifo_init, .init = gk104_fifo_init,
.fini = gk104_fifo_fini, .fini = gk104_fifo_fini,
.intr = gk104_fifo_intr, .intr = gk104_fifo_intr,
......
...@@ -32,7 +32,6 @@ gk20a_fifo = { ...@@ -32,7 +32,6 @@ gk20a_fifo = {
.chid_ctor = gk110_fifo_chid_ctor, .chid_ctor = gk110_fifo_chid_ctor,
.runq_nr = gf100_fifo_runq_nr, .runq_nr = gf100_fifo_runq_nr,
.runl_ctor = gk104_fifo_runl_ctor, .runl_ctor = gk104_fifo_runl_ctor,
.info = gk104_fifo_info,
.init = gk104_fifo_init, .init = gk104_fifo_init,
.fini = gk104_fifo_fini, .fini = gk104_fifo_fini,
.intr = gk104_fifo_intr, .intr = gk104_fifo_intr,
......
...@@ -122,7 +122,6 @@ gm107_fifo = { ...@@ -122,7 +122,6 @@ gm107_fifo = {
.chid_ctor = gk110_fifo_chid_ctor, .chid_ctor = gk110_fifo_chid_ctor,
.runq_nr = gf100_fifo_runq_nr, .runq_nr = gf100_fifo_runq_nr,
.runl_ctor = gk104_fifo_runl_ctor, .runl_ctor = gk104_fifo_runl_ctor,
.info = gk104_fifo_info,
.init = gk104_fifo_init, .init = gk104_fifo_init,
.fini = gk104_fifo_fini, .fini = gk104_fifo_fini,
.intr = gk104_fifo_intr, .intr = gk104_fifo_intr,
......
...@@ -52,7 +52,6 @@ gm200_fifo = { ...@@ -52,7 +52,6 @@ gm200_fifo = {
.chid_ctor = gk110_fifo_chid_ctor, .chid_ctor = gk110_fifo_chid_ctor,
.runq_nr = gm200_fifo_runq_nr, .runq_nr = gm200_fifo_runq_nr,
.runl_ctor = gk104_fifo_runl_ctor, .runl_ctor = gk104_fifo_runl_ctor,
.info = gk104_fifo_info,
.init = gk104_fifo_init, .init = gk104_fifo_init,
.fini = gk104_fifo_fini, .fini = gk104_fifo_fini,
.intr = gk104_fifo_intr, .intr = gk104_fifo_intr,
......
...@@ -94,7 +94,6 @@ gp100_fifo = { ...@@ -94,7 +94,6 @@ gp100_fifo = {
.chid_ctor = gk110_fifo_chid_ctor, .chid_ctor = gk110_fifo_chid_ctor,
.runq_nr = gm200_fifo_runq_nr, .runq_nr = gm200_fifo_runq_nr,
.runl_ctor = gk104_fifo_runl_ctor, .runl_ctor = gk104_fifo_runl_ctor,
.info = gk104_fifo_info,
.init = gk104_fifo_init, .init = gk104_fifo_init,
.fini = gk104_fifo_fini, .fini = gk104_fifo_fini,
.intr = gk104_fifo_intr, .intr = gk104_fifo_intr,
......
...@@ -322,7 +322,6 @@ gv100_fifo = { ...@@ -322,7 +322,6 @@ gv100_fifo = {
.chid_ctor = gk110_fifo_chid_ctor, .chid_ctor = gk110_fifo_chid_ctor,
.runq_nr = gm200_fifo_runq_nr, .runq_nr = gm200_fifo_runq_nr,
.runl_ctor = gk104_fifo_runl_ctor, .runl_ctor = gk104_fifo_runl_ctor,
.info = gk104_fifo_info,
.init = gk104_fifo_init, .init = gk104_fifo_init,
.fini = gk104_fifo_fini, .fini = gk104_fifo_fini,
.intr = gk104_fifo_intr, .intr = gk104_fifo_intr,
......
...@@ -25,7 +25,6 @@ struct nvkm_fifo_func { ...@@ -25,7 +25,6 @@ struct nvkm_fifo_func {
int (*runq_nr)(struct nvkm_fifo *); int (*runq_nr)(struct nvkm_fifo *);
int (*runl_ctor)(struct nvkm_fifo *); int (*runl_ctor)(struct nvkm_fifo *);
int (*info)(struct nvkm_fifo *, u64 mthd, u64 *data);
void (*init)(struct nvkm_fifo *); void (*init)(struct nvkm_fifo *);
void (*fini)(struct nvkm_fifo *); void (*fini)(struct nvkm_fifo *);
......
...@@ -449,7 +449,6 @@ tu102_fifo = { ...@@ -449,7 +449,6 @@ tu102_fifo = {
.chid_ctor = gk110_fifo_chid_ctor, .chid_ctor = gk110_fifo_chid_ctor,
.runq_nr = gm200_fifo_runq_nr, .runq_nr = gm200_fifo_runq_nr,
.runl_ctor = gk104_fifo_runl_ctor, .runl_ctor = gk104_fifo_runl_ctor,
.info = gk104_fifo_info,
.init = gk104_fifo_init, .init = gk104_fifo_init,
.fini = gk104_fifo_fini, .fini = gk104_fifo_fini,
.intr = tu102_fifo_intr, .intr = tu102_fifo_intr,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment