diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2018-12-11 05:50:02 +0100 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2018-12-11 06:37:47 +0100 |
commit | 85532bd984d77cef5a59e9cbb73e8161b94017ae (patch) | |
tree | fc37226779fb04545fbe745f0b1704d2ff1a1a75 /drivers/gpu | |
parent | drm/nouveau/fifo/gk104-: return channel instance in ctor args (diff) | |
download | linux-85532bd984d77cef5a59e9cbb73e8161b94017ae.tar.xz linux-85532bd984d77cef5a59e9cbb73e8161b94017ae.zip |
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>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/include/nvif/cla06f.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_abi16.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_chan.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_chan.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drm.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c | 13 |
7 files changed, 28 insertions, 17 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvif/cla06f.h b/drivers/gpu/drm/nouveau/include/nvif/cla06f.h index e588cc720299..81401eb970ea 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/cla06f.h +++ b/drivers/gpu/drm/nouveau/include/nvif/cla06f.h @@ -4,7 +4,7 @@ struct kepler_channel_gpfifo_a_v0 { __u8 version; - __u8 pad01[1]; + __u8 priv; __u16 chid; __u32 ilength; __u64 ioffset; diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index e67a471331b5..b06cdac8f3a2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -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; diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index a154978d74ef..5daf9248ae63 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -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); diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.h b/drivers/gpu/drm/nouveau/nouveau_chan.h index 93d065d4a2a1..a62d233b2a97 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.h +++ b/drivers/gpu/drm/nouveau/nouveau_chan.h @@ -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 *); diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 2b2baf6e0e0d..100cab059e49 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -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); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c index 523f8a09c52a..8e30b3d3ff10 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c @@ -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); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c index 97c3af3de900..65db8a1be943 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogv100.c @@ -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); } |