aboutsummaryrefslogtreecommitdiff
path: root/linux-core/ati_pcigart.c
diff options
context:
space:
mode:
authorJeff Hartmann <jhartmann@valinux.com>2001-08-10 16:29:21 +0000
committerJeff Hartmann <jhartmann@valinux.com>2001-08-10 16:29:21 +0000
commit97b8aa52bba602d5babe225983f7e4c7cb4d7492 (patch)
tree922882797ea335549c01849c4dd2cdc350938be0 /linux-core/ati_pcigart.c
parentb6923b39539c34c2a589197def5eee72a9d719bf (diff)
Commit Keith Owens kernel Makefile changes, merge and commit alpha patch
set from Jay Estabrook (sans some mga modifications which broke other arch's.)
Diffstat (limited to 'linux-core/ati_pcigart.c')
-rw-r--r--linux-core/ati_pcigart.c95
1 files changed, 82 insertions, 13 deletions
diff --git a/linux-core/ati_pcigart.c b/linux-core/ati_pcigart.c
index 93c5148f..99d17ee7 100644
--- a/linux-core/ati_pcigart.c
+++ b/linux-core/ati_pcigart.c
@@ -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,24 +82,45 @@ 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;
@@ -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;
+ }
+
+ 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 0;
+ return 1;
}