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