static int nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size) { union { struct nv50_disp_mthd_v0 v0; struct nv50_disp_mthd_v1 v1; } *args = data; struct nv50_disp_root *root = nv50_disp_root(object); struct nv50_disp *disp = root->disp; struct nvkm_outp *temp, *outp = NULL; struct nvkm_head *head; u16 type, mask = 0; int hidx, ret = -ENOSYS; if (mthd != NV50_DISP_MTHD) return -EINVAL; nvif_ioctl(object, "disp mthd size %d\n", size); if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) { nvif_ioctl(object, "disp mthd vers %d mthd %02x head %d\n", args->v0.version, args->v0.method, args->v0.head); mthd = args->v0.method; hidx = args->v0.head; } else if (!(ret = nvif_unpack(ret, &data, &size, args->v1, 1, 1, true))) { nvif_ioctl(object, "disp mthd vers %d mthd %02x " "type %04x mask %04x\n", args->v1.version, args->v1.method, args->v1.hasht, args->v1.hashm); mthd = args->v1.method; type = args->v1.hasht; mask = args->v1.hashm; hidx = ffs((mask >> 8) & 0x0f) - 1; } else
int nv50_dac_power(NV50_DISP_MTHD_V1) { struct nvkm_device *device = disp->base.engine.subdev.device; const u32 doff = outp->or * 0x800; union { struct nv50_disp_dac_pwr_v0 v0; } *args = data; u32 stat; int ret; nvif_ioctl(object, "disp dac pwr size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nvif_ioctl(object, "disp dac pwr vers %d state %d data %d " "vsync %d hsync %d\n", args->v0.version, args->v0.state, args->v0.data, args->v0.vsync, args->v0.hsync); stat = 0x00000040 * !args->v0.state; stat |= 0x00000010 * !args->v0.data; stat |= 0x00000004 * !args->v0.vsync; stat |= 0x00000001 * !args->v0.hsync; } else return ret; nvkm_msec(device, 2000, if (!(nvkm_rd32(device, 0x61a004 + doff) & 0x80000000)) break; );
int nv50_pior_power(NV50_DISP_MTHD_V1) { struct nvkm_device *device = disp->base.engine.subdev.device; const u32 soff = outp->or * 0x800; union { struct nv50_disp_pior_pwr_v0 v0; } *args = data; u32 ctrl, type; int ret; nvif_ioctl(object, "disp pior pwr size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nvif_ioctl(object, "disp pior pwr vers %d state %d type %x\n", args->v0.version, args->v0.state, args->v0.type); if (args->v0.type > 0x0f) return -EINVAL; ctrl = !!args->v0.state; type = args->v0.type; } else return ret; nvkm_msec(device, 2000, if (!(nvkm_rd32(device, 0x61e004 + soff) & 0x80000000)) break; );
static int nvkm_ioctl_sclass(struct nouveau_handle *handle, void *data, u32 size) { struct nouveau_object *object = handle->object; union { struct nvif_ioctl_sclass_v0 v0; } *args = data; int ret; if (!nv_iclass(object, NV_PARENT_CLASS)) { nv_debug(object, "cannot have children (sclass)\n"); return -ENODEV; } nv_ioctl(object, "sclass size %d\n", size); if (nvif_unpack(args->v0, 0, 0, true)) { nv_ioctl(object, "sclass vers %d count %d\n", args->v0.version, args->v0.count); if (size == args->v0.count * sizeof(args->v0.oclass[0])) { ret = nouveau_parent_lclass(object, args->v0.oclass, args->v0.count); if (ret >= 0) { args->v0.count = ret; ret = 0; } } else { ret = -EINVAL; } } return ret; }
int tu104_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_object **pobject) { struct nvkm_object *parent = oclass->parent; union { struct volta_channel_gpfifo_a_v0 v0; } *args = data; int ret = -ENOSYS; nvif_ioctl(parent, "create channel gpfifo size %d\n", size); 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 priv %d\n", args->v0.version, args->v0.vmm, args->v0.ioffset, args->v0.ilength, args->v0.runlist, args->v0.priv); if (args->v0.priv && !oclass->client->super) return -EINVAL; return gv100_fifo_gpfifo_new_(&tu104_fifo_gpfifo, fifo, &args->v0.runlist, &args->v0.chid, args->v0.vmm, args->v0.ioffset, args->v0.ilength, &args->v0.inst, args->v0.priv, &args->v0.token, oclass, pobject); } return ret; }
int nv50_disp_base_new(const struct nv50_disp_dmac_func *func, const struct nv50_disp_chan_mthd *mthd, struct nv50_disp_root *root, int chid, const struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_object **pobject) { union { struct nv50_disp_base_channel_dma_v0 v0; } *args = data; struct nvkm_object *parent = oclass->parent; struct nv50_disp *disp = root->disp; int head, ret = -ENOSYS; u64 push; nvif_ioctl(parent, "create disp base channel dma size %d\n", size); if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { nvif_ioctl(parent, "create disp base channel dma vers %d " "pushbuf %016llx head %d\n", args->v0.version, args->v0.pushbuf, args->v0.head); if (!nvkm_head_find(&disp->base, args->v0.head)) return -EINVAL; push = args->v0.pushbuf; head = args->v0.head; } else return ret; return nv50_disp_dmac_new_(func, mthd, root, chid + head, head, push, oclass, pobject); }
int nv50_dac_power(NV50_DISP_MTHD_V1) { const u32 doff = outp->or * 0x800; union { struct nv50_disp_dac_pwr_v0 v0; } *args = data; u32 stat; int ret; nv_ioctl(object, "disp dac pwr size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nv_ioctl(object, "disp dac pwr vers %d state %d data %d " "vsync %d hsync %d\n", args->v0.version, args->v0.state, args->v0.data, args->v0.vsync, args->v0.hsync); stat = 0x00000040 * !args->v0.state; stat |= 0x00000010 * !args->v0.data; stat |= 0x00000004 * !args->v0.vsync; stat |= 0x00000001 * !args->v0.hsync; } else return ret; nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); nv_mask(priv, 0x61a004 + doff, 0xc000007f, 0x80000000 | stat); nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); return 0; }
int nvkm_ioctl(struct nvkm_client *client, bool supervisor, void *data, u32 size, void **hack) { struct nvkm_object *object = &client->object; union { struct nvif_ioctl_v0 v0; } *args = data; int ret; client->super = supervisor; nvif_ioctl(object, "size %d\n", size); if (nvif_unpack(args->v0, 0, 0, true)) { nvif_ioctl(object, "vers %d type %02x object %016llx owner %02x\n", args->v0.version, args->v0.type, args->v0.object, args->v0.owner); ret = nvkm_ioctl_path(client, args->v0.object, args->v0.type, data, size, args->v0.owner, &args->v0.route, &args->v0.token); } nvif_ioctl(object, "return %d\n", ret); if (hack) { *hack = client->data; client->data = NULL; } client->super = false; return ret; }
static int nvkm_ioctl_sclass(struct nvkm_object *object, void *data, u32 size) { union { struct nvif_ioctl_sclass_v0 v0; } *args = data; struct nvkm_oclass oclass; int ret, i = 0; nvif_ioctl(object, "sclass size %d\n", size); if (nvif_unpack(args->v0, 0, 0, true)) { nvif_ioctl(object, "sclass vers %d count %d\n", args->v0.version, args->v0.count); if (size != args->v0.count * sizeof(args->v0.oclass[0])) return -EINVAL; while (object->func->sclass && object->func->sclass(object, i, &oclass) >= 0) { if (i < args->v0.count) { args->v0.oclass[i].oclass = oclass.base.oclass; args->v0.oclass[i].minver = oclass.base.minver; args->v0.oclass[i].maxver = oclass.base.maxver; } i++; } args->v0.count = i; } return ret; }
int nv50_disp_oimm_new(const struct nv50_disp_chan_func *func, const struct nv50_disp_chan_mthd *mthd, struct nv50_disp_root *root, int ctrl, int user, const struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_object **pobject) { union { struct nv50_disp_overlay_v0 v0; } *args = data; struct nvkm_object *parent = oclass->parent; struct nv50_disp *disp = root->disp; int head, ret = -ENOSYS; nvif_ioctl(parent, "create disp overlay size %d\n", size); if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { nvif_ioctl(parent, "create disp overlay vers %d head %d\n", args->v0.version, args->v0.head); if (!nvkm_head_find(&disp->base, args->v0.head)) return -EINVAL; head = args->v0.head; } else return ret; return nv50_disp_chan_new_(func, mthd, root, ctrl + head, user + head, head, oclass, pobject); }
static int nvkm_ioctl_ntfy_new(struct nouveau_handle *handle, void *data, u32 size) { struct nouveau_client *client = nouveau_client(handle->object); struct nouveau_object *object = handle->object; struct nouveau_ofuncs *ofuncs = object->oclass->ofuncs; union { struct nvif_ioctl_ntfy_new_v0 v0; } *args = data; struct nvkm_event *event; int ret; nv_ioctl(object, "ntfy new size %d\n", size); if (nvif_unpack(args->v0, 0, 0, true)) { nv_ioctl(object, "ntfy new vers %d event %02x\n", args->v0.version, args->v0.event); if (ret = -ENODEV, ofuncs->ntfy) ret = ofuncs->ntfy(object, args->v0.event, &event); if (ret == 0) { ret = nvkm_client_notify_new(client, event, data, size); if (ret >= 0) { args->v0.index = ret; ret = 0; } } } return ret; }
int gf119_disp_root_scanoutpos(NV50_DISP_MTHD_V0) { struct nvkm_device *device = disp->base.engine.subdev.device; const u32 total = nvkm_rd32(device, 0x640414 + (head * 0x300)); const u32 blanke = nvkm_rd32(device, 0x64041c + (head * 0x300)); const u32 blanks = nvkm_rd32(device, 0x640420 + (head * 0x300)); union { struct nv04_disp_scanoutpos_v0 v0; } *args = data; int ret; nvif_ioctl(object, "disp scanoutpos size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nvif_ioctl(object, "disp scanoutpos vers %d\n", args->v0.version); args->v0.vblanke = (blanke & 0xffff0000) >> 16; args->v0.hblanke = (blanke & 0x0000ffff); args->v0.vblanks = (blanks & 0xffff0000) >> 16; args->v0.hblanks = (blanks & 0x0000ffff); args->v0.vtotal = ( total & 0xffff0000) >> 16; args->v0.htotal = ( total & 0x0000ffff); args->v0.time[0] = ktime_to_ns(ktime_get()); args->v0.vline = /* vline read locks hline */ nvkm_rd32(device, 0x616340 + (head * 0x800)) & 0xffff; args->v0.time[1] = ktime_to_ns(ktime_get()); args->v0.hline = nvkm_rd32(device, 0x616344 + (head * 0x800)) & 0xffff; } else
static int nvkm_ioctl_ntfy_new(struct nvkm_object *object, void *data, u32 size) { union { struct nvif_ioctl_ntfy_new_v0 v0; } *args = data; struct nvkm_event *event; int ret; nvif_ioctl(object, "ntfy new size %d\n", size); if (nvif_unpack(args->v0, 0, 0, true)) { nvif_ioctl(object, "ntfy new vers %d event %02x\n", args->v0.version, args->v0.event); ret = nvkm_object_ntfy(object, args->v0.event, &event); if (ret == 0) { ret = nvkm_client_notify_new(object, event, data, size); if (ret >= 0) { args->v0.index = ret; ret = 0; } } } return ret; }
static int nvkm_ioctl_wr(struct nvkm_object *object, void *data, u32 size) { union { struct nvif_ioctl_wr_v0 v0; } *args = data; int ret; nvif_ioctl(object, "wr size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nvif_ioctl(object, "wr vers %d size %d addr %016llx data %08x\n", args->v0.version, args->v0.size, args->v0.addr, args->v0.data); } else return ret; switch (args->v0.size) { case 1: return nvkm_object_wr08(object, args->v0.addr, args->v0.data); case 2: return nvkm_object_wr16(object, args->v0.addr, args->v0.data); case 4: return nvkm_object_wr32(object, args->v0.addr, args->v0.data); default: break; } return -EINVAL; }
int nv50_pior_power(NV50_DISP_MTHD_V1) { const u32 soff = outp->or * 0x800; union { struct nv50_disp_pior_pwr_v0 v0; } *args = data; u32 ctrl, type; int ret; nv_ioctl(object, "disp pior pwr size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nv_ioctl(object, "disp pior pwr vers %d state %d type %x\n", args->v0.version, args->v0.state, args->v0.type); if (args->v0.type > 0x0f) return -EINVAL; ctrl = !!args->v0.state; type = args->v0.type; } else return ret; nv_wait(priv, 0x61e004 + soff, 0x80000000, 0x00000000); nv_mask(priv, 0x61e004 + soff, 0x80000101, 0x80000000 | ctrl); nv_wait(priv, 0x61e004 + soff, 0x80000000, 0x00000000); priv->pior.type[outp->or] = type; return 0; }
static int nv04_disp_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size) { struct nv04_disp_root *root = nv04_disp_root(object); union { struct nv04_disp_mthd_v0 v0; } *args = data; struct nvkm_head *head; int id, ret = -ENOSYS; nvif_ioctl(object, "disp mthd size %d\n", size); if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) { nvif_ioctl(object, "disp mthd vers %d mthd %02x head %d\n", args->v0.version, args->v0.method, args->v0.head); mthd = args->v0.method; id = args->v0.head; } else return ret; if (!(head = nvkm_head_find(root->disp, id))) return -ENXIO; switch (mthd) { case NV04_DISP_SCANOUTPOS: return nvkm_head_mthd_scanoutpos(object, head, data, size); default: break; } return -EINVAL; }
int nv50_disp_oimm_new(const struct nv50_disp_chan_func *func, const struct nv50_disp_chan_mthd *mthd, struct nv50_disp_root *root, int chid, const struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_object **pobject) { union { struct nv50_disp_overlay_v0 v0; } *args = data; struct nvkm_object *parent = oclass->parent; struct nv50_disp *disp = root->disp; int head, ret; nvif_ioctl(parent, "create disp overlay size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nvif_ioctl(parent, "create disp overlay vers %d head %d\n", args->v0.version, args->v0.head); if (args->v0.head > disp->base.head.nr) return -EINVAL; head = args->v0.head; } else return ret; return nv50_disp_chan_new_(func, mthd, root, chid + head, head, oclass, pobject); }
int nvkm_ioctl(struct nouveau_client *client, bool supervisor, void *data, u32 size, void **hack) { union { struct nvif_ioctl_v0 v0; } *args = data; int ret; client->super = supervisor; nv_ioctl(client, "size %d\n", size); if (nvif_unpack(args->v0, 0, 0, true)) { nv_ioctl(client, "vers %d type %02x path %d owner %02x\n", args->v0.version, args->v0.type, args->v0.path_nr, args->v0.owner); ret = nvkm_ioctl_path(client->root, args->v0.type, args->v0.path_nr, args->v0.path, data, size, args->v0.owner, &args->v0.route, &args->v0.token); } nv_ioctl(client, "return %d\n", ret); if (hack) { *hack = client->data; client->data = NULL; } client->super = false; return ret; }
static int gv100_disp_wimm_new_(const struct nv50_disp_chan_func *func, const struct nv50_disp_chan_mthd *mthd, struct nv50_disp *disp, int chid, const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject) { union { struct nvc37b_window_imm_channel_dma_v0 v0; } *args = argv; struct nvkm_object *parent = oclass->parent; int wndw, ret = -ENOSYS; u64 push; nvif_ioctl(parent, "create window imm channel dma size %d\n", argc); if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) { nvif_ioctl(parent, "create window imm channel dma vers %d " "pushbuf %016llx index %d\n", args->v0.version, args->v0.pushbuf, args->v0.index); if (!(disp->wndw.mask & BIT(args->v0.index))) return -EINVAL; push = args->v0.pushbuf; wndw = args->v0.index; } else return ret; return nv50_disp_dmac_new_(func, mthd, disp, chid + wndw, wndw, push, oclass, pobject); }
static int nv40_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_object **pobject) { struct nvkm_object *parent = oclass->parent; union { struct nv03_channel_dma_v0 v0; } *args = data; struct nv04_fifo *fifo = nv04_fifo(base); struct nv04_fifo_chan *chan = NULL; struct nvkm_device *device = fifo->base.engine.subdev.device; struct nvkm_instmem *imem = device->imem; int 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 %08x\n", args->v0.version, args->v0.pushbuf, args->v0.offset); if (!args->v0.pushbuf) return -EINVAL; } else return ret; if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL))) return -ENOMEM; *pobject = &chan->base.object; ret = nvkm_fifo_chan_ctor(&nv40_fifo_dma_func, &fifo->base, 0x1000, 0x1000, false, 0, args->v0.pushbuf, (1ULL << NVKM_ENGINE_DMAOBJ) | (1ULL << NVKM_ENGINE_GR) | (1ULL << NVKM_ENGINE_MPEG) | (1ULL << NVKM_ENGINE_SW), 0, 0xc00000, 0x1000, oclass, &chan->base); chan->fifo = fifo; if (ret) return ret; args->v0.chid = chan->base.chid; chan->ramfc = chan->base.chid * 128; nvkm_kmap(imem->ramfc); nvkm_wo32(imem->ramfc, chan->ramfc + 0x00, args->v0.offset); nvkm_wo32(imem->ramfc, chan->ramfc + 0x04, args->v0.offset); nvkm_wo32(imem->ramfc, chan->ramfc + 0x0c, chan->base.push->addr >> 4); nvkm_wo32(imem->ramfc, chan->ramfc + 0x18, 0x30000000 | NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | #ifdef __BIG_ENDIAN NV_PFIFO_CACHE1_BIG_ENDIAN | #endif NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8); nvkm_wo32(imem->ramfc, chan->ramfc + 0x3c, 0x0001ffff); nvkm_done(imem->ramfc); return 0; }
int gk104_hdmi_ctrl(NV50_DISP_MTHD_V1) { struct nvkm_device *device = disp->base.engine.subdev.device; const u32 hoff = (head * 0x800); const u32 hdmi = (head * 0x400); union { struct nv50_disp_sor_hdmi_pwr_v0 v0; } *args = data; u32 ctrl; int ret; nvif_ioctl(object, "disp sor hdmi ctrl size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nvif_ioctl(object, "disp sor hdmi ctrl vers %d state %d " "max_ac_packet %d rekey %d\n", args->v0.version, args->v0.state, args->v0.max_ac_packet, args->v0.rekey); if (args->v0.max_ac_packet > 0x1f || args->v0.rekey > 0x7f) return -EINVAL; ctrl = 0x40000000 * !!args->v0.state; ctrl |= args->v0.max_ac_packet << 16; ctrl |= args->v0.rekey; } else return ret; if (!(ctrl & 0x40000000)) { nvkm_mask(device, 0x616798 + hoff, 0x40000000, 0x00000000); nvkm_mask(device, 0x6900c0 + hdmi, 0x00000001, 0x00000000); nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000000); return 0; } /* AVI InfoFrame */ nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000000); nvkm_wr32(device, 0x690008 + hdmi, 0x000d0282); nvkm_wr32(device, 0x69000c + hdmi, 0x0000006f); nvkm_wr32(device, 0x690010 + hdmi, 0x00000000); nvkm_wr32(device, 0x690014 + hdmi, 0x00000000); nvkm_wr32(device, 0x690018 + hdmi, 0x00000000); nvkm_mask(device, 0x690000 + hdmi, 0x00000001, 0x00000001); /* ??? InfoFrame? */ nvkm_mask(device, 0x6900c0 + hdmi, 0x00000001, 0x00000000); nvkm_wr32(device, 0x6900cc + hdmi, 0x00000010); nvkm_mask(device, 0x6900c0 + hdmi, 0x00000001, 0x00000001); /* ??? */ nvkm_wr32(device, 0x690080 + hdmi, 0x82000000); /* HDMI_CTRL */ nvkm_mask(device, 0x616798 + hoff, 0x401f007f, ctrl); return 0; }
static int nv10_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine, struct nvkm_oclass *oclass, void *data, u32 size, struct nvkm_object **pobject) { union { struct nv03_channel_dma_v0 v0; } *args = data; struct nv04_fifo_priv *priv = (void *)engine; struct nv04_fifo_chan *chan; int ret; nv_ioctl(parent, "create channel dma size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nv_ioctl(parent, "create channel dma vers %d pushbuf %08x " "offset %016llx\n", args->v0.version, args->v0.pushbuf, args->v0.offset); } else return ret; ret = nvkm_fifo_channel_create(parent, engine, oclass, 0, 0x800000, 0x10000, args->v0.pushbuf, (1ULL << NVDEV_ENGINE_DMAOBJ) | (1ULL << NVDEV_ENGINE_SW) | (1ULL << NVDEV_ENGINE_GR), &chan); *pobject = nv_object(chan); if (ret) return ret; args->v0.chid = chan->base.chid; nv_parent(chan)->object_attach = nv04_fifo_object_attach; nv_parent(chan)->object_detach = nv04_fifo_object_detach; nv_parent(chan)->context_attach = nv04_fifo_context_attach; chan->ramfc = chan->base.chid * 32; nv_wo32(priv->ramfc, chan->ramfc + 0x00, args->v0.offset); nv_wo32(priv->ramfc, chan->ramfc + 0x04, args->v0.offset); nv_wo32(priv->ramfc, chan->ramfc + 0x0c, chan->base.pushgpu->addr >> 4); nv_wo32(priv->ramfc, chan->ramfc + 0x14, NV_PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES | NV_PFIFO_CACHE1_DMA_FETCH_SIZE_128_BYTES | #ifdef __BIG_ENDIAN NV_PFIFO_CACHE1_BIG_ENDIAN | #endif NV_PFIFO_CACHE1_DMA_FETCH_MAX_REQS_8); return 0; }
static int nvkm_ioctl_nop(struct nvkm_object *object, void *data, u32 size) { union { struct nvif_ioctl_nop_v0 v0; } *args = data; int ret; nvif_ioctl(object, "nop size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nvif_ioctl(object, "nop vers %lld\n", args->v0.version); args->v0.version = NVIF_VERSION_LATEST; } return ret; }
static int nvkm_ioctl_mthd(struct nvkm_object *object, void *data, u32 size) { union { struct nvif_ioctl_mthd_v0 v0; } *args = data; int ret; nvif_ioctl(object, "mthd size %d\n", size); if (nvif_unpack(args->v0, 0, 0, true)) { nvif_ioctl(object, "mthd vers %d mthd %02x\n", args->v0.version, args->v0.method); ret = nvkm_object_mthd(object, args->v0.method, data, size); } return ret; }
static int nvkm_ioctl_map(struct nvkm_object *object, void *data, u32 size) { union { struct nvif_ioctl_map_v0 v0; } *args = data; int ret; nvif_ioctl(object, "map size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nvif_ioctl(object, "map vers %d\n", args->v0.version); ret = nvkm_object_map(object, &args->v0.handle, &args->v0.length); } return ret; }
static int gf100_fermi_mthd_zbc_color(struct nvkm_object *object, void *data, u32 size) { struct gf100_gr *gr = (void *)object->engine; union { struct fermi_a_zbc_color_v0 v0; } *args = data; int ret; if (nvif_unpack(args->v0, 0, 0, false)) { switch (args->v0.format) { case FERMI_A_ZBC_COLOR_V0_FMT_ZERO: case FERMI_A_ZBC_COLOR_V0_FMT_UNORM_ONE: case FERMI_A_ZBC_COLOR_V0_FMT_RF32_GF32_BF32_AF32: case FERMI_A_ZBC_COLOR_V0_FMT_R16_G16_B16_A16: case FERMI_A_ZBC_COLOR_V0_FMT_RN16_GN16_BN16_AN16: case FERMI_A_ZBC_COLOR_V0_FMT_RS16_GS16_BS16_AS16: case FERMI_A_ZBC_COLOR_V0_FMT_RU16_GU16_BU16_AU16: case FERMI_A_ZBC_COLOR_V0_FMT_RF16_GF16_BF16_AF16: case FERMI_A_ZBC_COLOR_V0_FMT_A8R8G8B8: case FERMI_A_ZBC_COLOR_V0_FMT_A8RL8GL8BL8: case FERMI_A_ZBC_COLOR_V0_FMT_A2B10G10R10: case FERMI_A_ZBC_COLOR_V0_FMT_AU2BU10GU10RU10: case FERMI_A_ZBC_COLOR_V0_FMT_A8B8G8R8: case FERMI_A_ZBC_COLOR_V0_FMT_A8BL8GL8RL8: case FERMI_A_ZBC_COLOR_V0_FMT_AN8BN8GN8RN8: case FERMI_A_ZBC_COLOR_V0_FMT_AS8BS8GS8RS8: case FERMI_A_ZBC_COLOR_V0_FMT_AU8BU8GU8RU8: case FERMI_A_ZBC_COLOR_V0_FMT_A2R10G10B10: case FERMI_A_ZBC_COLOR_V0_FMT_BF10GF11RF11: ret = gf100_gr_zbc_color_get(gr, args->v0.format, args->v0.ds, args->v0.l2); if (ret >= 0) { args->v0.index = ret; return 0; } break; default: return -EINVAL; } } return ret; }
static int nvkm_ioctl_ntfy_put(struct nvkm_object *object, void *data, u32 size) { struct nvkm_client *client = object->client; union { struct nvif_ioctl_ntfy_put_v0 v0; } *args = data; int ret; nvif_ioctl(object, "ntfy put size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nvif_ioctl(object, "ntfy put vers %d index %d\n", args->v0.version, args->v0.index); ret = nvkm_client_notify_put(client, args->v0.index); } return ret; }
static int nvkm_udevice_time(struct nvkm_udevice *udev, void *data, u32 size) { struct nvkm_object *object = &udev->object; struct nvkm_device *device = udev->device; union { struct nv_device_time_v0 v0; } *args = data; int ret = -ENOSYS; nvif_ioctl(object, "device time size %d\n", size); if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { nvif_ioctl(object, "device time vers %d\n", args->v0.version); args->v0.time = nvkm_timer_read(device->timer); } return ret; }
static int nvkm_ioctl_ntfy_get(struct nouveau_handle *handle, void *data, u32 size) { struct nouveau_client *client = nouveau_client(handle->object); struct nouveau_object *object = handle->object; union { struct nvif_ioctl_ntfy_get_v0 v0; } *args = data; int ret; nv_ioctl(object, "ntfy get size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nv_ioctl(object, "ntfy get vers %d index %d\n", args->v0.version, args->v0.index); ret = nvkm_client_notify_get(client, args->v0.index); } return ret; }
static int nvkm_ioctl_wr(struct nouveau_handle *handle, void *data, u32 size) { struct nouveau_object *object = handle->object; struct nouveau_ofuncs *ofuncs = object->oclass->ofuncs; union { struct nvif_ioctl_wr_v0 v0; } *args = data; int ret; nv_ioctl(object, "wr size %d\n", size); if (nvif_unpack(args->v0, 0, 0, false)) { nv_ioctl(object, "wr vers %d size %d addr %016llx data %08x\n", args->v0.version, args->v0.size, args->v0.addr, args->v0.data); switch (args->v0.size) { case 1: if (ret = -ENODEV, ofuncs->wr08) { nv_wo08(object, args->v0.addr, args->v0.data); ret = 0; } break; case 2: if (ret = -ENODEV, ofuncs->wr16) { nv_wo16(object, args->v0.addr, args->v0.data); ret = 0; } break; case 4: if (ret = -ENODEV, ofuncs->wr32) { nv_wo32(object, args->v0.addr, args->v0.data); ret = 0; } break; default: ret = -EINVAL; break; } } return ret; }