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