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-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
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/9.1/sys/dev/agp/agp_i810.c 237594 2012-06-26 10:32:09Z kib $");
   42 
   43 #include "opt_bus.h"
   44 
   45 #if 0
   46 #define KTR_AGP_I810    KTR_DEV
   47 #else
   48 #define KTR_AGP_I810    0
   49 #endif
   50 
   51 #include <sys/param.h>
   52 #include <sys/systm.h>
   53 #include <sys/malloc.h>
   54 #include <sys/kernel.h>
   55 #include <sys/ktr.h>
   56 #include <sys/module.h>
   57 #include <sys/bus.h>
   58 #include <sys/lock.h>
   59 #include <sys/mutex.h>
   60 #include <sys/proc.h>
   61 
   62 #include <dev/agp/agppriv.h>
   63 #include <dev/agp/agpreg.h>
   64 #include <dev/agp/agp_i810.h>
   65 #include <dev/pci/pcivar.h>
   66 #include <dev/pci/pcireg.h>
   67 #include <dev/pci/pci_private.h>
   68 
   69 #include <vm/vm.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 = 0,
  734         }
  735 };
  736 
  737 static const struct agp_i810_match*
  738 agp_i810_match(device_t dev)
  739 {
  740         int i, devid;
  741 
  742         if (pci_get_class(dev) != PCIC_DISPLAY
  743             || pci_get_subclass(dev) != PCIS_DISPLAY_VGA)
  744                 return (NULL);
  745 
  746         devid = pci_get_devid(dev);
  747         for (i = 0; agp_i810_matches[i].devid != 0; i++) {
  748                 if (agp_i810_matches[i].devid == devid)
  749                         break;
  750         }
  751         if (agp_i810_matches[i].devid == 0)
  752                 return (NULL);
  753         else
  754                 return (&agp_i810_matches[i]);
  755 }
  756 
  757 /*
  758  * Find bridge device.
  759  */
  760 static device_t
  761 agp_i810_find_bridge(device_t dev)
  762 {
  763 
  764         return (pci_find_dbsf(0, 0, 0, 0));
  765 }
  766 
  767 static void
  768 agp_i810_identify(driver_t *driver, device_t parent)
  769 {
  770 
  771         if (device_find_child(parent, "agp", -1) == NULL &&
  772             agp_i810_match(parent))
  773                 device_add_child(parent, "agp", -1);
  774 }
  775 
  776 static int
  777 agp_i810_check_active(device_t bridge_dev)
  778 {
  779         u_int8_t smram;
  780 
  781         smram = pci_read_config(bridge_dev, AGP_I810_SMRAM, 1);
  782         if ((smram & AGP_I810_SMRAM_GMS) == AGP_I810_SMRAM_GMS_DISABLED)
  783                 return (ENXIO);
  784         return (0);
  785 }
  786 
  787 static int
  788 agp_i830_check_active(device_t bridge_dev)
  789 {
  790         int gcc1;
  791 
  792         gcc1 = pci_read_config(bridge_dev, AGP_I830_GCC1, 1);
  793         if ((gcc1 & AGP_I830_GCC1_DEV2) == AGP_I830_GCC1_DEV2_DISABLED)
  794                 return (ENXIO);
  795         return (0);
  796 }
  797 
  798 static int
  799 agp_i915_check_active(device_t bridge_dev)
  800 {
  801         int deven;
  802 
  803         deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4);
  804         if ((deven & AGP_I915_DEVEN_D2F0) == AGP_I915_DEVEN_D2F0_DISABLED)
  805                 return (ENXIO);
  806         return (0);
  807 }
  808 
  809 static int
  810 agp_sb_check_active(device_t bridge_dev)
  811 {
  812         int deven;
  813 
  814         deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4);
  815         if ((deven & AGP_SB_DEVEN_D2EN) == AGP_SB_DEVEN_D2EN_DISABLED)
  816                 return (ENXIO);
  817         return (0);
  818 }
  819 
  820 static void
  821 agp_82852_set_desc(device_t dev, const struct agp_i810_match *match)
  822 {
  823 
  824         switch (pci_read_config(dev, AGP_I85X_CAPID, 1)) {
  825         case AGP_I855_GME:
  826                 device_set_desc(dev,
  827                     "Intel 82855GME (855GME GMCH) SVGA controller");
  828                 break;
  829         case AGP_I855_GM:
  830                 device_set_desc(dev,
  831                     "Intel 82855GM (855GM GMCH) SVGA controller");
  832                 break;
  833         case AGP_I852_GME:
  834                 device_set_desc(dev,
  835                     "Intel 82852GME (852GME GMCH) SVGA controller");
  836                 break;
  837         case AGP_I852_GM:
  838                 device_set_desc(dev,
  839                     "Intel 82852GM (852GM GMCH) SVGA controller");
  840                 break;
  841         default:
  842                 device_set_desc(dev,
  843                     "Intel 8285xM (85xGM GMCH) SVGA controller");
  844                 break;
  845         }
  846 }
  847 
  848 static void
  849 agp_i810_set_desc(device_t dev, const struct agp_i810_match *match)
  850 {
  851 
  852         device_set_desc(dev, match->name);
  853 }
  854 
  855 static int
  856 agp_i810_probe(device_t dev)
  857 {
  858         device_t bdev;
  859         const struct agp_i810_match *match;
  860         int err;
  861 
  862         if (resource_disabled("agp", device_get_unit(dev)))
  863                 return (ENXIO);
  864         match = agp_i810_match(dev);
  865         if (match == NULL)
  866                 return (ENXIO);
  867 
  868         bdev = agp_i810_find_bridge(dev);
  869         if (bdev == NULL) {
  870                 if (bootverbose)
  871                         printf("I810: can't find bridge device\n");
  872                 return (ENXIO);
  873         }
  874 
  875         /*
  876          * checking whether internal graphics device has been activated.
  877          */
  878         err = match->driver->check_active(bdev);
  879         if (err != 0) {
  880                 if (bootverbose)
  881                         printf("i810: disabled, not probing\n");
  882                 return (err);
  883         }
  884 
  885         match->driver->set_desc(dev, match);
  886         return (BUS_PROBE_DEFAULT);
  887 }
  888 
  889 static void
  890 agp_i810_dump_regs(device_t dev)
  891 {
  892         struct agp_i810_softc *sc = device_get_softc(dev);
  893 
  894         device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
  895             bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
  896         device_printf(dev, "AGP_I810_MISCC: 0x%04x\n",
  897             pci_read_config(sc->bdev, AGP_I810_MISCC, 2));
  898 }
  899 
  900 static void
  901 agp_i830_dump_regs(device_t dev)
  902 {
  903         struct agp_i810_softc *sc = device_get_softc(dev);
  904 
  905         device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
  906             bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
  907         device_printf(dev, "AGP_I830_GCC1: 0x%02x\n",
  908             pci_read_config(sc->bdev, AGP_I830_GCC1, 1));
  909 }
  910 
  911 static void
  912 agp_i855_dump_regs(device_t dev)
  913 {
  914         struct agp_i810_softc *sc = device_get_softc(dev);
  915 
  916         device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
  917             bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
  918         device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
  919             pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
  920 }
  921 
  922 static void
  923 agp_i915_dump_regs(device_t dev)
  924 {
  925         struct agp_i810_softc *sc = device_get_softc(dev);
  926 
  927         device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
  928             bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
  929         device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
  930             pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
  931         device_printf(dev, "AGP_I915_MSAC: 0x%02x\n",
  932             pci_read_config(sc->bdev, AGP_I915_MSAC, 1));
  933 }
  934 
  935 static void
  936 agp_i965_dump_regs(device_t dev)
  937 {
  938         struct agp_i810_softc *sc = device_get_softc(dev);
  939 
  940         device_printf(dev, "AGP_I965_PGTBL_CTL2: %08x\n",
  941             bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2));
  942         device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
  943             pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
  944         device_printf(dev, "AGP_I965_MSAC: 0x%02x\n",
  945             pci_read_config(sc->bdev, AGP_I965_MSAC, 1));
  946 }
  947 
  948 static void
  949 agp_sb_dump_regs(device_t dev)
  950 {
  951         struct agp_i810_softc *sc = device_get_softc(dev);
  952 
  953         device_printf(dev, "AGP_SNB_GFX_MODE: %08x\n",
  954             bus_read_4(sc->sc_res[0], AGP_SNB_GFX_MODE));
  955         device_printf(dev, "AGP_SNB_GCC1: 0x%04x\n",
  956             pci_read_config(sc->bdev, AGP_SNB_GCC1, 2));
  957 }
  958 
  959 static int
  960 agp_i810_get_stolen_size(device_t dev)
  961 {
  962         struct agp_i810_softc *sc;
  963 
  964         sc = device_get_softc(dev);
  965         sc->stolen = 0;
  966         sc->stolen_size = 0;
  967         return (0);
  968 }
  969 
  970 static int
  971 agp_i830_get_stolen_size(device_t dev)
  972 {
  973         struct agp_i810_softc *sc;
  974         unsigned int gcc1;
  975 
  976         sc = device_get_softc(dev);
  977 
  978         gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 1);
  979         switch (gcc1 & AGP_I830_GCC1_GMS) {
  980         case AGP_I830_GCC1_GMS_STOLEN_512:
  981                 sc->stolen = (512 - 132) * 1024 / 4096;
  982                 sc->stolen_size = 512 * 1024;
  983                 break;
  984         case AGP_I830_GCC1_GMS_STOLEN_1024: 
  985                 sc->stolen = (1024 - 132) * 1024 / 4096;
  986                 sc->stolen_size = 1024 * 1024;
  987                 break;
  988         case AGP_I830_GCC1_GMS_STOLEN_8192: 
  989                 sc->stolen = (8192 - 132) * 1024 / 4096;
  990                 sc->stolen_size = 8192 * 1024;
  991                 break;
  992         default:
  993                 sc->stolen = 0;
  994                 device_printf(dev,
  995                     "unknown memory configuration, disabling (GCC1 %x)\n",
  996                     gcc1);
  997                 return (EINVAL);
  998         }
  999         return (0);
 1000 }
 1001 
 1002 static int
 1003 agp_i915_get_stolen_size(device_t dev)
 1004 {
 1005         struct agp_i810_softc *sc;
 1006         unsigned int gcc1, stolen, gtt_size;
 1007 
 1008         sc = device_get_softc(dev);
 1009 
 1010         /*
 1011          * Stolen memory is set up at the beginning of the aperture by
 1012          * the BIOS, consisting of the GATT followed by 4kb for the
 1013          * BIOS display.
 1014          */
 1015         switch (sc->match->driver->chiptype) {
 1016         case CHIP_I855:
 1017                 gtt_size = 128;
 1018                 break;
 1019         case CHIP_I915:
 1020                 gtt_size = 256;
 1021                 break;
 1022         case CHIP_I965:
 1023                 switch (bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL) &
 1024                         AGP_I810_PGTBL_SIZE_MASK) {
 1025                 case AGP_I810_PGTBL_SIZE_128KB:
 1026                         gtt_size = 128;
 1027                         break;
 1028                 case AGP_I810_PGTBL_SIZE_256KB:
 1029                         gtt_size = 256;
 1030                         break;
 1031                 case AGP_I810_PGTBL_SIZE_512KB:
 1032                         gtt_size = 512;
 1033                         break;
 1034                 case AGP_I965_PGTBL_SIZE_1MB:
 1035                         gtt_size = 1024;
 1036                         break;
 1037                 case AGP_I965_PGTBL_SIZE_2MB:
 1038                         gtt_size = 2048;
 1039                         break;
 1040                 case AGP_I965_PGTBL_SIZE_1_5MB:
 1041                         gtt_size = 1024 + 512;
 1042                         break;
 1043                 default:
 1044                         device_printf(dev, "Bad PGTBL size\n");
 1045                         return (EINVAL);
 1046                 }
 1047                 break;
 1048         case CHIP_G33:
 1049                 gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 2);
 1050                 switch (gcc1 & AGP_G33_MGGC_GGMS_MASK) {
 1051                 case AGP_G33_MGGC_GGMS_SIZE_1M:
 1052                         gtt_size = 1024;
 1053                         break;
 1054                 case AGP_G33_MGGC_GGMS_SIZE_2M:
 1055                         gtt_size = 2048;
 1056                         break;
 1057                 default:
 1058                         device_printf(dev, "Bad PGTBL size\n");
 1059                         return (EINVAL);
 1060                 }
 1061                 break;
 1062         case CHIP_IGD:
 1063         case CHIP_G4X:
 1064                 gtt_size = 0;
 1065                 break;
 1066         default:
 1067                 device_printf(dev, "Bad chiptype\n");
 1068                 return (EINVAL);
 1069         }
 1070 
 1071         /* GCC1 is called MGGC on i915+ */
 1072         gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1);
 1073         switch (gcc1 & AGP_I855_GCC1_GMS) {
 1074         case AGP_I855_GCC1_GMS_STOLEN_1M:
 1075                 stolen = 1024;
 1076                 break;
 1077         case AGP_I855_GCC1_GMS_STOLEN_4M:
 1078                 stolen = 4 * 1024;
 1079                 break;
 1080         case AGP_I855_GCC1_GMS_STOLEN_8M:
 1081                 stolen = 8 * 1024;
 1082                 break;
 1083         case AGP_I855_GCC1_GMS_STOLEN_16M:
 1084                 stolen = 16 * 1024;
 1085                 break;
 1086         case AGP_I855_GCC1_GMS_STOLEN_32M:
 1087                 stolen = 32 * 1024;
 1088                 break;
 1089         case AGP_I915_GCC1_GMS_STOLEN_48M:
 1090                 stolen = sc->match->driver->gen > 2 ? 48 * 1024 : 0;
 1091                 break;
 1092         case AGP_I915_GCC1_GMS_STOLEN_64M:
 1093                 stolen = sc->match->driver->gen > 2 ? 64 * 1024 : 0;
 1094                 break;
 1095         case AGP_G33_GCC1_GMS_STOLEN_128M:
 1096                 stolen = sc->match->driver->gen > 2 ? 128 * 1024 : 0;
 1097                 break;
 1098         case AGP_G33_GCC1_GMS_STOLEN_256M:
 1099                 stolen = sc->match->driver->gen > 2 ? 256 * 1024 : 0;
 1100                 break;
 1101         case AGP_G4X_GCC1_GMS_STOLEN_96M:
 1102                 if (sc->match->driver->chiptype == CHIP_I965 ||
 1103                     sc->match->driver->chiptype == CHIP_G4X)
 1104                         stolen = 96 * 1024;
 1105                 else
 1106                         stolen = 0;
 1107                 break;
 1108         case AGP_G4X_GCC1_GMS_STOLEN_160M:
 1109                 if (sc->match->driver->chiptype == CHIP_I965 ||
 1110                     sc->match->driver->chiptype == CHIP_G4X)
 1111                         stolen = 160 * 1024;
 1112                 else
 1113                         stolen = 0;
 1114                 break;
 1115         case AGP_G4X_GCC1_GMS_STOLEN_224M:
 1116                 if (sc->match->driver->chiptype == CHIP_I965 ||
 1117                     sc->match->driver->chiptype == CHIP_G4X)
 1118                         stolen = 224 * 1024;
 1119                 else
 1120                         stolen = 0;
 1121                 break;
 1122         case AGP_G4X_GCC1_GMS_STOLEN_352M:
 1123                 if (sc->match->driver->chiptype == CHIP_I965 ||
 1124                     sc->match->driver->chiptype == CHIP_G4X)
 1125                         stolen = 352 * 1024;
 1126                 else
 1127                         stolen = 0;
 1128                 break;
 1129         default:
 1130                 device_printf(dev,
 1131                     "unknown memory configuration, disabling (GCC1 %x)\n",
 1132                     gcc1);
 1133                 return (EINVAL);
 1134         }
 1135 
 1136         gtt_size += 4;
 1137         sc->stolen_size = stolen * 1024;
 1138         sc->stolen = (stolen - gtt_size) * 1024 / 4096;
 1139 
 1140         return (0);
 1141 }
 1142 
 1143 static int
 1144 agp_sb_get_stolen_size(device_t dev)
 1145 {
 1146         struct agp_i810_softc *sc;
 1147         uint16_t gmch_ctl;
 1148 
 1149         sc = device_get_softc(dev);
 1150         gmch_ctl = pci_read_config(sc->bdev, AGP_SNB_GCC1, 2);
 1151         switch (gmch_ctl & AGP_SNB_GMCH_GMS_STOLEN_MASK) {
 1152         case AGP_SNB_GMCH_GMS_STOLEN_32M:
 1153                 sc->stolen_size = 32 * 1024 * 1024;
 1154                 break;
 1155         case AGP_SNB_GMCH_GMS_STOLEN_64M:
 1156                 sc->stolen_size = 64 * 1024 * 1024;
 1157                 break;
 1158         case AGP_SNB_GMCH_GMS_STOLEN_96M:
 1159                 sc->stolen_size = 96 * 1024 * 1024;
 1160                 break;
 1161         case AGP_SNB_GMCH_GMS_STOLEN_128M:
 1162                 sc->stolen_size = 128 * 1024 * 1024;
 1163                 break;
 1164         case AGP_SNB_GMCH_GMS_STOLEN_160M:
 1165                 sc->stolen_size = 160 * 1024 * 1024;
 1166                 break;
 1167         case AGP_SNB_GMCH_GMS_STOLEN_192M:
 1168                 sc->stolen_size = 192 * 1024 * 1024;
 1169                 break;
 1170         case AGP_SNB_GMCH_GMS_STOLEN_224M:
 1171                 sc->stolen_size = 224 * 1024 * 1024;
 1172                 break;
 1173         case AGP_SNB_GMCH_GMS_STOLEN_256M:
 1174                 sc->stolen_size = 256 * 1024 * 1024;
 1175                 break;
 1176         case AGP_SNB_GMCH_GMS_STOLEN_288M:
 1177                 sc->stolen_size = 288 * 1024 * 1024;
 1178                 break;
 1179         case AGP_SNB_GMCH_GMS_STOLEN_320M:
 1180                 sc->stolen_size = 320 * 1024 * 1024;
 1181                 break;
 1182         case AGP_SNB_GMCH_GMS_STOLEN_352M:
 1183                 sc->stolen_size = 352 * 1024 * 1024;
 1184                 break;
 1185         case AGP_SNB_GMCH_GMS_STOLEN_384M:
 1186                 sc->stolen_size = 384 * 1024 * 1024;
 1187                 break;
 1188         case AGP_SNB_GMCH_GMS_STOLEN_416M:
 1189                 sc->stolen_size = 416 * 1024 * 1024;
 1190                 break;
 1191         case AGP_SNB_GMCH_GMS_STOLEN_448M:
 1192                 sc->stolen_size = 448 * 1024 * 1024;
 1193                 break;
 1194         case AGP_SNB_GMCH_GMS_STOLEN_480M:
 1195                 sc->stolen_size = 480 * 1024 * 1024;
 1196                 break;
 1197         case AGP_SNB_GMCH_GMS_STOLEN_512M:
 1198                 sc->stolen_size = 512 * 1024 * 1024;
 1199                 break;
 1200         }
 1201         sc->stolen = (sc->stolen_size - 4) / 4096;
 1202         return (0);
 1203 }
 1204 
 1205 static int
 1206 agp_i810_get_gtt_mappable_entries(device_t dev)
 1207 {
 1208         struct agp_i810_softc *sc;
 1209         uint32_t ap;
 1210         uint16_t miscc;
 1211 
 1212         sc = device_get_softc(dev);
 1213         miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2);
 1214         if ((miscc & AGP_I810_MISCC_WINSIZE) == AGP_I810_MISCC_WINSIZE_32)
 1215                 ap = 32;
 1216         else
 1217                 ap = 64;
 1218         sc->gtt_mappable_entries = (ap * 1024 * 1024) >> AGP_PAGE_SHIFT;
 1219         return (0);
 1220 }
 1221 
 1222 static int
 1223 agp_i830_get_gtt_mappable_entries(device_t dev)
 1224 {
 1225         struct agp_i810_softc *sc;
 1226         uint32_t ap;
 1227         uint16_t gmch_ctl;
 1228 
 1229         sc = device_get_softc(dev);
 1230         gmch_ctl = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
 1231         if ((gmch_ctl & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64)
 1232                 ap = 64;
 1233         else
 1234                 ap = 128;
 1235         sc->gtt_mappable_entries = (ap * 1024 * 1024) >> AGP_PAGE_SHIFT;
 1236         return (0);
 1237 }
 1238 
 1239 static int
 1240 agp_i915_get_gtt_mappable_entries(device_t dev)
 1241 {
 1242         struct agp_i810_softc *sc;
 1243         uint32_t ap;
 1244 
 1245         sc = device_get_softc(dev);
 1246         ap = AGP_GET_APERTURE(dev);
 1247         sc->gtt_mappable_entries = ap >> AGP_PAGE_SHIFT;
 1248         return (0);
 1249 }
 1250 
 1251 static int
 1252 agp_i810_get_gtt_total_entries(device_t dev)
 1253 {
 1254         struct agp_i810_softc *sc;
 1255 
 1256         sc = device_get_softc(dev);
 1257         sc->gtt_total_entries = sc->gtt_mappable_entries;
 1258         return (0);
 1259 }
 1260 
 1261 static int
 1262 agp_i965_get_gtt_total_entries(device_t dev)
 1263 {
 1264         struct agp_i810_softc *sc;
 1265         uint32_t pgetbl_ctl;
 1266         int error;
 1267 
 1268         sc = device_get_softc(dev);
 1269         error = 0;
 1270         pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
 1271         switch (pgetbl_ctl & AGP_I810_PGTBL_SIZE_MASK) {
 1272         case AGP_I810_PGTBL_SIZE_128KB:
 1273                 sc->gtt_total_entries = 128 * 1024 / 4;
 1274                 break;
 1275         case AGP_I810_PGTBL_SIZE_256KB:
 1276                 sc->gtt_total_entries = 256 * 1024 / 4;
 1277                 break;
 1278         case AGP_I810_PGTBL_SIZE_512KB:
 1279                 sc->gtt_total_entries = 512 * 1024 / 4;
 1280                 break;
 1281         /* GTT pagetable sizes bigger than 512KB are not possible on G33! */
 1282         case AGP_I810_PGTBL_SIZE_1MB:
 1283                 sc->gtt_total_entries = 1024 * 1024 / 4;
 1284                 break;
 1285         case AGP_I810_PGTBL_SIZE_2MB:
 1286                 sc->gtt_total_entries = 2 * 1024 * 1024 / 4;
 1287                 break;
 1288         case AGP_I810_PGTBL_SIZE_1_5MB:
 1289                 sc->gtt_total_entries = (1024 + 512) * 1024 / 4;
 1290                 break;
 1291         default:
 1292                 device_printf(dev, "Unknown page table size\n");
 1293                 error = ENXIO;
 1294         }
 1295         return (error);
 1296 }
 1297 
 1298 static void
 1299 agp_gen5_adjust_pgtbl_size(device_t dev, uint32_t sz)
 1300 {
 1301         struct agp_i810_softc *sc;
 1302         uint32_t pgetbl_ctl, pgetbl_ctl2;
 1303 
 1304         sc = device_get_softc(dev);
 1305 
 1306         /* Disable per-process page table. */
 1307         pgetbl_ctl2 = bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2);
 1308         pgetbl_ctl2 &= ~AGP_I810_PGTBL_ENABLED;
 1309         bus_write_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2, pgetbl_ctl2);
 1310 
 1311         /* Write the new ggtt size. */
 1312         pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
 1313         pgetbl_ctl &= ~AGP_I810_PGTBL_SIZE_MASK;
 1314         pgetbl_ctl |= sz;
 1315         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgetbl_ctl);
 1316 }
 1317 
 1318 static int
 1319 agp_gen5_get_gtt_total_entries(device_t dev)
 1320 {
 1321         struct agp_i810_softc *sc;
 1322         uint16_t gcc1;
 1323 
 1324         sc = device_get_softc(dev);
 1325 
 1326         gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
 1327         switch (gcc1 & AGP_G4x_GCC1_SIZE_MASK) {
 1328         case AGP_G4x_GCC1_SIZE_1M:
 1329         case AGP_G4x_GCC1_SIZE_VT_1M:
 1330                 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1MB);
 1331                 break;
 1332         case AGP_G4x_GCC1_SIZE_VT_1_5M:
 1333                 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1_5MB);
 1334                 break;
 1335         case AGP_G4x_GCC1_SIZE_2M:
 1336         case AGP_G4x_GCC1_SIZE_VT_2M:
 1337                 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_2MB);
 1338                 break;
 1339         default:
 1340                 device_printf(dev, "Unknown page table size\n");
 1341                 return (ENXIO);
 1342         }
 1343 
 1344         return (agp_i965_get_gtt_total_entries(dev));
 1345 }
 1346 
 1347 static int
 1348 agp_sb_get_gtt_total_entries(device_t dev)
 1349 {
 1350         struct agp_i810_softc *sc;
 1351         uint16_t gcc1;
 1352 
 1353         sc = device_get_softc(dev);
 1354 
 1355         gcc1 = pci_read_config(sc->bdev, AGP_SNB_GCC1, 2);
 1356         switch (gcc1 & AGP_SNB_GTT_SIZE_MASK) {
 1357         default:
 1358         case AGP_SNB_GTT_SIZE_0M:
 1359                 printf("Bad GTT size mask: 0x%04x\n", gcc1);
 1360                 return (ENXIO);
 1361         case AGP_SNB_GTT_SIZE_1M:
 1362                 sc->gtt_total_entries = 1024 * 1024 / 4;
 1363                 break;
 1364         case AGP_SNB_GTT_SIZE_2M:
 1365                 sc->gtt_total_entries = 2 * 1024 * 1024 / 4;
 1366                 break;
 1367         }
 1368         return (0);
 1369 }
 1370 
 1371 static int
 1372 agp_i810_install_gatt(device_t dev)
 1373 {
 1374         struct agp_i810_softc *sc;
 1375 
 1376         sc = device_get_softc(dev);
 1377 
 1378         /* Some i810s have on-chip memory called dcache. */
 1379         if ((bus_read_1(sc->sc_res[0], AGP_I810_DRT) & AGP_I810_DRT_POPULATED)
 1380             != 0)
 1381                 sc->dcache_size = 4 * 1024 * 1024;
 1382         else
 1383                 sc->dcache_size = 0;
 1384 
 1385         /* According to the specs the gatt on the i810 must be 64k. */
 1386         sc->gatt->ag_virtual = contigmalloc(64 * 1024, M_AGP, 0, 0, ~0,
 1387             PAGE_SIZE, 0);
 1388         if (sc->gatt->ag_virtual == NULL) {
 1389                 if (bootverbose)
 1390                         device_printf(dev, "contiguous allocation failed\n");
 1391                 return (ENOMEM);
 1392         }
 1393 
 1394         bzero(sc->gatt->ag_virtual, sc->gatt->ag_entries * sizeof(u_int32_t));
 1395         sc->gatt->ag_physical = vtophys((vm_offset_t)sc->gatt->ag_virtual);
 1396         agp_flush_cache();
 1397         /* Install the GATT. */
 1398         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL,
 1399             sc->gatt->ag_physical | 1);
 1400         return (0);
 1401 }
 1402 
 1403 static int
 1404 agp_i830_install_gatt(device_t dev)
 1405 {
 1406         struct agp_i810_softc *sc;
 1407         uint32_t pgtblctl;
 1408 
 1409         sc = device_get_softc(dev);
 1410 
 1411         /*
 1412          * The i830 automatically initializes the 128k gatt on boot.
 1413          * GATT address is already in there, make sure it's enabled.
 1414          */
 1415         pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
 1416         pgtblctl |= 1;
 1417         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
 1418         
 1419         sc->gatt->ag_physical = pgtblctl & ~1;
 1420         return (0);
 1421 }
 1422 
 1423 static int
 1424 agp_i810_attach(device_t dev)
 1425 {
 1426         struct agp_i810_softc *sc;
 1427         int error;
 1428 
 1429         sc = device_get_softc(dev);
 1430         sc->bdev = agp_i810_find_bridge(dev);
 1431         if (sc->bdev == NULL)
 1432                 return (ENOENT);
 1433 
 1434         sc->match = agp_i810_match(dev);
 1435 
 1436         agp_set_aperture_resource(dev, sc->match->driver->gen <= 2 ?
 1437             AGP_APBASE : AGP_I915_GMADR);
 1438         error = agp_generic_attach(dev);
 1439         if (error)
 1440                 return (error);
 1441 
 1442         if (ptoa((vm_paddr_t)Maxmem) >
 1443             (1ULL << sc->match->driver->busdma_addr_mask_sz) - 1) {
 1444                 device_printf(dev, "agp_i810 does not support physical "
 1445                     "memory above %ju.\n", (uintmax_t)(1ULL <<
 1446                     sc->match->driver->busdma_addr_mask_sz) - 1);
 1447                 return (ENOENT);
 1448         }
 1449 
 1450         if (bus_alloc_resources(dev, sc->match->driver->res_spec, sc->sc_res)) {
 1451                 agp_generic_detach(dev);
 1452                 return (ENODEV);
 1453         }
 1454 
 1455         sc->initial_aperture = AGP_GET_APERTURE(dev);
 1456         sc->gatt = malloc(sizeof(struct agp_gatt), M_AGP, M_WAITOK);
 1457         sc->gatt->ag_entries = AGP_GET_APERTURE(dev) >> AGP_PAGE_SHIFT;
 1458 
 1459         if ((error = sc->match->driver->get_stolen_size(dev)) != 0 ||
 1460             (error = sc->match->driver->install_gatt(dev)) != 0 ||
 1461             (error = sc->match->driver->get_gtt_mappable_entries(dev)) != 0 ||
 1462             (error = sc->match->driver->get_gtt_total_entries(dev)) != 0 ||
 1463             (error = sc->match->driver->chipset_flush_setup(dev)) != 0) {
 1464                 bus_release_resources(dev, sc->match->driver->res_spec,
 1465                     sc->sc_res);
 1466                 free(sc->gatt, M_AGP);
 1467                 agp_generic_detach(dev);
 1468                 return (error);
 1469         }
 1470 
 1471         intel_agp = dev;
 1472         device_printf(dev, "aperture size is %dM",
 1473             sc->initial_aperture / 1024 / 1024);
 1474         if (sc->stolen > 0)
 1475                 printf(", detected %dk stolen memory\n", sc->stolen * 4);
 1476         else
 1477                 printf("\n");
 1478         if (bootverbose) {
 1479                 sc->match->driver->dump_regs(dev);
 1480                 device_printf(dev, "Mappable GTT entries: %d\n",
 1481                     sc->gtt_mappable_entries);
 1482                 device_printf(dev, "Total GTT entries: %d\n",
 1483                     sc->gtt_total_entries);
 1484         }
 1485         return (0);
 1486 }
 1487 
 1488 static void
 1489 agp_i810_deinstall_gatt(device_t dev)
 1490 {
 1491         struct agp_i810_softc *sc;
 1492 
 1493         sc = device_get_softc(dev);
 1494         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, 0);
 1495         contigfree(sc->gatt->ag_virtual, 64 * 1024, M_AGP);
 1496 }
 1497 
 1498 static void
 1499 agp_i830_deinstall_gatt(device_t dev)
 1500 {
 1501         struct agp_i810_softc *sc;
 1502         unsigned int pgtblctl;
 1503 
 1504         sc = device_get_softc(dev);
 1505         pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
 1506         pgtblctl &= ~1;
 1507         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
 1508 }
 1509 
 1510 static int
 1511 agp_i810_detach(device_t dev)
 1512 {
 1513         struct agp_i810_softc *sc;
 1514 
 1515         sc = device_get_softc(dev);
 1516         agp_free_cdev(dev);
 1517 
 1518         /* Clear the GATT base. */
 1519         sc->match->driver->deinstall_gatt(dev);
 1520 
 1521         sc->match->driver->chipset_flush_teardown(dev);
 1522 
 1523         /* Put the aperture back the way it started. */
 1524         AGP_SET_APERTURE(dev, sc->initial_aperture);
 1525 
 1526         free(sc->gatt, M_AGP);
 1527         bus_release_resources(dev, sc->match->driver->res_spec, sc->sc_res);
 1528         agp_free_res(dev);
 1529 
 1530         return (0);
 1531 }
 1532 
 1533 static int
 1534 agp_i810_resume(device_t dev)
 1535 {
 1536         struct agp_i810_softc *sc;
 1537         sc = device_get_softc(dev);
 1538 
 1539         AGP_SET_APERTURE(dev, sc->initial_aperture);
 1540 
 1541         /* Install the GATT. */
 1542         bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL,
 1543         sc->gatt->ag_physical | 1);
 1544 
 1545         return (bus_generic_resume(dev));
 1546 }
 1547 
 1548 /**
 1549  * Sets the PCI resource size of the aperture on i830-class and below chipsets,
 1550  * while returning failure on later chipsets when an actual change is
 1551  * requested.
 1552  *
 1553  * This whole function is likely bogus, as the kernel would probably need to
 1554  * reconfigure the placement of the AGP aperture if a larger size is requested,
 1555  * which doesn't happen currently.
 1556  */
 1557 static int
 1558 agp_i810_set_aperture(device_t dev, u_int32_t aperture)
 1559 {
 1560         struct agp_i810_softc *sc;
 1561         u_int16_t miscc;
 1562 
 1563         sc = device_get_softc(dev);
 1564         /*
 1565          * Double check for sanity.
 1566          */
 1567         if (aperture != 32 * 1024 * 1024 && aperture != 64 * 1024 * 1024) {
 1568                 device_printf(dev, "bad aperture size %d\n", aperture);
 1569                 return (EINVAL);
 1570         }
 1571 
 1572         miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2);
 1573         miscc &= ~AGP_I810_MISCC_WINSIZE;
 1574         if (aperture == 32 * 1024 * 1024)
 1575                 miscc |= AGP_I810_MISCC_WINSIZE_32;
 1576         else
 1577                 miscc |= AGP_I810_MISCC_WINSIZE_64;
 1578         
 1579         pci_write_config(sc->bdev, AGP_I810_MISCC, miscc, 2);
 1580         return (0);
 1581 }
 1582 
 1583 static int
 1584 agp_i830_set_aperture(device_t dev, u_int32_t aperture)
 1585 {
 1586         struct agp_i810_softc *sc;
 1587         u_int16_t gcc1;
 1588 
 1589         sc = device_get_softc(dev);
 1590 
 1591         if (aperture != 64 * 1024 * 1024 &&
 1592             aperture != 128 * 1024 * 1024) {
 1593                 device_printf(dev, "bad aperture size %d\n", aperture);
 1594                 return (EINVAL);
 1595         }
 1596         gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
 1597         gcc1 &= ~AGP_I830_GCC1_GMASIZE;
 1598         if (aperture == 64 * 1024 * 1024)
 1599                 gcc1 |= AGP_I830_GCC1_GMASIZE_64;
 1600         else
 1601                 gcc1 |= AGP_I830_GCC1_GMASIZE_128;
 1602 
 1603         pci_write_config(sc->bdev, AGP_I830_GCC1, gcc1, 2);
 1604         return (0);
 1605 }
 1606 
 1607 static int
 1608 agp_i915_set_aperture(device_t dev, u_int32_t aperture)
 1609 {
 1610 
 1611         return (agp_generic_set_aperture(dev, aperture));
 1612 }
 1613 
 1614 static int
 1615 agp_i810_method_set_aperture(device_t dev, u_int32_t aperture)
 1616 {
 1617         struct agp_i810_softc *sc;
 1618 
 1619         sc = device_get_softc(dev);
 1620         return (sc->match->driver->set_aperture(dev, aperture));
 1621 }
 1622 
 1623 /**
 1624  * Writes a GTT entry mapping the page at the given offset from the
 1625  * beginning of the aperture to the given physical address.  Setup the
 1626  * caching mode according to flags.
 1627  *
 1628  * For gen 1, 2 and 3, GTT start is located at AGP_I810_GTT offset
 1629  * from corresponding BAR start. For gen 4, offset is 512KB +
 1630  * AGP_I810_GTT, for gen 5 and 6 it is 2MB + AGP_I810_GTT.
 1631  *
 1632  * Also, the bits of the physical page address above 4GB needs to be
 1633  * placed into bits 40-32 of PTE.
 1634  */
 1635 static void
 1636 agp_i810_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1637     int flags)
 1638 {
 1639         uint32_t pte;
 1640 
 1641         pte = (u_int32_t)physical | I810_PTE_VALID;
 1642         if (flags == AGP_DCACHE_MEMORY)
 1643                 pte |= I810_PTE_LOCAL;
 1644         else if (flags == AGP_USER_CACHED_MEMORY)
 1645                 pte |= I830_PTE_SYSTEM_CACHED;
 1646         agp_i810_write_gtt(dev, index, pte);
 1647 }
 1648 
 1649 static void
 1650 agp_i810_write_gtt(device_t dev, u_int index, uint32_t pte)
 1651 {
 1652         struct agp_i810_softc *sc;
 1653 
 1654         sc = device_get_softc(dev);
 1655         bus_write_4(sc->sc_res[0], AGP_I810_GTT + index * 4, pte);
 1656         CTR2(KTR_AGP_I810, "810_pte %x %x", index, pte);
 1657 }
 1658 
 1659 static void
 1660 agp_i830_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1661     int flags)
 1662 {
 1663         uint32_t pte;
 1664 
 1665         pte = (u_int32_t)physical | I810_PTE_VALID;
 1666         if (flags == AGP_USER_CACHED_MEMORY)
 1667                 pte |= I830_PTE_SYSTEM_CACHED;
 1668         agp_i810_write_gtt(dev, index, pte);
 1669 }
 1670 
 1671 static void
 1672 agp_i915_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1673     int flags)
 1674 {
 1675         uint32_t pte;
 1676 
 1677         pte = (u_int32_t)physical | I810_PTE_VALID;
 1678         if (flags == AGP_USER_CACHED_MEMORY)
 1679                 pte |= I830_PTE_SYSTEM_CACHED;
 1680         pte |= (physical & 0x0000000f00000000ull) >> 28;
 1681         agp_i915_write_gtt(dev, index, pte);
 1682 }
 1683 
 1684 static void
 1685 agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte)
 1686 {
 1687         struct agp_i810_softc *sc;
 1688 
 1689         sc = device_get_softc(dev);
 1690         bus_write_4(sc->sc_res[1], index * 4, pte);
 1691         CTR2(KTR_AGP_I810, "915_pte %x %x", index, pte);
 1692 }
 1693 
 1694 static void
 1695 agp_i965_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1696     int flags)
 1697 {
 1698         uint32_t pte;
 1699 
 1700         pte = (u_int32_t)physical | I810_PTE_VALID;
 1701         if (flags == AGP_USER_CACHED_MEMORY)
 1702                 pte |= I830_PTE_SYSTEM_CACHED;
 1703         pte |= (physical & 0x0000000f00000000ull) >> 28;
 1704         agp_i965_write_gtt(dev, index, pte);
 1705 }
 1706 
 1707 static void
 1708 agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte)
 1709 {
 1710         struct agp_i810_softc *sc;
 1711 
 1712         sc = device_get_softc(dev);
 1713         bus_write_4(sc->sc_res[0], index * 4 + (512 * 1024), pte);
 1714         CTR2(KTR_AGP_I810, "965_pte %x %x", index, pte);
 1715 }
 1716 
 1717 static void
 1718 agp_g4x_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1719     int flags)
 1720 {
 1721         uint32_t pte;
 1722 
 1723         pte = (u_int32_t)physical | I810_PTE_VALID;
 1724         if (flags == AGP_USER_CACHED_MEMORY)
 1725                 pte |= I830_PTE_SYSTEM_CACHED;
 1726         pte |= (physical & 0x0000000f00000000ull) >> 28;
 1727         agp_g4x_write_gtt(dev, index, pte);
 1728 }
 1729 
 1730 static void
 1731 agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte)
 1732 {
 1733         struct agp_i810_softc *sc;
 1734 
 1735         sc = device_get_softc(dev);
 1736         bus_write_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024), pte);
 1737         CTR2(KTR_AGP_I810, "g4x_pte %x %x", index, pte);
 1738 }
 1739 
 1740 static void
 1741 agp_sb_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
 1742     int flags)
 1743 {
 1744         int type_mask, gfdt;
 1745         uint32_t pte;
 1746 
 1747         pte = (u_int32_t)physical | I810_PTE_VALID;
 1748         type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT;
 1749         gfdt = (flags & AGP_USER_CACHED_MEMORY_GFDT) != 0 ? GEN6_PTE_GFDT : 0;
 1750 
 1751         if (type_mask == AGP_USER_MEMORY)
 1752                 pte |= GEN6_PTE_UNCACHED;
 1753         else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC)
 1754                 pte |= GEN6_PTE_LLC_MLC | gfdt;
 1755         else
 1756                 pte |= GEN6_PTE_LLC | gfdt;
 1757 
 1758         pte |= (physical & 0x000000ff00000000ull) >> 28;
 1759         agp_sb_write_gtt(dev, index, pte);
 1760 }
 1761 
 1762 static void
 1763 agp_sb_write_gtt(device_t dev, u_int index, uint32_t pte)
 1764 {
 1765         struct agp_i810_softc *sc;
 1766 
 1767         sc = device_get_softc(dev);
 1768         bus_write_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024), pte);
 1769         CTR2(KTR_AGP_I810, "sb_pte %x %x", index, pte);
 1770 }
 1771 
 1772 static int
 1773 agp_i810_bind_page(device_t dev, vm_offset_t offset, vm_offset_t physical)
 1774 {
 1775         struct agp_i810_softc *sc = device_get_softc(dev);
 1776         u_int index;
 1777 
 1778         if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) {
 1779                 device_printf(dev, "failed: offset is 0x%08jx, "
 1780                     "shift is %d, entries is %d\n", (intmax_t)offset,
 1781                     AGP_PAGE_SHIFT, sc->gatt->ag_entries);
 1782                 return (EINVAL);
 1783         }
 1784         index = offset >> AGP_PAGE_SHIFT;
 1785         if (sc->stolen != 0 && index < sc->stolen) {
 1786                 device_printf(dev, "trying to bind into stolen memory\n");
 1787                 return (EINVAL);
 1788         }
 1789         sc->match->driver->install_gtt_pte(dev, index, physical, 0);
 1790         return (0);
 1791 }
 1792 
 1793 static int
 1794 agp_i810_unbind_page(device_t dev, vm_offset_t offset)
 1795 {
 1796         struct agp_i810_softc *sc;
 1797         u_int index;
 1798 
 1799         sc = device_get_softc(dev);
 1800         if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
 1801                 return (EINVAL);
 1802         index = offset >> AGP_PAGE_SHIFT;
 1803         if (sc->stolen != 0 && index < sc->stolen) {
 1804                 device_printf(dev, "trying to unbind from stolen memory\n");
 1805                 return (EINVAL);
 1806         }
 1807         sc->match->driver->install_gtt_pte(dev, index, 0, 0);
 1808         return (0);
 1809 }
 1810 
 1811 static u_int32_t
 1812 agp_i810_read_gtt_pte(device_t dev, u_int index)
 1813 {
 1814         struct agp_i810_softc *sc;
 1815         u_int32_t pte;
 1816 
 1817         sc = device_get_softc(dev);
 1818         pte = bus_read_4(sc->sc_res[0], AGP_I810_GTT + index * 4);
 1819         return (pte);
 1820 }
 1821 
 1822 static u_int32_t
 1823 agp_i915_read_gtt_pte(device_t dev, u_int index)
 1824 {
 1825         struct agp_i810_softc *sc;
 1826         u_int32_t pte;
 1827 
 1828         sc = device_get_softc(dev);
 1829         pte = bus_read_4(sc->sc_res[1], index * 4);
 1830         return (pte);
 1831 }
 1832 
 1833 static u_int32_t
 1834 agp_i965_read_gtt_pte(device_t dev, u_int index)
 1835 {
 1836         struct agp_i810_softc *sc;
 1837         u_int32_t pte;
 1838 
 1839         sc = device_get_softc(dev);
 1840         pte = bus_read_4(sc->sc_res[0], index * 4 + (512 * 1024));
 1841         return (pte);
 1842 }
 1843 
 1844 static u_int32_t
 1845 agp_g4x_read_gtt_pte(device_t dev, u_int index)
 1846 {
 1847         struct agp_i810_softc *sc;
 1848         u_int32_t pte;
 1849 
 1850         sc = device_get_softc(dev);
 1851         pte = bus_read_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024));
 1852         return (pte);
 1853 }
 1854 
 1855 static vm_paddr_t
 1856 agp_i810_read_gtt_pte_paddr(device_t dev, u_int index)
 1857 {
 1858         struct agp_i810_softc *sc;
 1859         u_int32_t pte;
 1860         vm_paddr_t res;
 1861 
 1862         sc = device_get_softc(dev);
 1863         pte = sc->match->driver->read_gtt_pte(dev, index);
 1864         res = pte & ~PAGE_MASK;
 1865         return (res);
 1866 }
 1867 
 1868 static vm_paddr_t
 1869 agp_i915_read_gtt_pte_paddr(device_t dev, u_int index)
 1870 {
 1871         struct agp_i810_softc *sc;
 1872         u_int32_t pte;
 1873         vm_paddr_t res;
 1874 
 1875         sc = device_get_softc(dev);
 1876         pte = sc->match->driver->read_gtt_pte(dev, index);
 1877         res = (pte & ~PAGE_MASK) | ((pte & 0xf0) << 28);
 1878         return (res);
 1879 }
 1880 
 1881 static vm_paddr_t
 1882 agp_sb_read_gtt_pte_paddr(device_t dev, u_int index)
 1883 {
 1884         struct agp_i810_softc *sc;
 1885         u_int32_t pte;
 1886         vm_paddr_t res;
 1887 
 1888         sc = device_get_softc(dev);
 1889         pte = sc->match->driver->read_gtt_pte(dev, index);
 1890         res = (pte & ~PAGE_MASK) | ((pte & 0xff0) << 28);
 1891         return (res);
 1892 }
 1893 
 1894 /*
 1895  * Writing via memory mapped registers already flushes all TLBs.
 1896  */
 1897 static void
 1898 agp_i810_flush_tlb(device_t dev)
 1899 {
 1900 }
 1901 
 1902 static int
 1903 agp_i810_enable(device_t dev, u_int32_t mode)
 1904 {
 1905 
 1906         return (0);
 1907 }
 1908 
 1909 static struct agp_memory *
 1910 agp_i810_alloc_memory(device_t dev, int type, vm_size_t size)
 1911 {
 1912         struct agp_i810_softc *sc;
 1913         struct agp_memory *mem;
 1914         vm_page_t m;
 1915 
 1916         sc = device_get_softc(dev);
 1917 
 1918         if ((size & (AGP_PAGE_SIZE - 1)) != 0 ||
 1919             sc->agp.as_allocated + size > sc->agp.as_maxmem)
 1920                 return (0);
 1921 
 1922         if (type == 1) {
 1923                 /*
 1924                  * Mapping local DRAM into GATT.
 1925                  */
 1926                 if (sc->match->driver->chiptype != CHIP_I810)
 1927                         return (0);
 1928                 if (size != sc->dcache_size)
 1929                         return (0);
 1930         } else if (type == 2) {
 1931                 /*
 1932                  * Type 2 is the contiguous physical memory type, that hands
 1933                  * back a physical address.  This is used for cursors on i810.
 1934                  * Hand back as many single pages with physical as the user
 1935                  * wants, but only allow one larger allocation (ARGB cursor)
 1936                  * for simplicity.
 1937                  */
 1938                 if (size != AGP_PAGE_SIZE) {
 1939                         if (sc->argb_cursor != NULL)
 1940                                 return (0);
 1941 
 1942                         /* Allocate memory for ARGB cursor, if we can. */
 1943                         sc->argb_cursor = contigmalloc(size, M_AGP,
 1944                            0, 0, ~0, PAGE_SIZE, 0);
 1945                         if (sc->argb_cursor == NULL)
 1946                                 return (0);
 1947                 }
 1948         }
 1949 
 1950         mem = malloc(sizeof *mem, M_AGP, M_WAITOK);
 1951         mem->am_id = sc->agp.as_nextid++;
 1952         mem->am_size = size;
 1953         mem->am_type = type;
 1954         if (type != 1 && (type != 2 || size == AGP_PAGE_SIZE))
 1955                 mem->am_obj = vm_object_allocate(OBJT_DEFAULT,
 1956                     atop(round_page(size)));
 1957         else
 1958                 mem->am_obj = 0;
 1959 
 1960         if (type == 2) {
 1961                 if (size == AGP_PAGE_SIZE) {
 1962                         /*
 1963                          * Allocate and wire down the page now so that we can
 1964                          * get its physical address.
 1965                          */
 1966                         VM_OBJECT_LOCK(mem->am_obj);
 1967                         m = vm_page_grab(mem->am_obj, 0, VM_ALLOC_NOBUSY |
 1968                             VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_RETRY);
 1969                         VM_OBJECT_UNLOCK(mem->am_obj);
 1970                         mem->am_physical = VM_PAGE_TO_PHYS(m);
 1971                 } else {
 1972                         /* Our allocation is already nicely wired down for us.
 1973                          * Just grab the physical address.
 1974                          */
 1975                         mem->am_physical = vtophys(sc->argb_cursor);
 1976                 }
 1977         } else
 1978                 mem->am_physical = 0;
 1979 
 1980         mem->am_offset = 0;
 1981         mem->am_is_bound = 0;
 1982         TAILQ_INSERT_TAIL(&sc->agp.as_memory, mem, am_link);
 1983         sc->agp.as_allocated += size;
 1984 
 1985         return (mem);
 1986 }
 1987 
 1988 static int
 1989 agp_i810_free_memory(device_t dev, struct agp_memory *mem)
 1990 {
 1991         struct agp_i810_softc *sc;
 1992         vm_page_t m;
 1993 
 1994         if (mem->am_is_bound)
 1995                 return (EBUSY);
 1996 
 1997         sc = device_get_softc(dev);
 1998 
 1999         if (mem->am_type == 2) {
 2000                 if (mem->am_size == AGP_PAGE_SIZE) {
 2001                         /*
 2002                          * Unwire the page which we wired in alloc_memory.
 2003                          */
 2004                         VM_OBJECT_LOCK(mem->am_obj);
 2005                         m = vm_page_lookup(mem->am_obj, 0);
 2006                         vm_page_lock(m);
 2007                         vm_page_unwire(m, 0);
 2008                         vm_page_unlock(m);
 2009                         VM_OBJECT_UNLOCK(mem->am_obj);
 2010                 } else {
 2011                         contigfree(sc->argb_cursor, mem->am_size, M_AGP);
 2012                         sc->argb_cursor = NULL;
 2013                 }
 2014         }
 2015 
 2016         sc->agp.as_allocated -= mem->am_size;
 2017         TAILQ_REMOVE(&sc->agp.as_memory, mem, am_link);
 2018         if (mem->am_obj)
 2019                 vm_object_deallocate(mem->am_obj);
 2020         free(mem, M_AGP);
 2021         return (0);
 2022 }
 2023 
 2024 static int
 2025 agp_i810_bind_memory(device_t dev, struct agp_memory *mem, vm_offset_t offset)
 2026 {
 2027         struct agp_i810_softc *sc;
 2028         vm_offset_t i;
 2029 
 2030         /* Do some sanity checks first. */
 2031         if ((offset & (AGP_PAGE_SIZE - 1)) != 0 ||
 2032             offset + mem->am_size > AGP_GET_APERTURE(dev)) {
 2033                 device_printf(dev, "binding memory at bad offset %#x\n",
 2034                     (int)offset);
 2035                 return (EINVAL);
 2036         }
 2037 
 2038         sc = device_get_softc(dev);
 2039         if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
 2040                 mtx_lock(&sc->agp.as_lock);
 2041                 if (mem->am_is_bound) {
 2042                         mtx_unlock(&sc->agp.as_lock);
 2043                         return (EINVAL);
 2044                 }
 2045                 /* The memory's already wired down, just stick it in the GTT. */
 2046                 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
 2047                         sc->match->driver->install_gtt_pte(dev, (offset + i) >>
 2048                             AGP_PAGE_SHIFT, mem->am_physical + i, 0);
 2049                 }
 2050                 agp_flush_cache();
 2051                 mem->am_offset = offset;
 2052                 mem->am_is_bound = 1;
 2053                 mtx_unlock(&sc->agp.as_lock);
 2054                 return (0);
 2055         }
 2056 
 2057         if (mem->am_type != 1)
 2058                 return (agp_generic_bind_memory(dev, mem, offset));
 2059 
 2060         /*
 2061          * Mapping local DRAM into GATT.
 2062          */
 2063         if (sc->match->driver->chiptype != CHIP_I810)
 2064                 return (EINVAL);
 2065         for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
 2066                 bus_write_4(sc->sc_res[0],
 2067                     AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, i | 3);
 2068 
 2069         return (0);
 2070 }
 2071 
 2072 static int
 2073 agp_i810_unbind_memory(device_t dev, struct agp_memory *mem)
 2074 {
 2075         struct agp_i810_softc *sc;
 2076         vm_offset_t i;
 2077 
 2078         sc = device_get_softc(dev);
 2079 
 2080         if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
 2081                 mtx_lock(&sc->agp.as_lock);
 2082                 if (!mem->am_is_bound) {
 2083                         mtx_unlock(&sc->agp.as_lock);
 2084                         return (EINVAL);
 2085                 }
 2086 
 2087                 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
 2088                         sc->match->driver->install_gtt_pte(dev,
 2089                             (mem->am_offset + i) >> AGP_PAGE_SHIFT, 0, 0);
 2090                 }
 2091                 agp_flush_cache();
 2092                 mem->am_is_bound = 0;
 2093                 mtx_unlock(&sc->agp.as_lock);
 2094                 return (0);
 2095         }
 2096 
 2097         if (mem->am_type != 1)
 2098                 return (agp_generic_unbind_memory(dev, mem));
 2099 
 2100         if (sc->match->driver->chiptype != CHIP_I810)
 2101                 return (EINVAL);
 2102         for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
 2103                 sc->match->driver->install_gtt_pte(dev, i >> AGP_PAGE_SHIFT,
 2104                     0, 0);
 2105         }
 2106         return (0);
 2107 }
 2108 
 2109 static device_method_t agp_i810_methods[] = {
 2110         /* Device interface */
 2111         DEVMETHOD(device_identify,      agp_i810_identify),
 2112         DEVMETHOD(device_probe,         agp_i810_probe),
 2113         DEVMETHOD(device_attach,        agp_i810_attach),
 2114         DEVMETHOD(device_detach,        agp_i810_detach),
 2115         DEVMETHOD(device_suspend,       bus_generic_suspend),
 2116         DEVMETHOD(device_resume,        agp_i810_resume),
 2117 
 2118         /* AGP interface */
 2119         DEVMETHOD(agp_get_aperture,     agp_generic_get_aperture),
 2120         DEVMETHOD(agp_set_aperture,     agp_i810_method_set_aperture),
 2121         DEVMETHOD(agp_bind_page,        agp_i810_bind_page),
 2122         DEVMETHOD(agp_unbind_page,      agp_i810_unbind_page),
 2123         DEVMETHOD(agp_flush_tlb,        agp_i810_flush_tlb),
 2124         DEVMETHOD(agp_enable,           agp_i810_enable),
 2125         DEVMETHOD(agp_alloc_memory,     agp_i810_alloc_memory),
 2126         DEVMETHOD(agp_free_memory,      agp_i810_free_memory),
 2127         DEVMETHOD(agp_bind_memory,      agp_i810_bind_memory),
 2128         DEVMETHOD(agp_unbind_memory,    agp_i810_unbind_memory),
 2129         DEVMETHOD(agp_chipset_flush,    agp_intel_gtt_chipset_flush),
 2130 
 2131         { 0, 0 }
 2132 };
 2133 
 2134 static driver_t agp_i810_driver = {
 2135         "agp",
 2136         agp_i810_methods,
 2137         sizeof(struct agp_i810_softc),
 2138 };
 2139 
 2140 static devclass_t agp_devclass;
 2141 
 2142 DRIVER_MODULE(agp_i810, vgapci, agp_i810_driver, agp_devclass, 0, 0);
 2143 MODULE_DEPEND(agp_i810, agp, 1, 1, 1);
 2144 MODULE_DEPEND(agp_i810, pci, 1, 1, 1);
 2145 
 2146 extern vm_page_t bogus_page;
 2147 
 2148 void
 2149 agp_intel_gtt_clear_range(device_t dev, u_int first_entry, u_int num_entries)
 2150 {
 2151         struct agp_i810_softc *sc;
 2152         u_int i;
 2153 
 2154         sc = device_get_softc(dev);
 2155         for (i = 0; i < num_entries; i++)
 2156                 sc->match->driver->install_gtt_pte(dev, first_entry + i,
 2157                     VM_PAGE_TO_PHYS(bogus_page), 0);
 2158         sc->match->driver->read_gtt_pte(dev, first_entry + num_entries - 1);
 2159 }
 2160 
 2161 void
 2162 agp_intel_gtt_insert_pages(device_t dev, u_int first_entry, u_int num_entries,
 2163     vm_page_t *pages, u_int flags)
 2164 {
 2165         struct agp_i810_softc *sc;
 2166         u_int i;
 2167 
 2168         sc = device_get_softc(dev);
 2169         for (i = 0; i < num_entries; i++) {
 2170                 MPASS(pages[i]->valid == VM_PAGE_BITS_ALL);
 2171                 MPASS(pages[i]->wire_count > 0);
 2172                 sc->match->driver->install_gtt_pte(dev, first_entry + i,
 2173                     VM_PAGE_TO_PHYS(pages[i]), flags);
 2174         }
 2175         sc->match->driver->read_gtt_pte(dev, first_entry + num_entries - 1);
 2176 }
 2177 
 2178 struct intel_gtt
 2179 agp_intel_gtt_get(device_t dev)
 2180 {
 2181         struct agp_i810_softc *sc;
 2182         struct intel_gtt res;
 2183 
 2184         sc = device_get_softc(dev);
 2185         res.stolen_size = sc->stolen_size;
 2186         res.gtt_total_entries = sc->gtt_total_entries;
 2187         res.gtt_mappable_entries = sc->gtt_mappable_entries;
 2188         res.do_idle_maps = 0;
 2189         res.scratch_page_dma = VM_PAGE_TO_PHYS(bogus_page);
 2190         return (res);
 2191 }
 2192 
 2193 static int
 2194 agp_i810_chipset_flush_setup(device_t dev)
 2195 {
 2196 
 2197         return (0);
 2198 }
 2199 
 2200 static void
 2201 agp_i810_chipset_flush_teardown(device_t dev)
 2202 {
 2203 
 2204         /* Nothing to do. */
 2205 }
 2206 
 2207 static void
 2208 agp_i810_chipset_flush(device_t dev)
 2209 {
 2210 
 2211         /* Nothing to do. */
 2212 }
 2213 
 2214 static void
 2215 agp_i830_chipset_flush(device_t dev)
 2216 {
 2217         struct agp_i810_softc *sc;
 2218         uint32_t hic;
 2219         int i;
 2220 
 2221         sc = device_get_softc(dev);
 2222         pmap_invalidate_cache();
 2223         hic = bus_read_4(sc->sc_res[0], AGP_I830_HIC);
 2224         bus_write_4(sc->sc_res[0], AGP_I830_HIC, hic | (1 << 31));
 2225         for (i = 0; i < 20000 /* 1 sec */; i++) {
 2226                 hic = bus_read_4(sc->sc_res[0], AGP_I830_HIC);
 2227                 if ((hic & (1 << 31)) != 0)
 2228                         break;
 2229                 DELAY(50);
 2230         }
 2231 }
 2232 
 2233 static int
 2234 agp_i915_chipset_flush_alloc_page(device_t dev, uint64_t start, uint64_t end)
 2235 {
 2236         struct agp_i810_softc *sc;
 2237         device_t vga;
 2238 
 2239         sc = device_get_softc(dev);
 2240         vga = device_get_parent(dev);
 2241         sc->sc_flush_page_rid = 100;
 2242         sc->sc_flush_page_res = BUS_ALLOC_RESOURCE(device_get_parent(vga), dev,
 2243             SYS_RES_MEMORY, &sc->sc_flush_page_rid, start, end, PAGE_SIZE,
 2244             RF_ACTIVE);
 2245         if (sc->sc_flush_page_res == NULL) {
 2246                 device_printf(dev, "Failed to allocate flush page at 0x%jx\n",
 2247                     (uintmax_t)start);
 2248                 return (EINVAL);
 2249         }
 2250         sc->sc_flush_page_vaddr = rman_get_virtual(sc->sc_flush_page_res);
 2251         if (bootverbose) {
 2252                 device_printf(dev, "Allocated flush page phys 0x%jx virt %p\n",
 2253                     (uintmax_t)rman_get_start(sc->sc_flush_page_res),
 2254                     sc->sc_flush_page_vaddr);
 2255         }
 2256         return (0);
 2257 }
 2258 
 2259 static void
 2260 agp_i915_chipset_flush_free_page(device_t dev)
 2261 {
 2262         struct agp_i810_softc *sc;
 2263         device_t vga;
 2264 
 2265         sc = device_get_softc(dev);
 2266         vga = device_get_parent(dev);
 2267         if (sc->sc_flush_page_res == NULL)
 2268                 return;
 2269         BUS_DEACTIVATE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY,
 2270             sc->sc_flush_page_rid, sc->sc_flush_page_res);
 2271         BUS_RELEASE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY,
 2272             sc->sc_flush_page_rid, sc->sc_flush_page_res);
 2273 }
 2274 
 2275 static int
 2276 agp_i915_chipset_flush_setup(device_t dev)
 2277 {
 2278         struct agp_i810_softc *sc;
 2279         uint32_t temp;
 2280         int error;
 2281 
 2282         sc = device_get_softc(dev);
 2283         temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4);
 2284         if ((temp & 1) != 0) {
 2285                 temp &= ~1;
 2286                 if (bootverbose)
 2287                         device_printf(dev,
 2288                             "Found already configured flush page at 0x%jx\n",
 2289                             (uintmax_t)temp);
 2290                 sc->sc_bios_allocated_flush_page = 1;
 2291                 /*
 2292                  * In the case BIOS initialized the flush pointer (?)
 2293                  * register, expect that BIOS also set up the resource
 2294                  * for the page.
 2295                  */
 2296                 error = agp_i915_chipset_flush_alloc_page(dev, temp,
 2297                     temp + PAGE_SIZE - 1);
 2298                 if (error != 0)
 2299                         return (error);
 2300         } else {
 2301                 sc->sc_bios_allocated_flush_page = 0;
 2302                 error = agp_i915_chipset_flush_alloc_page(dev, 0, 0xffffffff);
 2303                 if (error != 0)
 2304                         return (error);
 2305                 temp = rman_get_start(sc->sc_flush_page_res);
 2306                 pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp | 1, 4);
 2307         }
 2308         return (0);
 2309 }
 2310 
 2311 static void
 2312 agp_i915_chipset_flush_teardown(device_t dev)
 2313 {
 2314         struct agp_i810_softc *sc;
 2315         uint32_t temp;
 2316 
 2317         sc = device_get_softc(dev);
 2318         if (sc->sc_flush_page_res == NULL)
 2319                 return;
 2320         if (!sc->sc_bios_allocated_flush_page) {
 2321                 temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4);
 2322                 temp &= ~1;
 2323                 pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp, 4);
 2324         }               
 2325         agp_i915_chipset_flush_free_page(dev);
 2326 }
 2327 
 2328 static int
 2329 agp_i965_chipset_flush_setup(device_t dev)
 2330 {
 2331         struct agp_i810_softc *sc;
 2332         uint64_t temp;
 2333         uint32_t temp_hi, temp_lo;
 2334         int error;
 2335 
 2336         sc = device_get_softc(dev);
 2337 
 2338         temp_hi = pci_read_config(sc->bdev, AGP_I965_IFPADDR + 4, 4);
 2339         temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4);
 2340 
 2341         if ((temp_lo & 1) != 0) {
 2342                 temp = ((uint64_t)temp_hi << 32) | (temp_lo & ~1);
 2343                 if (bootverbose)
 2344                         device_printf(dev,
 2345                             "Found already configured flush page at 0x%jx\n",
 2346                             (uintmax_t)temp);
 2347                 sc->sc_bios_allocated_flush_page = 1;
 2348                 /*
 2349                  * In the case BIOS initialized the flush pointer (?)
 2350                  * register, expect that BIOS also set up the resource
 2351                  * for the page.
 2352                  */
 2353                 error = agp_i915_chipset_flush_alloc_page(dev, temp,
 2354                     temp + PAGE_SIZE - 1);
 2355                 if (error != 0)
 2356                         return (error);
 2357         } else {
 2358                 sc->sc_bios_allocated_flush_page = 0;
 2359                 error = agp_i915_chipset_flush_alloc_page(dev, 0, ~0);
 2360                 if (error != 0)
 2361                         return (error);
 2362                 temp = rman_get_start(sc->sc_flush_page_res);
 2363                 pci_write_config(sc->bdev, AGP_I965_IFPADDR + 4,
 2364                     (temp >> 32) & UINT32_MAX, 4);
 2365                 pci_write_config(sc->bdev, AGP_I965_IFPADDR,
 2366                     (temp & UINT32_MAX) | 1, 4);
 2367         }
 2368         return (0);
 2369 }
 2370 
 2371 static void
 2372 agp_i965_chipset_flush_teardown(device_t dev)
 2373 {
 2374         struct agp_i810_softc *sc;
 2375         uint32_t temp_lo;
 2376 
 2377         sc = device_get_softc(dev);
 2378         if (sc->sc_flush_page_res == NULL)
 2379                 return;
 2380         if (!sc->sc_bios_allocated_flush_page) {
 2381                 temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4);
 2382                 temp_lo &= ~1;
 2383                 pci_write_config(sc->bdev, AGP_I965_IFPADDR, temp_lo, 4);
 2384         }
 2385         agp_i915_chipset_flush_free_page(dev);
 2386 }
 2387 
 2388 static void
 2389 agp_i915_chipset_flush(device_t dev)
 2390 {
 2391         struct agp_i810_softc *sc;
 2392 
 2393         sc = device_get_softc(dev);
 2394         *(uint32_t *)sc->sc_flush_page_vaddr = 1;
 2395 }
 2396 
 2397 int
 2398 agp_intel_gtt_chipset_flush(device_t dev)
 2399 {
 2400         struct agp_i810_softc *sc;
 2401 
 2402         sc = device_get_softc(dev);
 2403         sc->match->driver->chipset_flush(dev);
 2404         return (0);
 2405 }
 2406 
 2407 void
 2408 agp_intel_gtt_unmap_memory(device_t dev, struct sglist *sg_list)
 2409 {
 2410 }
 2411 
 2412 int
 2413 agp_intel_gtt_map_memory(device_t dev, vm_page_t *pages, u_int num_entries,
 2414     struct sglist **sg_list)
 2415 {
 2416         struct agp_i810_softc *sc;
 2417         struct sglist *sg;
 2418         int i;
 2419 #if 0
 2420         int error;
 2421         bus_dma_tag_t dmat;
 2422 #endif
 2423 
 2424         if (*sg_list != NULL)
 2425                 return (0);
 2426         sc = device_get_softc(dev);
 2427         sg = sglist_alloc(num_entries, M_WAITOK /* XXXKIB */);
 2428         for (i = 0; i < num_entries; i++) {
 2429                 sg->sg_segs[i].ss_paddr = VM_PAGE_TO_PHYS(pages[i]);
 2430                 sg->sg_segs[i].ss_len = PAGE_SIZE;
 2431         }
 2432 
 2433 #if 0
 2434         error = bus_dma_tag_create(bus_get_dma_tag(dev),
 2435             1 /* alignment */, 0 /* boundary */,
 2436             1ULL << sc->match->busdma_addr_mask_sz /* lowaddr */,
 2437             BUS_SPACE_MAXADDR /* highaddr */,
 2438             NULL /* filtfunc */, NULL /* filtfuncarg */,
 2439             BUS_SPACE_MAXADDR /* maxsize */,
 2440             BUS_SPACE_UNRESTRICTED /* nsegments */,
 2441             BUS_SPACE_MAXADDR /* maxsegsz */,
 2442             0 /* flags */, NULL /* lockfunc */, NULL /* lockfuncarg */,
 2443             &dmat);
 2444         if (error != 0) {
 2445                 sglist_free(sg);
 2446                 return (error);
 2447         }
 2448         /* XXXKIB */
 2449 #endif
 2450         *sg_list = sg;
 2451         return (0);
 2452 }
 2453 
 2454 void
 2455 agp_intel_gtt_insert_sg_entries(device_t dev, struct sglist *sg_list,
 2456     u_int first_entry, u_int flags)
 2457 {
 2458         struct agp_i810_softc *sc;
 2459         vm_paddr_t spaddr;
 2460         size_t slen;
 2461         u_int i, j;
 2462 
 2463         sc = device_get_softc(dev);
 2464         for (i = j = 0; j < sg_list->sg_nseg; j++) {
 2465                 spaddr = sg_list->sg_segs[i].ss_paddr;
 2466                 slen = sg_list->sg_segs[i].ss_len;
 2467                 for (; slen > 0; i++) {
 2468                         sc->match->driver->install_gtt_pte(dev, first_entry + i,
 2469                             spaddr, flags);
 2470                         spaddr += AGP_PAGE_SIZE;
 2471                         slen -= AGP_PAGE_SIZE;
 2472                 }
 2473         }
 2474         sc->match->driver->read_gtt_pte(dev, first_entry + i - 1);
 2475 }
 2476 
 2477 void
 2478 intel_gtt_clear_range(u_int first_entry, u_int num_entries)
 2479 {
 2480 
 2481         agp_intel_gtt_clear_range(intel_agp, first_entry, num_entries);
 2482 }
 2483 
 2484 void
 2485 intel_gtt_insert_pages(u_int first_entry, u_int num_entries, vm_page_t *pages,
 2486     u_int flags)
 2487 {
 2488 
 2489         agp_intel_gtt_insert_pages(intel_agp, first_entry, num_entries,
 2490             pages, flags);
 2491 }
 2492 
 2493 struct intel_gtt
 2494 intel_gtt_get(void)
 2495 {
 2496 
 2497         return (agp_intel_gtt_get(intel_agp));
 2498 }
 2499 
 2500 int
 2501 intel_gtt_chipset_flush(void)
 2502 {
 2503 
 2504         return (agp_intel_gtt_chipset_flush(intel_agp));
 2505 }
 2506 
 2507 void
 2508 intel_gtt_unmap_memory(struct sglist *sg_list)
 2509 {
 2510 
 2511         agp_intel_gtt_unmap_memory(intel_agp, sg_list);
 2512 }
 2513 
 2514 int
 2515 intel_gtt_map_memory(vm_page_t *pages, u_int num_entries,
 2516     struct sglist **sg_list)
 2517 {
 2518 
 2519         return (agp_intel_gtt_map_memory(intel_agp, pages, num_entries,
 2520             sg_list));
 2521 }
 2522 
 2523 void
 2524 intel_gtt_insert_sg_entries(struct sglist *sg_list, u_int first_entry,
 2525     u_int flags)
 2526 {
 2527 
 2528         agp_intel_gtt_insert_sg_entries(intel_agp, sg_list, first_entry, flags);
 2529 }
 2530 
 2531 device_t
 2532 intel_gtt_get_bridge_device(void)
 2533 {
 2534         struct agp_i810_softc *sc;
 2535 
 2536         sc = device_get_softc(intel_agp);
 2537         return (sc->bdev);
 2538 }
 2539 
 2540 vm_paddr_t
 2541 intel_gtt_read_pte_paddr(u_int entry)
 2542 {
 2543         struct agp_i810_softc *sc;
 2544 
 2545         sc = device_get_softc(intel_agp);
 2546         return (sc->match->driver->read_gtt_pte_paddr(intel_agp, entry));
 2547 }
 2548 
 2549 u_int32_t
 2550 intel_gtt_read_pte(u_int entry)
 2551 {
 2552         struct agp_i810_softc *sc;
 2553 
 2554         sc = device_get_softc(intel_agp);
 2555         return (sc->match->driver->read_gtt_pte(intel_agp, entry));
 2556 }
 2557 
 2558 void
 2559 intel_gtt_write(u_int entry, uint32_t val)
 2560 {
 2561         struct agp_i810_softc *sc;
 2562 
 2563         sc = device_get_softc(intel_agp);
 2564         return (sc->match->driver->write_gtt(intel_agp, entry, val));
 2565 }

Cache object: 88f10bdcc1015c8009de3b689e1b0666


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