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/dev/agp/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  * Copyright (c) 2011 The FreeBSD Foundation
    5  * All rights reserved.
    6  *
    7  * Portions of this software were developed by Konstantin Belousov
    8  * under sponsorship from the FreeBSD Foundation.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  */
   31 
   32 /*
   33  * Fixes for 830/845G support: David Dawes <dawes@xfree86.org>
   34  * 852GM/855GM/865G support added by David Dawes <dawes@xfree86.org>
   35  *
   36  * This is generic Intel GTT handling code, morphed from the AGP
   37  * bridge code.
   38  */
   39 
   40 #include <sys/cdefs.h>
   41 __FBSDID("$FreeBSD: releng/10.1/sys/dev/agp/agp_i810.c 261455 2014-02-04 03:36:42Z eadler $");
   42 
   43 #if 0
   44 #define KTR_AGP_I810    KTR_DEV
   45 #else
   46 #define KTR_AGP_I810    0
   47 #endif
   48 
   49 #include <sys/param.h>
   50 #include <sys/systm.h>
   51 #include <sys/malloc.h>
   52 #include <sys/kernel.h>
   53 #include <sys/ktr.h>
   54 #include <sys/module.h>
   55 #include <sys/bus.h>
   56 #include <sys/lock.h>
   57 #include <sys/mutex.h>
   58 #include <sys/proc.h>
   59 #include <sys/rwlock.h>
   60 
   61 #include <dev/agp/agppriv.h>
   62 #include <dev/agp/agpreg.h>
   63 #include <dev/agp/agp_i810.h>
   64 #include <dev/pci/pcivar.h>
   65 #include <dev/pci/pcireg.h>
   66 #include <dev/pci/pci_private.h>
   67 
   68 #include <vm/vm.h>
   69 #include <vm/vm_param.h>
   70 #include <vm/vm_object.h>
   71 #include <vm/vm_page.h>
   72 #include <vm/vm_pageout.h>
   73 #include <vm/pmap.h>
   74 
   75 #include <machine/bus.h>
   76 #include <machine/resource.h>
   77 #include <machine/md_var.h>
   78 #include <sys/rman.h>
   79 
   80 MALLOC_DECLARE(M_AGP);
   81 
   82 struct agp_i810_match;
   83 
   84 static int agp_i810_check_active(device_t bridge_dev);
   85 static int agp_i830_check_active(device_t bridge_dev);
   86 static int agp_i915_check_active(device_t bridge_dev);
   87 static int agp_sb_check_active(device_t bridge_dev);
   88 
   89 static void agp_82852_set_desc(device_t dev,
   90     const struct agp_i810_match *match);
   91 static void agp_i810_set_desc(device_t dev, const struct agp_i810_match *match);
   92 
   93 static void agp_i810_dump_regs(device_t dev);
   94 static void agp_i830_dump_regs(device_t dev);
   95 static void agp_i855_dump_regs(device_t dev);
   96 static void agp_i915_dump_regs(device_t dev);
   97 static void agp_i965_dump_regs(device_t dev);
   98 static void agp_sb_dump_regs(device_t dev);
   99 
  100 static int agp_i810_get_stolen_size(device_t dev);
  101 static int agp_i830_get_stolen_size(device_t dev);
  102 static int agp_i915_get_stolen_size(device_t dev);
  103 static int agp_sb_get_stolen_size(device_t dev);
  104 
  105 static int agp_i810_get_gtt_mappable_entries(device_t dev);
  106 static int agp_i830_get_gtt_mappable_entries(device_t dev);
  107 static int agp_i915_get_gtt_mappable_entries(device_t dev);
  108 
  109 static int agp_i810_get_gtt_total_entries(device_t dev);
  110 static int agp_i965_get_gtt_total_entries(device_t dev);
  111 static int agp_gen5_get_gtt_total_entries(device_t dev);
  112 static int agp_sb_get_gtt_total_entries(device_t dev);
  113 
  114 static int agp_i810_install_gatt(device_t dev);
  115 static int agp_i830_install_gatt(device_t dev);
  116 
  117 static void agp_i810_deinstall_gatt(device_t dev);
  118 static void agp_i830_deinstall_gatt(device_t dev);
  119 
  120 static void agp_i810_install_gtt_pte(device_t dev, u_int index,
  121     vm_offset_t physical, int flags);
  122 static void agp_i830_install_gtt_pte(device_t dev, u_int index,
  123     vm_offset_t physical, int flags);
  124 static void agp_i915_install_gtt_pte(device_t dev, u_int index,
  125     vm_offset_t physical, int flags);
  126 static void agp_i965_install_gtt_pte(device_t dev, u_int index,
  127     vm_offset_t physical, int flags);
  128 static void agp_g4x_install_gtt_pte(device_t dev, u_int index,
  129     vm_offset_t physical, int flags);
  130 static void agp_sb_install_gtt_pte(device_t dev, u_int index,
  131     vm_offset_t physical, int flags);
  132 
  133 static void agp_i810_write_gtt(device_t dev, u_int index, uint32_t pte);
  134 static void agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte);
  135 static void agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte);
  136 static void agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte);
  137 static void agp_sb_write_gtt(device_t dev, u_int index, uint32_t pte);
  138 
  139 static u_int32_t agp_i810_read_gtt_pte(device_t dev, u_int index);
  140 static u_int32_t agp_i915_read_gtt_pte(device_t dev, u_int index);
  141 static u_int32_t agp_i965_read_gtt_pte(device_t dev, u_int index);
  142 static u_int32_t agp_g4x_read_gtt_pte(device_t dev, u_int index);
  143 
  144 static vm_paddr_t agp_i810_read_gtt_pte_paddr(device_t dev, u_int index);
  145 static vm_paddr_t agp_i915_read_gtt_pte_paddr(device_t dev, u_int index);
  146 static vm_paddr_t agp_sb_read_gtt_pte_paddr(device_t dev, u_int index);
  147 
  148 static int agp_i810_set_aperture(device_t dev, u_int32_t aperture);
  149 static int agp_i830_set_aperture(device_t dev, u_int32_t aperture);
  150 static int agp_i915_set_aperture(device_t dev, u_int32_t aperture);
  151 
  152 static int agp_i810_chipset_flush_setup(device_t dev);
  153 static int agp_i915_chipset_flush_setup(device_t dev);
  154 static int agp_i965_chipset_flush_setup(device_t dev);
  155 
  156 static void agp_i810_chipset_flush_teardown(device_t dev);
  157 static void agp_i915_chipset_flush_teardown(device_t dev);
  158 static void agp_i965_chipset_flush_teardown(device_t dev);
  159 
  160 static void agp_i810_chipset_flush(device_t dev);
  161 static void agp_i830_chipset_flush(device_t dev);
  162 static void agp_i915_chipset_flush(device_t dev);
  163 
  164 enum {
  165         CHIP_I810,      /* i810/i815 */
  166         CHIP_I830,      /* 830M/845G */
  167         CHIP_I855,      /* 852GM/855GM/865G */
  168         CHIP_I915,      /* 915G/915GM */
  169         CHIP_I965,      /* G965 */
  170         CHIP_G33,       /* G33/Q33/Q35 */
  171         CHIP_IGD,       /* Pineview */
  172         CHIP_G4X,       /* G45/Q45 */
  173         CHIP_SB,        /* SandyBridge */
  174 };
  175 
  176 /* The i810 through i855 have the registers at BAR 1, and the GATT gets
  177  * allocated by us.  The i915 has registers in BAR 0 and the GATT is at the
  178  * start of the stolen memory, and should only be accessed by the OS through
  179  * BAR 3.  The G965 has registers and GATT in the same BAR (0) -- first 512KB
  180  * is registers, second 512KB is GATT.
  181  */
  182 static struct resource_spec agp_i810_res_spec[] = {
  183         { SYS_RES_MEMORY, AGP_I810_MMADR, RF_ACTIVE | RF_SHAREABLE },
  184         { -1, 0 }
  185 };
  186 
  187 static struct resource_spec agp_i915_res_spec[] = {
  188         { SYS_RES_MEMORY, AGP_I915_MMADR, RF_ACTIVE | RF_SHAREABLE },
  189         { SYS_RES_MEMORY, AGP_I915_GTTADR, RF_ACTIVE | RF_SHAREABLE },
  190         { -1, 0 }
  191 };
  192 
  193 static struct resource_spec agp_i965_res_spec[] = {
  194         { SYS_RES_MEMORY, AGP_I965_GTTMMADR, RF_ACTIVE | RF_SHAREABLE },
  195         { -1, 0 }
  196 };
  197 
  198 static struct resource_spec agp_g4x_res_spec[] = {
  199         { SYS_RES_MEMORY, AGP_G4X_MMADR, RF_ACTIVE | RF_SHAREABLE },
  200         { SYS_RES_MEMORY, AGP_G4X_GTTADR, RF_ACTIVE | RF_SHAREABLE },
  201         { -1, 0 }
  202 };
  203 
  204 struct agp_i810_softc {
  205         struct agp_softc agp;
  206         u_int32_t initial_aperture;     /* aperture size at startup */
  207         struct agp_gatt *gatt;
  208         u_int32_t dcache_size;          /* i810 only */
  209         u_int32_t stolen;               /* number of i830/845 gtt
  210                                            entries for stolen memory */
  211         u_int stolen_size;              /* BIOS-reserved graphics memory */
  212         u_int gtt_total_entries;        /* Total number of gtt ptes */
  213         u_int gtt_mappable_entries;     /* Number of gtt ptes mappable by CPU */
  214         device_t bdev;                  /* bridge device */
  215         void *argb_cursor;              /* contigmalloc area for ARGB cursor */
  216         struct resource *sc_res[2];
  217         const struct agp_i810_match *match;
  218         int sc_flush_page_rid;
  219         struct resource *sc_flush_page_res;
  220         void *sc_flush_page_vaddr;
  221         int sc_bios_allocated_flush_page;
  222 };
  223 
  224 static device_t intel_agp;
  225 
  226 struct agp_i810_driver {
  227         int chiptype;
  228         int gen;
  229         int busdma_addr_mask_sz;
  230         struct resource_spec *res_spec;
  231         int (*check_active)(device_t);
  232         void (*set_desc)(device_t, const struct agp_i810_match *);
  233         void (*dump_regs)(device_t);
  234         int (*get_stolen_size)(device_t);
  235         int (*get_gtt_total_entries)(device_t);
  236         int (*get_gtt_mappable_entries)(device_t);
  237         int (*install_gatt)(device_t);
  238         void (*deinstall_gatt)(device_t);
  239         void (*write_gtt)(device_t, u_int, uint32_t);
  240         void (*install_gtt_pte)(device_t, u_int, vm_offset_t, int);
  241         u_int32_t (*read_gtt_pte)(device_t, u_int);
  242         vm_paddr_t (*read_gtt_pte_paddr)(device_t , u_int);
  243         int (*set_aperture)(device_t, u_int32_t);
  244         int (*chipset_flush_setup)(device_t);
  245         void (*chipset_flush_teardown)(device_t);
  246         void (*chipset_flush)(device_t);
  247 };
  248 
  249 static const struct agp_i810_driver agp_i810_i810_driver = {
  250         .chiptype = CHIP_I810,
  251         .gen = 1,
  252         .busdma_addr_mask_sz = 32,
  253         .res_spec = agp_i810_res_spec,
  254         .check_active = agp_i810_check_active,
  255         .set_desc = agp_i810_set_desc,
  256         .dump_regs = agp_i810_dump_regs,
  257         .get_stolen_size = agp_i810_get_stolen_size,
  258         .get_gtt_mappable_entries = agp_i810_get_gtt_mappable_entries,
  259         .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
  260         .install_gatt = agp_i810_install_gatt,
  261         .deinstall_gatt = agp_i810_deinstall_gatt,
  262         .write_gtt = agp_i810_write_gtt,
  263         .install_gtt_pte = agp_i810_install_gtt_pte,
  264         .read_gtt_pte = agp_i810_read_gtt_pte,
  265         .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
  266         .set_aperture = agp_i810_set_aperture,
  267         .chipset_flush_setup = agp_i810_chipset_flush_setup,
  268         .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
  269         .chipset_flush = agp_i810_chipset_flush,
  270 };
  271 
  272 static const struct agp_i810_driver agp_i810_i815_driver = {
  273         .chiptype = CHIP_I810,
  274         .gen = 2,
  275         .busdma_addr_mask_sz = 32,
  276         .res_spec = agp_i810_res_spec,
  277         .check_active = agp_i810_check_active,
  278         .set_desc = agp_i810_set_desc,
  279         .dump_regs = agp_i810_dump_regs,
  280         .get_stolen_size = agp_i810_get_stolen_size,
  281         .get_gtt_mappable_entries = agp_i830_get_gtt_mappable_entries,
  282         .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
  283         .install_gatt = agp_i810_install_gatt,
  284         .deinstall_gatt = agp_i810_deinstall_gatt,
  285         .write_gtt = agp_i810_write_gtt,
  286         .install_gtt_pte = agp_i810_install_gtt_pte,
  287         .read_gtt_pte = agp_i810_read_gtt_pte,
  288         .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
  289         .set_aperture = agp_i810_set_aperture,
  290         .chipset_flush_setup = agp_i810_chipset_flush_setup,
  291         .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
  292         .chipset_flush = agp_i830_chipset_flush,
  293 };
  294 
  295 static const struct agp_i810_driver agp_i810_i830_driver = {
  296         .chiptype = CHIP_I830,
  297         .gen = 2,
  298         .busdma_addr_mask_sz = 32,
  299         .res_spec = agp_i810_res_spec,
  300         .check_active = agp_i830_check_active,
  301         .set_desc = agp_i810_set_desc,
  302         .dump_regs = agp_i830_dump_regs,
  303         .get_stolen_size = agp_i830_get_stolen_size,
  304         .get_gtt_mappable_entries = agp_i830_get_gtt_mappable_entries,
  305         .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
  306         .install_gatt = agp_i830_install_gatt,
  307         .deinstall_gatt = agp_i830_deinstall_gatt,
  308         .write_gtt = agp_i810_write_gtt,
  309         .install_gtt_pte = agp_i830_install_gtt_pte,
  310         .read_gtt_pte = agp_i810_read_gtt_pte,
  311         .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
  312         .set_aperture = agp_i830_set_aperture,
  313         .chipset_flush_setup = agp_i810_chipset_flush_setup,
  314         .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
  315         .chipset_flush = agp_i830_chipset_flush,
  316 };
  317 
  318 static const struct agp_i810_driver agp_i810_i855_driver = {
  319         .chiptype = CHIP_I855,
  320         .gen = 2,
  321         .busdma_addr_mask_sz = 32,
  322         .res_spec = agp_i810_res_spec,
  323         .check_active = agp_i830_check_active,
  324         .set_desc = agp_82852_set_desc,
  325         .dump_regs = agp_i855_dump_regs,
  326         .get_stolen_size = agp_i915_get_stolen_size,
  327         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  328         .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
  329         .install_gatt = agp_i830_install_gatt,
  330         .deinstall_gatt = agp_i830_deinstall_gatt,
  331         .write_gtt = agp_i810_write_gtt,
  332         .install_gtt_pte = agp_i830_install_gtt_pte,
  333         .read_gtt_pte = agp_i810_read_gtt_pte,
  334         .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
  335         .set_aperture = agp_i830_set_aperture,
  336         .chipset_flush_setup = agp_i810_chipset_flush_setup,
  337         .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
  338         .chipset_flush = agp_i830_chipset_flush,
  339 };
  340 
  341 static const struct agp_i810_driver agp_i810_i865_driver = {
  342         .chiptype = CHIP_I855,
  343         .gen = 2,
  344         .busdma_addr_mask_sz = 32,
  345         .res_spec = agp_i810_res_spec,
  346         .check_active = agp_i830_check_active,
  347         .set_desc = agp_i810_set_desc,
  348         .dump_regs = agp_i855_dump_regs,
  349         .get_stolen_size = agp_i915_get_stolen_size,
  350         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  351         .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
  352         .install_gatt = agp_i830_install_gatt,
  353         .deinstall_gatt = agp_i830_deinstall_gatt,
  354         .write_gtt = agp_i810_write_gtt,
  355         .install_gtt_pte = agp_i830_install_gtt_pte,
  356         .read_gtt_pte = agp_i810_read_gtt_pte,
  357         .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
  358         .set_aperture = agp_i915_set_aperture,
  359         .chipset_flush_setup = agp_i810_chipset_flush_setup,
  360         .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
  361         .chipset_flush = agp_i830_chipset_flush,
  362 };
  363 
  364 static const struct agp_i810_driver agp_i810_i915_driver = {
  365         .chiptype = CHIP_I915,
  366         .gen = 3,
  367         .busdma_addr_mask_sz = 32,
  368         .res_spec = agp_i915_res_spec,
  369         .check_active = agp_i915_check_active,
  370         .set_desc = agp_i810_set_desc,
  371         .dump_regs = agp_i915_dump_regs,
  372         .get_stolen_size = agp_i915_get_stolen_size,
  373         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  374         .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
  375         .install_gatt = agp_i830_install_gatt,
  376         .deinstall_gatt = agp_i830_deinstall_gatt,
  377         .write_gtt = agp_i915_write_gtt,
  378         .install_gtt_pte = agp_i915_install_gtt_pte,
  379         .read_gtt_pte = agp_i915_read_gtt_pte,
  380         .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
  381         .set_aperture = agp_i915_set_aperture,
  382         .chipset_flush_setup = agp_i915_chipset_flush_setup,
  383         .chipset_flush_teardown = agp_i915_chipset_flush_teardown,
  384         .chipset_flush = agp_i915_chipset_flush,
  385 };
  386 
  387 static const struct agp_i810_driver agp_i810_g965_driver = {
  388         .chiptype = CHIP_I965,
  389         .gen = 4,
  390         .busdma_addr_mask_sz = 36,
  391         .res_spec = agp_i965_res_spec,
  392         .check_active = agp_i915_check_active,
  393         .set_desc = agp_i810_set_desc,
  394         .dump_regs = agp_i965_dump_regs,
  395         .get_stolen_size = agp_i915_get_stolen_size,
  396         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  397         .get_gtt_total_entries = agp_i965_get_gtt_total_entries,
  398         .install_gatt = agp_i830_install_gatt,
  399         .deinstall_gatt = agp_i830_deinstall_gatt,
  400         .write_gtt = agp_i965_write_gtt,
  401         .install_gtt_pte = agp_i965_install_gtt_pte,
  402         .read_gtt_pte = agp_i965_read_gtt_pte,
  403         .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
  404         .set_aperture = agp_i915_set_aperture,
  405         .chipset_flush_setup = agp_i965_chipset_flush_setup,
  406         .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
  407         .chipset_flush = agp_i915_chipset_flush,
  408 };
  409 
  410 static const struct agp_i810_driver agp_i810_g33_driver = {
  411         .chiptype = CHIP_G33,
  412         .gen = 3,
  413         .busdma_addr_mask_sz = 36,
  414         .res_spec = agp_i915_res_spec,
  415         .check_active = agp_i915_check_active,
  416         .set_desc = agp_i810_set_desc,
  417         .dump_regs = agp_i965_dump_regs,
  418         .get_stolen_size = agp_i915_get_stolen_size,
  419         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  420         .get_gtt_total_entries = agp_i965_get_gtt_total_entries,
  421         .install_gatt = agp_i830_install_gatt,
  422         .deinstall_gatt = agp_i830_deinstall_gatt,
  423         .write_gtt = agp_i915_write_gtt,
  424         .install_gtt_pte = agp_i915_install_gtt_pte,
  425         .read_gtt_pte = agp_i915_read_gtt_pte,
  426         .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
  427         .set_aperture = agp_i915_set_aperture,
  428         .chipset_flush_setup = agp_i965_chipset_flush_setup,
  429         .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
  430         .chipset_flush = agp_i915_chipset_flush,
  431 };
  432 
  433 static const struct agp_i810_driver agp_i810_igd_driver = {
  434         .chiptype = CHIP_IGD,
  435         .gen = 3,
  436         .busdma_addr_mask_sz = 36,
  437         .res_spec = agp_i915_res_spec,
  438         .check_active = agp_i915_check_active,
  439         .set_desc = agp_i810_set_desc,
  440         .dump_regs = agp_i915_dump_regs,
  441         .get_stolen_size = agp_i915_get_stolen_size,
  442         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  443         .get_gtt_total_entries = agp_i965_get_gtt_total_entries,
  444         .install_gatt = agp_i830_install_gatt,
  445         .deinstall_gatt = agp_i830_deinstall_gatt,
  446         .write_gtt = agp_i915_write_gtt,
  447         .install_gtt_pte = agp_i915_install_gtt_pte,
  448         .read_gtt_pte = agp_i915_read_gtt_pte,
  449         .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
  450         .set_aperture = agp_i915_set_aperture,
  451         .chipset_flush_setup = agp_i965_chipset_flush_setup,
  452         .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
  453         .chipset_flush = agp_i915_chipset_flush,
  454 };
  455 
  456 static const struct agp_i810_driver agp_i810_g4x_driver = {
  457         .chiptype = CHIP_G4X,
  458         .gen = 5,
  459         .busdma_addr_mask_sz = 36,
  460         .res_spec = agp_i965_res_spec,
  461         .check_active = agp_i915_check_active,
  462         .set_desc = agp_i810_set_desc,
  463         .dump_regs = agp_i965_dump_regs,
  464         .get_stolen_size = agp_i915_get_stolen_size,
  465         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  466         .get_gtt_total_entries = agp_gen5_get_gtt_total_entries,
  467         .install_gatt = agp_i830_install_gatt,
  468         .deinstall_gatt = agp_i830_deinstall_gatt,
  469         .write_gtt = agp_g4x_write_gtt,
  470         .install_gtt_pte = agp_g4x_install_gtt_pte,
  471         .read_gtt_pte = agp_g4x_read_gtt_pte,
  472         .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
  473         .set_aperture = agp_i915_set_aperture,
  474         .chipset_flush_setup = agp_i965_chipset_flush_setup,
  475         .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
  476         .chipset_flush = agp_i915_chipset_flush,
  477 };
  478 
  479 static const struct agp_i810_driver agp_i810_sb_driver = {
  480         .chiptype = CHIP_SB,
  481         .gen = 6,
  482         .busdma_addr_mask_sz = 40,
  483         .res_spec = agp_g4x_res_spec,
  484         .check_active = agp_sb_check_active,
  485         .set_desc = agp_i810_set_desc,
  486         .dump_regs = agp_sb_dump_regs,
  487         .get_stolen_size = agp_sb_get_stolen_size,
  488         .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
  489         .get_gtt_total_entries = agp_sb_get_gtt_total_entries,
  490         .install_gatt = agp_i830_install_gatt,
  491         .deinstall_gatt = agp_i830_deinstall_gatt,
  492         .write_gtt = agp_sb_write_gtt,
  493         .install_gtt_pte = agp_sb_install_gtt_pte,
  494         .read_gtt_pte = agp_g4x_read_gtt_pte,
  495         .read_gtt_pte_paddr = agp_sb_read_gtt_pte_paddr,
  496         .set_aperture = agp_i915_set_aperture,
  497         .chipset_flush_setup = agp_i810_chipset_flush_setup,
  498         .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
  499         .chipset_flush = agp_i810_chipset_flush,
  500 };
  501 
  502 /* For adding new devices, devid is the id of the graphics controller
  503  * (pci:0:2:0, for example).  The placeholder (usually at pci:0:2:1) for the
  504  * second head should never be added.  The bridge_offset is the offset to
  505  * subtract from devid to get the id of the hostb that the device is on.
  506  */
  507 static const struct agp_i810_match {
  508         int devid;
  509         char *name;
  510         const struct agp_i810_driver *driver;
  511 } agp_i810_matches[] = {
  512         {
  513                 .devid = 0x71218086,
  514                 .name = "Intel 82810 (i810 GMCH) SVGA controller",
  515                 .driver = &agp_i810_i810_driver
  516         },
  517         {
  518                 .devid = 0x71238086,
  519                 .name = "Intel 82810-DC100 (i810-DC100 GMCH) SVGA controller",
  520                 .driver = &agp_i810_i810_driver
  521         },
  522         {
  523                 .devid = 0x71258086,
  524                 .name = "Intel 82810E (i810E GMCH) SVGA controller",
  525                 .driver = &agp_i810_i810_driver
  526         },
  527         {
  528                 .devid = 0x11328086,
  529                 .name = "Intel 82815 (i815 GMCH) SVGA controller",
  530                 .driver = &agp_i810_i815_driver
  531         },
  532         {
  533                 .devid = 0x35778086,
  534                 .name = "Intel 82830M (830M GMCH) SVGA controller",
  535                 .driver = &agp_i810_i830_driver
  536         },
  537         {
  538                 .devid = 0x25628086,
  539                 .name = "Intel 82845M (845M GMCH) SVGA controller",
  540                 .driver = &agp_i810_i830_driver
  541         },
  542         {
  543                 .devid = 0x35828086,
  544                 .name = "Intel 82852/855GM SVGA controller",
  545                 .driver = &agp_i810_i855_driver
  546         },
  547         {
  548                 .devid = 0x25728086,
  549                 .name = "Intel 82865G (865G GMCH) SVGA controller",
  550                 .driver = &agp_i810_i865_driver
  551         },
  552         {
  553                 .devid = 0x25828086,
  554                 .name = "Intel 82915G (915G GMCH) SVGA controller",
  555                 .driver = &agp_i810_i915_driver
  556         },
  557         {
  558                 .devid = 0x258A8086,
  559                 .name = "Intel E7221 SVGA controller",
  560                 .driver = &agp_i810_i915_driver
  561         },
  562         {
  563                 .devid = 0x25928086,
  564                 .name = "Intel 82915GM (915GM GMCH) SVGA controller",
  565                 .driver = &agp_i810_i915_driver
  566         },
  567         {
  568                 .devid = 0x27728086,
  569                 .name = "Intel 82945G (945G GMCH) SVGA controller",
  570                 .driver = &agp_i810_i915_driver
  571         },
  572         {
  573                 .devid = 0x27A28086,
  574                 .name = "Intel 82945GM (945GM GMCH) SVGA controller",
  575                 .driver = &agp_i810_i915_driver
  576         },
  577         {
  578                 .devid = 0x27AE8086,
  579                 .name = "Intel 945GME SVGA controller",
  580                 .driver = &agp_i810_i915_driver
  581         },
  582         {
  583                 .devid = 0x29728086,
  584                 .name = "Intel 946GZ SVGA controller",
  585                 .driver = &agp_i810_g965_driver
  586         },
  587         {
  588                 .devid = 0x29828086,
  589                 .name = "Intel G965 SVGA controller",
  590                 .driver = &agp_i810_g965_driver
  591         },
  592         {
  593                 .devid = 0x29928086,
  594                 .name = "Intel Q965 SVGA controller",
  595                 .driver = &agp_i810_g965_driver
  596         },
  597         {
  598                 .devid = 0x29A28086,
  599                 .name = "Intel G965 SVGA controller",
  600                 .driver = &agp_i810_g965_driver
  601         },
  602         {
  603                 .devid = 0x29B28086,
  604                 .name = "Intel Q35 SVGA controller",
  605                 .driver = &agp_i810_g33_driver
  606         },
  607         {
  608                 .devid = 0x29C28086,
  609                 .name = "Intel G33 SVGA controller",
  610                 .driver = &agp_i810_g33_driver
  611         },
  612         {
  613                 .devid = 0x29D28086,
  614                 .name = "Intel Q33 SVGA controller",
  615                 .driver = &agp_i810_g33_driver
  616         },
  617         {
  618                 .devid = 0xA0018086,
  619                 .name = "Intel Pineview SVGA controller",
  620                 .driver = &agp_i810_igd_driver
  621         },
  622         {
  623                 .devid = 0xA0118086,
  624                 .name = "Intel Pineview (M) SVGA controller",
  625                 .driver = &agp_i810_igd_driver
  626         },
  627         {
  628                 .devid = 0x2A028086,
  629                 .name = "Intel GM965 SVGA controller",
  630                 .driver = &agp_i810_g965_driver
  631         },
  632         {
  633                 .devid = 0x2A128086,
  634                 .name = "Intel GME965 SVGA controller",
  635                 .driver = &agp_i810_g965_driver
  636         },
  637         {
  638                 .devid = 0x2A428086,
  639                 .name = "Intel GM45 SVGA controller",
  640                 .driver = &agp_i810_g4x_driver
  641         },
  642         {
  643                 .devid = 0x2E028086,
  644                 .name = "Intel Eaglelake SVGA controller",
  645                 .driver = &agp_i810_g4x_driver
  646         },
  647         {
  648                 .devid = 0x2E128086,
  649                 .name = "Intel Q45 SVGA controller",
  650                 .driver = &agp_i810_g4x_driver
  651         },
  652         {
  653                 .devid = 0x2E228086,
  654                 .name = "Intel G45 SVGA controller",
  655                 .driver = &agp_i810_g4x_driver
  656         },
  657         {
  658                 .devid = 0x2E328086,
  659                 .name = "Intel G41 SVGA controller",
  660                 .driver = &agp_i810_g4x_driver
  661         },
  662         {
  663                 .devid = 0x00428086,
  664                 .name = "Intel Ironlake (D) SVGA controller",
  665                 .driver = &agp_i810_g4x_driver
  666         },
  667         {
  668                 .devid = 0x00468086,
  669                 .name = "Intel Ironlake (M) SVGA controller",
  670                 .driver = &agp_i810_g4x_driver
  671         },
  672         {
  673                 .devid = 0x01028086,
  674                 .name = "SandyBridge desktop GT1 IG",
  675                 .driver = &agp_i810_sb_driver
  676         },
  677         {
  678                 .devid = 0x01128086,
  679                 .name = "SandyBridge desktop GT2 IG",
  680                 .driver = &agp_i810_sb_driver
  681         },
  682         {
  683                 .devid = 0x01228086,
  684                 .name = "SandyBridge desktop GT2+ IG",
  685                 .driver = &agp_i810_sb_driver
  686         },
  687         {
  688                 .devid = 0x01068086,
  689                 .name = "SandyBridge mobile GT1 IG",
  690                 .driver = &agp_i810_sb_driver
  691         },
  692         {
  693                 .devid = 0x01168086,
  694                 .name = "SandyBridge mobile GT2 IG",
  695                 .driver = &agp_i810_sb_driver
  696         },
  697         {
  698                 .devid = 0x01268086,
  699                 .name = "SandyBridge mobile GT2+ IG",
  700                 .driver = &agp_i810_sb_driver
  701         },
  702         {
  703                 .devid = 0x010a8086,
  704                 .name = "SandyBridge server IG",
  705                 .driver = &agp_i810_sb_driver
  706         },
  707         {
  708                 .devid = 0x01528086,
  709                 .name = "IvyBridge desktop GT1 IG",
  710                 .driver = &agp_i810_sb_driver
  711         },
  712         {
  713                 .devid = 0x01628086,
  714                 .name = "IvyBridge desktop GT2 IG",
  715                 .driver = &agp_i810_sb_driver
  716         },
  717         {
  718                 .devid = 0x01568086,
  719                 .name = "IvyBridge mobile GT1 IG",
  720                 .driver = &agp_i810_sb_driver
  721         },
  722         {
  723                 .devid = 0x01668086,
  724                 .name = "IvyBridge mobile GT2 IG",
  725                 .driver = &agp_i810_sb_driver
  726         },
  727         {
  728                 .devid = 0x015a8086,
  729                 .name = "IvyBridge server GT1 IG",
  730                 .driver = &agp_i810_sb_driver
  731         },
  732         {
  733                 .devid = 0x016a8086,
  734                 .name = "IvyBridge server GT2 IG",
  735                 .driver = &agp_i810_sb_driver
  736         },
  737         {
  738                 .devid = 0,
  739         }
  740 };
  741 
  742 static const struct agp_i810_match*
  743 agp_i810_match(device_t dev)
  744 {
  745         int i, devid;
  746 
  747         if (pci_get_class(dev) != PCIC_DISPLAY
  748             || pci_get_subclass(dev) != PCIS_DISPLAY_VGA)
  749                 return (NULL);
  750 
  751         devid = pci_get_devid(dev);
  752         for (i = 0; agp_i810_matches[i].devid != 0; i++) {
  753                 if (agp_i810_matches[i].devid == devid)
  754                         break;
  755         }
  756         if (agp_i810_matches[i].devid == 0)
  757                 return (NULL);
  758         else
  759                 return (&agp_i810_matches[i]);
  760 }
  761 
  762 /*
  763  * Find bridge device.
  764  */
  765 static device_t
  766 agp_i810_find_bridge(device_t dev)
  767 {
  768 
  769         return (pci_find_dbsf(0, 0, 0, 0));
  770 }
  771 
  772 static void
  773 agp_i810_identify(driver_t *driver, device_t parent)
  774 {
  775 
  776         if (device_find_child(parent, "agp", -1) == NULL &&
  777             agp_i810_match(parent))
  778                 device_add_child(parent, "agp", -1);
  779 }
  780 
  781 static int
  782 agp_i810_check_active(device_t bridge_dev)
  783 {
  784         u_int8_t smram;
  785 
  786         smram = pci_read_config(bridge_dev, AGP_I810_SMRAM, 1);
  787         if ((smram & AGP_I810_SMRAM_GMS) == AGP_I810_SMRAM_GMS_DISABLED)
  788                 return (ENXIO);
  789         return (0);
  790 }
  791 
  792 static int
  793 agp_i830_check_active(device_t bridge_dev)
  794 {
  795         int gcc1;
  796 
  797         gcc1 = pci_read_config(bridge_dev, AGP_I830_GCC1, 1);
  798         if ((gcc1 & AGP_I830_GCC1_DEV2) == AGP_I830_GCC1_DEV2_DISABLED)
  799                 return (ENXIO);
  800         return (0);
  801 }
  802 
  803 static int
  804 agp_i915_check_active(device_t bridge_dev)
  805 {
  806         int deven;
  807 
  808         deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4);
  809         if ((deven & AGP_I915_DEVEN_D2F0) == AGP_I915_DEVEN_D2F0_DISABLED)
  810                 return (ENXIO);
  811         return (0);
  812 }
  813 
  814 static int
  815 agp_sb_check_active(device_t bridge_dev)
  816 {
  817         int deven;
  818 
  819         deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4);
  820         if ((deven & AGP_SB_DEVEN_D2EN) == AGP_SB_DEVEN_D2EN_DISABLED)
  821                 return (ENXIO);
  822         return (0);
  823 }
  824 
  825 static void
  826 agp_82852_set_desc(device_t dev, const struct agp_i810_match *match)
  827 {
  828 
  829         switch (pci_read_config(dev, AGP_I85X_CAPID, 1)) {
  830         case AGP_I855_GME:
  831                 device_set_desc(dev,
  832                     "Intel 82855GME (855GME GMCH) SVGA controller");
  833                 break;
  834         case AGP_I855_GM:
  835                 device_set_desc(dev,
  836                     "Intel 82855GM (855GM GMCH) SVGA controller");
  837                 break;
  838         case AGP_I852_GME:
  839                 device_set_desc(dev,
  840                     "Intel 82852GME (852GME GMCH) SVGA controller");
  841                 break;
  842         case AGP_I852_GM:
  843                 device_set_desc(dev,
  844                     "Intel 82852GM (852GM GMCH) SVGA controller");
  845                 break;
  846         default:
  847                 device_set_desc(dev,
  848                     "Intel 8285xM (85xGM GMCH) SVGA controller");
  849                 break;
  850         }
  851 }
  852 
  853 static void
  854 agp_i810_set_desc(device_t dev, const struct agp_i810_match *match)
  855 {
  856 
  857         device_set_desc(dev, match->name);
  858 }
  859 
  860 static int
  861 agp_i810_probe(device_t dev)
  862 {
  863         device_t bdev;
  864         const struct agp_i810_match *match;
  865         int err;
  866 
  867         if (resource_disabled("agp", device_get_unit(dev)))
  868                 return (ENXIO);
  869         match = agp_i810_match(dev);
  870         if (match == NULL)
  871                 return (ENXIO);
  872 
  873         bdev = agp_i810_find_bridge(dev);
  874         if (bdev == NULL) {
  875                 if (bootverbose)
  876                         printf("I810: can't find bridge device\n");
  877                 return (ENXIO);
  878         }
  879 
  880         /*
  881          * checking whether internal graphics device has been activated.
  882          */
  883         err = match->driver->check_active(bdev);
  884         if (err != 0) {
  885                 if (bootverbose)
  886                         printf("i810: disabled, not probing\n");
  887                 return (err);
  888         }
  889 
  890         match->driver->set_desc(dev, match);
  891         return (BUS_PROBE_DEFAULT);
  892 }
  893 
  894 static void
  895 agp_i810_dump_regs(device_t dev)
  896 {
  897         struct agp_i810_softc *sc = device_get_softc(dev);
  898 
  899         device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
  900             bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
  901         device_printf(dev, "AGP_I810_MISCC: 0x%04x\n",
  902             pci_read_config(sc->bdev, AGP_I810_MISCC, 2));
  903 }
  904 
  905 static void
  906 agp_i830_dump_regs(device_t dev)
  907 {
  908         struct agp_i810_softc *sc = device_get_softc(dev);
  909 
  910         device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
  911             bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
  912         device_printf(dev, "AGP_I830_GCC1: 0x%02x\n",
  913             pci_read_config(sc->bdev, AGP_I830_GCC1, 1));
  914 }
  915 
  916 static void
  917 agp_i855_dump_regs(device_t dev)
  918 {
  919         struct agp_i810_softc *sc = device_get_softc(dev);
  920 
  921         device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
  922             bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
  923         device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
  924             pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
  925 }
  926 
  927 static void
  928 agp_i915_dump_regs(device_t dev)
  929 {
  930         struct agp_i810_softc *sc = device_get_softc(dev);
  931 
  932         device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
  933             bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
  934         device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
  935             pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
  936         device_printf(dev, "AGP_I915_MSAC: 0x%02x\n",
  937             pci_read_config(sc->bdev, AGP_I915_MSAC, 1));
  938 }
  939 
  940 static void
  941 agp_i965_dump_regs(device_t dev)
  942 {
  943         struct agp_i810_softc *sc = device_get_softc(dev);
  944 
  945         device_printf(dev, "AGP_I965_PGTBL_CTL2: %08x\n",
  946             bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2));
  947         device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
  948             pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
  949         device_printf(dev, "AGP_I965_MSAC: 0x%02x\n",
  950             pci_read_config(sc->bdev, AGP_I965_MSAC, 1));
  951 }
  952 
  953 static void
  954 agp_sb_dump_regs(device_t dev)
  955 {
  956         struct agp_i810_softc *sc = device_get_softc(dev);
  957 
  958         device_printf(dev, "AGP_SNB_GFX_MODE: %08x\n",
  959             bus_read_4(sc->sc_res[0], AGP_SNB_GFX_MODE));
  960         device_printf(dev, "AGP_SNB_GCC1: 0x%04x\n",
  961             pci_read_config(sc->bdev, AGP_SNB_GCC1, 2));
  962 }
  963 
  964 static int
  965 agp_i810_get_stolen_size(device_t dev)
  966 {
  967         struct agp_i810_softc *sc;
  968 
  969         sc = device_get_softc(dev);
  970         sc->stolen = 0;
  971         sc->stolen_size = 0;
  972         return (0);
  973 }
  974 
  975 static int
  976 agp_i830_get_stolen_size(device_t dev)
  977 {
  978         struct agp_i810_softc *sc;
  979         unsigned int gcc1;
  980 
  981         sc = device_get_softc(dev);
  982 
  983         gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 1);
  984         switch (gcc1 & AGP_I830_GCC1_GMS) {
  985         case AGP_I830_GCC1_GMS_STOLEN_512:
  986                 sc->stolen = (512 - 132) * 1024 / 4096;
  987                 sc->stolen_size = 512 * 1024;
  988                 break;
  989         case AGP_I830_GCC1_GMS_STOLEN_1024: 
  990                 sc->stolen = (1024 - 132) * 1024 / 4096;
  991                 sc->stolen_size = 1024 * 1024;
  992                 break;
  993         case AGP_I830_GCC1_GMS_STOLEN_8192: 
  994                 sc->stolen = (8192 - 132) * 1024 / 4096;
  995                 sc->stolen_size = 8192 * 1024;
  996                 break;
  997         default:
  998                 sc->stolen = 0;
  999                 device_printf(dev,
 1000                     "unknown memory configuration, disabling (GCC1 %x)\n",
 1001                     gcc1);
 1002                 return (EINVAL);
 1003         }
 1004         return (0);
 1005 }
 1006 
 1007 static int
 1008 agp_i915_get_stolen_size(device_t dev)
 1009 {
 1010         struct agp_i810_softc *sc;
 1011         unsigned int gcc1, stolen, gtt_size;
 1012 
 1013         sc = device_get_softc(dev);
 1014 
 1015         /*
 1016          * Stolen memory is set up at the beginning of the aperture by
 1017          * the BIOS, consisting of the GATT followed by 4kb for the
 1018          * BIOS display.
 1019          */
 1020         switch (sc->match->driver->chiptype) {
 1021         case CHIP_I855:
 1022                 gtt_size = 128;
 1023                 break;
 1024         case CHIP_I915:
 1025                 gtt_size = 256;
 1026                 break;
 1027         case CHIP_I965:
 1028                 switch (bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL) &
 1029                         AGP_I810_PGTBL_SIZE_MASK) {
 1030                 case AGP_I810_PGTBL_SIZE_128KB:
 1031                         gtt_size = 128;
 1032                         break;
 1033                 case AGP_I810_PGTBL_SIZE_256KB:
 1034                         gtt_size = 256;
 1035                         break;
 1036                 case AGP_I810_PGTBL_SIZE_512KB:
 1037                         gtt_size = 512;
 1038                         break;
 1039                 case AGP_I965_PGTBL_SIZE_1MB:
 1040                         gtt_size = 1024;
 1041                         break;
 1042                 case AGP_I965_PGTBL_SIZE_2MB:
 1043                         gtt_size = 2048;
 1044                         break;
 1045                 case AGP_I965_PGTBL_SIZE_1_5MB:
 1046                         gtt_size = 1024 + 512;
 1047                         break;
 1048                 default:
 1049                         device_printf(dev, "Bad PGTBL size\n");
 1050                         return (EINVAL);
 1051                 }
 1052                 break;
 1053         case CHIP_G33:
 1054                 gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 2);
 1055                 switch (gcc1 & AGP_G33_MGGC_GGMS_MASK) {
 1056                 case AGP_G33_MGGC_GGMS_SIZE_1M:
 1057                         gtt_size = 1024;
 1058                         break;
 1059                 case AGP_G33_MGGC_GGMS_SIZE_2M:
 1060                         gtt_size = 2048;
 1061                         break;
 1062                 default:
 1063                         device_printf(dev, "Bad PGTBL size\n");
 1064                         return (EINVAL);
 1065                 }
 1066                 break;
 1067         case CHIP_IGD:
 1068         case CHIP_G4X:
 1069                 gtt_size = 0;
 1070                 break;
 1071         default:
 1072                 device_printf(dev, "Bad chiptype\n");
 1073                 return (EINVAL);
 1074         }
 1075 
 1076         /* GCC1 is called MGGC on i915+ */
 1077         gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1);
 1078         switch (gcc1 & AGP_I855_GCC1_GMS) {
 1079         case AGP_I855_GCC1_GMS_STOLEN_1M:
 1080                 stolen = 1024;
 1081                 break;
 1082         case AGP_I855_GCC1_GMS_STOLEN_4M:
 1083                 stolen = 4 * 1024;
 1084                 break;
 1085         case AGP_I855_GCC1_GMS_STOLEN_8M:
 1086                 stolen = 8 * 1024;
 1087                 break;
 1088         case AGP_I855_GCC1_GMS_STOLEN_16M:
 1089                 stolen = 16 * 1024;
 1090                 break;
 1091         case AGP_I855_GCC1_GMS_STOLEN_32M:
 1092                 stolen = 32 * 1024;
 1093                 break;
 1094         case AGP_I915_GCC1_GMS_STOLEN_48M:
 1095                 stolen = sc->match->driver->gen > 2 ? 48 * 1024 : 0;
 1096                 break;
 1097         case AGP_I915_GCC1_GMS_STOLEN_64M:
 1098                 stolen = sc->match->driver->gen > 2 ? 64 * 1024 : 0;
 1099                 break;
 1100         case AGP_G33_GCC1_GMS_STOLEN_128M:
 1101                 stolen = sc->match->driver->gen > 2 ? 128 * 1024 : 0;
 1102                 break;
 1103         case AGP_G33_GCC1_GMS_STOLEN_256M:
 1104                 stolen = sc->match->driver->gen > 2 ? 256 * 1024 : 0;
 1105                 break;
 1106         case AGP_G4X_GCC1_GMS_STOLEN_96M:
 1107                 if (sc->match->driver->chiptype == CHIP_I965 ||
 1108                     sc->match->driver->chiptype == CHIP_G4X)
 1109                         stolen = 96 * 1024;
 1110                 else
 1111                         stolen = 0;
 1112                 break;
 1113         case AGP_G4X_GCC1_GMS_STOLEN_160M:
 1114                 if (sc->match->driver->chiptype == CHIP_I965 ||
 1115                     sc->match->driver->chiptype == CHIP_G4X)
 1116                         stolen = 160 * 1024;
 1117                 else
 1118                         stolen = 0;
 1119                 break;
 1120         case AGP_G4X_GCC1_GMS_STOLEN_224M:
 1121                 if (sc->match->driver->chiptype == CHIP_I965 ||
 1122                     sc->match->driver->chiptype == CHIP_G4X)
 1123                         stolen = 224 * 1024;
 1124                 else
 1125                         stolen = 0;
 1126                 break;
 1127         case AGP_G4X_GCC1_GMS_STOLEN_352M:
 1128                 if (sc->match->driver->chiptype == CHIP_I965 ||
 1129                     sc->match->driver->chiptype == CHIP_G4X)
 1130                         stolen = 352 * 1024;
 1131                 else
 1132                         stolen = 0;
 1133                 break;
 1134         default:
 1135                 device_printf(dev,
 1136                     "unknown memory configuration, disabling (GCC1 %x)\n",
 1137                     gcc1);
 1138                 return (EINVAL);
 1139         }
 1140 
 1141         gtt_size += 4;
 1142         sc->stolen_size = stolen * 1024;
 1143         sc->stolen = (stolen - gtt_size) * 1024 / 4096;
 1144 
 1145         return (0);
 1146 }
 1147 
 1148 static int
 1149 agp_sb_get_stolen_size(device_t dev)
 1150 {
 1151         struct agp_i810_softc *sc;
 1152         uint16_t gmch_ctl;
 1153 
 1154         sc = device_get_softc(dev);
 1155         gmch_ctl = pci_read_config(sc->bdev, AGP_SNB_GCC1, 2);
 1156         switch (gmch_ctl & AGP_SNB_GMCH_GMS_STOLEN_MASK) {
 1157         case AGP_SNB_GMCH_GMS_STOLEN_32M:
 1158                 sc->stolen_size = 32 * 1024 * 1024;
 1159                 break;
 1160         case AGP_SNB_GMCH_GMS_STOLEN_64M:
 1161                 sc->stolen_size = 64 * 1024 * 1024;
 1162                 break;
 1163         case AGP_SNB_GMCH_GMS_STOLEN_96M:
 1164                 sc->stolen_size = 96 * 1024 * 1024;
 1165                 break;
 1166         case AGP_SNB_GMCH_GMS_STOLEN_128M:
 1167                 sc->stolen_size = 128 * 1024 * 1024;
 1168                 break;
 1169         case AGP_SNB_GMCH_GMS_STOLEN_160M:
 1170                 sc->stolen_size = 160 * 1024 * 1024;
 1171                 break;
 1172         case AGP_SNB_GMCH_GMS_STOLEN_192M:
 1173                 sc->stolen_size = 192 * 1024 * 1024;
 1174                 break;
 1175         case AGP_SNB_GMCH_GMS_STOLEN_224M:
 1176                 sc->stolen_size = 224 * 1024 * 1024;
 1177                 break;
 1178         case AGP_SNB_GMCH_GMS_STOLEN_256M:
 1179                 sc->stolen_size = 256 * 1024 * 1024;
 1180                 break;
 1181         case AGP_SNB_GMCH_GMS_STOLEN_288M:
 1182                 sc->stolen_size = 288 * 1024 * 1024;
 1183                 break;
 1184         case AGP_SNB_GMCH_GMS_STOLEN_320M:
 1185                 sc->stolen_size = 320 * 1024 * 1024;
 1186                 break;
 1187         case AGP_SNB_GMCH_GMS_STOLEN_352M:
 1188                 sc->stolen_size = 352 * 1024 * 1024;
 1189                 break;
 1190         case AGP_SNB_GMCH_GMS_STOLEN_384M:
 1191                 sc->stolen_size = 384 * 1024 * 1024;
 1192                 break;
 1193         case AGP_SNB_GMCH_GMS_STOLEN_416M:
 1194                 sc->stolen_size = 416 * 1024 * 1024;
 1195                 break;
 1196         case AGP_SNB_GMCH_GMS_STOLEN_448M:
 1197                 sc->stolen_size = 448 * 1024 * 1024;
 1198                 break;
 1199         case AGP_SNB_GMCH_GMS_STOLEN_480M:
 1200                 sc->stolen_size = 480 * 1024 * 1024;
 1201                 break;
 1202         case AGP_SNB_GMCH_GMS_STOLEN_512M:
 1203                 sc->stolen_size = 512 * 1024 * 1024;
 1204                 break;
 1205         }
 1206         sc->stolen = (sc->stolen_size - 4) / 4096;
 1207         return (0);
 1208 }
 1209 
 1210 static int
 1211 agp_i810_get_gtt_mappable_entries(device_t dev)
 1212 {
 1213         struct agp_i810_softc *sc;
 1214         uint32_t ap;
 1215         uint16_t miscc;
 1216 
 1217         sc = device_get_softc(dev);
 1218         miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2);
 1219         if ((miscc & AGP_I810_MISCC_WINSIZE) == AGP_I810_MISCC_WINSIZE_32)
 1220                 ap = 32;
 1221         else
 1222                 ap = 64;
 1223         sc->gtt_mappable_entries = (ap * 1024 * 1024) >> AGP_PAGE_SHIFT;
 1224         return (0);
 1225 }
 1226 
 1227 static int
 1228 agp_i830_get_gtt_mappable_entries(device_t dev)
 1229 {
 1230         struct agp_i810_softc *sc;
 1231         uint32_t ap;
 1232         uint16_t gmch_ctl;
 1233 
 1234         sc = device_get_softc(dev);
 1235         gmch_ctl = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
 1236         if ((gmch_ctl & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64)
 1237                 ap = 64;
 1238         else
 1239                 ap = 128;
 1240         sc->gtt_mappable_entries = (ap * 1024 * 1024) >> AGP_PAGE_SHIFT;
 1241         return (0);
 1242 }
 1243 
 1244 static int
 1245 agp_i915_get_gtt_mappable_entries(device_t dev)
 1246 {
 1247         struct agp_i810_softc *sc;
 1248         uint32_t ap;
 1249 
 1250         sc = device_get_softc(dev);
 1251         ap = AGP_GET_APERTURE(dev);
 1252         sc->gtt_mappable_entries = ap >> AGP_PAGE_SHIFT;
 1253         return (0);
 1254 }
 1255 
 1256 static int
 1257 agp_i810_get_gtt_total_entries(device_t dev)
 1258 {
 1259         struct agp_i810_softc *sc;
 1260 
 1261         sc = device_get_softc(dev);
 1262         sc->gtt_total_entries = sc->gtt_mappable_entries;
 1263         return (0);
 1264 }
 1265 
 1266 static int
 1267 agp_i965_get_gtt_total_entries(device_t dev)
 1268 {
 1269         struct agp_i810_softc *sc;
 1270         uint32_t pgetbl_ctl;
 1271         int error;
 1272 
 1273         sc = device_get_softc(dev);
 1274         error = 0;
 1275         pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
 1276         switch (pgetbl_ctl & AGP_I810_PGTBL_SIZE_MASK) {
 1277         case AGP_I810_PGTBL_SIZE_128KB:
 1278                 sc->gtt_total_entries = 128 * 1024 / 4;
 1279                 break;
 1280         case AGP_I810_PGTBL_SIZE_256KB:
 1281                 sc->gtt_total_entries = 256 * 1024 / 4;
 1282                 break;
 1283         case AGP_I810_PGTBL_SIZE_512KB:
 1284                 sc->gtt_total_entries = 512 * 1024 / 4;
 1285                 break;
 1286         /* GTT pagetable sizes bigger than 512KB are not possible on G33! */
 1287         case AGP_I810_PGTBL_SIZE_1MB:
 1288                 sc->gtt_total_entries = 1024 * 1024 / 4;
 1289                 break;
 1290         case AGP_I810_PGTBL_SIZE_2MB:
 1291                 sc->gtt_total_entries = 2 * 1024 * 1024 / 4;
 1292                 break;
 1293         case AGP_I810_PGTBL_SIZE_1_5MB:
 1294                 sc->gtt_total_entries = (1024 + 512) * 1024 / 4;
 1295                 break;
 1296         default:
 1297                 device_printf(dev, "Unknown page table size\n");
 1298                 error = ENXIO;
 1299         }
 1300         return (error);
 1301 }
 1302 
 1303 static void
 1304 agp_gen5_adjust_pgtbl_size(device_t dev, uint32_t sz)
 1305 {
 1306         struct agp_i810_softc *sc;
 1307         uint32_t pgetbl_ctl, pgetbl_ctl2;
 1308 
 1309         sc = device_get_softc(dev);
 1310 
 1311         /* Disable per-process page table. */
 1312         pgetbl_ctl2 = bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2);
 1313         pgetbl_ctl2 &= ~AGP_I810_PGTBL_ENABLED;
 1314         bus_write_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2, pgetbl_ctl2);
 1315 
 1316         /* Write the new ggtt size. */
 1317         pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
 1318         pgetbl_ctl &= ~AGP_I810_PGTBL_SIZE_MASK;
 1319         pgetbl_ctl |= sz;
 1320         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgetbl_ctl);
 1321 }
 1322 
 1323 static int
 1324 agp_gen5_get_gtt_total_entries(device_t dev)
 1325 {
 1326         struct agp_i810_softc *sc;
 1327         uint16_t gcc1;
 1328 
 1329         sc = device_get_softc(dev);
 1330 
 1331         gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
 1332         switch (gcc1 & AGP_G4x_GCC1_SIZE_MASK) {
 1333         case AGP_G4x_GCC1_SIZE_1M:
 1334         case AGP_G4x_GCC1_SIZE_VT_1M:
 1335                 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1MB);
 1336                 break;
 1337         case AGP_G4x_GCC1_SIZE_VT_1_5M:
 1338                 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1_5MB);
 1339                 break;
 1340         case AGP_G4x_GCC1_SIZE_2M:
 1341         case AGP_G4x_GCC1_SIZE_VT_2M:
 1342                 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_2MB);
 1343                 break;
 1344         default:
 1345                 device_printf(dev, "Unknown page table size\n");
 1346                 return (ENXIO);
 1347         }
 1348 
 1349         return (agp_i965_get_gtt_total_entries(dev));
 1350 }
 1351 
 1352 static int
 1353 agp_sb_get_gtt_total_entries(device_t dev)
 1354 {
 1355         struct agp_i810_softc *sc;
 1356         uint16_t gcc1;
 1357 
 1358         sc = device_get_softc(dev);
 1359 
 1360         gcc1 = pci_read_config(sc->bdev, AGP_SNB_GCC1, 2);
 1361         switch (gcc1 & AGP_SNB_GTT_SIZE_MASK) {
 1362         default:
 1363         case AGP_SNB_GTT_SIZE_0M:
 1364                 printf("Bad GTT size mask: 0x%04x\n", gcc1);
 1365                 return (ENXIO);
 1366         case AGP_SNB_GTT_SIZE_1M:
 1367                 sc->gtt_total_entries = 1024 * 1024 / 4;
 1368                 break;
 1369         case AGP_SNB_GTT_SIZE_2M:
 1370                 sc->gtt_total_entries = 2 * 1024 * 1024 / 4;
 1371                 break;
 1372         }
 1373         return (0);
 1374 }
 1375 
 1376 static int
 1377 agp_i810_install_gatt(device_t dev)
 1378 {
 1379         struct agp_i810_softc *sc;
 1380 
 1381         sc = device_get_softc(dev);
 1382 
 1383         /* Some i810s have on-chip memory called dcache. */
 1384         if ((bus_read_1(sc->sc_res[0], AGP_I810_DRT) & AGP_I810_DRT_POPULATED)
 1385             != 0)
 1386                 sc->dcache_size = 4 * 1024 * 1024;
 1387         else
 1388                 sc->dcache_size = 0;
 1389 
 1390         /* According to the specs the gatt on the i810 must be 64k. */
 1391         sc->gatt->ag_virtual = contigmalloc(64 * 1024, M_AGP, 0, 0, ~0,
 1392             PAGE_SIZE, 0);
 1393         if (sc->gatt->ag_virtual == NULL) {
 1394                 if (bootverbose)
 1395                         device_printf(dev, "contiguous allocation failed\n");
 1396                 return (ENOMEM);
 1397         }
 1398 
 1399         bzero(sc->gatt->ag_virtual, sc->gatt->ag_entries * sizeof(u_int32_t));
 1400         sc->gatt->ag_physical = vtophys((vm_offset_t)sc->gatt->ag_virtual);
 1401         agp_flush_cache();
 1402         /* Install the GATT. */
 1403         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL,
 1404             sc->gatt->ag_physical | 1);
 1405         return (0);
 1406 }
 1407 
 1408 static int
 1409 agp_i830_install_gatt(device_t dev)
 1410 {
 1411         struct agp_i810_softc *sc;
 1412         uint32_t pgtblctl;
 1413 
 1414         sc = device_get_softc(dev);
 1415 
 1416         /*
 1417          * The i830 automatically initializes the 128k gatt on boot.
 1418          * GATT address is already in there, make sure it's enabled.
 1419          */
 1420         pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
 1421         pgtblctl |= 1;
 1422         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
 1423         
 1424         sc->gatt->ag_physical = pgtblctl & ~1;
 1425         return (0);
 1426 }
 1427 
 1428 static int
 1429 agp_i810_attach(device_t dev)
 1430 {
 1431         struct agp_i810_softc *sc;
 1432         int error;
 1433 
 1434         sc = device_get_softc(dev);
 1435         sc->bdev = agp_i810_find_bridge(dev);
 1436         if (sc->bdev == NULL)
 1437                 return (ENOENT);
 1438 
 1439         sc->match = agp_i810_match(dev);
 1440 
 1441         agp_set_aperture_resource(dev, sc->match->driver->gen <= 2 ?
 1442             AGP_APBASE : AGP_I915_GMADR);
 1443         error = agp_generic_attach(dev);
 1444         if (error)
 1445                 return (error);
 1446 
 1447         if (ptoa((vm_paddr_t)Maxmem) >
 1448             (1ULL << sc->match->driver->busdma_addr_mask_sz) - 1) {
 1449                 device_printf(dev, "agp_i810 does not support physical "
 1450                     "memory above %ju.\n", (uintmax_t)(1ULL <<
 1451                     sc->match->driver->busdma_addr_mask_sz) - 1);
 1452                 return (ENOENT);
 1453         }
 1454 
 1455         if (bus_alloc_resources(dev, sc->match->driver->res_spec, sc->sc_res)) {
 1456                 agp_generic_detach(dev);
 1457                 return (ENODEV);
 1458         }
 1459 
 1460         sc->initial_aperture = AGP_GET_APERTURE(dev);
 1461         sc->gatt = malloc(sizeof(struct agp_gatt), M_AGP, M_WAITOK);
 1462         sc->gatt->ag_entries = AGP_GET_APERTURE(dev) >> AGP_PAGE_SHIFT;
 1463 
 1464         if ((error = sc->match->driver->get_stolen_size(dev)) != 0 ||
 1465             (error = sc->match->driver->install_gatt(dev)) != 0 ||
 1466             (error = sc->match->driver->get_gtt_mappable_entries(dev)) != 0 ||
 1467             (error = sc->match->driver->get_gtt_total_entries(dev)) != 0 ||
 1468             (error = sc->match->driver->chipset_flush_setup(dev)) != 0) {
 1469                 bus_release_resources(dev, sc->match->driver->res_spec,
 1470                     sc->sc_res);
 1471                 free(sc->gatt, M_AGP);
 1472                 agp_generic_detach(dev);
 1473                 return (error);
 1474         }
 1475 
 1476         intel_agp = dev;
 1477         device_printf(dev, "aperture size is %dM",
 1478             sc->initial_aperture / 1024 / 1024);
 1479         if (sc->stolen > 0)
 1480                 printf(", detected %dk stolen memory\n", sc->stolen * 4);
 1481         else
 1482                 printf("\n");
 1483         if (bootverbose) {
 1484                 sc->match->driver->dump_regs(dev);
 1485                 device_printf(dev, "Mappable GTT entries: %d\n",
 1486                     sc->gtt_mappable_entries);
 1487                 device_printf(dev, "Total GTT entries: %d\n",
 1488                     sc->gtt_total_entries);
 1489         }
 1490         return (0);
 1491 }
 1492 
 1493 static void
 1494 agp_i810_deinstall_gatt(device_t dev)
 1495 {
 1496         struct agp_i810_softc *sc;
 1497 
 1498         sc = device_get_softc(dev);
 1499         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, 0);
 1500         contigfree(sc->gatt->ag_virtual, 64 * 1024, M_AGP);
 1501 }
 1502 
 1503 static void
 1504 agp_i830_deinstall_gatt(device_t dev)
 1505 {
 1506         struct agp_i810_softc *sc;
 1507         unsigned int pgtblctl;
 1508 
 1509         sc = device_get_softc(dev);
 1510         pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
 1511         pgtblctl &= ~1;
 1512         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
 1513 }
 1514 
 1515 static int
 1516 agp_i810_detach(device_t dev)
 1517 {
 1518         struct agp_i810_softc *sc;
 1519 
 1520         sc = device_get_softc(dev);
 1521         agp_free_cdev(dev);
 1522 
 1523         /* Clear the GATT base. */
 1524         sc->match->driver->deinstall_gatt(dev);
 1525 
 1526         sc->match->driver->chipset_flush_teardown(dev);
 1527 
 1528         /* Put the aperture back the way it started. */
 1529         AGP_SET_APERTURE(dev, sc->initial_aperture);
 1530 
 1531         free(sc->gatt, M_AGP);
 1532         bus_release_resources(dev, sc->match->driver->res_spec, sc->sc_res);
 1533         agp_free_res(dev);
 1534 
 1535         return (0);
 1536 }
 1537 
 1538 static int
 1539 agp_i810_resume(device_t dev)
 1540 {
 1541         struct agp_i810_softc *sc;
 1542         sc = device_get_softc(dev);
 1543 
 1544         AGP_SET_APERTURE(dev, sc->initial_aperture);
 1545 
 1546         /* Install the GATT. */
 1547         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL,
 1548         sc->gatt->ag_physical | 1);
 1549 
 1550         return (bus_generic_resume(dev));
 1551 }
 1552 
 1553 /**
 1554  * Sets the PCI resource size of the aperture on i830-class and below chipsets,
 1555  * while returning failure on later chipsets when an actual change is
 1556  * requested.
 1557  *
 1558  * This whole function is likely bogus, as the kernel would probably need to
 1559  * reconfigure the placement of the AGP aperture if a larger size is requested,
 1560  * which doesn't happen currently.
 1561  */
 1562 static int
 1563 agp_i810_set_aperture(device_t dev, u_int32_t aperture)
 1564 {
 1565         struct agp_i810_softc *sc;
 1566         u_int16_t miscc;
 1567 
 1568         sc = device_get_softc(dev);
 1569         /*
 1570          * Double check for sanity.
 1571          */
 1572         if (aperture != 32 * 1024 * 1024 && aperture != 64 * 1024 * 1024) {
 1573                 device_printf(dev, "bad aperture size %d\n", aperture);
 1574                 return (EINVAL);
 1575         }
 1576 
 1577         miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2);
 1578         miscc &= ~AGP_I810_MISCC_WINSIZE;
 1579         if (aperture == 32 * 1024 * 1024)
 1580                 miscc |= AGP_I810_MISCC_WINSIZE_32;
 1581         else
 1582                 miscc |= AGP_I810_MISCC_WINSIZE_64;
 1583         
 1584         pci_write_config(sc->bdev, AGP_I810_MISCC, miscc, 2);
 1585         return (0);
 1586 }
 1587 
 1588 static int
 1589 agp_i830_set_aperture(device_t dev, u_int32_t aperture)
 1590 {
 1591         struct agp_i810_softc *sc;
 1592         u_int16_t gcc1;
 1593 
 1594         sc = device_get_softc(dev);
 1595 
 1596         if (aperture != 64 * 1024 * 1024 &&
 1597             aperture != 128 * 1024 * 1024) {
 1598                 device_printf(dev, "bad aperture size %d\n", aperture);
 1599                 return (EINVAL);
 1600         }
 1601         gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
 1602         gcc1 &= ~AGP_I830_GCC1_GMASIZE;
 1603         if (aperture == 64 * 1024 * 1024)
 1604                 gcc1 |= AGP_I830_GCC1_GMASIZE_64;
 1605         else
 1606                 gcc1 |= AGP_I830_GCC1_GMASIZE_128;
 1607 
 1608         pci_write_config(sc->bdev, AGP_I830_GCC1, gcc1, 2);
 1609         return (0);
 1610 }
 1611 
 1612 static int
 1613 agp_i915_set_aperture(device_t dev, u_int32_t aperture)
 1614 {
 1615 
 1616         return (agp_generic_set_aperture(dev, aperture));
 1617 }
 1618 
 1619 static int
 1620 agp_i810_method_set_aperture(device_t dev, u_int32_t aperture)
 1621 {
 1622         struct agp_i810_softc *sc;
 1623 
 1624         sc = device_get_softc(dev);
 1625         return (sc->match->driver->set_aperture(dev, aperture));
 1626 }
 1627 
 1628 /**
 1629  * Writes a GTT entry mapping the page at the given offset from the
 1630  * beginning of the aperture to the given physical address.  Setup the
 1631  * caching mode according to flags.
 1632  *
 1633  * For gen 1, 2 and 3, GTT start is located at AGP_I810_GTT offset
 1634  * from corresponding BAR start. For gen 4, offset is 512KB +
 1635  * AGP_I810_GTT, for gen 5 and 6 it is 2MB + AGP_I810_GTT.
 1636  *
 1637  * Also, the bits of the physical page address above 4GB needs to be
 1638  * placed into bits 40-32 of PTE.
 1639  */
 1640 static void
 1641 agp_i810_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1642     int flags)
 1643 {
 1644         uint32_t pte;
 1645 
 1646         pte = (u_int32_t)physical | I810_PTE_VALID;
 1647         if (flags == AGP_DCACHE_MEMORY)
 1648                 pte |= I810_PTE_LOCAL;
 1649         else if (flags == AGP_USER_CACHED_MEMORY)
 1650                 pte |= I830_PTE_SYSTEM_CACHED;
 1651         agp_i810_write_gtt(dev, index, pte);
 1652 }
 1653 
 1654 static void
 1655 agp_i810_write_gtt(device_t dev, u_int index, uint32_t pte)
 1656 {
 1657         struct agp_i810_softc *sc;
 1658 
 1659         sc = device_get_softc(dev);
 1660         bus_write_4(sc->sc_res[0], AGP_I810_GTT + index * 4, pte);
 1661         CTR2(KTR_AGP_I810, "810_pte %x %x", index, pte);
 1662 }
 1663 
 1664 static void
 1665 agp_i830_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1666     int flags)
 1667 {
 1668         uint32_t pte;
 1669 
 1670         pte = (u_int32_t)physical | I810_PTE_VALID;
 1671         if (flags == AGP_USER_CACHED_MEMORY)
 1672                 pte |= I830_PTE_SYSTEM_CACHED;
 1673         agp_i810_write_gtt(dev, index, pte);
 1674 }
 1675 
 1676 static void
 1677 agp_i915_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1678     int flags)
 1679 {
 1680         uint32_t pte;
 1681 
 1682         pte = (u_int32_t)physical | I810_PTE_VALID;
 1683         if (flags == AGP_USER_CACHED_MEMORY)
 1684                 pte |= I830_PTE_SYSTEM_CACHED;
 1685         pte |= (physical & 0x0000000f00000000ull) >> 28;
 1686         agp_i915_write_gtt(dev, index, pte);
 1687 }
 1688 
 1689 static void
 1690 agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte)
 1691 {
 1692         struct agp_i810_softc *sc;
 1693 
 1694         sc = device_get_softc(dev);
 1695         bus_write_4(sc->sc_res[1], index * 4, pte);
 1696         CTR2(KTR_AGP_I810, "915_pte %x %x", index, pte);
 1697 }
 1698 
 1699 static void
 1700 agp_i965_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1701     int flags)
 1702 {
 1703         uint32_t pte;
 1704 
 1705         pte = (u_int32_t)physical | I810_PTE_VALID;
 1706         if (flags == AGP_USER_CACHED_MEMORY)
 1707                 pte |= I830_PTE_SYSTEM_CACHED;
 1708         pte |= (physical & 0x0000000f00000000ull) >> 28;
 1709         agp_i965_write_gtt(dev, index, pte);
 1710 }
 1711 
 1712 static void
 1713 agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte)
 1714 {
 1715         struct agp_i810_softc *sc;
 1716 
 1717         sc = device_get_softc(dev);
 1718         bus_write_4(sc->sc_res[0], index * 4 + (512 * 1024), pte);
 1719         CTR2(KTR_AGP_I810, "965_pte %x %x", index, pte);
 1720 }
 1721 
 1722 static void
 1723 agp_g4x_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1724     int flags)
 1725 {
 1726         uint32_t pte;
 1727 
 1728         pte = (u_int32_t)physical | I810_PTE_VALID;
 1729         if (flags == AGP_USER_CACHED_MEMORY)
 1730                 pte |= I830_PTE_SYSTEM_CACHED;
 1731         pte |= (physical & 0x0000000f00000000ull) >> 28;
 1732         agp_g4x_write_gtt(dev, index, pte);
 1733 }
 1734 
 1735 static void
 1736 agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte)
 1737 {
 1738         struct agp_i810_softc *sc;
 1739 
 1740         sc = device_get_softc(dev);
 1741         bus_write_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024), pte);
 1742         CTR2(KTR_AGP_I810, "g4x_pte %x %x", index, pte);
 1743 }
 1744 
 1745 static void
 1746 agp_sb_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1747     int flags)
 1748 {
 1749         int type_mask, gfdt;
 1750         uint32_t pte;
 1751 
 1752         pte = (u_int32_t)physical | I810_PTE_VALID;
 1753         type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT;
 1754         gfdt = (flags & AGP_USER_CACHED_MEMORY_GFDT) != 0 ? GEN6_PTE_GFDT : 0;
 1755 
 1756         if (type_mask == AGP_USER_MEMORY)
 1757                 pte |= GEN6_PTE_UNCACHED;
 1758         else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC)
 1759                 pte |= GEN6_PTE_LLC_MLC | gfdt;
 1760         else
 1761                 pte |= GEN6_PTE_LLC | gfdt;
 1762 
 1763         pte |= (physical & 0x000000ff00000000ull) >> 28;
 1764         agp_sb_write_gtt(dev, index, pte);
 1765 }
 1766 
 1767 static void
 1768 agp_sb_write_gtt(device_t dev, u_int index, uint32_t pte)
 1769 {
 1770         struct agp_i810_softc *sc;
 1771 
 1772         sc = device_get_softc(dev);
 1773         bus_write_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024), pte);
 1774         CTR2(KTR_AGP_I810, "sb_pte %x %x", index, pte);
 1775 }
 1776 
 1777 static int
 1778 agp_i810_bind_page(device_t dev, vm_offset_t offset, vm_offset_t physical)
 1779 {
 1780         struct agp_i810_softc *sc = device_get_softc(dev);
 1781         u_int index;
 1782 
 1783         if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) {
 1784                 device_printf(dev, "failed: offset is 0x%08jx, "
 1785                     "shift is %d, entries is %d\n", (intmax_t)offset,
 1786                     AGP_PAGE_SHIFT, sc->gatt->ag_entries);
 1787                 return (EINVAL);
 1788         }
 1789         index = offset >> AGP_PAGE_SHIFT;
 1790         if (sc->stolen != 0 && index < sc->stolen) {
 1791                 device_printf(dev, "trying to bind into stolen memory\n");
 1792                 return (EINVAL);
 1793         }
 1794         sc->match->driver->install_gtt_pte(dev, index, physical, 0);
 1795         return (0);
 1796 }
 1797 
 1798 static int
 1799 agp_i810_unbind_page(device_t dev, vm_offset_t offset)
 1800 {
 1801         struct agp_i810_softc *sc;
 1802         u_int index;
 1803 
 1804         sc = device_get_softc(dev);
 1805         if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
 1806                 return (EINVAL);
 1807         index = offset >> AGP_PAGE_SHIFT;
 1808         if (sc->stolen != 0 && index < sc->stolen) {
 1809                 device_printf(dev, "trying to unbind from stolen memory\n");
 1810                 return (EINVAL);
 1811         }
 1812         sc->match->driver->install_gtt_pte(dev, index, 0, 0);
 1813         return (0);
 1814 }
 1815 
 1816 static u_int32_t
 1817 agp_i810_read_gtt_pte(device_t dev, u_int index)
 1818 {
 1819         struct agp_i810_softc *sc;
 1820         u_int32_t pte;
 1821 
 1822         sc = device_get_softc(dev);
 1823         pte = bus_read_4(sc->sc_res[0], AGP_I810_GTT + index * 4);
 1824         return (pte);
 1825 }
 1826 
 1827 static u_int32_t
 1828 agp_i915_read_gtt_pte(device_t dev, u_int index)
 1829 {
 1830         struct agp_i810_softc *sc;
 1831         u_int32_t pte;
 1832 
 1833         sc = device_get_softc(dev);
 1834         pte = bus_read_4(sc->sc_res[1], index * 4);
 1835         return (pte);
 1836 }
 1837 
 1838 static u_int32_t
 1839 agp_i965_read_gtt_pte(device_t dev, u_int index)
 1840 {
 1841         struct agp_i810_softc *sc;
 1842         u_int32_t pte;
 1843 
 1844         sc = device_get_softc(dev);
 1845         pte = bus_read_4(sc->sc_res[0], index * 4 + (512 * 1024));
 1846         return (pte);
 1847 }
 1848 
 1849 static u_int32_t
 1850 agp_g4x_read_gtt_pte(device_t dev, u_int index)
 1851 {
 1852         struct agp_i810_softc *sc;
 1853         u_int32_t pte;
 1854 
 1855         sc = device_get_softc(dev);
 1856         pte = bus_read_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024));
 1857         return (pte);
 1858 }
 1859 
 1860 static vm_paddr_t
 1861 agp_i810_read_gtt_pte_paddr(device_t dev, u_int index)
 1862 {
 1863         struct agp_i810_softc *sc;
 1864         u_int32_t pte;
 1865         vm_paddr_t res;
 1866 
 1867         sc = device_get_softc(dev);
 1868         pte = sc->match->driver->read_gtt_pte(dev, index);
 1869         res = pte & ~PAGE_MASK;
 1870         return (res);
 1871 }
 1872 
 1873 static vm_paddr_t
 1874 agp_i915_read_gtt_pte_paddr(device_t dev, u_int index)
 1875 {
 1876         struct agp_i810_softc *sc;
 1877         u_int32_t pte;
 1878         vm_paddr_t res;
 1879 
 1880         sc = device_get_softc(dev);
 1881         pte = sc->match->driver->read_gtt_pte(dev, index);
 1882         res = (pte & ~PAGE_MASK) | ((pte & 0xf0) << 28);
 1883         return (res);
 1884 }
 1885 
 1886 static vm_paddr_t
 1887 agp_sb_read_gtt_pte_paddr(device_t dev, u_int index)
 1888 {
 1889         struct agp_i810_softc *sc;
 1890         u_int32_t pte;
 1891         vm_paddr_t res;
 1892 
 1893         sc = device_get_softc(dev);
 1894         pte = sc->match->driver->read_gtt_pte(dev, index);
 1895         res = (pte & ~PAGE_MASK) | ((pte & 0xff0) << 28);
 1896         return (res);
 1897 }
 1898 
 1899 /*
 1900  * Writing via memory mapped registers already flushes all TLBs.
 1901  */
 1902 static void
 1903 agp_i810_flush_tlb(device_t dev)
 1904 {
 1905 }
 1906 
 1907 static int
 1908 agp_i810_enable(device_t dev, u_int32_t mode)
 1909 {
 1910 
 1911         return (0);
 1912 }
 1913 
 1914 static struct agp_memory *
 1915 agp_i810_alloc_memory(device_t dev, int type, vm_size_t size)
 1916 {
 1917         struct agp_i810_softc *sc;
 1918         struct agp_memory *mem;
 1919         vm_page_t m;
 1920 
 1921         sc = device_get_softc(dev);
 1922 
 1923         if ((size & (AGP_PAGE_SIZE - 1)) != 0 ||
 1924             sc->agp.as_allocated + size > sc->agp.as_maxmem)
 1925                 return (0);
 1926 
 1927         if (type == 1) {
 1928                 /*
 1929                  * Mapping local DRAM into GATT.
 1930                  */
 1931                 if (sc->match->driver->chiptype != CHIP_I810)
 1932                         return (0);
 1933                 if (size != sc->dcache_size)
 1934                         return (0);
 1935         } else if (type == 2) {
 1936                 /*
 1937                  * Type 2 is the contiguous physical memory type, that hands
 1938                  * back a physical address.  This is used for cursors on i810.
 1939                  * Hand back as many single pages with physical as the user
 1940                  * wants, but only allow one larger allocation (ARGB cursor)
 1941                  * for simplicity.
 1942                  */
 1943                 if (size != AGP_PAGE_SIZE) {
 1944                         if (sc->argb_cursor != NULL)
 1945                                 return (0);
 1946 
 1947                         /* Allocate memory for ARGB cursor, if we can. */
 1948                         sc->argb_cursor = contigmalloc(size, M_AGP,
 1949                            0, 0, ~0, PAGE_SIZE, 0);
 1950                         if (sc->argb_cursor == NULL)
 1951                                 return (0);
 1952                 }
 1953         }
 1954 
 1955         mem = malloc(sizeof *mem, M_AGP, M_WAITOK);
 1956         mem->am_id = sc->agp.as_nextid++;
 1957         mem->am_size = size;
 1958         mem->am_type = type;
 1959         if (type != 1 && (type != 2 || size == AGP_PAGE_SIZE))
 1960                 mem->am_obj = vm_object_allocate(OBJT_DEFAULT,
 1961                     atop(round_page(size)));
 1962         else
 1963                 mem->am_obj = 0;
 1964 
 1965         if (type == 2) {
 1966                 if (size == AGP_PAGE_SIZE) {
 1967                         /*
 1968                          * Allocate and wire down the page now so that we can
 1969                          * get its physical address.
 1970                          */
 1971                         VM_OBJECT_WLOCK(mem->am_obj);
 1972                         m = vm_page_grab(mem->am_obj, 0, VM_ALLOC_NOBUSY |
 1973                             VM_ALLOC_WIRED | VM_ALLOC_ZERO);
 1974                         VM_OBJECT_WUNLOCK(mem->am_obj);
 1975                         mem->am_physical = VM_PAGE_TO_PHYS(m);
 1976                 } else {
 1977                         /* Our allocation is already nicely wired down for us.
 1978                          * Just grab the physical address.
 1979                          */
 1980                         mem->am_physical = vtophys(sc->argb_cursor);
 1981                 }
 1982         } else
 1983                 mem->am_physical = 0;
 1984 
 1985         mem->am_offset = 0;
 1986         mem->am_is_bound = 0;
 1987         TAILQ_INSERT_TAIL(&sc->agp.as_memory, mem, am_link);
 1988         sc->agp.as_allocated += size;
 1989 
 1990         return (mem);
 1991 }
 1992 
 1993 static int
 1994 agp_i810_free_memory(device_t dev, struct agp_memory *mem)
 1995 {
 1996         struct agp_i810_softc *sc;
 1997         vm_page_t m;
 1998 
 1999         if (mem->am_is_bound)
 2000                 return (EBUSY);
 2001 
 2002         sc = device_get_softc(dev);
 2003 
 2004         if (mem->am_type == 2) {
 2005                 if (mem->am_size == AGP_PAGE_SIZE) {
 2006                         /*
 2007                          * Unwire the page which we wired in alloc_memory.
 2008                          */
 2009                         VM_OBJECT_WLOCK(mem->am_obj);
 2010                         m = vm_page_lookup(mem->am_obj, 0);
 2011                         vm_page_lock(m);
 2012                         vm_page_unwire(m, 0);
 2013                         vm_page_unlock(m);
 2014                         VM_OBJECT_WUNLOCK(mem->am_obj);
 2015                 } else {
 2016                         contigfree(sc->argb_cursor, mem->am_size, M_AGP);
 2017                         sc->argb_cursor = NULL;
 2018                 }
 2019         }
 2020 
 2021         sc->agp.as_allocated -= mem->am_size;
 2022         TAILQ_REMOVE(&sc->agp.as_memory, mem, am_link);
 2023         if (mem->am_obj)
 2024                 vm_object_deallocate(mem->am_obj);
 2025         free(mem, M_AGP);
 2026         return (0);
 2027 }
 2028 
 2029 static int
 2030 agp_i810_bind_memory(device_t dev, struct agp_memory *mem, vm_offset_t offset)
 2031 {
 2032         struct agp_i810_softc *sc;
 2033         vm_offset_t i;
 2034 
 2035         /* Do some sanity checks first. */
 2036         if ((offset & (AGP_PAGE_SIZE - 1)) != 0 ||
 2037             offset + mem->am_size > AGP_GET_APERTURE(dev)) {
 2038                 device_printf(dev, "binding memory at bad offset %#x\n",
 2039                     (int)offset);
 2040                 return (EINVAL);
 2041         }
 2042 
 2043         sc = device_get_softc(dev);
 2044         if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
 2045                 mtx_lock(&sc->agp.as_lock);
 2046                 if (mem->am_is_bound) {
 2047                         mtx_unlock(&sc->agp.as_lock);
 2048                         return (EINVAL);
 2049                 }
 2050                 /* The memory's already wired down, just stick it in the GTT. */
 2051                 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
 2052                         sc->match->driver->install_gtt_pte(dev, (offset + i) >>
 2053                             AGP_PAGE_SHIFT, mem->am_physical + i, 0);
 2054                 }
 2055                 agp_flush_cache();
 2056                 mem->am_offset = offset;
 2057                 mem->am_is_bound = 1;
 2058                 mtx_unlock(&sc->agp.as_lock);
 2059                 return (0);
 2060         }
 2061 
 2062         if (mem->am_type != 1)
 2063                 return (agp_generic_bind_memory(dev, mem, offset));
 2064 
 2065         /*
 2066          * Mapping local DRAM into GATT.
 2067          */
 2068         if (sc->match->driver->chiptype != CHIP_I810)
 2069                 return (EINVAL);
 2070         for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
 2071                 bus_write_4(sc->sc_res[0],
 2072                     AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, i | 3);
 2073 
 2074         return (0);
 2075 }
 2076 
 2077 static int
 2078 agp_i810_unbind_memory(device_t dev, struct agp_memory *mem)
 2079 {
 2080         struct agp_i810_softc *sc;
 2081         vm_offset_t i;
 2082 
 2083         sc = device_get_softc(dev);
 2084 
 2085         if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
 2086                 mtx_lock(&sc->agp.as_lock);
 2087                 if (!mem->am_is_bound) {
 2088                         mtx_unlock(&sc->agp.as_lock);
 2089                         return (EINVAL);
 2090                 }
 2091 
 2092                 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
 2093                         sc->match->driver->install_gtt_pte(dev,
 2094                             (mem->am_offset + i) >> AGP_PAGE_SHIFT, 0, 0);
 2095                 }
 2096                 agp_flush_cache();
 2097                 mem->am_is_bound = 0;
 2098                 mtx_unlock(&sc->agp.as_lock);
 2099                 return (0);
 2100         }
 2101 
 2102         if (mem->am_type != 1)
 2103                 return (agp_generic_unbind_memory(dev, mem));
 2104 
 2105         if (sc->match->driver->chiptype != CHIP_I810)
 2106                 return (EINVAL);
 2107         for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
 2108                 sc->match->driver->install_gtt_pte(dev, i >> AGP_PAGE_SHIFT,
 2109                     0, 0);
 2110         }
 2111         return (0);
 2112 }
 2113 
 2114 static device_method_t agp_i810_methods[] = {
 2115         /* Device interface */
 2116         DEVMETHOD(device_identify,      agp_i810_identify),
 2117         DEVMETHOD(device_probe,         agp_i810_probe),
 2118         DEVMETHOD(device_attach,        agp_i810_attach),
 2119         DEVMETHOD(device_detach,        agp_i810_detach),
 2120         DEVMETHOD(device_suspend,       bus_generic_suspend),
 2121         DEVMETHOD(device_resume,        agp_i810_resume),
 2122 
 2123         /* AGP interface */
 2124         DEVMETHOD(agp_get_aperture,     agp_generic_get_aperture),
 2125         DEVMETHOD(agp_set_aperture,     agp_i810_method_set_aperture),
 2126         DEVMETHOD(agp_bind_page,        agp_i810_bind_page),
 2127         DEVMETHOD(agp_unbind_page,      agp_i810_unbind_page),
 2128         DEVMETHOD(agp_flush_tlb,        agp_i810_flush_tlb),
 2129         DEVMETHOD(agp_enable,           agp_i810_enable),
 2130         DEVMETHOD(agp_alloc_memory,     agp_i810_alloc_memory),
 2131         DEVMETHOD(agp_free_memory,      agp_i810_free_memory),
 2132         DEVMETHOD(agp_bind_memory,      agp_i810_bind_memory),
 2133         DEVMETHOD(agp_unbind_memory,    agp_i810_unbind_memory),
 2134         DEVMETHOD(agp_chipset_flush,    agp_intel_gtt_chipset_flush),
 2135 
 2136         { 0, 0 }
 2137 };
 2138 
 2139 static driver_t agp_i810_driver = {
 2140         "agp",
 2141         agp_i810_methods,
 2142         sizeof(struct agp_i810_softc),
 2143 };
 2144 
 2145 static devclass_t agp_devclass;
 2146 
 2147 DRIVER_MODULE(agp_i810, vgapci, agp_i810_driver, agp_devclass, 0, 0);
 2148 MODULE_DEPEND(agp_i810, agp, 1, 1, 1);
 2149 MODULE_DEPEND(agp_i810, pci, 1, 1, 1);
 2150 
 2151 extern vm_page_t bogus_page;
 2152 
 2153 void
 2154 agp_intel_gtt_clear_range(device_t dev, u_int first_entry, u_int num_entries)
 2155 {
 2156         struct agp_i810_softc *sc;
 2157         u_int i;
 2158 
 2159         sc = device_get_softc(dev);
 2160         for (i = 0; i < num_entries; i++)
 2161                 sc->match->driver->install_gtt_pte(dev, first_entry + i,
 2162                     VM_PAGE_TO_PHYS(bogus_page), 0);
 2163         sc->match->driver->read_gtt_pte(dev, first_entry + num_entries - 1);
 2164 }
 2165 
 2166 void
 2167 agp_intel_gtt_insert_pages(device_t dev, u_int first_entry, u_int num_entries,
 2168     vm_page_t *pages, u_int flags)
 2169 {
 2170         struct agp_i810_softc *sc;
 2171         u_int i;
 2172 
 2173         sc = device_get_softc(dev);
 2174         for (i = 0; i < num_entries; i++) {
 2175                 MPASS(pages[i]->valid == VM_PAGE_BITS_ALL);
 2176                 MPASS(pages[i]->wire_count > 0);
 2177                 sc->match->driver->install_gtt_pte(dev, first_entry + i,
 2178                     VM_PAGE_TO_PHYS(pages[i]), flags);
 2179         }
 2180         sc->match->driver->read_gtt_pte(dev, first_entry + num_entries - 1);
 2181 }
 2182 
 2183 struct intel_gtt
 2184 agp_intel_gtt_get(device_t dev)
 2185 {
 2186         struct agp_i810_softc *sc;
 2187         struct intel_gtt res;
 2188 
 2189         sc = device_get_softc(dev);
 2190         res.stolen_size = sc->stolen_size;
 2191         res.gtt_total_entries = sc->gtt_total_entries;
 2192         res.gtt_mappable_entries = sc->gtt_mappable_entries;
 2193         res.do_idle_maps = 0;
 2194         res.scratch_page_dma = VM_PAGE_TO_PHYS(bogus_page);
 2195         return (res);
 2196 }
 2197 
 2198 static int
 2199 agp_i810_chipset_flush_setup(device_t dev)
 2200 {
 2201 
 2202         return (0);
 2203 }
 2204 
 2205 static void
 2206 agp_i810_chipset_flush_teardown(device_t dev)
 2207 {
 2208 
 2209         /* Nothing to do. */
 2210 }
 2211 
 2212 static void
 2213 agp_i810_chipset_flush(device_t dev)
 2214 {
 2215 
 2216         /* Nothing to do. */
 2217 }
 2218 
 2219 static void
 2220 agp_i830_chipset_flush(device_t dev)
 2221 {
 2222         struct agp_i810_softc *sc;
 2223         uint32_t hic;
 2224         int i;
 2225 
 2226         sc = device_get_softc(dev);
 2227         pmap_invalidate_cache();
 2228         hic = bus_read_4(sc->sc_res[0], AGP_I830_HIC);
 2229         bus_write_4(sc->sc_res[0], AGP_I830_HIC, hic | (1U << 31));
 2230         for (i = 0; i < 20000 /* 1 sec */; i++) {
 2231                 hic = bus_read_4(sc->sc_res[0], AGP_I830_HIC);
 2232                 if ((hic & (1U << 31)) == 0)
 2233                         break;
 2234                 DELAY(50);
 2235         }
 2236 }
 2237 
 2238 static int
 2239 agp_i915_chipset_flush_alloc_page(device_t dev, uint64_t start, uint64_t end)
 2240 {
 2241         struct agp_i810_softc *sc;
 2242         device_t vga;
 2243 
 2244         sc = device_get_softc(dev);
 2245         vga = device_get_parent(dev);
 2246         sc->sc_flush_page_rid = 100;
 2247         sc->sc_flush_page_res = BUS_ALLOC_RESOURCE(device_get_parent(vga), dev,
 2248             SYS_RES_MEMORY, &sc->sc_flush_page_rid, start, end, PAGE_SIZE,
 2249             RF_ACTIVE);
 2250         if (sc->sc_flush_page_res == NULL) {
 2251                 device_printf(dev, "Failed to allocate flush page at 0x%jx\n",
 2252                     (uintmax_t)start);
 2253                 return (EINVAL);
 2254         }
 2255         sc->sc_flush_page_vaddr = rman_get_virtual(sc->sc_flush_page_res);
 2256         if (bootverbose) {
 2257                 device_printf(dev, "Allocated flush page phys 0x%jx virt %p\n",
 2258                     (uintmax_t)rman_get_start(sc->sc_flush_page_res),
 2259                     sc->sc_flush_page_vaddr);
 2260         }
 2261         return (0);
 2262 }
 2263 
 2264 static void
 2265 agp_i915_chipset_flush_free_page(device_t dev)
 2266 {
 2267         struct agp_i810_softc *sc;
 2268         device_t vga;
 2269 
 2270         sc = device_get_softc(dev);
 2271         vga = device_get_parent(dev);
 2272         if (sc->sc_flush_page_res == NULL)
 2273                 return;
 2274         BUS_DEACTIVATE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY,
 2275             sc->sc_flush_page_rid, sc->sc_flush_page_res);
 2276         BUS_RELEASE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY,
 2277             sc->sc_flush_page_rid, sc->sc_flush_page_res);
 2278 }
 2279 
 2280 static int
 2281 agp_i915_chipset_flush_setup(device_t dev)
 2282 {
 2283         struct agp_i810_softc *sc;
 2284         uint32_t temp;
 2285         int error;
 2286 
 2287         sc = device_get_softc(dev);
 2288         temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4);
 2289         if ((temp & 1) != 0) {
 2290                 temp &= ~1;
 2291                 if (bootverbose)
 2292                         device_printf(dev,
 2293                             "Found already configured flush page at 0x%jx\n",
 2294                             (uintmax_t)temp);
 2295                 sc->sc_bios_allocated_flush_page = 1;
 2296                 /*
 2297                  * In the case BIOS initialized the flush pointer (?)
 2298                  * register, expect that BIOS also set up the resource
 2299                  * for the page.
 2300                  */
 2301                 error = agp_i915_chipset_flush_alloc_page(dev, temp,
 2302                     temp + PAGE_SIZE - 1);
 2303                 if (error != 0)
 2304                         return (error);
 2305         } else {
 2306                 sc->sc_bios_allocated_flush_page = 0;
 2307                 error = agp_i915_chipset_flush_alloc_page(dev, 0, 0xffffffff);
 2308                 if (error != 0)
 2309                         return (error);
 2310                 temp = rman_get_start(sc->sc_flush_page_res);
 2311                 pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp | 1, 4);
 2312         }
 2313         return (0);
 2314 }
 2315 
 2316 static void
 2317 agp_i915_chipset_flush_teardown(device_t dev)
 2318 {
 2319         struct agp_i810_softc *sc;
 2320         uint32_t temp;
 2321 
 2322         sc = device_get_softc(dev);
 2323         if (sc->sc_flush_page_res == NULL)
 2324                 return;
 2325         if (!sc->sc_bios_allocated_flush_page) {
 2326                 temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4);
 2327                 temp &= ~1;
 2328                 pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp, 4);
 2329         }               
 2330         agp_i915_chipset_flush_free_page(dev);
 2331 }
 2332 
 2333 static int
 2334 agp_i965_chipset_flush_setup(device_t dev)
 2335 {
 2336         struct agp_i810_softc *sc;
 2337         uint64_t temp;
 2338         uint32_t temp_hi, temp_lo;
 2339         int error;
 2340 
 2341         sc = device_get_softc(dev);
 2342 
 2343         temp_hi = pci_read_config(sc->bdev, AGP_I965_IFPADDR + 4, 4);
 2344         temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4);
 2345 
 2346         if ((temp_lo & 1) != 0) {
 2347                 temp = ((uint64_t)temp_hi << 32) | (temp_lo & ~1);
 2348                 if (bootverbose)
 2349                         device_printf(dev,
 2350                             "Found already configured flush page at 0x%jx\n",
 2351                             (uintmax_t)temp);
 2352                 sc->sc_bios_allocated_flush_page = 1;
 2353                 /*
 2354                  * In the case BIOS initialized the flush pointer (?)
 2355                  * register, expect that BIOS also set up the resource
 2356                  * for the page.
 2357                  */
 2358                 error = agp_i915_chipset_flush_alloc_page(dev, temp,
 2359                     temp + PAGE_SIZE - 1);
 2360                 if (error != 0)
 2361                         return (error);
 2362         } else {
 2363                 sc->sc_bios_allocated_flush_page = 0;
 2364                 error = agp_i915_chipset_flush_alloc_page(dev, 0, ~0);
 2365                 if (error != 0)
 2366                         return (error);
 2367                 temp = rman_get_start(sc->sc_flush_page_res);
 2368                 pci_write_config(sc->bdev, AGP_I965_IFPADDR + 4,
 2369                     (temp >> 32) & UINT32_MAX, 4);
 2370                 pci_write_config(sc->bdev, AGP_I965_IFPADDR,
 2371                     (temp & UINT32_MAX) | 1, 4);
 2372         }
 2373         return (0);
 2374 }
 2375 
 2376 static void
 2377 agp_i965_chipset_flush_teardown(device_t dev)
 2378 {
 2379         struct agp_i810_softc *sc;
 2380         uint32_t temp_lo;
 2381 
 2382         sc = device_get_softc(dev);
 2383         if (sc->sc_flush_page_res == NULL)
 2384                 return;
 2385         if (!sc->sc_bios_allocated_flush_page) {
 2386                 temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4);
 2387                 temp_lo &= ~1;
 2388                 pci_write_config(sc->bdev, AGP_I965_IFPADDR, temp_lo, 4);
 2389         }
 2390         agp_i915_chipset_flush_free_page(dev);
 2391 }
 2392 
 2393 static void
 2394 agp_i915_chipset_flush(device_t dev)
 2395 {
 2396         struct agp_i810_softc *sc;
 2397 
 2398         sc = device_get_softc(dev);
 2399         *(uint32_t *)sc->sc_flush_page_vaddr = 1;
 2400 }
 2401 
 2402 int
 2403 agp_intel_gtt_chipset_flush(device_t dev)
 2404 {
 2405         struct agp_i810_softc *sc;
 2406 
 2407         sc = device_get_softc(dev);
 2408         sc->match->driver->chipset_flush(dev);
 2409         return (0);
 2410 }
 2411 
 2412 void
 2413 agp_intel_gtt_unmap_memory(device_t dev, struct sglist *sg_list)
 2414 {
 2415 }
 2416 
 2417 int
 2418 agp_intel_gtt_map_memory(device_t dev, vm_page_t *pages, u_int num_entries,
 2419     struct sglist **sg_list)
 2420 {
 2421         struct agp_i810_softc *sc;
 2422         struct sglist *sg;
 2423         int i;
 2424 #if 0
 2425         int error;
 2426         bus_dma_tag_t dmat;
 2427 #endif
 2428 
 2429         if (*sg_list != NULL)
 2430                 return (0);
 2431         sc = device_get_softc(dev);
 2432         sg = sglist_alloc(num_entries, M_WAITOK /* XXXKIB */);
 2433         for (i = 0; i < num_entries; i++) {
 2434                 sg->sg_segs[i].ss_paddr = VM_PAGE_TO_PHYS(pages[i]);
 2435                 sg->sg_segs[i].ss_len = PAGE_SIZE;
 2436         }
 2437 
 2438 #if 0
 2439         error = bus_dma_tag_create(bus_get_dma_tag(dev),
 2440             1 /* alignment */, 0 /* boundary */,
 2441             1ULL << sc->match->busdma_addr_mask_sz /* lowaddr */,
 2442             BUS_SPACE_MAXADDR /* highaddr */,
 2443             NULL /* filtfunc */, NULL /* filtfuncarg */,
 2444             BUS_SPACE_MAXADDR /* maxsize */,
 2445             BUS_SPACE_UNRESTRICTED /* nsegments */,
 2446             BUS_SPACE_MAXADDR /* maxsegsz */,
 2447             0 /* flags */, NULL /* lockfunc */, NULL /* lockfuncarg */,
 2448             &dmat);
 2449         if (error != 0) {
 2450                 sglist_free(sg);
 2451                 return (error);
 2452         }
 2453         /* XXXKIB */
 2454 #endif
 2455         *sg_list = sg;
 2456         return (0);
 2457 }
 2458 
 2459 void
 2460 agp_intel_gtt_insert_sg_entries(device_t dev, struct sglist *sg_list,
 2461     u_int first_entry, u_int flags)
 2462 {
 2463         struct agp_i810_softc *sc;
 2464         vm_paddr_t spaddr;
 2465         size_t slen;
 2466         u_int i, j;
 2467 
 2468         sc = device_get_softc(dev);
 2469         for (i = j = 0; j < sg_list->sg_nseg; j++) {
 2470                 spaddr = sg_list->sg_segs[i].ss_paddr;
 2471                 slen = sg_list->sg_segs[i].ss_len;
 2472                 for (; slen > 0; i++) {
 2473                         sc->match->driver->install_gtt_pte(dev, first_entry + i,
 2474                             spaddr, flags);
 2475                         spaddr += AGP_PAGE_SIZE;
 2476                         slen -= AGP_PAGE_SIZE;
 2477                 }
 2478         }
 2479         sc->match->driver->read_gtt_pte(dev, first_entry + i - 1);
 2480 }
 2481 
 2482 void
 2483 intel_gtt_clear_range(u_int first_entry, u_int num_entries)
 2484 {
 2485 
 2486         agp_intel_gtt_clear_range(intel_agp, first_entry, num_entries);
 2487 }
 2488 
 2489 void
 2490 intel_gtt_insert_pages(u_int first_entry, u_int num_entries, vm_page_t *pages,
 2491     u_int flags)
 2492 {
 2493 
 2494         agp_intel_gtt_insert_pages(intel_agp, first_entry, num_entries,
 2495             pages, flags);
 2496 }
 2497 
 2498 struct intel_gtt
 2499 intel_gtt_get(void)
 2500 {
 2501 
 2502         return (agp_intel_gtt_get(intel_agp));
 2503 }
 2504 
 2505 int
 2506 intel_gtt_chipset_flush(void)
 2507 {
 2508 
 2509         return (agp_intel_gtt_chipset_flush(intel_agp));
 2510 }
 2511 
 2512 void
 2513 intel_gtt_unmap_memory(struct sglist *sg_list)
 2514 {
 2515 
 2516         agp_intel_gtt_unmap_memory(intel_agp, sg_list);
 2517 }
 2518 
 2519 int
 2520 intel_gtt_map_memory(vm_page_t *pages, u_int num_entries,
 2521     struct sglist **sg_list)
 2522 {
 2523 
 2524         return (agp_intel_gtt_map_memory(intel_agp, pages, num_entries,
 2525             sg_list));
 2526 }
 2527 
 2528 void
 2529 intel_gtt_insert_sg_entries(struct sglist *sg_list, u_int first_entry,
 2530     u_int flags)
 2531 {
 2532 
 2533         agp_intel_gtt_insert_sg_entries(intel_agp, sg_list, first_entry, flags);
 2534 }
 2535 
 2536 device_t
 2537 intel_gtt_get_bridge_device(void)
 2538 {
 2539         struct agp_i810_softc *sc;
 2540 
 2541         sc = device_get_softc(intel_agp);
 2542         return (sc->bdev);
 2543 }
 2544 
 2545 vm_paddr_t
 2546 intel_gtt_read_pte_paddr(u_int entry)
 2547 {
 2548         struct agp_i810_softc *sc;
 2549 
 2550         sc = device_get_softc(intel_agp);
 2551         return (sc->match->driver->read_gtt_pte_paddr(intel_agp, entry));
 2552 }
 2553 
 2554 u_int32_t
 2555 intel_gtt_read_pte(u_int entry)
 2556 {
 2557         struct agp_i810_softc *sc;
 2558 
 2559         sc = device_get_softc(intel_agp);
 2560         return (sc->match->driver->read_gtt_pte(intel_agp, entry));
 2561 }
 2562 
 2563 void
 2564 intel_gtt_write(u_int entry, uint32_t val)
 2565 {
 2566         struct agp_i810_softc *sc;
 2567 
 2568         sc = device_get_softc(intel_agp);
 2569         return (sc->match->driver->write_gtt(intel_agp, entry, val));
 2570 }

Cache object: 16b306dd316a7cc1d78d01c3df8755fb


[ 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.