drm/nouveau/fifo/gk104-: support enabling privileged ce functions
Will be used by SVM code to allow direct (without going through MMU) memcpy using the GPU copy engines. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
86b442d74c
commit
85532bd984
|
@ -4,7 +4,7 @@
|
|||
|
||||
struct kepler_channel_gpfifo_a_v0 {
|
||||
__u8 version;
|
||||
__u8 pad01[1];
|
||||
__u8 priv;
|
||||
__u16 chid;
|
||||
__u32 ilength;
|
||||
__u64 ioffset;
|
||||
|
|
|
@ -306,7 +306,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
|
|||
|
||||
/* create channel object and initialise dma and fence management */
|
||||
ret = nouveau_channel_new(drm, device, init->fb_ctxdma_handle,
|
||||
init->tt_ctxdma_handle, &chan->chan);
|
||||
init->tt_ctxdma_handle, false, &chan->chan);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
|
|
|
@ -217,7 +217,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
|
|||
|
||||
static int
|
||||
nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
|
||||
u64 runlist, struct nouveau_channel **pchan)
|
||||
u64 runlist, bool priv, struct nouveau_channel **pchan)
|
||||
{
|
||||
struct nouveau_cli *cli = (void *)device->object.client;
|
||||
static const u16 oclasses[] = { VOLTA_CHANNEL_GPFIFO_A,
|
||||
|
@ -253,6 +253,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
|
|||
args.kepler.ioffset = 0x10000 + chan->push.addr;
|
||||
args.kepler.runlist = runlist;
|
||||
args.kepler.vmm = nvif_handle(&cli->vmm.vmm.object);
|
||||
args.kepler.priv = priv;
|
||||
size = sizeof(args.kepler);
|
||||
} else
|
||||
if (oclass[0] >= FERMI_CHANNEL_GPFIFO) {
|
||||
|
@ -450,7 +451,8 @@ 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, struct nouveau_channel **pchan)
|
||||
u32 arg0, u32 arg1, bool priv,
|
||||
struct nouveau_channel **pchan)
|
||||
{
|
||||
struct nouveau_cli *cli = (void *)device->object.client;
|
||||
bool super;
|
||||
|
@ -460,7 +462,7 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
|
|||
super = cli->base.super;
|
||||
cli->base.super = true;
|
||||
|
||||
ret = nouveau_channel_ind(drm, device, arg0, pchan);
|
||||
ret = nouveau_channel_ind(drm, device, arg0, priv, pchan);
|
||||
if (ret) {
|
||||
NV_PRINTK(dbg, cli, "ib channel create, %d\n", ret);
|
||||
ret = nouveau_channel_dma(drm, device, pchan);
|
||||
|
|
|
@ -49,7 +49,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, struct nouveau_channel **);
|
||||
u32 arg0, u32 arg1, bool priv,
|
||||
struct nouveau_channel **);
|
||||
void nouveau_channel_del(struct nouveau_channel **);
|
||||
int nouveau_channel_idle(struct nouveau_channel *);
|
||||
|
||||
|
|
|
@ -370,7 +370,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
|
|||
if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
|
||||
ret = nouveau_channel_new(drm, &drm->client.device,
|
||||
nvif_fifo_runlist_ce(device), 0,
|
||||
&drm->cechan);
|
||||
true, &drm->cechan);
|
||||
if (ret)
|
||||
NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
|
||||
|
||||
|
@ -381,7 +381,8 @@ nouveau_accel_init(struct nouveau_drm *drm)
|
|||
device->info.chipset != 0xaa &&
|
||||
device->info.chipset != 0xac) {
|
||||
ret = nouveau_channel_new(drm, &drm->client.device,
|
||||
NvDmaFB, NvDmaTT, &drm->cechan);
|
||||
NvDmaFB, NvDmaTT, false,
|
||||
&drm->cechan);
|
||||
if (ret)
|
||||
NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
|
||||
|
||||
|
@ -393,7 +394,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
|
|||
}
|
||||
|
||||
ret = nouveau_channel_new(drm, &drm->client.device,
|
||||
arg0, arg1, &drm->channel);
|
||||
arg0, arg1, false, &drm->channel);
|
||||
if (ret) {
|
||||
NV_ERROR(drm, "failed to create kernel channel, %d\n", ret);
|
||||
nouveau_accel_fini(drm);
|
||||
|
|
|
@ -240,7 +240,7 @@ gk104_fifo_gpfifo_func = {
|
|||
|
||||
static int
|
||||
gk104_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
|
||||
u64 vmm, u64 ioffset, u64 ilength, u64 *inst,
|
||||
u64 vmm, u64 ioffset, u64 ilength, u64 *inst, bool priv,
|
||||
const struct nvkm_oclass *oclass,
|
||||
struct nvkm_object **pobject)
|
||||
{
|
||||
|
@ -316,6 +316,7 @@ gk104_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
|
|||
nvkm_wo32(chan->base.inst, 0x94, 0x30000001);
|
||||
nvkm_wo32(chan->base.inst, 0x9c, 0x00000100);
|
||||
nvkm_wo32(chan->base.inst, 0xac, 0x0000001f);
|
||||
nvkm_wo32(chan->base.inst, 0xe4, priv ? 0x00000020 : 0x00000000);
|
||||
nvkm_wo32(chan->base.inst, 0xe8, chan->base.chid);
|
||||
nvkm_wo32(chan->base.inst, 0xb8, 0xf8000000);
|
||||
nvkm_wo32(chan->base.inst, 0xf8, 0x10003080); /* 0x002310 */
|
||||
|
@ -338,9 +339,11 @@ gk104_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
|
|||
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
|
||||
nvif_ioctl(parent, "create channel gpfifo vers %d vmm %llx "
|
||||
"ioffset %016llx ilength %08x "
|
||||
"runlist %016llx\n",
|
||||
"runlist %016llx priv %d\n",
|
||||
args->v0.version, args->v0.vmm, args->v0.ioffset,
|
||||
args->v0.ilength, args->v0.runlist);
|
||||
args->v0.ilength, args->v0.runlist, args->v0.priv);
|
||||
if (args->v0.priv && !oclass->client->super)
|
||||
return -EINVAL;
|
||||
return gk104_fifo_gpfifo_new_(fifo,
|
||||
&args->v0.runlist,
|
||||
&args->v0.chid,
|
||||
|
@ -348,6 +351,7 @@ gk104_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
|
|||
args->v0.ioffset,
|
||||
args->v0.ilength,
|
||||
&args->v0.inst,
|
||||
args->v0.priv,
|
||||
oclass, pobject);
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,7 @@ gv100_fifo_gpfifo_func = {
|
|||
|
||||
static int
|
||||
gv100_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
|
||||
u64 vmm, u64 ioffset, u64 ilength, u64 *inst,
|
||||
u64 vmm, u64 ioffset, u64 ilength, u64 *inst, bool priv,
|
||||
const struct nvkm_oclass *oclass,
|
||||
struct nvkm_object **pobject)
|
||||
{
|
||||
|
@ -185,9 +185,9 @@ gv100_fifo_gpfifo_new_(struct gk104_fifo *fifo, u64 *runlists, u16 *chid,
|
|||
(ilength << 16));
|
||||
nvkm_wo32(chan->base.inst, 0x084, 0x20400000);
|
||||
nvkm_wo32(chan->base.inst, 0x094, 0x30000001);
|
||||
nvkm_wo32(chan->base.inst, 0x0e4, 0x00000020);
|
||||
nvkm_wo32(chan->base.inst, 0x0e4, priv ? 0x00000020 : 0x00000000);
|
||||
nvkm_wo32(chan->base.inst, 0x0e8, chan->base.chid);
|
||||
nvkm_wo32(chan->base.inst, 0x0f4, 0x00001100);
|
||||
nvkm_wo32(chan->base.inst, 0x0f4, 0x00001000);
|
||||
nvkm_wo32(chan->base.inst, 0x0f8, 0x10003080);
|
||||
nvkm_mo32(chan->base.inst, 0x218, 0x00000000, 0x00000000);
|
||||
nvkm_wo32(chan->base.inst, 0x220, 0x020a1000);
|
||||
|
@ -210,9 +210,11 @@ gv100_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
|
|||
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
|
||||
nvif_ioctl(parent, "create channel gpfifo vers %d vmm %llx "
|
||||
"ioffset %016llx ilength %08x "
|
||||
"runlist %016llx\n",
|
||||
"runlist %016llx priv %d\n",
|
||||
args->v0.version, args->v0.vmm, args->v0.ioffset,
|
||||
args->v0.ilength, args->v0.runlist);
|
||||
args->v0.ilength, args->v0.runlist, args->v0.priv);
|
||||
if (args->v0.priv && !oclass->client->super)
|
||||
return -EINVAL;
|
||||
return gv100_fifo_gpfifo_new_(fifo,
|
||||
&args->v0.runlist,
|
||||
&args->v0.chid,
|
||||
|
@ -220,6 +222,7 @@ gv100_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
|
|||
args->v0.ioffset,
|
||||
args->v0.ilength,
|
||||
&args->v0.inst,
|
||||
args->v0.priv,
|
||||
oclass, pobject);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue