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