int nouveau_card_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine; int ret; vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state, nouveau_switcheroo_reprobe, nouveau_switcheroo_can_switch); /* Initialise internal driver API hooks */ ret = nouveau_init_engine_ptrs(dev); if (ret) goto out; engine = &dev_priv->engine; spin_lock_init(&dev_priv->channels.lock); spin_lock_init(&dev_priv->tile.lock); spin_lock_init(&dev_priv->context_switch_lock); spin_lock_init(&dev_priv->vm_lock); /* Make the CRTCs and I2C buses accessible */ ret = engine->display.early_init(dev); if (ret) goto out; /* Parse BIOS tables / Run init tables if card not POSTed */ ret = nouveau_bios_init(dev); if (ret) goto out_display_early; nouveau_pm_init(dev); ret = nouveau_mem_vram_init(dev); if (ret) goto out_bios; ret = nouveau_gpuobj_init(dev); if (ret) goto out_vram; ret = engine->instmem.init(dev); if (ret) goto out_gpuobj; ret = nouveau_mem_gart_init(dev); if (ret) goto out_instmem; /* PMC */ ret = engine->mc.init(dev); if (ret) goto out_gart; /* PGPIO */ ret = engine->gpio.init(dev); if (ret) goto out_mc; /* PTIMER */ ret = engine->timer.init(dev); if (ret) goto out_gpio; /* PFB */ ret = engine->fb.init(dev); if (ret) goto out_timer; if (nouveau_noaccel) engine->graph.accel_blocked = true; else { /* PGRAPH */ ret = engine->graph.init(dev); if (ret) goto out_fb; /* PCRYPT */ ret = engine->crypt.init(dev); if (ret) goto out_graph; /* PFIFO */ ret = engine->fifo.init(dev); if (ret) goto out_crypt; } ret = engine->display.create(dev); if (ret) goto out_fifo; ret = drm_vblank_init(dev, nv_two_heads(dev) ? 2 : 1); if (ret) goto out_vblank; ret = nouveau_irq_init(dev); if (ret) goto out_vblank; /* what about PVIDEO/PCRTC/PRAMDAC etc? */ if (!engine->graph.accel_blocked) { ret = nouveau_fence_init(dev); if (ret) goto out_irq; ret = nouveau_card_init_channel(dev); if (ret) goto out_fence; } nouveau_fbcon_init(dev); drm_kms_helper_poll_init(dev); return 0; out_fence: nouveau_fence_fini(dev); out_irq: nouveau_irq_fini(dev); out_vblank: drm_vblank_cleanup(dev); engine->display.destroy(dev); out_fifo: if (!nouveau_noaccel) engine->fifo.takedown(dev); out_crypt: if (!nouveau_noaccel) engine->crypt.takedown(dev); out_graph: if (!nouveau_noaccel) engine->graph.takedown(dev); out_fb: engine->fb.takedown(dev); out_timer: engine->timer.takedown(dev); out_gpio: engine->gpio.takedown(dev); out_mc: engine->mc.takedown(dev); out_gart: nouveau_mem_gart_fini(dev); out_instmem: engine->instmem.takedown(dev); out_gpuobj: nouveau_gpuobj_takedown(dev); out_vram: nouveau_mem_vram_fini(dev); out_bios: nouveau_pm_fini(dev); nouveau_bios_takedown(dev); out_display_early: engine->display.late_takedown(dev); out: vga_client_register(dev->pdev, NULL, NULL, NULL); return ret; }
int nouveau_card_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine; struct nouveau_gpuobj *gpuobj; int ret; NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE) return 0; /* Determine exact chipset we're running on */ if (dev_priv->card_type < NV_10) dev_priv->chipset = dev_priv->card_type; else dev_priv->chipset = (nv_rd32(dev, NV03_PMC_BOOT_0) & 0x0ff00000) >> 20; /* Initialise internal driver API hooks */ ret = nouveau_init_engine_ptrs(dev); if (ret) return ret; engine = &dev_priv->engine; dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; /* Parse BIOS tables / Run init tables if card not POSTed */ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ret = nouveau_bios_init(dev); if (ret) return ret; } ret = nouveau_gpuobj_early_init(dev); if (ret) return ret; /* Initialise instance memory, must happen before mem_init so we * know exactly how much VRAM we're able to use for "normal" * purposes. */ ret = engine->instmem.init(dev); if (ret) return ret; /* Setup the memory manager */ ret = nouveau_mem_init(dev); if (ret) return ret; ret = nouveau_gpuobj_init(dev); if (ret) return ret; /* PMC */ ret = engine->mc.init(dev); if (ret) return ret; /* PTIMER */ ret = engine->timer.init(dev); if (ret) return ret; /* PFB */ ret = engine->fb.init(dev); if (ret) return ret; /* PGRAPH */ ret = engine->graph.init(dev); if (ret) return ret; /* PFIFO */ ret = engine->fifo.init(dev); if (ret) return ret; /* this call irq_preinstall, register irq handler and * call irq_postinstall */ ret = drm_irq_install(dev); if (ret) return ret; ret = drm_vblank_init(dev, 0); if (ret) return ret; /* what about PVIDEO/PCRTC/PRAMDAC etc? */ ret = nouveau_channel_alloc(dev, &dev_priv->channel, (struct drm_file *)-2, NvDmaFB, NvDmaTT); if (ret) return ret; gpuobj = NULL; ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, 0, nouveau_mem_fb_amount(dev), NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM, &gpuobj); if (ret) return ret; ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM, gpuobj, NULL); if (ret) { nouveau_gpuobj_del(dev, &gpuobj); return ret; } gpuobj = NULL; ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0, dev_priv->gart_info.aper_size, NV_DMA_ACCESS_RW, &gpuobj, NULL); if (ret) return ret; ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART, gpuobj, NULL); if (ret) { nouveau_gpuobj_del(dev, &gpuobj); return ret; } if (drm_core_check_feature(dev, DRIVER_MODESET)) { if (dev_priv->card_type >= NV_50) { ret = nv50_display_create(dev); if (ret) return ret; } else { ret = nv04_display_create(dev); if (ret) return ret; } } ret = nouveau_backlight_init(dev); if (ret) NV_ERROR(dev, "Error %d registering backlight\n", ret); dev_priv->init_state = NOUVEAU_CARD_INIT_DONE; if (drm_core_check_feature(dev, DRIVER_MODESET)) drm_helper_initial_config(dev); return 0; }
int nouveau_card_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine; int ret, e = 0; vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state, nouveau_switcheroo_reprobe, nouveau_switcheroo_can_switch); /* Initialise internal driver API hooks */ ret = nouveau_init_engine_ptrs(dev); if (ret) goto out; engine = &dev_priv->engine; spin_lock_init(&dev_priv->channels.lock); spin_lock_init(&dev_priv->tile.lock); spin_lock_init(&dev_priv->context_switch_lock); spin_lock_init(&dev_priv->vm_lock); /* Make the CRTCs and I2C buses accessible */ ret = engine->display.early_init(dev); if (ret) goto out; /* Parse BIOS tables / Run init tables if card not POSTed */ ret = nouveau_bios_init(dev); if (ret) goto out_display_early; /* workaround an odd issue on nvc1 by disabling the device's * nosnoop capability. hopefully won't cause issues until a * better fix is found - assuming there is one... */ if (dev_priv->chipset == 0xc1) { nv_mask(dev, 0x00088080, 0x00000800, 0x00000000); } /* PMC */ ret = engine->mc.init(dev); if (ret) goto out_bios; /* PTIMER */ ret = engine->timer.init(dev); if (ret) goto out_mc; /* PFB */ ret = engine->fb.init(dev); if (ret) goto out_timer; ret = engine->vram.init(dev); if (ret) goto out_fb; /* PGPIO */ ret = nouveau_gpio_create(dev); if (ret) goto out_vram; ret = nouveau_gpuobj_init(dev); if (ret) goto out_gpio; ret = engine->instmem.init(dev); if (ret) goto out_gpuobj; ret = nouveau_mem_vram_init(dev); if (ret) goto out_instmem; ret = nouveau_mem_gart_init(dev); if (ret) goto out_ttmvram; if (!dev_priv->noaccel) { switch (dev_priv->card_type) { case NV_04: nv04_graph_create(dev); break; case NV_10: nv10_graph_create(dev); break; case NV_20: case NV_30: nv20_graph_create(dev); break; case NV_40: nv40_graph_create(dev); break; case NV_50: nv50_graph_create(dev); break; case NV_C0: case NV_D0: nvc0_graph_create(dev); break; default: break; } switch (dev_priv->chipset) { case 0x84: case 0x86: case 0x92: case 0x94: case 0x96: case 0xa0: nv84_crypt_create(dev); break; case 0x98: case 0xaa: case 0xac: nv98_crypt_create(dev); break; } switch (dev_priv->card_type) { case NV_50: switch (dev_priv->chipset) { case 0xa3: case 0xa5: case 0xa8: case 0xaf: nva3_copy_create(dev); break; } break; case NV_C0: nvc0_copy_create(dev, 0); nvc0_copy_create(dev, 1); break; default: break; } if (dev_priv->chipset >= 0xa3 || dev_priv->chipset == 0x98) { nv84_bsp_create(dev); nv84_vp_create(dev); nv98_ppp_create(dev); } else if (dev_priv->chipset >= 0x84) { nv50_mpeg_create(dev); nv84_bsp_create(dev); nv84_vp_create(dev); } else if (dev_priv->chipset >= 0x50) { nv50_mpeg_create(dev); } else if (dev_priv->card_type == NV_40 || dev_priv->chipset == 0x31 || dev_priv->chipset == 0x34 || dev_priv->chipset == 0x36) { nv31_mpeg_create(dev); } for (e = 0; e < NVOBJ_ENGINE_NR; e++) { if (dev_priv->eng[e]) { ret = dev_priv->eng[e]->init(dev, e); if (ret) goto out_engine; } } /* PFIFO */ ret = engine->fifo.init(dev); if (ret) goto out_engine; } ret = nouveau_irq_init(dev); if (ret) goto out_fifo; ret = nouveau_display_create(dev); if (ret) goto out_irq; nouveau_backlight_init(dev); nouveau_pm_init(dev); ret = nouveau_fence_init(dev); if (ret) goto out_pm; if (dev_priv->eng[NVOBJ_ENGINE_GR]) { ret = nouveau_card_channel_init(dev); if (ret) goto out_fence; } if (dev->mode_config.num_crtc) { ret = nouveau_display_init(dev); if (ret) goto out_chan; nouveau_fbcon_init(dev); } return 0; out_chan: nouveau_card_channel_fini(dev); out_fence: nouveau_fence_fini(dev); out_pm: nouveau_pm_fini(dev); nouveau_backlight_exit(dev); nouveau_display_destroy(dev); out_irq: nouveau_irq_fini(dev); out_fifo: if (!dev_priv->noaccel) engine->fifo.takedown(dev); out_engine: if (!dev_priv->noaccel) { for (e = e - 1; e >= 0; e--) { if (!dev_priv->eng[e]) continue; dev_priv->eng[e]->fini(dev, e, false); dev_priv->eng[e]->destroy(dev,e ); } } nouveau_mem_gart_fini(dev); out_ttmvram: nouveau_mem_vram_fini(dev); out_instmem: engine->instmem.takedown(dev); out_gpuobj: nouveau_gpuobj_takedown(dev); out_gpio: nouveau_gpio_destroy(dev); out_vram: engine->vram.takedown(dev); out_fb: engine->fb.takedown(dev); out_timer: engine->timer.takedown(dev); out_mc: engine->mc.takedown(dev); out_bios: nouveau_bios_takedown(dev); out_display_early: engine->display.late_takedown(dev); out: vga_client_register(dev->pdev, NULL, NULL, NULL); return ret; }
int nouveau_card_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine; int ret; NV_DEBUG(dev, "prev state = %d\n", dev_priv->init_state); if (dev_priv->init_state == NOUVEAU_CARD_INIT_DONE) return 0; vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state, nouveau_switcheroo_can_switch); /* Initialise internal driver API hooks */ ret = nouveau_init_engine_ptrs(dev); if (ret) goto out; engine = &dev_priv->engine; dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; spin_lock_init(&dev_priv->context_switch_lock); /* Parse BIOS tables / Run init tables if card not POSTed */ if (drm_core_check_feature(dev, DRIVER_MODESET)) { ret = nouveau_bios_init(dev); if (ret) goto out; } ret = nouveau_mem_detect(dev); if (ret) goto out_bios; ret = nouveau_gpuobj_early_init(dev); if (ret) goto out_bios; /* Initialise instance memory, must happen before mem_init so we * know exactly how much VRAM we're able to use for "normal" * purposes. */ ret = engine->instmem.init(dev); if (ret) goto out_gpuobj_early; /* Setup the memory manager */ ret = nouveau_mem_init(dev); if (ret) goto out_instmem; ret = nouveau_gpuobj_init(dev); if (ret) goto out_mem; /* PMC */ ret = engine->mc.init(dev); if (ret) goto out_gpuobj; /* PTIMER */ ret = engine->timer.init(dev); if (ret) goto out_mc; /* PFB */ ret = engine->fb.init(dev); if (ret) goto out_timer; if (nouveau_noaccel) engine->graph.accel_blocked = true; else { /* PGRAPH */ ret = engine->graph.init(dev); if (ret) goto out_fb; /* PFIFO */ ret = engine->fifo.init(dev); if (ret) goto out_graph; } /* this call irq_preinstall, register irq handler and * call irq_postinstall */ ret = drm_irq_install(dev); if (ret) goto out_fifo; ret = drm_vblank_init(dev, 0); if (ret) goto out_irq; /* what about PVIDEO/PCRTC/PRAMDAC etc? */ if (!engine->graph.accel_blocked) { ret = nouveau_card_init_channel(dev); if (ret) goto out_irq; } if (drm_core_check_feature(dev, DRIVER_MODESET)) { if (dev_priv->card_type >= NV_50) ret = nv50_display_create(dev); else ret = nv04_display_create(dev); if (ret) goto out_channel; } ret = nouveau_backlight_init(dev); if (ret) NV_ERROR(dev, "Error %d registering backlight\n", ret); dev_priv->init_state = NOUVEAU_CARD_INIT_DONE; if (drm_core_check_feature(dev, DRIVER_MODESET)) { nouveau_fbcon_init(dev); drm_kms_helper_poll_init(dev); } return 0; out_channel: if (dev_priv->channel) { nouveau_channel_free(dev_priv->channel); dev_priv->channel = NULL; } out_irq: drm_irq_uninstall(dev); out_fifo: if (!nouveau_noaccel) engine->fifo.takedown(dev); out_graph: if (!nouveau_noaccel) engine->graph.takedown(dev); out_fb: engine->fb.takedown(dev); out_timer: engine->timer.takedown(dev); out_mc: engine->mc.takedown(dev); out_gpuobj: nouveau_gpuobj_takedown(dev); out_mem: nouveau_sgdma_takedown(dev); nouveau_mem_close(dev); out_instmem: engine->instmem.takedown(dev); out_gpuobj_early: nouveau_gpuobj_late_takedown(dev); out_bios: nouveau_bios_takedown(dev); out: vga_client_register(dev->pdev, NULL, NULL, NULL); return ret; }