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; }
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; }
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; }
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; }
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; }
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; }