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