GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / char / agp / ali-agp.c
blob048f46861ed7e10beb64cbd6a3c0e128b27371f1
1 /*
2 * ALi AGPGART routines.
3 */
5 #include <linux/types.h>
6 #include <linux/module.h>
7 #include <linux/pci.h>
8 #include <linux/init.h>
9 #include <linux/agp_backend.h>
10 #include <asm/page.h> /* PAGE_SIZE */
11 #include "agp.h"
13 #define ALI_AGPCTRL 0xb8
14 #define ALI_ATTBASE 0xbc
15 #define ALI_TLBCTRL 0xc0
16 #define ALI_TAGCTRL 0xc4
17 #define ALI_CACHE_FLUSH_CTRL 0xD0
18 #define ALI_CACHE_FLUSH_ADDR_MASK 0xFFFFF000
19 #define ALI_CACHE_FLUSH_EN 0x100
21 static int ali_fetch_size(void)
23 int i;
24 u32 temp;
25 struct aper_size_info_32 *values;
27 pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp);
28 temp &= ~(0xfffffff0);
29 values = A_SIZE_32(agp_bridge->driver->aperture_sizes);
31 for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
32 if (temp == values[i].size_value) {
33 agp_bridge->previous_size =
34 agp_bridge->current_size = (void *) (values + i);
35 agp_bridge->aperture_size_idx = i;
36 return values[i].size;
40 return 0;
43 static void ali_tlbflush(struct agp_memory *mem)
45 u32 temp;
47 pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp);
48 temp &= 0xfffffff0;
49 temp |= (1<<0 | 1<<1);
50 pci_write_config_dword(agp_bridge->dev, ALI_TAGCTRL, temp);
53 static void ali_cleanup(void)
55 struct aper_size_info_32 *previous_size;
56 u32 temp;
58 previous_size = A_SIZE_32(agp_bridge->previous_size);
60 pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp);
61 // clear tag
62 pci_write_config_dword(agp_bridge->dev, ALI_TAGCTRL,
63 ((temp & 0xffffff00) | 0x00000001|0x00000002));
65 pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp);
66 pci_write_config_dword(agp_bridge->dev, ALI_ATTBASE,
67 ((temp & 0x00000ff0) | previous_size->size_value));
70 static int ali_configure(void)
72 u32 temp;
73 struct aper_size_info_32 *current_size;
75 current_size = A_SIZE_32(agp_bridge->current_size);
77 /* aperture size and gatt addr */
78 pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp);
79 temp = (((temp & 0x00000ff0) | (agp_bridge->gatt_bus_addr & 0xfffff000))
80 | (current_size->size_value & 0xf));
81 pci_write_config_dword(agp_bridge->dev, ALI_ATTBASE, temp);
83 /* tlb control */
84 pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp);
85 pci_write_config_dword(agp_bridge->dev, ALI_TLBCTRL, ((temp & 0xffffff00) | 0x00000010));
87 /* address to map to */
88 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
89 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
92 pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp);
93 temp &= 0xffffff7f; //enable TLB
94 pci_write_config_dword(agp_bridge->dev, ALI_TLBCTRL, temp);
96 return 0;
100 static void m1541_cache_flush(void)
102 int i, page_count;
103 u32 temp;
105 global_cache_flush();
107 page_count = 1 << A_SIZE_32(agp_bridge->current_size)->page_order;
108 for (i = 0; i < PAGE_SIZE * page_count; i += PAGE_SIZE) {
109 pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
110 &temp);
111 pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
112 (((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
113 (agp_bridge->gatt_bus_addr + i)) |
114 ALI_CACHE_FLUSH_EN));
118 static struct page *m1541_alloc_page(struct agp_bridge_data *bridge)
120 struct page *page = agp_generic_alloc_page(agp_bridge);
121 u32 temp;
123 if (!page)
124 return NULL;
126 pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
127 pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
128 (((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
129 page_to_phys(page)) | ALI_CACHE_FLUSH_EN ));
130 return page;
133 static void ali_destroy_page(struct page *page, int flags)
135 if (page) {
136 if (flags & AGP_PAGE_DESTROY_UNMAP) {
137 global_cache_flush(); /* is this really needed? --hch */
138 agp_generic_destroy_page(page, flags);
139 } else
140 agp_generic_destroy_page(page, flags);
144 static void m1541_destroy_page(struct page *page, int flags)
146 u32 temp;
148 if (page == NULL)
149 return;
151 if (flags & AGP_PAGE_DESTROY_UNMAP) {
152 global_cache_flush();
154 pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
155 pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
156 (((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
157 page_to_phys(page)) | ALI_CACHE_FLUSH_EN));
159 agp_generic_destroy_page(page, flags);
163 /* Setup function */
165 static const struct aper_size_info_32 ali_generic_sizes[7] =
167 {256, 65536, 6, 10},
168 {128, 32768, 5, 9},
169 {64, 16384, 4, 8},
170 {32, 8192, 3, 7},
171 {16, 4096, 2, 6},
172 {8, 2048, 1, 4},
173 {4, 1024, 0, 3}
176 static const struct agp_bridge_driver ali_generic_bridge = {
177 .owner = THIS_MODULE,
178 .aperture_sizes = ali_generic_sizes,
179 .size_type = U32_APER_SIZE,
180 .num_aperture_sizes = 7,
181 .needs_scratch_page = true,
182 .configure = ali_configure,
183 .fetch_size = ali_fetch_size,
184 .cleanup = ali_cleanup,
185 .tlb_flush = ali_tlbflush,
186 .mask_memory = agp_generic_mask_memory,
187 .masks = NULL,
188 .agp_enable = agp_generic_enable,
189 .cache_flush = global_cache_flush,
190 .create_gatt_table = agp_generic_create_gatt_table,
191 .free_gatt_table = agp_generic_free_gatt_table,
192 .insert_memory = agp_generic_insert_memory,
193 .remove_memory = agp_generic_remove_memory,
194 .alloc_by_type = agp_generic_alloc_by_type,
195 .free_by_type = agp_generic_free_by_type,
196 .agp_alloc_page = agp_generic_alloc_page,
197 .agp_destroy_page = ali_destroy_page,
198 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
201 static const struct agp_bridge_driver ali_m1541_bridge = {
202 .owner = THIS_MODULE,
203 .aperture_sizes = ali_generic_sizes,
204 .size_type = U32_APER_SIZE,
205 .num_aperture_sizes = 7,
206 .configure = ali_configure,
207 .fetch_size = ali_fetch_size,
208 .cleanup = ali_cleanup,
209 .tlb_flush = ali_tlbflush,
210 .mask_memory = agp_generic_mask_memory,
211 .masks = NULL,
212 .agp_enable = agp_generic_enable,
213 .cache_flush = m1541_cache_flush,
214 .create_gatt_table = agp_generic_create_gatt_table,
215 .free_gatt_table = agp_generic_free_gatt_table,
216 .insert_memory = agp_generic_insert_memory,
217 .remove_memory = agp_generic_remove_memory,
218 .alloc_by_type = agp_generic_alloc_by_type,
219 .free_by_type = agp_generic_free_by_type,
220 .agp_alloc_page = m1541_alloc_page,
221 .agp_destroy_page = m1541_destroy_page,
222 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
226 static struct agp_device_ids ali_agp_device_ids[] __devinitdata =
229 .device_id = PCI_DEVICE_ID_AL_M1541,
230 .chipset_name = "M1541",
233 .device_id = PCI_DEVICE_ID_AL_M1621,
234 .chipset_name = "M1621",
237 .device_id = PCI_DEVICE_ID_AL_M1631,
238 .chipset_name = "M1631",
241 .device_id = PCI_DEVICE_ID_AL_M1632,
242 .chipset_name = "M1632",
245 .device_id = PCI_DEVICE_ID_AL_M1641,
246 .chipset_name = "M1641",
249 .device_id = PCI_DEVICE_ID_AL_M1644,
250 .chipset_name = "M1644",
253 .device_id = PCI_DEVICE_ID_AL_M1647,
254 .chipset_name = "M1647",
257 .device_id = PCI_DEVICE_ID_AL_M1651,
258 .chipset_name = "M1651",
261 .device_id = PCI_DEVICE_ID_AL_M1671,
262 .chipset_name = "M1671",
265 .device_id = PCI_DEVICE_ID_AL_M1681,
266 .chipset_name = "M1681",
269 .device_id = PCI_DEVICE_ID_AL_M1683,
270 .chipset_name = "M1683",
273 { }, /* dummy final entry, always present */
276 static int __devinit agp_ali_probe(struct pci_dev *pdev,
277 const struct pci_device_id *ent)
279 struct agp_device_ids *devs = ali_agp_device_ids;
280 struct agp_bridge_data *bridge;
281 u8 hidden_1621_id, cap_ptr;
282 int j;
284 cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
285 if (!cap_ptr)
286 return -ENODEV;
288 /* probe for known chipsets */
289 for (j = 0; devs[j].chipset_name; j++) {
290 if (pdev->device == devs[j].device_id)
291 goto found;
294 dev_err(&pdev->dev, "unsupported ALi chipset [%04x/%04x])\n",
295 pdev->vendor, pdev->device);
296 return -ENODEV;
299 found:
300 bridge = agp_alloc_bridge();
301 if (!bridge)
302 return -ENOMEM;
304 bridge->dev = pdev;
305 bridge->capndx = cap_ptr;
307 switch (pdev->device) {
308 case PCI_DEVICE_ID_AL_M1541:
309 bridge->driver = &ali_m1541_bridge;
310 break;
311 case PCI_DEVICE_ID_AL_M1621:
312 pci_read_config_byte(pdev, 0xFB, &hidden_1621_id);
313 switch (hidden_1621_id) {
314 case 0x31:
315 devs[j].chipset_name = "M1631";
316 break;
317 case 0x32:
318 devs[j].chipset_name = "M1632";
319 break;
320 case 0x41:
321 devs[j].chipset_name = "M1641";
322 break;
323 case 0x43:
324 devs[j].chipset_name = "M1621";
325 break;
326 case 0x47:
327 devs[j].chipset_name = "M1647";
328 break;
329 case 0x51:
330 devs[j].chipset_name = "M1651";
331 break;
332 default:
333 break;
335 /*FALLTHROUGH*/
336 default:
337 bridge->driver = &ali_generic_bridge;
340 dev_info(&pdev->dev, "ALi %s chipset\n", devs[j].chipset_name);
342 /* Fill in the mode register */
343 pci_read_config_dword(pdev,
344 bridge->capndx+PCI_AGP_STATUS,
345 &bridge->mode);
347 pci_set_drvdata(pdev, bridge);
348 return agp_add_bridge(bridge);
351 static void __devexit agp_ali_remove(struct pci_dev *pdev)
353 struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
355 agp_remove_bridge(bridge);
356 agp_put_bridge(bridge);
359 static struct pci_device_id agp_ali_pci_table[] = {
361 .class = (PCI_CLASS_BRIDGE_HOST << 8),
362 .class_mask = ~0,
363 .vendor = PCI_VENDOR_ID_AL,
364 .device = PCI_ANY_ID,
365 .subvendor = PCI_ANY_ID,
366 .subdevice = PCI_ANY_ID,
371 MODULE_DEVICE_TABLE(pci, agp_ali_pci_table);
373 static struct pci_driver agp_ali_pci_driver = {
374 .name = "agpgart-ali",
375 .id_table = agp_ali_pci_table,
376 .probe = agp_ali_probe,
377 .remove = agp_ali_remove,
380 static int __init agp_ali_init(void)
382 if (agp_off)
383 return -EINVAL;
384 return pci_register_driver(&agp_ali_pci_driver);
387 static void __exit agp_ali_cleanup(void)
389 pci_unregister_driver(&agp_ali_pci_driver);
392 module_init(agp_ali_init);
393 module_exit(agp_ali_cleanup);
395 MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
396 MODULE_LICENSE("GPL and additional rights");