******************************************************************************/
struct nv03_channel_dma_v0 {
+ __u8 version;
+ __u8 chid;
+ __u8 pad02[2];
+ __u32 offset;
+ __u64 pushbuf;
+};
+
+struct nv50_channel_dma_v0 {
__u8 version;
__u8 chid;
__u8 pad02[6];
+ __u64 vm;
__u64 pushbuf;
__u64 offset;
};
__u32 ilength;
__u64 ioffset;
__u64 pushbuf;
+ __u64 vm;
+};
+
+struct fermi_channel_gpfifo_v0 {
+ __u8 version;
+ __u8 chid;
+ __u8 pad02[2];
+ __u32 ilength;
+ __u64 ioffset;
+ __u64 vm;
};
struct kepler_channel_gpfifo_a_v0 {
__u16 chid;
__u32 ilength;
__u64 ioffset;
- __u64 pushbuf;
+ __u64 vm;
};
/*******************************************************************************
const u16 *oclass = oclasses;
union {
struct nv50_channel_gpfifo_v0 nv50;
+ struct fermi_channel_gpfifo_v0 fermi;
struct kepler_channel_gpfifo_a_v0 kepler;
} args;
struct nouveau_channel *chan;
if (oclass[0] >= KEPLER_CHANNEL_GPFIFO_A) {
args.kepler.version = 0;
args.kepler.engine = engine;
- args.kepler.pushbuf = nvif_handle(&chan->push.ctxdma);
args.kepler.ilength = 0x02000;
args.kepler.ioffset = 0x10000 + chan->push.vma.offset;
+ args.kepler.vm = 0;
size = sizeof(args.kepler);
+ } else
+ if (oclass[0] >= FERMI_CHANNEL_GPFIFO) {
+ args.fermi.version = 0;
+ args.fermi.ilength = 0x02000;
+ args.fermi.ioffset = 0x10000 + chan->push.vma.offset;
+ args.fermi.vm = 0;
+ size = sizeof(args.fermi);
} else {
args.nv50.version = 0;
- args.nv50.pushbuf = nvif_handle(&chan->push.ctxdma);
args.nv50.ilength = 0x02000;
args.nv50.ioffset = 0x10000 + chan->push.vma.offset;
+ args.nv50.pushbuf = nvif_handle(&chan->push.ctxdma);
+ args.nv50.vm = 0;
size = sizeof(args.nv50);
}
if (ret == 0) {
if (chan->user.oclass >= KEPLER_CHANNEL_GPFIFO_A)
chan->chid = args.kepler.chid;
+ else
+ if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO)
+ chan->chid = args.fermi.chid;
else
chan->chid = args.nv50.chid;
return ret;
return ret;
/* validate dma object representing push buffer */
- handle = nvkm_client_search(client, pushbuf);
- if (!handle)
- return -ENOENT;
- dmaobj = (void *)handle->object;
-
- dmaeng = (void *)dmaobj->base.engine;
- switch (dmaobj->base.oclass->handle) {
- case NV_DMA_FROM_MEMORY:
- case NV_DMA_IN_MEMORY:
- break;
- default:
- return -EINVAL;
- }
+ if (pushbuf) {
+ handle = nvkm_client_search(client, pushbuf);
+ if (!handle)
+ return -ENOENT;
+ dmaobj = (void *)handle->object;
+
+ dmaeng = (void *)dmaobj->base.engine;
+ switch (dmaobj->base.oclass->handle) {
+ case NV_DMA_FROM_MEMORY:
+ case NV_DMA_IN_MEMORY:
+ break;
+ default:
+ return -EINVAL;
+ }
- ret = dmaeng->bind(dmaobj, parent, &chan->pushgpu);
- if (ret)
- return ret;
+ ret = dmaeng->bind(dmaobj, parent, &chan->pushgpu);
+ if (ret)
+ return ret;
+ }
/* find a free fifo channel */
spin_lock_irqsave(&fifo->lock, flags);
struct nvkm_object **pobject)
{
union {
- struct nv03_channel_dma_v0 v0;
+ struct nv50_channel_dma_v0 v0;
} *args = data;
struct nvkm_bar *bar = nvkm_bar(parent);
struct nv50_fifo_base *base = (void *)parent;
nvif_ioctl(parent, "create channel dma vers %d pushbuf %llx "
"offset %016llx\n", args->v0.version,
args->v0.pushbuf, args->v0.offset);
+ if (args->v0.vm)
+ return -ENOENT;
} else
return ret;
"ioffset %016llx ilength %08x\n",
args->v0.version, args->v0.pushbuf, args->v0.ioffset,
args->v0.ilength);
+ if (args->v0.vm)
+ return -ENOENT;
} else
return ret;
struct nvkm_object **pobject)
{
union {
- struct nv50_channel_gpfifo_v0 v0;
+ struct fermi_channel_gpfifo_v0 v0;
} *args = data;
struct nvkm_bar *bar = nvkm_bar(parent);
struct gf100_fifo *fifo = (void *)engine;
nvif_ioctl(parent, "create channel gpfifo size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
- nvif_ioctl(parent, "create channel gpfifo vers %d pushbuf %llx "
+ nvif_ioctl(parent, "create channel gpfifo vers %d "
"ioffset %016llx ilength %08x\n",
- args->v0.version, args->v0.pushbuf, args->v0.ioffset,
+ args->v0.version, args->v0.ioffset,
args->v0.ilength);
+ if (args->v0.vm)
+ return -ENOENT;
} else
return ret;
ret = nvkm_fifo_channel_create(parent, engine, oclass, 1,
- fifo->user.bar.offset, 0x1000,
- args->v0.pushbuf,
+ fifo->user.bar.offset, 0x1000, 0,
(1ULL << NVDEV_ENGINE_SW) |
(1ULL << NVDEV_ENGINE_GR) |
(1ULL << NVDEV_ENGINE_CE0) |
nvif_ioctl(parent, "create channel gpfifo size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
- nvif_ioctl(parent, "create channel gpfifo vers %d pushbuf %llx "
+ nvif_ioctl(parent, "create channel gpfifo vers %d "
"ioffset %016llx ilength %08x engine %08x\n",
- args->v0.version, args->v0.pushbuf, args->v0.ioffset,
+ args->v0.version, args->v0.ioffset,
args->v0.ilength, args->v0.engine);
+ if (args->v0.vm)
+ return -ENOENT;
} else
return ret;
i = __ffs(engines);
ret = nvkm_fifo_channel_create(parent, engine, oclass, 1,
- fifo->user.bar.offset, 0x200,
- args->v0.pushbuf,
+ fifo->user.bar.offset, 0x200, 0,
fifo_engine[i].mask, &chan);
*pobject = nv_object(chan);
if (ret)
nvif_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create channel dma vers %d pushbuf %llx "
- "offset %016llx\n", args->v0.version,
+ "offset %08x\n", args->v0.version,
args->v0.pushbuf, args->v0.offset);
} else
return ret;
nvif_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create channel dma vers %d pushbuf %llx "
- "offset %016llx\n", args->v0.version,
+ "offset %08x\n", args->v0.version,
args->v0.pushbuf, args->v0.offset);
} else
return ret;
nvif_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create channel dma vers %d pushbuf %llx "
- "offset %016llx\n", args->v0.version,
+ "offset %08x\n", args->v0.version,
args->v0.pushbuf, args->v0.offset);
} else
return ret;
nvif_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(parent, "create channel dma vers %d pushbuf %llx "
- "offset %016llx\n", args->v0.version,
+ "offset %08x\n", args->v0.version,
args->v0.pushbuf, args->v0.offset);
} else
return ret;
struct nvkm_object **pobject)
{
union {
- struct nv03_channel_dma_v0 v0;
+ struct nv50_channel_dma_v0 v0;
} *args = data;
struct nvkm_bar *bar = nvkm_bar(parent);
struct nv50_fifo_base *base = (void *)parent;
nvif_ioctl(parent, "create channel dma vers %d pushbuf %llx "
"offset %016llx\n", args->v0.version,
args->v0.pushbuf, args->v0.offset);
+ if (args->v0.vm)
+ return -ENOENT;
} else
return ret;
"ioffset %016llx ilength %08x\n",
args->v0.version, args->v0.pushbuf, args->v0.ioffset,
args->v0.ilength);
+ if (args->v0.vm)
+ return -ENOENT;
} else
return ret;