1/*-
2 * Copyright (c) 2000 Doug Rabson
3 * Copyright (c) 2000 Ruslan Ermilov
4 * Copyright (c) 2011 The FreeBSD Foundation
5 * All rights reserved.
6 *
7 * Portions of this software were developed by Konstantin Belousov
8 * under sponsorship from the FreeBSD Foundation.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * Fixes for 830/845G support: David Dawes <dawes@xfree86.org>
34 * 852GM/855GM/865G support added by David Dawes <dawes@xfree86.org>
35 *
36 * This is generic Intel GTT handling code, morphed from the AGP
37 * bridge code.
38 */
39
40#include <sys/cdefs.h>
41__FBSDID("$FreeBSD$");
42
43#include "opt_bus.h"
44
45#if 0
46#define	KTR_AGP_I810	KTR_DEV
47#else
48#define	KTR_AGP_I810	0
49#endif
50
51#include <sys/param.h>
52#include <sys/systm.h>
53#include <sys/malloc.h>
54#include <sys/kernel.h>
55#include <sys/ktr.h>
56#include <sys/module.h>
57#include <sys/bus.h>
58#include <sys/lock.h>
59#include <sys/mutex.h>
60#include <sys/proc.h>
61
62#include <dev/agp/agppriv.h>
63#include <dev/agp/agpreg.h>
64#include <dev/agp/agp_i810.h>
65#include <dev/pci/pcivar.h>
66#include <dev/pci/pcireg.h>
67#include <dev/pci/pci_private.h>
68
69#include <vm/vm.h>
70#include <vm/vm_param.h>
71#include <vm/vm_object.h>
72#include <vm/vm_page.h>
73#include <vm/vm_pageout.h>
74#include <vm/pmap.h>
75
76#include <machine/bus.h>
77#include <machine/resource.h>
78#include <machine/md_var.h>
79#include <sys/rman.h>
80
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 = 0x016a8086,
735		.name = "IvyBridge server GT2 IG",
736		.driver = &agp_i810_sb_driver
737	},
738	{
739		.devid = 0,
740	}
741};
742
743static const struct agp_i810_match*
744agp_i810_match(device_t dev)
745{
746	int i, devid;
747
748	if (pci_get_class(dev) != PCIC_DISPLAY
749	    || pci_get_subclass(dev) != PCIS_DISPLAY_VGA)
750		return (NULL);
751
752	devid = pci_get_devid(dev);
753	for (i = 0; agp_i810_matches[i].devid != 0; i++) {
754		if (agp_i810_matches[i].devid == devid)
755			break;
756	}
757	if (agp_i810_matches[i].devid == 0)
758		return (NULL);
759	else
760		return (&agp_i810_matches[i]);
761}
762
763/*
764 * Find bridge device.
765 */
766static device_t
767agp_i810_find_bridge(device_t dev)
768{
769
770	return (pci_find_dbsf(0, 0, 0, 0));
771}
772
773static void
774agp_i810_identify(driver_t *driver, device_t parent)
775{
776
777	if (device_find_child(parent, "agp", -1) == NULL &&
778	    agp_i810_match(parent))
779		device_add_child(parent, "agp", -1);
780}
781
782static int
783agp_i810_check_active(device_t bridge_dev)
784{
785	u_int8_t smram;
786
787	smram = pci_read_config(bridge_dev, AGP_I810_SMRAM, 1);
788	if ((smram & AGP_I810_SMRAM_GMS) == AGP_I810_SMRAM_GMS_DISABLED)
789		return (ENXIO);
790	return (0);
791}
792
793static int
794agp_i830_check_active(device_t bridge_dev)
795{
796	int gcc1;
797
798	gcc1 = pci_read_config(bridge_dev, AGP_I830_GCC1, 1);
799	if ((gcc1 & AGP_I830_GCC1_DEV2) == AGP_I830_GCC1_DEV2_DISABLED)
800		return (ENXIO);
801	return (0);
802}
803
804static int
805agp_i915_check_active(device_t bridge_dev)
806{
807	int deven;
808
809	deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4);
810	if ((deven & AGP_I915_DEVEN_D2F0) == AGP_I915_DEVEN_D2F0_DISABLED)
811		return (ENXIO);
812	return (0);
813}
814
815static int
816agp_sb_check_active(device_t bridge_dev)
817{
818	int deven;
819
820	deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4);
821	if ((deven & AGP_SB_DEVEN_D2EN) == AGP_SB_DEVEN_D2EN_DISABLED)
822		return (ENXIO);
823	return (0);
824}
825
826static void
827agp_82852_set_desc(device_t dev, const struct agp_i810_match *match)
828{
829
830	switch (pci_read_config(dev, AGP_I85X_CAPID, 1)) {
831	case AGP_I855_GME:
832		device_set_desc(dev,
833		    "Intel 82855GME (855GME GMCH) SVGA controller");
834		break;
835	case AGP_I855_GM:
836		device_set_desc(dev,
837		    "Intel 82855GM (855GM GMCH) SVGA controller");
838		break;
839	case AGP_I852_GME:
840		device_set_desc(dev,
841		    "Intel 82852GME (852GME GMCH) SVGA controller");
842		break;
843	case AGP_I852_GM:
844		device_set_desc(dev,
845		    "Intel 82852GM (852GM GMCH) SVGA controller");
846		break;
847	default:
848		device_set_desc(dev,
849		    "Intel 8285xM (85xGM GMCH) SVGA controller");
850		break;
851	}
852}
853
854static void
855agp_i810_set_desc(device_t dev, const struct agp_i810_match *match)
856{
857
858	device_set_desc(dev, match->name);
859}
860
861static int
862agp_i810_probe(device_t dev)
863{
864	device_t bdev;
865	const struct agp_i810_match *match;
866	int err;
867
868	if (resource_disabled("agp", device_get_unit(dev)))
869		return (ENXIO);
870	match = agp_i810_match(dev);
871	if (match == NULL)
872		return (ENXIO);
873
874	bdev = agp_i810_find_bridge(dev);
875	if (bdev == NULL) {
876		if (bootverbose)
877			printf("I810: can't find bridge device\n");
878		return (ENXIO);
879	}
880
881	/*
882	 * checking whether internal graphics device has been activated.
883	 */
884	err = match->driver->check_active(bdev);
885	if (err != 0) {
886		if (bootverbose)
887			printf("i810: disabled, not probing\n");
888		return (err);
889	}
890
891	match->driver->set_desc(dev, match);
892	return (BUS_PROBE_DEFAULT);
893}
894
895static void
896agp_i810_dump_regs(device_t dev)
897{
898	struct agp_i810_softc *sc = device_get_softc(dev);
899
900	device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
901	    bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
902	device_printf(dev, "AGP_I810_MISCC: 0x%04x\n",
903	    pci_read_config(sc->bdev, AGP_I810_MISCC, 2));
904}
905
906static void
907agp_i830_dump_regs(device_t dev)
908{
909	struct agp_i810_softc *sc = device_get_softc(dev);
910
911	device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
912	    bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
913	device_printf(dev, "AGP_I830_GCC1: 0x%02x\n",
914	    pci_read_config(sc->bdev, AGP_I830_GCC1, 1));
915}
916
917static void
918agp_i855_dump_regs(device_t dev)
919{
920	struct agp_i810_softc *sc = device_get_softc(dev);
921
922	device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
923	    bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
924	device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
925	    pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
926}
927
928static void
929agp_i915_dump_regs(device_t dev)
930{
931	struct agp_i810_softc *sc = device_get_softc(dev);
932
933	device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
934	    bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
935	device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
936	    pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
937	device_printf(dev, "AGP_I915_MSAC: 0x%02x\n",
938	    pci_read_config(sc->bdev, AGP_I915_MSAC, 1));
939}
940
941static void
942agp_i965_dump_regs(device_t dev)
943{
944	struct agp_i810_softc *sc = device_get_softc(dev);
945
946	device_printf(dev, "AGP_I965_PGTBL_CTL2: %08x\n",
947	    bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2));
948	device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
949	    pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
950	device_printf(dev, "AGP_I965_MSAC: 0x%02x\n",
951	    pci_read_config(sc->bdev, AGP_I965_MSAC, 1));
952}
953
954static void
955agp_sb_dump_regs(device_t dev)
956{
957	struct agp_i810_softc *sc = device_get_softc(dev);
958
959	device_printf(dev, "AGP_SNB_GFX_MODE: %08x\n",
960	    bus_read_4(sc->sc_res[0], AGP_SNB_GFX_MODE));
961	device_printf(dev, "AGP_SNB_GCC1: 0x%04x\n",
962	    pci_read_config(sc->bdev, AGP_SNB_GCC1, 2));
963}
964
965static int
966agp_i810_get_stolen_size(device_t dev)
967{
968	struct agp_i810_softc *sc;
969
970	sc = device_get_softc(dev);
971	sc->stolen = 0;
972	sc->stolen_size = 0;
973	return (0);
974}
975
976static int
977agp_i830_get_stolen_size(device_t dev)
978{
979	struct agp_i810_softc *sc;
980	unsigned int gcc1;
981
982	sc = device_get_softc(dev);
983
984	gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 1);
985	switch (gcc1 & AGP_I830_GCC1_GMS) {
986	case AGP_I830_GCC1_GMS_STOLEN_512:
987		sc->stolen = (512 - 132) * 1024 / 4096;
988		sc->stolen_size = 512 * 1024;
989		break;
990	case AGP_I830_GCC1_GMS_STOLEN_1024:
991		sc->stolen = (1024 - 132) * 1024 / 4096;
992		sc->stolen_size = 1024 * 1024;
993		break;
994	case AGP_I830_GCC1_GMS_STOLEN_8192:
995		sc->stolen = (8192 - 132) * 1024 / 4096;
996		sc->stolen_size = 8192 * 1024;
997		break;
998	default:
999		sc->stolen = 0;
1000		device_printf(dev,
1001		    "unknown memory configuration, disabling (GCC1 %x)\n",
1002		    gcc1);
1003		return (EINVAL);
1004	}
1005	return (0);
1006}
1007
1008static int
1009agp_i915_get_stolen_size(device_t dev)
1010{
1011	struct agp_i810_softc *sc;
1012	unsigned int gcc1, stolen, gtt_size;
1013
1014	sc = device_get_softc(dev);
1015
1016	/*
1017	 * Stolen memory is set up at the beginning of the aperture by
1018	 * the BIOS, consisting of the GATT followed by 4kb for the
1019	 * BIOS display.
1020	 */
1021	switch (sc->match->driver->chiptype) {
1022	case CHIP_I855:
1023		gtt_size = 128;
1024		break;
1025	case CHIP_I915:
1026		gtt_size = 256;
1027		break;
1028	case CHIP_I965:
1029		switch (bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL) &
1030			AGP_I810_PGTBL_SIZE_MASK) {
1031		case AGP_I810_PGTBL_SIZE_128KB:
1032			gtt_size = 128;
1033			break;
1034		case AGP_I810_PGTBL_SIZE_256KB:
1035			gtt_size = 256;
1036			break;
1037		case AGP_I810_PGTBL_SIZE_512KB:
1038			gtt_size = 512;
1039			break;
1040		case AGP_I965_PGTBL_SIZE_1MB:
1041			gtt_size = 1024;
1042			break;
1043		case AGP_I965_PGTBL_SIZE_2MB:
1044			gtt_size = 2048;
1045			break;
1046		case AGP_I965_PGTBL_SIZE_1_5MB:
1047			gtt_size = 1024 + 512;
1048			break;
1049		default:
1050			device_printf(dev, "Bad PGTBL size\n");
1051			return (EINVAL);
1052		}
1053		break;
1054	case CHIP_G33:
1055		gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 2);
1056		switch (gcc1 & AGP_G33_MGGC_GGMS_MASK) {
1057		case AGP_G33_MGGC_GGMS_SIZE_1M:
1058			gtt_size = 1024;
1059			break;
1060		case AGP_G33_MGGC_GGMS_SIZE_2M:
1061			gtt_size = 2048;
1062			break;
1063		default:
1064			device_printf(dev, "Bad PGTBL size\n");
1065			return (EINVAL);
1066		}
1067		break;
1068	case CHIP_IGD:
1069	case CHIP_G4X:
1070		gtt_size = 0;
1071		break;
1072	default:
1073		device_printf(dev, "Bad chiptype\n");
1074		return (EINVAL);
1075	}
1076
1077	/* GCC1 is called MGGC on i915+ */
1078	gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1);
1079	switch (gcc1 & AGP_I855_GCC1_GMS) {
1080	case AGP_I855_GCC1_GMS_STOLEN_1M:
1081		stolen = 1024;
1082		break;
1083	case AGP_I855_GCC1_GMS_STOLEN_4M:
1084		stolen = 4 * 1024;
1085		break;
1086	case AGP_I855_GCC1_GMS_STOLEN_8M:
1087		stolen = 8 * 1024;
1088		break;
1089	case AGP_I855_GCC1_GMS_STOLEN_16M:
1090		stolen = 16 * 1024;
1091		break;
1092	case AGP_I855_GCC1_GMS_STOLEN_32M:
1093		stolen = 32 * 1024;
1094		break;
1095	case AGP_I915_GCC1_GMS_STOLEN_48M:
1096		stolen = sc->match->driver->gen > 2 ? 48 * 1024 : 0;
1097		break;
1098	case AGP_I915_GCC1_GMS_STOLEN_64M:
1099		stolen = sc->match->driver->gen > 2 ? 64 * 1024 : 0;
1100		break;
1101	case AGP_G33_GCC1_GMS_STOLEN_128M:
1102		stolen = sc->match->driver->gen > 2 ? 128 * 1024 : 0;
1103		break;
1104	case AGP_G33_GCC1_GMS_STOLEN_256M:
1105		stolen = sc->match->driver->gen > 2 ? 256 * 1024 : 0;
1106		break;
1107	case AGP_G4X_GCC1_GMS_STOLEN_96M:
1108		if (sc->match->driver->chiptype == CHIP_I965 ||
1109		    sc->match->driver->chiptype == CHIP_G4X)
1110			stolen = 96 * 1024;
1111		else
1112			stolen = 0;
1113		break;
1114	case AGP_G4X_GCC1_GMS_STOLEN_160M:
1115		if (sc->match->driver->chiptype == CHIP_I965 ||
1116		    sc->match->driver->chiptype == CHIP_G4X)
1117			stolen = 160 * 1024;
1118		else
1119			stolen = 0;
1120		break;
1121	case AGP_G4X_GCC1_GMS_STOLEN_224M:
1122		if (sc->match->driver->chiptype == CHIP_I965 ||
1123		    sc->match->driver->chiptype == CHIP_G4X)
1124			stolen = 224 * 1024;
1125		else
1126			stolen = 0;
1127		break;
1128	case AGP_G4X_GCC1_GMS_STOLEN_352M:
1129		if (sc->match->driver->chiptype == CHIP_I965 ||
1130		    sc->match->driver->chiptype == CHIP_G4X)
1131			stolen = 352 * 1024;
1132		else
1133			stolen = 0;
1134		break;
1135	default:
1136		device_printf(dev,
1137		    "unknown memory configuration, disabling (GCC1 %x)\n",
1138		    gcc1);
1139		return (EINVAL);
1140	}
1141
1142	gtt_size += 4;
1143	sc->stolen_size = stolen * 1024;
1144	sc->stolen = (stolen - gtt_size) * 1024 / 4096;
1145
1146	return (0);
1147}
1148
1149static int
1150agp_sb_get_stolen_size(device_t dev)
1151{
1152	struct agp_i810_softc *sc;
1153	uint16_t gmch_ctl;
1154
1155	sc = device_get_softc(dev);
1156	gmch_ctl = pci_read_config(sc->bdev, AGP_SNB_GCC1, 2);
1157	switch (gmch_ctl & AGP_SNB_GMCH_GMS_STOLEN_MASK) {
1158	case AGP_SNB_GMCH_GMS_STOLEN_32M:
1159		sc->stolen_size = 32 * 1024 * 1024;
1160		break;
1161	case AGP_SNB_GMCH_GMS_STOLEN_64M:
1162		sc->stolen_size = 64 * 1024 * 1024;
1163		break;
1164	case AGP_SNB_GMCH_GMS_STOLEN_96M:
1165		sc->stolen_size = 96 * 1024 * 1024;
1166		break;
1167	case AGP_SNB_GMCH_GMS_STOLEN_128M:
1168		sc->stolen_size = 128 * 1024 * 1024;
1169		break;
1170	case AGP_SNB_GMCH_GMS_STOLEN_160M:
1171		sc->stolen_size = 160 * 1024 * 1024;
1172		break;
1173	case AGP_SNB_GMCH_GMS_STOLEN_192M:
1174		sc->stolen_size = 192 * 1024 * 1024;
1175		break;
1176	case AGP_SNB_GMCH_GMS_STOLEN_224M:
1177		sc->stolen_size = 224 * 1024 * 1024;
1178		break;
1179	case AGP_SNB_GMCH_GMS_STOLEN_256M:
1180		sc->stolen_size = 256 * 1024 * 1024;
1181		break;
1182	case AGP_SNB_GMCH_GMS_STOLEN_288M:
1183		sc->stolen_size = 288 * 1024 * 1024;
1184		break;
1185	case AGP_SNB_GMCH_GMS_STOLEN_320M:
1186		sc->stolen_size = 320 * 1024 * 1024;
1187		break;
1188	case AGP_SNB_GMCH_GMS_STOLEN_352M:
1189		sc->stolen_size = 352 * 1024 * 1024;
1190		break;
1191	case AGP_SNB_GMCH_GMS_STOLEN_384M:
1192		sc->stolen_size = 384 * 1024 * 1024;
1193		break;
1194	case AGP_SNB_GMCH_GMS_STOLEN_416M:
1195		sc->stolen_size = 416 * 1024 * 1024;
1196		break;
1197	case AGP_SNB_GMCH_GMS_STOLEN_448M:
1198		sc->stolen_size = 448 * 1024 * 1024;
1199		break;
1200	case AGP_SNB_GMCH_GMS_STOLEN_480M:
1201		sc->stolen_size = 480 * 1024 * 1024;
1202		break;
1203	case AGP_SNB_GMCH_GMS_STOLEN_512M:
1204		sc->stolen_size = 512 * 1024 * 1024;
1205		break;
1206	}
1207	sc->stolen = (sc->stolen_size - 4) / 4096;
1208	return (0);
1209}
1210
1211static int
1212agp_i810_get_gtt_mappable_entries(device_t dev)
1213{
1214	struct agp_i810_softc *sc;
1215	uint32_t ap;
1216	uint16_t miscc;
1217
1218	sc = device_get_softc(dev);
1219	miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2);
1220	if ((miscc & AGP_I810_MISCC_WINSIZE) == AGP_I810_MISCC_WINSIZE_32)
1221		ap = 32;
1222	else
1223		ap = 64;
1224	sc->gtt_mappable_entries = (ap * 1024 * 1024) >> AGP_PAGE_SHIFT;
1225	return (0);
1226}
1227
1228static int
1229agp_i830_get_gtt_mappable_entries(device_t dev)
1230{
1231	struct agp_i810_softc *sc;
1232	uint32_t ap;
1233	uint16_t gmch_ctl;
1234
1235	sc = device_get_softc(dev);
1236	gmch_ctl = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
1237	if ((gmch_ctl & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64)
1238		ap = 64;
1239	else
1240		ap = 128;
1241	sc->gtt_mappable_entries = (ap * 1024 * 1024) >> AGP_PAGE_SHIFT;
1242	return (0);
1243}
1244
1245static int
1246agp_i915_get_gtt_mappable_entries(device_t dev)
1247{
1248	struct agp_i810_softc *sc;
1249	uint32_t ap;
1250
1251	sc = device_get_softc(dev);
1252	ap = AGP_GET_APERTURE(dev);
1253	sc->gtt_mappable_entries = ap >> AGP_PAGE_SHIFT;
1254	return (0);
1255}
1256
1257static int
1258agp_i810_get_gtt_total_entries(device_t dev)
1259{
1260	struct agp_i810_softc *sc;
1261
1262	sc = device_get_softc(dev);
1263	sc->gtt_total_entries = sc->gtt_mappable_entries;
1264	return (0);
1265}
1266
1267static int
1268agp_i965_get_gtt_total_entries(device_t dev)
1269{
1270	struct agp_i810_softc *sc;
1271	uint32_t pgetbl_ctl;
1272	int error;
1273
1274	sc = device_get_softc(dev);
1275	error = 0;
1276	pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
1277	switch (pgetbl_ctl & AGP_I810_PGTBL_SIZE_MASK) {
1278	case AGP_I810_PGTBL_SIZE_128KB:
1279		sc->gtt_total_entries = 128 * 1024 / 4;
1280		break;
1281	case AGP_I810_PGTBL_SIZE_256KB:
1282		sc->gtt_total_entries = 256 * 1024 / 4;
1283		break;
1284	case AGP_I810_PGTBL_SIZE_512KB:
1285		sc->gtt_total_entries = 512 * 1024 / 4;
1286		break;
1287	/* GTT pagetable sizes bigger than 512KB are not possible on G33! */
1288	case AGP_I810_PGTBL_SIZE_1MB:
1289		sc->gtt_total_entries = 1024 * 1024 / 4;
1290		break;
1291	case AGP_I810_PGTBL_SIZE_2MB:
1292		sc->gtt_total_entries = 2 * 1024 * 1024 / 4;
1293		break;
1294	case AGP_I810_PGTBL_SIZE_1_5MB:
1295		sc->gtt_total_entries = (1024 + 512) * 1024 / 4;
1296		break;
1297	default:
1298		device_printf(dev, "Unknown page table size\n");
1299		error = ENXIO;
1300	}
1301	return (error);
1302}
1303
1304static void
1305agp_gen5_adjust_pgtbl_size(device_t dev, uint32_t sz)
1306{
1307	struct agp_i810_softc *sc;
1308	uint32_t pgetbl_ctl, pgetbl_ctl2;
1309
1310	sc = device_get_softc(dev);
1311
1312	/* Disable per-process page table. */
1313	pgetbl_ctl2 = bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2);
1314	pgetbl_ctl2 &= ~AGP_I810_PGTBL_ENABLED;
1315	bus_write_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2, pgetbl_ctl2);
1316
1317	/* Write the new ggtt size. */
1318	pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
1319	pgetbl_ctl &= ~AGP_I810_PGTBL_SIZE_MASK;
1320	pgetbl_ctl |= sz;
1321	bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgetbl_ctl);
1322}
1323
1324static int
1325agp_gen5_get_gtt_total_entries(device_t dev)
1326{
1327	struct agp_i810_softc *sc;
1328	uint16_t gcc1;
1329
1330	sc = device_get_softc(dev);
1331
1332	gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
1333	switch (gcc1 & AGP_G4x_GCC1_SIZE_MASK) {
1334	case AGP_G4x_GCC1_SIZE_1M:
1335	case AGP_G4x_GCC1_SIZE_VT_1M:
1336		agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1MB);
1337		break;
1338	case AGP_G4x_GCC1_SIZE_VT_1_5M:
1339		agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1_5MB);
1340		break;
1341	case AGP_G4x_GCC1_SIZE_2M:
1342	case AGP_G4x_GCC1_SIZE_VT_2M:
1343		agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_2MB);
1344		break;
1345	default:
1346		device_printf(dev, "Unknown page table size\n");
1347		return (ENXIO);
1348	}
1349
1350	return (agp_i965_get_gtt_total_entries(dev));
1351}
1352
1353static int
1354agp_sb_get_gtt_total_entries(device_t dev)
1355{
1356	struct agp_i810_softc *sc;
1357	uint16_t gcc1;
1358
1359	sc = device_get_softc(dev);
1360
1361	gcc1 = pci_read_config(sc->bdev, AGP_SNB_GCC1, 2);
1362	switch (gcc1 & AGP_SNB_GTT_SIZE_MASK) {
1363	default:
1364	case AGP_SNB_GTT_SIZE_0M:
1365		printf("Bad GTT size mask: 0x%04x\n", gcc1);
1366		return (ENXIO);
1367	case AGP_SNB_GTT_SIZE_1M:
1368		sc->gtt_total_entries = 1024 * 1024 / 4;
1369		break;
1370	case AGP_SNB_GTT_SIZE_2M:
1371		sc->gtt_total_entries = 2 * 1024 * 1024 / 4;
1372		break;
1373	}
1374	return (0);
1375}
1376
1377static int
1378agp_i810_install_gatt(device_t dev)
1379{
1380	struct agp_i810_softc *sc;
1381
1382	sc = device_get_softc(dev);
1383
1384	/* Some i810s have on-chip memory called dcache. */
1385	if ((bus_read_1(sc->sc_res[0], AGP_I810_DRT) & AGP_I810_DRT_POPULATED)
1386	    != 0)
1387		sc->dcache_size = 4 * 1024 * 1024;
1388	else
1389		sc->dcache_size = 0;
1390
1391	/* According to the specs the gatt on the i810 must be 64k. */
1392	sc->gatt->ag_virtual = contigmalloc(64 * 1024, M_AGP, 0, 0, ~0,
1393	    PAGE_SIZE, 0);
1394	if (sc->gatt->ag_virtual == NULL) {
1395		if (bootverbose)
1396			device_printf(dev, "contiguous allocation failed\n");
1397		return (ENOMEM);
1398	}
1399
1400	bzero(sc->gatt->ag_virtual, sc->gatt->ag_entries * sizeof(u_int32_t));
1401	sc->gatt->ag_physical = vtophys((vm_offset_t)sc->gatt->ag_virtual);
1402	agp_flush_cache();
1403	/* Install the GATT. */
1404	bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL,
1405	    sc->gatt->ag_physical | 1);
1406	return (0);
1407}
1408
1409static int
1410agp_i830_install_gatt(device_t dev)
1411{
1412	struct agp_i810_softc *sc;
1413	uint32_t pgtblctl;
1414
1415	sc = device_get_softc(dev);
1416
1417	/*
1418	 * The i830 automatically initializes the 128k gatt on boot.
1419	 * GATT address is already in there, make sure it's enabled.
1420	 */
1421	pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
1422	pgtblctl |= 1;
1423	bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
1424
1425	sc->gatt->ag_physical = pgtblctl & ~1;
1426	return (0);
1427}
1428
1429static int
1430agp_i810_attach(device_t dev)
1431{
1432	struct agp_i810_softc *sc;
1433	int error;
1434
1435	sc = device_get_softc(dev);
1436	sc->bdev = agp_i810_find_bridge(dev);
1437	if (sc->bdev == NULL)
1438		return (ENOENT);
1439
1440	sc->match = agp_i810_match(dev);
1441
1442	agp_set_aperture_resource(dev, sc->match->driver->gen <= 2 ?
1443	    AGP_APBASE : AGP_I915_GMADR);
1444	error = agp_generic_attach(dev);
1445	if (error)
1446		return (error);
1447
1448	if (ptoa((vm_paddr_t)Maxmem) >
1449	    (1ULL << sc->match->driver->busdma_addr_mask_sz) - 1) {
1450		device_printf(dev, "agp_i810 does not support physical "
1451		    "memory above %ju.\n", (uintmax_t)(1ULL <<
1452		    sc->match->driver->busdma_addr_mask_sz) - 1);
1453		return (ENOENT);
1454	}
1455
1456	if (bus_alloc_resources(dev, sc->match->driver->res_spec, sc->sc_res)) {
1457		agp_generic_detach(dev);
1458		return (ENODEV);
1459	}
1460
1461	sc->initial_aperture = AGP_GET_APERTURE(dev);
1462	sc->gatt = malloc(sizeof(struct agp_gatt), M_AGP, M_WAITOK);
1463	sc->gatt->ag_entries = AGP_GET_APERTURE(dev) >> AGP_PAGE_SHIFT;
1464
1465	if ((error = sc->match->driver->get_stolen_size(dev)) != 0 ||
1466	    (error = sc->match->driver->install_gatt(dev)) != 0 ||
1467	    (error = sc->match->driver->get_gtt_mappable_entries(dev)) != 0 ||
1468	    (error = sc->match->driver->get_gtt_total_entries(dev)) != 0 ||
1469	    (error = sc->match->driver->chipset_flush_setup(dev)) != 0) {
1470		bus_release_resources(dev, sc->match->driver->res_spec,
1471		    sc->sc_res);
1472		free(sc->gatt, M_AGP);
1473		agp_generic_detach(dev);
1474		return (error);
1475	}
1476
1477	intel_agp = dev;
1478	device_printf(dev, "aperture size is %dM",
1479	    sc->initial_aperture / 1024 / 1024);
1480	if (sc->stolen > 0)
1481		printf(", detected %dk stolen memory\n", sc->stolen * 4);
1482	else
1483		printf("\n");
1484	if (bootverbose) {
1485		sc->match->driver->dump_regs(dev);
1486		device_printf(dev, "Mappable GTT entries: %d\n",
1487		    sc->gtt_mappable_entries);
1488		device_printf(dev, "Total GTT entries: %d\n",
1489		    sc->gtt_total_entries);
1490	}
1491	return (0);
1492}
1493
1494static void
1495agp_i810_deinstall_gatt(device_t dev)
1496{
1497	struct agp_i810_softc *sc;
1498
1499	sc = device_get_softc(dev);
1500	bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, 0);
1501	contigfree(sc->gatt->ag_virtual, 64 * 1024, M_AGP);
1502}
1503
1504static void
1505agp_i830_deinstall_gatt(device_t dev)
1506{
1507	struct agp_i810_softc *sc;
1508	unsigned int pgtblctl;
1509
1510	sc = device_get_softc(dev);
1511	pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
1512	pgtblctl &= ~1;
1513	bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
1514}
1515
1516static int
1517agp_i810_detach(device_t dev)
1518{
1519	struct agp_i810_softc *sc;
1520
1521	sc = device_get_softc(dev);
1522	agp_free_cdev(dev);
1523
1524	/* Clear the GATT base. */
1525	sc->match->driver->deinstall_gatt(dev);
1526
1527	sc->match->driver->chipset_flush_teardown(dev);
1528
1529	/* Put the aperture back the way it started. */
1530	AGP_SET_APERTURE(dev, sc->initial_aperture);
1531
1532	free(sc->gatt, M_AGP);
1533	bus_release_resources(dev, sc->match->driver->res_spec, sc->sc_res);
1534	agp_free_res(dev);
1535
1536	return (0);
1537}
1538
1539static int
1540agp_i810_resume(device_t dev)
1541{
1542	struct agp_i810_softc *sc;
1543	sc = device_get_softc(dev);
1544
1545	AGP_SET_APERTURE(dev, sc->initial_aperture);
1546
1547	/* Install the GATT. */
1548	bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL,
1549	sc->gatt->ag_physical | 1);
1550
1551	return (bus_generic_resume(dev));
1552}
1553
1554/**
1555 * Sets the PCI resource size of the aperture on i830-class and below chipsets,
1556 * while returning failure on later chipsets when an actual change is
1557 * requested.
1558 *
1559 * This whole function is likely bogus, as the kernel would probably need to
1560 * reconfigure the placement of the AGP aperture if a larger size is requested,
1561 * which doesn't happen currently.
1562 */
1563static int
1564agp_i810_set_aperture(device_t dev, u_int32_t aperture)
1565{
1566	struct agp_i810_softc *sc;
1567	u_int16_t miscc;
1568
1569	sc = device_get_softc(dev);
1570	/*
1571	 * Double check for sanity.
1572	 */
1573	if (aperture != 32 * 1024 * 1024 && aperture != 64 * 1024 * 1024) {
1574		device_printf(dev, "bad aperture size %d\n", aperture);
1575		return (EINVAL);
1576	}
1577
1578	miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2);
1579	miscc &= ~AGP_I810_MISCC_WINSIZE;
1580	if (aperture == 32 * 1024 * 1024)
1581		miscc |= AGP_I810_MISCC_WINSIZE_32;
1582	else
1583		miscc |= AGP_I810_MISCC_WINSIZE_64;
1584
1585	pci_write_config(sc->bdev, AGP_I810_MISCC, miscc, 2);
1586	return (0);
1587}
1588
1589static int
1590agp_i830_set_aperture(device_t dev, u_int32_t aperture)
1591{
1592	struct agp_i810_softc *sc;
1593	u_int16_t gcc1;
1594
1595	sc = device_get_softc(dev);
1596
1597	if (aperture != 64 * 1024 * 1024 &&
1598	    aperture != 128 * 1024 * 1024) {
1599		device_printf(dev, "bad aperture size %d\n", aperture);
1600		return (EINVAL);
1601	}
1602	gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
1603	gcc1 &= ~AGP_I830_GCC1_GMASIZE;
1604	if (aperture == 64 * 1024 * 1024)
1605		gcc1 |= AGP_I830_GCC1_GMASIZE_64;
1606	else
1607		gcc1 |= AGP_I830_GCC1_GMASIZE_128;
1608
1609	pci_write_config(sc->bdev, AGP_I830_GCC1, gcc1, 2);
1610	return (0);
1611}
1612
1613static int
1614agp_i915_set_aperture(device_t dev, u_int32_t aperture)
1615{
1616
1617	return (agp_generic_set_aperture(dev, aperture));
1618}
1619
1620static int
1621agp_i810_method_set_aperture(device_t dev, u_int32_t aperture)
1622{
1623	struct agp_i810_softc *sc;
1624
1625	sc = device_get_softc(dev);
1626	return (sc->match->driver->set_aperture(dev, aperture));
1627}
1628
1629/**
1630 * Writes a GTT entry mapping the page at the given offset from the
1631 * beginning of the aperture to the given physical address.  Setup the
1632 * caching mode according to flags.
1633 *
1634 * For gen 1, 2 and 3, GTT start is located at AGP_I810_GTT offset
1635 * from corresponding BAR start. For gen 4, offset is 512KB +
1636 * AGP_I810_GTT, for gen 5 and 6 it is 2MB + AGP_I810_GTT.
1637 *
1638 * Also, the bits of the physical page address above 4GB needs to be
1639 * placed into bits 40-32 of PTE.
1640 */
1641static void
1642agp_i810_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1643    int flags)
1644{
1645	uint32_t pte;
1646
1647	pte = (u_int32_t)physical | I810_PTE_VALID;
1648	if (flags == AGP_DCACHE_MEMORY)
1649		pte |= I810_PTE_LOCAL;
1650	else if (flags == AGP_USER_CACHED_MEMORY)
1651		pte |= I830_PTE_SYSTEM_CACHED;
1652	agp_i810_write_gtt(dev, index, pte);
1653}
1654
1655static void
1656agp_i810_write_gtt(device_t dev, u_int index, uint32_t pte)
1657{
1658	struct agp_i810_softc *sc;
1659
1660	sc = device_get_softc(dev);
1661	bus_write_4(sc->sc_res[0], AGP_I810_GTT + index * 4, pte);
1662	CTR2(KTR_AGP_I810, "810_pte %x %x", index, pte);
1663}
1664
1665static void
1666agp_i830_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1667    int flags)
1668{
1669	uint32_t pte;
1670
1671	pte = (u_int32_t)physical | I810_PTE_VALID;
1672	if (flags == AGP_USER_CACHED_MEMORY)
1673		pte |= I830_PTE_SYSTEM_CACHED;
1674	agp_i810_write_gtt(dev, index, pte);
1675}
1676
1677static void
1678agp_i915_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1679    int flags)
1680{
1681	uint32_t pte;
1682
1683	pte = (u_int32_t)physical | I810_PTE_VALID;
1684	if (flags == AGP_USER_CACHED_MEMORY)
1685		pte |= I830_PTE_SYSTEM_CACHED;
1686	pte |= (physical & 0x0000000f00000000ull) >> 28;
1687	agp_i915_write_gtt(dev, index, pte);
1688}
1689
1690static void
1691agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte)
1692{
1693	struct agp_i810_softc *sc;
1694
1695	sc = device_get_softc(dev);
1696	bus_write_4(sc->sc_res[1], index * 4, pte);
1697	CTR2(KTR_AGP_I810, "915_pte %x %x", index, pte);
1698}
1699
1700static void
1701agp_i965_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1702    int flags)
1703{
1704	uint32_t pte;
1705
1706	pte = (u_int32_t)physical | I810_PTE_VALID;
1707	if (flags == AGP_USER_CACHED_MEMORY)
1708		pte |= I830_PTE_SYSTEM_CACHED;
1709	pte |= (physical & 0x0000000f00000000ull) >> 28;
1710	agp_i965_write_gtt(dev, index, pte);
1711}
1712
1713static void
1714agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte)
1715{
1716	struct agp_i810_softc *sc;
1717
1718	sc = device_get_softc(dev);
1719	bus_write_4(sc->sc_res[0], index * 4 + (512 * 1024), pte);
1720	CTR2(KTR_AGP_I810, "965_pte %x %x", index, pte);
1721}
1722
1723static void
1724agp_g4x_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1725    int flags)
1726{
1727	uint32_t pte;
1728
1729	pte = (u_int32_t)physical | I810_PTE_VALID;
1730	if (flags == AGP_USER_CACHED_MEMORY)
1731		pte |= I830_PTE_SYSTEM_CACHED;
1732	pte |= (physical & 0x0000000f00000000ull) >> 28;
1733	agp_g4x_write_gtt(dev, index, pte);
1734}
1735
1736static void
1737agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte)
1738{
1739	struct agp_i810_softc *sc;
1740
1741	sc = device_get_softc(dev);
1742	bus_write_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024), pte);
1743	CTR2(KTR_AGP_I810, "g4x_pte %x %x", index, pte);
1744}
1745
1746static void
1747agp_sb_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1748    int flags)
1749{
1750	int type_mask, gfdt;
1751	uint32_t pte;
1752
1753	pte = (u_int32_t)physical | I810_PTE_VALID;
1754	type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT;
1755	gfdt = (flags & AGP_USER_CACHED_MEMORY_GFDT) != 0 ? GEN6_PTE_GFDT : 0;
1756
1757	if (type_mask == AGP_USER_MEMORY)
1758		pte |= GEN6_PTE_UNCACHED;
1759	else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC)
1760		pte |= GEN6_PTE_LLC_MLC | gfdt;
1761	else
1762		pte |= GEN6_PTE_LLC | gfdt;
1763
1764	pte |= (physical & 0x000000ff00000000ull) >> 28;
1765	agp_sb_write_gtt(dev, index, pte);
1766}
1767
1768static void
1769agp_sb_write_gtt(device_t dev, u_int index, uint32_t pte)
1770{
1771	struct agp_i810_softc *sc;
1772
1773	sc = device_get_softc(dev);
1774	bus_write_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024), pte);
1775	CTR2(KTR_AGP_I810, "sb_pte %x %x", index, pte);
1776}
1777
1778static int
1779agp_i810_bind_page(device_t dev, vm_offset_t offset, vm_offset_t physical)
1780{
1781	struct agp_i810_softc *sc = device_get_softc(dev);
1782	u_int index;
1783
1784	if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) {
1785		device_printf(dev, "failed: offset is 0x%08jx, "
1786		    "shift is %d, entries is %d\n", (intmax_t)offset,
1787		    AGP_PAGE_SHIFT, sc->gatt->ag_entries);
1788		return (EINVAL);
1789	}
1790	index = offset >> AGP_PAGE_SHIFT;
1791	if (sc->stolen != 0 && index < sc->stolen) {
1792		device_printf(dev, "trying to bind into stolen memory\n");
1793		return (EINVAL);
1794	}
1795	sc->match->driver->install_gtt_pte(dev, index, physical, 0);
1796	return (0);
1797}
1798
1799static int
1800agp_i810_unbind_page(device_t dev, vm_offset_t offset)
1801{
1802	struct agp_i810_softc *sc;
1803	u_int index;
1804
1805	sc = device_get_softc(dev);
1806	if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
1807		return (EINVAL);
1808	index = offset >> AGP_PAGE_SHIFT;
1809	if (sc->stolen != 0 && index < sc->stolen) {
1810		device_printf(dev, "trying to unbind from stolen memory\n");
1811		return (EINVAL);
1812	}
1813	sc->match->driver->install_gtt_pte(dev, index, 0, 0);
1814	return (0);
1815}
1816
1817static u_int32_t
1818agp_i810_read_gtt_pte(device_t dev, u_int index)
1819{
1820	struct agp_i810_softc *sc;
1821	u_int32_t pte;
1822
1823	sc = device_get_softc(dev);
1824	pte = bus_read_4(sc->sc_res[0], AGP_I810_GTT + index * 4);
1825	return (pte);
1826}
1827
1828static u_int32_t
1829agp_i915_read_gtt_pte(device_t dev, u_int index)
1830{
1831	struct agp_i810_softc *sc;
1832	u_int32_t pte;
1833
1834	sc = device_get_softc(dev);
1835	pte = bus_read_4(sc->sc_res[1], index * 4);
1836	return (pte);
1837}
1838
1839static u_int32_t
1840agp_i965_read_gtt_pte(device_t dev, u_int index)
1841{
1842	struct agp_i810_softc *sc;
1843	u_int32_t pte;
1844
1845	sc = device_get_softc(dev);
1846	pte = bus_read_4(sc->sc_res[0], index * 4 + (512 * 1024));
1847	return (pte);
1848}
1849
1850static u_int32_t
1851agp_g4x_read_gtt_pte(device_t dev, u_int index)
1852{
1853	struct agp_i810_softc *sc;
1854	u_int32_t pte;
1855
1856	sc = device_get_softc(dev);
1857	pte = bus_read_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024));
1858	return (pte);
1859}
1860
1861static vm_paddr_t
1862agp_i810_read_gtt_pte_paddr(device_t dev, u_int index)
1863{
1864	struct agp_i810_softc *sc;
1865	u_int32_t pte;
1866	vm_paddr_t res;
1867
1868	sc = device_get_softc(dev);
1869	pte = sc->match->driver->read_gtt_pte(dev, index);
1870	res = pte & ~PAGE_MASK;
1871	return (res);
1872}
1873
1874static vm_paddr_t
1875agp_i915_read_gtt_pte_paddr(device_t dev, u_int index)
1876{
1877	struct agp_i810_softc *sc;
1878	u_int32_t pte;
1879	vm_paddr_t res;
1880
1881	sc = device_get_softc(dev);
1882	pte = sc->match->driver->read_gtt_pte(dev, index);
1883	res = (pte & ~PAGE_MASK) | ((pte & 0xf0) << 28);
1884	return (res);
1885}
1886
1887static vm_paddr_t
1888agp_sb_read_gtt_pte_paddr(device_t dev, u_int index)
1889{
1890	struct agp_i810_softc *sc;
1891	u_int32_t pte;
1892	vm_paddr_t res;
1893
1894	sc = device_get_softc(dev);
1895	pte = sc->match->driver->read_gtt_pte(dev, index);
1896	res = (pte & ~PAGE_MASK) | ((pte & 0xff0) << 28);
1897	return (res);
1898}
1899
1900/*
1901 * Writing via memory mapped registers already flushes all TLBs.
1902 */
1903static void
1904agp_i810_flush_tlb(device_t dev)
1905{
1906}
1907
1908static int
1909agp_i810_enable(device_t dev, u_int32_t mode)
1910{
1911
1912	return (0);
1913}
1914
1915static struct agp_memory *
1916agp_i810_alloc_memory(device_t dev, int type, vm_size_t size)
1917{
1918	struct agp_i810_softc *sc;
1919	struct agp_memory *mem;
1920	vm_page_t m;
1921
1922	sc = device_get_softc(dev);
1923
1924	if ((size & (AGP_PAGE_SIZE - 1)) != 0 ||
1925	    sc->agp.as_allocated + size > sc->agp.as_maxmem)
1926		return (0);
1927
1928	if (type == 1) {
1929		/*
1930		 * Mapping local DRAM into GATT.
1931		 */
1932		if (sc->match->driver->chiptype != CHIP_I810)
1933			return (0);
1934		if (size != sc->dcache_size)
1935			return (0);
1936	} else if (type == 2) {
1937		/*
1938		 * Type 2 is the contiguous physical memory type, that hands
1939		 * back a physical address.  This is used for cursors on i810.
1940		 * Hand back as many single pages with physical as the user
1941		 * wants, but only allow one larger allocation (ARGB cursor)
1942		 * for simplicity.
1943		 */
1944		if (size != AGP_PAGE_SIZE) {
1945			if (sc->argb_cursor != NULL)
1946				return (0);
1947
1948			/* Allocate memory for ARGB cursor, if we can. */
1949			sc->argb_cursor = contigmalloc(size, M_AGP,
1950			   0, 0, ~0, PAGE_SIZE, 0);
1951			if (sc->argb_cursor == NULL)
1952				return (0);
1953		}
1954	}
1955
1956	mem = malloc(sizeof *mem, M_AGP, M_WAITOK);
1957	mem->am_id = sc->agp.as_nextid++;
1958	mem->am_size = size;
1959	mem->am_type = type;
1960	if (type != 1 && (type != 2 || size == AGP_PAGE_SIZE))
1961		mem->am_obj = vm_object_allocate(OBJT_DEFAULT,
1962		    atop(round_page(size)));
1963	else
1964		mem->am_obj = 0;
1965
1966	if (type == 2) {
1967		if (size == AGP_PAGE_SIZE) {
1968			/*
1969			 * Allocate and wire down the page now so that we can
1970			 * get its physical address.
1971			 */
1972			VM_OBJECT_LOCK(mem->am_obj);
1973			m = vm_page_grab(mem->am_obj, 0, VM_ALLOC_NOBUSY |
1974			    VM_ALLOC_WIRED | VM_ALLOC_ZERO | VM_ALLOC_RETRY);
1975			VM_OBJECT_UNLOCK(mem->am_obj);
1976			mem->am_physical = VM_PAGE_TO_PHYS(m);
1977		} else {
1978			/* Our allocation is already nicely wired down for us.
1979			 * Just grab the physical address.
1980			 */
1981			mem->am_physical = vtophys(sc->argb_cursor);
1982		}
1983	} else
1984		mem->am_physical = 0;
1985
1986	mem->am_offset = 0;
1987	mem->am_is_bound = 0;
1988	TAILQ_INSERT_TAIL(&sc->agp.as_memory, mem, am_link);
1989	sc->agp.as_allocated += size;
1990
1991	return (mem);
1992}
1993
1994static int
1995agp_i810_free_memory(device_t dev, struct agp_memory *mem)
1996{
1997	struct agp_i810_softc *sc;
1998	vm_page_t m;
1999
2000	if (mem->am_is_bound)
2001		return (EBUSY);
2002
2003	sc = device_get_softc(dev);
2004
2005	if (mem->am_type == 2) {
2006		if (mem->am_size == AGP_PAGE_SIZE) {
2007			/*
2008			 * Unwire the page which we wired in alloc_memory.
2009			 */
2010			VM_OBJECT_LOCK(mem->am_obj);
2011			m = vm_page_lookup(mem->am_obj, 0);
2012			vm_page_lock(m);
2013			vm_page_unwire(m, 0);
2014			vm_page_unlock(m);
2015			VM_OBJECT_UNLOCK(mem->am_obj);
2016		} else {
2017			contigfree(sc->argb_cursor, mem->am_size, M_AGP);
2018			sc->argb_cursor = NULL;
2019		}
2020	}
2021
2022	sc->agp.as_allocated -= mem->am_size;
2023	TAILQ_REMOVE(&sc->agp.as_memory, mem, am_link);
2024	if (mem->am_obj)
2025		vm_object_deallocate(mem->am_obj);
2026	free(mem, M_AGP);
2027	return (0);
2028}
2029
2030static int
2031agp_i810_bind_memory(device_t dev, struct agp_memory *mem, vm_offset_t offset)
2032{
2033	struct agp_i810_softc *sc;
2034	vm_offset_t i;
2035
2036	/* Do some sanity checks first. */
2037	if ((offset & (AGP_PAGE_SIZE - 1)) != 0 ||
2038	    offset + mem->am_size > AGP_GET_APERTURE(dev)) {
2039		device_printf(dev, "binding memory at bad offset %#x\n",
2040		    (int)offset);
2041		return (EINVAL);
2042	}
2043
2044	sc = device_get_softc(dev);
2045	if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
2046		mtx_lock(&sc->agp.as_lock);
2047		if (mem->am_is_bound) {
2048			mtx_unlock(&sc->agp.as_lock);
2049			return (EINVAL);
2050		}
2051		/* The memory's already wired down, just stick it in the GTT. */
2052		for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
2053			sc->match->driver->install_gtt_pte(dev, (offset + i) >>
2054			    AGP_PAGE_SHIFT, mem->am_physical + i, 0);
2055		}
2056		agp_flush_cache();
2057		mem->am_offset = offset;
2058		mem->am_is_bound = 1;
2059		mtx_unlock(&sc->agp.as_lock);
2060		return (0);
2061	}
2062
2063	if (mem->am_type != 1)
2064		return (agp_generic_bind_memory(dev, mem, offset));
2065
2066	/*
2067	 * Mapping local DRAM into GATT.
2068	 */
2069	if (sc->match->driver->chiptype != CHIP_I810)
2070		return (EINVAL);
2071	for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
2072		bus_write_4(sc->sc_res[0],
2073		    AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, i | 3);
2074
2075	return (0);
2076}
2077
2078static int
2079agp_i810_unbind_memory(device_t dev, struct agp_memory *mem)
2080{
2081	struct agp_i810_softc *sc;
2082	vm_offset_t i;
2083
2084	sc = device_get_softc(dev);
2085
2086	if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
2087		mtx_lock(&sc->agp.as_lock);
2088		if (!mem->am_is_bound) {
2089			mtx_unlock(&sc->agp.as_lock);
2090			return (EINVAL);
2091		}
2092
2093		for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
2094			sc->match->driver->install_gtt_pte(dev,
2095			    (mem->am_offset + i) >> AGP_PAGE_SHIFT, 0, 0);
2096		}
2097		agp_flush_cache();
2098		mem->am_is_bound = 0;
2099		mtx_unlock(&sc->agp.as_lock);
2100		return (0);
2101	}
2102
2103	if (mem->am_type != 1)
2104		return (agp_generic_unbind_memory(dev, mem));
2105
2106	if (sc->match->driver->chiptype != CHIP_I810)
2107		return (EINVAL);
2108	for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
2109		sc->match->driver->install_gtt_pte(dev, i >> AGP_PAGE_SHIFT,
2110		    0, 0);
2111	}
2112	return (0);
2113}
2114
2115static device_method_t agp_i810_methods[] = {
2116	/* Device interface */
2117	DEVMETHOD(device_identify,	agp_i810_identify),
2118	DEVMETHOD(device_probe,		agp_i810_probe),
2119	DEVMETHOD(device_attach,	agp_i810_attach),
2120	DEVMETHOD(device_detach,	agp_i810_detach),
2121	DEVMETHOD(device_suspend,	bus_generic_suspend),
2122	DEVMETHOD(device_resume,	agp_i810_resume),
2123
2124	/* AGP interface */
2125	DEVMETHOD(agp_get_aperture,	agp_generic_get_aperture),
2126	DEVMETHOD(agp_set_aperture,	agp_i810_method_set_aperture),
2127	DEVMETHOD(agp_bind_page,	agp_i810_bind_page),
2128	DEVMETHOD(agp_unbind_page,	agp_i810_unbind_page),
2129	DEVMETHOD(agp_flush_tlb,	agp_i810_flush_tlb),
2130	DEVMETHOD(agp_enable,		agp_i810_enable),
2131	DEVMETHOD(agp_alloc_memory,	agp_i810_alloc_memory),
2132	DEVMETHOD(agp_free_memory,	agp_i810_free_memory),
2133	DEVMETHOD(agp_bind_memory,	agp_i810_bind_memory),
2134	DEVMETHOD(agp_unbind_memory,	agp_i810_unbind_memory),
2135	DEVMETHOD(agp_chipset_flush,	agp_intel_gtt_chipset_flush),
2136
2137	{ 0, 0 }
2138};
2139
2140static driver_t agp_i810_driver = {
2141	"agp",
2142	agp_i810_methods,
2143	sizeof(struct agp_i810_softc),
2144};
2145
2146static devclass_t agp_devclass;
2147
2148DRIVER_MODULE(agp_i810, vgapci, agp_i810_driver, agp_devclass, 0, 0);
2149MODULE_DEPEND(agp_i810, agp, 1, 1, 1);
2150MODULE_DEPEND(agp_i810, pci, 1, 1, 1);
2151
2152extern vm_page_t bogus_page;
2153
2154void
2155agp_intel_gtt_clear_range(device_t dev, u_int first_entry, u_int num_entries)
2156{
2157	struct agp_i810_softc *sc;
2158	u_int i;
2159
2160	sc = device_get_softc(dev);
2161	for (i = 0; i < num_entries; i++)
2162		sc->match->driver->install_gtt_pte(dev, first_entry + i,
2163		    VM_PAGE_TO_PHYS(bogus_page), 0);
2164	sc->match->driver->read_gtt_pte(dev, first_entry + num_entries - 1);
2165}
2166
2167void
2168agp_intel_gtt_insert_pages(device_t dev, u_int first_entry, u_int num_entries,
2169    vm_page_t *pages, u_int flags)
2170{
2171	struct agp_i810_softc *sc;
2172	u_int i;
2173
2174	sc = device_get_softc(dev);
2175	for (i = 0; i < num_entries; i++) {
2176		MPASS(pages[i]->valid == VM_PAGE_BITS_ALL);
2177		MPASS(pages[i]->wire_count > 0);
2178		sc->match->driver->install_gtt_pte(dev, first_entry + i,
2179		    VM_PAGE_TO_PHYS(pages[i]), flags);
2180	}
2181	sc->match->driver->read_gtt_pte(dev, first_entry + num_entries - 1);
2182}
2183
2184struct intel_gtt
2185agp_intel_gtt_get(device_t dev)
2186{
2187	struct agp_i810_softc *sc;
2188	struct intel_gtt res;
2189
2190	sc = device_get_softc(dev);
2191	res.stolen_size = sc->stolen_size;
2192	res.gtt_total_entries = sc->gtt_total_entries;
2193	res.gtt_mappable_entries = sc->gtt_mappable_entries;
2194	res.do_idle_maps = 0;
2195	res.scratch_page_dma = VM_PAGE_TO_PHYS(bogus_page);
2196	return (res);
2197}
2198
2199static int
2200agp_i810_chipset_flush_setup(device_t dev)
2201{
2202
2203	return (0);
2204}
2205
2206static void
2207agp_i810_chipset_flush_teardown(device_t dev)
2208{
2209
2210	/* Nothing to do. */
2211}
2212
2213static void
2214agp_i810_chipset_flush(device_t dev)
2215{
2216
2217	/* Nothing to do. */
2218}
2219
2220static void
2221agp_i830_chipset_flush(device_t dev)
2222{
2223	struct agp_i810_softc *sc;
2224	uint32_t hic;
2225	int i;
2226
2227	sc = device_get_softc(dev);
2228	pmap_invalidate_cache();
2229	hic = bus_read_4(sc->sc_res[0], AGP_I830_HIC);
2230	bus_write_4(sc->sc_res[0], AGP_I830_HIC, hic | (1 << 31));
2231	for (i = 0; i < 20000 /* 1 sec */; i++) {
2232		hic = bus_read_4(sc->sc_res[0], AGP_I830_HIC);
2233		if ((hic & (1 << 31)) == 0)
2234			break;
2235		DELAY(50);
2236	}
2237}
2238
2239static int
2240agp_i915_chipset_flush_alloc_page(device_t dev, uint64_t start, uint64_t end)
2241{
2242	struct agp_i810_softc *sc;
2243	device_t vga;
2244
2245	sc = device_get_softc(dev);
2246	vga = device_get_parent(dev);
2247	sc->sc_flush_page_rid = 100;
2248	sc->sc_flush_page_res = BUS_ALLOC_RESOURCE(device_get_parent(vga), dev,
2249	    SYS_RES_MEMORY, &sc->sc_flush_page_rid, start, end, PAGE_SIZE,
2250	    RF_ACTIVE);
2251	if (sc->sc_flush_page_res == NULL) {
2252		device_printf(dev, "Failed to allocate flush page at 0x%jx\n",
2253		    (uintmax_t)start);
2254		return (EINVAL);
2255	}
2256	sc->sc_flush_page_vaddr = rman_get_virtual(sc->sc_flush_page_res);
2257	if (bootverbose) {
2258		device_printf(dev, "Allocated flush page phys 0x%jx virt %p\n",
2259		    (uintmax_t)rman_get_start(sc->sc_flush_page_res),
2260		    sc->sc_flush_page_vaddr);
2261	}
2262	return (0);
2263}
2264
2265static void
2266agp_i915_chipset_flush_free_page(device_t dev)
2267{
2268	struct agp_i810_softc *sc;
2269	device_t vga;
2270
2271	sc = device_get_softc(dev);
2272	vga = device_get_parent(dev);
2273	if (sc->sc_flush_page_res == NULL)
2274		return;
2275	BUS_DEACTIVATE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY,
2276	    sc->sc_flush_page_rid, sc->sc_flush_page_res);
2277	BUS_RELEASE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY,
2278	    sc->sc_flush_page_rid, sc->sc_flush_page_res);
2279}
2280
2281static int
2282agp_i915_chipset_flush_setup(device_t dev)
2283{
2284	struct agp_i810_softc *sc;
2285	uint32_t temp;
2286	int error;
2287
2288	sc = device_get_softc(dev);
2289	temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4);
2290	if ((temp & 1) != 0) {
2291		temp &= ~1;
2292		if (bootverbose)
2293			device_printf(dev,
2294			    "Found already configured flush page at 0x%jx\n",
2295			    (uintmax_t)temp);
2296		sc->sc_bios_allocated_flush_page = 1;
2297		/*
2298		 * In the case BIOS initialized the flush pointer (?)
2299		 * register, expect that BIOS also set up the resource
2300		 * for the page.
2301		 */
2302		error = agp_i915_chipset_flush_alloc_page(dev, temp,
2303		    temp + PAGE_SIZE - 1);
2304		if (error != 0)
2305			return (error);
2306	} else {
2307		sc->sc_bios_allocated_flush_page = 0;
2308		error = agp_i915_chipset_flush_alloc_page(dev, 0, 0xffffffff);
2309		if (error != 0)
2310			return (error);
2311		temp = rman_get_start(sc->sc_flush_page_res);
2312		pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp | 1, 4);
2313	}
2314	return (0);
2315}
2316
2317static void
2318agp_i915_chipset_flush_teardown(device_t dev)
2319{
2320	struct agp_i810_softc *sc;
2321	uint32_t temp;
2322
2323	sc = device_get_softc(dev);
2324	if (sc->sc_flush_page_res == NULL)
2325		return;
2326	if (!sc->sc_bios_allocated_flush_page) {
2327		temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4);
2328		temp &= ~1;
2329		pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp, 4);
2330	}
2331	agp_i915_chipset_flush_free_page(dev);
2332}
2333
2334static int
2335agp_i965_chipset_flush_setup(device_t dev)
2336{
2337	struct agp_i810_softc *sc;
2338	uint64_t temp;
2339	uint32_t temp_hi, temp_lo;
2340	int error;
2341
2342	sc = device_get_softc(dev);
2343
2344	temp_hi = pci_read_config(sc->bdev, AGP_I965_IFPADDR + 4, 4);
2345	temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4);
2346
2347	if ((temp_lo & 1) != 0) {
2348		temp = ((uint64_t)temp_hi << 32) | (temp_lo & ~1);
2349		if (bootverbose)
2350			device_printf(dev,
2351			    "Found already configured flush page at 0x%jx\n",
2352			    (uintmax_t)temp);
2353		sc->sc_bios_allocated_flush_page = 1;
2354		/*
2355		 * In the case BIOS initialized the flush pointer (?)
2356		 * register, expect that BIOS also set up the resource
2357		 * for the page.
2358		 */
2359		error = agp_i915_chipset_flush_alloc_page(dev, temp,
2360		    temp + PAGE_SIZE - 1);
2361		if (error != 0)
2362			return (error);
2363	} else {
2364		sc->sc_bios_allocated_flush_page = 0;
2365		error = agp_i915_chipset_flush_alloc_page(dev, 0, ~0);
2366		if (error != 0)
2367			return (error);
2368		temp = rman_get_start(sc->sc_flush_page_res);
2369		pci_write_config(sc->bdev, AGP_I965_IFPADDR + 4,
2370		    (temp >> 32) & UINT32_MAX, 4);
2371		pci_write_config(sc->bdev, AGP_I965_IFPADDR,
2372		    (temp & UINT32_MAX) | 1, 4);
2373	}
2374	return (0);
2375}
2376
2377static void
2378agp_i965_chipset_flush_teardown(device_t dev)
2379{
2380	struct agp_i810_softc *sc;
2381	uint32_t temp_lo;
2382
2383	sc = device_get_softc(dev);
2384	if (sc->sc_flush_page_res == NULL)
2385		return;
2386	if (!sc->sc_bios_allocated_flush_page) {
2387		temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4);
2388		temp_lo &= ~1;
2389		pci_write_config(sc->bdev, AGP_I965_IFPADDR, temp_lo, 4);
2390	}
2391	agp_i915_chipset_flush_free_page(dev);
2392}
2393
2394static void
2395agp_i915_chipset_flush(device_t dev)
2396{
2397	struct agp_i810_softc *sc;
2398
2399	sc = device_get_softc(dev);
2400	*(uint32_t *)sc->sc_flush_page_vaddr = 1;
2401}
2402
2403int
2404agp_intel_gtt_chipset_flush(device_t dev)
2405{
2406	struct agp_i810_softc *sc;
2407
2408	sc = device_get_softc(dev);
2409	sc->match->driver->chipset_flush(dev);
2410	return (0);
2411}
2412
2413void
2414agp_intel_gtt_unmap_memory(device_t dev, struct sglist *sg_list)
2415{
2416}
2417
2418int
2419agp_intel_gtt_map_memory(device_t dev, vm_page_t *pages, u_int num_entries,
2420    struct sglist **sg_list)
2421{
2422	struct agp_i810_softc *sc;
2423	struct sglist *sg;
2424	int i;
2425#if 0
2426	int error;
2427	bus_dma_tag_t dmat;
2428#endif
2429
2430	if (*sg_list != NULL)
2431		return (0);
2432	sc = device_get_softc(dev);
2433	sg = sglist_alloc(num_entries, M_WAITOK /* XXXKIB */);
2434	for (i = 0; i < num_entries; i++) {
2435		sg->sg_segs[i].ss_paddr = VM_PAGE_TO_PHYS(pages[i]);
2436		sg->sg_segs[i].ss_len = PAGE_SIZE;
2437	}
2438
2439#if 0
2440	error = bus_dma_tag_create(bus_get_dma_tag(dev),
2441	    1 /* alignment */, 0 /* boundary */,
2442	    1ULL << sc->match->busdma_addr_mask_sz /* lowaddr */,
2443	    BUS_SPACE_MAXADDR /* highaddr */,
2444            NULL /* filtfunc */, NULL /* filtfuncarg */,
2445	    BUS_SPACE_MAXADDR /* maxsize */,
2446	    BUS_SPACE_UNRESTRICTED /* nsegments */,
2447	    BUS_SPACE_MAXADDR /* maxsegsz */,
2448	    0 /* flags */, NULL /* lockfunc */, NULL /* lockfuncarg */,
2449	    &dmat);
2450	if (error != 0) {
2451		sglist_free(sg);
2452		return (error);
2453	}
2454	/* XXXKIB */
2455#endif
2456	*sg_list = sg;
2457	return (0);
2458}
2459
2460void
2461agp_intel_gtt_insert_sg_entries(device_t dev, struct sglist *sg_list,
2462    u_int first_entry, u_int flags)
2463{
2464	struct agp_i810_softc *sc;
2465	vm_paddr_t spaddr;
2466	size_t slen;
2467	u_int i, j;
2468
2469	sc = device_get_softc(dev);
2470	for (i = j = 0; j < sg_list->sg_nseg; j++) {
2471		spaddr = sg_list->sg_segs[i].ss_paddr;
2472		slen = sg_list->sg_segs[i].ss_len;
2473		for (; slen > 0; i++) {
2474			sc->match->driver->install_gtt_pte(dev, first_entry + i,
2475			    spaddr, flags);
2476			spaddr += AGP_PAGE_SIZE;
2477			slen -= AGP_PAGE_SIZE;
2478		}
2479	}
2480	sc->match->driver->read_gtt_pte(dev, first_entry + i - 1);
2481}
2482
2483void
2484intel_gtt_clear_range(u_int first_entry, u_int num_entries)
2485{
2486
2487	agp_intel_gtt_clear_range(intel_agp, first_entry, num_entries);
2488}
2489
2490void
2491intel_gtt_insert_pages(u_int first_entry, u_int num_entries, vm_page_t *pages,
2492    u_int flags)
2493{
2494
2495	agp_intel_gtt_insert_pages(intel_agp, first_entry, num_entries,
2496	    pages, flags);
2497}
2498
2499struct intel_gtt
2500intel_gtt_get(void)
2501{
2502
2503	return (agp_intel_gtt_get(intel_agp));
2504}
2505
2506int
2507intel_gtt_chipset_flush(void)
2508{
2509
2510	return (agp_intel_gtt_chipset_flush(intel_agp));
2511}
2512
2513void
2514intel_gtt_unmap_memory(struct sglist *sg_list)
2515{
2516
2517	agp_intel_gtt_unmap_memory(intel_agp, sg_list);
2518}
2519
2520int
2521intel_gtt_map_memory(vm_page_t *pages, u_int num_entries,
2522    struct sglist **sg_list)
2523{
2524
2525	return (agp_intel_gtt_map_memory(intel_agp, pages, num_entries,
2526	    sg_list));
2527}
2528
2529void
2530intel_gtt_insert_sg_entries(struct sglist *sg_list, u_int first_entry,
2531    u_int flags)
2532{
2533
2534	agp_intel_gtt_insert_sg_entries(intel_agp, sg_list, first_entry, flags);
2535}
2536
2537device_t
2538intel_gtt_get_bridge_device(void)
2539{
2540	struct agp_i810_softc *sc;
2541
2542	sc = device_get_softc(intel_agp);
2543	return (sc->bdev);
2544}
2545
2546vm_paddr_t
2547intel_gtt_read_pte_paddr(u_int entry)
2548{
2549	struct agp_i810_softc *sc;
2550
2551	sc = device_get_softc(intel_agp);
2552	return (sc->match->driver->read_gtt_pte_paddr(intel_agp, entry));
2553}
2554
2555u_int32_t
2556intel_gtt_read_pte(u_int entry)
2557{
2558	struct agp_i810_softc *sc;
2559
2560	sc = device_get_softc(intel_agp);
2561	return (sc->match->driver->read_gtt_pte(intel_agp, entry));
2562}
2563
2564void
2565intel_gtt_write(u_int entry, uint32_t val)
2566{
2567	struct agp_i810_softc *sc;
2568
2569	sc = device_get_softc(intel_agp);
2570	return (sc->match->driver->write_gtt(intel_agp, entry, val));
2571}
2572