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)
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;
......
......@@ -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);
......
......@@ -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 *);
......
......@@ -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);
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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,
......
......@@ -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);
......
......@@ -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,
......
......@@ -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,
......
......@@ -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,
......
......@@ -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,
......
......@@ -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,
......
......@@ -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,
......
......@@ -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,
......
......@@ -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 *);
......
......@@ -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,
......
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