Пример #1
0
int
nouveau_i2c_port_create_(struct nouveau_object *parent,
			 struct nouveau_object *engine,
			 struct nouveau_oclass *oclass, u8 index,
			 const struct i2c_algorithm *algo,
			 int size, void **pobject)
{
	struct nouveau_device *device = nv_device(parent);
	struct nouveau_i2c *i2c = (void *)engine;
	struct nouveau_i2c_port *port;
	int ret;

	ret = nouveau_object_create_(parent, engine, oclass, 0, size, pobject);
	port = *pobject;
	if (ret)
		return ret;

	snprintf(port->adapter.name, sizeof(port->adapter.name),
		 "nouveau-%s-%d", device->name, index);
	port->adapter.owner = THIS_MODULE;
	port->adapter.dev.parent = &device->pdev->dev;
	port->index = index;
	i2c_set_adapdata(&port->adapter, i2c);

	if ( algo == &nouveau_i2c_bit_algo &&
	    !nouveau_boolopt(device->cfgopt, "NvI2C", CSTMSEL)) {
		struct i2c_algo_bit_data *bit;

		bit = kzalloc(sizeof(*bit), GFP_KERNEL);
		if (!bit)
			return -ENOMEM;

		bit->udelay = 10;
		bit->timeout = usecs_to_jiffies(2200);
		bit->data = port;
		bit->pre_xfer = nouveau_i2c_pre_xfer;
		bit->setsda = nouveau_i2c_setsda;
		bit->setscl = nouveau_i2c_setscl;
		bit->getsda = nouveau_i2c_getsda;
		bit->getscl = nouveau_i2c_getscl;

		port->adapter.algo_data = bit;
		ret = i2c_bit_add_bus(&port->adapter);
	} else {
		port->adapter.algo_data = port;
		port->adapter.algo = algo;
		ret = i2c_add_adapter(&port->adapter);
	}

	/* drop port's i2c subdev refcount, i2c handles this itself */
	if (ret == 0) {
		list_add_tail(&port->head, &i2c->ports);
		atomic_dec(&parent->refcount);
		atomic_dec(&engine->refcount);
	}

	return ret;
}
Пример #2
0
static int
nvc0_ram_prog(struct nouveau_fb *pfb)
{
	struct nouveau_device *device = nv_device(pfb);
	struct nvc0_ram *ram = (void *)pfb->ram;
	struct nvc0_ramfuc *fuc = &ram->fuc;
	ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false));
	return 0;
}
Пример #3
0
static int
nve0_ram_prog(struct nouveau_fb *pfb)
{
	struct nouveau_device *device = nv_device(pfb);
	struct nve0_ram *ram = (void *)pfb->ram;
	struct nve0_ramfuc *fuc = &ram->fuc;
	ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", true));
	return (ram->base.next == &ram->base.xition);
}
Пример #4
0
int
nouveau_i2c_port_create_(struct nouveau_object *parent,
			 struct nouveau_object *engine,
			 struct nouveau_oclass *oclass, u8 index,
			 const struct i2c_algorithm *algo,
			 const struct nouveau_i2c_func *func,
			 int size, void **pobject)
{
	struct nouveau_device *device = nv_device(engine);
	struct nouveau_i2c *i2c = (void *)engine;
	struct nouveau_i2c_port *port;
	int ret;

	ret = nouveau_object_create_(parent, engine, oclass, 0, size, pobject);
	port = *pobject;
	if (ret)
		return ret;

	snprintf(port->adapter.name, sizeof(port->adapter.name),
		 "nouveau-%s-%d", device->name, index);
	port->adapter.owner = THIS_MODULE;
	port->adapter.dev.parent = nv_device_base(device);
	port->index = index;
	port->aux = -1;
	port->func = func;
	mutex_init(&port->mutex);

	if ( algo == &nouveau_i2c_bit_algo &&
	    !nouveau_boolopt(device->cfgopt, "NvI2C", CSTMSEL)) {
		struct i2c_algo_bit_data *bit;

		bit = kzalloc(sizeof(*bit), GFP_KERNEL);
		if (!bit)
			return -ENOMEM;

		bit->udelay = 10;
		bit->timeout = usecs_to_jiffies(2200);
		bit->data = port;
		bit->pre_xfer = nouveau_i2c_pre_xfer;
		bit->post_xfer = nouveau_i2c_post_xfer;
		bit->setsda = nouveau_i2c_setsda;
		bit->setscl = nouveau_i2c_setscl;
		bit->getsda = nouveau_i2c_getsda;
		bit->getscl = nouveau_i2c_getscl;

		port->adapter.algo_data = bit;
		ret = i2c_bit_add_bus(&port->adapter);
	} else {
		port->adapter.algo_data = port;
		port->adapter.algo = algo;
		ret = i2c_add_adapter(&port->adapter);
	}

	if (ret == 0)
		list_add_tail(&port->head, &i2c->ports);
	return ret;
}
Пример #5
0
int
nouveau_engine_create_(struct nouveau_object *parent,
		       struct nouveau_object *engobj,
		       struct nouveau_oclass *oclass, bool enable,
		       const char *iname, const char *fname,
		       int length, void **pobject)
{
	struct nouveau_engine *engine;
	int ret;

	ret = nouveau_subdev_create_(parent, engobj, oclass, NV_ENGINE_CLASS,
				     iname, fname, length, pobject);
	engine = *pobject;
	if (ret)
		return ret;

	if (parent) {
		struct nouveau_device *device = nv_device(parent);
		int engidx = nv_engidx(nv_object(engine));

		if (device->disable_mask & (1ULL << engidx)) {
			if (!nouveau_boolopt(device->cfgopt, iname, false)) {
				nv_debug(engine, "engine disabled by hw/fw\n");
				return -ENODEV;
			}

			nv_warn(engine, "ignoring hw/fw engine disable\n");
		}

		if (!nouveau_boolopt(device->cfgopt, iname, enable)) {
			if (!enable)
				nv_warn(engine, "disabled, %s=1 to enable\n", iname);
			return -ENODEV;
		}
	}

	INIT_LIST_HEAD(&engine->contexts);
	spin_lock_init(&engine->lock);
	return 0;
}
Пример #6
0
static int
nv41_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
		struct nouveau_oclass *oclass, void *data, u32 size,
		struct nouveau_object **pobject)
{
	struct nouveau_device *device = nv_device(parent);
	struct nv04_vmmgr_priv *priv;
	int ret;

	if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) ||
	    !nouveau_boolopt(device->cfgopt, "NvPCIE", true)) {
		return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass,
					   data, size, pobject);
	}

	ret = nouveau_vmmgr_create(parent, engine, oclass, "PCIEGART",
				   "pciegart", &priv);
	*pobject = nv_object(priv);
	if (ret)
		return ret;

	priv->base.create = nv04_vm_create;
	priv->base.limit = NV41_GART_SIZE;
	priv->base.dma_bits = 39;
	priv->base.pgt_bits = 32 - 12;
	priv->base.spg_shift = 12;
	priv->base.lpg_shift = 12;
	priv->base.map_sg = nv41_vm_map_sg;
	priv->base.unmap = nv41_vm_unmap;
	priv->base.flush = nv41_vm_flush;

	ret = nouveau_vm_create(&priv->base, 0, NV41_GART_SIZE, 0, 4096,
				&priv->vm);
	if (ret)
		return ret;

	ret = nouveau_gpuobj_new(nv_object(priv), NULL,
				(NV41_GART_SIZE / NV41_GART_PAGE) * 4,
				 16, NVOBJ_FLAG_ZERO_ALLOC,
				 &priv->vm->pgt[0].obj[0]);
	priv->vm->pgt[0].refcount[0] = 1;
	if (ret)
		return ret;

	return 0;
}
Пример #7
0
int
nouveau_devinit_create_(struct nouveau_object *parent,
			struct nouveau_object *engine,
			struct nouveau_oclass *oclass,
			int size, void **pobject)
{
	struct nouveau_devinit_impl *impl = (void *)oclass;
	struct nouveau_device *device = nv_device(parent);
	struct nouveau_devinit *devinit;
	int ret;

	ret = nouveau_subdev_create_(parent, engine, oclass, 0, "DEVINIT",
				     "init", size, pobject);
	devinit = *pobject;
	if (ret)
		return ret;

	devinit->post = nouveau_boolopt(device->cfgopt, "NvForcePost", false);
	devinit->meminit = impl->meminit;
	devinit->pll_set = impl->pll_set;
	devinit->mmio    = impl->mmio;
	return 0;
}
Пример #8
0
int
nouveau_fanpwm_create(struct nouveau_therm *therm, struct dcb_gpio_func *func)
{
	struct nouveau_device *device = nv_device(therm);
	struct nouveau_therm_priv *tpriv = (void *)therm;
	struct nouveau_fanpwm_priv *priv;
	u32 divs, duty;

	if (!nouveau_boolopt(device->cfgopt, "NvFanPWM", func->param) ||
	    !therm->pwm_ctrl ||
	     therm->pwm_get(therm, func->line, &divs, &duty) == -ENODEV)
		return -ENODEV;

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	tpriv->fan = &priv->base;
	if (!priv)
		return -ENOMEM;

	priv->base.type = "PWM";
	priv->base.get = nouveau_fanpwm_get;
	priv->base.set = nouveau_fanpwm_set;
	priv->func = *func;
	return 0;
}
Пример #9
0
int
nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
		   struct nouveau_oclass *bclass, int length, void **pobject)
{
	const struct nouveau_mc_oclass *oclass = (void *)bclass;
	struct nouveau_device *device = nv_device(parent);
	struct nouveau_mc *pmc;
	int ret;

	ret = nouveau_subdev_create_(parent, engine, bclass, 0, "PMC",
				     "master", length, pobject);
	pmc = *pobject;
	if (ret)
		return ret;

	if (nv_device_is_pci(device))
		switch (device->pdev->device & 0x0ff0) {
		case 0x00f0:
		case 0x02e0:
			/* BR02? NFI how these would be handled yet exactly */
			break;
		default:
			switch (device->chipset) {
			case 0xaa:
				/* reported broken, nv also disable it */
				break;
			default:
				pmc->use_msi = true;
				break;
		}

		pmc->use_msi = nouveau_boolopt(device->cfgopt, "NvMSI",
					       pmc->use_msi);

		if (pmc->use_msi && oclass->msi_rearm) {
			pmc->use_msi = pci_enable_msi(device->pdev) == 0;
			if (pmc->use_msi) {
				nv_info(pmc, "MSI interrupts enabled\n");
				oclass->msi_rearm(pmc);
			}
		} else {
			pmc->use_msi = false;
		}
	}

#if defined(__NetBSD__)
	if (nv_device_is_pci(device)) {
		const pci_chipset_tag_t pc = device->pdev->pd_pa.pa_pc;
		pci_intr_handle_t ih;

		if (pci_intr_map(&device->pdev->pd_pa, &ih))
			return -EIO;

		pmc->irq_cookie = pci_intr_establish(pc, ih, IPL_VM,
		    &nouveau_mc_intr, pmc);
		if (pmc->irq_cookie == NULL)
			return -EIO;
#if defined (__arm__)
	} else {
		pmc->irq_cookie = intr_establish(TEGRA_INTR_GPU,
		    IPL_VM, IST_LEVEL, nouveau_mc_intr, pmc);
		if (pmc->irq_cookie == NULL)
			return -EIO;
#endif
	}
#else
	ret = nv_device_get_irq(device, true);
	if (ret < 0)
		return ret;
	pmc->irq = ret;

	ret = request_irq(pmc->irq, nouveau_mc_intr, IRQF_SHARED, "nouveau",
			  pmc);

	if (ret < 0)
		return ret;
#endif

	return 0;
}