mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-29 17:28:21 +02:00
Commit Keith Owens kernel Makefile changes, merge and commit alpha patch
set from Jay Estabrook (sans some mga modifications which broke other
arch's.)
This commit is contained in:
parent
b6923b3953
commit
97b8aa52bb
17 changed files with 448 additions and 69 deletions
|
|
@ -3,9 +3,7 @@
|
|||
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
|
||||
|
||||
O_TARGET := drm.o
|
||||
export-objs := gamma_drv.o tdfx_drv.o r128_drv.o mga_drv.o i810_drv.o \
|
||||
ffb_drv.o
|
||||
list-multi := gamma.o tdfx.o r128.o mga.o i810.o ffb.o
|
||||
list-multi := gamma.o tdfx.o r128.o mga.o i810.o ffb.o radeon.o
|
||||
|
||||
gamma-objs := gamma_drv.o gamma_dma.o
|
||||
tdfx-objs := tdfx_drv.o
|
||||
|
|
|
|||
|
|
@ -72,8 +72,6 @@ static void DRM(ati_free_pcigart_table)( unsigned long address )
|
|||
int i;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
if ( !address ) return;
|
||||
|
||||
page = virt_to_page( address );
|
||||
|
||||
for ( i = 0 ; i <= ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
|
||||
|
|
@ -84,25 +82,46 @@ static void DRM(ati_free_pcigart_table)( unsigned long address )
|
|||
free_pages( address, ATI_PCIGART_TABLE_ORDER );
|
||||
}
|
||||
|
||||
unsigned long DRM(ati_pcigart_init)( drm_device_t *dev )
|
||||
int DRM(ati_pcigart_init)( drm_device_t *dev,
|
||||
unsigned long *addr,
|
||||
dma_addr_t *bus_addr)
|
||||
{
|
||||
drm_sg_mem_t *entry = dev->sg;
|
||||
unsigned long address;
|
||||
unsigned long address = 0;
|
||||
unsigned long pages;
|
||||
u32 *pci_gart, page_base;
|
||||
int i, j;
|
||||
u32 *pci_gart, page_base, bus_address = 0;
|
||||
int i, j, ret = 0;
|
||||
|
||||
if ( !entry ) {
|
||||
DRM_ERROR( "no scatter/gather memory!\n" );
|
||||
return 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
address = DRM(ati_alloc_pcigart_table)();
|
||||
if ( !address ) {
|
||||
DRM_ERROR( "cannot allocate PCI GART page!\n" );
|
||||
return 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
#if defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020400)
|
||||
if ( !dev->pdev ) {
|
||||
DRM_ERROR( "PCI device unknown!\n" );
|
||||
goto done;
|
||||
}
|
||||
|
||||
bus_address = pci_map_single(dev->pdev, (void *)address,
|
||||
ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
|
||||
PCI_DMA_TODEVICE);
|
||||
if (bus_address == 0) {
|
||||
DRM_ERROR( "unable to map PCIGART pages!\n" );
|
||||
DRM(ati_free_pcigart_table)( address );
|
||||
address = 0;
|
||||
goto done;
|
||||
}
|
||||
#else
|
||||
bus_address = virt_to_bus( (void *)address );
|
||||
#endif
|
||||
|
||||
pci_gart = (u32 *)address;
|
||||
|
||||
pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
|
||||
|
|
@ -111,28 +130,78 @@ unsigned long DRM(ati_pcigart_init)( drm_device_t *dev )
|
|||
memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
|
||||
|
||||
for ( i = 0 ; i < pages ; i++ ) {
|
||||
#if defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020400)
|
||||
/* we need to support large memory configurations */
|
||||
entry->busaddr[i] = pci_map_single(dev->pdev,
|
||||
entry->pagelist[i]->virtual,
|
||||
PAGE_SIZE,
|
||||
PCI_DMA_TODEVICE);
|
||||
if (entry->busaddr[i] == 0) {
|
||||
DRM_ERROR( "unable to map PCIGART pages!\n" );
|
||||
DRM(ati_pcigart_cleanup)( dev, address, bus_address );
|
||||
address = 0;
|
||||
bus_address = 0;
|
||||
goto done;
|
||||
}
|
||||
page_base = (u32) entry->busaddr[i];
|
||||
#else
|
||||
page_base = virt_to_bus( entry->pagelist[i]->virtual );
|
||||
#endif
|
||||
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
|
||||
*pci_gart++ = cpu_to_le32( page_base );
|
||||
page_base += ATI_PCIGART_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
#if __i386__
|
||||
asm volatile ( "wbinvd" ::: "memory" );
|
||||
#else
|
||||
mb();
|
||||
#endif
|
||||
|
||||
return address;
|
||||
done:
|
||||
*addr = address;
|
||||
*bus_addr = bus_address;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DRM(ati_pcigart_cleanup)( unsigned long address )
|
||||
int DRM(ati_pcigart_cleanup)( drm_device_t *dev,
|
||||
unsigned long addr,
|
||||
dma_addr_t bus_addr)
|
||||
{
|
||||
#if defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020400)
|
||||
drm_sg_mem_t *entry = dev->sg;
|
||||
unsigned long pages;
|
||||
int i;
|
||||
|
||||
if ( address ) {
|
||||
DRM(ati_free_pcigart_table)( address );
|
||||
/* we need to support large memory configurations */
|
||||
if ( !entry ) {
|
||||
DRM_ERROR( "no scatter/gather memory!\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
if ( bus_addr ) {
|
||||
pci_unmap_single(dev->pdev, bus_addr,
|
||||
ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
|
||||
PCI_DMA_TODEVICE);
|
||||
|
||||
pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
|
||||
? entry->pages : ATI_MAX_PCIGART_PAGES;
|
||||
|
||||
for ( i = 0 ; i < pages ; i++ ) {
|
||||
if ( !entry->busaddr[i] ) break;
|
||||
pci_unmap_single(dev->pdev, entry->busaddr[i],
|
||||
PAGE_SIZE, PCI_DMA_TODEVICE);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if ( addr ) {
|
||||
DRM(ati_free_pcigart_table)( addr );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -624,6 +624,9 @@ typedef struct drm_sg_mem {
|
|||
void *virtual;
|
||||
int pages;
|
||||
struct page **pagelist;
|
||||
#if defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020400)
|
||||
dma_addr_t *busaddr;
|
||||
#endif
|
||||
} drm_sg_mem_t;
|
||||
|
||||
typedef struct drm_sigdata {
|
||||
|
|
@ -715,6 +718,7 @@ typedef struct drm_device {
|
|||
drm_agp_head_t *agp;
|
||||
#endif
|
||||
#ifdef __alpha__
|
||||
struct pci_dev *pdev;
|
||||
#if LINUX_VERSION_CODE < 0x020403
|
||||
struct pci_controler *hose;
|
||||
#else
|
||||
|
|
@ -1018,8 +1022,12 @@ extern int DRM(sg_free)(struct inode *inode, struct file *filp,
|
|||
#endif
|
||||
|
||||
/* ATI PCIGART support (ati_pcigart.h) */
|
||||
extern unsigned long DRM(ati_pcigart_init)(drm_device_t *dev);
|
||||
extern int DRM(ati_pcigart_cleanup)(unsigned long address);
|
||||
extern int DRM(ati_pcigart_init)(drm_device_t *dev,
|
||||
unsigned long *addr,
|
||||
dma_addr_t *bus_addr);
|
||||
extern int DRM(ati_pcigart_cleanup)(drm_device_t *dev,
|
||||
unsigned long addr,
|
||||
dma_addr_t bus_addr);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -114,8 +114,10 @@ int DRM(setunique)(struct inode *inode, struct file *filp,
|
|||
if (*p) break;
|
||||
|
||||
pci_dev = pci_find_slot(b, PCI_DEVFN(d,f));
|
||||
if (pci_dev)
|
||||
if (pci_dev) {
|
||||
dev->pdev = pci_dev;
|
||||
dev->hose = pci_dev->sysdata;
|
||||
}
|
||||
} while(0);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -47,12 +47,17 @@ void DRM(sg_cleanup)( drm_sg_mem_t *entry )
|
|||
|
||||
vfree( entry->virtual );
|
||||
|
||||
#if defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020400)
|
||||
DRM(free)( entry->busaddr,
|
||||
entry->pages * sizeof(*entry->busaddr),
|
||||
DRM_MEM_PAGES );
|
||||
#endif
|
||||
DRM(free)( entry->pagelist,
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES );
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES );
|
||||
DRM(free)( entry,
|
||||
sizeof(*entry),
|
||||
DRM_MEM_SGLISTS );
|
||||
sizeof(*entry),
|
||||
DRM_MEM_SGLISTS );
|
||||
}
|
||||
|
||||
int DRM(sg_alloc)( struct inode *inode, struct file *filp,
|
||||
|
|
@ -93,16 +98,35 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp,
|
|||
DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS );
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
|
||||
|
||||
#if defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020400)
|
||||
entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr),
|
||||
DRM_MEM_PAGES );
|
||||
if ( !entry->busaddr ) {
|
||||
DRM(free)( entry->pagelist,
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES );
|
||||
DRM(free)( entry,
|
||||
sizeof(*entry),
|
||||
DRM_MEM_SGLISTS );
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) );
|
||||
#endif
|
||||
|
||||
entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
|
||||
if ( !entry->virtual ) {
|
||||
#if defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020400)
|
||||
DRM(free)( entry->busaddr,
|
||||
entry->pages * sizeof(*entry->busaddr),
|
||||
DRM_MEM_PAGES );
|
||||
#endif
|
||||
DRM(free)( entry->pagelist,
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES );
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES );
|
||||
DRM(free)( entry,
|
||||
sizeof(*entry),
|
||||
DRM_MEM_SGLISTS );
|
||||
sizeof(*entry),
|
||||
DRM_MEM_SGLISTS );
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,64 @@ struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
|
|||
int write_access)
|
||||
#endif
|
||||
{
|
||||
#if defined(__alpha__) && __REALLY_HAVE_AGP
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_map_t *map = NULL;
|
||||
drm_map_list_t *r_list;
|
||||
struct list_head *list;
|
||||
|
||||
/*
|
||||
* Find the right map
|
||||
*/
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *)list;
|
||||
map = r_list->map;
|
||||
if (!map) continue;
|
||||
if (map->offset == VM_OFFSET(vma)) break;
|
||||
}
|
||||
|
||||
if (map && map->type == _DRM_AGP) {
|
||||
unsigned long offset = address - vma->vm_start;
|
||||
unsigned long baddr = VM_OFFSET(vma) + offset;
|
||||
struct drm_agp_mem *agpmem;
|
||||
struct page *page;
|
||||
|
||||
/*
|
||||
* Make it a bus-relative address
|
||||
*/
|
||||
baddr -= dev->hose->mem_space->start;
|
||||
|
||||
/*
|
||||
* It's AGP memory - find the real physical page to map
|
||||
*/
|
||||
for(agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
|
||||
if (agpmem->bound <= baddr &&
|
||||
agpmem->bound + agpmem->pages * PAGE_SIZE > baddr)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!agpmem) {
|
||||
/*
|
||||
* Oops - no memory found
|
||||
*/
|
||||
return NOPAGE_SIGBUS; /* couldn't find it */
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the page, inc the use count, and return it
|
||||
*/
|
||||
offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
|
||||
agpmem->memory->memory[offset] &= ~1UL; /* HACK */
|
||||
page = virt_to_page(__va(agpmem->memory->memory[offset]));
|
||||
#if 0
|
||||
DRM_ERROR("baddr = 0x%lx page = 0x%lx, offset = 0x%lx\n",
|
||||
baddr, __va(agpmem->memory->memory[offset]), offset);
|
||||
#endif
|
||||
get_page(page);
|
||||
return page;
|
||||
}
|
||||
#endif
|
||||
return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
}
|
||||
|
||||
|
|
@ -434,9 +492,20 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
|
|||
}
|
||||
|
||||
switch (map->type) {
|
||||
case _DRM_AGP:
|
||||
#if defined(__alpha__)
|
||||
/*
|
||||
* On Alpha we can't talk to bus dma address from the
|
||||
* CPU, so for memory of type DRM_AGP, we'll deal with
|
||||
* sorting out the real physical pages and mappings
|
||||
* in nopage()
|
||||
*/
|
||||
vma->vm_ops = &DRM(vm_ops);
|
||||
break;
|
||||
#endif
|
||||
/* fall through to _DRM_FRAME_BUFFER... */
|
||||
case _DRM_FRAME_BUFFER:
|
||||
case _DRM_REGISTERS:
|
||||
case _DRM_AGP:
|
||||
if (VM_OFFSET(vma) >= __pa(high_memory)) {
|
||||
#if defined(__i386__)
|
||||
if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
|
||||
|
|
|
|||
|
|
@ -3,9 +3,7 @@
|
|||
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
|
||||
|
||||
O_TARGET := drm.o
|
||||
export-objs := gamma_drv.o tdfx_drv.o r128_drv.o mga_drv.o i810_drv.o \
|
||||
ffb_drv.o
|
||||
list-multi := gamma.o tdfx.o r128.o mga.o i810.o ffb.o
|
||||
list-multi := gamma.o tdfx.o r128.o mga.o i810.o ffb.o radeon.o
|
||||
|
||||
gamma-objs := gamma_drv.o gamma_dma.o
|
||||
tdfx-objs := tdfx_drv.o
|
||||
|
|
|
|||
|
|
@ -72,8 +72,6 @@ static void DRM(ati_free_pcigart_table)( unsigned long address )
|
|||
int i;
|
||||
DRM_DEBUG( "%s\n", __FUNCTION__ );
|
||||
|
||||
if ( !address ) return;
|
||||
|
||||
page = virt_to_page( address );
|
||||
|
||||
for ( i = 0 ; i <= ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
|
||||
|
|
@ -84,25 +82,46 @@ static void DRM(ati_free_pcigart_table)( unsigned long address )
|
|||
free_pages( address, ATI_PCIGART_TABLE_ORDER );
|
||||
}
|
||||
|
||||
unsigned long DRM(ati_pcigart_init)( drm_device_t *dev )
|
||||
int DRM(ati_pcigart_init)( drm_device_t *dev,
|
||||
unsigned long *addr,
|
||||
dma_addr_t *bus_addr)
|
||||
{
|
||||
drm_sg_mem_t *entry = dev->sg;
|
||||
unsigned long address;
|
||||
unsigned long address = 0;
|
||||
unsigned long pages;
|
||||
u32 *pci_gart, page_base;
|
||||
int i, j;
|
||||
u32 *pci_gart, page_base, bus_address = 0;
|
||||
int i, j, ret = 0;
|
||||
|
||||
if ( !entry ) {
|
||||
DRM_ERROR( "no scatter/gather memory!\n" );
|
||||
return 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
address = DRM(ati_alloc_pcigart_table)();
|
||||
if ( !address ) {
|
||||
DRM_ERROR( "cannot allocate PCI GART page!\n" );
|
||||
return 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
#if defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020400)
|
||||
if ( !dev->pdev ) {
|
||||
DRM_ERROR( "PCI device unknown!\n" );
|
||||
goto done;
|
||||
}
|
||||
|
||||
bus_address = pci_map_single(dev->pdev, (void *)address,
|
||||
ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
|
||||
PCI_DMA_TODEVICE);
|
||||
if (bus_address == 0) {
|
||||
DRM_ERROR( "unable to map PCIGART pages!\n" );
|
||||
DRM(ati_free_pcigart_table)( address );
|
||||
address = 0;
|
||||
goto done;
|
||||
}
|
||||
#else
|
||||
bus_address = virt_to_bus( (void *)address );
|
||||
#endif
|
||||
|
||||
pci_gart = (u32 *)address;
|
||||
|
||||
pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
|
||||
|
|
@ -111,28 +130,78 @@ unsigned long DRM(ati_pcigart_init)( drm_device_t *dev )
|
|||
memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
|
||||
|
||||
for ( i = 0 ; i < pages ; i++ ) {
|
||||
#if defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020400)
|
||||
/* we need to support large memory configurations */
|
||||
entry->busaddr[i] = pci_map_single(dev->pdev,
|
||||
entry->pagelist[i]->virtual,
|
||||
PAGE_SIZE,
|
||||
PCI_DMA_TODEVICE);
|
||||
if (entry->busaddr[i] == 0) {
|
||||
DRM_ERROR( "unable to map PCIGART pages!\n" );
|
||||
DRM(ati_pcigart_cleanup)( dev, address, bus_address );
|
||||
address = 0;
|
||||
bus_address = 0;
|
||||
goto done;
|
||||
}
|
||||
page_base = (u32) entry->busaddr[i];
|
||||
#else
|
||||
page_base = virt_to_bus( entry->pagelist[i]->virtual );
|
||||
#endif
|
||||
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
|
||||
*pci_gart++ = cpu_to_le32( page_base );
|
||||
page_base += ATI_PCIGART_PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
#if __i386__
|
||||
asm volatile ( "wbinvd" ::: "memory" );
|
||||
#else
|
||||
mb();
|
||||
#endif
|
||||
|
||||
return address;
|
||||
done:
|
||||
*addr = address;
|
||||
*bus_addr = bus_address;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DRM(ati_pcigart_cleanup)( unsigned long address )
|
||||
int DRM(ati_pcigart_cleanup)( drm_device_t *dev,
|
||||
unsigned long addr,
|
||||
dma_addr_t bus_addr)
|
||||
{
|
||||
#if defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020400)
|
||||
drm_sg_mem_t *entry = dev->sg;
|
||||
unsigned long pages;
|
||||
int i;
|
||||
|
||||
if ( address ) {
|
||||
DRM(ati_free_pcigart_table)( address );
|
||||
/* we need to support large memory configurations */
|
||||
if ( !entry ) {
|
||||
DRM_ERROR( "no scatter/gather memory!\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
if ( bus_addr ) {
|
||||
pci_unmap_single(dev->pdev, bus_addr,
|
||||
ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
|
||||
PCI_DMA_TODEVICE);
|
||||
|
||||
pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
|
||||
? entry->pages : ATI_MAX_PCIGART_PAGES;
|
||||
|
||||
for ( i = 0 ; i < pages ; i++ ) {
|
||||
if ( !entry->busaddr[i] ) break;
|
||||
pci_unmap_single(dev->pdev, entry->busaddr[i],
|
||||
PAGE_SIZE, PCI_DMA_TODEVICE);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if ( addr ) {
|
||||
DRM(ati_free_pcigart_table)( addr );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
12
linux/drmP.h
12
linux/drmP.h
|
|
@ -624,6 +624,9 @@ typedef struct drm_sg_mem {
|
|||
void *virtual;
|
||||
int pages;
|
||||
struct page **pagelist;
|
||||
#if defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020400)
|
||||
dma_addr_t *busaddr;
|
||||
#endif
|
||||
} drm_sg_mem_t;
|
||||
|
||||
typedef struct drm_sigdata {
|
||||
|
|
@ -715,6 +718,7 @@ typedef struct drm_device {
|
|||
drm_agp_head_t *agp;
|
||||
#endif
|
||||
#ifdef __alpha__
|
||||
struct pci_dev *pdev;
|
||||
#if LINUX_VERSION_CODE < 0x020403
|
||||
struct pci_controler *hose;
|
||||
#else
|
||||
|
|
@ -1018,8 +1022,12 @@ extern int DRM(sg_free)(struct inode *inode, struct file *filp,
|
|||
#endif
|
||||
|
||||
/* ATI PCIGART support (ati_pcigart.h) */
|
||||
extern unsigned long DRM(ati_pcigart_init)(drm_device_t *dev);
|
||||
extern int DRM(ati_pcigart_cleanup)(unsigned long address);
|
||||
extern int DRM(ati_pcigart_init)(drm_device_t *dev,
|
||||
unsigned long *addr,
|
||||
dma_addr_t *bus_addr);
|
||||
extern int DRM(ati_pcigart_cleanup)(drm_device_t *dev,
|
||||
unsigned long addr,
|
||||
dma_addr_t bus_addr);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -114,8 +114,10 @@ int DRM(setunique)(struct inode *inode, struct file *filp,
|
|||
if (*p) break;
|
||||
|
||||
pci_dev = pci_find_slot(b, PCI_DEVFN(d,f));
|
||||
if (pci_dev)
|
||||
if (pci_dev) {
|
||||
dev->pdev = pci_dev;
|
||||
dev->hose = pci_dev->sysdata;
|
||||
}
|
||||
} while(0);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -47,12 +47,17 @@ void DRM(sg_cleanup)( drm_sg_mem_t *entry )
|
|||
|
||||
vfree( entry->virtual );
|
||||
|
||||
#if defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020400)
|
||||
DRM(free)( entry->busaddr,
|
||||
entry->pages * sizeof(*entry->busaddr),
|
||||
DRM_MEM_PAGES );
|
||||
#endif
|
||||
DRM(free)( entry->pagelist,
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES );
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES );
|
||||
DRM(free)( entry,
|
||||
sizeof(*entry),
|
||||
DRM_MEM_SGLISTS );
|
||||
sizeof(*entry),
|
||||
DRM_MEM_SGLISTS );
|
||||
}
|
||||
|
||||
int DRM(sg_alloc)( struct inode *inode, struct file *filp,
|
||||
|
|
@ -93,16 +98,35 @@ int DRM(sg_alloc)( struct inode *inode, struct file *filp,
|
|||
DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS );
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
|
||||
|
||||
#if defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020400)
|
||||
entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr),
|
||||
DRM_MEM_PAGES );
|
||||
if ( !entry->busaddr ) {
|
||||
DRM(free)( entry->pagelist,
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES );
|
||||
DRM(free)( entry,
|
||||
sizeof(*entry),
|
||||
DRM_MEM_SGLISTS );
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) );
|
||||
#endif
|
||||
|
||||
entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
|
||||
if ( !entry->virtual ) {
|
||||
#if defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020400)
|
||||
DRM(free)( entry->busaddr,
|
||||
entry->pages * sizeof(*entry->busaddr),
|
||||
DRM_MEM_PAGES );
|
||||
#endif
|
||||
DRM(free)( entry->pagelist,
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES );
|
||||
entry->pages * sizeof(*entry->pagelist),
|
||||
DRM_MEM_PAGES );
|
||||
DRM(free)( entry,
|
||||
sizeof(*entry),
|
||||
DRM_MEM_SGLISTS );
|
||||
sizeof(*entry),
|
||||
DRM_MEM_SGLISTS );
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,6 +67,64 @@ struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
|
|||
int write_access)
|
||||
#endif
|
||||
{
|
||||
#if defined(__alpha__) && __REALLY_HAVE_AGP
|
||||
drm_file_t *priv = vma->vm_file->private_data;
|
||||
drm_device_t *dev = priv->dev;
|
||||
drm_map_t *map = NULL;
|
||||
drm_map_list_t *r_list;
|
||||
struct list_head *list;
|
||||
|
||||
/*
|
||||
* Find the right map
|
||||
*/
|
||||
list_for_each(list, &dev->maplist->head) {
|
||||
r_list = (drm_map_list_t *)list;
|
||||
map = r_list->map;
|
||||
if (!map) continue;
|
||||
if (map->offset == VM_OFFSET(vma)) break;
|
||||
}
|
||||
|
||||
if (map && map->type == _DRM_AGP) {
|
||||
unsigned long offset = address - vma->vm_start;
|
||||
unsigned long baddr = VM_OFFSET(vma) + offset;
|
||||
struct drm_agp_mem *agpmem;
|
||||
struct page *page;
|
||||
|
||||
/*
|
||||
* Make it a bus-relative address
|
||||
*/
|
||||
baddr -= dev->hose->mem_space->start;
|
||||
|
||||
/*
|
||||
* It's AGP memory - find the real physical page to map
|
||||
*/
|
||||
for(agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
|
||||
if (agpmem->bound <= baddr &&
|
||||
agpmem->bound + agpmem->pages * PAGE_SIZE > baddr)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!agpmem) {
|
||||
/*
|
||||
* Oops - no memory found
|
||||
*/
|
||||
return NOPAGE_SIGBUS; /* couldn't find it */
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the page, inc the use count, and return it
|
||||
*/
|
||||
offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
|
||||
agpmem->memory->memory[offset] &= ~1UL; /* HACK */
|
||||
page = virt_to_page(__va(agpmem->memory->memory[offset]));
|
||||
#if 0
|
||||
DRM_ERROR("baddr = 0x%lx page = 0x%lx, offset = 0x%lx\n",
|
||||
baddr, __va(agpmem->memory->memory[offset]), offset);
|
||||
#endif
|
||||
get_page(page);
|
||||
return page;
|
||||
}
|
||||
#endif
|
||||
return NOPAGE_SIGBUS; /* Disallow mremap */
|
||||
}
|
||||
|
||||
|
|
@ -434,9 +492,20 @@ int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
|
|||
}
|
||||
|
||||
switch (map->type) {
|
||||
case _DRM_AGP:
|
||||
#if defined(__alpha__)
|
||||
/*
|
||||
* On Alpha we can't talk to bus dma address from the
|
||||
* CPU, so for memory of type DRM_AGP, we'll deal with
|
||||
* sorting out the real physical pages and mappings
|
||||
* in nopage()
|
||||
*/
|
||||
vma->vm_ops = &DRM(vm_ops);
|
||||
break;
|
||||
#endif
|
||||
/* fall through to _DRM_FRAME_BUFFER... */
|
||||
case _DRM_FRAME_BUFFER:
|
||||
case _DRM_REGISTERS:
|
||||
case _DRM_AGP:
|
||||
if (VM_OFFSET(vma) >= __pa(high_memory)) {
|
||||
#if defined(__i386__)
|
||||
if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
|
||||
|
|
|
|||
|
|
@ -145,14 +145,28 @@ extern int mga_warp_init( drm_mga_private_t *dev_priv );
|
|||
#define mga_flush_write_combine() mb()
|
||||
|
||||
|
||||
#define MGA_BASE( reg ) ((u32)(dev_priv->mmio->handle))
|
||||
#define MGA_BASE( reg ) ((unsigned long)(dev_priv->mmio->handle))
|
||||
#define MGA_ADDR( reg ) (MGA_BASE(reg) + reg)
|
||||
|
||||
#define MGA_DEREF( reg ) *(volatile u32 *)MGA_ADDR( reg )
|
||||
#define MGA_DEREF8( reg ) *(volatile u8 *)MGA_ADDR( reg )
|
||||
|
||||
#ifdef __alpha__
|
||||
#define MGA_READ( reg ) (_MGA_READ((u32 *)MGA_ADDR(reg)))
|
||||
#define MGA_WRITE( reg, val ) do { wmb(); MGA_DEREF( reg ) = val; } while (0)
|
||||
#define MGA_WRITE8( reg, val ) do { wmb(); MGA_DEREF8( reg ) = val; } while (0)
|
||||
|
||||
static inline u32 _MGA_READ(u32 *addr)
|
||||
{
|
||||
mb();
|
||||
return *(volatile u32 *)addr;
|
||||
}
|
||||
|
||||
#else
|
||||
#define MGA_READ( reg ) MGA_DEREF( reg )
|
||||
#define MGA_WRITE( reg, val ) do { MGA_DEREF( reg ) = val; } while (0)
|
||||
#define MGA_DEREF8( reg ) *(volatile u8 *)MGA_ADDR( reg )
|
||||
#define MGA_WRITE8( reg, val ) do { MGA_DEREF8( reg ) = val; } while (0)
|
||||
#endif
|
||||
|
||||
#define DWGREG0 0x1c00
|
||||
#define DWGREG0_END 0x1dff
|
||||
|
|
|
|||
|
|
@ -350,12 +350,20 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev,
|
|||
tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle;
|
||||
page_ofs = tmp_ofs >> PAGE_SHIFT;
|
||||
|
||||
#if defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020400)
|
||||
R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
|
||||
entry->busaddr[page_ofs]);
|
||||
DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n",
|
||||
entry->busaddr[page_ofs],
|
||||
entry->handle + tmp_ofs );
|
||||
#else
|
||||
R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
|
||||
virt_to_bus(entry->pagelist[page_ofs]->virtual));
|
||||
|
||||
DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n",
|
||||
virt_to_bus(entry->pagelist[page_ofs]->virtual),
|
||||
entry->handle + tmp_ofs );
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set watermark control */
|
||||
|
|
@ -599,15 +607,14 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
|
|||
dev_priv->sarea_priv->last_dispatch );
|
||||
|
||||
if ( dev_priv->is_pci ) {
|
||||
dev_priv->phys_pci_gart = DRM(ati_pcigart_init)( dev );
|
||||
if ( !dev_priv->phys_pci_gart ) {
|
||||
if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
|
||||
&dev_priv->bus_pci_gart) ) {
|
||||
DRM_ERROR( "failed to init PCI GART!\n" );
|
||||
dev->dev_private = (void *)dev_priv;
|
||||
r128_do_cleanup_cce( dev );
|
||||
return -ENOMEM;
|
||||
}
|
||||
R128_WRITE( R128_PCI_GART_PAGE,
|
||||
virt_to_bus( (void *)dev_priv->phys_pci_gart ) );
|
||||
R128_WRITE( R128_PCI_GART_PAGE, dev_priv->bus_pci_gart );
|
||||
}
|
||||
|
||||
r128_cce_init_ring_buffer( dev, dev_priv );
|
||||
|
|
@ -629,6 +636,11 @@ int r128_do_cleanup_cce( drm_device_t *dev )
|
|||
DRM_IOREMAPFREE( dev_priv->cce_ring );
|
||||
DRM_IOREMAPFREE( dev_priv->ring_rptr );
|
||||
DRM_IOREMAPFREE( dev_priv->buffers );
|
||||
} else {
|
||||
if (!DRM(ati_pcigart_cleanup)( dev,
|
||||
dev_priv->phys_pci_gart,
|
||||
dev_priv->bus_pci_gart ))
|
||||
DRM_ERROR( "failed to cleanup PCI GART!\n" );
|
||||
}
|
||||
|
||||
DRM(free)( dev->dev_private, sizeof(drm_r128_private_t),
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ typedef struct drm_r128_private {
|
|||
int usec_timeout;
|
||||
int is_pci;
|
||||
unsigned long phys_pci_gart;
|
||||
dma_addr_t bus_pci_gart;
|
||||
unsigned long cce_buffers_offset;
|
||||
|
||||
atomic_t idle_count;
|
||||
|
|
|
|||
|
|
@ -622,13 +622,20 @@ static void radeon_cp_init_ring_buffer( drm_device_t *dev,
|
|||
|
||||
tmp_ofs = dev_priv->ring_rptr->offset - dev->sg->handle;
|
||||
page_ofs = tmp_ofs >> PAGE_SHIFT;
|
||||
|
||||
#if defined(__alpha__) && (LINUX_VERSION_CODE >= 0x020400)
|
||||
RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
|
||||
entry->busaddr[page_ofs]);
|
||||
DRM_DEBUG( "ring rptr: offset=0x%08x handle=0x%08lx\n",
|
||||
entry->busaddr[page_ofs],
|
||||
entry->handle + tmp_ofs );
|
||||
#else
|
||||
RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
|
||||
virt_to_bus(entry->pagelist[page_ofs]->virtual));
|
||||
|
||||
DRM_DEBUG( "ring rptr: offset=0x%08lx handle=0x%08lx\n",
|
||||
virt_to_bus(entry->pagelist[page_ofs]->virtual),
|
||||
entry->handle + tmp_ofs );
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Set ring buffer size */
|
||||
|
|
@ -929,8 +936,8 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
|
|||
dev_priv->sarea_priv->last_clear );
|
||||
|
||||
if ( dev_priv->is_pci ) {
|
||||
dev_priv->phys_pci_gart = DRM(ati_pcigart_init)( dev );
|
||||
if ( !dev_priv->phys_pci_gart ) {
|
||||
if (!DRM(ati_pcigart_init)( dev, &dev_priv->phys_pci_gart,
|
||||
&dev_priv->bus_pci_gart)) {
|
||||
DRM_ERROR( "failed to init PCI GART!\n" );
|
||||
dev->dev_private = (void *)dev_priv;
|
||||
radeon_do_cleanup_cp(dev);
|
||||
|
|
@ -944,8 +951,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
|
|||
|
||||
/* set PCI GART page-table base address
|
||||
*/
|
||||
RADEON_WRITE( RADEON_AIC_PT_BASE,
|
||||
virt_to_bus( (void *)dev_priv->phys_pci_gart ) );
|
||||
RADEON_WRITE( RADEON_AIC_PT_BASE, dev_priv->bus_pci_gart );
|
||||
|
||||
/* set address range for PCI address translate
|
||||
*/
|
||||
|
|
@ -990,6 +996,11 @@ int radeon_do_cleanup_cp( drm_device_t *dev )
|
|||
DRM_IOREMAPFREE( dev_priv->cp_ring );
|
||||
DRM_IOREMAPFREE( dev_priv->ring_rptr );
|
||||
DRM_IOREMAPFREE( dev_priv->buffers );
|
||||
} else {
|
||||
if (!DRM(ati_pcigart_cleanup)( dev,
|
||||
dev_priv->phys_pci_gart,
|
||||
dev_priv->bus_pci_gart ))
|
||||
DRM_ERROR( "failed to cleanup PCI GART!\n" );
|
||||
}
|
||||
|
||||
DRM(free)( dev->dev_private, sizeof(drm_radeon_private_t),
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ typedef struct drm_radeon_private {
|
|||
int usec_timeout;
|
||||
int is_pci;
|
||||
unsigned long phys_pci_gart;
|
||||
dma_addr_t bus_pci_gart;
|
||||
|
||||
atomic_t idle_count;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue