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