예제 #1
0
파일: nouveau_agp.c 프로젝트: 24hours/linux
static bool
nouveau_agp_enabled(struct nouveau_drm *drm)
{
	struct drm_device *dev = drm->dev;

	if (!dev->pdev || !drm_pci_device_is_agp(dev) || !dev->agp)
		return false;

	if (drm->agp.stat == UNKNOWN) {
		if (!nouveau_agpmode)
			return false;
#ifdef __powerpc__
		/* Disable AGP by default on all PowerPC machines for
		 * now -- At least some UniNorth-2 AGP bridges are
		 * known to be broken: DMA from the host to the card
		 * works just fine, but writeback from the card to the
		 * host goes straight to memory untranslated bypassing
		 * the GATT somehow, making them quite painful to deal
		 * with...
		 */
		if (nouveau_agpmode == -1)
			return false;
#endif
		return true;
	}

	return (drm->agp.stat == ENABLED);
}
예제 #2
0
파일: radeon_kms.c 프로젝트: 2asoft/freebsd
/**
 * radeon_driver_load_kms - Main load function for KMS.
 *
 * @dev: drm dev pointer
 * @flags: device flags
 *
 * This is the main load function for KMS (all asics).
 * It calls radeon_device_init() to set up the non-display
 * parts of the chip (asic init, CP, writeback, etc.), and
 * radeon_modeset_init() to set up the display parts
 * (crtcs, encoders, hotplug detect, etc.).
 * Returns 0 on success, error on failure.
 */
int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
{
	struct radeon_device *rdev;
	int r, acpi_status;

	rdev = malloc(sizeof(struct radeon_device), DRM_MEM_DRIVER, M_NOWAIT | M_ZERO);
	if (rdev == NULL) {
		return -ENOMEM;
	}
	dev->dev_private = (void *)rdev;

	/* update BUS flag */
	if (drm_pci_device_is_agp(dev)) {
		DRM_INFO("RADEON_IS_AGP\n");
		flags |= RADEON_IS_AGP;
	} else if (drm_pci_device_is_pcie(dev)) {
		DRM_INFO("RADEON_IS_PCIE\n");
		flags |= RADEON_IS_PCIE;
	} else {
		DRM_INFO("RADEON_IS_PCI\n");
		flags |= RADEON_IS_PCI;
	}

	/* radeon_device_init should report only fatal error
	 * like memory allocation failure or iomapping failure,
	 * or memory manager initialization failure, it must
	 * properly initialize the GPU MC controller and permit
	 * VRAM allocation
	 */
	r = radeon_device_init(rdev, dev, flags);
	if (r) {
		dev_err(dev->dev, "Fatal error during GPU init\n");
		goto out;
	}

	/* Again modeset_init should fail only on fatal error
	 * otherwise it should provide enough functionalities
	 * for shadowfb to run
	 */
	r = radeon_modeset_init(rdev);
	if (r)
		dev_err(dev->dev, "Fatal error during modeset init\n");

	/* Call ACPI methods: require modeset init
	 * but failure is not fatal
	 */
	if (!r) {
		acpi_status = radeon_acpi_init(rdev);
		if (acpi_status)
		dev_dbg(dev->dev,
				"Error during ACPI methods call\n");
	}

out:
	if (r)
		radeon_driver_unload_kms(dev);
	return r;
}
예제 #3
0
static bool
nouveau_agp_enabled(struct nouveau_drm *drm)
{
	struct drm_device *dev = drm->dev;

	if (!drm_pci_device_is_agp(dev) || !dev->agp)
		return false;

	if (drm->agp.stat == UNKNOWN) {
		if (!nouveau_agpmode)
			return false;
		return true;
	}

	return (drm->agp.stat == ENABLED);
}
예제 #4
0
/**
 * radeon_driver_load_kms - Main load function for KMS.
 *
 * @dev: drm dev pointer
 * @flags: device flags
 *
 * This is the main load function for KMS (all asics).
 * It calls radeon_device_init() to set up the non-display
 * parts of the chip (asic init, CP, writeback, etc.), and
 * radeon_modeset_init() to set up the display parts
 * (crtcs, encoders, hotplug detect, etc.).
 * Returns 0 on success, error on failure.
 */
int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
{
	struct radeon_device *rdev;
	int r, acpi_status;

	rdev = kzalloc(sizeof(struct radeon_device), GFP_KERNEL);
	if (rdev == NULL) {
		return -ENOMEM;
	}
	dev->dev_private = (void *)rdev;

	/* update BUS flag */
	if (drm_pci_device_is_agp(dev)) {
		DRM_INFO("RADEON_IS_AGP\n");
		flags |= RADEON_IS_AGP;
	} else if (pci_is_pcie(dev->dev->bsddev)) {
		DRM_INFO("RADEON_IS_PCIE\n");
		flags |= RADEON_IS_PCIE;
	} else {
		DRM_INFO("RADEON_IS_PCI\n");
		flags |= RADEON_IS_PCI;
	}

#ifdef PM_TODO
	if ((radeon_runtime_pm != 0) &&
	    radeon_has_atpx() &&
	    ((flags & RADEON_IS_IGP) == 0))
#endif

	/* radeon_device_init should report only fatal error
	 * like memory allocation failure or iomapping failure,
	 * or memory manager initialization failure, it must
	 * properly initialize the GPU MC controller and permit
	 * VRAM allocation
	 */
	r = radeon_device_init(rdev, dev, dev->pdev, flags);
	if (r) {
		dev_err(&dev->pdev->dev, "Fatal error during GPU init\n");
		goto out;
	}

	/* Again modeset_init should fail only on fatal error
	 * otherwise it should provide enough functionalities
	 * for shadowfb to run
	 */
	r = radeon_modeset_init(rdev);
	if (r)
		dev_err(&dev->pdev->dev, "Fatal error during modeset init\n");

	/* Call ACPI methods: require modeset init
	 * but failure is not fatal
	 */
	if (!r) {
		acpi_status = radeon_acpi_init(rdev);
		if (acpi_status)
		dev_dbg(&dev->pdev->dev,
				"Error during ACPI methods call\n");
	}

#ifdef PM_TODO
	if (radeon_is_px(dev)) {
		pm_runtime_use_autosuspend(dev->dev);
		pm_runtime_set_autosuspend_delay(dev->dev, 5000);
		pm_runtime_set_active(dev->dev);
		pm_runtime_allow(dev->dev);
		pm_runtime_mark_last_busy(dev->dev);
		pm_runtime_put_autosuspend(dev->dev);
	}
#endif

out:
	if (r)
		radeon_driver_unload_kms(dev);


	return r;
}
예제 #5
0
static int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
{
	struct drm_device *ddev = p->rdev->ddev;
	struct radeon_cs_chunk *chunk;
	struct radeon_cs_buckets buckets;
	unsigned i, j;
	bool duplicate;

	if (p->chunk_relocs_idx == -1) {
		return 0;
	}
	chunk = &p->chunks[p->chunk_relocs_idx];
	p->dma_reloc_idx = 0;
	/* FIXME: we assume that each relocs use 4 dwords */
	p->nrelocs = chunk->length_dw / 4;
	p->relocs_ptr = kcalloc(p->nrelocs, sizeof(void *), GFP_KERNEL);
	if (p->relocs_ptr == NULL) {
		return -ENOMEM;
	}
	p->relocs = kcalloc(p->nrelocs, sizeof(struct radeon_cs_reloc), GFP_KERNEL);
	if (p->relocs == NULL) {
		return -ENOMEM;
	}

	radeon_cs_buckets_init(&buckets);

	for (i = 0; i < p->nrelocs; i++) {
		struct drm_radeon_cs_reloc *r;
		unsigned priority;

		duplicate = false;
		r = (struct drm_radeon_cs_reloc *)&chunk->kdata[i*4];
		for (j = 0; j < i; j++) {
			if (r->handle == p->relocs[j].handle) {
				p->relocs_ptr[i] = &p->relocs[j];
				duplicate = true;
				break;
			}
		}
		if (duplicate) {
			p->relocs[i].handle = 0;
			continue;
		}

		p->relocs[i].gobj = drm_gem_object_lookup(ddev, p->filp,
							  r->handle);
		if (p->relocs[i].gobj == NULL) {
			DRM_ERROR("gem object lookup failed 0x%x\n",
				  r->handle);
			return -ENOENT;
		}
		p->relocs_ptr[i] = &p->relocs[i];
		p->relocs[i].robj = gem_to_radeon_bo(p->relocs[i].gobj);

		/* The userspace buffer priorities are from 0 to 15. A higher
		 * number means the buffer is more important.
		 * Also, the buffers used for write have a higher priority than
		 * the buffers used for read only, which doubles the range
		 * to 0 to 31. 32 is reserved for the kernel driver.
		 */
		priority = (r->flags & 0xf) * 2 + !!r->write_domain;

		/* the first reloc of an UVD job is the msg and that must be in
		   VRAM, also but everything into VRAM on AGP cards to avoid
		   image corruptions */
		if (p->ring == R600_RING_TYPE_UVD_INDEX &&
		    (i == 0 || drm_pci_device_is_agp(p->rdev->ddev))) {
			/* TODO: is this still needed for NI+ ? */
			p->relocs[i].prefered_domains =
				RADEON_GEM_DOMAIN_VRAM;

			p->relocs[i].allowed_domains =
				RADEON_GEM_DOMAIN_VRAM;

			/* prioritize this over any other relocation */
			priority = RADEON_CS_MAX_PRIORITY;
		} else {
			uint32_t domain = r->write_domain ?
				r->write_domain : r->read_domains;

			if (domain & RADEON_GEM_DOMAIN_CPU) {
				DRM_ERROR("RADEON_GEM_DOMAIN_CPU is not valid "
					  "for command submission\n");
				return -EINVAL;
			}

			p->relocs[i].prefered_domains = domain;
			if (domain == RADEON_GEM_DOMAIN_VRAM)
				domain |= RADEON_GEM_DOMAIN_GTT;
			p->relocs[i].allowed_domains = domain;
		}

		p->relocs[i].tv.bo = &p->relocs[i].robj->tbo;
		p->relocs[i].handle = r->handle;

		radeon_cs_buckets_add(&buckets, &p->relocs[i].tv.head,
				      priority);
	}

	radeon_cs_buckets_get_list(&buckets, &p->validated);

	if (p->cs_flags & RADEON_CS_USE_VM)
		p->vm_bos = radeon_vm_get_bos(p->rdev, p->ib.vm,
					      &p->validated);

	return radeon_bo_list_validate(p->rdev, &p->ticket, &p->validated, p->ring);
}