Merge branch 'vendor/LIBPCAP' (early part)
[dragonfly.git] / sys / dev / agp / agp_i810.c
1 /*
2  * Copyright (c) 2000 Doug Rabson
3  * Copyright (c) 2000 Ruslan Ermilov
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *      $FreeBSD: src/sys/dev/agp/agp_i810.c,v 1.43 2007/11/12 21:51:36 jhb Exp $
28  *      $DragonFly: src/sys/dev/agp/agp_i810.c,v 1.19 2008/10/03 08:56:58 hasso Exp $
29  */
30
31 /*
32  * Fixes for 830/845G support: David Dawes <dawes@xfree86.org>
33  * 852GM/855GM/865G support added by David Dawes <dawes@xfree86.org>
34  */
35
36 #include "opt_bus.h"
37
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/malloc.h>
41 #include <sys/kernel.h>
42 #include <sys/bus.h>
43 #include <sys/lock.h>
44 #include <sys/rman.h>
45
46 #include <bus/pci/pcivar.h>
47 #include <bus/pci/pcireg.h>
48 #include "agppriv.h"
49 #include "agpreg.h"
50
51 #include <vm/vm.h>
52 #include <vm/vm_object.h>
53 #include <vm/vm_page.h>
54 #include <vm/vm_pageout.h>
55 #include <vm/pmap.h>
56
57 #include <machine/md_var.h>
58
59 #define bus_read_1(r, o) \
60                    bus_space_read_1((r)->r_bustag, (r)->r_bushandle, (o))
61 #define bus_read_4(r, o) \
62                    bus_space_read_4((r)->r_bustag, (r)->r_bushandle, (o))
63 #define bus_write_4(r, o, v) \
64                     bus_space_write_4((r)->r_bustag, (r)->r_bushandle, (o), (v))
65
66 MALLOC_DECLARE(M_AGP);
67
68 enum {
69         CHIP_I810,      /* i810/i815 */
70         CHIP_I830,      /* 830M/845G */
71         CHIP_I855,      /* 852GM/855GM/865G */
72         CHIP_I915,      /* 915G/915GM */
73         CHIP_I965,      /* G965 */
74         CHIP_G33,       /* G33/Q33/Q35 */
75         CHIP_G4X,       /* G45/Q45 */
76 };
77
78 /* The i810 through i855 have the registers at BAR 1, and the GATT gets
79  * allocated by us.  The i915 has registers in BAR 0 and the GATT is at the
80  * start of the stolen memory, and should only be accessed by the OS through
81  * BAR 3.  The G965 has registers and GATT in the same BAR (0) -- first 512KB
82  * is registers, second 512KB is GATT.
83  */
84 static struct resource_spec agp_i810_res_spec[] = {
85         { SYS_RES_MEMORY, AGP_I810_MMADR, RF_ACTIVE | RF_SHAREABLE },
86         { -1, 0 }
87 };
88
89 static struct resource_spec agp_i915_res_spec[] = {
90         { SYS_RES_MEMORY, AGP_I915_MMADR, RF_ACTIVE | RF_SHAREABLE },
91         { SYS_RES_MEMORY, AGP_I915_GTTADR, RF_ACTIVE | RF_SHAREABLE },
92         { -1, 0 }
93 };
94
95 static struct resource_spec agp_i965_res_spec[] = {
96         { SYS_RES_MEMORY, AGP_I965_GTTMMADR, RF_ACTIVE | RF_SHAREABLE },
97         { -1, 0 }
98 };
99
100 struct agp_i810_softc {
101         struct agp_softc agp;
102         u_int32_t initial_aperture;     /* aperture size at startup */
103         struct agp_gatt *gatt;
104         int chiptype;                   /* i810-like or i830 */
105         u_int32_t dcache_size;          /* i810 only */
106         u_int32_t stolen;               /* number of i830/845 gtt entries for stolen memory */
107         device_t bdev;                  /* bridge device */
108
109         void *argb_cursor;              /* contigmalloc area for ARGB cursor */
110
111         struct resource_spec * sc_res_spec;
112         struct resource *sc_res[2];
113 };
114
115 /* For adding new devices, devid is the id of the graphics controller
116  * (pci:0:2:0, for example).  The placeholder (usually at pci:0:2:1) for the
117  * second head should never be added.  The bridge_offset is the offset to
118  * subtract from devid to get the id of the hostb that the device is on.
119  */
120 static const struct agp_i810_match {
121         int devid;
122         int chiptype;
123         int bridge_offset;
124         char *name;
125 } agp_i810_matches[] = {
126         {0x71218086, CHIP_I810, 0x00010000,
127             "Intel 82810 (i810 GMCH) SVGA controller"},
128         {0x71238086, CHIP_I810, 0x00010000,
129             "Intel 82810-DC100 (i810-DC100 GMCH) SVGA controller"},
130         {0x71258086, CHIP_I810, 0x00010000,
131             "Intel 82810E (i810E GMCH) SVGA controller"},
132         {0x11328086, CHIP_I810, 0x00020000,
133             "Intel 82815 (i815 GMCH) SVGA controller"},
134         {0x35778086, CHIP_I830, 0x00020000,
135             "Intel 82830M (830M GMCH) SVGA controller"},
136         {0x25628086, CHIP_I830, 0x00020000,
137             "Intel 82845M (845M GMCH) SVGA controller"},
138         {0x35828086, CHIP_I855, 0x00020000,
139             "Intel 82852/855GM SVGA controller"},
140         {0x25728086, CHIP_I855, 0x00020000,
141             "Intel 82865G (865G GMCH) SVGA controller"},
142         {0x25828086, CHIP_I915, 0x00020000,
143             "Intel 82915G (915G GMCH) SVGA controller"},
144         {0x258A8086, CHIP_I915, 0x00020000,
145             "Intel E7221 SVGA controller"},
146         {0x25928086, CHIP_I915, 0x00020000,
147             "Intel 82915GM (915GM GMCH) SVGA controller"},
148         {0x27728086, CHIP_I915, 0x00020000,
149             "Intel 82945G (945G GMCH) SVGA controller"},
150         {0x27A28086, CHIP_I915, 0x00020000,
151             "Intel 82945GM (945GM GMCH) SVGA controller"},
152         {0x27AE8086, CHIP_I915, 0x00020000,
153             "Intel 945GME SVGA controller"},
154         {0x29728086, CHIP_I965, 0x00020000,
155             "Intel 946GZ SVGA controller"},
156         {0x29828086, CHIP_I965, 0x00020000,
157             "Intel G965 SVGA controller"},
158         {0x29928086, CHIP_I965, 0x00020000,
159             "Intel Q965 SVGA controller"},
160         {0x29A28086, CHIP_I965, 0x00020000,
161             "Intel G965 SVGA controller"},
162         {0x29B28086, CHIP_G33, 0x00020000,
163             "Intel Q35 SVGA controller"},
164         {0x29C28086, CHIP_G33, 0x00020000,
165             "Intel G33 SVGA controller"},
166         {0x29D28086, CHIP_G33, 0x00020000,
167             "Intel Q33 SVGA controller"},
168         {0x2A028086, CHIP_I965, 0x00020000,
169             "Intel GM965 SVGA controller"},
170         {0x2A128086, CHIP_I965, 0x00020000,
171             "Intel GME965 SVGA controller"},
172         {0x2A428086, CHIP_G4X, 0x00020000,
173             "Intel GM45 SVGA controller"},
174         {0x2E028086, CHIP_G4X, 0x00020000,
175             "Intel 4 Series SVGA controller"},
176         {0x2E328086, CHIP_G4X, 0x00020000,
177             "Intel 4 Series SVGA controller"},
178         {0x2E128086, CHIP_G4X, 0x00020000,
179             "Intel Q45 SVGA controller"},
180         {0x2E228086, CHIP_G4X, 0x00020000,
181             "Intel G45 SVGA controller"},
182         {0, 0, 0, NULL}
183 };
184
185 static const struct agp_i810_match*
186 agp_i810_match(device_t dev)
187 {
188         int i, devid;
189
190         if (pci_get_class(dev) != PCIC_DISPLAY
191             || pci_get_subclass(dev) != PCIS_DISPLAY_VGA)
192                 return NULL;
193
194         devid = pci_get_devid(dev);
195         for (i = 0; agp_i810_matches[i].devid != 0; i++) {
196                 if (agp_i810_matches[i].devid == devid)
197                     break;
198         }
199         if (agp_i810_matches[i].devid == 0)
200                 return NULL;
201         else
202                 return &agp_i810_matches[i];
203 }
204
205 /*
206  * Find bridge device.
207  */
208 static device_t
209 agp_i810_find_bridge(device_t dev)
210 {
211         device_t *children, child;
212         int nchildren, i;
213         u_int32_t devid;
214         const struct agp_i810_match *match;
215   
216         match = agp_i810_match(dev);
217         devid = match->devid - match->bridge_offset;
218
219         if (device_get_children(device_get_parent(dev), &children, &nchildren))
220                 return 0;
221
222         for (i = 0; i < nchildren; i++) {
223                 child = children[i];
224
225                 if (pci_get_devid(child) == devid) {
226                         kfree(children, M_TEMP);
227                         return child;
228                 }
229         }
230         kfree(children, M_TEMP);
231         return 0;
232 }
233
234 static void
235 agp_i810_identify(driver_t *driver, device_t parent)
236 {
237
238         if (device_find_child(parent, "agp", -1) == NULL &&
239             agp_i810_match(parent))
240                 device_add_child(parent, "agp", -1);
241 }
242
243 static int
244 agp_i810_probe(device_t dev)
245 {
246         device_t bdev;
247         const struct agp_i810_match *match;
248         u_int8_t smram;
249         int gcc1, deven;
250
251         if (resource_disabled("agp", device_get_unit(dev)))
252                 return (ENXIO);
253         match = agp_i810_match(dev);
254         if (match == NULL)
255                 return ENXIO;
256
257         bdev = agp_i810_find_bridge(dev);
258         if (!bdev) {
259                 if (bootverbose)
260                         kprintf("I810: can't find bridge device\n");
261                 return ENXIO;
262         }
263
264         /*
265          * checking whether internal graphics device has been activated.
266          */
267         switch (match->chiptype) {
268         case CHIP_I810:
269                 smram = pci_read_config(bdev, AGP_I810_SMRAM, 1);
270                 if ((smram & AGP_I810_SMRAM_GMS) ==
271                     AGP_I810_SMRAM_GMS_DISABLED) {
272                         if (bootverbose)
273                                 kprintf("I810: disabled, not probing\n");
274                         return ENXIO;
275                 }
276                 break;
277         case CHIP_I830:
278         case CHIP_I855:
279                 gcc1 = pci_read_config(bdev, AGP_I830_GCC1, 1);
280                 if ((gcc1 & AGP_I830_GCC1_DEV2) ==
281                     AGP_I830_GCC1_DEV2_DISABLED) {
282                         if (bootverbose)
283                                 kprintf("I830: disabled, not probing\n");
284                         return ENXIO;
285                 }
286                 break;
287         case CHIP_I915:
288         case CHIP_I965:
289         case CHIP_G33:
290         case CHIP_G4X:
291                 deven = pci_read_config(bdev, AGP_I915_DEVEN, 4);
292                 if ((deven & AGP_I915_DEVEN_D2F0) ==
293                     AGP_I915_DEVEN_D2F0_DISABLED) {
294                         if (bootverbose)
295                                 kprintf("I915: disabled, not probing\n");
296                         return ENXIO;
297                 }
298                 break;
299         }
300
301         device_verbose(dev);
302         if (match->devid == 0x35828086) {
303                 switch (pci_read_config(dev, AGP_I85X_CAPID, 1)) {
304                 case AGP_I855_GME:
305                         device_set_desc(dev,
306                             "Intel 82855GME (855GME GMCH) SVGA controller");
307                         break;
308                 case AGP_I855_GM:
309                         device_set_desc(dev,
310                             "Intel 82855GM (855GM GMCH) SVGA controller");
311                         break;
312                 case AGP_I852_GME:
313                         device_set_desc(dev,
314                             "Intel 82852GME (852GME GMCH) SVGA controller");
315                         break;
316                 case AGP_I852_GM:
317                         device_set_desc(dev,
318                             "Intel 82852GM (852GM GMCH) SVGA controller");
319                         break;
320                 default:
321                         device_set_desc(dev,
322                             "Intel 8285xM (85xGM GMCH) SVGA controller");
323                         break;
324                 }
325         } else {
326                 device_set_desc(dev, match->name);
327         }
328
329         return BUS_PROBE_DEFAULT;
330 }
331
332 static void
333 agp_i810_dump_regs(device_t dev)
334 {
335         struct agp_i810_softc *sc = device_get_softc(dev);
336
337         device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
338             bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
339
340         switch (sc->chiptype) {
341         case CHIP_I810:
342                 device_printf(dev, "AGP_I810_MISCC: 0x%04x\n",
343                     pci_read_config(sc->bdev, AGP_I810_MISCC, 2));
344                 break;
345         case CHIP_I830:
346                 device_printf(dev, "AGP_I830_GCC1: 0x%02x\n",
347                     pci_read_config(sc->bdev, AGP_I830_GCC1, 1));
348                 break;
349         case CHIP_I855:
350                 device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
351                     pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
352                 break;
353         case CHIP_I915:
354         case CHIP_I965:
355         case CHIP_G33:
356         case CHIP_G4X:
357                 device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
358                     pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
359                 device_printf(dev, "AGP_I915_MSAC: 0x%02x\n",
360                     pci_read_config(sc->bdev, AGP_I915_MSAC, 1));
361                 break;
362         }
363         device_printf(dev, "Aperture resource size: %d bytes\n",
364             AGP_GET_APERTURE(dev));
365 }
366
367 static int
368 agp_i810_attach(device_t dev)
369 {
370         struct agp_i810_softc *sc = device_get_softc(dev);
371         struct agp_gatt *gatt;
372         const struct agp_i810_match *match;
373         int error;
374
375         sc->bdev = agp_i810_find_bridge(dev);
376         if (!sc->bdev)
377                 return ENOENT;
378
379         match = agp_i810_match(dev);
380         sc->chiptype = match->chiptype;
381
382         switch (sc->chiptype) {
383         case CHIP_I810:
384         case CHIP_I830:
385         case CHIP_I855:
386                 sc->sc_res_spec = agp_i810_res_spec;
387                 agp_set_aperture_resource(dev, AGP_APBASE);
388                 break;
389         case CHIP_I915:
390         case CHIP_G33:
391                 sc->sc_res_spec = agp_i915_res_spec;
392                 agp_set_aperture_resource(dev, AGP_I915_GMADR);
393                 break;
394         case CHIP_I965:
395         case CHIP_G4X:
396                 sc->sc_res_spec = agp_i965_res_spec;
397                 agp_set_aperture_resource(dev, AGP_I915_GMADR);
398                 break;
399         }
400
401         error = agp_generic_attach(dev);
402         if (error)
403                 return error;
404
405         if (sc->chiptype != CHIP_I965 && sc->chiptype != CHIP_G33 &&
406             sc->chiptype != CHIP_G4X && ptoa((vm_paddr_t)Maxmem) > 0xfffffffful)
407         {
408                 device_printf(dev, "agp_i810.c does not support physical "
409                     "memory above 4GB.\n");
410                 return ENOENT;
411         }
412
413         if (bus_alloc_resources(dev, sc->sc_res_spec, sc->sc_res)) {
414                 agp_generic_detach(dev);
415                 return ENODEV;
416         }
417
418         sc->initial_aperture = AGP_GET_APERTURE(dev);
419         if (sc->initial_aperture == 0) {
420                 device_printf(dev, "bad initial aperture size, disabling\n");
421                 return ENXIO;
422         }
423
424         gatt = kmalloc( sizeof(struct agp_gatt), M_AGP, M_INTWAIT);
425         sc->gatt = gatt;
426
427         gatt->ag_entries = AGP_GET_APERTURE(dev) >> AGP_PAGE_SHIFT;
428
429         if ( sc->chiptype == CHIP_I810 ) {
430                 /* Some i810s have on-chip memory called dcache */
431                 if (bus_read_1(sc->sc_res[0], AGP_I810_DRT) &
432                     AGP_I810_DRT_POPULATED)
433                         sc->dcache_size = 4 * 1024 * 1024;
434                 else
435                         sc->dcache_size = 0;
436
437                 /* According to the specs the gatt on the i810 must be 64k */
438                 gatt->ag_virtual = contigmalloc( 64 * 1024, M_AGP, 0, 
439                                         0, ~0, PAGE_SIZE, 0);
440                 if (!gatt->ag_virtual) {
441                         if (bootverbose)
442                                 device_printf(dev, "contiguous allocation failed\n");
443                         bus_release_resources(dev, sc->sc_res_spec,
444                             sc->sc_res);
445                         kfree(gatt, M_AGP);
446                         agp_generic_detach(dev);
447                         return ENOMEM;
448                 }
449                 bzero(gatt->ag_virtual, gatt->ag_entries * sizeof(u_int32_t));
450         
451                 gatt->ag_physical = vtophys((vm_offset_t) gatt->ag_virtual);
452                 agp_flush_cache();
453                 /* Install the GATT. */
454                 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL,
455                     gatt->ag_physical | 1);
456         } else if ( sc->chiptype == CHIP_I830 ) {
457                 /* The i830 automatically initializes the 128k gatt on boot. */
458                 unsigned int gcc1, pgtblctl;
459                 
460                 gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 1);
461                 switch (gcc1 & AGP_I830_GCC1_GMS) {
462                         case AGP_I830_GCC1_GMS_STOLEN_512:
463                                 sc->stolen = (512 - 132) * 1024 / 4096;
464                                 break;
465                         case AGP_I830_GCC1_GMS_STOLEN_1024: 
466                                 sc->stolen = (1024 - 132) * 1024 / 4096;
467                                 break;
468                         case AGP_I830_GCC1_GMS_STOLEN_8192: 
469                                 sc->stolen = (8192 - 132) * 1024 / 4096;
470                                 break;
471                         default:
472                                 sc->stolen = 0;
473                                 device_printf(dev, "unknown memory configuration, disabling\n");
474                                 bus_release_resources(dev, sc->sc_res_spec,
475                                     sc->sc_res);
476                                 kfree(gatt, M_AGP);
477                                 agp_generic_detach(dev);
478                                 return EINVAL;
479                 }
480                 if (sc->stolen > 0) {
481                         device_printf(dev, "detected %dk stolen memory\n",
482                             sc->stolen * 4);
483                 }
484                 device_printf(dev, "aperture size is %dM\n",
485                     sc->initial_aperture / 1024 / 1024);
486
487                 /* GATT address is already in there, make sure it's enabled */
488                 pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
489                 pgtblctl |= 1;
490                 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
491
492                 gatt->ag_physical = pgtblctl & ~1;
493         } else if (sc->chiptype == CHIP_I855 || sc->chiptype == CHIP_I915 ||
494             sc->chiptype == CHIP_I965 || sc->chiptype == CHIP_G33 ||
495             sc->chiptype == CHIP_G4X) {
496                 unsigned int gcc1, pgtblctl, stolen, gtt_size;
497
498                 /* Stolen memory is set up at the beginning of the aperture by
499                  * the BIOS, consisting of the GATT followed by 4kb for the
500                  * BIOS display.
501                  */
502                 switch (sc->chiptype) {
503                 case CHIP_I855:
504                         gtt_size = 128;
505                         break;
506                 case CHIP_I915:
507                         gtt_size = 256;
508                         break;
509                 case CHIP_I965:
510                         switch (bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL) &
511                             AGP_I810_PGTBL_SIZE_MASK) {
512                         case AGP_I810_PGTBL_SIZE_128KB:
513                                 gtt_size = 128;
514                                 break;
515                         case AGP_I810_PGTBL_SIZE_256KB:
516                                 gtt_size = 256;
517                                 break;
518                         case AGP_I810_PGTBL_SIZE_512KB:
519                                 gtt_size = 512;
520                                 break;
521                         case AGP_I965_PGTBL_SIZE_1MB:
522                                 gtt_size = 1024;
523                                 break;
524                         case AGP_I965_PGTBL_SIZE_2MB:
525                                 gtt_size = 2048;
526                                 break;
527                         case AGP_I965_PGTBL_SIZE_1_5MB:
528                                 gtt_size = 1024 + 512;
529                                 break;
530                         default:
531                                 device_printf(dev, "Bad PGTBL size\n");
532                                 bus_release_resources(dev, sc->sc_res_spec,
533                                     sc->sc_res);
534                                 kfree(gatt, M_AGP);
535                                 agp_generic_detach(dev);
536                                 return EINVAL;
537                         }
538                         break;
539                 case CHIP_G33:
540                         gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 2);
541                         switch (gcc1 & AGP_G33_MGGC_GGMS_MASK) {
542                         case AGP_G33_MGGC_GGMS_SIZE_1M:
543                                 gtt_size = 1024;
544                                 break;
545                         case AGP_G33_MGGC_GGMS_SIZE_2M:
546                                 gtt_size = 2048;
547                                 break;
548                         default:
549                                 device_printf(dev, "Bad PGTBL size\n");
550                                 bus_release_resources(dev, sc->sc_res_spec,
551                                     sc->sc_res);
552                                 kfree(gatt, M_AGP);
553                                 agp_generic_detach(dev);
554                                 return EINVAL;
555                         }
556                         break;
557                 case CHIP_G4X:
558                         gtt_size = 0;
559                         break;
560                 default:
561                         device_printf(dev, "Bad chiptype\n");
562                         bus_release_resources(dev, sc->sc_res_spec,
563                             sc->sc_res);
564                         kfree(gatt, M_AGP);
565                         agp_generic_detach(dev);
566                         return EINVAL;
567                 }
568
569                 /* GCC1 is called MGGC on i915+ */
570                 gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1);
571                 switch (gcc1 & AGP_I855_GCC1_GMS) {
572                 case AGP_I855_GCC1_GMS_STOLEN_1M:
573                         stolen = 1024;
574                         break;
575                 case AGP_I855_GCC1_GMS_STOLEN_4M:
576                         stolen = 4 * 1024;
577                         break;
578                 case AGP_I855_GCC1_GMS_STOLEN_8M:
579                         stolen = 8 * 1024;
580                         break;
581                 case AGP_I855_GCC1_GMS_STOLEN_16M:
582                         stolen = 16 * 1024;
583                         break;
584                 case AGP_I855_GCC1_GMS_STOLEN_32M:
585                         stolen = 32 * 1024;
586                         break;
587                 case AGP_I915_GCC1_GMS_STOLEN_48M:
588                         if (sc->chiptype == CHIP_I915 ||
589                             sc->chiptype == CHIP_I965 ||
590                             sc->chiptype == CHIP_G33 ||
591                             sc->chiptype == CHIP_G4X) {
592                                 stolen = 48 * 1024;
593                         } else {
594                                 stolen = 0;
595                         }
596                         break;
597                 case AGP_I915_GCC1_GMS_STOLEN_64M:
598                         if (sc->chiptype == CHIP_I915 ||
599                             sc->chiptype == CHIP_I965 ||
600                             sc->chiptype == CHIP_G33 ||
601                             sc->chiptype == CHIP_G4X) {
602                                 stolen = 64 * 1024;
603                         } else {
604                                 stolen = 0;
605                         }
606                         break;
607                 case AGP_G33_GCC1_GMS_STOLEN_128M:
608                         if (sc->chiptype == CHIP_I965 ||
609                             sc->chiptype == CHIP_G33 ||
610                             sc->chiptype == CHIP_G4X) {
611                                 stolen = 128 * 1024;
612                         } else {
613                                 stolen = 0;
614                         }
615                         break;
616                 case AGP_G33_GCC1_GMS_STOLEN_256M:
617                         if (sc->chiptype == CHIP_I965 ||
618                             sc->chiptype == CHIP_G33 ||
619                             sc->chiptype == CHIP_G4X) {
620                                 stolen = 256 * 1024;
621                         } else {
622                                 stolen = 0;
623                         }
624                         break;
625                 case AGP_G4X_GCC1_GMS_STOLEN_96M:
626                         if (sc->chiptype == CHIP_I965 ||
627                             sc->chiptype == CHIP_G4X) {
628                                 stolen = 96 * 1024;
629                         } else {
630                                 stolen = 0;
631                         }
632                         break;
633                 case AGP_G4X_GCC1_GMS_STOLEN_160M:
634                         if (sc->chiptype == CHIP_I965 ||
635                             sc->chiptype == CHIP_G4X) {
636                                 stolen = 160 * 1024;
637                         } else {
638                                 stolen = 0;
639                         }
640                         break;
641                 case AGP_G4X_GCC1_GMS_STOLEN_224M:
642                         if (sc->chiptype == CHIP_I965 ||
643                             sc->chiptype == CHIP_G4X) {
644                                 stolen = 224 * 1024;
645                         } else {
646                                 stolen = 0;
647                         }
648                         break;
649                 case AGP_G4X_GCC1_GMS_STOLEN_352M:
650                         if (sc->chiptype == CHIP_I965 ||
651                             sc->chiptype == CHIP_G4X) {
652                                 stolen = 352 * 1024;
653                         } else {
654                                 stolen = 0;
655                         }
656                         break;
657                 default:
658                         device_printf(dev, "unknown memory configuration, "
659                             "disabling\n");
660                         bus_release_resources(dev, sc->sc_res_spec,
661                             sc->sc_res);
662                         kfree(gatt, M_AGP);
663                         agp_generic_detach(dev);
664                         return EINVAL;
665                 }
666
667                 gtt_size += 4;
668
669                 sc->stolen = (stolen - gtt_size) * 1024 / 4096;
670                 if (sc->stolen > 0)
671                         device_printf(dev, "detected %dk stolen memory\n", sc->stolen * 4);
672                 device_printf(dev, "aperture size is %dM\n", sc->initial_aperture / 1024 / 1024);
673
674                 /* GATT address is already in there, make sure it's enabled */
675                 pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
676                 pgtblctl |= 1;
677                 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
678
679                 gatt->ag_physical = pgtblctl & ~1;
680         }
681
682         /* Add a device for the drm to attach to */
683         /* XXX This will go away once we have vgapci */
684         if (!device_add_child(dev, "drmsub", -1))
685                 device_printf(dev, "could not add drm subdevice\n");
686
687         if (0)
688                 agp_i810_dump_regs(dev);
689
690         return 0;
691 }
692
693 static int
694 agp_i810_detach(device_t dev)
695 {
696         struct agp_i810_softc *sc = device_get_softc(dev);
697         device_t child;
698
699         agp_free_cdev(dev);
700
701         /* Clear the GATT base. */
702         if ( sc->chiptype == CHIP_I810 ) {
703                 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, 0);
704         } else {
705                 unsigned int pgtblctl;
706                 pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
707                 pgtblctl &= ~1;
708                 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
709         }
710
711         /* Put the aperture back the way it started. */
712         AGP_SET_APERTURE(dev, sc->initial_aperture);
713
714         if ( sc->chiptype == CHIP_I810 ) {
715                 contigfree(sc->gatt->ag_virtual, 64 * 1024, M_AGP);
716         }
717         kfree(sc->gatt, M_AGP);
718
719         bus_release_resources(dev, sc->sc_res_spec, sc->sc_res);
720         agp_free_res(dev);
721
722         /* XXX This will go away once we have vgapci */
723         child = device_find_child(dev, "drmsub", 0);
724         if (child != NULL)
725                 device_delete_child(dev, child);
726
727         return 0;
728 }
729
730 static int
731 agp_i810_resume(device_t dev)
732 {
733         struct agp_i810_softc *sc;
734         sc = device_get_softc(dev);
735
736         AGP_SET_APERTURE(dev, sc->initial_aperture);
737
738         /* Install the GATT. */
739         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL,
740         sc->gatt->ag_physical | 1);
741
742         return (bus_generic_resume(dev));
743 }
744
745 /**
746  * Sets the PCI resource size of the aperture on i830-class and below chipsets,
747  * while returning failure on later chipsets when an actual change is
748  * requested.
749  *
750  * This whole function is likely bogus, as the kernel would probably need to
751  * reconfigure the placement of the AGP aperture if a larger size is requested,
752  * which doesn't happen currently.
753  */
754 static int
755 agp_i810_set_aperture(device_t dev, u_int32_t aperture)
756 {
757         struct agp_i810_softc *sc = device_get_softc(dev);
758         u_int16_t miscc, gcc1;
759
760         switch (sc->chiptype) {
761         case CHIP_I810:
762                 /*
763                  * Double check for sanity.
764                  */
765                 if (aperture != 32 * 1024 * 1024 && aperture != 64 * 1024 * 1024) {
766                         device_printf(dev, "bad aperture size %d\n", aperture);
767                         return EINVAL;
768                 }
769
770                 miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2);
771                 miscc &= ~AGP_I810_MISCC_WINSIZE;
772                 if (aperture == 32 * 1024 * 1024)
773                         miscc |= AGP_I810_MISCC_WINSIZE_32;
774                 else
775                         miscc |= AGP_I810_MISCC_WINSIZE_64;
776         
777                 pci_write_config(sc->bdev, AGP_I810_MISCC, miscc, 2);
778                 break;
779         case CHIP_I830:
780                 if (aperture != 64 * 1024 * 1024 &&
781                     aperture != 128 * 1024 * 1024) {
782                         device_printf(dev, "bad aperture size %d\n", aperture);
783                         return EINVAL;
784                 }
785                 gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
786                 gcc1 &= ~AGP_I830_GCC1_GMASIZE;
787                 if (aperture == 64 * 1024 * 1024)
788                         gcc1 |= AGP_I830_GCC1_GMASIZE_64;
789                 else
790                         gcc1 |= AGP_I830_GCC1_GMASIZE_128;
791
792                 pci_write_config(sc->bdev, AGP_I830_GCC1, gcc1, 2);
793                 break;
794         case CHIP_I855:
795         case CHIP_I915:
796         case CHIP_I965:
797         case CHIP_G33:
798         case CHIP_G4X:
799                 return agp_generic_set_aperture(dev, aperture);
800         }
801
802         return 0;
803 }
804
805 /**
806  * Writes a GTT entry mapping the page at the given offset from the beginning
807  * of the aperture to the given physical address.
808  */
809 static void
810 agp_i810_write_gtt_entry(device_t dev, int offset, vm_offset_t physical,
811     int enabled)
812 {
813         struct agp_i810_softc *sc = device_get_softc(dev);
814         u_int32_t pte;
815
816         pte = (u_int32_t)physical | 1;
817         if (sc->chiptype == CHIP_I965 || sc->chiptype == CHIP_G33 ||
818             sc->chiptype == CHIP_G4X) {
819                 pte |= (physical & 0x0000000f00000000ull) >> 28;
820         } else {
821                 /* If we do actually have memory above 4GB on an older system,
822                  * crash cleanly rather than scribble on system memory,
823                  * so we know we need to fix it.
824                  */
825                 KASSERT((pte & 0x0000000f00000000ull) == 0,
826                     (">4GB physical address in agp"));
827         }
828
829         switch (sc->chiptype) {
830         case CHIP_I810:
831         case CHIP_I830:
832         case CHIP_I855:
833                 bus_write_4(sc->sc_res[0],
834                     AGP_I810_GTT + (offset >> AGP_PAGE_SHIFT) * 4, pte);
835                 break;
836         case CHIP_I915:
837         case CHIP_G33:
838                 bus_write_4(sc->sc_res[1],
839                     (offset >> AGP_PAGE_SHIFT) * 4, pte);
840                 break;
841         case CHIP_I965:
842                 bus_write_4(sc->sc_res[0],
843                     (offset >> AGP_PAGE_SHIFT) * 4 + (512 * 1024), pte);
844                 break;
845         case CHIP_G4X:
846                 bus_write_4(sc->sc_res[0],
847                     (offset >> AGP_PAGE_SHIFT) * 4 + (2 * 1024 * 1024), pte);
848                 break;
849         }
850 }
851
852 static int
853 agp_i810_bind_page(device_t dev, int offset, vm_offset_t physical)
854 {
855         struct agp_i810_softc *sc = device_get_softc(dev);
856
857         if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) {
858                 device_printf(dev, "failed: offset is 0x%08x, shift is %d, entries is %d\n", offset, AGP_PAGE_SHIFT, sc->gatt->ag_entries);
859                 return EINVAL;
860         }
861
862         if ( sc->chiptype != CHIP_I810 ) {
863                 if ( (offset >> AGP_PAGE_SHIFT) < sc->stolen ) {
864                         device_printf(dev, "trying to bind into stolen memory");
865                         return EINVAL;
866                 }
867         }
868
869         agp_i810_write_gtt_entry(dev, offset, physical, 1);
870
871         return 0;
872 }
873
874 static int
875 agp_i810_unbind_page(device_t dev, int offset)
876 {
877         struct agp_i810_softc *sc = device_get_softc(dev);
878
879         if (offset < 0 || offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
880                 return EINVAL;
881
882         if ( sc->chiptype != CHIP_I810 ) {
883                 if ( (offset >> AGP_PAGE_SHIFT) < sc->stolen ) {
884                         device_printf(dev, "trying to unbind from stolen memory");
885                         return EINVAL;
886                 }
887         }
888
889         agp_i810_write_gtt_entry(dev, offset, 0, 0);
890
891         return 0;
892 }
893
894 /*
895  * Writing via memory mapped registers already flushes all TLBs.
896  */
897 static void
898 agp_i810_flush_tlb(device_t dev)
899 {
900 }
901
902 static int
903 agp_i810_enable(device_t dev, u_int32_t mode)
904 {
905
906         return 0;
907 }
908
909 static struct agp_memory *
910 agp_i810_alloc_memory(device_t dev, int type, vm_size_t size)
911 {
912         struct agp_i810_softc *sc = device_get_softc(dev);
913         struct agp_memory *mem;
914
915         if ((size & (AGP_PAGE_SIZE - 1)) != 0)
916                 return 0;
917
918         if (sc->agp.as_allocated + size > sc->agp.as_maxmem)
919                 return 0;
920
921         if (type == 1) {
922                 /*
923                  * Mapping local DRAM into GATT.
924                  */
925                 if ( sc->chiptype != CHIP_I810 )
926                         return 0;
927                 if (size != sc->dcache_size)
928                         return 0;
929         } else if (type == 2) {
930                 /*
931                  * Type 2 is the contiguous physical memory type, that hands
932                  * back a physical address.  This is used for cursors on i810.
933                  * Hand back as many single pages with physical as the user
934                  * wants, but only allow one larger allocation (ARGB cursor)
935                  * for simplicity.
936                  */
937                 if (size != AGP_PAGE_SIZE) {
938                         if (sc->argb_cursor != NULL)
939                                 return 0;
940
941                         /* Allocate memory for ARGB cursor, if we can. */
942                         sc->argb_cursor = contigmalloc(size, M_AGP,
943                            0, 0, ~0, PAGE_SIZE, 0);
944                         if (sc->argb_cursor == NULL)
945                                 return 0;
946                 }
947         }
948
949         mem = kmalloc(sizeof *mem, M_AGP, M_INTWAIT);
950         mem->am_id = sc->agp.as_nextid++;
951         mem->am_size = size;
952         mem->am_type = type;
953         if (type != 1 && (type != 2 || size == AGP_PAGE_SIZE))
954                 mem->am_obj = vm_object_allocate(OBJT_DEFAULT,
955                                                  atop(round_page(size)));
956         else
957                 mem->am_obj = 0;
958
959         if (type == 2) {
960                 if (size == AGP_PAGE_SIZE) {
961                         /*
962                          * Allocate and wire down the page now so that we can
963                          * get its physical address.
964                          */
965                         vm_page_t m;
966         
967                         m = vm_page_grab(mem->am_obj, 0, 
968                                          VM_ALLOC_NORMAL|VM_ALLOC_ZERO|VM_ALLOC_RETRY);
969                         if ((m->flags & PG_ZERO) == 0)
970                                 vm_page_zero_fill(m);
971                         vm_page_wire(m);
972                         mem->am_physical = VM_PAGE_TO_PHYS(m);
973                         vm_page_wakeup(m);
974                 } else {
975                         /* Our allocation is already nicely wired down for us.
976                          * Just grab the physical address.
977                          */
978                         mem->am_physical = vtophys(sc->argb_cursor);
979                 }
980         } else {
981                 mem->am_physical = 0;
982         }
983
984         mem->am_offset = 0;
985         mem->am_is_bound = 0;
986         TAILQ_INSERT_TAIL(&sc->agp.as_memory, mem, am_link);
987         sc->agp.as_allocated += size;
988
989         return mem;
990 }
991
992 static int
993 agp_i810_free_memory(device_t dev, struct agp_memory *mem)
994 {
995         struct agp_i810_softc *sc = device_get_softc(dev);
996
997         if (mem->am_is_bound)
998                 return EBUSY;
999
1000         if (mem->am_type == 2) {
1001                 if (mem->am_size == AGP_PAGE_SIZE) {
1002                         /*
1003                          * Unwire the page which we wired in alloc_memory.
1004                          */
1005                         vm_page_t m = vm_page_lookup(mem->am_obj, 0);
1006                         vm_page_unwire(m, 0);
1007                 } else {
1008                         contigfree(sc->argb_cursor, mem->am_size, M_AGP);
1009                         sc->argb_cursor = NULL;
1010                 }
1011         }
1012
1013         sc->agp.as_allocated -= mem->am_size;
1014         TAILQ_REMOVE(&sc->agp.as_memory, mem, am_link);
1015         if (mem->am_obj)
1016                 vm_object_deallocate(mem->am_obj);
1017         kfree(mem, M_AGP);
1018         return 0;
1019 }
1020
1021 static int
1022 agp_i810_bind_memory(device_t dev, struct agp_memory *mem,
1023                      vm_offset_t offset)
1024 {
1025         struct agp_i810_softc *sc = device_get_softc(dev);
1026         vm_offset_t i;
1027
1028         /* Do some sanity checks first. */
1029         if (offset < 0 || (offset & (AGP_PAGE_SIZE - 1)) != 0 ||
1030             offset + mem->am_size > AGP_GET_APERTURE(dev)) {
1031                 device_printf(dev, "binding memory at bad offset %#x\n",
1032                     (int)offset);
1033                 return EINVAL;
1034         }
1035
1036         if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
1037                 lockmgr(&sc->agp.as_lock, LK_EXCLUSIVE);
1038                 if (mem->am_is_bound) {
1039                         lockmgr(&sc->agp.as_lock, LK_RELEASE);
1040                         return EINVAL;
1041                 }
1042                 /* The memory's already wired down, just stick it in the GTT. */
1043                 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
1044                         agp_i810_write_gtt_entry(dev, offset + i,
1045                             mem->am_physical + i, 1);
1046                 }
1047                 agp_flush_cache();
1048                 mem->am_offset = offset;
1049                 mem->am_is_bound = 1;
1050                 lockmgr(&sc->agp.as_lock, LK_RELEASE);
1051                 return 0;
1052         }
1053
1054         if (mem->am_type != 1)
1055                 return agp_generic_bind_memory(dev, mem, offset);
1056
1057         if ( sc->chiptype != CHIP_I810 )
1058                 return EINVAL;
1059
1060         for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
1061                 bus_write_4(sc->sc_res[0],
1062                     AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, i | 3);
1063         }
1064
1065         return 0;
1066 }
1067
1068 static int
1069 agp_i810_unbind_memory(device_t dev, struct agp_memory *mem)
1070 {
1071         struct agp_i810_softc *sc = device_get_softc(dev);
1072         vm_offset_t i;
1073
1074         if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
1075                 lockmgr(&sc->agp.as_lock, LK_EXCLUSIVE);
1076                 if (!mem->am_is_bound) {
1077                         lockmgr(&sc->agp.as_lock, LK_RELEASE);
1078                         return EINVAL;
1079                 }
1080
1081                 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
1082                         agp_i810_write_gtt_entry(dev, mem->am_offset + i,
1083                             0, 0);
1084                 }
1085                 agp_flush_cache();
1086                 mem->am_is_bound = 0;
1087                 lockmgr(&sc->agp.as_lock, LK_RELEASE);
1088                 return 0;
1089         }
1090
1091         if (mem->am_type != 1)
1092                 return agp_generic_unbind_memory(dev, mem);
1093
1094         if ( sc->chiptype != CHIP_I810 )
1095                 return EINVAL;
1096
1097         for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
1098                 bus_write_4(sc->sc_res[0],
1099                     AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, 0);
1100         }
1101
1102         return 0;
1103 }
1104
1105 static device_method_t agp_i810_methods[] = {
1106         /* Device interface */
1107         DEVMETHOD(device_identify,      agp_i810_identify),
1108         DEVMETHOD(device_probe,         agp_i810_probe),
1109         DEVMETHOD(device_attach,        agp_i810_attach),
1110         DEVMETHOD(device_detach,        agp_i810_detach),
1111         DEVMETHOD(device_suspend,       bus_generic_suspend),
1112         DEVMETHOD(device_resume,        agp_i810_resume),
1113
1114         /* AGP interface */
1115         DEVMETHOD(agp_get_aperture,     agp_generic_get_aperture),
1116         DEVMETHOD(agp_set_aperture,     agp_i810_set_aperture),
1117         DEVMETHOD(agp_bind_page,        agp_i810_bind_page),
1118         DEVMETHOD(agp_unbind_page,      agp_i810_unbind_page),
1119         DEVMETHOD(agp_flush_tlb,        agp_i810_flush_tlb),
1120         DEVMETHOD(agp_enable,           agp_i810_enable),
1121         DEVMETHOD(agp_alloc_memory,     agp_i810_alloc_memory),
1122         DEVMETHOD(agp_free_memory,      agp_i810_free_memory),
1123         DEVMETHOD(agp_bind_memory,      agp_i810_bind_memory),
1124         DEVMETHOD(agp_unbind_memory,    agp_i810_unbind_memory),
1125
1126         { 0, 0 }
1127 };
1128
1129 static driver_t agp_i810_driver = {
1130         "agp",
1131         agp_i810_methods,
1132         sizeof(struct agp_i810_softc),
1133 };
1134
1135 static devclass_t agp_devclass;
1136
1137 DRIVER_MODULE(agp_i810, pci, agp_i810_driver, agp_devclass, 0, 0);
1138 MODULE_DEPEND(agp_i810, agp, 1, 1, 1);
1139 MODULE_DEPEND(agp_i810, pci, 1, 1, 1);