Пример #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;
}
Пример #2
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;
}
Пример #3
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;
}
Пример #4
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;
}