vserver 1.9.5.x5
[linux-2.6.git] / drivers / char / agp / intel-mch-agp.c
1 /*
2  * Intel MCH 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 "agp.h"
10
11
12 #define AGP_DCACHE_MEMORY       1
13 #define AGP_PHYS_MEMORY         2
14
15 static struct gatt_mask intel_i810_masks[] =
16 {
17         {.mask = I810_PTE_VALID, .type = 0},
18         {.mask = (I810_PTE_VALID | I810_PTE_LOCAL), .type = AGP_DCACHE_MEMORY},
19         {.mask = I810_PTE_VALID, .type = 0}
20 };
21
22 static void intel_i810_tlbflush(struct agp_memory *mem)
23 {
24         return;
25 }
26
27 static void intel_i810_agp_enable(u32 mode)
28 {
29         return;
30 }
31
32
33 /*
34  * The i810/i830 requires a physical address to program its mouse
35  * pointer into hardware.
36  * However the Xserver still writes to it through the agp aperture.
37  */
38 static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
39 {
40         struct agp_memory *new;
41         void *addr;
42
43         if (pg_count != 1)
44                 return NULL;
45
46         addr = agp_bridge->driver->agp_alloc_page();
47         if (addr == NULL)
48                 return NULL;
49
50         new = agp_create_memory(1);
51         if (new == NULL)
52                 return NULL;
53
54         new->memory[0] = virt_to_phys(addr);
55         new->page_count = 1;
56         new->num_scratch_pages = 1;
57         new->type = AGP_PHYS_MEMORY;
58         new->physical = new->memory[0];
59         return new;
60 }
61
62 static void intel_i810_free_by_type(struct agp_memory *curr)
63 {
64         agp_free_key(curr->key);
65         if(curr->type == AGP_PHYS_MEMORY) {
66                 agp_bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[0]));
67                 vfree(curr->memory);
68         }
69         kfree(curr);
70 }
71
72 static unsigned long intel_i810_mask_memory(unsigned long addr, int type)
73 {
74         /* Type checking must be done elsewhere */
75         return addr | agp_bridge->driver->masks[type].mask;
76 }
77
78 static struct aper_size_info_fixed intel_i830_sizes[] =
79 {
80         {128, 32768, 5},
81         /* The 64M mode still requires a 128k gatt */
82         {64, 16384, 5}
83 };
84
85 static struct _intel_i830_private {
86         struct pci_dev *i830_dev;               /* device one */
87         volatile u8 __iomem *registers;
88         int gtt_entries;
89 } intel_i830_private;
90
91 static void intel_i830_init_gtt_entries(void)
92 {
93         u16 gmch_ctrl;
94         int gtt_entries;
95         u8 rdct;
96         int local = 0;
97         static const int ddt[4] = { 0, 16, 32, 64 };
98
99         pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
100
101         if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB ||
102             agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) {
103                 switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
104                 case I830_GMCH_GMS_STOLEN_512:
105                         gtt_entries = KB(512) - KB(132);
106                         break;
107                 case I830_GMCH_GMS_STOLEN_1024:
108                         gtt_entries = MB(1) - KB(132);
109                         break;
110                 case I830_GMCH_GMS_STOLEN_8192:
111                         gtt_entries = MB(8) - KB(132);
112                         break;
113                 case I830_GMCH_GMS_LOCAL:
114                         rdct = readb(intel_i830_private.registers+I830_RDRAM_CHANNEL_TYPE);
115                         gtt_entries = (I830_RDRAM_ND(rdct) + 1) *
116                                         MB(ddt[I830_RDRAM_DDT(rdct)]);
117                         local = 1;
118                         break;
119                 default:
120                         gtt_entries = 0;
121                         break;
122                 }
123         } else {
124                 switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
125                 case I855_GMCH_GMS_STOLEN_1M:
126                         gtt_entries = MB(1) - KB(132);
127                         break;
128                 case I855_GMCH_GMS_STOLEN_4M:
129                         gtt_entries = MB(4) - KB(132);
130                         break;
131                 case I855_GMCH_GMS_STOLEN_8M:
132                         gtt_entries = MB(8) - KB(132);
133                         break;
134                 case I855_GMCH_GMS_STOLEN_16M:
135                         gtt_entries = MB(16) - KB(132);
136                         break;
137                 case I855_GMCH_GMS_STOLEN_32M:
138                         gtt_entries = MB(32) - KB(132);
139                         break;
140                 default:
141                         gtt_entries = 0;
142                         break;
143                 }
144         }
145         if (gtt_entries > 0)
146                 printk(KERN_INFO PFX "Detected %dK %s memory.\n",
147                        gtt_entries / KB(1), local ? "local" : "stolen");
148         else
149                 printk(KERN_INFO PFX
150                        "No pre-allocated video memory detected.\n");
151         gtt_entries /= KB(4);
152
153         intel_i830_private.gtt_entries = gtt_entries;
154 }
155
156 /* The intel i830 automatically initializes the agp aperture during POST.
157  * Use the memory already set aside for in the GTT.
158  */
159 static int intel_i830_create_gatt_table(void)
160 {
161         int page_order;
162         struct aper_size_info_fixed *size;
163         int num_entries;
164         u32 temp;
165
166         size = agp_bridge->current_size;
167         page_order = size->page_order;
168         num_entries = size->num_entries;
169         agp_bridge->gatt_table_real = NULL;
170
171         pci_read_config_dword(intel_i830_private.i830_dev,I810_MMADDR,&temp);
172         temp &= 0xfff80000;
173
174         intel_i830_private.registers = (volatile u8 __iomem*) ioremap(temp,128 * 4096);
175         if (!intel_i830_private.registers)
176                 return -ENOMEM;
177
178         temp = readl(intel_i830_private.registers+I810_PGETBL_CTL) & 0xfffff000;
179         global_cache_flush();   /* FIXME: ?? */
180
181         /* we have to call this as early as possible after the MMIO base address is known */
182         intel_i830_init_gtt_entries();
183
184         agp_bridge->gatt_table = NULL;
185
186         agp_bridge->gatt_bus_addr = temp;
187
188         return 0;
189 }
190
191 /* Return the gatt table to a sane state. Use the top of stolen
192  * memory for the GTT.
193  */
194 static int intel_i830_free_gatt_table(void)
195 {
196         return 0;
197 }
198
199 static int intel_i830_fetch_size(void)
200 {
201         u16 gmch_ctrl;
202         struct aper_size_info_fixed *values;
203
204         values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
205
206         if (agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82830_HB &&
207             agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82845G_HB) {
208                 /* 855GM/852GM/865G has 128MB aperture size */
209                 agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
210                 agp_bridge->aperture_size_idx = 0;
211                 return values[0].size;
212         }
213
214         pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
215
216         if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
217                 agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
218                 agp_bridge->aperture_size_idx = 0;
219                 return values[0].size;
220         } else {
221                 agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
222                 agp_bridge->aperture_size_idx = 1;
223                 return values[1].size;
224         }
225
226         return 0;
227 }
228
229 static int intel_i830_configure(void)
230 {
231         struct aper_size_info_fixed *current_size;
232         u32 temp;
233         u16 gmch_ctrl;
234         int i;
235
236         current_size = A_SIZE_FIX(agp_bridge->current_size);
237
238         pci_read_config_dword(intel_i830_private.i830_dev,I810_GMADDR,&temp);
239         agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
240
241         pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
242         gmch_ctrl |= I830_GMCH_ENABLED;
243         pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
244
245         writel(agp_bridge->gatt_bus_addr|I810_PGETBL_ENABLED, intel_i830_private.registers+I810_PGETBL_CTL);
246         readl(intel_i830_private.registers+I810_PGETBL_CTL);    /* PCI Posting. */
247
248         if (agp_bridge->driver->needs_scratch_page) {
249                 for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++) {
250                         writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
251                         readl(intel_i830_private.registers+I810_PTE_BASE+(i*4));        /* PCI Posting. */
252                 }
253         }
254         global_cache_flush();
255         return 0;
256 }
257
258 static void intel_i830_cleanup(void)
259 {
260         iounmap((void __iomem *) intel_i830_private.registers);
261 }
262
263 static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start,
264                                 int type)
265 {
266         int i,j,num_entries;
267         void *temp;
268
269         temp = agp_bridge->current_size;
270         num_entries = A_SIZE_FIX(temp)->num_entries;
271
272         if (pg_start < intel_i830_private.gtt_entries) {
273                 printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
274                                 pg_start,intel_i830_private.gtt_entries);
275
276                 printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
277                 return -EINVAL;
278         }
279
280         if ((pg_start + mem->page_count) > num_entries)
281                 return -EINVAL;
282
283         /* The i830 can't check the GTT for entries since its read only,
284          * depend on the caller to make the correct offset decisions.
285          */
286
287         if ((type != 0 && type != AGP_PHYS_MEMORY) ||
288                 (mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
289                 return -EINVAL;
290
291         global_cache_flush();   /* FIXME: ?? */
292
293         for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
294                 writel(agp_bridge->driver->mask_memory(mem->memory[i], mem->type),
295                                 intel_i830_private.registers+I810_PTE_BASE+(j*4));
296                 readl(intel_i830_private.registers+I810_PTE_BASE+(j*4));        /* PCI Posting. */
297         }
298
299         global_cache_flush();
300
301         agp_bridge->driver->tlb_flush(mem);
302
303         return 0;
304 }
305
306 static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
307                                 int type)
308 {
309         int i;
310
311         global_cache_flush();
312
313         if (pg_start < intel_i830_private.gtt_entries) {
314                 printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
315                 return -EINVAL;
316         }
317
318         for (i = pg_start; i < (mem->page_count + pg_start); i++) {
319                 writel(agp_bridge->scratch_page, intel_i830_private.registers+I810_PTE_BASE+(i*4));
320                 readl(intel_i830_private.registers+I810_PTE_BASE+(i*4));        /* PCI Posting. */
321         }
322
323         global_cache_flush();
324         agp_bridge->driver->tlb_flush(mem);
325         return 0;
326 }
327
328 static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
329 {
330         if (type == AGP_PHYS_MEMORY)
331                 return alloc_agpphysmem_i8xx(pg_count, type);
332
333         /* always return NULL for other allocation types for now */
334         return NULL;
335 }
336
337 static int intel_8xx_fetch_size(void)
338 {
339         u8 temp;
340         int i;
341         struct aper_size_info_8 *values;
342
343         pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
344
345         values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
346
347         for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
348                 if (temp == values[i].size_value) {
349                         agp_bridge->previous_size =
350                                 agp_bridge->current_size = (void *) (values + i);
351                         agp_bridge->aperture_size_idx = i;
352                         return values[i].size;
353                 }
354         }
355         return 0;
356 }
357
358 static void intel_8xx_tlbflush(struct agp_memory *mem)
359 {
360         u32 temp;
361         pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
362         pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp & ~(1 << 7));
363         pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
364         pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp | (1 << 7));
365 }
366
367 static void intel_8xx_cleanup(void)
368 {
369         u16 temp;
370         struct aper_size_info_8 *previous_size;
371
372         previous_size = A_SIZE_8(agp_bridge->previous_size);
373         pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
374         pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
375         pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
376 }
377
378 static int intel_845_configure(void)
379 {
380         u32 temp;
381         u8 temp2;
382         struct aper_size_info_8 *current_size;
383
384         current_size = A_SIZE_8(agp_bridge->current_size);
385
386         /* aperture size */
387         pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); 
388
389         /* address to map to */
390         pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
391         agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
392
393         /* attbase - aperture base */
394         pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); 
395
396         /* agpctrl */
397         pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000); 
398
399         /* agpm */
400         pci_read_config_byte(agp_bridge->dev, INTEL_I845_AGPM, &temp2);
401         pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));
402         /* clear any possible error conditions */
403         pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c); 
404         return 0;
405 }
406
407
408 /* Setup function */
409 static struct gatt_mask intel_generic_masks[] =
410 {
411         {.mask = 0x00000017, .type = 0}
412 };
413
414 static struct aper_size_info_8 intel_8xx_sizes[7] =
415 {
416         {256, 65536, 6, 0},
417         {128, 32768, 5, 32},
418         {64, 16384, 4, 48},
419         {32, 8192, 3, 56},
420         {16, 4096, 2, 60},
421         {8, 2048, 1, 62},
422         {4, 1024, 0, 63}
423 };
424
425 static struct agp_bridge_driver intel_830_driver = {
426         .owner                  = THIS_MODULE,
427         .aperture_sizes         = intel_i830_sizes,
428         .size_type              = FIXED_APER_SIZE,
429         .num_aperture_sizes     = 2,
430         .needs_scratch_page     = TRUE,
431         .configure              = intel_i830_configure,
432         .fetch_size             = intel_i830_fetch_size,
433         .cleanup                = intel_i830_cleanup,
434         .tlb_flush              = intel_i810_tlbflush,
435         .mask_memory            = intel_i810_mask_memory,
436         .masks                  = intel_i810_masks,
437         .agp_enable             = intel_i810_agp_enable,
438         .cache_flush            = global_cache_flush,
439         .create_gatt_table      = intel_i830_create_gatt_table,
440         .free_gatt_table        = intel_i830_free_gatt_table,
441         .insert_memory          = intel_i830_insert_entries,
442         .remove_memory          = intel_i830_remove_entries,
443         .alloc_by_type          = intel_i830_alloc_by_type,
444         .free_by_type           = intel_i810_free_by_type,
445         .agp_alloc_page         = agp_generic_alloc_page,
446         .agp_destroy_page       = agp_generic_destroy_page,
447 };
448
449 static struct agp_bridge_driver intel_845_driver = {
450         .owner                  = THIS_MODULE,
451         .aperture_sizes         = intel_8xx_sizes,
452         .size_type              = U8_APER_SIZE,
453         .num_aperture_sizes     = 7,
454         .configure              = intel_845_configure,
455         .fetch_size             = intel_8xx_fetch_size,
456         .cleanup                = intel_8xx_cleanup,
457         .tlb_flush              = intel_8xx_tlbflush,
458         .mask_memory            = agp_generic_mask_memory,
459         .masks                  = intel_generic_masks,
460         .agp_enable             = agp_generic_enable,
461         .cache_flush            = global_cache_flush,
462         .create_gatt_table      = agp_generic_create_gatt_table,
463         .free_gatt_table        = agp_generic_free_gatt_table,
464         .insert_memory          = agp_generic_insert_memory,
465         .remove_memory          = agp_generic_remove_memory,
466         .alloc_by_type          = agp_generic_alloc_by_type,
467         .free_by_type           = agp_generic_free_by_type,
468         .agp_alloc_page         = agp_generic_alloc_page,
469         .agp_destroy_page       = agp_generic_destroy_page,
470 };
471
472
473 static int find_i830(u16 device)
474 {
475         struct pci_dev *i830_dev;
476
477         i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL, device, NULL);
478         if (i830_dev && PCI_FUNC(i830_dev->devfn) != 0) {
479                 i830_dev = pci_get_device(PCI_VENDOR_ID_INTEL,
480                                 device, i830_dev);
481         }
482
483         if (!i830_dev)
484                 return 0;
485
486         intel_i830_private.i830_dev = i830_dev;
487         return 1;
488 }
489
490 static int __devinit agp_intelmch_probe(struct pci_dev *pdev,
491                                      const struct pci_device_id *ent)
492 {
493         struct agp_bridge_data *bridge;
494         struct resource *r;
495         char *name = "(unknown)";
496         u8 cap_ptr = 0;
497
498         cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
499         if (!cap_ptr) 
500                 return -ENODEV;
501
502         bridge = agp_alloc_bridge();
503         if (!bridge)
504                 return -ENOMEM;
505
506         switch (pdev->device) {
507         case PCI_DEVICE_ID_INTEL_82865_HB:
508                 if (find_i830(PCI_DEVICE_ID_INTEL_82865_IG)) {
509                         bridge->driver = &intel_830_driver;
510                 } else {
511                         bridge->driver = &intel_845_driver;
512                 }
513                 name = "865";
514                 break;
515         case PCI_DEVICE_ID_INTEL_82875_HB:
516                 bridge->driver = &intel_845_driver;
517                 name = "i875";
518                 break;
519
520         default:
521                 printk(KERN_ERR PFX "Unsupported Intel chipset (device id: %04x)\n",
522                             pdev->device);
523                 return -ENODEV;
524         };
525
526         bridge->dev = pdev;
527         bridge->capndx = cap_ptr;
528
529         if (bridge->driver == &intel_830_driver)
530                 bridge->dev_private_data = &intel_i830_private;
531
532         printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n", name);
533
534         /*
535         * The following fixes the case where the BIOS has "forgotten" to
536         * provide an address range for the GART.
537         * 20030610 - hamish@zot.org
538         */
539         r = &pdev->resource[0];
540         if (!r->start && r->end) {
541                 if(pci_assign_resource(pdev, 0)) {
542                         printk(KERN_ERR PFX "could not assign resource 0\n");
543                         return -ENODEV;
544                 }
545         }
546
547         /*
548         * If the device has not been properly setup, the following will catch
549         * the problem and should stop the system from crashing.
550         * 20030610 - hamish@zot.org
551         */
552         if (pci_enable_device(pdev)) {
553                 printk(KERN_ERR PFX "Unable to Enable PCI device\n");
554                 return -ENODEV;
555         }
556
557         /* Fill in the mode register */
558         if (cap_ptr) {
559                 pci_read_config_dword(pdev,
560                                 bridge->capndx+PCI_AGP_STATUS,
561                                 &bridge->mode);
562         }
563
564         pci_set_drvdata(pdev, bridge);
565         return agp_add_bridge(bridge);
566 }
567
568 static void __devexit agp_intelmch_remove(struct pci_dev *pdev)
569 {
570         struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
571
572         agp_remove_bridge(bridge);
573         if (intel_i830_private.i830_dev)
574                 pci_dev_put(intel_i830_private.i830_dev);
575         agp_put_bridge(bridge);
576 }
577
578 static int agp_intelmch_resume(struct pci_dev *pdev)
579 {
580         struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
581
582         pci_restore_state(pdev);
583
584         if (bridge->driver == &intel_845_driver)
585                 intel_845_configure();
586
587         return 0;
588 }
589
590 static struct pci_device_id agp_intelmch_pci_table[] = {
591         {
592         .class          = (PCI_CLASS_BRIDGE_HOST << 8),
593         .class_mask     = ~0,
594         .vendor         = PCI_VENDOR_ID_INTEL,
595         .device         = PCI_DEVICE_ID_INTEL_82865_HB,
596         .subvendor      = PCI_ANY_ID,
597         .subdevice      = PCI_ANY_ID,
598         },
599         {
600         .class          = (PCI_CLASS_BRIDGE_HOST << 8),
601         .class_mask     = ~0,
602         .vendor         = PCI_VENDOR_ID_INTEL,
603         .device         = PCI_DEVICE_ID_INTEL_82875_HB,
604         .subvendor      = PCI_ANY_ID,
605         .subdevice      = PCI_ANY_ID,
606         },
607         { }
608 };
609
610 MODULE_DEVICE_TABLE(pci, agp_intelmch_pci_table);
611
612 static struct pci_driver agp_intelmch_pci_driver = {
613         .name           = "agpgart-intel-mch",
614         .id_table       = agp_intelmch_pci_table,
615         .probe          = agp_intelmch_probe,
616         .remove         = agp_intelmch_remove,
617         .resume         = agp_intelmch_resume,
618 };
619
620 /* intel_agp_init() must not be declared static for explicit
621    early initialization to work (ie i810fb) */
622 int __init agp_intelmch_init(void)
623 {
624         static int agp_initialised=0;
625
626         if (agp_initialised == 1)
627                 return 0;
628         agp_initialised=1;
629
630         return pci_module_init(&agp_intelmch_pci_driver);
631 }
632
633 static void __exit agp_intelmch_cleanup(void)
634 {
635         pci_unregister_driver(&agp_intelmch_pci_driver);
636 }
637
638 module_init(agp_intelmch_init);
639 module_exit(agp_intelmch_cleanup);
640
641 MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
642 MODULE_LICENSE("GPL");
643