Beispiel #1
0
void
nouveau_vga_fini(struct nouveau_drm *drm)
{
	struct drm_device *dev = drm->dev;
	vga_switcheroo_unregister_client(dev->pdev);
	vga_client_register(dev->pdev, NULL, NULL, NULL);
}
Beispiel #2
0
static void nouveau_card_takedown(struct drm_device *dev)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;
	struct nouveau_engine *engine = &dev_priv->engine;
	int e;

	if (dev->mode_config.num_crtc) {
		nouveau_fbcon_fini(dev);
		nouveau_display_fini(dev);
	}

	nouveau_card_channel_fini(dev);
	nouveau_pm_fini(dev);
	nouveau_backlight_exit(dev);
	nouveau_display_destroy(dev);

	if (!dev_priv->noaccel) {
		for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) {
			if (dev_priv->eng[e]) {
				dev_priv->eng[e]->fini(dev, e, false);
				dev_priv->eng[e]->destroy(dev,e );
			}
		}
	}

	if (dev_priv->vga_ram) {
		nouveau_bo_unpin(dev_priv->vga_ram);
		nouveau_bo_ref(NULL, &dev_priv->vga_ram);
	}

	mutex_lock(&dev->struct_mutex);
	ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
	ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT);
	mutex_unlock(&dev->struct_mutex);
	nouveau_mem_gart_fini(dev);
	nouveau_mem_vram_fini(dev);

	engine->instmem.takedown(dev);
	nouveau_gpuobj_takedown(dev);

	nouveau_gpio_destroy(dev);
	engine->vram.takedown(dev);
	engine->fb.takedown(dev);
	engine->timer.takedown(dev);
	engine->mc.takedown(dev);

	nouveau_bios_takedown(dev);
	engine->display.late_takedown(dev);

	nouveau_irq_fini(dev);

	vga_switcheroo_unregister_client(dev->pdev);
	vga_client_register(dev->pdev, NULL, NULL, NULL);
}
Beispiel #3
0
void
nouveau_vga_fini(struct nouveau_drm *drm)
{
	struct drm_device *dev = drm->dev;
	bool runtime = false;

	if (nouveau_runtime_pm == 1)
		runtime = true;
	if ((nouveau_runtime_pm == -1) && (nouveau_is_optimus() || nouveau_is_v1_dsm()))
		runtime = true;

	vga_switcheroo_unregister_client(dev->pdev);
	if (runtime && nouveau_is_v1_dsm() && !nouveau_is_optimus())
		vga_switcheroo_fini_domain_pm_ops(drm->dev->dev);
	vga_client_register(dev->pdev, NULL, NULL, NULL);
}
Beispiel #4
0
int i915_driver_unload(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	int ret;

	ret = i915_gem_suspend(dev);
	if (ret) {
		DRM_ERROR("failed to idle hardware: %d\n", ret);
		return ret;
	}

	intel_power_domains_fini(dev_priv);

	intel_gpu_ips_teardown();

	i915_teardown_sysfs(dev);

	WARN_ON(unregister_oom_notifier(&dev_priv->mm.oom_notifier));
	unregister_shrinker(&dev_priv->mm.shrinker);

	io_mapping_free(dev_priv->gtt.mappable);
	arch_phys_wc_del(dev_priv->gtt.mtrr);

	acpi_video_unregister();

	if (drm_core_check_feature(dev, DRIVER_MODESET))
		intel_fbdev_fini(dev);

	drm_vblank_cleanup(dev);

	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
		intel_modeset_cleanup(dev);

		/*
		 * free the memory space allocated for the child device
		 * config parsed from VBT
		 */
		if (dev_priv->vbt.child_dev && dev_priv->vbt.child_dev_num) {
			kfree(dev_priv->vbt.child_dev);
			dev_priv->vbt.child_dev = NULL;
			dev_priv->vbt.child_dev_num = 0;
		}

		vga_switcheroo_unregister_client(dev->pdev);
		vga_client_register(dev->pdev, NULL, NULL, NULL);
	}

	/* Free error state after interrupts are fully disabled. */
	del_timer_sync(&dev_priv->gpu_error.hangcheck_timer);
	cancel_work_sync(&dev_priv->gpu_error.work);
	i915_destroy_error_state(dev);

	if (dev->pdev->msi_enabled)
		pci_disable_msi(dev->pdev);

	intel_opregion_fini(dev);

	if (drm_core_check_feature(dev, DRIVER_MODESET)) {
		/* Flush any outstanding unpin_work. */
		flush_workqueue(dev_priv->wq);

		mutex_lock(&dev->struct_mutex);
		i915_gem_cleanup_ringbuffer(dev);
		i915_gem_context_fini(dev);
		mutex_unlock(&dev->struct_mutex);
		i915_gem_cleanup_stolen(dev);
	}

	intel_teardown_gmbus(dev);
	intel_teardown_mchbar(dev);

	destroy_workqueue(dev_priv->dp_wq);
	destroy_workqueue(dev_priv->wq);
	pm_qos_remove_request(&dev_priv->pm_qos);

	i915_global_gtt_cleanup(dev);

	intel_uncore_fini(dev);
	if (dev_priv->regs != NULL)
		pci_iounmap(dev->pdev, dev_priv->regs);

	if (dev_priv->slab)
		kmem_cache_destroy(dev_priv->slab);

	pci_dev_put(dev_priv->bridge_dev);
	kfree(dev_priv);

	return 0;
}
Beispiel #5
0
static int i915_load_modeset_init(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	int ret;

	ret = intel_parse_bios(dev);
	if (ret)
		DRM_INFO("failed to find VBIOS tables\n");

	/* If we have > 1 VGA cards, then we need to arbitrate access
	 * to the common VGA resources.
	 *
	 * If we are a secondary display controller (!PCI_DISPLAY_CLASS_VGA),
	 * then we do not take part in VGA arbitration and the
	 * vga_client_register() fails with -ENODEV.
	 */
	ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
	if (ret && ret != -ENODEV)
		goto out;

	intel_register_dsm_handler();

	ret = vga_switcheroo_register_client(dev->pdev, &i915_switcheroo_ops, false);
	if (ret)
		goto cleanup_vga_client;

	/* Initialise stolen first so that we may reserve preallocated
	 * objects for the BIOS to KMS transition.
	 */
	ret = i915_gem_init_stolen(dev);
	if (ret)
		goto cleanup_vga_switcheroo;

	intel_power_domains_init_hw(dev_priv);

	ret = intel_irq_install(dev_priv);
	if (ret)
		goto cleanup_gem_stolen;

	/* Important: The output setup functions called by modeset_init need
	 * working irqs for e.g. gmbus and dp aux transfers. */
	intel_modeset_init(dev);

	ret = i915_gem_init(dev);
	if (ret)
		goto cleanup_irq;

	intel_modeset_gem_init(dev);

	/* Always safe in the mode setting case. */
	/* FIXME: do pre/post-mode set stuff in core KMS code */
	dev->vblank_disable_allowed = true;
	if (INTEL_INFO(dev)->num_pipes == 0)
		return 0;

	ret = intel_fbdev_init(dev);
	if (ret)
		goto cleanup_gem;

	/* Only enable hotplug handling once the fbdev is fully set up. */
	intel_hpd_init(dev_priv);

	/*
	 * Some ports require correctly set-up hpd registers for detection to
	 * work properly (leading to ghost connected connector status), e.g. VGA
	 * on gm45.  Hence we can only set up the initial fbdev config after hpd
	 * irqs are fully enabled. Now we should scan for the initial config
	 * only once hotplug handling is enabled, but due to screwed-up locking
	 * around kms/fbdev init we can't protect the fdbev initial config
	 * scanning against hotplug events. Hence do this first and ignore the
	 * tiny window where we will loose hotplug notifactions.
	 */
	async_schedule(intel_fbdev_initial_config, dev_priv);

	drm_kms_helper_poll_init(dev);

	return 0;

cleanup_gem:
	mutex_lock(&dev->struct_mutex);
	i915_gem_cleanup_ringbuffer(dev);
	i915_gem_context_fini(dev);
	mutex_unlock(&dev->struct_mutex);
cleanup_irq:
	drm_irq_uninstall(dev);
cleanup_gem_stolen:
	i915_gem_cleanup_stolen(dev);
cleanup_vga_switcheroo:
	vga_switcheroo_unregister_client(dev->pdev);
cleanup_vga_client:
	vga_client_register(dev->pdev, NULL, NULL, NULL);
out:
	return ret;
}
Beispiel #6
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_ops);

	/* 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_fifo_create(dev);
			break;
		case NV_10:
		case NV_20:
		case NV_30:
			if (dev_priv->chipset < 0x17)
				nv10_fifo_create(dev);
			else
				nv17_fifo_create(dev);
			break;
		case NV_40:
			nv40_fifo_create(dev);
			break;
		case NV_50:
			if (dev_priv->chipset == 0x50)
				nv50_fifo_create(dev);
			else
				nv84_fifo_create(dev);
			break;
		case NV_C0:
		case NV_D0:
			nvc0_fifo_create(dev);
			break;
		case NV_E0:
			nve0_fifo_create(dev);
			break;
		default:
			break;
		}

		switch (dev_priv->card_type) {
		case NV_04:
			nv04_fence_create(dev);
			break;
		case NV_10:
		case NV_20:
		case NV_30:
		case NV_40:
		case NV_50:
			if (dev_priv->chipset < 0x84)
				nv10_fence_create(dev);
			else
				nv84_fence_create(dev);
			break;
		case NV_C0:
		case NV_D0:
		case NV_E0:
			nvc0_fence_create(dev);
			break;
		default:
			break;
		}

		switch (dev_priv->card_type) {
		case NV_04:
		case NV_10:
		case NV_20:
		case NV_30:
		case NV_40:
			nv04_software_create(dev);
			break;
		case NV_50:
			nv50_software_create(dev);
			break;
		case NV_C0:
		case NV_D0:
		case NV_E0:
			nvc0_software_create(dev);
			break;
		default:
			break;
		}

		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;
		case NV_E0:
			nve0_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:
			if (!(nv_rd32(dev, 0x022500) & 0x00000200))
				nvc0_copy_create(dev, 1);
		case NV_D0:
			if (!(nv_rd32(dev, 0x022500) & 0x00000100))
				nvc0_copy_create(dev, 0);
			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;
			}
		}
	}

	ret = nouveau_irq_init(dev);
	if (ret)
		goto out_engine;

	ret = nouveau_display_create(dev);
	if (ret)
		goto out_irq;

	nouveau_backlight_init(dev);
	nouveau_pm_init(dev);

	if (dev_priv->eng[NVOBJ_ENGINE_GR]) {
		ret = nouveau_card_channel_init(dev);
		if (ret)
			goto out_pm;
	}

	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_pm:
	nouveau_pm_fini(dev);
	nouveau_backlight_exit(dev);
	nouveau_display_destroy(dev);
out_irq:
	nouveau_irq_fini(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_switcheroo_unregister_client(dev->pdev);
	vga_client_register(dev->pdev, NULL, NULL, NULL);
	return ret;
}