aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/ati_pcigart.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-11-02 00:49:07 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-02 00:49:07 -0500
commitd8762748cae4f85b3201c0304969d993b42d5258 (patch)
tree559819d9b17e5ee305d705cf9f31ac5de2aab54a /drivers/char/drm/ati_pcigart.c
parentce4633704038f9bf39f20c10691747d6fc127bf4 (diff)
parenta4e62fa031a9681477207b08391c3a5c5c831ce7 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6
Manual fixups for some clashes due to re-indenting.
Diffstat (limited to 'drivers/char/drm/ati_pcigart.c')
-rw-r--r--drivers/char/drm/ati_pcigart.c152
1 files changed, 86 insertions, 66 deletions
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
index 0aec5ef481b8..6d3fec160bff 100644
--- a/drivers/char/drm/ati_pcigart.c
+++ b/drivers/char/drm/ati_pcigart.c
@@ -1,5 +1,5 @@
1/** 1/**
2 * \file ati_pcigart.h 2 * \file ati_pcigart.c
3 * ATI PCI GART support 3 * ATI PCI GART support
4 * 4 *
5 * \author Gareth Hughes <gareth@valinux.com> 5 * \author Gareth Hughes <gareth@valinux.com>
@@ -52,85 +52,91 @@
52# define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */ 52# define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */
53# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */ 53# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
54 54
55static unsigned long drm_ati_alloc_pcigart_table( void ) 55static unsigned long drm_ati_alloc_pcigart_table(void)
56{ 56{
57 unsigned long address; 57 unsigned long address;
58 struct page *page; 58 struct page *page;
59 int i; 59 int i;
60 DRM_DEBUG( "%s\n", __FUNCTION__ ); 60 DRM_DEBUG("%s\n", __FUNCTION__);
61 61
62 address = __get_free_pages( GFP_KERNEL, ATI_PCIGART_TABLE_ORDER ); 62 address = __get_free_pages(GFP_KERNEL, ATI_PCIGART_TABLE_ORDER);
63 if ( address == 0UL ) { 63 if (address == 0UL) {
64 return 0; 64 return 0;
65 } 65 }
66 66
67 page = virt_to_page( address ); 67 page = virt_to_page(address);
68 68
69 for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) { 69 for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) {
70 get_page(page); 70 get_page(page);
71 SetPageReserved( page ); 71 SetPageReserved(page);
72 } 72 }
73 73
74 DRM_DEBUG( "%s: returning 0x%08lx\n", __FUNCTION__, address ); 74 DRM_DEBUG("%s: returning 0x%08lx\n", __FUNCTION__, address);
75 return address; 75 return address;
76} 76}
77 77
78static void drm_ati_free_pcigart_table( unsigned long address ) 78static void drm_ati_free_pcigart_table(unsigned long address)
79{ 79{
80 struct page *page; 80 struct page *page;
81 int i; 81 int i;
82 DRM_DEBUG( "%s\n", __FUNCTION__ ); 82 DRM_DEBUG("%s\n", __FUNCTION__);
83 83
84 page = virt_to_page( address ); 84 page = virt_to_page(address);
85 85
86 for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) { 86 for (i = 0; i < ATI_PCIGART_TABLE_PAGES; i++, page++) {
87 __put_page(page); 87 __put_page(page);
88 ClearPageReserved( page ); 88 ClearPageReserved(page);
89 } 89 }
90 90
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,
95 unsigned long addr, 95 drm_ati_pcigart_info * gart_info)
96 dma_addr_t bus_addr)
97{ 96{
98 drm_sg_mem_t *entry = dev->sg; 97 drm_sg_mem_t *entry = dev->sg;
99 unsigned long pages; 98 unsigned long pages;
100 int i; 99 int i;
101 100
102 /* we need to support large memory configurations */ 101 /* we need to support large memory configurations */
103 if ( !entry ) { 102 if (!entry) {
104 DRM_ERROR( "no scatter/gather memory!\n" ); 103 DRM_ERROR("no scatter/gather memory!\n");
105 return 0; 104 return 0;
106 } 105 }
107 106
108 if ( bus_addr ) { 107 if (gart_info->bus_addr) {
109 pci_unmap_single(dev->pdev, bus_addr, 108 if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
110 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, 109 pci_unmap_single(dev->pdev, gart_info->bus_addr,
111 PCI_DMA_TODEVICE); 110 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
111 PCI_DMA_TODEVICE);
112 }
112 113
113 pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES ) 114 pages = (entry->pages <= ATI_MAX_PCIGART_PAGES)
114 ? entry->pages : ATI_MAX_PCIGART_PAGES; 115 ? entry->pages : ATI_MAX_PCIGART_PAGES;
115 116
116 for ( i = 0 ; i < pages ; i++ ) { 117 for (i = 0; i < pages; i++) {
117 if ( !entry->busaddr[i] ) break; 118 if (!entry->busaddr[i])
119 break;
118 pci_unmap_single(dev->pdev, entry->busaddr[i], 120 pci_unmap_single(dev->pdev, entry->busaddr[i],
119 PAGE_SIZE, PCI_DMA_TODEVICE); 121 PAGE_SIZE, PCI_DMA_TODEVICE);
120 } 122 }
123
124 if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
125 gart_info->bus_addr = 0;
121 } 126 }
122 127
123 if ( addr ) { 128 if (gart_info->gart_table_location == DRM_ATI_GART_MAIN
124 drm_ati_free_pcigart_table( addr ); 129 && gart_info->addr) {
130 drm_ati_free_pcigart_table(gart_info->addr);
131 gart_info->addr = 0;
125 } 132 }
126 133
127 return 1; 134 return 1;
128} 135}
136
129EXPORT_SYMBOL(drm_ati_pcigart_cleanup); 137EXPORT_SYMBOL(drm_ati_pcigart_cleanup);
130 138
131int drm_ati_pcigart_init( drm_device_t *dev, 139int 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{ 140{
135 drm_sg_mem_t *entry = dev->sg; 141 drm_sg_mem_t *entry = dev->sg;
136 unsigned long address = 0; 142 unsigned long address = 0;
@@ -138,48 +144,57 @@ int drm_ati_pcigart_init( drm_device_t *dev,
138 u32 *pci_gart, page_base, bus_address = 0; 144 u32 *pci_gart, page_base, bus_address = 0;
139 int i, j, ret = 0; 145 int i, j, ret = 0;
140 146
141 if ( !entry ) { 147 if (!entry) {
142 DRM_ERROR( "no scatter/gather memory!\n" ); 148 DRM_ERROR("no scatter/gather memory!\n");
143 goto done; 149 goto done;
144 } 150 }
145 151
146 address = drm_ati_alloc_pcigart_table(); 152 if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
147 if ( !address ) { 153 DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n");
148 DRM_ERROR( "cannot allocate PCI GART page!\n" );
149 goto done;
150 }
151 154
152 if ( !dev->pdev ) { 155 address = drm_ati_alloc_pcigart_table();
153 DRM_ERROR( "PCI device unknown!\n" ); 156 if (!address) {
154 goto done; 157 DRM_ERROR("cannot allocate PCI GART page!\n");
155 } 158 goto done;
159 }
156 160
157 bus_address = pci_map_single(dev->pdev, (void *)address, 161 if (!dev->pdev) {
158 ATI_PCIGART_TABLE_PAGES * PAGE_SIZE, 162 DRM_ERROR("PCI device unknown!\n");
159 PCI_DMA_TODEVICE); 163 goto done;
160 if (bus_address == 0) { 164 }
161 DRM_ERROR( "unable to map PCIGART pages!\n" ); 165
162 drm_ati_free_pcigart_table( address ); 166 bus_address = pci_map_single(dev->pdev, (void *)address,
163 address = 0; 167 ATI_PCIGART_TABLE_PAGES *
164 goto done; 168 PAGE_SIZE, PCI_DMA_TODEVICE);
169 if (bus_address == 0) {
170 DRM_ERROR("unable to map PCIGART pages!\n");
171 drm_ati_free_pcigart_table(address);
172 address = 0;
173 goto done;
174 }
175 } else {
176 address = gart_info->addr;
177 bus_address = gart_info->bus_addr;
178 DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n",
179 bus_address, address);
165 } 180 }
166 181
167 pci_gart = (u32 *)address; 182 pci_gart = (u32 *) address;
168 183
169 pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES ) 184 pages = (entry->pages <= ATI_MAX_PCIGART_PAGES)
170 ? entry->pages : ATI_MAX_PCIGART_PAGES; 185 ? entry->pages : ATI_MAX_PCIGART_PAGES;
171 186
172 memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) ); 187 memset(pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32));
173 188
174 for ( i = 0 ; i < pages ; i++ ) { 189 for (i = 0; i < pages; i++) {
175 /* we need to support large memory configurations */ 190 /* we need to support large memory configurations */
176 entry->busaddr[i] = pci_map_single(dev->pdev, 191 entry->busaddr[i] = pci_map_single(dev->pdev,
177 page_address( entry->pagelist[i] ), 192 page_address(entry->
178 PAGE_SIZE, 193 pagelist[i]),
179 PCI_DMA_TODEVICE); 194 PAGE_SIZE, PCI_DMA_TODEVICE);
180 if (entry->busaddr[i] == 0) { 195 if (entry->busaddr[i] == 0) {
181 DRM_ERROR( "unable to map PCIGART pages!\n" ); 196 DRM_ERROR("unable to map PCIGART pages!\n");
182 drm_ati_pcigart_cleanup( dev, address, bus_address ); 197 drm_ati_pcigart_cleanup(dev, gart_info);
183 address = 0; 198 address = 0;
184 bus_address = 0; 199 bus_address = 0;
185 goto done; 200 goto done;
@@ -187,7 +202,11 @@ int drm_ati_pcigart_init( drm_device_t *dev,
187 page_base = (u32) entry->busaddr[i]; 202 page_base = (u32) entry->busaddr[i];
188 203
189 for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) { 204 for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
190 *pci_gart++ = cpu_to_le32( page_base ); 205 if (gart_info->is_pcie)
206 *pci_gart = (cpu_to_le32(page_base) >> 8) | 0xc;
207 else
208 *pci_gart = cpu_to_le32(page_base);
209 *pci_gart++;
191 page_base += ATI_PCIGART_PAGE_SIZE; 210 page_base += ATI_PCIGART_PAGE_SIZE;
192 } 211 }
193 } 212 }
@@ -200,9 +219,10 @@ int drm_ati_pcigart_init( drm_device_t *dev,
200 mb(); 219 mb();
201#endif 220#endif
202 221
203done: 222 done:
204 *addr = address; 223 gart_info->addr = address;
205 *bus_addr = bus_address; 224 gart_info->bus_addr = bus_address;
206 return ret; 225 return ret;
207} 226}
227
208EXPORT_SYMBOL(drm_ati_pcigart_init); 228EXPORT_SYMBOL(drm_ati_pcigart_init);