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