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