Rev 948 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 948 | Rev 951 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | #include "types.h" |
1 | #include "types.h" |
- | 2 | #include "link.h" |
|
Line 2... | Line 3... | ||
2 | 3 | ||
3 | #include |
4 | #include |
4 | #include |
5 | #include |
Line 9... | Line 10... | ||
9 | 10 | ||
Line 10... | Line 11... | ||
10 | #include "syscall.h" |
11 | #include "syscall.h" |
Line 11... | Line 12... | ||
11 | 12 | ||
Line 12... | Line 13... | ||
12 | 13 | ||
Line 45... | Line 46... | ||
45 | // return retval; |
46 | // return retval; |
46 | }; |
47 | }; |
Line -... | Line 48... | ||
- | 48 | ||
- | 49 | ||
47 | 50 | #include "pci.inc" |
|
48 | 51 | ||
49 | static void intel_8xx_tlbflush(void *mem) |
52 | static void intel_8xx_tlbflush(void *mem) |
Line 50... | Line 53... | ||
50 | { |
53 | { |
51 | u32_t temp; |
54 | u32_t temp; |
52 | 55 | ||
53 | temp = pciReadLong(agp_dev.PciTag, INTEL_AGPCTRL); |
56 | temp = pciReadLong(bridge->PciTag, INTEL_AGPCTRL); |
54 | pciWriteLong(agp_dev.PciTag, INTEL_AGPCTRL, temp & ~(1 << 7)); |
57 | pciWriteLong(bridge->PciTag, INTEL_AGPCTRL, temp & ~(1 << 7)); |
Line 55... | Line 58... | ||
55 | temp = pciReadLong(agp_dev.PciTag, INTEL_AGPCTRL); |
58 | temp = pciReadLong(bridge->PciTag, INTEL_AGPCTRL); |
56 | pciWriteLong(agp_dev.PciTag, INTEL_AGPCTRL, temp | (1 << 7)); |
59 | pciWriteLong(bridge->PciTag, INTEL_AGPCTRL, temp | (1 << 7)); |
Line 67... | Line 70... | ||
67 | { 8, 2048, 2, 62 }, |
70 | { 8, 2048, 2, 62 }, |
68 | { 4, 1024, 1, 63 } |
71 | { 4, 1024, 1, 63 } |
69 | }; |
72 | }; |
70 | 73 | ||
Line 71... | Line -... | ||
71 | #if 0 |
- | |
72 | static int agp_backend_initialize(struct agp_bridge_data *bridge) |
- | |
73 | { |
- | |
74 | int size_value, rc, got_gatt=0, got_keylist=0; |
- | |
75 | - | ||
76 | bridge->max_memory_agp = agp_find_max(); |
- | |
77 | bridge->version = &agp_current_version; |
- | |
78 | - | ||
79 | if (bridge->driver->needs_scratch_page) { |
- | |
80 | void *addr = bridge->driver->agp_alloc_page(bridge); |
- | |
81 | - | ||
82 | if (!addr) { |
- | |
83 | printk(KERN_ERR PFX "unable to get memory for scratch page.\n"); |
- | |
84 | return -ENOMEM; |
- | |
85 | } |
- | |
86 | flush_agp_mappings(); |
- | |
87 | - | ||
88 | bridge->scratch_page_real = virt_to_gart(addr); |
- | |
89 | bridge->scratch_page = |
- | |
90 | bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0); |
- | |
91 | } |
- | |
92 | - | ||
93 | size_value = bridge->driver->fetch_size(); |
- | |
94 | if (size_value == 0) { |
- | |
95 | printk(KERN_ERR PFX "unable to determine aperture size.\n"); |
- | |
96 | rc = -EINVAL; |
- | |
97 | goto err_out; |
- | |
98 | } |
- | |
99 | if (bridge->driver->create_gatt_table(bridge)) { |
- | |
100 | printk(KERN_ERR PFX |
- | |
101 | "unable to get memory for graphics translation table.\n"); |
- | |
102 | rc = -ENOMEM; |
- | |
103 | goto err_out; |
- | |
104 | } |
- | |
105 | got_gatt = 1; |
- | |
106 | - | ||
107 | bridge->key_list = vmalloc(PAGE_SIZE * 4); |
- | |
108 | if (bridge->key_list == NULL) { |
- | |
109 | printk(KERN_ERR PFX "error allocating memory for key lists.\n"); |
- | |
110 | rc = -ENOMEM; |
- | |
111 | goto err_out; |
- | |
112 | } |
- | |
113 | got_keylist = 1; |
- | |
114 | - | ||
115 | /* FIXME vmalloc'd memory not guaranteed contiguous */ |
- | |
116 | memset(bridge->key_list, 0, PAGE_SIZE * 4); |
- | |
Line 117... | Line -... | ||
117 | - | ||
118 | if (bridge->driver->configure()) { |
- | |
119 | printk(KERN_ERR PFX "error configuring host chipset.\n"); |
- | |
120 | rc = -EINVAL; |
- | |
121 | goto err_out; |
- | |
Line 122... | Line -... | ||
122 | } |
- | |
123 | - | ||
124 | return 0; |
- | |
125 | - | ||
126 | err_out: |
- | |
127 | if (bridge->driver->needs_scratch_page) { |
- | |
128 | bridge->driver->agp_destroy_page( |
- | |
129 | gart_to_virt(bridge->scratch_page_real)); |
- | |
130 | flush_agp_mappings(); |
- | |
131 | } |
- | |
132 | if (got_gatt) |
- | |
133 | bridge->driver->free_gatt_table(bridge); |
- | |
134 | if (got_keylist) { |
- | |
135 | vfree(bridge->key_list); |
- | |
136 | bridge->key_list = NULL; |
- | |
137 | } |
- | |
138 | return rc; |
- | |
139 | } |
- | |
140 | - | ||
141 | - | ||
142 | #endif |
- | |
143 | 74 | ||
144 | 75 | ||
145 | static int intel_845_configure(void *bridge) |
76 | static int intel_845_configure() |
146 | { |
77 | { |
147 | u32_t temp; |
78 | u32_t temp; |
Line 148... | Line -... | ||
148 | u8_t temp2; |
- | |
149 | aper_size_t *current_size; |
- | |
150 | 79 | u8_t temp2; |
|
Line 151... | Line 80... | ||
151 | agp_t *agp = (agp_t*)bridge; |
80 | aper_size_t *current_size; |
152 | 81 | ||
Line 153... | Line 82... | ||
153 | current_size = agp->current_size; |
82 | current_size = bridge->current_size; |
Line 154... | Line 83... | ||
154 | 83 | ||
155 | /* aperture size */ |
84 | /* aperture size */ |
156 | pciWriteByte(agp->PciTag, INTEL_APSIZE, current_size->size_value); |
85 | pciWriteByte(bridge->PciTag, INTEL_APSIZE, current_size->size_value); |
157 | 86 | ||
158 | dbgprintf("INTEL_APSIZE %d\n", current_size->size_value ); |
87 | dbgprintf("INTEL_APSIZE %d\n", current_size->size_value ); |
159 | 88 | ||
160 | if (agp->apbase_config != 0) |
89 | if (bridge->apbase_config != 0) |
161 | { |
90 | { |
162 | pciWriteLong(agp->PciTag, AGP_APBASE, agp->apbase_config); |
91 | pciWriteLong(bridge->PciTag, AGP_APBASE, bridge->apbase_config); |
163 | } |
92 | } |
164 | else |
93 | else |
Line 165... | Line 94... | ||
165 | { |
94 | { |
Line 166... | Line 95... | ||
166 | /* address to map to */ |
95 | /* address to map to */ |
167 | temp = pciReadLong(agp->PciTag, AGP_APBASE); |
96 | temp = pciReadLong(bridge->PciTag, AGP_APBASE); |
Line 168... | Line 97... | ||
168 | agp->gart_addr = (temp & PCI_MAP_MEMORY_ADDRESS_MASK); |
97 | bridge->gart_addr = (temp & PCI_MAP_MEMORY_ADDRESS_MASK); |
169 | agp->apbase_config = temp; |
98 | bridge->apbase_config = temp; |
Line 170... | Line 99... | ||
170 | } |
99 | } |
171 | 100 | ||
172 | dbgprintf("AGP_APBASE %x\n", temp ); |
101 | dbgprintf("AGP_APBASE %x\n", temp ); |
173 | 102 | ||
174 | /* attbase - aperture base */ |
103 | /* attbase - aperture base */ |
175 | pciWriteLong(agp->PciTag, INTEL_ATTBASE, agp->gatt_dma); |
104 | pciWriteLong(bridge->PciTag, INTEL_ATTBASE, bridge->gatt_dma); |
176 | 105 | ||
Line 177... | Line 106... | ||
177 | /* agpctrl */ |
106 | /* agpctrl */ |
178 | pciWriteLong(agp->PciTag, INTEL_AGPCTRL, 0x0000); |
107 | pciWriteLong(bridge->PciTag, INTEL_AGPCTRL, 0x0000); |
179 | 108 | ||
Line 180... | Line 109... | ||
180 | /* agpm */ |
109 | /* agpm */ |
Line 181... | Line 110... | ||
181 | temp2 = pciReadByte(agp->PciTag, INTEL_I845_AGPM); |
110 | temp2 = pciReadByte(bridge->PciTag, INTEL_I845_AGPM); |
182 | pciWriteByte(agp->PciTag, INTEL_I845_AGPM, temp2 | (1 << 1)); |
111 | pciWriteByte(bridge->PciTag, INTEL_I845_AGPM, temp2 | (1 << 1)); |
- | 112 | /* clear any possible error conditions */ |
|
183 | /* clear any possible error conditions */ |
113 | pciWriteWord(bridge->PciTag, INTEL_I845_ERRSTS, 0x001c); |
184 | pciWriteWord(agp->PciTag, INTEL_I845_ERRSTS, 0x001c); |
114 | return 0; |
185 | return 0; |
115 | } |
186 | } |
116 | |
187 | 117 | ||
Line 188... | Line -... | ||
188 | - | ||
189 | int agp_generic_create_gatt_table(agp_t *bridge) |
- | |
190 | { |
- | |
191 | count_t pages; |
118 | int agp_generic_create_gatt_table() |
192 | - | ||
193 | pages = bridge->current_size->pages_count; |
- | |
194 | - | ||
195 | bridge->gatt_dma = AllocPages(pages); |
- | |
Line -... | Line 119... | ||
- | 119 | { |
|
- | 120 | count_t pages; |
|
- | 121 | ||
- | 122 | pages = bridge->current_size->pages_count; |
|
- | 123 | ||
- | 124 | if( bridge->gatt_dma = AllocPages(pages)) |
|
- | 125 | { |
|
- | 126 | if(bridge->gatt_table = |
|
- | 127 | (u32_t*)MapIoMem((void*)bridge->gatt_dma, |
|
- | 128 | pages<<12, PG_SW+PG_NOCACHE)) |
|
- | 129 | { |
|
- | 130 | dbgprintf("gatt map %x at %x %d pages\n",bridge->gatt_dma , |
|
- | 131 | bridge->gatt_table, pages); |
|
- | 132 | ||
- | 133 | /* AK: bogus, should encode addresses > 4GB */ |
|
196 | 134 | ||
197 | bridge->gatt_table = (u32_t*)MapIoMem((void*)bridge->gatt_dma, |
135 | u32_t volatile *table = bridge->gatt_table; |
Line 198... | Line -... | ||
198 | pages<<12, PG_SW+PG_NOCACHE); |
- | |
199 | 136 | ||
200 | dbgprintf("gatt map %x at %x %d pages\n",bridge->gatt_dma , |
137 | count_t count = bridge->current_size->num_entries; |
201 | bridge->gatt_table, pages); |
138 | |
202 | 139 | while(count--) { /* FIXME memset */ |
|
Line 203... | Line 140... | ||
203 | if (bridge->gatt_table == NULL) |
140 | addr_t tmp; |
Line 204... | Line 141... | ||
204 | return -30;//ENOMEM; |
141 | |
Line 205... | Line 142... | ||
205 | 142 | *table = 0; |
|
206 | /* AK: bogus, should encode addresses > 4GB */ |
143 | table++; |
207 | // for (i = 0; i < num_entries; i++) { |
144 | } |
208 | // writel(bridge->scratch_page, bridge->gatt_table+i); |
145 | return 1; |
209 | // readl(bridge->gatt_table+i); /* PCI Posting. */ |
146 | }; |
210 | // } |
147 | }; |
211 | 148 | dbgprintf("unable to get memory for " |
|
212 | return 0; |
149 | "graphics translation table.\n"); |
213 | } |
150 | return 0; |
214 | 151 | } |
|
215 | 152 | ||
216 | 153 | ||
Line 217... | Line 154... | ||
217 | static int __intel_8xx_fetch_size(u8_t temp) |
154 | static int __intel_8xx_fetch_size(u8_t temp) |
218 | { |
155 | { |
219 | int i; |
156 | int i; |
Line 220... | Line 157... | ||
220 | aper_size_t *values; |
157 | aper_size_t *values; |
221 | 158 | ||
222 | // values = A_SIZE_8(agp_bridge->driver->aperture_sizes); |
159 | values = bridge->aperture_sizes; |
Line 223... | Line 160... | ||
223 | 160 | ||
Line 262... | Line 199... | ||
262 | // curr->is_flushed = TRUE; |
199 | // curr->is_flushed = TRUE; |
263 | // } |
200 | // } |
264 | // ret_val = curr->bridge->driver->insert_memory(curr, pg_start, curr->type); |
201 | // ret_val = curr->bridge->driver->insert_memory(curr, pg_start, curr->type); |
265 | 202 | ||
Line 266... | Line 203... | ||
266 | u32_t volatile *table = &agp_dev.gatt_table[agp_addr>>12]; |
203 | u32_t volatile *table = &bridge->gatt_table[agp_addr>>12]; |
Line 267... | Line 204... | ||
267 | 204 | ||
Line 268... | Line 205... | ||
268 | count = size >> 12; |
205 | count = size >> 12; |
Line 269... | Line 206... | ||
269 | 206 | ||
270 | dma_addr |= 0x00000017; |
207 | dma_addr |= 0x00000017; |
271 | - | ||
272 | while(count--) |
- | |
273 | { |
208 | |
274 | addr_t tmp; |
- | |
275 | 209 | while(count--) |
|
276 | *table = dma_addr; |
210 | { |
277 | tmp = *table; /* PCI Posting. */ |
211 | *table = dma_addr; |
Line 278... | Line 212... | ||
278 | table++; |
212 | table++; |
Line 279... | Line 213... | ||
279 | dma_addr+=4096; |
213 | dma_addr+=4096; |
280 | } |
214 | } |
Line 281... | Line 215... | ||
281 | 215 | ||
282 | agp_dev.tlb_flush(NULL); |
216 | bridge->tlb_flush(NULL); |
283 | 217 | ||
284 | // if (ret_val != 0) |
218 | // if (ret_val != 0) |
Line -... | Line 219... | ||
- | 219 | // return ret_val; |
|
- | 220 | ||
- | 221 | // curr->is_bound = TRUE; |
|
- | 222 | // curr->pg_start = pg_start; |
|
- | 223 | return 0; |
|
- | 224 | } |
|
- | 225 | ||
- | 226 | void get_agp_version(agp_t *bridge) |
|
- | 227 | { |
|
- | 228 | u32_t ncapid; |
|
- | 229 | ||
- | 230 | /* Exit early if already set by errata workarounds. */ |
|
- | 231 | if (bridge->major_version != 0) |
|
- | 232 | return; |
|
- | 233 | ||
- | 234 | ncapid = pciReadLong(bridge->PciTag, bridge->capndx); |
|
- | 235 | bridge->major_version = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf; |
|
- | 236 | bridge->minor_version = (ncapid >> AGP_MINOR_VERSION_SHIFT) & 0xf; |
|
- | 237 | } |
|
- | 238 | ||
- | 239 | static void agp_v2_parse_one(u32_t *requested_mode, u32_t *bridge_agpstat, u32_t *vga_agpstat) |
|
- | 240 | { |
|
- | 241 | u32_t tmp; |
|
- | 242 | ||
- | 243 | if (*requested_mode & AGP2_RESERVED_MASK) { |
|
- | 244 | dbgprintf("reserved bits set (%x) in mode 0x%x. Fixed.\n", |
|
- | 245 | *requested_mode & AGP2_RESERVED_MASK, *requested_mode); |
|
- | 246 | *requested_mode &= ~AGP2_RESERVED_MASK; |
|
- | 247 | } |
|
- | 248 | ||
- | 249 | /* Check the speed bits make sense. Only one should be set. */ |
|
- | 250 | tmp = *requested_mode & 7; |
|
- | 251 | switch (tmp) { |
|
- | 252 | case 0: |
|
- | 253 | dbgprintf("Setting to x1 mode.\n"); |
|
- | 254 | *requested_mode |= AGPSTAT2_1X; |
|
- | 255 | break; |
|
- | 256 | case 1: |
|
- | 257 | case 2: |
|
- | 258 | break; |
|
- | 259 | case 3: |
|
- | 260 | *requested_mode &= ~(AGPSTAT2_1X); /* rate=2 */ |
|
- | 261 | break; |
|
- | 262 | case 4: |
|
- | 263 | break; |
|
- | 264 | case 5: |
|
- | 265 | case 6: |
|
- | 266 | case 7: |
|
- | 267 | *requested_mode &= ~(AGPSTAT2_1X|AGPSTAT2_2X); /* rate=4*/ |
|
- | 268 | break; |
|
- | 269 | } |
|
- | 270 | ||
- | 271 | /* disable SBA if it's not supported */ |
|
- | 272 | if (!((*bridge_agpstat & AGPSTAT_SBA) && (*vga_agpstat & AGPSTAT_SBA) && (*requested_mode & AGPSTAT_SBA))) |
|
- | 273 | *bridge_agpstat &= ~AGPSTAT_SBA; |
|
- | 274 | ||
- | 275 | /* Set rate */ |
|
- | 276 | if (!((*bridge_agpstat & AGPSTAT2_4X) && (*vga_agpstat & AGPSTAT2_4X) && (*requested_mode & AGPSTAT2_4X))) |
|
- | 277 | *bridge_agpstat &= ~AGPSTAT2_4X; |
|
- | 278 | ||
- | 279 | if (!((*bridge_agpstat & AGPSTAT2_2X) && (*vga_agpstat & AGPSTAT2_2X) && (*requested_mode & AGPSTAT2_2X))) |
|
- | 280 | *bridge_agpstat &= ~AGPSTAT2_2X; |
|
- | 281 | ||
- | 282 | if (!((*bridge_agpstat & AGPSTAT2_1X) && (*vga_agpstat & AGPSTAT2_1X) && (*requested_mode & AGPSTAT2_1X))) |
|
- | 283 | *bridge_agpstat &= ~AGPSTAT2_1X; |
|
- | 284 | ||
- | 285 | /* Now we know what mode it should be, clear out the unwanted bits. */ |
|
- | 286 | if (*bridge_agpstat & AGPSTAT2_4X) |
|
- | 287 | *bridge_agpstat &= ~(AGPSTAT2_1X | AGPSTAT2_2X); /* 4X */ |
|
- | 288 | ||
- | 289 | if (*bridge_agpstat & AGPSTAT2_2X) |
|
- | 290 | *bridge_agpstat &= ~(AGPSTAT2_1X | AGPSTAT2_4X); /* 2X */ |
|
- | 291 | ||
- | 292 | if (*bridge_agpstat & AGPSTAT2_1X) |
|
- | 293 | *bridge_agpstat &= ~(AGPSTAT2_2X | AGPSTAT2_4X); /* 1X */ |
|
- | 294 | ||
- | 295 | /* Apply any errata. */ |
|
- | 296 | if (bridge->flags & AGP_ERRATA_FASTWRITES) |
|
- | 297 | *bridge_agpstat &= ~AGPSTAT_FW; |
|
- | 298 | ||
- | 299 | if (bridge->flags & AGP_ERRATA_SBA) |
|
- | 300 | *bridge_agpstat &= ~AGPSTAT_SBA; |
|
- | 301 | ||
- | 302 | if (bridge->flags & AGP_ERRATA_1X) { |
|
- | 303 | *bridge_agpstat &= ~(AGPSTAT2_2X | AGPSTAT2_4X); |
|
- | 304 | *bridge_agpstat |= AGPSTAT2_1X; |
|
- | 305 | } |
|
- | 306 | ||
- | 307 | /* If we've dropped down to 1X, disable fast writes. */ |
|
- | 308 | if (*bridge_agpstat & AGPSTAT2_1X) |
|
- | 309 | *bridge_agpstat &= ~AGPSTAT_FW; |
|
- | 310 | } |
|
- | 311 | ||
- | 312 | ||
- | 313 | static void agp_v3_parse_one(u32_t *requested_mode, |
|
- | 314 | u32_t *bridge_agpstat, |
|
- | 315 | u32_t *vga_agpstat) |
|
- | 316 | { |
|
- | 317 | u32_t origbridge = *bridge_agpstat, origvga = *vga_agpstat; |
|
- | 318 | u32_t tmp; |
|
- | 319 | ||
- | 320 | if (*requested_mode & AGP3_RESERVED_MASK) |
|
- | 321 | { |
|
- | 322 | dbgprintf("reserved bits set (%x) in mode 0x%x. Fixed.\n", |
|
- | 323 | *requested_mode & AGP3_RESERVED_MASK, *requested_mode); |
|
- | 324 | *requested_mode &= ~AGP3_RESERVED_MASK; |
|
- | 325 | } |
|
- | 326 | ||
- | 327 | /* Check the speed bits make sense. */ |
|
- | 328 | tmp = *requested_mode & 7; |
|
- | 329 | if (tmp == 0) { |
|
- | 330 | dbgprintf("Setting to AGP3 x4 mode.\n"); |
|
- | 331 | *requested_mode |= AGPSTAT3_4X; |
|
- | 332 | } |
|
- | 333 | if (tmp >= 3) { |
|
- | 334 | dbgprintf("Setting to AGP3 x8 mode.\n"); |
|
- | 335 | *requested_mode = (*requested_mode & ~7) | AGPSTAT3_8X; |
|
- | 336 | } |
|
- | 337 | ||
- | 338 | /* ARQSZ - Set the value to the maximum one. |
|
- | 339 | * Don't allow the mode register to override values. */ |
|
- | 340 | *bridge_agpstat = ((*bridge_agpstat & ~AGPSTAT_ARQSZ) | |
|
- | 341 | max_t(u32_t,(*bridge_agpstat & AGPSTAT_ARQSZ),(*vga_agpstat & AGPSTAT_ARQSZ))); |
|
- | 342 | ||
- | 343 | /* Calibration cycle. |
|
- | 344 | * Don't allow the mode register to override values. */ |
|
- | 345 | *bridge_agpstat = ((*bridge_agpstat & ~AGPSTAT_CAL_MASK) | |
|
- | 346 | min_t(u32_t,(*bridge_agpstat & AGPSTAT_CAL_MASK),(*vga_agpstat & AGPSTAT_CAL_MASK))); |
|
- | 347 | ||
- | 348 | /* SBA *must* be supported for AGP v3 */ |
|
- | 349 | *bridge_agpstat |= AGPSTAT_SBA; |
|
- | 350 | ||
- | 351 | /* |
|
- | 352 | * Set speed. |
|
- | 353 | * Check for invalid speeds. This can happen when applications |
|
- | 354 | * written before the AGP 3.0 standard pass AGP2.x modes to AGP3 hardware |
|
- | 355 | */ |
|
- | 356 | if (*requested_mode & AGPSTAT_MODE_3_0) { |
|
- | 357 | /* |
|
- | 358 | * Caller hasn't a clue what it is doing. Bridge is in 3.0 mode, |
|
- | 359 | * have been passed a 3.0 mode, but with 2.x speed bits set. |
|
- | 360 | * AGP2.x 4x -> AGP3.0 4x. |
|
- | 361 | */ |
|
- | 362 | if (*requested_mode & AGPSTAT2_4X) { |
|
- | 363 | dbgprintf("broken AGP3 flags (%x). Fixed.\n", *requested_mode); |
|
- | 364 | *requested_mode &= ~AGPSTAT2_4X; |
|
- | 365 | *requested_mode |= AGPSTAT3_4X; |
|
- | 366 | } |
|
- | 367 | } else { |
|
- | 368 | /* |
|
- | 369 | * The caller doesn't know what they are doing. We are in 3.0 mode, |
|
- | 370 | * but have been passed an AGP 2.x mode. |
|
- | 371 | * Convert AGP 1x,2x,4x -> AGP 3.0 4x. |
|
- | 372 | */ |
|
- | 373 | dbgprintf("broken AGP2 flags (%x) in AGP3 mode. Fixed.\n",*requested_mode); |
|
- | 374 | *requested_mode &= ~(AGPSTAT2_4X | AGPSTAT2_2X | AGPSTAT2_1X); |
|
- | 375 | *requested_mode |= AGPSTAT3_4X; |
|
- | 376 | } |
|
- | 377 | ||
- | 378 | if (*requested_mode & AGPSTAT3_8X) { |
|
- | 379 | if (!(*bridge_agpstat & AGPSTAT3_8X)) { |
|
- | 380 | *bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD); |
|
- | 381 | *bridge_agpstat |= AGPSTAT3_4X; |
|
- | 382 | dbgprintf("requested AGPx8 but bridge not capable.\n"); |
|
- | 383 | return; |
|
- | 384 | } |
|
- | 385 | if (!(*vga_agpstat & AGPSTAT3_8X)) { |
|
- | 386 | *bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD); |
|
- | 387 | *bridge_agpstat |= AGPSTAT3_4X; |
|
- | 388 | dbgprintf("requested AGPx8 but graphic card not capable.\n"); |
|
- | 389 | return; |
|
- | 390 | } |
|
- | 391 | /* All set, bridge & device can do AGP x8*/ |
|
- | 392 | *bridge_agpstat &= ~(AGPSTAT3_4X | AGPSTAT3_RSVD); |
|
- | 393 | goto done; |
|
- | 394 | ||
- | 395 | } else { |
|
- | 396 | ||
- | 397 | /* |
|
- | 398 | * If we didn't specify AGPx8, we can only do x4. |
|
- | 399 | * If the hardware can't do x4, we're up shit creek, and never |
|
- | 400 | * should have got this far. |
|
- | 401 | */ |
|
- | 402 | *bridge_agpstat &= ~(AGPSTAT3_8X | AGPSTAT3_RSVD); |
|
- | 403 | if ((*bridge_agpstat & AGPSTAT3_4X) && (*vga_agpstat & AGPSTAT3_4X)) |
|
- | 404 | *bridge_agpstat |= AGPSTAT3_4X; |
|
- | 405 | else { |
|
- | 406 | dbgprintf("Badness. Don't know which AGP mode to set. " |
|
- | 407 | "[bridge_agpstat:%x vga_agpstat:%x fell back to:- bridge_agpstat:%x vga_agpstat:%x]\n", |
|
- | 408 | origbridge, origvga, *bridge_agpstat, *vga_agpstat); |
|
- | 409 | if (!(*bridge_agpstat & AGPSTAT3_4X)) |
|
- | 410 | dbgprintf("Bridge couldn't do AGP x4.\n"); |
|
- | 411 | if (!(*vga_agpstat & AGPSTAT3_4X)) |
|
- | 412 | dbgprintf("Graphic card couldn't do AGP x4.\n"); |
|
- | 413 | return; |
|
- | 414 | } |
|
- | 415 | } |
|
- | 416 | ||
- | 417 | done: |
|
- | 418 | /* Apply any errata. */ |
|
- | 419 | if (bridge->flags & AGP_ERRATA_FASTWRITES) |
|
- | 420 | *bridge_agpstat &= ~AGPSTAT_FW; |
|
- | 421 | ||
- | 422 | if (bridge->flags & AGP_ERRATA_SBA) |
|
- | 423 | *bridge_agpstat &= ~AGPSTAT_SBA; |
|
- | 424 | ||
- | 425 | if (bridge->flags & AGP_ERRATA_1X) { |
|
- | 426 | *bridge_agpstat &= ~(AGPSTAT2_2X | AGPSTAT2_4X); |
|
- | 427 | *bridge_agpstat |= AGPSTAT2_1X; |
|
- | 428 | } |
|
- | 429 | } |
|
- | 430 | ||
- | 431 | ||
- | 432 | u32_t agp_collect_device_status(agp_t *bridge, u32_t requested_mode, |
|
- | 433 | u32_t bridge_agpstat) |
|
- | 434 | { |
|
- | 435 | PCITAG vgaTag; |
|
- | 436 | u32_t vga_agpstat; |
|
- | 437 | int cap_ptr; |
|
- | 438 | ||
- | 439 | for (;;) |
|
- | 440 | { |
|
- | 441 | vgaTag = pci_find_class(PCI_CLASS_DISPLAY_VGA); |
|
- | 442 | if (vgaTag == -1) |
|
- | 443 | { |
|
- | 444 | dbgprintf("Couldn't find an AGP VGA controller.\n"); |
|
- | 445 | return 0; |
|
- | 446 | } |
|
- | 447 | cap_ptr = pci_find_capability(vgaTag, PCI_CAP_ID_AGP); |
|
- | 448 | if (cap_ptr) |
|
- | 449 | break; |
|
- | 450 | } |
|
- | 451 | ||
- | 452 | /* |
|
- | 453 | * Ok, here we have a AGP device. Disable impossible |
|
- | 454 | * settings, and adjust the readqueue to the minimum. |
|
- | 455 | */ |
|
- | 456 | vga_agpstat = pciReadLong(vgaTag, cap_ptr+PCI_AGP_STATUS); |
|
- | 457 | ||
- | 458 | /* adjust RQ depth */ |
|
- | 459 | bridge_agpstat = ((bridge_agpstat & ~AGPSTAT_RQ_DEPTH) | |
|
- | 460 | min_t(u32_t, (requested_mode & AGPSTAT_RQ_DEPTH), |
|
- | 461 | min_t(u32_t, (bridge_agpstat & AGPSTAT_RQ_DEPTH), (vga_agpstat & AGPSTAT_RQ_DEPTH)))); |
|
- | 462 | ||
- | 463 | /* disable FW if it's not supported */ |
|
- | 464 | if (!((bridge_agpstat & AGPSTAT_FW) && |
|
- | 465 | (vga_agpstat & AGPSTAT_FW) && |
|
- | 466 | (requested_mode & AGPSTAT_FW))) |
|
- | 467 | bridge_agpstat &= ~AGPSTAT_FW; |
|
- | 468 | ||
- | 469 | /* Check to see if we are operating in 3.0 mode */ |
|
- | 470 | if (bridge->mode & AGPSTAT_MODE_3_0) |
|
- | 471 | agp_v3_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat); |
|
- | 472 | else |
|
- | 473 | agp_v2_parse_one(&requested_mode, &bridge_agpstat, &vga_agpstat); |
|
- | 474 | ||
- | 475 | return bridge_agpstat; |
|
- | 476 | } |
|
- | 477 | ||
- | 478 | ||
- | 479 | void agp_device_command(u32_t bridge_agpstat, int agp_v3) |
|
- | 480 | { |
|
- | 481 | PCITAG device = 0; |
|
- | 482 | int mode; |
|
- | 483 | ||
- | 484 | mode = bridge_agpstat & 0x7; |
|
- | 485 | if (agp_v3) |
|
- | 486 | mode *= 4; |
|
- | 487 | ||
- | 488 | for_each_pci_dev(device) |
|
- | 489 | { |
|
- | 490 | int agp = pci_find_capability(device, PCI_CAP_ID_AGP); |
|
- | 491 | if (!agp) |
|
- | 492 | continue; |
|
- | 493 | ||
- | 494 | dbgprintf("Putting AGP V%d device at into %dx mode\n", |
|
- | 495 | agp_v3 ? 3 : 2, mode); |
|
- | 496 | pciWriteLong(device, agp + PCI_AGP_COMMAND, bridge_agpstat); |
|
- | 497 | } |
|
- | 498 | } |
|
- | 499 | ||
- | 500 | ||
- | 501 | struct agp_3_5_dev |
|
- | 502 | { |
|
- | 503 | link_t link; |
|
- | 504 | int capndx; |
|
- | 505 | u32_t maxbw; |
|
- | 506 | PCITAG tag; |
|
- | 507 | }; |
|
- | 508 | ||
- | 509 | ||
- | 510 | /* |
|
- | 511 | * Fully configure and enable an AGP 3.0 host bridge and all the devices |
|
- | 512 | * lying behind it. |
|
- | 513 | */ |
|
- | 514 | int agp_3_5_enable(agp_t *bridge) |
|
- | 515 | { |
|
- | 516 | u8_t mcapndx; |
|
- | 517 | u32_t isoch, arqsz; |
|
- | 518 | u32_t tstatus, mstatus, ncapid; |
|
- | 519 | u32_t mmajor; |
|
- | 520 | u16_t mpstat; |
|
- | 521 | ||
- | 522 | link_t dev_list; |
|
- | 523 | ||
- | 524 | struct agp_3_5_dev *cur, *pos; |
|
- | 525 | ||
- | 526 | unsigned int ndevs = 0; |
|
- | 527 | PCITAG dev = 0; |
|
- | 528 | int ret = 0; |
|
- | 529 | ||
- | 530 | /* Extract some power-on defaults from the target */ |
|
- | 531 | tstatus = pciReadLong(bridge->PciTag, bridge->capndx+AGPSTAT); |
|
- | 532 | isoch = (tstatus >> 17) & 0x1; |
|
- | 533 | if (isoch == 0) /* isoch xfers not available, bail out. */ |
|
- | 534 | return -1; |
|
- | 535 | ||
- | 536 | arqsz = (tstatus >> 13) & 0x7; |
|
- | 537 | ||
- | 538 | list_initialize(&dev_list); |
|
- | 539 | ||
- | 540 | /* Find all AGP devices, and add them to dev_list. */ |
|
- | 541 | for_each_pci_dev(dev) |
|
- | 542 | { |
|
- | 543 | u16_t devclass; |
|
- | 544 | ||
- | 545 | mcapndx = pci_find_capability(dev, PCI_CAP_ID_AGP); |
|
- | 546 | if (mcapndx == 0) |
|
- | 547 | continue; |
|
- | 548 | ||
- | 549 | devclass = pciReadWord(dev, 0x0A); |
|
- | 550 | ||
- | 551 | switch (devclass & 0xff00) |
|
- | 552 | { |
|
- | 553 | case 0x0600: /* Bridge */ |
|
- | 554 | /* Skip bridges. We should call this function for each one. */ |
|
- | 555 | continue; |
|
- | 556 | ||
- | 557 | case 0x0001: /* Unclassified device */ |
|
- | 558 | /* Don't know what this is, but log it for investigation. */ |
|
- | 559 | if (mcapndx != 0) { |
|
- | 560 | dbgprintf("Wacky, found unclassified AGP device.\n"); |
|
- | 561 | } |
|
- | 562 | continue; |
|
- | 563 | ||
- | 564 | case 0x0300: /* Display controller */ |
|
- | 565 | case 0x0400: /* Multimedia controller */ |
|
- | 566 | if((cur = malloc(sizeof(*cur))) == NULL) |
|
- | 567 | { |
|
- | 568 | ret = -1; |
|
- | 569 | goto free_and_exit; |
|
- | 570 | } |
|
- | 571 | cur->tag = dev; |
|
- | 572 | list_prepend(&cur->link, &dev_list); |
|
- | 573 | ndevs++; |
|
- | 574 | continue; |
|
- | 575 | ||
- | 576 | default: |
|
- | 577 | continue; |
|
- | 578 | } |
|
- | 579 | } |
|
- | 580 | ||
- | 581 | /* |
|
- | 582 | * Take an initial pass through the devices lying behind our host |
|
- | 583 | * bridge. Make sure each one is actually an AGP 3.0 device, otherwise |
|
- | 584 | * exit with an error message. Along the way store the AGP 3.0 |
|
- | 585 | * cap_ptr for each device |
|
- | 586 | */ |
|
- | 587 | ||
- | 588 | cur = (struct agp_3_5_dev*)dev_list.next; |
|
- | 589 | ||
- | 590 | while(&cur->link != &dev_list) |
|
- | 591 | { |
|
- | 592 | dev = cur->tag; |
|
- | 593 | ||
- | 594 | mpstat = pciReadWord(dev, PCI_STATUS); |
|
- | 595 | if ((mpstat & PCI_STATUS_CAP_LIST) == 0) |
|
- | 596 | continue; |
|
- | 597 | ||
- | 598 | mcapndx = pciReadByte(dev, PCI_CAPABILITY_LIST); |
|
- | 599 | if (mcapndx != 0) { |
|
- | 600 | do { |
|
- | 601 | ncapid = pciReadLong(dev, mcapndx); |
|
- | 602 | if ((ncapid & 0xff) != 2) |
|
- | 603 | mcapndx = (ncapid >> 8) & 0xff; |
|
- | 604 | } |
|
- | 605 | while (((ncapid & 0xff) != 2) && (mcapndx != 0)); |
|
- | 606 | } |
|
- | 607 | ||
- | 608 | if (mcapndx == 0) { |
|
- | 609 | dbgprintf("woah! Non-AGP device " |
|
- | 610 | "found on the secondary bus of an AGP 3.5 bridge!\n"); |
|
- | 611 | ret = -1; |
|
- | 612 | goto free_and_exit; |
|
- | 613 | } |
|
- | 614 | ||
- | 615 | mmajor = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf; |
|
- | 616 | if (mmajor < 3) { |
|
- | 617 | dbgprintf("woah! AGP 2.0 device " |
|
- | 618 | "found on the secondary bus of an AGP 3.5 " |
|
- | 619 | "bridge operating with AGP 3.0 electricals!\n"); |
|
- | 620 | ret = -1; |
|
- | 621 | goto free_and_exit; |
|
- | 622 | } |
|
- | 623 | ||
- | 624 | cur->capndx = mcapndx; |
|
- | 625 | ||
- | 626 | mstatus = pciReadLong(dev, cur->capndx+AGPSTAT); |
|
- | 627 | ||
- | 628 | if (((mstatus >> 3) & 0x1) == 0) { |
|
- | 629 | dbgprintf("woah! AGP 3.x device " |
|
- | 630 | "not operating in AGP 3.x mode found on the " |
|
- | 631 | "secondary bus of an AGP 3.5 bridge operating " |
|
- | 632 | "with AGP 3.0 electricals!\n"); |
|
- | 633 | ret = -1; |
|
- | 634 | goto free_and_exit; |
|
- | 635 | } |
|
- | 636 | cur = (struct agp_3_5_dev*)cur->link.next; |
|
- | 637 | } |
|
- | 638 | ||
- | 639 | /* |
|
- | 640 | * Call functions to divide target resources amongst the AGP 3.0 |
|
- | 641 | * masters. This process is dramatically different depending on |
|
- | 642 | * whether isochronous transfers are supported. |
|
- | 643 | */ |
|
- | 644 | if (isoch) { |
|
- | 645 | ret = agp_3_5_isochronous_node_enable(bridge, &dev_list, ndevs); |
|
- | 646 | if (ret) { |
|
- | 647 | dbgprintf("Something bad happened setting " |
|
- | 648 | "up isochronous xfers. Falling back to " |
|
- | 649 | "non-isochronous xfer mode.\n"); |
|
- | 650 | } else { |
|
- | 651 | goto free_and_exit; |
|
- | 652 | } |
|
- | 653 | } |
|
- | 654 | agp_3_5_nonisochronous_node_enable(bridge, dev_list, ndevs); |
|
- | 655 | ||
- | 656 | free_and_exit: |
|
- | 657 | /* Be sure to free the dev_list */ |
|
- | 658 | for (pos = (struct agp_3_5_dev*)dev_list.next; &pos->link != &dev_list; ) |
|
- | 659 | { |
|
- | 660 | cur = pos; |
|
- | 661 | ||
- | 662 | pos = (struct agp_3_5_dev*)pos->link.next; |
|
- | 663 | free(cur); |
|
- | 664 | } |
|
- | 665 | ||
- | 666 | get_out: |
|
- | 667 | return ret; |
|
- | 668 | } |
|
- | 669 | ||
- | 670 | ||
- | 671 | void agp_generic_enable(u32_t requested_mode) |
|
- | 672 | { |
|
- | 673 | u32_t bridge_agpstat, temp; |
|
- | 674 | ||
- | 675 | get_agp_version(bridge); |
|
- | 676 | ||
- | 677 | dbgprintf("Found an AGP %d.%d compliant device.\n", |
|
- | 678 | bridge->major_version, bridge->minor_version); |
|
- | 679 | ||
- | 680 | bridge_agpstat = pciReadLong(bridge->PciTag, |
|
- | 681 | bridge->capndx + PCI_AGP_STATUS); |
|
- | 682 | ||
- | 683 | bridge_agpstat = agp_collect_device_status(bridge, requested_mode, bridge_agpstat); |
|
- | 684 | if (bridge_agpstat == 0) |
|
- | 685 | /* Something bad happened. FIXME: Return error code? */ |
|
- | 686 | return; |
|
- | 687 | ||
- | 688 | bridge_agpstat |= AGPSTAT_AGP_ENABLE; |
|
- | 689 | ||
- | 690 | /* Do AGP version specific frobbing. */ |
|
- | 691 | if (bridge->major_version >= 3) |
|
- | 692 | { |
|
- | 693 | if (bridge->mode & AGPSTAT_MODE_3_0) |
|
- | 694 | { |
|
- | 695 | /* If we have 3.5, we can do the isoch stuff. */ |
|
- | 696 | if (bridge->minor_version >= 5) |
|
- | 697 | agp_3_5_enable(bridge); |
|
- | 698 | agp_device_command(bridge_agpstat, TRUE); |
|
- | 699 | return; |
|
- | 700 | } |
|
- | 701 | else |
|
- | 702 | { |
|
- | 703 | /* Disable calibration cycle in RX91<1> when not in AGP3.0 mode of operation.*/ |
|
- | 704 | bridge_agpstat &= ~(7<<10) ; |
|
- | 705 | temp = pciReadLong(bridge->PciTag, bridge->capndx+AGPCTRL); |
|
- | 706 | temp |= (1<<9); |
|
- | 707 | pciWriteLong(bridge->PciTag, bridge->capndx+AGPCTRL, temp); |
|
- | 708 | ||
- | 709 | dbgprintf("Device is in legacy mode," |
|
- | 710 | " falling back to 2.x\n"); |
|
Line 285... | Line 711... | ||
285 | // return ret_val; |
711 | } |
286 | 712 | } |
|
287 | // curr->is_bound = TRUE; |
713 | |
288 | // curr->pg_start = pg_start; |
714 | /* AGP v<3 */ |
289 | return 0; |
715 | agp_device_command(bridge_agpstat, FALSE); |
290 | } |
716 | } |
291 | 717 | ||
292 | 718 | ||
293 | static agp_t intel_845_driver = |
719 | static agp_t intel_845_driver = |
294 | { |
720 | { |
295 | // .aperture_sizes = intel_8xx_sizes, |
721 | .aperture_sizes = intel_8xx_sizes, |
296 | // .size_type = U8_APER_SIZE, |
722 | // .size_type = U8_APER_SIZE, |
297 | // .num_aperture_sizes = 7, |
723 | // .num_aperture_sizes = 7, |
298 | .configure = intel_845_configure, |
724 | .configure = intel_845_configure, |
299 | .fetch_size = intel_8xx_fetch_size, |
725 | .fetch_size = intel_8xx_fetch_size, |
300 | // .cleanup = intel_8xx_cleanup, |
726 | // .cleanup = intel_8xx_cleanup, |
301 | .tlb_flush = intel_8xx_tlbflush, |
727 | .tlb_flush = intel_8xx_tlbflush, |
302 | // .mask_memory = agp_generic_mask_memory, |
728 | // .mask_memory = agp_generic_mask_memory, |
303 | // .masks = intel_generic_masks, |
729 | // .masks = intel_generic_masks, |
304 | // .agp_enable = agp_generic_enable, |
730 | // .agp_enable = agp_generic_enable, |
305 | // .cache_flush = global_cache_flush, |
731 | // .cache_flush = global_cache_flush, |
306 | // .create_gatt_table = agp_generic_create_gatt_table, |
732 | .create_gatt_table = agp_generic_create_gatt_table, |
Line -... | Line 733... | ||
- | 733 | // .free_gatt_table = agp_generic_free_gatt_table, |
|
- | 734 | // .insert_memory = agp_generic_insert_memory, |
|
- | 735 | // .remove_memory = agp_generic_remove_memory, |
|
- | 736 | // .alloc_by_type = agp_generic_alloc_by_type, |
|
- | 737 | // .free_by_type = agp_generic_free_by_type, |
|
- | 738 | // .agp_alloc_page = agp_generic_alloc_page, |
|
- | 739 | // .agp_destroy_page = agp_generic_destroy_page, |
|
- | 740 | }; |
|
- | 741 | ||
- | 742 | int init_bridge(PCITAG pciTag) |
|
- | 743 | { |
|
- | 744 | size_t size_value; |
|
- | 745 | ||
- | 746 | bridge = &intel_845_driver; |
|
- | 747 | ||
- | 748 | bridge->PciTag = pciTag; |
|
- | 749 | ||
- | 750 | bridge->capndx = pci_find_capability(pciTag, PCI_CAP_ID_AGP); |
|
- | 751 | ||
- | 752 | size_value = bridge->fetch_size(); |
|
- | 753 | ||
- | 754 | if (size_value == 0) { |
|
- | 755 | dbgprintf("unable to determine aperture size.\n"); |
|
- | 756 | return 0; |
|
- | 757 | }; |
|
- | 758 | ||
- | 759 | dbgprintf("fetch size = %x\n", size_value); |
|
Line 307... | Line 760... | ||
307 | // .free_gatt_table = agp_generic_free_gatt_table, |
760 |