Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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;
	);
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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);
}
Ejemplo n.º 10
0
static int
nvkm_ioctl_path(struct nvkm_client *client, u64 handle, u32 type,
		void *data, u32 size, u8 owner, u8 *route, u64 *token)
{
	struct nvkm_object *object;
	int ret;

	if (handle)
		object = nvkm_client_search(client, handle);
	else
		object = &client->object;
	if (unlikely(!object)) {
		nvif_ioctl(&client->object, "object not found\n");
		return -ENOENT;
	}

	if (owner != NVIF_IOCTL_V0_OWNER_ANY && owner != object->route) {
		nvif_ioctl(&client->object, "route != owner\n");
		return -EACCES;
	}
	*route = object->route;
	*token = object->token;

	if (ret = -EINVAL, type < ARRAY_SIZE(nvkm_ioctl_v0)) {
		if (nvkm_ioctl_v0[type].version == 0)
			ret = nvkm_ioctl_v0[type].func(object, data, size);
	}

	return ret;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
0
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);
}
Ejemplo n.º 13
0
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;
	);
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
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);
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
0
static int
nvkm_ioctl_unmap(struct nvkm_object *object, void *data, u32 size)
{
	union {
		struct nvif_ioctl_unmap none;
	} *args = data;
	int ret;

	nvif_ioctl(object, "unmap size %d\n", size);
	if (nvif_unvers(args->none)) {
		nvif_ioctl(object, "unmap\n");
	}

	return ret;
}
Ejemplo n.º 19
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;
}
Ejemplo n.º 20
0
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;
}
Ejemplo n.º 21
0
static int
nvkm_ioctl_del(struct nvkm_object *object, void *data, u32 size)
{
	union {
		struct nvif_ioctl_del none;
	} *args = data;
	int ret;

	nvif_ioctl(object, "delete size %d\n", size);
	if (nvif_unvers(args->none)) {
		nvif_ioctl(object, "delete\n");
		nvkm_object_fini(object, false);
		nvkm_object_del(&object);
	}

	return ret;
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
0
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;
}
Ejemplo n.º 24
0
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;
}
Ejemplo n.º 25
0
int
nvkm_udevice_new(const struct nvkm_oclass *oclass, void *data, u32 size,
		 struct nvkm_object **pobject)
{
	union {
		struct nv_device_v0 v0;
	} *args = data;
	struct nvkm_client *client = oclass->client;
	struct nvkm_object *parent = &client->object;
	const struct nvkm_object_func *func;
	struct nvkm_udevice *udev;
	int ret = -ENOSYS;

	nvif_ioctl(parent, "create device size %d\n", size);
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
		nvif_ioctl(parent, "create device v%d device %016llx\n",
			   args->v0.version, args->v0.device);
	} else
		return ret;

	/* give priviledged clients register access */
	if (client->super)
		func = &nvkm_udevice_super;
	else
		func = &nvkm_udevice;

	if (!(udev = kzalloc(sizeof(*udev), GFP_KERNEL)))
		return -ENOMEM;
	nvkm_object_ctor(func, oclass, &udev->object);
	*pobject = &udev->object;

	/* find the device that matches what the client requested */
	if (args->v0.device != ~0)
		udev->device = nvkm_device_find(args->v0.device);
	else
		udev->device = nvkm_device_find(client->device);
	if (!udev->device)
		return -ENODEV;

	return 0;
}
Ejemplo n.º 26
0
static int
nvkm_ioctl_rd(struct nvkm_object *object, void *data, u32 size)
{
	union {
		struct nvif_ioctl_rd_v0 v0;
	} *args = data;
	union {
		u8  b08;
		u16 b16;
		u32 b32;
	} v;
	int ret;

	nvif_ioctl(object, "rd size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, false)) {
		nvif_ioctl(object, "rd vers %d size %d addr %016llx\n",
			   args->v0.version, args->v0.size, args->v0.addr);
		switch (args->v0.size) {
		case 1:
			ret = nvkm_object_rd08(object, args->v0.addr, &v.b08);
			args->v0.data = v.b08;
			break;
		case 2:
			ret = nvkm_object_rd16(object, args->v0.addr, &v.b16);
			args->v0.data = v.b16;
			break;
		case 4:
			ret = nvkm_object_rd32(object, args->v0.addr, &v.b32);
			args->v0.data = v.b32;
			break;
		default:
			ret = -EINVAL;
			break;
		}
	}

	return ret;
}
Ejemplo n.º 27
0
static int
gf100_fermi_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
	nvif_ioctl(object, "fermi mthd %08x\n", mthd);
	switch (mthd) {
	case FERMI_A_ZBC_COLOR:
		return gf100_fermi_mthd_zbc_color(object, data, size);
	case FERMI_A_ZBC_DEPTH:
		return gf100_fermi_mthd_zbc_depth(object, data, size);
	default:
		break;
	}
	return -EINVAL;
}
Ejemplo n.º 28
0
static int
nvkm_udevice_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
	struct nvkm_udevice *udev = nvkm_udevice(object);
	nvif_ioctl(object, "device mthd %08x\n", mthd);
	switch (mthd) {
	case NV_DEVICE_V0_INFO:
		return nvkm_udevice_info(udev, data, size);
	case NV_DEVICE_V0_TIME:
		return nvkm_udevice_time(udev, data, size);
	default:
		break;
	}
	return -EINVAL;
}
Ejemplo n.º 29
0
int
gf100_dmaobj_new(struct nvkm_dma *dma, const struct nvkm_oclass *oclass,
		 void *data, u32 size, struct nvkm_dmaobj **pdmaobj)
{
	union {
		struct gf100_dma_v0 v0;
	} *args;
	struct nvkm_object *parent = oclass->parent;
	struct gf100_dmaobj *dmaobj;
	u32 kind, user, unkn;
	int ret;

	if (!(dmaobj = kzalloc(sizeof(*dmaobj), GFP_KERNEL)))
		return -ENOMEM;
	*pdmaobj = &dmaobj->base;

	ret = nvkm_dmaobj_ctor(&gf100_dmaobj_func, dma, oclass,
			       &data, &size, &dmaobj->base);
	if (ret)
		return ret;

	ret  = -ENOSYS;
	args = data;

	nvif_ioctl(parent, "create gf100 dma size %d\n", size);
	if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
		nvif_ioctl(parent,
			   "create gf100 dma vers %d priv %d kind %02x\n",
			   args->v0.version, args->v0.priv, args->v0.kind);
		kind = args->v0.kind;
		user = args->v0.priv;
		unkn = 0;
	} else
	if (size == 0) {
		if (dmaobj->base.target != NV_MEM_TARGET_VM) {
			kind = GF100_DMA_V0_KIND_PITCH;
			user = GF100_DMA_V0_PRIV_US;
			unkn = 2;
		} else {
			kind = GF100_DMA_V0_KIND_VM;
			user = GF100_DMA_V0_PRIV_VM;
			unkn = 0;
		}
	} else
		return ret;

	if (user > 2)
		return -EINVAL;
	dmaobj->flags0 |= (kind << 22) | (user << 20) | oclass->base.oclass;
	dmaobj->flags5 |= (unkn << 16);

	switch (dmaobj->base.target) {
	case NV_MEM_TARGET_VM:
		dmaobj->flags0 |= 0x00000000;
		break;
	case NV_MEM_TARGET_VRAM:
		dmaobj->flags0 |= 0x00010000;
		break;
	case NV_MEM_TARGET_PCI:
		dmaobj->flags0 |= 0x00020000;
		break;
	case NV_MEM_TARGET_PCI_NOSNOOP:
		dmaobj->flags0 |= 0x00030000;
		break;
	default:
		return -EINVAL;
	}

	switch (dmaobj->base.access) {
	case NV_MEM_ACCESS_VM:
		break;
	case NV_MEM_ACCESS_RO:
		dmaobj->flags0 |= 0x00040000;
		break;
	case NV_MEM_ACCESS_WO:
	case NV_MEM_ACCESS_RW:
		dmaobj->flags0 |= 0x00080000;
		break;
	}

	return 0;
}
Ejemplo n.º 30
0
int
nv50_dmaobj_new(struct nvkm_dma *dma, const struct nvkm_oclass *oclass,
		void *data, u32 size, struct nvkm_dmaobj **pdmaobj)
{
	union {
		struct nv50_dma_v0 v0;
	} *args;
	struct nvkm_object *parent = oclass->parent;
	struct nv50_dmaobj *dmaobj;
	u32 user, part, comp, kind;
	int ret;

	if (!(dmaobj = kzalloc(sizeof(*dmaobj), GFP_KERNEL)))
		return -ENOMEM;
	*pdmaobj = &dmaobj->base;

	ret = nvkm_dmaobj_ctor(&nv50_dmaobj_func, dma, oclass,
			       &data, &size, &dmaobj->base);
	if (ret)
		return ret;

	args = data;

	nvif_ioctl(parent, "create nv50 dma size %d\n", size);
	if (nvif_unpack(args->v0, 0, 0, false)) {
		nvif_ioctl(parent, "create nv50 dma vers %d priv %d part %d "
				   "comp %d kind %02x\n", args->v0.version,
			   args->v0.priv, args->v0.part, args->v0.comp,
			   args->v0.kind);
		user = args->v0.priv;
		part = args->v0.part;
		comp = args->v0.comp;
		kind = args->v0.kind;
	} else
	if (size == 0) {
		if (dmaobj->base.target != NV_MEM_TARGET_VM) {
			user = NV50_DMA_V0_PRIV_US;
			part = NV50_DMA_V0_PART_256;
			comp = NV50_DMA_V0_COMP_NONE;
			kind = NV50_DMA_V0_KIND_PITCH;
		} else {
			user = NV50_DMA_V0_PRIV_VM;
			part = NV50_DMA_V0_PART_VM;
			comp = NV50_DMA_V0_COMP_VM;
			kind = NV50_DMA_V0_KIND_VM;
		}
	} else
		return ret;

	if (user > 2 || part > 2 || comp > 3 || kind > 0x7f)
		return -EINVAL;
	dmaobj->flags0 = (comp << 29) | (kind << 22) | (user << 20) |
			 oclass->base.oclass;
	dmaobj->flags5 = (part << 16);

	switch (dmaobj->base.target) {
	case NV_MEM_TARGET_VM:
		dmaobj->flags0 |= 0x00000000;
		break;
	case NV_MEM_TARGET_VRAM:
		dmaobj->flags0 |= 0x00010000;
		break;
	case NV_MEM_TARGET_PCI:
		dmaobj->flags0 |= 0x00020000;
		break;
	case NV_MEM_TARGET_PCI_NOSNOOP:
		dmaobj->flags0 |= 0x00030000;
		break;
	default:
		return -EINVAL;
	}

	switch (dmaobj->base.access) {
	case NV_MEM_ACCESS_VM:
		break;
	case NV_MEM_ACCESS_RO:
		dmaobj->flags0 |= 0x00040000;
		break;
	case NV_MEM_ACCESS_WO:
	case NV_MEM_ACCESS_RW:
		dmaobj->flags0 |= 0x00080000;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}