Esempio n. 1
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 = kmalloc(sizeof(struct radeon_device), DRM_MEM_DRIVER,
		       M_ZERO | M_WAITOK);
	if (rdev == NULL) {
		return -ENOMEM;
	}
	dev->dev_private = (void *)rdev;

	/* update BUS flag */
	if (drm_device_is_agp(dev)) {
		DRM_INFO("RADEON_IS_AGP\n");
		flags |= RADEON_IS_AGP;
	} else if (drm_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;
}
int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
{
	struct radeon_device *rdev;
	int r;

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

	/* update BUS flag */
	if (drm_device_is_agp(dev)) {
		flags |= RADEON_IS_AGP;
	} else if (drm_device_is_pcie(dev)) {
		flags |= RADEON_IS_PCIE;
	} else {
		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, 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");
out:
	if (r)
		radeon_driver_unload_kms(dev);
	return r;
}
Esempio n. 3
0
/**
 * radeon_msi_ok - asic specific msi checks
 *
 * @rdev: radeon device pointer
 *
 * Handles asic specific MSI checks to determine if
 * MSIs should be enabled on a particular chip (all asics).
 * Returns true if MSIs should be enabled, false if MSIs
 * should not be enabled.
 */
int radeon_msi_ok(struct drm_device *dev, unsigned long flags)
{
	int family;

	family = flags & RADEON_FAMILY_MASK;

	/* RV370/RV380 was first asic with MSI support */
	if (family < CHIP_RV380)
		return false;

	/* MSIs don't work on AGP */
	if (drm_device_is_agp(dev))
		return false;

	/* force MSI on */
	if (radeon_msi == 1)
		return true;
	else if (radeon_msi == 0)
		return false;

	/* Quirks */
	/* HP RS690 only seems to work with MSIs. */
	if ((dev->pci_device == 0x791f) &&
	    (dev->pci_subvendor == 0x103c) &&
	    (dev->pci_subdevice == 0x30c2))
		return true;

	/* Dell RS690 only seems to work with MSIs. */
	if ((dev->pci_device == 0x791f) &&
	    (dev->pci_subvendor == 0x1028) &&
	    (dev->pci_subdevice == 0x01fc))
		return true;

	/* Dell RS690 only seems to work with MSIs. */
	if ((dev->pci_device == 0x791f) &&
	    (dev->pci_subvendor == 0x1028) &&
	    (dev->pci_subdevice == 0x01fd))
		return true;

	/* Gateway RS690 only seems to work with MSIs. */
	if ((dev->pci_device == 0x791f) &&
	    (dev->pci_subvendor == 0x107b) &&
	    (dev->pci_subdevice == 0x0185))
		return true;

	/* try and enable MSIs by default on all RS690s */
	if (family == CHIP_RS690)
		return true;

	/* RV515 seems to have MSI issues where it loses
	 * MSI rearms occasionally. This leads to lockups and freezes.
	 * disable it by default.
	 */
	if (family == CHIP_RV515)
		return false;
	if (flags & RADEON_IS_IGP) {
		/* APUs work fine with MSIs */
		if (family >= CHIP_PALM)
			return true;
		/* lots of IGPs have problems with MSIs */
		return false;
	}

	return true;
}
Esempio n. 4
0
static int fill_in_dev(drm_device_t * dev, struct pci_dev *pdev,
                       const struct pci_device_id *ent,
                       struct drm_driver *driver)
{
    int retcode;

    spin_lock_init(&dev->count_lock);
    init_timer(&dev->timer);
    sema_init(&dev->struct_sem, 1);
    sema_init(&dev->ctxlist_sem, 1);

    dev->pdev = pdev;

#ifdef __alpha__
    dev->hose = pdev->sysdata;
    dev->pci_domain = dev->hose->bus->number;
#else
    dev->pci_domain = 0;
#endif
    dev->pci_bus = pdev->bus->number;
    dev->pci_slot = PCI_SLOT(pdev->devfn);
    dev->pci_func = PCI_FUNC(pdev->devfn);
    dev->irq = pdev->irq;

    dev->maplist = drm_calloc(1, sizeof(*dev->maplist), DRM_MEM_MAPS);
    if (dev->maplist == NULL)
        return -ENOMEM;
    INIT_LIST_HEAD(&dev->maplist->head);

    /* the DRM has 6 counters */
    dev->counters = 6;
    dev->types[0] = _DRM_STAT_LOCK;
    dev->types[1] = _DRM_STAT_OPENS;
    dev->types[2] = _DRM_STAT_CLOSES;
    dev->types[3] = _DRM_STAT_IOCTLS;
    dev->types[4] = _DRM_STAT_LOCKS;
    dev->types[5] = _DRM_STAT_UNLOCKS;

    dev->driver = driver;

    if (dev->driver->load)
        if ((retcode = dev->driver->load(dev, ent->driver_data)))
            goto error_out_unreg;

    if (drm_core_has_AGP(dev)) {
        if (drm_device_is_agp(dev))
            dev->agp = drm_agp_init(dev);
        if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP)
                && (dev->agp == NULL)) {
            DRM_ERROR("Cannot initialize the agpgart module.\n");
            retcode = -EINVAL;
            goto error_out_unreg;
        }

        if (drm_core_has_MTRR(dev)) {
            if (dev->agp)
                dev->agp->agp_mtrr =
                    mtrr_add(dev->agp->agp_info.aper_base,
                             dev->agp->agp_info.aper_size *
                             1024 * 1024, MTRR_TYPE_WRCOMB, 1);
        }
    }

    retcode = drm_ctxbitmap_init(dev);
    if (retcode) {
        DRM_ERROR("Cannot allocate memory for context bitmap.\n");
        goto error_out_unreg;
    }

    return 0;

error_out_unreg:
    drm_lastclose(dev);
    return retcode;
}
static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
			   const struct pci_device_id *ent,
			   struct drm_driver *driver)
{
	int retcode;

	INIT_LIST_HEAD(&dev->filelist);
	INIT_LIST_HEAD(&dev->ctxlist);
	INIT_LIST_HEAD(&dev->vmalist);
	INIT_LIST_HEAD(&dev->maplist);

	spin_lock_init(&dev->count_lock);
	spin_lock_init(&dev->drw_lock);
	spin_lock_init(&dev->tasklet_lock);
	spin_lock_init(&dev->lock.spinlock);
	init_timer(&dev->timer);
	mutex_init(&dev->struct_mutex);
	mutex_init(&dev->ctxlist_mutex);

	idr_init(&dev->drw_idr);

	dev->pdev = pdev;
	dev->pci_device = pdev->device;
	dev->pci_vendor = pdev->vendor;

#ifdef __alpha__
	dev->hose = pdev->sysdata;
#endif
	dev->irq = pdev->irq;

	if (drm_ht_create(&dev->map_hash, 12)) {
		return -ENOMEM;
	}

	/* the DRM has 6 basic counters */
	dev->counters = 6;
	dev->types[0] = _DRM_STAT_LOCK;
	dev->types[1] = _DRM_STAT_OPENS;
	dev->types[2] = _DRM_STAT_CLOSES;
	dev->types[3] = _DRM_STAT_IOCTLS;
	dev->types[4] = _DRM_STAT_LOCKS;
	dev->types[5] = _DRM_STAT_UNLOCKS;

	dev->driver = driver;

	if (drm_core_has_AGP(dev)) {
		if (drm_device_is_agp(dev))
			dev->agp = drm_agp_init(dev);
		if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP)
		    && (dev->agp == NULL)) {
			DRM_ERROR("Cannot initialize the agpgart module.\n");
			retcode = -EINVAL;
			goto error_out_unreg;
		}
		if (drm_core_has_MTRR(dev)) {
			if (dev->agp)
				dev->agp->agp_mtrr =
				    mtrr_add(dev->agp->agp_info.aper_base,
					     dev->agp->agp_info.aper_size *
					     1024 * 1024, MTRR_TYPE_WRCOMB, 1);
		}
	}

	if (dev->driver->load)
		if ((retcode = dev->driver->load(dev, ent->driver_data)))
			goto error_out_unreg;

	retcode = drm_ctxbitmap_init(dev);
	if (retcode) {
		DRM_ERROR("Cannot allocate memory for context bitmap.\n");
		goto error_out_unreg;
	}

	return 0;

      error_out_unreg:
	drm_lastclose(dev);
	return retcode;
}