aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/ati_pcigart.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@starflyer.(none)>2005-09-11 06:28:11 -0400
committerDave Airlie <airlied@linux.ie>2005-09-11 06:28:11 -0400
commitea98a92ff18c03bf7f4d21536986cbbcb4c10cd9 (patch)
treefbff15aaacf19824083c9edb8d37548031636580 /drivers/char/drm/ati_pcigart.c
parent9d17601c4e132eee9fe450191f6866fb9fb5a762 (diff)
drm: add radeon PCI express support
Add support for Radeon PCI Express cards (needs a new X.org DDX) Also allows PCI GART table to be stored in VRAM for non PCIE cards Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char/drm/ati_pcigart.c')
-rw-r--r--drivers/char/drm/ati_pcigart.c82
1 files changed, 49 insertions, 33 deletions
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
index 0aec5ef481b8..957596c63934 100644
--- a/drivers/char/drm/ati_pcigart.c
+++ b/drivers/char/drm/ati_pcigart.c
@@ -91,9 +91,7 @@ static void drm_ati_free_pcigart_table( unsigned long address )
91 free_pages( address, ATI_PCIGART_TABLE_ORDER ); 91 free_pages( address, ATI_PCIGART_TABLE_ORDER );
92} 92}
93 93
94int drm_ati_pcigart_cleanup( drm_device_t *dev, 94int drm_ati_pcigart_cleanup(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
95 unsigned long addr,
96 dma_addr_t bus_addr)
97{ 95{
98 drm_sg_mem_t *entry = dev->sg; 96 drm_sg_mem_t *entry = dev->sg;
99 unsigned long pages; 97 unsigned long pages;
@@ -105,10 +103,12 @@ int drm_ati_pcigart_cleanup( drm_device_t *dev,
105 return 0; 103 return 0;
106 } 104 }
107 105
108 if ( bus_addr ) { 106 if (gart_info->bus_addr) {
109 pci_unmap_single(dev->pdev, bus_addr, 107 if (gart_info->gart_table_location==DRM_ATI_GART_MAIN) {
110 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, 108 pci_unmap_single(dev->pdev, gart_info->bus_addr,
111 PCI_DMA_TODEVICE); 109 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
110 PCI_DMA_TODEVICE);
111 }
112 112
113 pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES ) 113 pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
114 ? entry->pages : ATI_MAX_PCIGART_PAGES; 114 ? entry->pages : ATI_MAX_PCIGART_PAGES;
@@ -118,19 +118,21 @@ int drm_ati_pcigart_cleanup( drm_device_t *dev,
118 pci_unmap_single(dev->pdev, entry->busaddr[i], 118 pci_unmap_single(dev->pdev, entry->busaddr[i],
119 PAGE_SIZE, PCI_DMA_TODEVICE); 119 PAGE_SIZE, PCI_DMA_TODEVICE);
120 } 120 }
121
122 if (gart_info->gart_table_location==DRM_ATI_GART_MAIN)
123 gart_info->bus_addr=0;
121 } 124 }
122 125
123 if ( addr ) { 126 if (gart_info->gart_table_location==DRM_ATI_GART_MAIN && gart_info->addr) {
124 drm_ati_free_pcigart_table( addr ); 127 drm_ati_free_pcigart_table(gart_info->addr);
128 gart_info->addr=0;
125 } 129 }
126 130
127 return 1; 131 return 1;
128} 132}
129EXPORT_SYMBOL(drm_ati_pcigart_cleanup); 133EXPORT_SYMBOL(drm_ati_pcigart_cleanup);
130 134
131int drm_ati_pcigart_init( drm_device_t *dev, 135int drm_ati_pcigart_init(drm_device_t *dev, drm_ati_pcigart_info *gart_info)
132 unsigned long *addr,
133 dma_addr_t *bus_addr)
134{ 136{
135 drm_sg_mem_t *entry = dev->sg; 137 drm_sg_mem_t *entry = dev->sg;
136 unsigned long address = 0; 138 unsigned long address = 0;
@@ -143,25 +145,36 @@ int drm_ati_pcigart_init( drm_device_t *dev,
143 goto done; 145 goto done;
144 } 146 }
145 147
146 address = drm_ati_alloc_pcigart_table(); 148 if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
147 if ( !address ) { 149 {
148 DRM_ERROR( "cannot allocate PCI GART page!\n" ); 150 DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n");
149 goto done; 151
150 } 152 address = drm_ati_alloc_pcigart_table();
153 if ( !address ) {
154 DRM_ERROR( "cannot allocate PCI GART page!\n" );
155 goto done;
156 }
157
158 if ( !dev->pdev ) {
159 DRM_ERROR( "PCI device unknown!\n" );
160 goto done;
161 }
151 162
152 if ( !dev->pdev ) { 163 bus_address = pci_map_single(dev->pdev, (void *)address,
153 DRM_ERROR( "PCI device unknown!\n" ); 164 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
154 goto done; 165 PCI_DMA_TODEVICE);
166 if (bus_address == 0) {
167 DRM_ERROR( "unable to map PCIGART pages!\n" );
168 drm_ati_free_pcigart_table( address );
169 address = 0;
170 goto done;
171 }
155 } 172 }
156 173 else
157 bus_address = pci_map_single(dev->pdev, (void *)address, 174 {
158 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, 175 address = gart_info->addr;
159 PCI_DMA_TODEVICE); 176 bus_address = gart_info->bus_addr;
160 if (bus_address == 0) { 177 DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n", bus_address, address);
161 DRM_ERROR( "unable to map PCIGART pages!\n" );
162 drm_ati_free_pcigart_table( address );
163 address = 0;
164 goto done;
165 } 178 }
166 179
167 pci_gart = (u32 *)address; 180 pci_gart = (u32 *)address;
@@ -179,7 +192,7 @@ int drm_ati_pcigart_init( drm_device_t *dev,
179 PCI_DMA_TODEVICE); 192 PCI_DMA_TODEVICE);
180 if (entry->busaddr[i] == 0) { 193 if (entry->busaddr[i] == 0) {
181 DRM_ERROR( "unable to map PCIGART pages!\n" ); 194 DRM_ERROR( "unable to map PCIGART pages!\n" );
182 drm_ati_pcigart_cleanup( dev, address, bus_address ); 195 drm_ati_pcigart_cleanup(dev, gart_info);
183 address = 0; 196 address = 0;
184 bus_address = 0; 197 bus_address = 0;
185 goto done; 198 goto done;
@@ -187,7 +200,10 @@ int drm_ati_pcigart_init( drm_device_t *dev,
187 page_base = (u32) entry->busaddr[i]; 200 page_base = (u32) entry->busaddr[i];
188 201
189 for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { 202 for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
190 *pci_gart++ = cpu_to_le32( page_base ); 203 if (gart_info->is_pcie)
204 *pci_gart = (cpu_to_le32(page_base)>>8) | 0xc;
205 else
206 *pci_gart++ = cpu_to_le32( page_base );
191 page_base += ATI_PCIGART_PAGE_SIZE; 207 page_base += ATI_PCIGART_PAGE_SIZE;
192 } 208 }
193 } 209 }
@@ -201,8 +217,8 @@ int drm_ati_pcigart_init( drm_device_t *dev,
201#endif 217#endif
202 218
203done: 219done:
204 *addr = address; 220 gart_info->addr = address;
205 *bus_addr = bus_address; 221 gart_info->bus_addr = bus_address;
206 return ret; 222 return ret;
207} 223}
208EXPORT_SYMBOL(drm_ati_pcigart_init); 224EXPORT_SYMBOL(drm_ati_pcigart_init);