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


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

FreeBSD/Linux Kernel Cross Reference
sys/dev/agp/agp_i810.c

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

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

Cache object: f885b1cbc7681f92a25f700d0af5fbb8


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