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:
parent
a98a3c52f8
commit
9d24907ccf
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
@ -11,6 +11,7 @@ struct nouveau_channel {
|
|||
|
||||
int chid;
|
||||
u64 inst;
|
||||
u32 token;
|
||||
|
||||
struct nvif_object vram;
|
||||
struct nvif_object gart;
|
||||
|
|
|
@ -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--;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 *,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue