drm/nouveau/fifo/gv100: return work submission token in channel ctor args

The token will also contain runlist ID on Turing, so instead expose it as
an opaque value from NVKM so the client doesn't need to care.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
Ben Skeggs 2018-12-11 14:50:02 +10:00
parent a98a3c52f8
commit 9d24907ccf
8 changed files with 63 additions and 13 deletions

View File

@ -68,7 +68,7 @@
#define KEPLER_CHANNEL_GPFIFO_B /* cla06f.h */ 0x0000a16f
#define MAXWELL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000b06f
#define PASCAL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000c06f
#define VOLTA_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000c36f
#define VOLTA_CHANNEL_GPFIFO_A /* clc36f.h */ 0x0000c36f
#define NV50_DISP /* cl5070.h */ 0x00005070
#define G82_DISP /* cl5070.h */ 0x00008270

View File

@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __NVIF_CLC36F_H__
#define __NVIF_CLC36F_H__
struct volta_channel_gpfifo_a_v0 {
__u8 version;
__u8 priv;
__u16 chid;
__u32 ilength;
__u64 ioffset;
__u64 runlist;
__u64 vmm;
__u64 inst;
__u32 token;
};
#define NVC36F_V0_NTFY_NON_STALL_INTERRUPT 0x00
#define NVC36F_V0_NTFY_KILLED 0x01
#endif

View File

@ -29,6 +29,7 @@
#include <nvif/cl506f.h>
#include <nvif/cl906f.h>
#include <nvif/cla06f.h>
#include <nvif/clc36f.h>
#include <nvif/ioctl.h>
/*XXX*/
@ -234,6 +235,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
struct nv50_channel_gpfifo_v0 nv50;
struct fermi_channel_gpfifo_v0 fermi;
struct kepler_channel_gpfifo_a_v0 kepler;
struct volta_channel_gpfifo_a_v0 volta;
} args;
struct nouveau_channel *chan;
u32 size;
@ -247,6 +249,15 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
/* create channel object */
do {
if (oclass[0] >= VOLTA_CHANNEL_GPFIFO_A) {
args.volta.version = 0;
args.volta.ilength = 0x02000;
args.volta.ioffset = 0x10000 + chan->push.addr;
args.volta.runlist = runlist;
args.volta.vmm = nvif_handle(&cli->vmm.vmm.object);
args.volta.priv = priv;
size = sizeof(args.volta);
} else
if (oclass[0] >= KEPLER_CHANNEL_GPFIFO_A) {
args.kepler.version = 0;
args.kepler.ilength = 0x02000;
@ -274,6 +285,11 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
ret = nvif_object_init(&device->object, 0, *oclass++,
&args, size, &chan->user);
if (ret == 0) {
if (chan->user.oclass >= VOLTA_CHANNEL_GPFIFO_A) {
chan->chid = args.volta.chid;
chan->inst = args.volta.inst;
chan->token = args.volta.token;
} else
if (chan->user.oclass >= KEPLER_CHANNEL_GPFIFO_A) {
chan->chid = args.kepler.chid;
chan->inst = args.kepler.inst;

View File

@ -11,6 +11,7 @@ struct nouveau_channel {
int chid;
u64 inst;
u32 token;
struct nvif_object vram;
struct nvif_object gart;

View File

@ -101,7 +101,7 @@ nv50_dma_push(struct nouveau_channel *chan, u64 offset, int length)
nvif_wr32(&chan->user, 0x8c, chan->dma.ib_put);
if (user->func && user->func->doorbell)
user->func->doorbell(user, chan->chid);
user->func->doorbell(user, chan->token);
chan->dma.ib_free--;
}

View File

@ -17,6 +17,7 @@ struct nvkm_fifo_chan_func {
bool suspend);
int (*object_ctor)(struct nvkm_fifo_chan *, struct nvkm_object *);
void (*object_dtor)(struct nvkm_fifo_chan *, int);
u32 (*submit_token)(struct nvkm_fifo_chan *);
};
int nvkm_fifo_chan_ctor(const struct nvkm_fifo_chan_func *, struct nvkm_fifo *,

View File

@ -38,4 +38,8 @@ int gk104_fifo_gpfifo_kick_locked(struct gk104_fifo_chan *);
int gv100_fifo_gpfifo_new(struct gk104_fifo *, const struct nvkm_oclass *,
void *data, u32 size, struct nvkm_object **);
int gv100_fifo_gpfifo_new_(const struct nvkm_fifo_chan_func *,
struct gk104_fifo *, u64 *, u16 *, u64, u64, u64,
u64 *, bool, u32 *, const struct nvkm_oclass *,
struct nvkm_object **);
#endif

View File

@ -25,9 +25,15 @@
#include <core/client.h>
#include <core/gpuobj.h>
#include <nvif/cla06f.h>
#include <nvif/clc36f.h>
#include <nvif/unpack.h>
static u32
gv100_fifo_gpfifo_submit_token(struct nvkm_fifo_chan *chan)
{
return chan->chid;
}
static int
gv100_fifo_gpfifo_engine_valid(struct gk104_fifo_chan *chan, bool ce, bool valid)
{
@ -100,8 +106,8 @@ gv100_fifo_gpfifo_engine_init(struct nvkm_fifo_chan *base,
return gv100_fifo_gpfifo_engine_valid(chan, false, true);
}
const struct nvkm_fifo_chan_func
gv100_fifo_gpfifo_func = {
static const struct nvkm_fifo_chan_func
gv100_fifo_gpfifo = {
.dtor = gk104_fifo_gpfifo_dtor,
.init = gk104_fifo_gpfifo_init,
.fini = gk104_fifo_gpfifo_fini,
@ -110,12 +116,14 @@ gv100_fifo_gpfifo_func = {
.engine_dtor = gk104_fifo_gpfifo_engine_dtor,
.engine_init = gv100_fifo_gpfifo_engine_init,
.engine_fini = gv100_fifo_gpfifo_engine_fini,
.submit_token = gv100_fifo_gpfifo_submit_token,
};
static int
gv100_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
int
gv100_fifo_gpfifo_new_(const struct nvkm_fifo_chan_func *func,
struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
u64 vmm, u64 ioffset, u64 ilength, u64 *inst, bool priv,
const struct nvkm_oclass *oclass,
u32 *token, const struct nvkm_oclass *oclass,
struct nvkm_object **pobject)
{
struct nvkm_device *device = fifo->base.engine.subdev.device;
@ -144,15 +152,15 @@ gv100_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
chan->runl = runlist;
INIT_LIST_HEAD(&chan->head);
ret = nvkm_fifo_chan_ctor(&gv100_fifo_gpfifo_func, &fifo->base,
0x1000, 0x1000, true, vmm, 0, subdevs,
1, fifo->user.bar->addr, 0x200,
ret = nvkm_fifo_chan_ctor(func, &fifo->base, 0x1000, 0x1000, true, vmm,
0, subdevs, 1, fifo->user.bar->addr, 0x200,
oclass, &chan->base);
if (ret)
return ret;
*chid = chan->base.chid;
*inst = chan->base.inst->addr;
*token = chan->base.func->submit_token(&chan->base);
/* Hack to support GPUs where even individual channels should be
* part of a channel group.
@ -218,7 +226,7 @@ gv100_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
{
struct nvkm_object *parent = oclass->parent;
union {
struct kepler_channel_gpfifo_a_v0 v0;
struct volta_channel_gpfifo_a_v0 v0;
} *args = data;
int ret = -ENOSYS;
@ -231,7 +239,7 @@ gv100_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
args->v0.ilength, args->v0.runlist, args->v0.priv);
if (args->v0.priv && !oclass->client->super)
return -EINVAL;
return gv100_fifo_gpfifo_new_(fifo,
return gv100_fifo_gpfifo_new_(&gv100_fifo_gpfifo, fifo,
&args->v0.runlist,
&args->v0.chid,
args->v0.vmm,
@ -239,6 +247,7 @@ gv100_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
args->v0.ilength,
&args->v0.inst,
args->v0.priv,
&args->v0.token,
oclass, pobject);
}