struct pipe_winsys * nouveau_pipe_winsys_new(struct nouveau_device *dev) { struct nouveau_pipe_winsys *nvpws; int ret; nvpws = CALLOC_STRUCT(nouveau_pipe_winsys); if (!nvpws) return NULL; ret = nouveau_channel_alloc(dev, 0xbeef0201, 0xbeef0202, &nvpws->channel); if (ret) { debug_printf("%s: error opening GPU channel: %d\n", __func__, ret); FREE(nvpws); return NULL; } nvpws->next_handle = 0x77000000; nvpws->base.buffer_create = nouveau_pipe_bo_create; nvpws->base.buffer_destroy = nouveau_pipe_bo_del; nvpws->base.user_buffer_create = nouveau_pipe_bo_user_create; nvpws->base.buffer_map = nouveau_pipe_bo_map; nvpws->base.buffer_unmap = nouveau_pipe_bo_unmap; nvpws->base.fence_reference = nouveau_pipe_fence_reference; nvpws->base.fence_signalled = nouveau_pipe_fence_signalled; nvpws->base.fence_finish = nouveau_pipe_fence_finish; nvpws->base.get_name = nouveau_get_name; nvpws->base.destroy = nouveau_destroy; return &nvpws->base; }
static int nouveau_card_channel_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan; int ret, oclass; ret = nouveau_channel_alloc(dev, &chan, NULL, NvDmaFB, NvDmaTT); dev_priv->channel = chan; if (ret) return ret; mutex_unlock(&dev_priv->channel->mutex); if (dev_priv->card_type <= NV_50) { if (dev_priv->card_type < NV_50) oclass = 0x0039; else oclass = 0x5039; ret = nouveau_gpuobj_gr_new(chan, NvM2MF, oclass); if (ret) goto error; ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000, &chan->m2mf_ntfy); if (ret) goto error; ret = RING_SPACE(chan, 6); if (ret) goto error; BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NAME, 1); OUT_RING (chan, NvM2MF); BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3); OUT_RING (chan, NvNotify0); OUT_RING (chan, chan->vram_handle); OUT_RING (chan, chan->gart_handle); } else if (dev_priv->card_type <= NV_D0) { ret = nouveau_gpuobj_gr_new(chan, 0x9039, 0x9039); if (ret) goto error; ret = RING_SPACE(chan, 2); if (ret) goto error; BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0000, 1); OUT_RING (chan, 0x00009039); } FIRE_RING (chan); error: if (ret) nouveau_card_channel_fini(dev); return ret; }
static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_channel_alloc *init = data; struct nouveau_channel *chan; int ret; if (dev_priv->engine.graph.accel_blocked) return -ENODEV; if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) return -EINVAL; ret = nouveau_channel_alloc(dev, &chan, file_priv, init->fb_ctxdma_handle, init->tt_ctxdma_handle); if (ret) return ret; init->channel = chan->id; if (chan->dma.ib_max) init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM | NOUVEAU_GEM_DOMAIN_GART; else if (chan->pushbuf_bo->bo.mem.mem_type == TTM_PL_VRAM) init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM; else init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART; if (dev_priv->card_type < NV_C0) { init->subchan[0].handle = NvM2MF; if (dev_priv->card_type < NV_50) init->subchan[0].grclass = 0x0039; else init->subchan[0].grclass = 0x5039; init->subchan[1].handle = NvSw; init->subchan[1].grclass = NV_SW; init->nr_subchan = 2; } else { init->subchan[0].handle = 0x9039; init->subchan[0].grclass = 0x9039; init->nr_subchan = 1; } /* Named memory object area */ ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem, &init->notifier_handle); if (ret == 0) atomic_inc(&chan->users); /* userspace reference */ nouveau_channel_put(&chan); return ret; }
static int nouveau_card_init_channel(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; int ret; ret = nouveau_channel_alloc(dev, &dev_priv->channel, (struct drm_file *)-2, NvDmaFB, NvDmaTT); if (ret) return ret; mutex_unlock(&dev_priv->channel->mutex); return 0; }
static int nouveau_card_channel_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan; int ret; ret = nouveau_channel_alloc(dev, &chan, NULL, NvDmaFB, NvDmaTT); dev_priv->channel = chan; if (ret) return ret; mutex_unlock(&dev_priv->channel->mutex); nouveau_bo_move_init(chan); return 0; }
static int nouveau_card_init_channel(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_gpuobj *gpuobj; int ret; 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) goto out_err; ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM, gpuobj, NULL); if (ret) goto out_err; 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) goto out_err; ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART, gpuobj, NULL); if (ret) goto out_err; return 0; out_err: nouveau_gpuobj_del(dev, &gpuobj); nouveau_channel_free(dev_priv->channel); dev_priv->channel = NULL; return ret; }
static int nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_channel_alloc *init = data; struct nouveau_channel *chan; int ret; NOUVEAU_CHECK_INITIALISED_WITH_RETURN; if (dev_priv->engine.graph.accel_blocked) return -ENODEV; if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0) return -EINVAL; ret = nouveau_channel_alloc(dev, &chan, file_priv, init->fb_ctxdma_handle, init->tt_ctxdma_handle); if (ret) return ret; init->channel = chan->id; init->subchan[0].handle = NvM2MF; if (dev_priv->card_type < NV_50) init->subchan[0].grclass = 0x0039; else init->subchan[0].grclass = 0x5039; init->subchan[1].handle = NvSw; init->subchan[1].grclass = NV_SW; init->nr_subchan = 2; /* Named memory object area */ ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem, &init->notifier_handle); if (ret) { nouveau_channel_free(chan); return ret; } return 0; }
int nouveau_screen_init(struct nouveau_screen *screen, struct nouveau_device *dev) { struct pipe_screen *pscreen = &screen->base; int ret; ret = nouveau_channel_alloc(dev, 0xbeef0201, 0xbeef0202, &screen->channel); if (ret) return ret; screen->device = dev; pscreen->get_name = nouveau_screen_get_name; pscreen->get_vendor = nouveau_screen_get_vendor; pscreen->fence_reference = nouveau_screen_fence_ref; pscreen->fence_signalled = nouveau_screen_fence_signalled; pscreen->fence_finish = nouveau_screen_fence_finish; util_format_s3tc_init(); return 0; }
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); } nouveau_pm_init(dev); ret = engine->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_vram_init(dev); if (ret) goto out_instmem; ret = nouveau_mem_gart_init(dev); if (ret) goto out_ttmvram; /* PMC */ ret = engine->mc.init(dev); if (ret) goto out_gart; /* PGPIO */ ret = nouveau_gpio_create(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 (!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); if (dev_priv->eng[NVOBJ_ENGINE_GR]) { ret = nouveau_fence_init(dev); if (ret) goto out_disp; ret = nouveau_channel_alloc(dev, &dev_priv->channel, NULL, NvDmaFB, NvDmaTT); if (ret) goto out_fence; mutex_unlock(&dev_priv->channel->mutex); } 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_channel_put_unlocked(&dev_priv->channel); out_fence: nouveau_fence_fini(dev); out_disp: 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 ); } } engine->fb.takedown(dev); out_timer: engine->timer.takedown(dev); out_gpio: nouveau_gpio_destroy(dev); out_mc: engine->mc.takedown(dev); out_gart: 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_vram: engine->vram.takedown(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; }