Merge branch 'for-2.6.25' of master.kernel.org:/pub/scm/linux/kernel/git/jwboyer...
[sfrench/cifs-2.6.git] / drivers / char / agp / amd-k7-agp.c
1 /*
2  * AMD K7 AGPGART routines.
3  */
4
5 #include <linux/module.h>
6 #include <linux/pci.h>
7 #include <linux/init.h>
8 #include <linux/agp_backend.h>
9 #include <linux/gfp.h>
10 #include <linux/page-flags.h>
11 #include <linux/mm.h>
12 #include "agp.h"
13
14 #define AMD_MMBASE      0x14
15 #define AMD_APSIZE      0xac
16 #define AMD_MODECNTL    0xb0
17 #define AMD_MODECNTL2   0xb2
18 #define AMD_GARTENABLE  0x02    /* In mmio region (16-bit register) */
19 #define AMD_ATTBASE     0x04    /* In mmio region (32-bit register) */
20 #define AMD_TLBFLUSH    0x0c    /* In mmio region (32-bit register) */
21 #define AMD_CACHEENTRY  0x10    /* In mmio region (32-bit register) */
22
23 static struct pci_device_id agp_amdk7_pci_table[];
24
25 struct amd_page_map {
26         unsigned long *real;
27         unsigned long __iomem *remapped;
28 };
29
30 static struct _amd_irongate_private {
31         volatile u8 __iomem *registers;
32         struct amd_page_map **gatt_pages;
33         int num_tables;
34 } amd_irongate_private;
35
36 static int amd_create_page_map(struct amd_page_map *page_map)
37 {
38         int i;
39
40         page_map->real = (unsigned long *) __get_free_page(GFP_KERNEL);
41         if (page_map->real == NULL)
42                 return -ENOMEM;
43
44 #ifndef CONFIG_X86
45         SetPageReserved(virt_to_page(page_map->real));
46         global_cache_flush();
47         page_map->remapped = ioremap_nocache(virt_to_gart(page_map->real),
48                                             PAGE_SIZE);
49         if (page_map->remapped == NULL) {
50                 ClearPageReserved(virt_to_page(page_map->real));
51                 free_page((unsigned long) page_map->real);
52                 page_map->real = NULL;
53                 return -ENOMEM;
54         }
55         global_cache_flush();
56 #else
57         set_memory_uc((unsigned long)page_map->real, 1);
58         page_map->remapped = page_map->real;
59 #endif
60
61         for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++) {
62                 writel(agp_bridge->scratch_page, page_map->remapped+i);
63                 readl(page_map->remapped+i);    /* PCI Posting. */
64         }
65
66         return 0;
67 }
68
69 static void amd_free_page_map(struct amd_page_map *page_map)
70 {
71 #ifndef CONFIG_X86
72         iounmap(page_map->remapped);
73         ClearPageReserved(virt_to_page(page_map->real));
74 #else
75         set_memory_wb((unsigned long)page_map->real, 1);
76 #endif
77         free_page((unsigned long) page_map->real);
78 }
79
80 static void amd_free_gatt_pages(void)
81 {
82         int i;
83         struct amd_page_map **tables;
84         struct amd_page_map *entry;
85
86         tables = amd_irongate_private.gatt_pages;
87         for (i = 0; i < amd_irongate_private.num_tables; i++) {
88                 entry = tables[i];
89                 if (entry != NULL) {
90                         if (entry->real != NULL)
91                                 amd_free_page_map(entry);
92                         kfree(entry);
93                 }
94         }
95         kfree(tables);
96         amd_irongate_private.gatt_pages = NULL;
97 }
98
99 static int amd_create_gatt_pages(int nr_tables)
100 {
101         struct amd_page_map **tables;
102         struct amd_page_map *entry;
103         int retval = 0;
104         int i;
105
106         tables = kzalloc((nr_tables + 1) * sizeof(struct amd_page_map *),GFP_KERNEL);
107         if (tables == NULL)
108                 return -ENOMEM;
109
110         for (i = 0; i < nr_tables; i++) {
111                 entry = kzalloc(sizeof(struct amd_page_map), GFP_KERNEL);
112                 tables[i] = entry;
113                 if (entry == NULL) {
114                         retval = -ENOMEM;
115                         break;
116                 }
117                 retval = amd_create_page_map(entry);
118                 if (retval != 0)
119                         break;
120         }
121         amd_irongate_private.num_tables = i;
122         amd_irongate_private.gatt_pages = tables;
123
124         if (retval != 0)
125                 amd_free_gatt_pages();
126
127         return retval;
128 }
129
130 /* Since we don't need contiguous memory we just try
131  * to get the gatt table once
132  */
133
134 #define GET_PAGE_DIR_OFF(addr) (addr >> 22)
135 #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \
136         GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr))
137 #define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12)
138 #define GET_GATT(addr) (amd_irongate_private.gatt_pages[\
139         GET_PAGE_DIR_IDX(addr)]->remapped)
140
141 static int amd_create_gatt_table(struct agp_bridge_data *bridge)
142 {
143         struct aper_size_info_lvl2 *value;
144         struct amd_page_map page_dir;
145         unsigned long addr;
146         int retval;
147         u32 temp;
148         int i;
149
150         value = A_SIZE_LVL2(agp_bridge->current_size);
151         retval = amd_create_page_map(&page_dir);
152         if (retval != 0)
153                 return retval;
154
155         retval = amd_create_gatt_pages(value->num_entries / 1024);
156         if (retval != 0) {
157                 amd_free_page_map(&page_dir);
158                 return retval;
159         }
160
161         agp_bridge->gatt_table_real = (u32 *)page_dir.real;
162         agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped;
163         agp_bridge->gatt_bus_addr = virt_to_gart(page_dir.real);
164
165         /* Get the address for the gart region.
166          * This is a bus address even on the alpha, b/c its
167          * used to program the agp master not the cpu
168          */
169
170         pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
171         addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
172         agp_bridge->gart_bus_addr = addr;
173
174         /* Calculate the agp offset */
175         for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
176                 writel(virt_to_gart(amd_irongate_private.gatt_pages[i]->real) | 1,
177                         page_dir.remapped+GET_PAGE_DIR_OFF(addr));
178                 readl(page_dir.remapped+GET_PAGE_DIR_OFF(addr));        /* PCI Posting. */
179         }
180
181         return 0;
182 }
183
184 static int amd_free_gatt_table(struct agp_bridge_data *bridge)
185 {
186         struct amd_page_map page_dir;
187
188         page_dir.real = (unsigned long *)agp_bridge->gatt_table_real;
189         page_dir.remapped = (unsigned long __iomem *)agp_bridge->gatt_table;
190
191         amd_free_gatt_pages();
192         amd_free_page_map(&page_dir);
193         return 0;
194 }
195
196 static int amd_irongate_fetch_size(void)
197 {
198         int i;
199         u32 temp;
200         struct aper_size_info_lvl2 *values;
201
202         pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp);
203         temp = (temp & 0x0000000e);
204         values = A_SIZE_LVL2(agp_bridge->driver->aperture_sizes);
205         for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
206                 if (temp == values[i].size_value) {
207                         agp_bridge->previous_size =
208                             agp_bridge->current_size = (void *) (values + i);
209
210                         agp_bridge->aperture_size_idx = i;
211                         return values[i].size;
212                 }
213         }
214
215         return 0;
216 }
217
218 static int amd_irongate_configure(void)
219 {
220         struct aper_size_info_lvl2 *current_size;
221         u32 temp;
222         u16 enable_reg;
223
224         current_size = A_SIZE_LVL2(agp_bridge->current_size);
225
226         /* Get the memory mapped registers */
227         pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp);
228         temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
229         amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096);
230         if (!amd_irongate_private.registers)
231                 return -ENOMEM;
232
233         /* Write out the address of the gatt table */
234         writel(agp_bridge->gatt_bus_addr, amd_irongate_private.registers+AMD_ATTBASE);
235         readl(amd_irongate_private.registers+AMD_ATTBASE);      /* PCI Posting. */
236
237         /* Write the Sync register */
238         pci_write_config_byte(agp_bridge->dev, AMD_MODECNTL, 0x80);
239
240         /* Set indexing mode */
241         pci_write_config_byte(agp_bridge->dev, AMD_MODECNTL2, 0x00);
242
243         /* Write the enable register */
244         enable_reg = readw(amd_irongate_private.registers+AMD_GARTENABLE);
245         enable_reg = (enable_reg | 0x0004);
246         writew(enable_reg, amd_irongate_private.registers+AMD_GARTENABLE);
247         readw(amd_irongate_private.registers+AMD_GARTENABLE);   /* PCI Posting. */
248
249         /* Write out the size register */
250         pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp);
251         temp = (((temp & ~(0x0000000e)) | current_size->size_value) | 1);
252         pci_write_config_dword(agp_bridge->dev, AMD_APSIZE, temp);
253
254         /* Flush the tlb */
255         writel(1, amd_irongate_private.registers+AMD_TLBFLUSH);
256         readl(amd_irongate_private.registers+AMD_TLBFLUSH);     /* PCI Posting.*/
257         return 0;
258 }
259
260 static void amd_irongate_cleanup(void)
261 {
262         struct aper_size_info_lvl2 *previous_size;
263         u32 temp;
264         u16 enable_reg;
265
266         previous_size = A_SIZE_LVL2(agp_bridge->previous_size);
267
268         enable_reg = readw(amd_irongate_private.registers+AMD_GARTENABLE);
269         enable_reg = (enable_reg & ~(0x0004));
270         writew(enable_reg, amd_irongate_private.registers+AMD_GARTENABLE);
271         readw(amd_irongate_private.registers+AMD_GARTENABLE);   /* PCI Posting. */
272
273         /* Write back the previous size and disable gart translation */
274         pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp);
275         temp = ((temp & ~(0x0000000f)) | previous_size->size_value);
276         pci_write_config_dword(agp_bridge->dev, AMD_APSIZE, temp);
277         iounmap((void __iomem *) amd_irongate_private.registers);
278 }
279
280 /*
281  * This routine could be implemented by taking the addresses
282  * written to the GATT, and flushing them individually.  However
283  * currently it just flushes the whole table.  Which is probably
284  * more efficent, since agp_memory blocks can be a large number of
285  * entries.
286  */
287
288 static void amd_irongate_tlbflush(struct agp_memory *temp)
289 {
290         writel(1, amd_irongate_private.registers+AMD_TLBFLUSH);
291         readl(amd_irongate_private.registers+AMD_TLBFLUSH);     /* PCI Posting. */
292 }
293
294 static int amd_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
295 {
296         int i, j, num_entries;
297         unsigned long __iomem *cur_gatt;
298         unsigned long addr;
299
300         num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries;
301
302         if (type != 0 || mem->type != 0)
303                 return -EINVAL;
304
305         if ((pg_start + mem->page_count) > num_entries)
306                 return -EINVAL;
307
308         j = pg_start;
309         while (j < (pg_start + mem->page_count)) {
310                 addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
311                 cur_gatt = GET_GATT(addr);
312                 if (!PGE_EMPTY(agp_bridge, readl(cur_gatt+GET_GATT_OFF(addr))))
313                         return -EBUSY;
314                 j++;
315         }
316
317         if (mem->is_flushed == FALSE) {
318                 global_cache_flush();
319                 mem->is_flushed = TRUE;
320         }
321
322         for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
323                 addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
324                 cur_gatt = GET_GATT(addr);
325                 writel(agp_generic_mask_memory(agp_bridge,
326                         mem->memory[i], mem->type), cur_gatt+GET_GATT_OFF(addr));
327                 readl(cur_gatt+GET_GATT_OFF(addr));     /* PCI Posting. */
328         }
329         amd_irongate_tlbflush(mem);
330         return 0;
331 }
332
333 static int amd_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
334 {
335         int i;
336         unsigned long __iomem *cur_gatt;
337         unsigned long addr;
338
339         if (type != 0 || mem->type != 0)
340                 return -EINVAL;
341
342         for (i = pg_start; i < (mem->page_count + pg_start); i++) {
343                 addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
344                 cur_gatt = GET_GATT(addr);
345                 writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr));
346                 readl(cur_gatt+GET_GATT_OFF(addr));     /* PCI Posting. */
347         }
348
349         amd_irongate_tlbflush(mem);
350         return 0;
351 }
352
353 static const struct aper_size_info_lvl2 amd_irongate_sizes[7] =
354 {
355         {2048, 524288, 0x0000000c},
356         {1024, 262144, 0x0000000a},
357         {512, 131072, 0x00000008},
358         {256, 65536, 0x00000006},
359         {128, 32768, 0x00000004},
360         {64, 16384, 0x00000002},
361         {32, 8192, 0x00000000}
362 };
363
364 static const struct gatt_mask amd_irongate_masks[] =
365 {
366         {.mask = 1, .type = 0}
367 };
368
369 static const struct agp_bridge_driver amd_irongate_driver = {
370         .owner                  = THIS_MODULE,
371         .aperture_sizes         = amd_irongate_sizes,
372         .size_type              = LVL2_APER_SIZE,
373         .num_aperture_sizes     = 7,
374         .configure              = amd_irongate_configure,
375         .fetch_size             = amd_irongate_fetch_size,
376         .cleanup                = amd_irongate_cleanup,
377         .tlb_flush              = amd_irongate_tlbflush,
378         .mask_memory            = agp_generic_mask_memory,
379         .masks                  = amd_irongate_masks,
380         .agp_enable             = agp_generic_enable,
381         .cache_flush            = global_cache_flush,
382         .create_gatt_table      = amd_create_gatt_table,
383         .free_gatt_table        = amd_free_gatt_table,
384         .insert_memory          = amd_insert_memory,
385         .remove_memory          = amd_remove_memory,
386         .alloc_by_type          = agp_generic_alloc_by_type,
387         .free_by_type           = agp_generic_free_by_type,
388         .agp_alloc_page         = agp_generic_alloc_page,
389         .agp_destroy_page       = agp_generic_destroy_page,
390         .agp_type_to_mask_type  = agp_generic_type_to_mask_type,
391 };
392
393 static struct agp_device_ids amd_agp_device_ids[] __devinitdata =
394 {
395         {
396                 .device_id      = PCI_DEVICE_ID_AMD_FE_GATE_7006,
397                 .chipset_name   = "Irongate",
398         },
399         {
400                 .device_id      = PCI_DEVICE_ID_AMD_FE_GATE_700E,
401                 .chipset_name   = "761",
402         },
403         {
404                 .device_id      = PCI_DEVICE_ID_AMD_FE_GATE_700C,
405                 .chipset_name   = "760MP",
406         },
407         { }, /* dummy final entry, always present */
408 };
409
410 static int __devinit agp_amdk7_probe(struct pci_dev *pdev,
411                                      const struct pci_device_id *ent)
412 {
413         struct agp_bridge_data *bridge;
414         u8 cap_ptr;
415         int j;
416
417         cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
418         if (!cap_ptr)
419                 return -ENODEV;
420
421         j = ent - agp_amdk7_pci_table;
422         printk(KERN_INFO PFX "Detected AMD %s chipset\n",
423                amd_agp_device_ids[j].chipset_name);
424
425         bridge = agp_alloc_bridge();
426         if (!bridge)
427                 return -ENOMEM;
428
429         bridge->driver = &amd_irongate_driver;
430         bridge->dev_private_data = &amd_irongate_private,
431         bridge->dev = pdev;
432         bridge->capndx = cap_ptr;
433
434         /* 751 Errata (22564_B-1.PDF)
435            erratum 20: strobe glitch with Nvidia NV10 GeForce cards.
436            system controller may experience noise due to strong drive strengths
437          */
438         if (agp_bridge->dev->device == PCI_DEVICE_ID_AMD_FE_GATE_7006) {
439                 u8 cap_ptr=0;
440                 struct pci_dev *gfxcard=NULL;
441                 while (!cap_ptr) {
442                         gfxcard = pci_get_class(PCI_CLASS_DISPLAY_VGA<<8, gfxcard);
443                         if (!gfxcard) {
444                                 printk (KERN_INFO PFX "Couldn't find an AGP VGA controller.\n");
445                                 return -ENODEV;
446                         }
447                         cap_ptr = pci_find_capability(gfxcard, PCI_CAP_ID_AGP);
448                 }
449
450                 /* With so many variants of NVidia cards, it's simpler just
451                    to blacklist them all, and then whitelist them as needed
452                    (if necessary at all). */
453                 if (gfxcard->vendor == PCI_VENDOR_ID_NVIDIA) {
454                         agp_bridge->flags |= AGP_ERRATA_1X;
455                         printk (KERN_INFO PFX "AMD 751 chipset with NVidia GeForce detected. Forcing to 1X due to errata.\n");
456                 }
457                 pci_dev_put(gfxcard);
458         }
459
460         /* 761 Errata (23613_F.pdf)
461          * Revisions B0/B1 were a disaster.
462          * erratum 44: SYSCLK/AGPCLK skew causes 2X failures -- Force mode to 1X
463          * erratum 45: Timing problem prevents fast writes -- Disable fast write.
464          * erratum 46: Setup violation on AGP SBA pins - Disable side band addressing.
465          * With this lot disabled, we should prevent lockups. */
466         if (agp_bridge->dev->device == PCI_DEVICE_ID_AMD_FE_GATE_700E) {
467                 if (pdev->revision == 0x10 || pdev->revision == 0x11) {
468                         agp_bridge->flags = AGP_ERRATA_FASTWRITES;
469                         agp_bridge->flags |= AGP_ERRATA_SBA;
470                         agp_bridge->flags |= AGP_ERRATA_1X;
471                         printk (KERN_INFO PFX "AMD 761 chipset with errata detected - disabling AGP fast writes & SBA and forcing to 1X.\n");
472                 }
473         }
474
475         /* Fill in the mode register */
476         pci_read_config_dword(pdev,
477                         bridge->capndx+PCI_AGP_STATUS,
478                         &bridge->mode);
479
480         pci_set_drvdata(pdev, bridge);
481         return agp_add_bridge(bridge);
482 }
483
484 static void __devexit agp_amdk7_remove(struct pci_dev *pdev)
485 {
486         struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
487
488         agp_remove_bridge(bridge);
489         agp_put_bridge(bridge);
490 }
491
492 /* must be the same order as name table above */
493 static struct pci_device_id agp_amdk7_pci_table[] = {
494         {
495         .class          = (PCI_CLASS_BRIDGE_HOST << 8),
496         .class_mask     = ~0,
497         .vendor         = PCI_VENDOR_ID_AMD,
498         .device         = PCI_DEVICE_ID_AMD_FE_GATE_7006,
499         .subvendor      = PCI_ANY_ID,
500         .subdevice      = PCI_ANY_ID,
501         },
502         {
503         .class          = (PCI_CLASS_BRIDGE_HOST << 8),
504         .class_mask     = ~0,
505         .vendor         = PCI_VENDOR_ID_AMD,
506         .device         = PCI_DEVICE_ID_AMD_FE_GATE_700E,
507         .subvendor      = PCI_ANY_ID,
508         .subdevice      = PCI_ANY_ID,
509         },
510         {
511         .class          = (PCI_CLASS_BRIDGE_HOST << 8),
512         .class_mask     = ~0,
513         .vendor         = PCI_VENDOR_ID_AMD,
514         .device         = PCI_DEVICE_ID_AMD_FE_GATE_700C,
515         .subvendor      = PCI_ANY_ID,
516         .subdevice      = PCI_ANY_ID,
517         },
518         { }
519 };
520
521 MODULE_DEVICE_TABLE(pci, agp_amdk7_pci_table);
522
523 static struct pci_driver agp_amdk7_pci_driver = {
524         .name           = "agpgart-amdk7",
525         .id_table       = agp_amdk7_pci_table,
526         .probe          = agp_amdk7_probe,
527         .remove         = agp_amdk7_remove,
528 };
529
530 static int __init agp_amdk7_init(void)
531 {
532         if (agp_off)
533                 return -EINVAL;
534         return pci_register_driver(&agp_amdk7_pci_driver);
535 }
536
537 static void __exit agp_amdk7_cleanup(void)
538 {
539         pci_unregister_driver(&agp_amdk7_pci_driver);
540 }
541
542 module_init(agp_amdk7_init);
543 module_exit(agp_amdk7_cleanup);
544
545 MODULE_LICENSE("GPL and additional rights");