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

Cache object: 5419aa9cab37391e32a184adf028f579


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