Exemple #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
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;
	);
Exemple #4
0
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;
}
Exemple #5
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;
}
Exemple #6
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);
}
Exemple #7
0
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;
}
Exemple #10
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);
}
Exemple #11
0
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;
}
Exemple #15
0
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;
}
Exemple #16
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);
}
Exemple #18
0
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;
}
Exemple #19
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);
}
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;
}
Exemple #22
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;
}
Exemple #26
0
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;
}
Exemple #28
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;
}
Exemple #29
0
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;
}
Exemple #30
0
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;
}