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