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