Merge git://proxy01.pd.intel.com:9419/git/mesa/drm into crestline

main
Nian Wu 2007-03-05 09:01:45 -05:00
commit 0a85c9fa02
8 changed files with 52 additions and 38 deletions

View File

@ -33,41 +33,25 @@
#include "drmP.h" #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 */ # 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; unsigned long address;
struct page *page; struct page *page;
int i; int i;
DRM_DEBUG("%s\n", __FUNCTION__);
DRM_DEBUG("%s: alloc %d order\n", __FUNCTION__, order);
address = __get_free_pages(GFP_KERNEL | __GFP_COMP, address = __get_free_pages(GFP_KERNEL | __GFP_COMP,
ATI_PCIGART_TABLE_ORDER); order);
if (address == 0UL) { if (address == 0UL) {
return NULL; return NULL;
} }
page = virt_to_page(address); page = virt_to_page(address);
for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) { for (i = 0; i < order; i++, page++) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
get_page(page); get_page(page);
#endif #endif
@ -78,22 +62,23 @@ static void *drm_ati_alloc_pcigart_table(void)
return (void *)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; struct page *page;
int i; int i;
int num_pages = 1 << order;
DRM_DEBUG("%s\n", __FUNCTION__); DRM_DEBUG("%s\n", __FUNCTION__);
page = virt_to_page((unsigned long)address); 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++) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
__put_page(page); __put_page(page);
#endif #endif
ClearPageReserved(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) int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
@ -101,6 +86,8 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
drm_sg_mem_t *entry = dev->sg; drm_sg_mem_t *entry = dev->sg;
unsigned long pages; unsigned long pages;
int i; int i;
int order;
int num_pages, max_pages;
/* we need to support large memory configurations */ /* we need to support large memory configurations */
if (!entry) { if (!entry) {
@ -108,15 +95,19 @@ int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
return 0; 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->bus_addr) {
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) { if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
pci_unmap_single(dev->pdev, gart_info->bus_addr, pci_unmap_single(dev->pdev, gart_info->bus_addr,
ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, num_pages * PAGE_SIZE,
PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
} }
pages = (entry->pages <= ATI_MAX_PCIGART_PAGES) max_pages = (gart_info->table_size / sizeof(u32));
? entry->pages : ATI_MAX_PCIGART_PAGES; pages = (entry->pages <= max_pages)
? entry->pages : max_pages;
for (i = 0; i < pages; i++) { for (i = 0; i < pages; i++) {
if (!entry->busaddr[i]) if (!entry->busaddr[i])
@ -132,7 +123,8 @@ 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 if (gart_info->gart_table_location == DRM_ATI_GART_MAIN
&& gart_info->addr) { && gart_info->addr) {
drm_ati_free_pcigart_table(gart_info->addr);
drm_ati_free_pcigart_table(gart_info->addr, order);
gart_info->addr = NULL; gart_info->addr = NULL;
} }
@ -147,6 +139,9 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
unsigned long pages; unsigned long pages;
u32 *pci_gart, page_base, bus_address = 0; u32 *pci_gart, page_base, bus_address = 0;
int i, j, ret = 0; int i, j, ret = 0;
int order;
int max_pages;
int num_pages;
if (!entry) { if (!entry) {
DRM_ERROR("no scatter/gather memory!\n"); DRM_ERROR("no scatter/gather memory!\n");
@ -156,7 +151,9 @@ 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) { if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n"); 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) { if (!address) {
DRM_ERROR("cannot allocate PCI GART page!\n"); DRM_ERROR("cannot allocate PCI GART page!\n");
goto done; goto done;
@ -168,11 +165,12 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
} }
bus_address = pci_map_single(dev->pdev, address, bus_address = pci_map_single(dev->pdev, address,
ATI_PCIGART_TABLE_PAGES * num_pages * PAGE_SIZE,
PAGE_SIZE, PCI_DMA_TODEVICE); PCI_DMA_TODEVICE);
if (bus_address == 0) { if (bus_address == 0) {
DRM_ERROR("unable to map PCIGART pages!\n"); 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; address = NULL;
goto done; goto done;
} }
@ -185,10 +183,11 @@ int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
pci_gart = (u32 *) address; pci_gart = (u32 *) address;
pages = (entry->pages <= ATI_MAX_PCIGART_PAGES) max_pages = (gart_info->table_size / sizeof(u32));
? entry->pages : ATI_MAX_PCIGART_PAGES; 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++) { for (i = 0; i < pages; i++) {
/* we need to support large memory configurations */ /* we need to support large memory configurations */

View File

@ -593,6 +593,7 @@ typedef struct ati_pcigart_info {
void *addr; void *addr;
dma_addr_t bus_addr; dma_addr_t bus_addr;
drm_local_map_t mapping; drm_local_map_t mapping;
int table_size;
} drm_ati_pcigart_info; } drm_ati_pcigart_info;

View File

@ -560,6 +560,7 @@ static int r128_do_init_cce(drm_device_t * dev, drm_r128_init_t * init)
if (dev_priv->is_pci) { if (dev_priv->is_pci) {
#endif #endif
dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN; dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN;
dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE;
dev_priv->gart_info.addr = NULL; dev_priv->gart_info.addr = NULL;
dev_priv->gart_info.bus_addr = 0; dev_priv->gart_info.bus_addr = 0;
dev_priv->gart_info.is_pcie = 0; dev_priv->gart_info.is_pcie = 0;

View File

@ -383,6 +383,8 @@ extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
#define R128_PERFORMANCE_BOXES 0 #define R128_PERFORMANCE_BOXES 0
#define R128_PCIGART_TABLE_SIZE 32768
#define R128_READ(reg) DRM_READ32( dev_priv->mmio, (reg) ) #define R128_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
#define R128_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) ) #define R128_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
#define R128_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) ) #define R128_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) )

View File

@ -1623,13 +1623,13 @@ static int radeon_do_init_cp(drm_device_t * dev, drm_radeon_init_t * init)
#endif #endif
{ {
/* if we have an offset set from userspace */ /* if we have an offset set from userspace */
if (dev_priv->pcigart_offset) { if (dev_priv->pcigart_offset_set) {
dev_priv->gart_info.bus_addr = dev_priv->gart_info.bus_addr =
dev_priv->pcigart_offset + dev_priv->fb_location; dev_priv->pcigart_offset + dev_priv->fb_location;
dev_priv->gart_info.mapping.offset = dev_priv->gart_info.mapping.offset =
dev_priv->gart_info.bus_addr; dev_priv->gart_info.bus_addr;
dev_priv->gart_info.mapping.size = dev_priv->gart_info.mapping.size =
RADEON_PCIGART_TABLE_SIZE; dev_priv->gart_info.table_size;
drm_core_ioremap(&dev_priv->gart_info.mapping, dev); drm_core_ioremap(&dev_priv->gart_info.mapping, dev);
dev_priv->gart_info.addr = dev_priv->gart_info.addr =
@ -2230,6 +2230,8 @@ int radeon_driver_firstopen(struct drm_device *dev)
drm_local_map_t *map; drm_local_map_t *map;
drm_radeon_private_t *dev_priv = dev->dev_private; drm_radeon_private_t *dev_priv = dev->dev_private;
dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
ret = drm_addmap(dev, drm_get_resource_start(dev, 2), ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
drm_get_resource_len(dev, 2), _DRM_REGISTERS, drm_get_resource_len(dev, 2), _DRM_REGISTERS,
_DRM_READ_ONLY, &dev_priv->mmio); _DRM_READ_ONLY, &dev_priv->mmio);

View File

@ -708,6 +708,7 @@ typedef struct drm_radeon_setparam {
#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */ #define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */
#define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */ #define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */
#define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */
/* 1.14: Clients can allocate/free a surface /* 1.14: Clients can allocate/free a surface
*/ */

View File

@ -95,10 +95,11 @@
* 1.24- Add general-purpose packet for manipulating scratch registers (r300) * 1.24- Add general-purpose packet for manipulating scratch registers (r300)
* 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL, * 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL,
* new packet type) * new packet type)
* 1.26- Add support for variable size PCI(E) gart aperture
*/ */
#define DRIVER_MAJOR 1 #define DRIVER_MAJOR 1
#define DRIVER_MINOR 25 #define DRIVER_MINOR 26
#define DRIVER_PATCHLEVEL 0 #define DRIVER_PATCHLEVEL 0
/* /*
@ -282,6 +283,7 @@ typedef struct drm_radeon_private {
struct radeon_virt_surface virt_surfaces[2*RADEON_MAX_SURFACES]; struct radeon_virt_surface virt_surfaces[2*RADEON_MAX_SURFACES];
unsigned long pcigart_offset; unsigned long pcigart_offset;
unsigned int pcigart_offset_set;
drm_ati_pcigart_info gart_info; drm_ati_pcigart_info gart_info;
u32 scratch_ages[5]; u32 scratch_ages[5];

View File

@ -3196,10 +3196,16 @@ static int radeon_cp_setparam(DRM_IOCTL_ARGS)
break; break;
case RADEON_SETPARAM_PCIGART_LOCATION: case RADEON_SETPARAM_PCIGART_LOCATION:
dev_priv->pcigart_offset = sp.value; dev_priv->pcigart_offset = sp.value;
dev_priv->pcigart_offset_set = 1;
break; break;
case RADEON_SETPARAM_NEW_MEMMAP: case RADEON_SETPARAM_NEW_MEMMAP:
dev_priv->new_memmap = sp.value; dev_priv->new_memmap = sp.value;
break; break;
case RADEON_SETPARAM_PCIGART_TABLE_SIZE:
dev_priv->gart_info.table_size = sp.value;
if (dev_priv->gart_info.table_size < RADEON_PCIGART_TABLE_SIZE)
dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
break;
default: default:
DRM_DEBUG("Invalid parameter %d\n", sp.param); DRM_DEBUG("Invalid parameter %d\n", sp.param);
return DRM_ERR(EINVAL); return DRM_ERR(EINVAL);