Beispiel #1
0
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;
}
Beispiel #2
0
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;
}