Exemple #1
0
int
nvkm_ltc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
		 struct nouveau_oclass *oclass, int length, void **pobject)
{
	const struct nvkm_ltc_impl *impl = (void *)oclass;
	struct nvkm_ltc_priv *priv;
	int ret;

	ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PLTCG",
				     "l2c", length, pobject);
	priv = *pobject;
	if (ret)
		return ret;

	memset(priv->zbc_color, 0x00, sizeof(priv->zbc_color));
	memset(priv->zbc_depth, 0x00, sizeof(priv->zbc_depth));

	priv->base.base.intr = impl->intr;
	priv->base.tags_alloc = nvkm_ltc_tags_alloc;
	priv->base.tags_free = nvkm_ltc_tags_free;
	priv->base.tags_clear = nvkm_ltc_tags_clear;
	priv->base.zbc_min = 1; /* reserve 0 for disabled */
	priv->base.zbc_max = min(impl->zbc, NOUVEAU_LTC_MAX_ZBC_CNT) - 1;
	priv->base.zbc_color_get = nvkm_ltc_zbc_color_get;
	priv->base.zbc_depth_get = nvkm_ltc_zbc_depth_get;
	return 0;
}
Exemple #2
0
int
nouveau_therm_create_(struct nouveau_object *parent,
                      struct nouveau_object *engine,
                      struct nouveau_oclass *oclass,
                      int length, void **pobject)
{
    struct nouveau_therm_priv *priv;
    int ret;

    ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PTHERM",
                                 "therm", length, pobject);
    priv = *pobject;
    if (ret)
        return ret;

    nouveau_alarm_init(&priv->alarm, nouveau_therm_alarm);
    spin_lock_init(&priv->lock);
    spin_lock_init(&priv->sensor.alarm_program_lock);

    priv->base.fan_get = nouveau_therm_fan_user_get;
    priv->base.fan_set = nouveau_therm_fan_user_set;
    priv->base.fan_sense = nouveau_therm_fan_sense;
    priv->base.attr_get = nouveau_therm_attr_get;
    priv->base.attr_set = nouveau_therm_attr_set;
    priv->mode = priv->suspend = -1; /* undefined */
    return 0;
}
Exemple #3
0
int
nouveau_fb_create_(struct nouveau_object *parent, struct nouveau_object *engine,
		   struct nouveau_oclass *oclass, int length, void **pobject)
{
	struct nouveau_fb_impl *impl = (void *)oclass;
	static const char *name[] = {
		[NV_MEM_TYPE_UNKNOWN] = "unknown",
		[NV_MEM_TYPE_STOLEN ] = "stolen system memory",
		[NV_MEM_TYPE_SGRAM  ] = "SGRAM",
		[NV_MEM_TYPE_SDRAM  ] = "SDRAM",
		[NV_MEM_TYPE_DDR1   ] = "DDR1",
		[NV_MEM_TYPE_DDR2   ] = "DDR2",
		[NV_MEM_TYPE_DDR3   ] = "DDR3",
		[NV_MEM_TYPE_GDDR2  ] = "GDDR2",
		[NV_MEM_TYPE_GDDR3  ] = "GDDR3",
		[NV_MEM_TYPE_GDDR4  ] = "GDDR4",
		[NV_MEM_TYPE_GDDR5  ] = "GDDR5",
	};
	struct nouveau_object *ram;
	struct nouveau_fb *pfb;
	int ret;

	ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PFB", "fb",
				     length, pobject);
	pfb = *pobject;
	if (ret)
		return ret;

	pfb->memtype_valid = impl->memtype;

	ret = nouveau_object_ctor(nv_object(pfb), nv_object(pfb),
				  impl->ram, NULL, 0, &ram);
	if (ret) {
		nv_fatal(pfb, "error detecting memory configuration!!\n");
		return ret;
	}

	atomic_dec(&ram->parent->refcount);
	atomic_dec(&ram->engine->refcount);
	pfb->ram = (void *)ram;

	if (!nouveau_mm_initialised(&pfb->vram)) {
		ret = nouveau_mm_init(&pfb->vram, 0, pfb->ram->size >> 12, 1);
		if (ret)
			return ret;
	}
Exemple #4
0
int
nouveau_bar_create_(struct nouveau_object *parent,
		    struct nouveau_object *engine,
		    struct nouveau_oclass *oclass, int length, void **pobject)
{
	struct nouveau_device *device = nv_device(parent);
	struct nouveau_bar *bar;
	int ret;

	ret = nouveau_subdev_create_(parent, engine, oclass, 0, "BARCTL",
				     "bar", length, pobject);
	bar = *pobject;
	if (ret)
		return ret;

	bar->iomem = ioremap(pci_resource_start(device->pdev, 3),
			     pci_resource_len(device->pdev, 3));
	return 0;
}
int
nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
		   struct nouveau_oclass *oclass, int length, void **pobject)
{
	struct nouveau_device *device = nv_device(parent);
	struct nouveau_mc *pmc;
	int ret;

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

	ret = request_irq(device->pdev->irq, nouveau_mc_intr,
			  IRQF_SHARED, "nouveau", pmc);
	if (ret < 0)
		return ret;

	return 0;
}
Exemple #6
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;
}
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;
}
Exemple #8
0
int
nouveau_bar_create_(struct nouveau_object *parent,
		    struct nouveau_object *engine,
		    struct nouveau_oclass *oclass, int length, void **pobject)
{
	struct nouveau_device *device = nv_device(parent);
	struct nouveau_bar *bar;
	int ret;

	ret = nouveau_subdev_create_(parent, engine, oclass, 0, "BARCTL",
				     "bar", length, pobject);
	bar = *pobject;
	if (ret)
		return ret;

	if (nv_device_resource_len(device, 3) != 0) {
		bar->iomem = ioremap(nv_device_resource_start(device, 3),
				     nv_device_resource_len(device, 3));
		if (!bar->iomem)
			nv_warn(bar, "PRAMIN ioremap failed\n");
	}

	return 0;
}
int
nouveau_gpio_create_(struct nouveau_object *parent,
		     struct nouveau_object *engine,
		     struct nouveau_oclass *oclass, int lines,
		     int length, void **pobject)
{
	struct nouveau_gpio *gpio;
	int ret;

	ret = nouveau_subdev_create_(parent, engine, oclass, 0, "GPIO", "gpio",
				     length, pobject);
	gpio = *pobject;
	if (ret)
		return ret;

	ret = nouveau_event_create(lines, &gpio->events);
	if (ret)
		return ret;

	gpio->find = nouveau_gpio_find;
	gpio->set  = nouveau_gpio_set;
	gpio->get  = nouveau_gpio_get;
	return 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;
}
int
nouveau_volt_create_(struct nouveau_object *parent,
		     struct nouveau_object *engine,
		     struct nouveau_oclass *oclass, int length, void **pobject)
{
	struct nouveau_bios *bios = nouveau_bios(parent);
	struct nouveau_volt *volt;
	struct nvbios_volt_entry ivid;
	struct nvbios_volt info;
	u8  ver, hdr, cnt, len;
	u16 data;
	int ret, i;

	ret = nouveau_subdev_create_(parent, engine, oclass, 0, "VOLT",
				     "voltage", length, pobject);
	volt = *pobject;
	if (ret)
		return ret;

	volt->get = nouveau_volt_get;
	volt->set = nouveau_volt_set;
	volt->set_id = nouveau_volt_set_id;

	data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info);
	if (data && info.vidmask && info.base && info.step) {
		for (i = 0; i < info.vidmask + 1; i++) {
			if (info.base >= info.min &&
			    info.base <= info.max) {
				volt->vid[volt->vid_nr].uv = info.base;
				volt->vid[volt->vid_nr].vid = i;
				volt->vid_nr++;
			}
			info.base += info.step;
		}
		volt->vid_mask = info.vidmask;
	} else
	if (data && info.vidmask) {
		for (i = 0; i < cnt; i++) {
			data = nvbios_volt_entry_parse(bios, i, &ver, &hdr,
						      &ivid);
			if (data) {
				volt->vid[volt->vid_nr].uv = ivid.voltage;
				volt->vid[volt->vid_nr].vid = ivid.vid;
				volt->vid_nr++;
			}
		}
		volt->vid_mask = info.vidmask;
	}

	if (volt->vid_nr) {
		for (i = 0; i < volt->vid_nr; i++) {
			nv_debug(volt, "VID %02x: %duv\n",
				 volt->vid[i].vid, volt->vid[i].uv);
		}

		/*XXX: this is an assumption.. there probably exists boards
		 * out there with i2c-connected voltage controllers too..
		 */
		ret = nouveau_voltgpio_init(volt);
		if (ret == 0) {
			volt->vid_get = nouveau_voltgpio_get;
			volt->vid_set = nouveau_voltgpio_set;
		}
	}

	return ret;
}