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