agp_i810.c revision 273963
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 273963 2014-11-02 11:26:37Z tijl $");
42
43#if 0
44#define	KTR_AGP_I810	KTR_DEV
45#else
46#define	KTR_AGP_I810	0
47#endif
48
49#include <sys/param.h>
50#include <sys/systm.h>
51#include <sys/malloc.h>
52#include <sys/kernel.h>
53#include <sys/ktr.h>
54#include <sys/module.h>
55#include <sys/bus.h>
56#include <sys/lock.h>
57#include <sys/mutex.h>
58#include <sys/proc.h>
59#include <sys/rwlock.h>
60
61#include <dev/agp/agppriv.h>
62#include <dev/agp/agpreg.h>
63#include <dev/agp/agp_i810.h>
64#include <dev/pci/pcivar.h>
65#include <dev/pci/pcireg.h>
66#include <dev/pci/pci_private.h>
67
68#include <vm/vm.h>
69#include <vm/vm_extern.h>
70#include <vm/vm_kern.h>
71#include <vm/vm_param.h>
72#include <vm/vm_object.h>
73#include <vm/vm_page.h>
74#include <vm/vm_pageout.h>
75#include <vm/pmap.h>
76
77#include <machine/bus.h>
78#include <machine/resource.h>
79#include <machine/md_var.h>
80#include <sys/rman.h>
81
82MALLOC_DECLARE(M_AGP);
83
84struct agp_i810_match;
85
86static int agp_i810_check_active(device_t bridge_dev);
87static int agp_i830_check_active(device_t bridge_dev);
88static int agp_i915_check_active(device_t bridge_dev);
89static int agp_sb_check_active(device_t bridge_dev);
90
91static void agp_82852_set_desc(device_t dev,
92    const struct agp_i810_match *match);
93static void agp_i810_set_desc(device_t dev, const struct agp_i810_match *match);
94
95static void agp_i810_dump_regs(device_t dev);
96static void agp_i830_dump_regs(device_t dev);
97static void agp_i855_dump_regs(device_t dev);
98static void agp_i915_dump_regs(device_t dev);
99static void agp_i965_dump_regs(device_t dev);
100static void agp_sb_dump_regs(device_t dev);
101
102static int agp_i810_get_stolen_size(device_t dev);
103static int agp_i830_get_stolen_size(device_t dev);
104static int agp_i915_get_stolen_size(device_t dev);
105static int agp_sb_get_stolen_size(device_t dev);
106
107static int agp_i810_get_gtt_mappable_entries(device_t dev);
108static int agp_i830_get_gtt_mappable_entries(device_t dev);
109static int agp_i915_get_gtt_mappable_entries(device_t dev);
110
111static int agp_i810_get_gtt_total_entries(device_t dev);
112static int agp_i965_get_gtt_total_entries(device_t dev);
113static int agp_gen5_get_gtt_total_entries(device_t dev);
114static int agp_sb_get_gtt_total_entries(device_t dev);
115
116static int agp_i810_install_gatt(device_t dev);
117static int agp_i830_install_gatt(device_t dev);
118
119static void agp_i810_deinstall_gatt(device_t dev);
120static void agp_i830_deinstall_gatt(device_t dev);
121
122static void agp_i810_install_gtt_pte(device_t dev, u_int index,
123    vm_offset_t physical, int flags);
124static void agp_i830_install_gtt_pte(device_t dev, u_int index,
125    vm_offset_t physical, int flags);
126static void agp_i915_install_gtt_pte(device_t dev, u_int index,
127    vm_offset_t physical, int flags);
128static void agp_i965_install_gtt_pte(device_t dev, u_int index,
129    vm_offset_t physical, int flags);
130static void agp_g4x_install_gtt_pte(device_t dev, u_int index,
131    vm_offset_t physical, int flags);
132static void agp_sb_install_gtt_pte(device_t dev, u_int index,
133    vm_offset_t physical, int flags);
134
135static void agp_i810_write_gtt(device_t dev, u_int index, uint32_t pte);
136static void agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte);
137static void agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte);
138static void agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte);
139static void agp_sb_write_gtt(device_t dev, u_int index, uint32_t pte);
140
141static u_int32_t agp_i810_read_gtt_pte(device_t dev, u_int index);
142static u_int32_t agp_i915_read_gtt_pte(device_t dev, u_int index);
143static u_int32_t agp_i965_read_gtt_pte(device_t dev, u_int index);
144static u_int32_t agp_g4x_read_gtt_pte(device_t dev, u_int index);
145
146static vm_paddr_t agp_i810_read_gtt_pte_paddr(device_t dev, u_int index);
147static vm_paddr_t agp_i915_read_gtt_pte_paddr(device_t dev, u_int index);
148static vm_paddr_t agp_sb_read_gtt_pte_paddr(device_t dev, u_int index);
149
150static int agp_i810_set_aperture(device_t dev, u_int32_t aperture);
151static int agp_i830_set_aperture(device_t dev, u_int32_t aperture);
152static int agp_i915_set_aperture(device_t dev, u_int32_t aperture);
153
154static int agp_i810_chipset_flush_setup(device_t dev);
155static int agp_i915_chipset_flush_setup(device_t dev);
156static int agp_i965_chipset_flush_setup(device_t dev);
157
158static void agp_i810_chipset_flush_teardown(device_t dev);
159static void agp_i915_chipset_flush_teardown(device_t dev);
160static void agp_i965_chipset_flush_teardown(device_t dev);
161
162static void agp_i810_chipset_flush(device_t dev);
163static void agp_i830_chipset_flush(device_t dev);
164static void agp_i915_chipset_flush(device_t dev);
165
166enum {
167	CHIP_I810,	/* i810/i815 */
168	CHIP_I830,	/* 830M/845G */
169	CHIP_I855,	/* 852GM/855GM/865G */
170	CHIP_I915,	/* 915G/915GM */
171	CHIP_I965,	/* G965 */
172	CHIP_G33,	/* G33/Q33/Q35 */
173	CHIP_IGD,	/* Pineview */
174	CHIP_G4X,	/* G45/Q45 */
175	CHIP_SB,	/* SandyBridge */
176};
177
178/* The i810 through i855 have the registers at BAR 1, and the GATT gets
179 * allocated by us.  The i915 has registers in BAR 0 and the GATT is at the
180 * start of the stolen memory, and should only be accessed by the OS through
181 * BAR 3.  The G965 has registers and GATT in the same BAR (0) -- first 512KB
182 * is registers, second 512KB is GATT.
183 */
184static struct resource_spec agp_i810_res_spec[] = {
185	{ SYS_RES_MEMORY, AGP_I810_MMADR, RF_ACTIVE | RF_SHAREABLE },
186	{ -1, 0 }
187};
188
189static struct resource_spec agp_i915_res_spec[] = {
190	{ SYS_RES_MEMORY, AGP_I915_MMADR, RF_ACTIVE | RF_SHAREABLE },
191	{ SYS_RES_MEMORY, AGP_I915_GTTADR, RF_ACTIVE | RF_SHAREABLE },
192	{ -1, 0 }
193};
194
195static struct resource_spec agp_i965_res_spec[] = {
196	{ SYS_RES_MEMORY, AGP_I965_GTTMMADR, RF_ACTIVE | RF_SHAREABLE },
197	{ -1, 0 }
198};
199
200static struct resource_spec agp_g4x_res_spec[] = {
201	{ SYS_RES_MEMORY, AGP_G4X_MMADR, RF_ACTIVE | RF_SHAREABLE },
202	{ SYS_RES_MEMORY, AGP_G4X_GTTADR, RF_ACTIVE | RF_SHAREABLE },
203	{ -1, 0 }
204};
205
206struct agp_i810_softc {
207	struct agp_softc agp;
208	u_int32_t initial_aperture;	/* aperture size at startup */
209	struct agp_gatt *gatt;
210	u_int32_t dcache_size;		/* i810 only */
211	u_int32_t stolen;		/* number of i830/845 gtt
212					   entries for stolen memory */
213	u_int stolen_size;		/* BIOS-reserved graphics memory */
214	u_int gtt_total_entries;	/* Total number of gtt ptes */
215	u_int gtt_mappable_entries;	/* Number of gtt ptes mappable by CPU */
216	device_t bdev;			/* bridge device */
217	void *argb_cursor;		/* contigmalloc area for ARGB cursor */
218	struct resource *sc_res[2];
219	const struct agp_i810_match *match;
220	int sc_flush_page_rid;
221	struct resource *sc_flush_page_res;
222	void *sc_flush_page_vaddr;
223	int sc_bios_allocated_flush_page;
224};
225
226static device_t intel_agp;
227
228struct agp_i810_driver {
229	int chiptype;
230	int gen;
231	int busdma_addr_mask_sz;
232	struct resource_spec *res_spec;
233	int (*check_active)(device_t);
234	void (*set_desc)(device_t, const struct agp_i810_match *);
235	void (*dump_regs)(device_t);
236	int (*get_stolen_size)(device_t);
237	int (*get_gtt_total_entries)(device_t);
238	int (*get_gtt_mappable_entries)(device_t);
239	int (*install_gatt)(device_t);
240	void (*deinstall_gatt)(device_t);
241	void (*write_gtt)(device_t, u_int, uint32_t);
242	void (*install_gtt_pte)(device_t, u_int, vm_offset_t, int);
243	u_int32_t (*read_gtt_pte)(device_t, u_int);
244	vm_paddr_t (*read_gtt_pte_paddr)(device_t , u_int);
245	int (*set_aperture)(device_t, u_int32_t);
246	int (*chipset_flush_setup)(device_t);
247	void (*chipset_flush_teardown)(device_t);
248	void (*chipset_flush)(device_t);
249};
250
251static const struct agp_i810_driver agp_i810_i810_driver = {
252	.chiptype = CHIP_I810,
253	.gen = 1,
254	.busdma_addr_mask_sz = 32,
255	.res_spec = agp_i810_res_spec,
256	.check_active = agp_i810_check_active,
257	.set_desc = agp_i810_set_desc,
258	.dump_regs = agp_i810_dump_regs,
259	.get_stolen_size = agp_i810_get_stolen_size,
260	.get_gtt_mappable_entries = agp_i810_get_gtt_mappable_entries,
261	.get_gtt_total_entries = agp_i810_get_gtt_total_entries,
262	.install_gatt = agp_i810_install_gatt,
263	.deinstall_gatt = agp_i810_deinstall_gatt,
264	.write_gtt = agp_i810_write_gtt,
265	.install_gtt_pte = agp_i810_install_gtt_pte,
266	.read_gtt_pte = agp_i810_read_gtt_pte,
267	.read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
268	.set_aperture = agp_i810_set_aperture,
269	.chipset_flush_setup = agp_i810_chipset_flush_setup,
270	.chipset_flush_teardown = agp_i810_chipset_flush_teardown,
271	.chipset_flush = agp_i810_chipset_flush,
272};
273
274static const struct agp_i810_driver agp_i810_i815_driver = {
275	.chiptype = CHIP_I810,
276	.gen = 2,
277	.busdma_addr_mask_sz = 32,
278	.res_spec = agp_i810_res_spec,
279	.check_active = agp_i810_check_active,
280	.set_desc = agp_i810_set_desc,
281	.dump_regs = agp_i810_dump_regs,
282	.get_stolen_size = agp_i810_get_stolen_size,
283	.get_gtt_mappable_entries = agp_i830_get_gtt_mappable_entries,
284	.get_gtt_total_entries = agp_i810_get_gtt_total_entries,
285	.install_gatt = agp_i810_install_gatt,
286	.deinstall_gatt = agp_i810_deinstall_gatt,
287	.write_gtt = agp_i810_write_gtt,
288	.install_gtt_pte = agp_i810_install_gtt_pte,
289	.read_gtt_pte = agp_i810_read_gtt_pte,
290	.read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
291	.set_aperture = agp_i810_set_aperture,
292	.chipset_flush_setup = agp_i810_chipset_flush_setup,
293	.chipset_flush_teardown = agp_i810_chipset_flush_teardown,
294	.chipset_flush = agp_i830_chipset_flush,
295};
296
297static const struct agp_i810_driver agp_i810_i830_driver = {
298	.chiptype = CHIP_I830,
299	.gen = 2,
300	.busdma_addr_mask_sz = 32,
301	.res_spec = agp_i810_res_spec,
302	.check_active = agp_i830_check_active,
303	.set_desc = agp_i810_set_desc,
304	.dump_regs = agp_i830_dump_regs,
305	.get_stolen_size = agp_i830_get_stolen_size,
306	.get_gtt_mappable_entries = agp_i830_get_gtt_mappable_entries,
307	.get_gtt_total_entries = agp_i810_get_gtt_total_entries,
308	.install_gatt = agp_i830_install_gatt,
309	.deinstall_gatt = agp_i830_deinstall_gatt,
310	.write_gtt = agp_i810_write_gtt,
311	.install_gtt_pte = agp_i830_install_gtt_pte,
312	.read_gtt_pte = agp_i810_read_gtt_pte,
313	.read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
314	.set_aperture = agp_i830_set_aperture,
315	.chipset_flush_setup = agp_i810_chipset_flush_setup,
316	.chipset_flush_teardown = agp_i810_chipset_flush_teardown,
317	.chipset_flush = agp_i830_chipset_flush,
318};
319
320static const struct agp_i810_driver agp_i810_i855_driver = {
321	.chiptype = CHIP_I855,
322	.gen = 2,
323	.busdma_addr_mask_sz = 32,
324	.res_spec = agp_i810_res_spec,
325	.check_active = agp_i830_check_active,
326	.set_desc = agp_82852_set_desc,
327	.dump_regs = agp_i855_dump_regs,
328	.get_stolen_size = agp_i915_get_stolen_size,
329	.get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
330	.get_gtt_total_entries = agp_i810_get_gtt_total_entries,
331	.install_gatt = agp_i830_install_gatt,
332	.deinstall_gatt = agp_i830_deinstall_gatt,
333	.write_gtt = agp_i810_write_gtt,
334	.install_gtt_pte = agp_i830_install_gtt_pte,
335	.read_gtt_pte = agp_i810_read_gtt_pte,
336	.read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
337	.set_aperture = agp_i830_set_aperture,
338	.chipset_flush_setup = agp_i810_chipset_flush_setup,
339	.chipset_flush_teardown = agp_i810_chipset_flush_teardown,
340	.chipset_flush = agp_i830_chipset_flush,
341};
342
343static const struct agp_i810_driver agp_i810_i865_driver = {
344	.chiptype = CHIP_I855,
345	.gen = 2,
346	.busdma_addr_mask_sz = 32,
347	.res_spec = agp_i810_res_spec,
348	.check_active = agp_i830_check_active,
349	.set_desc = agp_i810_set_desc,
350	.dump_regs = agp_i855_dump_regs,
351	.get_stolen_size = agp_i915_get_stolen_size,
352	.get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
353	.get_gtt_total_entries = agp_i810_get_gtt_total_entries,
354	.install_gatt = agp_i830_install_gatt,
355	.deinstall_gatt = agp_i830_deinstall_gatt,
356	.write_gtt = agp_i810_write_gtt,
357	.install_gtt_pte = agp_i830_install_gtt_pte,
358	.read_gtt_pte = agp_i810_read_gtt_pte,
359	.read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
360	.set_aperture = agp_i915_set_aperture,
361	.chipset_flush_setup = agp_i810_chipset_flush_setup,
362	.chipset_flush_teardown = agp_i810_chipset_flush_teardown,
363	.chipset_flush = agp_i830_chipset_flush,
364};
365
366static const struct agp_i810_driver agp_i810_i915_driver = {
367	.chiptype = CHIP_I915,
368	.gen = 3,
369	.busdma_addr_mask_sz = 32,
370	.res_spec = agp_i915_res_spec,
371	.check_active = agp_i915_check_active,
372	.set_desc = agp_i810_set_desc,
373	.dump_regs = agp_i915_dump_regs,
374	.get_stolen_size = agp_i915_get_stolen_size,
375	.get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
376	.get_gtt_total_entries = agp_i810_get_gtt_total_entries,
377	.install_gatt = agp_i830_install_gatt,
378	.deinstall_gatt = agp_i830_deinstall_gatt,
379	.write_gtt = agp_i915_write_gtt,
380	.install_gtt_pte = agp_i915_install_gtt_pte,
381	.read_gtt_pte = agp_i915_read_gtt_pte,
382	.read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
383	.set_aperture = agp_i915_set_aperture,
384	.chipset_flush_setup = agp_i915_chipset_flush_setup,
385	.chipset_flush_teardown = agp_i915_chipset_flush_teardown,
386	.chipset_flush = agp_i915_chipset_flush,
387};
388
389static const struct agp_i810_driver agp_i810_g965_driver = {
390	.chiptype = CHIP_I965,
391	.gen = 4,
392	.busdma_addr_mask_sz = 36,
393	.res_spec = agp_i965_res_spec,
394	.check_active = agp_i915_check_active,
395	.set_desc = agp_i810_set_desc,
396	.dump_regs = agp_i965_dump_regs,
397	.get_stolen_size = agp_i915_get_stolen_size,
398	.get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
399	.get_gtt_total_entries = agp_i965_get_gtt_total_entries,
400	.install_gatt = agp_i830_install_gatt,
401	.deinstall_gatt = agp_i830_deinstall_gatt,
402	.write_gtt = agp_i965_write_gtt,
403	.install_gtt_pte = agp_i965_install_gtt_pte,
404	.read_gtt_pte = agp_i965_read_gtt_pte,
405	.read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
406	.set_aperture = agp_i915_set_aperture,
407	.chipset_flush_setup = agp_i965_chipset_flush_setup,
408	.chipset_flush_teardown = agp_i965_chipset_flush_teardown,
409	.chipset_flush = agp_i915_chipset_flush,
410};
411
412static const struct agp_i810_driver agp_i810_g33_driver = {
413	.chiptype = CHIP_G33,
414	.gen = 3,
415	.busdma_addr_mask_sz = 36,
416	.res_spec = agp_i915_res_spec,
417	.check_active = agp_i915_check_active,
418	.set_desc = agp_i810_set_desc,
419	.dump_regs = agp_i965_dump_regs,
420	.get_stolen_size = agp_i915_get_stolen_size,
421	.get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
422	.get_gtt_total_entries = agp_i965_get_gtt_total_entries,
423	.install_gatt = agp_i830_install_gatt,
424	.deinstall_gatt = agp_i830_deinstall_gatt,
425	.write_gtt = agp_i915_write_gtt,
426	.install_gtt_pte = agp_i915_install_gtt_pte,
427	.read_gtt_pte = agp_i915_read_gtt_pte,
428	.read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
429	.set_aperture = agp_i915_set_aperture,
430	.chipset_flush_setup = agp_i965_chipset_flush_setup,
431	.chipset_flush_teardown = agp_i965_chipset_flush_teardown,
432	.chipset_flush = agp_i915_chipset_flush,
433};
434
435static const struct agp_i810_driver agp_i810_igd_driver = {
436	.chiptype = CHIP_IGD,
437	.gen = 3,
438	.busdma_addr_mask_sz = 36,
439	.res_spec = agp_i915_res_spec,
440	.check_active = agp_i915_check_active,
441	.set_desc = agp_i810_set_desc,
442	.dump_regs = agp_i915_dump_regs,
443	.get_stolen_size = agp_i915_get_stolen_size,
444	.get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
445	.get_gtt_total_entries = agp_i965_get_gtt_total_entries,
446	.install_gatt = agp_i830_install_gatt,
447	.deinstall_gatt = agp_i830_deinstall_gatt,
448	.write_gtt = agp_i915_write_gtt,
449	.install_gtt_pte = agp_i915_install_gtt_pte,
450	.read_gtt_pte = agp_i915_read_gtt_pte,
451	.read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
452	.set_aperture = agp_i915_set_aperture,
453	.chipset_flush_setup = agp_i965_chipset_flush_setup,
454	.chipset_flush_teardown = agp_i965_chipset_flush_teardown,
455	.chipset_flush = agp_i915_chipset_flush,
456};
457
458static const struct agp_i810_driver agp_i810_g4x_driver = {
459	.chiptype = CHIP_G4X,
460	.gen = 5,
461	.busdma_addr_mask_sz = 36,
462	.res_spec = agp_i965_res_spec,
463	.check_active = agp_i915_check_active,
464	.set_desc = agp_i810_set_desc,
465	.dump_regs = agp_i965_dump_regs,
466	.get_stolen_size = agp_i915_get_stolen_size,
467	.get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
468	.get_gtt_total_entries = agp_gen5_get_gtt_total_entries,
469	.install_gatt = agp_i830_install_gatt,
470	.deinstall_gatt = agp_i830_deinstall_gatt,
471	.write_gtt = agp_g4x_write_gtt,
472	.install_gtt_pte = agp_g4x_install_gtt_pte,
473	.read_gtt_pte = agp_g4x_read_gtt_pte,
474	.read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
475	.set_aperture = agp_i915_set_aperture,
476	.chipset_flush_setup = agp_i965_chipset_flush_setup,
477	.chipset_flush_teardown = agp_i965_chipset_flush_teardown,
478	.chipset_flush = agp_i915_chipset_flush,
479};
480
481static const struct agp_i810_driver agp_i810_sb_driver = {
482	.chiptype = CHIP_SB,
483	.gen = 6,
484	.busdma_addr_mask_sz = 40,
485	.res_spec = agp_g4x_res_spec,
486	.check_active = agp_sb_check_active,
487	.set_desc = agp_i810_set_desc,
488	.dump_regs = agp_sb_dump_regs,
489	.get_stolen_size = agp_sb_get_stolen_size,
490	.get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
491	.get_gtt_total_entries = agp_sb_get_gtt_total_entries,
492	.install_gatt = agp_i830_install_gatt,
493	.deinstall_gatt = agp_i830_deinstall_gatt,
494	.write_gtt = agp_sb_write_gtt,
495	.install_gtt_pte = agp_sb_install_gtt_pte,
496	.read_gtt_pte = agp_g4x_read_gtt_pte,
497	.read_gtt_pte_paddr = agp_sb_read_gtt_pte_paddr,
498	.set_aperture = agp_i915_set_aperture,
499	.chipset_flush_setup = agp_i810_chipset_flush_setup,
500	.chipset_flush_teardown = agp_i810_chipset_flush_teardown,
501	.chipset_flush = agp_i810_chipset_flush,
502};
503
504/* For adding new devices, devid is the id of the graphics controller
505 * (pci:0:2:0, for example).  The placeholder (usually at pci:0:2:1) for the
506 * second head should never be added.  The bridge_offset is the offset to
507 * subtract from devid to get the id of the hostb that the device is on.
508 */
509static const struct agp_i810_match {
510	int devid;
511	char *name;
512	const struct agp_i810_driver *driver;
513} agp_i810_matches[] = {
514	{
515		.devid = 0x71218086,
516		.name = "Intel 82810 (i810 GMCH) SVGA controller",
517		.driver = &agp_i810_i810_driver
518	},
519	{
520		.devid = 0x71238086,
521		.name = "Intel 82810-DC100 (i810-DC100 GMCH) SVGA controller",
522		.driver = &agp_i810_i810_driver
523	},
524	{
525		.devid = 0x71258086,
526		.name = "Intel 82810E (i810E GMCH) SVGA controller",
527		.driver = &agp_i810_i810_driver
528	},
529	{
530		.devid = 0x11328086,
531		.name = "Intel 82815 (i815 GMCH) SVGA controller",
532		.driver = &agp_i810_i815_driver
533	},
534	{
535		.devid = 0x35778086,
536		.name = "Intel 82830M (830M GMCH) SVGA controller",
537		.driver = &agp_i810_i830_driver
538	},
539	{
540		.devid = 0x25628086,
541		.name = "Intel 82845M (845M GMCH) SVGA controller",
542		.driver = &agp_i810_i830_driver
543	},
544	{
545		.devid = 0x35828086,
546		.name = "Intel 82852/855GM SVGA controller",
547		.driver = &agp_i810_i855_driver
548	},
549	{
550		.devid = 0x25728086,
551		.name = "Intel 82865G (865G GMCH) SVGA controller",
552		.driver = &agp_i810_i865_driver
553	},
554	{
555		.devid = 0x25828086,
556		.name = "Intel 82915G (915G GMCH) SVGA controller",
557		.driver = &agp_i810_i915_driver
558	},
559	{
560		.devid = 0x258A8086,
561		.name = "Intel E7221 SVGA controller",
562		.driver = &agp_i810_i915_driver
563	},
564	{
565		.devid = 0x25928086,
566		.name = "Intel 82915GM (915GM GMCH) SVGA controller",
567		.driver = &agp_i810_i915_driver
568	},
569	{
570		.devid = 0x27728086,
571		.name = "Intel 82945G (945G GMCH) SVGA controller",
572		.driver = &agp_i810_i915_driver
573	},
574	{
575		.devid = 0x27A28086,
576		.name = "Intel 82945GM (945GM GMCH) SVGA controller",
577		.driver = &agp_i810_i915_driver
578	},
579	{
580		.devid = 0x27AE8086,
581		.name = "Intel 945GME SVGA controller",
582		.driver = &agp_i810_i915_driver
583	},
584	{
585		.devid = 0x29728086,
586		.name = "Intel 946GZ SVGA controller",
587		.driver = &agp_i810_g965_driver
588	},
589	{
590		.devid = 0x29828086,
591		.name = "Intel G965 SVGA controller",
592		.driver = &agp_i810_g965_driver
593	},
594	{
595		.devid = 0x29928086,
596		.name = "Intel Q965 SVGA controller",
597		.driver = &agp_i810_g965_driver
598	},
599	{
600		.devid = 0x29A28086,
601		.name = "Intel G965 SVGA controller",
602		.driver = &agp_i810_g965_driver
603	},
604	{
605		.devid = 0x29B28086,
606		.name = "Intel Q35 SVGA controller",
607		.driver = &agp_i810_g33_driver
608	},
609	{
610		.devid = 0x29C28086,
611		.name = "Intel G33 SVGA controller",
612		.driver = &agp_i810_g33_driver
613	},
614	{
615		.devid = 0x29D28086,
616		.name = "Intel Q33 SVGA controller",
617		.driver = &agp_i810_g33_driver
618	},
619	{
620		.devid = 0xA0018086,
621		.name = "Intel Pineview SVGA controller",
622		.driver = &agp_i810_igd_driver
623	},
624	{
625		.devid = 0xA0118086,
626		.name = "Intel Pineview (M) SVGA controller",
627		.driver = &agp_i810_igd_driver
628	},
629	{
630		.devid = 0x2A028086,
631		.name = "Intel GM965 SVGA controller",
632		.driver = &agp_i810_g965_driver
633	},
634	{
635		.devid = 0x2A128086,
636		.name = "Intel GME965 SVGA controller",
637		.driver = &agp_i810_g965_driver
638	},
639	{
640		.devid = 0x2A428086,
641		.name = "Intel GM45 SVGA controller",
642		.driver = &agp_i810_g4x_driver
643	},
644	{
645		.devid = 0x2E028086,
646		.name = "Intel Eaglelake SVGA controller",
647		.driver = &agp_i810_g4x_driver
648	},
649	{
650		.devid = 0x2E128086,
651		.name = "Intel Q45 SVGA controller",
652		.driver = &agp_i810_g4x_driver
653	},
654	{
655		.devid = 0x2E228086,
656		.name = "Intel G45 SVGA controller",
657		.driver = &agp_i810_g4x_driver
658	},
659	{
660		.devid = 0x2E328086,
661		.name = "Intel G41 SVGA controller",
662		.driver = &agp_i810_g4x_driver
663	},
664	{
665		.devid = 0x00428086,
666		.name = "Intel Ironlake (D) SVGA controller",
667		.driver = &agp_i810_g4x_driver
668	},
669	{
670		.devid = 0x00468086,
671		.name = "Intel Ironlake (M) SVGA controller",
672		.driver = &agp_i810_g4x_driver
673	},
674	{
675		.devid = 0x01028086,
676		.name = "SandyBridge desktop GT1 IG",
677		.driver = &agp_i810_sb_driver
678	},
679	{
680		.devid = 0x01128086,
681		.name = "SandyBridge desktop GT2 IG",
682		.driver = &agp_i810_sb_driver
683	},
684	{
685		.devid = 0x01228086,
686		.name = "SandyBridge desktop GT2+ IG",
687		.driver = &agp_i810_sb_driver
688	},
689	{
690		.devid = 0x01068086,
691		.name = "SandyBridge mobile GT1 IG",
692		.driver = &agp_i810_sb_driver
693	},
694	{
695		.devid = 0x01168086,
696		.name = "SandyBridge mobile GT2 IG",
697		.driver = &agp_i810_sb_driver
698	},
699	{
700		.devid = 0x01268086,
701		.name = "SandyBridge mobile GT2+ IG",
702		.driver = &agp_i810_sb_driver
703	},
704	{
705		.devid = 0x010a8086,
706		.name = "SandyBridge server IG",
707		.driver = &agp_i810_sb_driver
708	},
709	{
710		.devid = 0x01528086,
711		.name = "IvyBridge desktop GT1 IG",
712		.driver = &agp_i810_sb_driver
713	},
714	{
715		.devid = 0x01628086,
716		.name = "IvyBridge desktop GT2 IG",
717		.driver = &agp_i810_sb_driver
718	},
719	{
720		.devid = 0x01568086,
721		.name = "IvyBridge mobile GT1 IG",
722		.driver = &agp_i810_sb_driver
723	},
724	{
725		.devid = 0x01668086,
726		.name = "IvyBridge mobile GT2 IG",
727		.driver = &agp_i810_sb_driver
728	},
729	{
730		.devid = 0x015a8086,
731		.name = "IvyBridge server GT1 IG",
732		.driver = &agp_i810_sb_driver
733	},
734	{
735		.devid = 0x016a8086,
736		.name = "IvyBridge server GT2 IG",
737		.driver = &agp_i810_sb_driver
738	},
739	{
740		.devid = 0,
741	}
742};
743
744static const struct agp_i810_match*
745agp_i810_match(device_t dev)
746{
747	int i, devid;
748
749	if (pci_get_class(dev) != PCIC_DISPLAY
750	    || pci_get_subclass(dev) != PCIS_DISPLAY_VGA)
751		return (NULL);
752
753	devid = pci_get_devid(dev);
754	for (i = 0; agp_i810_matches[i].devid != 0; i++) {
755		if (agp_i810_matches[i].devid == devid)
756			break;
757	}
758	if (agp_i810_matches[i].devid == 0)
759		return (NULL);
760	else
761		return (&agp_i810_matches[i]);
762}
763
764/*
765 * Find bridge device.
766 */
767static device_t
768agp_i810_find_bridge(device_t dev)
769{
770
771	return (pci_find_dbsf(0, 0, 0, 0));
772}
773
774static void
775agp_i810_identify(driver_t *driver, device_t parent)
776{
777
778	if (device_find_child(parent, "agp", -1) == NULL &&
779	    agp_i810_match(parent))
780		device_add_child(parent, "agp", -1);
781}
782
783static int
784agp_i810_check_active(device_t bridge_dev)
785{
786	u_int8_t smram;
787
788	smram = pci_read_config(bridge_dev, AGP_I810_SMRAM, 1);
789	if ((smram & AGP_I810_SMRAM_GMS) == AGP_I810_SMRAM_GMS_DISABLED)
790		return (ENXIO);
791	return (0);
792}
793
794static int
795agp_i830_check_active(device_t bridge_dev)
796{
797	int gcc1;
798
799	gcc1 = pci_read_config(bridge_dev, AGP_I830_GCC1, 1);
800	if ((gcc1 & AGP_I830_GCC1_DEV2) == AGP_I830_GCC1_DEV2_DISABLED)
801		return (ENXIO);
802	return (0);
803}
804
805static int
806agp_i915_check_active(device_t bridge_dev)
807{
808	int deven;
809
810	deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4);
811	if ((deven & AGP_I915_DEVEN_D2F0) == AGP_I915_DEVEN_D2F0_DISABLED)
812		return (ENXIO);
813	return (0);
814}
815
816static int
817agp_sb_check_active(device_t bridge_dev)
818{
819	int deven;
820
821	deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4);
822	if ((deven & AGP_SB_DEVEN_D2EN) == AGP_SB_DEVEN_D2EN_DISABLED)
823		return (ENXIO);
824	return (0);
825}
826
827static void
828agp_82852_set_desc(device_t dev, const struct agp_i810_match *match)
829{
830
831	switch (pci_read_config(dev, AGP_I85X_CAPID, 1)) {
832	case AGP_I855_GME:
833		device_set_desc(dev,
834		    "Intel 82855GME (855GME GMCH) SVGA controller");
835		break;
836	case AGP_I855_GM:
837		device_set_desc(dev,
838		    "Intel 82855GM (855GM GMCH) SVGA controller");
839		break;
840	case AGP_I852_GME:
841		device_set_desc(dev,
842		    "Intel 82852GME (852GME GMCH) SVGA controller");
843		break;
844	case AGP_I852_GM:
845		device_set_desc(dev,
846		    "Intel 82852GM (852GM GMCH) SVGA controller");
847		break;
848	default:
849		device_set_desc(dev,
850		    "Intel 8285xM (85xGM GMCH) SVGA controller");
851		break;
852	}
853}
854
855static void
856agp_i810_set_desc(device_t dev, const struct agp_i810_match *match)
857{
858
859	device_set_desc(dev, match->name);
860}
861
862static int
863agp_i810_probe(device_t dev)
864{
865	device_t bdev;
866	const struct agp_i810_match *match;
867	int err;
868
869	if (resource_disabled("agp", device_get_unit(dev)))
870		return (ENXIO);
871	match = agp_i810_match(dev);
872	if (match == NULL)
873		return (ENXIO);
874
875	bdev = agp_i810_find_bridge(dev);
876	if (bdev == NULL) {
877		if (bootverbose)
878			printf("I810: can't find bridge device\n");
879		return (ENXIO);
880	}
881
882	/*
883	 * checking whether internal graphics device has been activated.
884	 */
885	err = match->driver->check_active(bdev);
886	if (err != 0) {
887		if (bootverbose)
888			printf("i810: disabled, not probing\n");
889		return (err);
890	}
891
892	match->driver->set_desc(dev, match);
893	return (BUS_PROBE_DEFAULT);
894}
895
896static void
897agp_i810_dump_regs(device_t dev)
898{
899	struct agp_i810_softc *sc = device_get_softc(dev);
900
901	device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
902	    bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
903	device_printf(dev, "AGP_I810_MISCC: 0x%04x\n",
904	    pci_read_config(sc->bdev, AGP_I810_MISCC, 2));
905}
906
907static void
908agp_i830_dump_regs(device_t dev)
909{
910	struct agp_i810_softc *sc = device_get_softc(dev);
911
912	device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
913	    bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
914	device_printf(dev, "AGP_I830_GCC1: 0x%02x\n",
915	    pci_read_config(sc->bdev, AGP_I830_GCC1, 1));
916}
917
918static void
919agp_i855_dump_regs(device_t dev)
920{
921	struct agp_i810_softc *sc = device_get_softc(dev);
922
923	device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
924	    bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
925	device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
926	    pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
927}
928
929static void
930agp_i915_dump_regs(device_t dev)
931{
932	struct agp_i810_softc *sc = device_get_softc(dev);
933
934	device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
935	    bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
936	device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
937	    pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
938	device_printf(dev, "AGP_I915_MSAC: 0x%02x\n",
939	    pci_read_config(sc->bdev, AGP_I915_MSAC, 1));
940}
941
942static void
943agp_i965_dump_regs(device_t dev)
944{
945	struct agp_i810_softc *sc = device_get_softc(dev);
946
947	device_printf(dev, "AGP_I965_PGTBL_CTL2: %08x\n",
948	    bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2));
949	device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
950	    pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
951	device_printf(dev, "AGP_I965_MSAC: 0x%02x\n",
952	    pci_read_config(sc->bdev, AGP_I965_MSAC, 1));
953}
954
955static void
956agp_sb_dump_regs(device_t dev)
957{
958	struct agp_i810_softc *sc = device_get_softc(dev);
959
960	device_printf(dev, "AGP_SNB_GFX_MODE: %08x\n",
961	    bus_read_4(sc->sc_res[0], AGP_SNB_GFX_MODE));
962	device_printf(dev, "AGP_SNB_GCC1: 0x%04x\n",
963	    pci_read_config(sc->bdev, AGP_SNB_GCC1, 2));
964}
965
966static int
967agp_i810_get_stolen_size(device_t dev)
968{
969	struct agp_i810_softc *sc;
970
971	sc = device_get_softc(dev);
972	sc->stolen = 0;
973	sc->stolen_size = 0;
974	return (0);
975}
976
977static int
978agp_i830_get_stolen_size(device_t dev)
979{
980	struct agp_i810_softc *sc;
981	unsigned int gcc1;
982
983	sc = device_get_softc(dev);
984
985	gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 1);
986	switch (gcc1 & AGP_I830_GCC1_GMS) {
987	case AGP_I830_GCC1_GMS_STOLEN_512:
988		sc->stolen = (512 - 132) * 1024 / 4096;
989		sc->stolen_size = 512 * 1024;
990		break;
991	case AGP_I830_GCC1_GMS_STOLEN_1024:
992		sc->stolen = (1024 - 132) * 1024 / 4096;
993		sc->stolen_size = 1024 * 1024;
994		break;
995	case AGP_I830_GCC1_GMS_STOLEN_8192:
996		sc->stolen = (8192 - 132) * 1024 / 4096;
997		sc->stolen_size = 8192 * 1024;
998		break;
999	default:
1000		sc->stolen = 0;
1001		device_printf(dev,
1002		    "unknown memory configuration, disabling (GCC1 %x)\n",
1003		    gcc1);
1004		return (EINVAL);
1005	}
1006	return (0);
1007}
1008
1009static int
1010agp_i915_get_stolen_size(device_t dev)
1011{
1012	struct agp_i810_softc *sc;
1013	unsigned int gcc1, stolen, gtt_size;
1014
1015	sc = device_get_softc(dev);
1016
1017	/*
1018	 * Stolen memory is set up at the beginning of the aperture by
1019	 * the BIOS, consisting of the GATT followed by 4kb for the
1020	 * BIOS display.
1021	 */
1022	switch (sc->match->driver->chiptype) {
1023	case CHIP_I855:
1024		gtt_size = 128;
1025		break;
1026	case CHIP_I915:
1027		gtt_size = 256;
1028		break;
1029	case CHIP_I965:
1030		switch (bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL) &
1031			AGP_I810_PGTBL_SIZE_MASK) {
1032		case AGP_I810_PGTBL_SIZE_128KB:
1033			gtt_size = 128;
1034			break;
1035		case AGP_I810_PGTBL_SIZE_256KB:
1036			gtt_size = 256;
1037			break;
1038		case AGP_I810_PGTBL_SIZE_512KB:
1039			gtt_size = 512;
1040			break;
1041		case AGP_I965_PGTBL_SIZE_1MB:
1042			gtt_size = 1024;
1043			break;
1044		case AGP_I965_PGTBL_SIZE_2MB:
1045			gtt_size = 2048;
1046			break;
1047		case AGP_I965_PGTBL_SIZE_1_5MB:
1048			gtt_size = 1024 + 512;
1049			break;
1050		default:
1051			device_printf(dev, "Bad PGTBL size\n");
1052			return (EINVAL);
1053		}
1054		break;
1055	case CHIP_G33:
1056		gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 2);
1057		switch (gcc1 & AGP_G33_MGGC_GGMS_MASK) {
1058		case AGP_G33_MGGC_GGMS_SIZE_1M:
1059			gtt_size = 1024;
1060			break;
1061		case AGP_G33_MGGC_GGMS_SIZE_2M:
1062			gtt_size = 2048;
1063			break;
1064		default:
1065			device_printf(dev, "Bad PGTBL size\n");
1066			return (EINVAL);
1067		}
1068		break;
1069	case CHIP_IGD:
1070	case CHIP_G4X:
1071		gtt_size = 0;
1072		break;
1073	default:
1074		device_printf(dev, "Bad chiptype\n");
1075		return (EINVAL);
1076	}
1077
1078	/* GCC1 is called MGGC on i915+ */
1079	gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1);
1080	switch (gcc1 & AGP_I855_GCC1_GMS) {
1081	case AGP_I855_GCC1_GMS_STOLEN_1M:
1082		stolen = 1024;
1083		break;
1084	case AGP_I855_GCC1_GMS_STOLEN_4M:
1085		stolen = 4 * 1024;
1086		break;
1087	case AGP_I855_GCC1_GMS_STOLEN_8M:
1088		stolen = 8 * 1024;
1089		break;
1090	case AGP_I855_GCC1_GMS_STOLEN_16M:
1091		stolen = 16 * 1024;
1092		break;
1093	case AGP_I855_GCC1_GMS_STOLEN_32M:
1094		stolen = 32 * 1024;
1095		break;
1096	case AGP_I915_GCC1_GMS_STOLEN_48M:
1097		stolen = sc->match->driver->gen > 2 ? 48 * 1024 : 0;
1098		break;
1099	case AGP_I915_GCC1_GMS_STOLEN_64M:
1100		stolen = sc->match->driver->gen > 2 ? 64 * 1024 : 0;
1101		break;
1102	case AGP_G33_GCC1_GMS_STOLEN_128M:
1103		stolen = sc->match->driver->gen > 2 ? 128 * 1024 : 0;
1104		break;
1105	case AGP_G33_GCC1_GMS_STOLEN_256M:
1106		stolen = sc->match->driver->gen > 2 ? 256 * 1024 : 0;
1107		break;
1108	case AGP_G4X_GCC1_GMS_STOLEN_96M:
1109		if (sc->match->driver->chiptype == CHIP_I965 ||
1110		    sc->match->driver->chiptype == CHIP_G4X)
1111			stolen = 96 * 1024;
1112		else
1113			stolen = 0;
1114		break;
1115	case AGP_G4X_GCC1_GMS_STOLEN_160M:
1116		if (sc->match->driver->chiptype == CHIP_I965 ||
1117		    sc->match->driver->chiptype == CHIP_G4X)
1118			stolen = 160 * 1024;
1119		else
1120			stolen = 0;
1121		break;
1122	case AGP_G4X_GCC1_GMS_STOLEN_224M:
1123		if (sc->match->driver->chiptype == CHIP_I965 ||
1124		    sc->match->driver->chiptype == CHIP_G4X)
1125			stolen = 224 * 1024;
1126		else
1127			stolen = 0;
1128		break;
1129	case AGP_G4X_GCC1_GMS_STOLEN_352M:
1130		if (sc->match->driver->chiptype == CHIP_I965 ||
1131		    sc->match->driver->chiptype == CHIP_G4X)
1132			stolen = 352 * 1024;
1133		else
1134			stolen = 0;
1135		break;
1136	default:
1137		device_printf(dev,
1138		    "unknown memory configuration, disabling (GCC1 %x)\n",
1139		    gcc1);
1140		return (EINVAL);
1141	}
1142
1143	gtt_size += 4;
1144	sc->stolen_size = stolen * 1024;
1145	sc->stolen = (stolen - gtt_size) * 1024 / 4096;
1146
1147	return (0);
1148}
1149
1150static int
1151agp_sb_get_stolen_size(device_t dev)
1152{
1153	struct agp_i810_softc *sc;
1154	uint16_t gmch_ctl;
1155
1156	sc = device_get_softc(dev);
1157	gmch_ctl = pci_read_config(sc->bdev, AGP_SNB_GCC1, 2);
1158	switch (gmch_ctl & AGP_SNB_GMCH_GMS_STOLEN_MASK) {
1159	case AGP_SNB_GMCH_GMS_STOLEN_32M:
1160		sc->stolen_size = 32 * 1024 * 1024;
1161		break;
1162	case AGP_SNB_GMCH_GMS_STOLEN_64M:
1163		sc->stolen_size = 64 * 1024 * 1024;
1164		break;
1165	case AGP_SNB_GMCH_GMS_STOLEN_96M:
1166		sc->stolen_size = 96 * 1024 * 1024;
1167		break;
1168	case AGP_SNB_GMCH_GMS_STOLEN_128M:
1169		sc->stolen_size = 128 * 1024 * 1024;
1170		break;
1171	case AGP_SNB_GMCH_GMS_STOLEN_160M:
1172		sc->stolen_size = 160 * 1024 * 1024;
1173		break;
1174	case AGP_SNB_GMCH_GMS_STOLEN_192M:
1175		sc->stolen_size = 192 * 1024 * 1024;
1176		break;
1177	case AGP_SNB_GMCH_GMS_STOLEN_224M:
1178		sc->stolen_size = 224 * 1024 * 1024;
1179		break;
1180	case AGP_SNB_GMCH_GMS_STOLEN_256M:
1181		sc->stolen_size = 256 * 1024 * 1024;
1182		break;
1183	case AGP_SNB_GMCH_GMS_STOLEN_288M:
1184		sc->stolen_size = 288 * 1024 * 1024;
1185		break;
1186	case AGP_SNB_GMCH_GMS_STOLEN_320M:
1187		sc->stolen_size = 320 * 1024 * 1024;
1188		break;
1189	case AGP_SNB_GMCH_GMS_STOLEN_352M:
1190		sc->stolen_size = 352 * 1024 * 1024;
1191		break;
1192	case AGP_SNB_GMCH_GMS_STOLEN_384M:
1193		sc->stolen_size = 384 * 1024 * 1024;
1194		break;
1195	case AGP_SNB_GMCH_GMS_STOLEN_416M:
1196		sc->stolen_size = 416 * 1024 * 1024;
1197		break;
1198	case AGP_SNB_GMCH_GMS_STOLEN_448M:
1199		sc->stolen_size = 448 * 1024 * 1024;
1200		break;
1201	case AGP_SNB_GMCH_GMS_STOLEN_480M:
1202		sc->stolen_size = 480 * 1024 * 1024;
1203		break;
1204	case AGP_SNB_GMCH_GMS_STOLEN_512M:
1205		sc->stolen_size = 512 * 1024 * 1024;
1206		break;
1207	}
1208	sc->stolen = (sc->stolen_size - 4) / 4096;
1209	return (0);
1210}
1211
1212static int
1213agp_i810_get_gtt_mappable_entries(device_t dev)
1214{
1215	struct agp_i810_softc *sc;
1216	uint32_t ap;
1217	uint16_t miscc;
1218
1219	sc = device_get_softc(dev);
1220	miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2);
1221	if ((miscc & AGP_I810_MISCC_WINSIZE) == AGP_I810_MISCC_WINSIZE_32)
1222		ap = 32;
1223	else
1224		ap = 64;
1225	sc->gtt_mappable_entries = (ap * 1024 * 1024) >> AGP_PAGE_SHIFT;
1226	return (0);
1227}
1228
1229static int
1230agp_i830_get_gtt_mappable_entries(device_t dev)
1231{
1232	struct agp_i810_softc *sc;
1233	uint32_t ap;
1234	uint16_t gmch_ctl;
1235
1236	sc = device_get_softc(dev);
1237	gmch_ctl = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
1238	if ((gmch_ctl & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64)
1239		ap = 64;
1240	else
1241		ap = 128;
1242	sc->gtt_mappable_entries = (ap * 1024 * 1024) >> AGP_PAGE_SHIFT;
1243	return (0);
1244}
1245
1246static int
1247agp_i915_get_gtt_mappable_entries(device_t dev)
1248{
1249	struct agp_i810_softc *sc;
1250	uint32_t ap;
1251
1252	sc = device_get_softc(dev);
1253	ap = AGP_GET_APERTURE(dev);
1254	sc->gtt_mappable_entries = ap >> AGP_PAGE_SHIFT;
1255	return (0);
1256}
1257
1258static int
1259agp_i810_get_gtt_total_entries(device_t dev)
1260{
1261	struct agp_i810_softc *sc;
1262
1263	sc = device_get_softc(dev);
1264	sc->gtt_total_entries = sc->gtt_mappable_entries;
1265	return (0);
1266}
1267
1268static int
1269agp_i965_get_gtt_total_entries(device_t dev)
1270{
1271	struct agp_i810_softc *sc;
1272	uint32_t pgetbl_ctl;
1273	int error;
1274
1275	sc = device_get_softc(dev);
1276	error = 0;
1277	pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
1278	switch (pgetbl_ctl & AGP_I810_PGTBL_SIZE_MASK) {
1279	case AGP_I810_PGTBL_SIZE_128KB:
1280		sc->gtt_total_entries = 128 * 1024 / 4;
1281		break;
1282	case AGP_I810_PGTBL_SIZE_256KB:
1283		sc->gtt_total_entries = 256 * 1024 / 4;
1284		break;
1285	case AGP_I810_PGTBL_SIZE_512KB:
1286		sc->gtt_total_entries = 512 * 1024 / 4;
1287		break;
1288	/* GTT pagetable sizes bigger than 512KB are not possible on G33! */
1289	case AGP_I810_PGTBL_SIZE_1MB:
1290		sc->gtt_total_entries = 1024 * 1024 / 4;
1291		break;
1292	case AGP_I810_PGTBL_SIZE_2MB:
1293		sc->gtt_total_entries = 2 * 1024 * 1024 / 4;
1294		break;
1295	case AGP_I810_PGTBL_SIZE_1_5MB:
1296		sc->gtt_total_entries = (1024 + 512) * 1024 / 4;
1297		break;
1298	default:
1299		device_printf(dev, "Unknown page table size\n");
1300		error = ENXIO;
1301	}
1302	return (error);
1303}
1304
1305static void
1306agp_gen5_adjust_pgtbl_size(device_t dev, uint32_t sz)
1307{
1308	struct agp_i810_softc *sc;
1309	uint32_t pgetbl_ctl, pgetbl_ctl2;
1310
1311	sc = device_get_softc(dev);
1312
1313	/* Disable per-process page table. */
1314	pgetbl_ctl2 = bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2);
1315	pgetbl_ctl2 &= ~AGP_I810_PGTBL_ENABLED;
1316	bus_write_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2, pgetbl_ctl2);
1317
1318	/* Write the new ggtt size. */
1319	pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
1320	pgetbl_ctl &= ~AGP_I810_PGTBL_SIZE_MASK;
1321	pgetbl_ctl |= sz;
1322	bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgetbl_ctl);
1323}
1324
1325static int
1326agp_gen5_get_gtt_total_entries(device_t dev)
1327{
1328	struct agp_i810_softc *sc;
1329	uint16_t gcc1;
1330
1331	sc = device_get_softc(dev);
1332
1333	gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
1334	switch (gcc1 & AGP_G4x_GCC1_SIZE_MASK) {
1335	case AGP_G4x_GCC1_SIZE_1M:
1336	case AGP_G4x_GCC1_SIZE_VT_1M:
1337		agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1MB);
1338		break;
1339	case AGP_G4x_GCC1_SIZE_VT_1_5M:
1340		agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1_5MB);
1341		break;
1342	case AGP_G4x_GCC1_SIZE_2M:
1343	case AGP_G4x_GCC1_SIZE_VT_2M:
1344		agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_2MB);
1345		break;
1346	default:
1347		device_printf(dev, "Unknown page table size\n");
1348		return (ENXIO);
1349	}
1350
1351	return (agp_i965_get_gtt_total_entries(dev));
1352}
1353
1354static int
1355agp_sb_get_gtt_total_entries(device_t dev)
1356{
1357	struct agp_i810_softc *sc;
1358	uint16_t gcc1;
1359
1360	sc = device_get_softc(dev);
1361
1362	gcc1 = pci_read_config(sc->bdev, AGP_SNB_GCC1, 2);
1363	switch (gcc1 & AGP_SNB_GTT_SIZE_MASK) {
1364	default:
1365	case AGP_SNB_GTT_SIZE_0M:
1366		printf("Bad GTT size mask: 0x%04x\n", gcc1);
1367		return (ENXIO);
1368	case AGP_SNB_GTT_SIZE_1M:
1369		sc->gtt_total_entries = 1024 * 1024 / 4;
1370		break;
1371	case AGP_SNB_GTT_SIZE_2M:
1372		sc->gtt_total_entries = 2 * 1024 * 1024 / 4;
1373		break;
1374	}
1375	return (0);
1376}
1377
1378static int
1379agp_i810_install_gatt(device_t dev)
1380{
1381	struct agp_i810_softc *sc;
1382
1383	sc = device_get_softc(dev);
1384
1385	/* Some i810s have on-chip memory called dcache. */
1386	if ((bus_read_1(sc->sc_res[0], AGP_I810_DRT) & AGP_I810_DRT_POPULATED)
1387	    != 0)
1388		sc->dcache_size = 4 * 1024 * 1024;
1389	else
1390		sc->dcache_size = 0;
1391
1392	/* According to the specs the gatt on the i810 must be 64k. */
1393	sc->gatt->ag_virtual = (void *)kmem_alloc_contig(kernel_arena,
1394	    64 * 1024, M_NOWAIT | M_ZERO, 0, ~0, PAGE_SIZE,
1395	    0, VM_MEMATTR_WRITE_COMBINING);
1396	if (sc->gatt->ag_virtual == NULL) {
1397		if (bootverbose)
1398			device_printf(dev, "contiguous allocation failed\n");
1399		return (ENOMEM);
1400	}
1401
1402	sc->gatt->ag_physical = vtophys((vm_offset_t)sc->gatt->ag_virtual);
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	kmem_free(kernel_arena, (vm_offset_t)sc->gatt->ag_virtual, 64 * 1024);
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_WLOCK(mem->am_obj);
1973			m = vm_page_grab(mem->am_obj, 0, VM_ALLOC_NOBUSY |
1974			    VM_ALLOC_WIRED | VM_ALLOC_ZERO);
1975			VM_OBJECT_WUNLOCK(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_WLOCK(mem->am_obj);
2011			m = vm_page_lookup(mem->am_obj, 0);
2012			vm_page_lock(m);
2013			vm_page_unwire(m, PQ_INACTIVE);
2014			vm_page_unlock(m);
2015			VM_OBJECT_WUNLOCK(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		mem->am_offset = offset;
2057		mem->am_is_bound = 1;
2058		mtx_unlock(&sc->agp.as_lock);
2059		return (0);
2060	}
2061
2062	if (mem->am_type != 1)
2063		return (agp_generic_bind_memory(dev, mem, offset));
2064
2065	/*
2066	 * Mapping local DRAM into GATT.
2067	 */
2068	if (sc->match->driver->chiptype != CHIP_I810)
2069		return (EINVAL);
2070	for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
2071		bus_write_4(sc->sc_res[0],
2072		    AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, i | 3);
2073
2074	return (0);
2075}
2076
2077static int
2078agp_i810_unbind_memory(device_t dev, struct agp_memory *mem)
2079{
2080	struct agp_i810_softc *sc;
2081	vm_offset_t i;
2082
2083	sc = device_get_softc(dev);
2084
2085	if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
2086		mtx_lock(&sc->agp.as_lock);
2087		if (!mem->am_is_bound) {
2088			mtx_unlock(&sc->agp.as_lock);
2089			return (EINVAL);
2090		}
2091
2092		for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
2093			sc->match->driver->install_gtt_pte(dev,
2094			    (mem->am_offset + i) >> AGP_PAGE_SHIFT, 0, 0);
2095		}
2096		mem->am_is_bound = 0;
2097		mtx_unlock(&sc->agp.as_lock);
2098		return (0);
2099	}
2100
2101	if (mem->am_type != 1)
2102		return (agp_generic_unbind_memory(dev, mem));
2103
2104	if (sc->match->driver->chiptype != CHIP_I810)
2105		return (EINVAL);
2106	for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
2107		sc->match->driver->install_gtt_pte(dev, i >> AGP_PAGE_SHIFT,
2108		    0, 0);
2109	}
2110	return (0);
2111}
2112
2113static device_method_t agp_i810_methods[] = {
2114	/* Device interface */
2115	DEVMETHOD(device_identify,	agp_i810_identify),
2116	DEVMETHOD(device_probe,		agp_i810_probe),
2117	DEVMETHOD(device_attach,	agp_i810_attach),
2118	DEVMETHOD(device_detach,	agp_i810_detach),
2119	DEVMETHOD(device_suspend,	bus_generic_suspend),
2120	DEVMETHOD(device_resume,	agp_i810_resume),
2121
2122	/* AGP interface */
2123	DEVMETHOD(agp_get_aperture,	agp_generic_get_aperture),
2124	DEVMETHOD(agp_set_aperture,	agp_i810_method_set_aperture),
2125	DEVMETHOD(agp_bind_page,	agp_i810_bind_page),
2126	DEVMETHOD(agp_unbind_page,	agp_i810_unbind_page),
2127	DEVMETHOD(agp_flush_tlb,	agp_i810_flush_tlb),
2128	DEVMETHOD(agp_enable,		agp_i810_enable),
2129	DEVMETHOD(agp_alloc_memory,	agp_i810_alloc_memory),
2130	DEVMETHOD(agp_free_memory,	agp_i810_free_memory),
2131	DEVMETHOD(agp_bind_memory,	agp_i810_bind_memory),
2132	DEVMETHOD(agp_unbind_memory,	agp_i810_unbind_memory),
2133	DEVMETHOD(agp_chipset_flush,	agp_intel_gtt_chipset_flush),
2134
2135	{ 0, 0 }
2136};
2137
2138static driver_t agp_i810_driver = {
2139	"agp",
2140	agp_i810_methods,
2141	sizeof(struct agp_i810_softc),
2142};
2143
2144static devclass_t agp_devclass;
2145
2146DRIVER_MODULE(agp_i810, vgapci, agp_i810_driver, agp_devclass, 0, 0);
2147MODULE_DEPEND(agp_i810, agp, 1, 1, 1);
2148MODULE_DEPEND(agp_i810, pci, 1, 1, 1);
2149
2150extern vm_page_t bogus_page;
2151
2152void
2153agp_intel_gtt_clear_range(device_t dev, u_int first_entry, u_int num_entries)
2154{
2155	struct agp_i810_softc *sc;
2156	u_int i;
2157
2158	sc = device_get_softc(dev);
2159	for (i = 0; i < num_entries; i++)
2160		sc->match->driver->install_gtt_pte(dev, first_entry + i,
2161		    VM_PAGE_TO_PHYS(bogus_page), 0);
2162	sc->match->driver->read_gtt_pte(dev, first_entry + num_entries - 1);
2163}
2164
2165void
2166agp_intel_gtt_insert_pages(device_t dev, u_int first_entry, u_int num_entries,
2167    vm_page_t *pages, u_int flags)
2168{
2169	struct agp_i810_softc *sc;
2170	u_int i;
2171
2172	sc = device_get_softc(dev);
2173	for (i = 0; i < num_entries; i++) {
2174		MPASS(pages[i]->valid == VM_PAGE_BITS_ALL);
2175		MPASS(pages[i]->wire_count > 0);
2176		sc->match->driver->install_gtt_pte(dev, first_entry + i,
2177		    VM_PAGE_TO_PHYS(pages[i]), flags);
2178	}
2179	sc->match->driver->read_gtt_pte(dev, first_entry + num_entries - 1);
2180}
2181
2182struct intel_gtt
2183agp_intel_gtt_get(device_t dev)
2184{
2185	struct agp_i810_softc *sc;
2186	struct intel_gtt res;
2187
2188	sc = device_get_softc(dev);
2189	res.stolen_size = sc->stolen_size;
2190	res.gtt_total_entries = sc->gtt_total_entries;
2191	res.gtt_mappable_entries = sc->gtt_mappable_entries;
2192	res.do_idle_maps = 0;
2193	res.scratch_page_dma = VM_PAGE_TO_PHYS(bogus_page);
2194	return (res);
2195}
2196
2197static int
2198agp_i810_chipset_flush_setup(device_t dev)
2199{
2200
2201	return (0);
2202}
2203
2204static void
2205agp_i810_chipset_flush_teardown(device_t dev)
2206{
2207
2208	/* Nothing to do. */
2209}
2210
2211static void
2212agp_i810_chipset_flush(device_t dev)
2213{
2214
2215	/* Nothing to do. */
2216}
2217
2218static void
2219agp_i830_chipset_flush(device_t dev)
2220{
2221	struct agp_i810_softc *sc;
2222	uint32_t hic;
2223	int i;
2224
2225	sc = device_get_softc(dev);
2226	pmap_invalidate_cache();
2227	hic = bus_read_4(sc->sc_res[0], AGP_I830_HIC);
2228	bus_write_4(sc->sc_res[0], AGP_I830_HIC, hic | (1U << 31));
2229	for (i = 0; i < 20000 /* 1 sec */; i++) {
2230		hic = bus_read_4(sc->sc_res[0], AGP_I830_HIC);
2231		if ((hic & (1U << 31)) == 0)
2232			break;
2233		DELAY(50);
2234	}
2235}
2236
2237static int
2238agp_i915_chipset_flush_alloc_page(device_t dev, uint64_t start, uint64_t end)
2239{
2240	struct agp_i810_softc *sc;
2241	device_t vga;
2242
2243	sc = device_get_softc(dev);
2244	vga = device_get_parent(dev);
2245	sc->sc_flush_page_rid = 100;
2246	sc->sc_flush_page_res = BUS_ALLOC_RESOURCE(device_get_parent(vga), dev,
2247	    SYS_RES_MEMORY, &sc->sc_flush_page_rid, start, end, PAGE_SIZE,
2248	    RF_ACTIVE);
2249	if (sc->sc_flush_page_res == NULL) {
2250		device_printf(dev, "Failed to allocate flush page at 0x%jx\n",
2251		    (uintmax_t)start);
2252		return (EINVAL);
2253	}
2254	sc->sc_flush_page_vaddr = rman_get_virtual(sc->sc_flush_page_res);
2255	if (bootverbose) {
2256		device_printf(dev, "Allocated flush page phys 0x%jx virt %p\n",
2257		    (uintmax_t)rman_get_start(sc->sc_flush_page_res),
2258		    sc->sc_flush_page_vaddr);
2259	}
2260	return (0);
2261}
2262
2263static void
2264agp_i915_chipset_flush_free_page(device_t dev)
2265{
2266	struct agp_i810_softc *sc;
2267	device_t vga;
2268
2269	sc = device_get_softc(dev);
2270	vga = device_get_parent(dev);
2271	if (sc->sc_flush_page_res == NULL)
2272		return;
2273	BUS_DEACTIVATE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY,
2274	    sc->sc_flush_page_rid, sc->sc_flush_page_res);
2275	BUS_RELEASE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY,
2276	    sc->sc_flush_page_rid, sc->sc_flush_page_res);
2277}
2278
2279static int
2280agp_i915_chipset_flush_setup(device_t dev)
2281{
2282	struct agp_i810_softc *sc;
2283	uint32_t temp;
2284	int error;
2285
2286	sc = device_get_softc(dev);
2287	temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4);
2288	if ((temp & 1) != 0) {
2289		temp &= ~1;
2290		if (bootverbose)
2291			device_printf(dev,
2292			    "Found already configured flush page at 0x%jx\n",
2293			    (uintmax_t)temp);
2294		sc->sc_bios_allocated_flush_page = 1;
2295		/*
2296		 * In the case BIOS initialized the flush pointer (?)
2297		 * register, expect that BIOS also set up the resource
2298		 * for the page.
2299		 */
2300		error = agp_i915_chipset_flush_alloc_page(dev, temp,
2301		    temp + PAGE_SIZE - 1);
2302		if (error != 0)
2303			return (error);
2304	} else {
2305		sc->sc_bios_allocated_flush_page = 0;
2306		error = agp_i915_chipset_flush_alloc_page(dev, 0, 0xffffffff);
2307		if (error != 0)
2308			return (error);
2309		temp = rman_get_start(sc->sc_flush_page_res);
2310		pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp | 1, 4);
2311	}
2312	return (0);
2313}
2314
2315static void
2316agp_i915_chipset_flush_teardown(device_t dev)
2317{
2318	struct agp_i810_softc *sc;
2319	uint32_t temp;
2320
2321	sc = device_get_softc(dev);
2322	if (sc->sc_flush_page_res == NULL)
2323		return;
2324	if (!sc->sc_bios_allocated_flush_page) {
2325		temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4);
2326		temp &= ~1;
2327		pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp, 4);
2328	}
2329	agp_i915_chipset_flush_free_page(dev);
2330}
2331
2332static int
2333agp_i965_chipset_flush_setup(device_t dev)
2334{
2335	struct agp_i810_softc *sc;
2336	uint64_t temp;
2337	uint32_t temp_hi, temp_lo;
2338	int error;
2339
2340	sc = device_get_softc(dev);
2341
2342	temp_hi = pci_read_config(sc->bdev, AGP_I965_IFPADDR + 4, 4);
2343	temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4);
2344
2345	if ((temp_lo & 1) != 0) {
2346		temp = ((uint64_t)temp_hi << 32) | (temp_lo & ~1);
2347		if (bootverbose)
2348			device_printf(dev,
2349			    "Found already configured flush page at 0x%jx\n",
2350			    (uintmax_t)temp);
2351		sc->sc_bios_allocated_flush_page = 1;
2352		/*
2353		 * In the case BIOS initialized the flush pointer (?)
2354		 * register, expect that BIOS also set up the resource
2355		 * for the page.
2356		 */
2357		error = agp_i915_chipset_flush_alloc_page(dev, temp,
2358		    temp + PAGE_SIZE - 1);
2359		if (error != 0)
2360			return (error);
2361	} else {
2362		sc->sc_bios_allocated_flush_page = 0;
2363		error = agp_i915_chipset_flush_alloc_page(dev, 0, ~0);
2364		if (error != 0)
2365			return (error);
2366		temp = rman_get_start(sc->sc_flush_page_res);
2367		pci_write_config(sc->bdev, AGP_I965_IFPADDR + 4,
2368		    (temp >> 32) & UINT32_MAX, 4);
2369		pci_write_config(sc->bdev, AGP_I965_IFPADDR,
2370		    (temp & UINT32_MAX) | 1, 4);
2371	}
2372	return (0);
2373}
2374
2375static void
2376agp_i965_chipset_flush_teardown(device_t dev)
2377{
2378	struct agp_i810_softc *sc;
2379	uint32_t temp_lo;
2380
2381	sc = device_get_softc(dev);
2382	if (sc->sc_flush_page_res == NULL)
2383		return;
2384	if (!sc->sc_bios_allocated_flush_page) {
2385		temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4);
2386		temp_lo &= ~1;
2387		pci_write_config(sc->bdev, AGP_I965_IFPADDR, temp_lo, 4);
2388	}
2389	agp_i915_chipset_flush_free_page(dev);
2390}
2391
2392static void
2393agp_i915_chipset_flush(device_t dev)
2394{
2395	struct agp_i810_softc *sc;
2396
2397	sc = device_get_softc(dev);
2398	*(uint32_t *)sc->sc_flush_page_vaddr = 1;
2399}
2400
2401int
2402agp_intel_gtt_chipset_flush(device_t dev)
2403{
2404	struct agp_i810_softc *sc;
2405
2406	sc = device_get_softc(dev);
2407	sc->match->driver->chipset_flush(dev);
2408	return (0);
2409}
2410
2411void
2412agp_intel_gtt_unmap_memory(device_t dev, struct sglist *sg_list)
2413{
2414}
2415
2416int
2417agp_intel_gtt_map_memory(device_t dev, vm_page_t *pages, u_int num_entries,
2418    struct sglist **sg_list)
2419{
2420	struct agp_i810_softc *sc;
2421	struct sglist *sg;
2422	int i;
2423#if 0
2424	int error;
2425	bus_dma_tag_t dmat;
2426#endif
2427
2428	if (*sg_list != NULL)
2429		return (0);
2430	sc = device_get_softc(dev);
2431	sg = sglist_alloc(num_entries, M_WAITOK /* XXXKIB */);
2432	for (i = 0; i < num_entries; i++) {
2433		sg->sg_segs[i].ss_paddr = VM_PAGE_TO_PHYS(pages[i]);
2434		sg->sg_segs[i].ss_len = PAGE_SIZE;
2435	}
2436
2437#if 0
2438	error = bus_dma_tag_create(bus_get_dma_tag(dev),
2439	    1 /* alignment */, 0 /* boundary */,
2440	    1ULL << sc->match->busdma_addr_mask_sz /* lowaddr */,
2441	    BUS_SPACE_MAXADDR /* highaddr */,
2442            NULL /* filtfunc */, NULL /* filtfuncarg */,
2443	    BUS_SPACE_MAXADDR /* maxsize */,
2444	    BUS_SPACE_UNRESTRICTED /* nsegments */,
2445	    BUS_SPACE_MAXADDR /* maxsegsz */,
2446	    0 /* flags */, NULL /* lockfunc */, NULL /* lockfuncarg */,
2447	    &dmat);
2448	if (error != 0) {
2449		sglist_free(sg);
2450		return (error);
2451	}
2452	/* XXXKIB */
2453#endif
2454	*sg_list = sg;
2455	return (0);
2456}
2457
2458void
2459agp_intel_gtt_insert_sg_entries(device_t dev, struct sglist *sg_list,
2460    u_int first_entry, u_int flags)
2461{
2462	struct agp_i810_softc *sc;
2463	vm_paddr_t spaddr;
2464	size_t slen;
2465	u_int i, j;
2466
2467	sc = device_get_softc(dev);
2468	for (i = j = 0; j < sg_list->sg_nseg; j++) {
2469		spaddr = sg_list->sg_segs[i].ss_paddr;
2470		slen = sg_list->sg_segs[i].ss_len;
2471		for (; slen > 0; i++) {
2472			sc->match->driver->install_gtt_pte(dev, first_entry + i,
2473			    spaddr, flags);
2474			spaddr += AGP_PAGE_SIZE;
2475			slen -= AGP_PAGE_SIZE;
2476		}
2477	}
2478	sc->match->driver->read_gtt_pte(dev, first_entry + i - 1);
2479}
2480
2481void
2482intel_gtt_clear_range(u_int first_entry, u_int num_entries)
2483{
2484
2485	agp_intel_gtt_clear_range(intel_agp, first_entry, num_entries);
2486}
2487
2488void
2489intel_gtt_insert_pages(u_int first_entry, u_int num_entries, vm_page_t *pages,
2490    u_int flags)
2491{
2492
2493	agp_intel_gtt_insert_pages(intel_agp, first_entry, num_entries,
2494	    pages, flags);
2495}
2496
2497struct intel_gtt
2498intel_gtt_get(void)
2499{
2500
2501	return (agp_intel_gtt_get(intel_agp));
2502}
2503
2504int
2505intel_gtt_chipset_flush(void)
2506{
2507
2508	return (agp_intel_gtt_chipset_flush(intel_agp));
2509}
2510
2511void
2512intel_gtt_unmap_memory(struct sglist *sg_list)
2513{
2514
2515	agp_intel_gtt_unmap_memory(intel_agp, sg_list);
2516}
2517
2518int
2519intel_gtt_map_memory(vm_page_t *pages, u_int num_entries,
2520    struct sglist **sg_list)
2521{
2522
2523	return (agp_intel_gtt_map_memory(intel_agp, pages, num_entries,
2524	    sg_list));
2525}
2526
2527void
2528intel_gtt_insert_sg_entries(struct sglist *sg_list, u_int first_entry,
2529    u_int flags)
2530{
2531
2532	agp_intel_gtt_insert_sg_entries(intel_agp, sg_list, first_entry, flags);
2533}
2534
2535device_t
2536intel_gtt_get_bridge_device(void)
2537{
2538	struct agp_i810_softc *sc;
2539
2540	sc = device_get_softc(intel_agp);
2541	return (sc->bdev);
2542}
2543
2544vm_paddr_t
2545intel_gtt_read_pte_paddr(u_int entry)
2546{
2547	struct agp_i810_softc *sc;
2548
2549	sc = device_get_softc(intel_agp);
2550	return (sc->match->driver->read_gtt_pte_paddr(intel_agp, entry));
2551}
2552
2553u_int32_t
2554intel_gtt_read_pte(u_int entry)
2555{
2556	struct agp_i810_softc *sc;
2557
2558	sc = device_get_softc(intel_agp);
2559	return (sc->match->driver->read_gtt_pte(intel_agp, entry));
2560}
2561
2562void
2563intel_gtt_write(u_int entry, uint32_t val)
2564{
2565	struct agp_i810_softc *sc;
2566
2567	sc = device_get_softc(intel_agp);
2568	return (sc->match->driver->write_gtt(intel_agp, entry, val));
2569}
2570