The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/pci/agp_i810.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 79d39fc4f56f0d47ce526de865e8ddbb


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.