Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5335a40b authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'drm-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6

* 'drm-patches' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6:
  via: Make sure we flush write-combining using a follow-up read.
  via: Try to improve command-buffer chaining.
  drm: remove old taskqueue remnant
  drm: rename badly named define and cleanup ioctl code spacing
  radeon: Don't mess up page flipping when a file descriptor is closed.
  drm/radeon: upgrade to 1.27 - make PCI GART more flexible
parents 393bfca1 ef68d295
Loading
Loading
Loading
Loading
+45 −39
Original line number Diff line number Diff line
@@ -33,59 +33,44 @@

#include "drmP.h"

#if PAGE_SIZE == 65536
# define ATI_PCIGART_TABLE_ORDER	0
# define ATI_PCIGART_TABLE_PAGES	(1 << 0)
#elif PAGE_SIZE == 16384
# define ATI_PCIGART_TABLE_ORDER	1
# define ATI_PCIGART_TABLE_PAGES	(1 << 1)
#elif PAGE_SIZE == 8192
# define ATI_PCIGART_TABLE_ORDER 	2
# define ATI_PCIGART_TABLE_PAGES 	(1 << 2)
#elif PAGE_SIZE == 4096
# define ATI_PCIGART_TABLE_ORDER 	3
# define ATI_PCIGART_TABLE_PAGES 	(1 << 3)
#else
# error - PAGE_SIZE not 64K, 16K, 8K or 4K
#endif

# define ATI_MAX_PCIGART_PAGES		8192	/**< 32 MB aperture, 4K pages */
# define ATI_PCIGART_PAGE_SIZE		4096	/**< PCI GART page size */

static void *drm_ati_alloc_pcigart_table(void)
static void *drm_ati_alloc_pcigart_table(int order)
{
	unsigned long address;
	struct page *page;
	int i;
	DRM_DEBUG("%s\n", __FUNCTION__);

	DRM_DEBUG("%s: alloc %d order\n", __FUNCTION__, order);

	address = __get_free_pages(GFP_KERNEL | __GFP_COMP,
				   ATI_PCIGART_TABLE_ORDER);
				   order);
	if (address == 0UL) {
		return NULL;
	}

	page = virt_to_page(address);

	for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++)
	for (i = 0; i < order; i++, page++)
		SetPageReserved(page);

	DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address);
	return (void *)address;
}

static void drm_ati_free_pcigart_table(void *address)
static void drm_ati_free_pcigart_table(void *address, int order)
{
	struct page *page;
	int i;
	int num_pages = 1 << order;
	DRM_DEBUG("%s\n", __FUNCTION__);

	page = virt_to_page((unsigned long)address);

	for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++)
	for (i = 0; i < num_pages; i++, page++)
		ClearPageReserved(page);

	free_pages((unsigned long)address, ATI_PCIGART_TABLE_ORDER);
	free_pages((unsigned long)address, order);
}

int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
@@ -93,6 +78,8 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
	drm_sg_mem_t *entry = dev->sg;
	unsigned long pages;
	int i;
	int order;
	int num_pages, max_pages;

	/* we need to support large memory configurations */
	if (!entry) {
@@ -100,15 +87,19 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
		return 0;
	}

	order = drm_order((gart_info->table_size + (PAGE_SIZE-1)) / PAGE_SIZE);
	num_pages = 1 << order;

	if (gart_info->bus_addr) {
		if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
			pci_unmap_single(dev->pdev, gart_info->bus_addr,
					 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
					 num_pages * PAGE_SIZE,
					 PCI_DMA_TODEVICE);
		}

		pages = (entry->pages <= ATI_MAX_PCIGART_PAGES)
		    ? entry->pages : ATI_MAX_PCIGART_PAGES;
		max_pages = (gart_info->table_size / sizeof(u32));
		pages = (entry->pages <= max_pages)
		  ? entry->pages : max_pages;

		for (i = 0; i < pages; i++) {
			if (!entry->busaddr[i])
@@ -123,13 +114,12 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)

	if (gart_info->gart_table_location == DRM_ATI_GART_MAIN
	    && gart_info->addr) {
		drm_ati_free_pcigart_table(gart_info->addr);
		drm_ati_free_pcigart_table(gart_info->addr, order);
		gart_info->addr = NULL;
	}

	return 1;
}

EXPORT_SYMBOL(drm_ati_pcigart_cleanup);

int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
@@ -139,6 +129,9 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
	unsigned long pages;
	u32 *pci_gart, page_base, bus_address = 0;
	int i, j, ret = 0;
	int order;
	int max_pages;
	int num_pages;

	if (!entry) {
		DRM_ERROR("no scatter/gather memory!\n");
@@ -148,7 +141,10 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
	if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
		DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n");

		address = drm_ati_alloc_pcigart_table();
		order = drm_order((gart_info->table_size +
				   (PAGE_SIZE-1)) / PAGE_SIZE);
		num_pages = 1 << order;
		address = drm_ati_alloc_pcigart_table(order);
		if (!address) {
			DRM_ERROR("cannot allocate PCI GART page!\n");
			goto done;
@@ -160,11 +156,13 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
		}

		bus_address = pci_map_single(dev->pdev, address,
					     ATI_PCIGART_TABLE_PAGES *
					     PAGE_SIZE, PCI_DMA_TODEVICE);
					     num_pages * PAGE_SIZE,
					     PCI_DMA_TODEVICE);
		if (bus_address == 0) {
			DRM_ERROR("unable to map PCIGART pages!\n");
			drm_ati_free_pcigart_table(address);
			order = drm_order((gart_info->table_size +
					   (PAGE_SIZE-1)) / PAGE_SIZE);
			drm_ati_free_pcigart_table(address, order);
			address = NULL;
			goto done;
		}
@@ -177,10 +175,11 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)

	pci_gart = (u32 *) address;

	pages = (entry->pages <= ATI_MAX_PCIGART_PAGES)
	    ? entry->pages : ATI_MAX_PCIGART_PAGES;
	max_pages = (gart_info->table_size / sizeof(u32));
	pages = (entry->pages <= max_pages)
	    ? entry->pages : max_pages;

	memset(pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32));
	memset(pci_gart, 0, max_pages * sizeof(u32));

	for (i = 0; i < pages; i++) {
		/* we need to support large memory configurations */
@@ -198,10 +197,18 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
		page_base = (u32) entry->busaddr[i];

		for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
			if (gart_info->is_pcie)
			switch(gart_info->gart_reg_if) {
			case DRM_ATI_GART_IGP:
				*pci_gart = cpu_to_le32((page_base) | 0xc);
				break;
			case DRM_ATI_GART_PCIE:
				*pci_gart = cpu_to_le32((page_base >> 8) | 0xc);
			else
				break;
			default:
			case DRM_ATI_GART_PCI:
				*pci_gart = cpu_to_le32(page_base);
				break;
			}
			pci_gart++;
			page_base += ATI_PCIGART_PAGE_SIZE;
		}
@@ -220,5 +227,4 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
	gart_info->bus_addr = bus_address;
	return ret;
}

EXPORT_SYMBOL(drm_ati_pcigart_init);
+6 −1
Original line number Diff line number Diff line
@@ -519,12 +519,17 @@ typedef struct drm_vbl_sig {
#define DRM_ATI_GART_MAIN 1
#define DRM_ATI_GART_FB   2

#define DRM_ATI_GART_PCI 1
#define DRM_ATI_GART_PCIE 2
#define DRM_ATI_GART_IGP 3

typedef struct ati_pcigart_info {
	int gart_table_location;
	int is_pcie;
	int gart_reg_if;
	void *addr;
	dma_addr_t bus_addr;
	drm_local_map_t mapping;
	int table_size;
} drm_ati_pcigart_info;

/*
+4 −6
Original line number Diff line number Diff line
@@ -15,8 +15,6 @@
 * #define DRIVER_DESC		"Matrox G200/G400"
 * #define DRIVER_DATE		"20001127"
 *
 * #define DRIVER_IOCTL_COUNT	DRM_ARRAY_SIZE( mga_ioctls )
 *
 * #define drm_x		mga_##x
 * \endcode
 */
@@ -120,7 +118,7 @@ static drm_ioctl_desc_t drm_ioctls[] = {
	[DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW)] = {drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
};

#define DRIVER_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )
#define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls )

/**
 * Take down the DRM device.
@@ -496,11 +494,11 @@ int drm_ioctl(struct inode *inode, struct file *filp,
		  (long)old_encode_dev(priv->head->device),
		  priv->authenticated);

	if ((nr >= DRIVER_IOCTL_COUNT) &&
	if ((nr >= DRM_CORE_IOCTL_COUNT) &&
	    ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END)))
		goto err_i1;
	if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END)
		 && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
	if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) &&
	    (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
		ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
	else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE))
		ioctl = &drm_ioctls[nr];
+0 −3
Original line number Diff line number Diff line
@@ -70,9 +70,6 @@ static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size)

#endif

/** Task queue handler arguments */
#define DRM_TASKQUEUE_ARGS	void *arg

/** For data going into the kernel through the ioctl argument */
#define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3)	\
	if ( copy_from_user(&arg1, arg2, arg3) )	\
+1 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@
	{0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
	{0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \
	{0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
	{0x1002, 0x5955, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
	{0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
	{0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
	{0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
Loading