2 * Copyright (c) 2000 Doug Rabson
3 * Copyright (c) 2000 Ruslan Ermilov
4 * Copyright (c) 2011 The FreeBSD Foundation
7 * Portions of this software were developed by Konstantin Belousov
8 * under sponsorship from the FreeBSD Foundation.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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
31 * $FreeBSD: src/sys/dev/agp/agp_i810.c,v 1.56 2010/03/12 21:34:23 rnoland Exp $
35 * Fixes for 830/845G support: David Dawes <dawes@xfree86.org>
36 * 852GM/855GM/865G support added by David Dawes <dawes@xfree86.org>
38 * This is generic Intel GTT handling code, morphed from the AGP
43 #define KTR_AGP_I810 KTR_DEV
45 #define KTR_AGP_I810 0
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/malloc.h>
51 #include <sys/kernel.h>
56 #include <bus/pci/pcivar.h>
57 #include <bus/pci/pcireg.h>
60 #include <dev/agp/agp_i810.h>
63 #include <vm/vm_object.h>
64 #include <vm/vm_page.h>
65 #include <vm/vm_pageout.h>
68 #include <machine/md_var.h>
70 #define bus_read_1(r, o) \
71 bus_space_read_1((r)->r_bustag, (r)->r_bushandle, (o))
72 #define bus_read_4(r, o) \
73 bus_space_read_4((r)->r_bustag, (r)->r_bushandle, (o))
74 #define bus_write_4(r, o, v) \
75 bus_space_write_4((r)->r_bustag, (r)->r_bushandle, (o), (v))
77 MALLOC_DECLARE(M_AGP);
79 struct agp_i810_match;
81 static int agp_i810_check_active(device_t bridge_dev);
82 static int agp_i830_check_active(device_t bridge_dev);
83 static int agp_i915_check_active(device_t bridge_dev);
84 static int agp_sb_check_active(device_t bridge_dev);
86 static void agp_82852_set_desc(device_t dev,
87 const struct agp_i810_match *match);
88 static void agp_i810_set_desc(device_t dev, const struct agp_i810_match *match);
90 static void agp_i810_dump_regs(device_t dev);
91 static void agp_i830_dump_regs(device_t dev);
92 static void agp_i855_dump_regs(device_t dev);
93 static void agp_i915_dump_regs(device_t dev);
94 static void agp_i965_dump_regs(device_t dev);
95 static void agp_sb_dump_regs(device_t dev);
97 static int agp_i810_get_stolen_size(device_t dev);
98 static int agp_i830_get_stolen_size(device_t dev);
99 static int agp_i915_get_stolen_size(device_t dev);
100 static int agp_sb_get_stolen_size(device_t dev);
102 static int agp_i810_get_gtt_mappable_entries(device_t dev);
103 static int agp_i830_get_gtt_mappable_entries(device_t dev);
104 static int agp_i915_get_gtt_mappable_entries(device_t dev);
106 static int agp_i810_get_gtt_total_entries(device_t dev);
107 static int agp_i965_get_gtt_total_entries(device_t dev);
108 static int agp_gen5_get_gtt_total_entries(device_t dev);
109 static int agp_sb_get_gtt_total_entries(device_t dev);
111 static int agp_i810_install_gatt(device_t dev);
112 static int agp_i830_install_gatt(device_t dev);
114 static void agp_i810_deinstall_gatt(device_t dev);
115 static void agp_i830_deinstall_gatt(device_t dev);
117 static void agp_i810_install_gtt_pte(device_t dev, u_int index,
118 vm_offset_t physical, int flags);
119 static void agp_i830_install_gtt_pte(device_t dev, u_int index,
120 vm_offset_t physical, int flags);
121 static void agp_i915_install_gtt_pte(device_t dev, u_int index,
122 vm_offset_t physical, int flags);
123 static void agp_i965_install_gtt_pte(device_t dev, u_int index,
124 vm_offset_t physical, int flags);
125 static void agp_g4x_install_gtt_pte(device_t dev, u_int index,
126 vm_offset_t physical, int flags);
127 static void agp_sb_install_gtt_pte(device_t dev, u_int index,
128 vm_offset_t physical, int flags);
130 static void agp_i810_write_gtt(device_t dev, u_int index, uint32_t pte);
131 static void agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte);
132 static void agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte);
133 static void agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte);
134 static void agp_sb_write_gtt(device_t dev, u_int index, uint32_t pte);
136 static u_int32_t agp_i810_read_gtt_pte(device_t dev, u_int index);
137 static u_int32_t agp_i915_read_gtt_pte(device_t dev, u_int index);
138 static u_int32_t agp_i965_read_gtt_pte(device_t dev, u_int index);
139 static u_int32_t agp_g4x_read_gtt_pte(device_t dev, u_int index);
141 static vm_paddr_t agp_i810_read_gtt_pte_paddr(device_t dev, u_int index);
142 static vm_paddr_t agp_i915_read_gtt_pte_paddr(device_t dev, u_int index);
143 static vm_paddr_t agp_sb_read_gtt_pte_paddr(device_t dev, u_int index);
145 static int agp_i810_set_aperture(device_t dev, u_int32_t aperture);
146 static int agp_i830_set_aperture(device_t dev, u_int32_t aperture);
147 static int agp_i915_set_aperture(device_t dev, u_int32_t aperture);
149 static int agp_i810_chipset_flush_setup(device_t dev);
150 static int agp_i915_chipset_flush_setup(device_t dev);
151 static int agp_i965_chipset_flush_setup(device_t dev);
153 static void agp_i810_chipset_flush_teardown(device_t dev);
154 static void agp_i915_chipset_flush_teardown(device_t dev);
155 static void agp_i965_chipset_flush_teardown(device_t dev);
157 static void agp_i810_chipset_flush(device_t dev);
158 static void agp_i830_chipset_flush(device_t dev);
159 static void agp_i915_chipset_flush(device_t dev);
162 CHIP_I810, /* i810/i815 */
163 CHIP_I830, /* 830M/845G */
164 CHIP_I855, /* 852GM/855GM/865G */
165 CHIP_I915, /* 915G/915GM */
166 CHIP_I965, /* G965 */
167 CHIP_G33, /* G33/Q33/Q35 */
168 CHIP_IGD, /* Pineview */
169 CHIP_G4X, /* G45/Q45 */
170 CHIP_SB, /* SandyBridge */
173 /* The i810 through i855 have the registers at BAR 1, and the GATT gets
174 * allocated by us. The i915 has registers in BAR 0 and the GATT is at the
175 * start of the stolen memory, and should only be accessed by the OS through
176 * BAR 3. The G965 has registers and GATT in the same BAR (0) -- first 512KB
177 * is registers, second 512KB is GATT.
179 static struct resource_spec agp_i810_res_spec[] = {
180 { SYS_RES_MEMORY, AGP_I810_MMADR, RF_ACTIVE | RF_SHAREABLE },
184 static struct resource_spec agp_i915_res_spec[] = {
185 { SYS_RES_MEMORY, AGP_I915_MMADR, RF_ACTIVE | RF_SHAREABLE },
186 { SYS_RES_MEMORY, AGP_I915_GTTADR, RF_ACTIVE | RF_SHAREABLE },
190 static struct resource_spec agp_i965_res_spec[] = {
191 { SYS_RES_MEMORY, AGP_I965_GTTMMADR, RF_ACTIVE | RF_SHAREABLE },
195 static struct resource_spec agp_g4x_res_spec[] = {
196 { SYS_RES_MEMORY, AGP_G4X_MMADR, RF_ACTIVE | RF_SHAREABLE },
197 { SYS_RES_MEMORY, AGP_G4X_GTTADR, RF_ACTIVE | RF_SHAREABLE },
201 struct agp_i810_softc {
202 struct agp_softc agp;
203 u_int32_t initial_aperture; /* aperture size at startup */
204 struct agp_gatt *gatt;
205 u_int32_t dcache_size; /* i810 only */
206 u_int32_t stolen; /* number of i830/845 gtt
207 entries for stolen memory */
208 u_int stolen_size; /* BIOS-reserved graphics memory */
209 u_int gtt_total_entries; /* Total number of gtt ptes */
210 u_int gtt_mappable_entries; /* Number of gtt ptes mappable by CPU */
211 device_t bdev; /* bridge device */
212 void *argb_cursor; /* contigmalloc area for ARGB cursor */
213 struct resource *sc_res[2];
214 const struct agp_i810_match *match;
215 int sc_flush_page_rid;
216 struct resource *sc_flush_page_res;
217 void *sc_flush_page_vaddr;
218 int sc_bios_allocated_flush_page;
221 static device_t intel_agp;
223 struct agp_i810_driver {
226 int busdma_addr_mask_sz;
227 struct resource_spec *res_spec;
228 int (*check_active)(device_t);
229 void (*set_desc)(device_t, const struct agp_i810_match *);
230 void (*dump_regs)(device_t);
231 int (*get_stolen_size)(device_t);
232 int (*get_gtt_total_entries)(device_t);
233 int (*get_gtt_mappable_entries)(device_t);
234 int (*install_gatt)(device_t);
235 void (*deinstall_gatt)(device_t);
236 void (*write_gtt)(device_t, u_int, uint32_t);
237 void (*install_gtt_pte)(device_t, u_int, vm_offset_t, int);
238 u_int32_t (*read_gtt_pte)(device_t, u_int);
239 vm_paddr_t (*read_gtt_pte_paddr)(device_t , u_int);
240 int (*set_aperture)(device_t, u_int32_t);
241 int (*chipset_flush_setup)(device_t);
242 void (*chipset_flush_teardown)(device_t);
243 void (*chipset_flush)(device_t);
246 static const struct agp_i810_driver agp_i810_i810_driver = {
247 .chiptype = CHIP_I810,
249 .busdma_addr_mask_sz = 32,
250 .res_spec = agp_i810_res_spec,
251 .check_active = agp_i810_check_active,
252 .set_desc = agp_i810_set_desc,
253 .dump_regs = agp_i810_dump_regs,
254 .get_stolen_size = agp_i810_get_stolen_size,
255 .get_gtt_mappable_entries = agp_i810_get_gtt_mappable_entries,
256 .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
257 .install_gatt = agp_i810_install_gatt,
258 .deinstall_gatt = agp_i810_deinstall_gatt,
259 .write_gtt = agp_i810_write_gtt,
260 .install_gtt_pte = agp_i810_install_gtt_pte,
261 .read_gtt_pte = agp_i810_read_gtt_pte,
262 .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
263 .set_aperture = agp_i810_set_aperture,
264 .chipset_flush_setup = agp_i810_chipset_flush_setup,
265 .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
266 .chipset_flush = agp_i810_chipset_flush,
269 static const struct agp_i810_driver agp_i810_i815_driver = {
270 .chiptype = CHIP_I810,
272 .busdma_addr_mask_sz = 32,
273 .res_spec = agp_i810_res_spec,
274 .check_active = agp_i810_check_active,
275 .set_desc = agp_i810_set_desc,
276 .dump_regs = agp_i810_dump_regs,
277 .get_stolen_size = agp_i810_get_stolen_size,
278 .get_gtt_mappable_entries = agp_i830_get_gtt_mappable_entries,
279 .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
280 .install_gatt = agp_i810_install_gatt,
281 .deinstall_gatt = agp_i810_deinstall_gatt,
282 .write_gtt = agp_i810_write_gtt,
283 .install_gtt_pte = agp_i810_install_gtt_pte,
284 .read_gtt_pte = agp_i810_read_gtt_pte,
285 .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
286 .set_aperture = agp_i810_set_aperture,
287 .chipset_flush_setup = agp_i810_chipset_flush_setup,
288 .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
289 .chipset_flush = agp_i830_chipset_flush,
292 static const struct agp_i810_driver agp_i810_i830_driver = {
293 .chiptype = CHIP_I830,
295 .busdma_addr_mask_sz = 32,
296 .res_spec = agp_i810_res_spec,
297 .check_active = agp_i830_check_active,
298 .set_desc = agp_i810_set_desc,
299 .dump_regs = agp_i830_dump_regs,
300 .get_stolen_size = agp_i830_get_stolen_size,
301 .get_gtt_mappable_entries = agp_i830_get_gtt_mappable_entries,
302 .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
303 .install_gatt = agp_i830_install_gatt,
304 .deinstall_gatt = agp_i830_deinstall_gatt,
305 .write_gtt = agp_i810_write_gtt,
306 .install_gtt_pte = agp_i830_install_gtt_pte,
307 .read_gtt_pte = agp_i810_read_gtt_pte,
308 .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
309 .set_aperture = agp_i830_set_aperture,
310 .chipset_flush_setup = agp_i810_chipset_flush_setup,
311 .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
312 .chipset_flush = agp_i830_chipset_flush,
315 static const struct agp_i810_driver agp_i810_i855_driver = {
316 .chiptype = CHIP_I855,
318 .busdma_addr_mask_sz = 32,
319 .res_spec = agp_i810_res_spec,
320 .check_active = agp_i830_check_active,
321 .set_desc = agp_82852_set_desc,
322 .dump_regs = agp_i855_dump_regs,
323 .get_stolen_size = agp_i915_get_stolen_size,
324 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
325 .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
326 .install_gatt = agp_i830_install_gatt,
327 .deinstall_gatt = agp_i830_deinstall_gatt,
328 .write_gtt = agp_i810_write_gtt,
329 .install_gtt_pte = agp_i830_install_gtt_pte,
330 .read_gtt_pte = agp_i810_read_gtt_pte,
331 .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
332 .set_aperture = agp_i830_set_aperture,
333 .chipset_flush_setup = agp_i810_chipset_flush_setup,
334 .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
335 .chipset_flush = agp_i830_chipset_flush,
338 static const struct agp_i810_driver agp_i810_i865_driver = {
339 .chiptype = CHIP_I855,
341 .busdma_addr_mask_sz = 32,
342 .res_spec = agp_i810_res_spec,
343 .check_active = agp_i830_check_active,
344 .set_desc = agp_i810_set_desc,
345 .dump_regs = agp_i855_dump_regs,
346 .get_stolen_size = agp_i915_get_stolen_size,
347 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
348 .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
349 .install_gatt = agp_i830_install_gatt,
350 .deinstall_gatt = agp_i830_deinstall_gatt,
351 .write_gtt = agp_i810_write_gtt,
352 .install_gtt_pte = agp_i830_install_gtt_pte,
353 .read_gtt_pte = agp_i810_read_gtt_pte,
354 .read_gtt_pte_paddr = agp_i810_read_gtt_pte_paddr,
355 .set_aperture = agp_i915_set_aperture,
356 .chipset_flush_setup = agp_i810_chipset_flush_setup,
357 .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
358 .chipset_flush = agp_i830_chipset_flush,
361 static const struct agp_i810_driver agp_i810_i915_driver = {
362 .chiptype = CHIP_I915,
364 .busdma_addr_mask_sz = 32,
365 .res_spec = agp_i915_res_spec,
366 .check_active = agp_i915_check_active,
367 .set_desc = agp_i810_set_desc,
368 .dump_regs = agp_i915_dump_regs,
369 .get_stolen_size = agp_i915_get_stolen_size,
370 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
371 .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
372 .install_gatt = agp_i830_install_gatt,
373 .deinstall_gatt = agp_i830_deinstall_gatt,
374 .write_gtt = agp_i915_write_gtt,
375 .install_gtt_pte = agp_i915_install_gtt_pte,
376 .read_gtt_pte = agp_i915_read_gtt_pte,
377 .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
378 .set_aperture = agp_i915_set_aperture,
379 .chipset_flush_setup = agp_i915_chipset_flush_setup,
380 .chipset_flush_teardown = agp_i915_chipset_flush_teardown,
381 .chipset_flush = agp_i915_chipset_flush,
384 static const struct agp_i810_driver agp_i810_g965_driver = {
385 .chiptype = CHIP_I965,
387 .busdma_addr_mask_sz = 36,
388 .res_spec = agp_i965_res_spec,
389 .check_active = agp_i915_check_active,
390 .set_desc = agp_i810_set_desc,
391 .dump_regs = agp_i965_dump_regs,
392 .get_stolen_size = agp_i915_get_stolen_size,
393 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
394 .get_gtt_total_entries = agp_i965_get_gtt_total_entries,
395 .install_gatt = agp_i830_install_gatt,
396 .deinstall_gatt = agp_i830_deinstall_gatt,
397 .write_gtt = agp_i965_write_gtt,
398 .install_gtt_pte = agp_i965_install_gtt_pte,
399 .read_gtt_pte = agp_i965_read_gtt_pte,
400 .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
401 .set_aperture = agp_i915_set_aperture,
402 .chipset_flush_setup = agp_i965_chipset_flush_setup,
403 .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
404 .chipset_flush = agp_i915_chipset_flush,
407 static const struct agp_i810_driver agp_i810_g33_driver = {
408 .chiptype = CHIP_G33,
410 .busdma_addr_mask_sz = 36,
411 .res_spec = agp_i915_res_spec,
412 .check_active = agp_i915_check_active,
413 .set_desc = agp_i810_set_desc,
414 .dump_regs = agp_i965_dump_regs,
415 .get_stolen_size = agp_i915_get_stolen_size,
416 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
417 .get_gtt_total_entries = agp_i965_get_gtt_total_entries,
418 .install_gatt = agp_i830_install_gatt,
419 .deinstall_gatt = agp_i830_deinstall_gatt,
420 .write_gtt = agp_i915_write_gtt,
421 .install_gtt_pte = agp_i915_install_gtt_pte,
422 .read_gtt_pte = agp_i915_read_gtt_pte,
423 .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
424 .set_aperture = agp_i915_set_aperture,
425 .chipset_flush_setup = agp_i965_chipset_flush_setup,
426 .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
427 .chipset_flush = agp_i915_chipset_flush,
430 static const struct agp_i810_driver agp_i810_igd_driver = {
431 .chiptype = CHIP_IGD,
433 .busdma_addr_mask_sz = 36,
434 .res_spec = agp_i915_res_spec,
435 .check_active = agp_i915_check_active,
436 .set_desc = agp_i810_set_desc,
437 .dump_regs = agp_i915_dump_regs,
438 .get_stolen_size = agp_i915_get_stolen_size,
439 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
440 .get_gtt_total_entries = agp_i965_get_gtt_total_entries,
441 .install_gatt = agp_i830_install_gatt,
442 .deinstall_gatt = agp_i830_deinstall_gatt,
443 .write_gtt = agp_i915_write_gtt,
444 .install_gtt_pte = agp_i915_install_gtt_pte,
445 .read_gtt_pte = agp_i915_read_gtt_pte,
446 .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
447 .set_aperture = agp_i915_set_aperture,
448 .chipset_flush_setup = agp_i965_chipset_flush_setup,
449 .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
450 .chipset_flush = agp_i915_chipset_flush,
453 static const struct agp_i810_driver agp_i810_g4x_driver = {
454 .chiptype = CHIP_G4X,
456 .busdma_addr_mask_sz = 36,
457 .res_spec = agp_i965_res_spec,
458 .check_active = agp_i915_check_active,
459 .set_desc = agp_i810_set_desc,
460 .dump_regs = agp_i965_dump_regs,
461 .get_stolen_size = agp_i915_get_stolen_size,
462 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
463 .get_gtt_total_entries = agp_gen5_get_gtt_total_entries,
464 .install_gatt = agp_i830_install_gatt,
465 .deinstall_gatt = agp_i830_deinstall_gatt,
466 .write_gtt = agp_g4x_write_gtt,
467 .install_gtt_pte = agp_g4x_install_gtt_pte,
468 .read_gtt_pte = agp_g4x_read_gtt_pte,
469 .read_gtt_pte_paddr = agp_i915_read_gtt_pte_paddr,
470 .set_aperture = agp_i915_set_aperture,
471 .chipset_flush_setup = agp_i965_chipset_flush_setup,
472 .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
473 .chipset_flush = agp_i915_chipset_flush,
476 static const struct agp_i810_driver agp_i810_sb_driver = {
479 .busdma_addr_mask_sz = 40,
480 .res_spec = agp_g4x_res_spec,
481 .check_active = agp_sb_check_active,
482 .set_desc = agp_i810_set_desc,
483 .dump_regs = agp_sb_dump_regs,
484 .get_stolen_size = agp_sb_get_stolen_size,
485 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
486 .get_gtt_total_entries = agp_sb_get_gtt_total_entries,
487 .install_gatt = agp_i830_install_gatt,
488 .deinstall_gatt = agp_i830_deinstall_gatt,
489 .write_gtt = agp_sb_write_gtt,
490 .install_gtt_pte = agp_sb_install_gtt_pte,
491 .read_gtt_pte = agp_g4x_read_gtt_pte,
492 .read_gtt_pte_paddr = agp_sb_read_gtt_pte_paddr,
493 .set_aperture = agp_i915_set_aperture,
494 .chipset_flush_setup = agp_i810_chipset_flush_setup,
495 .chipset_flush_teardown = agp_i810_chipset_flush_teardown,
496 .chipset_flush = agp_i810_chipset_flush,
499 /* For adding new devices, devid is the id of the graphics controller
500 * (pci:0:2:0, for example). The placeholder (usually at pci:0:2:1) for the
501 * second head should never be added. The bridge_offset is the offset to
502 * subtract from devid to get the id of the hostb that the device is on.
504 static const struct agp_i810_match {
507 const struct agp_i810_driver *driver;
508 } agp_i810_matches[] = {
511 .name = "Intel 82810 (i810 GMCH) SVGA controller",
512 .driver = &agp_i810_i810_driver
516 .name = "Intel 82810-DC100 (i810-DC100 GMCH) SVGA controller",
517 .driver = &agp_i810_i810_driver
521 .name = "Intel 82810E (i810E GMCH) SVGA controller",
522 .driver = &agp_i810_i810_driver
526 .name = "Intel 82815 (i815 GMCH) SVGA controller",
527 .driver = &agp_i810_i815_driver
531 .name = "Intel 82830M (830M GMCH) SVGA controller",
532 .driver = &agp_i810_i830_driver
536 .name = "Intel 82845M (845M GMCH) SVGA controller",
537 .driver = &agp_i810_i830_driver
541 .name = "Intel 82852/855GM SVGA controller",
542 .driver = &agp_i810_i855_driver
546 .name = "Intel 82865G (865G GMCH) SVGA controller",
547 .driver = &agp_i810_i865_driver
551 .name = "Intel 82915G (915G GMCH) SVGA controller",
552 .driver = &agp_i810_i915_driver
556 .name = "Intel E7221 SVGA controller",
557 .driver = &agp_i810_i915_driver
561 .name = "Intel 82915GM (915GM GMCH) SVGA controller",
562 .driver = &agp_i810_i915_driver
566 .name = "Intel 82945G (945G GMCH) SVGA controller",
567 .driver = &agp_i810_i915_driver
571 .name = "Intel 82945GM (945GM GMCH) SVGA controller",
572 .driver = &agp_i810_i915_driver
576 .name = "Intel 945GME SVGA controller",
577 .driver = &agp_i810_i915_driver
581 .name = "Intel 946GZ SVGA controller",
582 .driver = &agp_i810_g965_driver
586 .name = "Intel G965 SVGA controller",
587 .driver = &agp_i810_g965_driver
591 .name = "Intel Q965 SVGA controller",
592 .driver = &agp_i810_g965_driver
596 .name = "Intel G965 SVGA controller",
597 .driver = &agp_i810_g965_driver
601 .name = "Intel Q35 SVGA controller",
602 .driver = &agp_i810_g33_driver
606 .name = "Intel G33 SVGA controller",
607 .driver = &agp_i810_g33_driver
611 .name = "Intel Q33 SVGA controller",
612 .driver = &agp_i810_g33_driver
616 .name = "Intel Pineview SVGA controller",
617 .driver = &agp_i810_igd_driver
621 .name = "Intel Pineview (M) SVGA controller",
622 .driver = &agp_i810_igd_driver
626 .name = "Intel GM965 SVGA controller",
627 .driver = &agp_i810_g965_driver
631 .name = "Intel GME965 SVGA controller",
632 .driver = &agp_i810_g965_driver
636 .name = "Intel GM45 SVGA controller",
637 .driver = &agp_i810_g4x_driver
641 .name = "Intel Eaglelake SVGA controller",
642 .driver = &agp_i810_g4x_driver
646 .name = "Intel Q45 SVGA controller",
647 .driver = &agp_i810_g4x_driver
651 .name = "Intel G45 SVGA controller",
652 .driver = &agp_i810_g4x_driver
656 .name = "Intel G41 SVGA controller",
657 .driver = &agp_i810_g4x_driver
661 .name = "Intel Ironlake (D) SVGA controller",
662 .driver = &agp_i810_g4x_driver
666 .name = "Intel Ironlake (M) SVGA controller",
667 .driver = &agp_i810_g4x_driver
671 .name = "SandyBridge desktop GT1 IG",
672 .driver = &agp_i810_sb_driver
676 .name = "SandyBridge desktop GT2 IG",
677 .driver = &agp_i810_sb_driver
681 .name = "SandyBridge desktop GT2+ IG",
682 .driver = &agp_i810_sb_driver
686 .name = "SandyBridge mobile GT1 IG",
687 .driver = &agp_i810_sb_driver
691 .name = "SandyBridge mobile GT2 IG",
692 .driver = &agp_i810_sb_driver
696 .name = "SandyBridge mobile GT2+ IG",
697 .driver = &agp_i810_sb_driver
701 .name = "SandyBridge server IG",
702 .driver = &agp_i810_sb_driver
706 .name = "IvyBridge desktop GT1 IG",
707 .driver = &agp_i810_sb_driver
711 .name = "IvyBridge desktop GT2 IG",
712 .driver = &agp_i810_sb_driver
716 .name = "IvyBridge mobile GT1 IG",
717 .driver = &agp_i810_sb_driver
721 .name = "IvyBridge mobile GT2 IG",
722 .driver = &agp_i810_sb_driver
726 .name = "IvyBridge server GT1 IG",
727 .driver = &agp_i810_sb_driver
731 .name = "IvyBridge server GT2 IG",
732 .driver = &agp_i810_sb_driver
739 static const struct agp_i810_match*
740 agp_i810_match(device_t dev)
744 if (pci_get_class(dev) != PCIC_DISPLAY)
747 devid = pci_get_devid(dev);
748 for (i = 0; agp_i810_matches[i].devid != 0; i++) {
749 if (agp_i810_matches[i].devid == devid)
752 if (agp_i810_matches[i].devid == 0)
755 return (&agp_i810_matches[i]);
759 * Find bridge device.
762 agp_i810_find_bridge(device_t dev)
765 return (pci_find_dbsf(0, 0, 0, 0));
769 agp_i810_identify(driver_t *driver, device_t parent)
772 if (device_find_child(parent, "agp", -1) == NULL &&
773 agp_i810_match(parent))
774 device_add_child(parent, "agp", -1);
778 agp_i810_check_active(device_t bridge_dev)
782 smram = pci_read_config(bridge_dev, AGP_I810_SMRAM, 1);
783 if ((smram & AGP_I810_SMRAM_GMS) == AGP_I810_SMRAM_GMS_DISABLED)
789 agp_i830_check_active(device_t bridge_dev)
793 gcc1 = pci_read_config(bridge_dev, AGP_I830_GCC1, 1);
794 if ((gcc1 & AGP_I830_GCC1_DEV2) == AGP_I830_GCC1_DEV2_DISABLED)
800 agp_i915_check_active(device_t bridge_dev)
804 deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4);
805 if ((deven & AGP_I915_DEVEN_D2F0) == AGP_I915_DEVEN_D2F0_DISABLED)
811 agp_sb_check_active(device_t bridge_dev)
815 deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4);
816 if ((deven & AGP_SB_DEVEN_D2EN) == AGP_SB_DEVEN_D2EN_DISABLED)
822 agp_82852_set_desc(device_t dev, const struct agp_i810_match *match)
825 switch (pci_read_config(dev, AGP_I85X_CAPID, 1)) {
828 "Intel 82855GME (855GME GMCH) SVGA controller");
832 "Intel 82855GM (855GM GMCH) SVGA controller");
836 "Intel 82852GME (852GME GMCH) SVGA controller");
840 "Intel 82852GM (852GM GMCH) SVGA controller");
844 "Intel 8285xM (85xGM GMCH) SVGA controller");
850 agp_i810_set_desc(device_t dev, const struct agp_i810_match *match)
853 device_set_desc(dev, match->name);
857 agp_i810_probe(device_t dev)
860 const struct agp_i810_match *match;
863 if (resource_disabled("agp", device_get_unit(dev)))
865 match = agp_i810_match(dev);
869 bdev = agp_i810_find_bridge(dev);
872 kprintf("I810: can't find bridge device\n");
877 * checking whether internal graphics device has been activated.
879 err = match->driver->check_active(bdev);
882 kprintf("i810: disabled, not probing\n");
886 match->driver->set_desc(dev, match);
887 return (BUS_PROBE_DEFAULT);
891 agp_i810_dump_regs(device_t dev)
893 struct agp_i810_softc *sc = device_get_softc(dev);
895 device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
896 bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
897 device_printf(dev, "AGP_I810_MISCC: 0x%04x\n",
898 pci_read_config(sc->bdev, AGP_I810_MISCC, 2));
902 agp_i830_dump_regs(device_t dev)
904 struct agp_i810_softc *sc = device_get_softc(dev);
906 device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
907 bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
908 device_printf(dev, "AGP_I830_GCC1: 0x%02x\n",
909 pci_read_config(sc->bdev, AGP_I830_GCC1, 1));
913 agp_i855_dump_regs(device_t dev)
915 struct agp_i810_softc *sc = device_get_softc(dev);
917 device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
918 bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
919 device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
920 pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
924 agp_i915_dump_regs(device_t dev)
926 struct agp_i810_softc *sc = device_get_softc(dev);
928 device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
929 bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
930 device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
931 pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
932 device_printf(dev, "AGP_I915_MSAC: 0x%02x\n",
933 pci_read_config(sc->bdev, AGP_I915_MSAC, 1));
937 agp_i965_dump_regs(device_t dev)
939 struct agp_i810_softc *sc = device_get_softc(dev);
941 device_printf(dev, "AGP_I965_PGTBL_CTL2: %08x\n",
942 bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2));
943 device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
944 pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
945 device_printf(dev, "AGP_I965_MSAC: 0x%02x\n",
946 pci_read_config(sc->bdev, AGP_I965_MSAC, 1));
950 agp_sb_dump_regs(device_t dev)
952 struct agp_i810_softc *sc = device_get_softc(dev);
954 device_printf(dev, "AGP_SNB_GFX_MODE: %08x\n",
955 bus_read_4(sc->sc_res[0], AGP_SNB_GFX_MODE));
956 device_printf(dev, "AGP_SNB_GCC1: 0x%04x\n",
957 pci_read_config(sc->bdev, AGP_SNB_GCC1, 2));
961 agp_i810_get_stolen_size(device_t dev)
963 struct agp_i810_softc *sc;
965 sc = device_get_softc(dev);
972 agp_i830_get_stolen_size(device_t dev)
974 struct agp_i810_softc *sc;
977 sc = device_get_softc(dev);
979 gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 1);
980 switch (gcc1 & AGP_I830_GCC1_GMS) {
981 case AGP_I830_GCC1_GMS_STOLEN_512:
982 sc->stolen = (512 - 132) * 1024 / 4096;
983 sc->stolen_size = 512 * 1024;
985 case AGP_I830_GCC1_GMS_STOLEN_1024:
986 sc->stolen = (1024 - 132) * 1024 / 4096;
987 sc->stolen_size = 1024 * 1024;
989 case AGP_I830_GCC1_GMS_STOLEN_8192:
990 sc->stolen = (8192 - 132) * 1024 / 4096;
991 sc->stolen_size = 8192 * 1024;
996 "unknown memory configuration, disabling (GCC1 %x)\n",
1004 agp_i915_get_stolen_size(device_t dev)
1006 struct agp_i810_softc *sc;
1007 unsigned int gcc1, stolen, gtt_size;
1009 sc = device_get_softc(dev);
1012 * Stolen memory is set up at the beginning of the aperture by
1013 * the BIOS, consisting of the GATT followed by 4kb for the
1016 switch (sc->match->driver->chiptype) {
1024 switch (bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL) &
1025 AGP_I810_PGTBL_SIZE_MASK) {
1026 case AGP_I810_PGTBL_SIZE_128KB:
1029 case AGP_I810_PGTBL_SIZE_256KB:
1032 case AGP_I810_PGTBL_SIZE_512KB:
1035 case AGP_I965_PGTBL_SIZE_1MB:
1038 case AGP_I965_PGTBL_SIZE_2MB:
1041 case AGP_I965_PGTBL_SIZE_1_5MB:
1042 gtt_size = 1024 + 512;
1045 device_printf(dev, "Bad PGTBL size\n");
1050 gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 2);
1051 switch (gcc1 & AGP_G33_MGGC_GGMS_MASK) {
1052 case AGP_G33_MGGC_GGMS_SIZE_1M:
1055 case AGP_G33_MGGC_GGMS_SIZE_2M:
1059 device_printf(dev, "Bad PGTBL size\n");
1068 device_printf(dev, "Bad chiptype\n");
1072 /* GCC1 is called MGGC on i915+ */
1073 gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1);
1074 switch (gcc1 & AGP_I855_GCC1_GMS) {
1075 case AGP_I855_GCC1_GMS_STOLEN_1M:
1078 case AGP_I855_GCC1_GMS_STOLEN_4M:
1081 case AGP_I855_GCC1_GMS_STOLEN_8M:
1084 case AGP_I855_GCC1_GMS_STOLEN_16M:
1087 case AGP_I855_GCC1_GMS_STOLEN_32M:
1090 case AGP_I915_GCC1_GMS_STOLEN_48M:
1091 stolen = sc->match->driver->gen > 2 ? 48 * 1024 : 0;
1093 case AGP_I915_GCC1_GMS_STOLEN_64M:
1094 stolen = sc->match->driver->gen > 2 ? 64 * 1024 : 0;
1096 case AGP_G33_GCC1_GMS_STOLEN_128M:
1097 stolen = sc->match->driver->gen > 2 ? 128 * 1024 : 0;
1099 case AGP_G33_GCC1_GMS_STOLEN_256M:
1100 stolen = sc->match->driver->gen > 2 ? 256 * 1024 : 0;
1102 case AGP_G4X_GCC1_GMS_STOLEN_96M:
1103 if (sc->match->driver->chiptype == CHIP_I965 ||
1104 sc->match->driver->chiptype == CHIP_G4X)
1109 case AGP_G4X_GCC1_GMS_STOLEN_160M:
1110 if (sc->match->driver->chiptype == CHIP_I965 ||
1111 sc->match->driver->chiptype == CHIP_G4X)
1112 stolen = 160 * 1024;
1116 case AGP_G4X_GCC1_GMS_STOLEN_224M:
1117 if (sc->match->driver->chiptype == CHIP_I965 ||
1118 sc->match->driver->chiptype == CHIP_G4X)
1119 stolen = 224 * 1024;
1123 case AGP_G4X_GCC1_GMS_STOLEN_352M:
1124 if (sc->match->driver->chiptype == CHIP_I965 ||
1125 sc->match->driver->chiptype == CHIP_G4X)
1126 stolen = 352 * 1024;
1132 "unknown memory configuration, disabling (GCC1 %x)\n",
1138 sc->stolen_size = stolen * 1024;
1139 sc->stolen = (stolen - gtt_size) * 1024 / 4096;
1145 agp_sb_get_stolen_size(device_t dev)
1147 struct agp_i810_softc *sc;
1150 sc = device_get_softc(dev);
1151 gmch_ctl = pci_read_config(sc->bdev, AGP_SNB_GCC1, 2);
1152 switch (gmch_ctl & AGP_SNB_GMCH_GMS_STOLEN_MASK) {
1153 case AGP_SNB_GMCH_GMS_STOLEN_32M:
1154 sc->stolen_size = 32 * 1024 * 1024;
1156 case AGP_SNB_GMCH_GMS_STOLEN_64M:
1157 sc->stolen_size = 64 * 1024 * 1024;
1159 case AGP_SNB_GMCH_GMS_STOLEN_96M:
1160 sc->stolen_size = 96 * 1024 * 1024;
1162 case AGP_SNB_GMCH_GMS_STOLEN_128M:
1163 sc->stolen_size = 128 * 1024 * 1024;
1165 case AGP_SNB_GMCH_GMS_STOLEN_160M:
1166 sc->stolen_size = 160 * 1024 * 1024;
1168 case AGP_SNB_GMCH_GMS_STOLEN_192M:
1169 sc->stolen_size = 192 * 1024 * 1024;
1171 case AGP_SNB_GMCH_GMS_STOLEN_224M:
1172 sc->stolen_size = 224 * 1024 * 1024;
1174 case AGP_SNB_GMCH_GMS_STOLEN_256M:
1175 sc->stolen_size = 256 * 1024 * 1024;
1177 case AGP_SNB_GMCH_GMS_STOLEN_288M:
1178 sc->stolen_size = 288 * 1024 * 1024;
1180 case AGP_SNB_GMCH_GMS_STOLEN_320M:
1181 sc->stolen_size = 320 * 1024 * 1024;
1183 case AGP_SNB_GMCH_GMS_STOLEN_352M:
1184 sc->stolen_size = 352 * 1024 * 1024;
1186 case AGP_SNB_GMCH_GMS_STOLEN_384M:
1187 sc->stolen_size = 384 * 1024 * 1024;
1189 case AGP_SNB_GMCH_GMS_STOLEN_416M:
1190 sc->stolen_size = 416 * 1024 * 1024;
1192 case AGP_SNB_GMCH_GMS_STOLEN_448M:
1193 sc->stolen_size = 448 * 1024 * 1024;
1195 case AGP_SNB_GMCH_GMS_STOLEN_480M:
1196 sc->stolen_size = 480 * 1024 * 1024;
1198 case AGP_SNB_GMCH_GMS_STOLEN_512M:
1199 sc->stolen_size = 512 * 1024 * 1024;
1202 sc->stolen = (sc->stolen_size - 4) / 4096;
1207 agp_i810_get_gtt_mappable_entries(device_t dev)
1209 struct agp_i810_softc *sc;
1213 sc = device_get_softc(dev);
1214 miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2);
1215 if ((miscc & AGP_I810_MISCC_WINSIZE) == AGP_I810_MISCC_WINSIZE_32)
1219 sc->gtt_mappable_entries = (ap * 1024 * 1024) >> AGP_PAGE_SHIFT;
1224 agp_i830_get_gtt_mappable_entries(device_t dev)
1226 struct agp_i810_softc *sc;
1230 sc = device_get_softc(dev);
1231 gmch_ctl = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
1232 if ((gmch_ctl & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64)
1236 sc->gtt_mappable_entries = (ap * 1024 * 1024) >> AGP_PAGE_SHIFT;
1241 agp_i915_get_gtt_mappable_entries(device_t dev)
1243 struct agp_i810_softc *sc;
1246 sc = device_get_softc(dev);
1247 ap = AGP_GET_APERTURE(dev);
1248 sc->gtt_mappable_entries = ap >> AGP_PAGE_SHIFT;
1253 agp_i810_get_gtt_total_entries(device_t dev)
1255 struct agp_i810_softc *sc;
1257 sc = device_get_softc(dev);
1258 sc->gtt_total_entries = sc->gtt_mappable_entries;
1263 agp_i965_get_gtt_total_entries(device_t dev)
1265 struct agp_i810_softc *sc;
1266 uint32_t pgetbl_ctl;
1269 sc = device_get_softc(dev);
1271 pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
1272 switch (pgetbl_ctl & AGP_I810_PGTBL_SIZE_MASK) {
1273 case AGP_I810_PGTBL_SIZE_128KB:
1274 sc->gtt_total_entries = 128 * 1024 / 4;
1276 case AGP_I810_PGTBL_SIZE_256KB:
1277 sc->gtt_total_entries = 256 * 1024 / 4;
1279 case AGP_I810_PGTBL_SIZE_512KB:
1280 sc->gtt_total_entries = 512 * 1024 / 4;
1282 /* GTT pagetable sizes bigger than 512KB are not possible on G33! */
1283 case AGP_I810_PGTBL_SIZE_1MB:
1284 sc->gtt_total_entries = 1024 * 1024 / 4;
1286 case AGP_I810_PGTBL_SIZE_2MB:
1287 sc->gtt_total_entries = 2 * 1024 * 1024 / 4;
1289 case AGP_I810_PGTBL_SIZE_1_5MB:
1290 sc->gtt_total_entries = (1024 + 512) * 1024 / 4;
1293 device_printf(dev, "Unknown page table size\n");
1300 agp_gen5_adjust_pgtbl_size(device_t dev, uint32_t sz)
1302 struct agp_i810_softc *sc;
1303 uint32_t pgetbl_ctl, pgetbl_ctl2;
1305 sc = device_get_softc(dev);
1307 /* Disable per-process page table. */
1308 pgetbl_ctl2 = bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2);
1309 pgetbl_ctl2 &= ~AGP_I810_PGTBL_ENABLED;
1310 bus_write_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2, pgetbl_ctl2);
1312 /* Write the new ggtt size. */
1313 pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
1314 pgetbl_ctl &= ~AGP_I810_PGTBL_SIZE_MASK;
1316 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgetbl_ctl);
1320 agp_gen5_get_gtt_total_entries(device_t dev)
1322 struct agp_i810_softc *sc;
1325 sc = device_get_softc(dev);
1327 gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
1328 switch (gcc1 & AGP_G4x_GCC1_SIZE_MASK) {
1329 case AGP_G4x_GCC1_SIZE_1M:
1330 case AGP_G4x_GCC1_SIZE_VT_1M:
1331 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1MB);
1333 case AGP_G4x_GCC1_SIZE_VT_1_5M:
1334 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1_5MB);
1336 case AGP_G4x_GCC1_SIZE_2M:
1337 case AGP_G4x_GCC1_SIZE_VT_2M:
1338 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_2MB);
1341 device_printf(dev, "Unknown page table size\n");
1345 return (agp_i965_get_gtt_total_entries(dev));
1349 agp_sb_get_gtt_total_entries(device_t dev)
1351 struct agp_i810_softc *sc;
1354 sc = device_get_softc(dev);
1356 gcc1 = pci_read_config(sc->bdev, AGP_SNB_GCC1, 2);
1357 switch (gcc1 & AGP_SNB_GTT_SIZE_MASK) {
1359 case AGP_SNB_GTT_SIZE_0M:
1360 kprintf("Bad GTT size mask: 0x%04x\n", gcc1);
1362 case AGP_SNB_GTT_SIZE_1M:
1363 sc->gtt_total_entries = 1024 * 1024 / 4;
1365 case AGP_SNB_GTT_SIZE_2M:
1366 sc->gtt_total_entries = 2 * 1024 * 1024 / 4;
1373 agp_i810_install_gatt(device_t dev)
1375 struct agp_i810_softc *sc;
1377 sc = device_get_softc(dev);
1379 /* Some i810s have on-chip memory called dcache. */
1380 if ((bus_read_1(sc->sc_res[0], AGP_I810_DRT) & AGP_I810_DRT_POPULATED)
1382 sc->dcache_size = 4 * 1024 * 1024;
1384 sc->dcache_size = 0;
1386 /* According to the specs the gatt on the i810 must be 64k. */
1387 sc->gatt->ag_virtual = contigmalloc(64 * 1024, M_AGP, 0, 0, ~0,
1389 if (sc->gatt->ag_virtual == NULL) {
1391 device_printf(dev, "contiguous allocation failed\n");
1395 bzero(sc->gatt->ag_virtual, sc->gatt->ag_entries * sizeof(u_int32_t));
1396 sc->gatt->ag_physical = vtophys((vm_offset_t)sc->gatt->ag_virtual);
1398 /* Install the GATT. */
1399 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL,
1400 sc->gatt->ag_physical | 1);
1405 agp_i830_install_gatt(device_t dev)
1407 struct agp_i810_softc *sc;
1410 sc = device_get_softc(dev);
1413 * The i830 automatically initializes the 128k gatt on boot.
1414 * GATT address is already in there, make sure it's enabled.
1416 pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
1418 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
1420 sc->gatt->ag_physical = pgtblctl & ~1;
1425 agp_i810_attach(device_t dev)
1427 struct agp_i810_softc *sc;
1430 sc = device_get_softc(dev);
1431 sc->bdev = agp_i810_find_bridge(dev);
1432 if (sc->bdev == NULL)
1435 sc->match = agp_i810_match(dev);
1437 agp_set_aperture_resource(dev, sc->match->driver->gen <= 2 ?
1438 AGP_APBASE : AGP_I915_GMADR);
1439 error = agp_generic_attach(dev);
1443 if (ptoa((vm_paddr_t)Maxmem) >
1444 (1ULL << sc->match->driver->busdma_addr_mask_sz) - 1) {
1445 device_printf(dev, "agp_i810 does not support physical "
1446 "memory above %ju.\n", (uintmax_t)(1ULL <<
1447 sc->match->driver->busdma_addr_mask_sz) - 1);
1451 if (bus_alloc_resources(dev, sc->match->driver->res_spec, sc->sc_res)) {
1452 agp_generic_detach(dev);
1456 sc->initial_aperture = AGP_GET_APERTURE(dev);
1457 sc->gatt = kmalloc(sizeof(struct agp_gatt), M_AGP, M_WAITOK);
1458 sc->gatt->ag_entries = AGP_GET_APERTURE(dev) >> AGP_PAGE_SHIFT;
1460 if ((error = sc->match->driver->get_stolen_size(dev)) != 0 ||
1461 (error = sc->match->driver->install_gatt(dev)) != 0 ||
1462 (error = sc->match->driver->get_gtt_mappable_entries(dev)) != 0 ||
1463 (error = sc->match->driver->get_gtt_total_entries(dev)) != 0 ||
1464 (error = sc->match->driver->chipset_flush_setup(dev)) != 0) {
1465 bus_release_resources(dev, sc->match->driver->res_spec,
1467 kfree(sc->gatt, M_AGP);
1468 agp_generic_detach(dev);
1473 device_printf(dev, "aperture size is %dM",
1474 sc->initial_aperture / 1024 / 1024);
1476 kprintf(", detected %dk stolen memory\n", sc->stolen * 4);
1480 sc->match->driver->dump_regs(dev);
1481 device_printf(dev, "Mappable GTT entries: %d\n",
1482 sc->gtt_mappable_entries);
1483 device_printf(dev, "Total GTT entries: %d\n",
1484 sc->gtt_total_entries);
1490 agp_i810_deinstall_gatt(device_t dev)
1492 struct agp_i810_softc *sc;
1494 sc = device_get_softc(dev);
1495 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, 0);
1496 contigfree(sc->gatt->ag_virtual, 64 * 1024, M_AGP);
1500 agp_i830_deinstall_gatt(device_t dev)
1502 struct agp_i810_softc *sc;
1503 unsigned int pgtblctl;
1505 sc = device_get_softc(dev);
1506 pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
1508 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
1512 agp_i810_detach(device_t dev)
1514 struct agp_i810_softc *sc;
1516 sc = device_get_softc(dev);
1519 /* Clear the GATT base. */
1520 sc->match->driver->deinstall_gatt(dev);
1522 sc->match->driver->chipset_flush_teardown(dev);
1524 /* Put the aperture back the way it started. */
1525 AGP_SET_APERTURE(dev, sc->initial_aperture);
1527 kfree(sc->gatt, M_AGP);
1528 bus_release_resources(dev, sc->match->driver->res_spec, sc->sc_res);
1535 agp_i810_resume(device_t dev)
1537 struct agp_i810_softc *sc;
1538 sc = device_get_softc(dev);
1540 AGP_SET_APERTURE(dev, sc->initial_aperture);
1542 /* Install the GATT. */
1543 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL,
1544 sc->gatt->ag_physical | 1);
1546 return (bus_generic_resume(dev));
1550 * Sets the PCI resource size of the aperture on i830-class and below chipsets,
1551 * while returning failure on later chipsets when an actual change is
1554 * This whole function is likely bogus, as the kernel would probably need to
1555 * reconfigure the placement of the AGP aperture if a larger size is requested,
1556 * which doesn't happen currently.
1559 agp_i810_set_aperture(device_t dev, u_int32_t aperture)
1561 struct agp_i810_softc *sc;
1564 sc = device_get_softc(dev);
1566 * Double check for sanity.
1568 if (aperture != 32 * 1024 * 1024 && aperture != 64 * 1024 * 1024) {
1569 device_printf(dev, "bad aperture size %d\n", aperture);
1573 miscc = pci_read_config(sc->bdev, AGP_I810_MISCC, 2);
1574 miscc &= ~AGP_I810_MISCC_WINSIZE;
1575 if (aperture == 32 * 1024 * 1024)
1576 miscc |= AGP_I810_MISCC_WINSIZE_32;
1578 miscc |= AGP_I810_MISCC_WINSIZE_64;
1580 pci_write_config(sc->bdev, AGP_I810_MISCC, miscc, 2);
1585 agp_i830_set_aperture(device_t dev, u_int32_t aperture)
1587 struct agp_i810_softc *sc;
1590 sc = device_get_softc(dev);
1592 if (aperture != 64 * 1024 * 1024 &&
1593 aperture != 128 * 1024 * 1024) {
1594 device_printf(dev, "bad aperture size %d\n", aperture);
1597 gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
1598 gcc1 &= ~AGP_I830_GCC1_GMASIZE;
1599 if (aperture == 64 * 1024 * 1024)
1600 gcc1 |= AGP_I830_GCC1_GMASIZE_64;
1602 gcc1 |= AGP_I830_GCC1_GMASIZE_128;
1604 pci_write_config(sc->bdev, AGP_I830_GCC1, gcc1, 2);
1609 agp_i915_set_aperture(device_t dev, u_int32_t aperture)
1612 return (agp_generic_set_aperture(dev, aperture));
1616 agp_i810_method_set_aperture(device_t dev, u_int32_t aperture)
1618 struct agp_i810_softc *sc;
1620 sc = device_get_softc(dev);
1621 return (sc->match->driver->set_aperture(dev, aperture));
1625 * Writes a GTT entry mapping the page at the given offset from the
1626 * beginning of the aperture to the given physical address. Setup the
1627 * caching mode according to flags.
1629 * For gen 1, 2 and 3, GTT start is located at AGP_I810_GTT offset
1630 * from corresponding BAR start. For gen 4, offset is 512KB +
1631 * AGP_I810_GTT, for gen 5 and 6 it is 2MB + AGP_I810_GTT.
1633 * Also, the bits of the physical page address above 4GB needs to be
1634 * placed into bits 40-32 of PTE.
1637 agp_i810_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1642 pte = (u_int32_t)physical | I810_PTE_VALID;
1643 if (flags == AGP_DCACHE_MEMORY)
1644 pte |= I810_PTE_LOCAL;
1645 else if (flags == AGP_USER_CACHED_MEMORY)
1646 pte |= I830_PTE_SYSTEM_CACHED;
1647 agp_i810_write_gtt(dev, index, pte);
1651 agp_i810_write_gtt(device_t dev, u_int index, uint32_t pte)
1653 struct agp_i810_softc *sc;
1655 sc = device_get_softc(dev);
1656 bus_write_4(sc->sc_res[0], AGP_I810_GTT + index * 4, pte);
1660 agp_i830_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1665 pte = (u_int32_t)physical | I810_PTE_VALID;
1666 if (flags == AGP_USER_CACHED_MEMORY)
1667 pte |= I830_PTE_SYSTEM_CACHED;
1668 agp_i810_write_gtt(dev, index, pte);
1672 agp_i915_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1677 pte = (u_int32_t)physical | I810_PTE_VALID;
1678 if (flags == AGP_USER_CACHED_MEMORY)
1679 pte |= I830_PTE_SYSTEM_CACHED;
1680 pte |= (physical & 0x0000000f00000000ull) >> 28;
1681 agp_i915_write_gtt(dev, index, pte);
1685 agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte)
1687 struct agp_i810_softc *sc;
1689 sc = device_get_softc(dev);
1690 bus_write_4(sc->sc_res[1], index * 4, pte);
1694 agp_i965_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1699 pte = (u_int32_t)physical | I810_PTE_VALID;
1700 if (flags == AGP_USER_CACHED_MEMORY)
1701 pte |= I830_PTE_SYSTEM_CACHED;
1702 pte |= (physical & 0x0000000f00000000ull) >> 28;
1703 agp_i965_write_gtt(dev, index, pte);
1707 agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte)
1709 struct agp_i810_softc *sc;
1711 sc = device_get_softc(dev);
1712 bus_write_4(sc->sc_res[0], index * 4 + (512 * 1024), pte);
1716 agp_g4x_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1721 pte = (u_int32_t)physical | I810_PTE_VALID;
1722 if (flags == AGP_USER_CACHED_MEMORY)
1723 pte |= I830_PTE_SYSTEM_CACHED;
1724 pte |= (physical & 0x0000000f00000000ull) >> 28;
1725 agp_g4x_write_gtt(dev, index, pte);
1729 agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte)
1731 struct agp_i810_softc *sc;
1733 sc = device_get_softc(dev);
1734 bus_write_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024), pte);
1738 agp_sb_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1741 int type_mask, gfdt;
1744 pte = (u_int32_t)physical | I810_PTE_VALID;
1745 type_mask = flags & ~AGP_USER_CACHED_MEMORY_GFDT;
1746 gfdt = (flags & AGP_USER_CACHED_MEMORY_GFDT) != 0 ? GEN6_PTE_GFDT : 0;
1748 if (type_mask == AGP_USER_MEMORY)
1749 pte |= GEN6_PTE_UNCACHED;
1750 else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC)
1751 pte |= GEN6_PTE_LLC_MLC | gfdt;
1753 pte |= GEN6_PTE_LLC | gfdt;
1755 pte |= (physical & 0x000000ff00000000ull) >> 28;
1756 agp_sb_write_gtt(dev, index, pte);
1760 agp_sb_write_gtt(device_t dev, u_int index, uint32_t pte)
1762 struct agp_i810_softc *sc;
1764 sc = device_get_softc(dev);
1765 bus_write_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024), pte);
1769 agp_i810_bind_page(device_t dev, vm_offset_t offset, vm_offset_t physical)
1771 struct agp_i810_softc *sc = device_get_softc(dev);
1774 if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) {
1775 device_printf(dev, "failed: offset is 0x%08jx, "
1776 "shift is %d, entries is %d\n", (intmax_t)offset,
1777 AGP_PAGE_SHIFT, sc->gatt->ag_entries);
1780 index = offset >> AGP_PAGE_SHIFT;
1781 if (sc->stolen != 0 && index < sc->stolen) {
1782 device_printf(dev, "trying to bind into stolen memory\n");
1785 sc->match->driver->install_gtt_pte(dev, index, physical, 0);
1790 agp_i810_unbind_page(device_t dev, vm_offset_t offset)
1792 struct agp_i810_softc *sc;
1795 sc = device_get_softc(dev);
1796 if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
1798 index = offset >> AGP_PAGE_SHIFT;
1799 if (sc->stolen != 0 && index < sc->stolen) {
1800 device_printf(dev, "trying to unbind from stolen memory\n");
1803 sc->match->driver->install_gtt_pte(dev, index, 0, 0);
1808 agp_i810_read_gtt_pte(device_t dev, u_int index)
1810 struct agp_i810_softc *sc;
1813 sc = device_get_softc(dev);
1814 pte = bus_read_4(sc->sc_res[0], AGP_I810_GTT + index * 4);
1819 agp_i915_read_gtt_pte(device_t dev, u_int index)
1821 struct agp_i810_softc *sc;
1824 sc = device_get_softc(dev);
1825 pte = bus_read_4(sc->sc_res[1], index * 4);
1830 agp_i965_read_gtt_pte(device_t dev, u_int index)
1832 struct agp_i810_softc *sc;
1835 sc = device_get_softc(dev);
1836 pte = bus_read_4(sc->sc_res[0], index * 4 + (512 * 1024));
1841 agp_g4x_read_gtt_pte(device_t dev, u_int index)
1843 struct agp_i810_softc *sc;
1846 sc = device_get_softc(dev);
1847 pte = bus_read_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024));
1852 agp_i810_read_gtt_pte_paddr(device_t dev, u_int index)
1854 struct agp_i810_softc *sc;
1858 sc = device_get_softc(dev);
1859 pte = sc->match->driver->read_gtt_pte(dev, index);
1860 res = pte & ~PAGE_MASK;
1865 agp_i915_read_gtt_pte_paddr(device_t dev, u_int index)
1867 struct agp_i810_softc *sc;
1871 sc = device_get_softc(dev);
1872 pte = sc->match->driver->read_gtt_pte(dev, index);
1873 res = (pte & ~PAGE_MASK) | ((pte & 0xf0) << 28);
1878 agp_sb_read_gtt_pte_paddr(device_t dev, u_int index)
1880 struct agp_i810_softc *sc;
1884 sc = device_get_softc(dev);
1885 pte = sc->match->driver->read_gtt_pte(dev, index);
1886 res = (pte & ~PAGE_MASK) | ((pte & 0xff0) << 28);
1891 * Writing via memory mapped registers already flushes all TLBs.
1894 agp_i810_flush_tlb(device_t dev)
1899 agp_i810_enable(device_t dev, u_int32_t mode)
1905 static struct agp_memory *
1906 agp_i810_alloc_memory(device_t dev, int type, vm_size_t size)
1908 struct agp_i810_softc *sc;
1909 struct agp_memory *mem;
1912 sc = device_get_softc(dev);
1914 if ((size & (AGP_PAGE_SIZE - 1)) != 0 ||
1915 sc->agp.as_allocated + size > sc->agp.as_maxmem)
1920 * Mapping local DRAM into GATT.
1922 if (sc->match->driver->chiptype != CHIP_I810)
1924 if (size != sc->dcache_size)
1926 } else if (type == 2) {
1928 * Type 2 is the contiguous physical memory type, that hands
1929 * back a physical address. This is used for cursors on i810.
1930 * Hand back as many single pages with physical as the user
1931 * wants, but only allow one larger allocation (ARGB cursor)
1934 if (size != AGP_PAGE_SIZE) {
1935 if (sc->argb_cursor != NULL)
1938 /* Allocate memory for ARGB cursor, if we can. */
1939 sc->argb_cursor = contigmalloc(size, M_AGP,
1940 0, 0, ~0, PAGE_SIZE, 0);
1941 if (sc->argb_cursor == NULL)
1946 mem = kmalloc(sizeof *mem, M_AGP, M_INTWAIT);
1947 mem->am_id = sc->agp.as_nextid++;
1948 mem->am_size = size;
1949 mem->am_type = type;
1950 if (type != 1 && (type != 2 || size == AGP_PAGE_SIZE))
1951 mem->am_obj = vm_object_allocate(OBJT_DEFAULT,
1952 atop(round_page(size)));
1957 if (size == AGP_PAGE_SIZE) {
1959 * Allocate and wire down the page now so that we can
1960 * get its physical address.
1962 VM_OBJECT_LOCK(mem->am_obj);
1963 m = vm_page_grab(mem->am_obj, 0, VM_ALLOC_NORMAL |
1967 VM_OBJECT_UNLOCK(mem->am_obj);
1968 mem->am_physical = VM_PAGE_TO_PHYS(m);
1971 /* Our allocation is already nicely wired down for us.
1972 * Just grab the physical address.
1974 mem->am_physical = vtophys(sc->argb_cursor);
1977 mem->am_physical = 0;
1980 mem->am_is_bound = 0;
1981 TAILQ_INSERT_TAIL(&sc->agp.as_memory, mem, am_link);
1982 sc->agp.as_allocated += size;
1988 agp_i810_free_memory(device_t dev, struct agp_memory *mem)
1990 struct agp_i810_softc *sc;
1992 if (mem->am_is_bound)
1995 sc = device_get_softc(dev);
1997 if (mem->am_type == 2) {
1998 if (mem->am_size == AGP_PAGE_SIZE) {
2000 * Unwire the page which we wired in alloc_memory.
2004 vm_object_hold(mem->am_obj);
2005 m = vm_page_lookup_busy_wait(mem->am_obj, 0,
2007 vm_object_drop(mem->am_obj);
2008 vm_page_unwire(m, 0);
2011 contigfree(sc->argb_cursor, mem->am_size, M_AGP);
2012 sc->argb_cursor = NULL;
2016 sc->agp.as_allocated -= mem->am_size;
2017 TAILQ_REMOVE(&sc->agp.as_memory, mem, am_link);
2019 vm_object_deallocate(mem->am_obj);
2025 agp_i810_bind_memory(device_t dev, struct agp_memory *mem, vm_offset_t offset)
2027 struct agp_i810_softc *sc;
2030 /* Do some sanity checks first. */
2031 if ((offset & (AGP_PAGE_SIZE - 1)) != 0 ||
2032 offset + mem->am_size > AGP_GET_APERTURE(dev)) {
2033 device_printf(dev, "binding memory at bad offset %#x\n",
2038 sc = device_get_softc(dev);
2039 if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
2040 lockmgr(&sc->agp.as_lock, LK_EXCLUSIVE);
2041 if (mem->am_is_bound) {
2042 lockmgr(&sc->agp.as_lock, LK_RELEASE);
2045 /* The memory's already wired down, just stick it in the GTT. */
2046 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
2047 sc->match->driver->install_gtt_pte(dev, (offset + i) >>
2048 AGP_PAGE_SHIFT, mem->am_physical + i, 0);
2051 mem->am_offset = offset;
2052 mem->am_is_bound = 1;
2053 lockmgr(&sc->agp.as_lock, LK_RELEASE);
2057 if (mem->am_type != 1)
2058 return (agp_generic_bind_memory(dev, mem, offset));
2061 * Mapping local DRAM into GATT.
2063 if (sc->match->driver->chiptype != CHIP_I810)
2065 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
2066 bus_write_4(sc->sc_res[0],
2067 AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, i | 3);
2073 agp_i810_unbind_memory(device_t dev, struct agp_memory *mem)
2075 struct agp_i810_softc *sc;
2078 sc = device_get_softc(dev);
2080 if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
2081 lockmgr(&sc->agp.as_lock, LK_EXCLUSIVE);
2082 if (!mem->am_is_bound) {
2083 lockmgr(&sc->agp.as_lock, LK_RELEASE);
2087 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
2088 sc->match->driver->install_gtt_pte(dev,
2089 (mem->am_offset + i) >> AGP_PAGE_SHIFT, 0, 0);
2092 mem->am_is_bound = 0;
2093 lockmgr(&sc->agp.as_lock, LK_RELEASE);
2097 if (mem->am_type != 1)
2098 return (agp_generic_unbind_memory(dev, mem));
2100 if (sc->match->driver->chiptype != CHIP_I810)
2102 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
2103 sc->match->driver->install_gtt_pte(dev, i >> AGP_PAGE_SHIFT,
2109 static device_method_t agp_i810_methods[] = {
2110 /* Device interface */
2111 DEVMETHOD(device_identify, agp_i810_identify),
2112 DEVMETHOD(device_probe, agp_i810_probe),
2113 DEVMETHOD(device_attach, agp_i810_attach),
2114 DEVMETHOD(device_detach, agp_i810_detach),
2115 DEVMETHOD(device_suspend, bus_generic_suspend),
2116 DEVMETHOD(device_resume, agp_i810_resume),
2119 DEVMETHOD(agp_get_aperture, agp_generic_get_aperture),
2120 DEVMETHOD(agp_set_aperture, agp_i810_method_set_aperture),
2121 DEVMETHOD(agp_bind_page, agp_i810_bind_page),
2122 DEVMETHOD(agp_unbind_page, agp_i810_unbind_page),
2123 DEVMETHOD(agp_flush_tlb, agp_i810_flush_tlb),
2124 DEVMETHOD(agp_enable, agp_i810_enable),
2125 DEVMETHOD(agp_alloc_memory, agp_i810_alloc_memory),
2126 DEVMETHOD(agp_free_memory, agp_i810_free_memory),
2127 DEVMETHOD(agp_bind_memory, agp_i810_bind_memory),
2128 DEVMETHOD(agp_unbind_memory, agp_i810_unbind_memory),
2129 DEVMETHOD(agp_chipset_flush, agp_intel_gtt_chipset_flush),
2134 static driver_t agp_i810_driver = {
2137 sizeof(struct agp_i810_softc),
2140 static devclass_t agp_devclass;
2142 DRIVER_MODULE(agp_i810, vgapci, agp_i810_driver, agp_devclass, NULL, NULL);
2143 MODULE_DEPEND(agp_i810, agp, 1, 1, 1);
2144 MODULE_DEPEND(agp_i810, pci, 1, 1, 1);
2146 extern vm_page_t bogus_page;
2149 agp_intel_gtt_clear_range(device_t dev, u_int first_entry, u_int num_entries)
2151 struct agp_i810_softc *sc;
2154 sc = device_get_softc(dev);
2155 for (i = 0; i < num_entries; i++)
2156 sc->match->driver->install_gtt_pte(dev, first_entry + i,
2157 VM_PAGE_TO_PHYS(bogus_page), 0);
2158 sc->match->driver->read_gtt_pte(dev, first_entry + num_entries - 1);
2162 agp_intel_gtt_insert_pages(device_t dev, u_int first_entry, u_int num_entries,
2163 vm_page_t *pages, u_int flags)
2165 struct agp_i810_softc *sc;
2168 sc = device_get_softc(dev);
2169 for (i = 0; i < num_entries; i++) {
2170 KKASSERT(pages[i]->valid == VM_PAGE_BITS_ALL);
2171 KKASSERT(pages[i]->wire_count > 0);
2172 sc->match->driver->install_gtt_pte(dev, first_entry + i,
2173 VM_PAGE_TO_PHYS(pages[i]), flags);
2175 sc->match->driver->read_gtt_pte(dev, first_entry + num_entries - 1);
2179 agp_intel_gtt_get(device_t dev)
2181 struct agp_i810_softc *sc;
2182 struct intel_gtt res;
2184 sc = device_get_softc(dev);
2185 res.stolen_size = sc->stolen_size;
2186 res.gtt_total_entries = sc->gtt_total_entries;
2187 res.gtt_mappable_entries = sc->gtt_mappable_entries;
2188 res.do_idle_maps = 0;
2189 res.scratch_page_dma = VM_PAGE_TO_PHYS(bogus_page);
2194 agp_i810_chipset_flush_setup(device_t dev)
2201 agp_i810_chipset_flush_teardown(device_t dev)
2204 /* Nothing to do. */
2208 agp_i810_chipset_flush(device_t dev)
2211 /* Nothing to do. */
2215 agp_i830_chipset_flush(device_t dev)
2217 struct agp_i810_softc *sc;
2221 sc = device_get_softc(dev);
2222 cpu_wbinvd_on_all_cpus();
2223 hic = bus_read_4(sc->sc_res[0], AGP_I830_HIC);
2224 bus_write_4(sc->sc_res[0], AGP_I830_HIC, hic | (1 << 31));
2225 for (i = 0; i < 20000 /* 1 sec */; i++) {
2226 hic = bus_read_4(sc->sc_res[0], AGP_I830_HIC);
2227 if ((hic & (1 << 31)) != 0)
2234 agp_i915_chipset_flush_alloc_page(device_t dev, uint64_t start, uint64_t end)
2236 struct agp_i810_softc *sc;
2239 sc = device_get_softc(dev);
2240 vga = device_get_parent(dev);
2241 sc->sc_flush_page_rid = 100;
2242 sc->sc_flush_page_res = BUS_ALLOC_RESOURCE(device_get_parent(vga), dev,
2243 SYS_RES_MEMORY, &sc->sc_flush_page_rid, start, end, PAGE_SIZE,
2245 if (sc->sc_flush_page_res == NULL) {
2246 device_printf(dev, "Failed to allocate flush page at 0x%jx\n",
2250 sc->sc_flush_page_vaddr = rman_get_virtual(sc->sc_flush_page_res);
2252 device_printf(dev, "Allocated flush page phys 0x%jx virt %p\n",
2253 (uintmax_t)rman_get_start(sc->sc_flush_page_res),
2254 sc->sc_flush_page_vaddr);
2260 agp_i915_chipset_flush_free_page(device_t dev)
2262 struct agp_i810_softc *sc;
2265 sc = device_get_softc(dev);
2266 vga = device_get_parent(dev);
2267 if (sc->sc_flush_page_res == NULL)
2269 BUS_DEACTIVATE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY,
2270 sc->sc_flush_page_rid, sc->sc_flush_page_res);
2271 BUS_RELEASE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY,
2272 sc->sc_flush_page_rid, sc->sc_flush_page_res);
2276 agp_i915_chipset_flush_setup(device_t dev)
2278 struct agp_i810_softc *sc;
2282 sc = device_get_softc(dev);
2283 temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4);
2284 if ((temp & 1) != 0) {
2288 "Found already configured flush page at 0x%jx\n",
2290 sc->sc_bios_allocated_flush_page = 1;
2292 * In the case BIOS initialized the flush pointer (?)
2293 * register, expect that BIOS also set up the resource
2296 error = agp_i915_chipset_flush_alloc_page(dev, temp,
2297 temp + PAGE_SIZE - 1);
2301 sc->sc_bios_allocated_flush_page = 0;
2302 error = agp_i915_chipset_flush_alloc_page(dev, 0, 0xffffffff);
2305 temp = rman_get_start(sc->sc_flush_page_res);
2306 pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp | 1, 4);
2312 agp_i915_chipset_flush_teardown(device_t dev)
2314 struct agp_i810_softc *sc;
2317 sc = device_get_softc(dev);
2318 if (sc->sc_flush_page_res == NULL)
2320 if (!sc->sc_bios_allocated_flush_page) {
2321 temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4);
2323 pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp, 4);
2325 agp_i915_chipset_flush_free_page(dev);
2329 agp_i965_chipset_flush_setup(device_t dev)
2331 struct agp_i810_softc *sc;
2333 uint32_t temp_hi, temp_lo;
2336 sc = device_get_softc(dev);
2338 temp_hi = pci_read_config(sc->bdev, AGP_I965_IFPADDR + 4, 4);
2339 temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4);
2341 if ((temp_lo & 1) != 0) {
2342 temp = ((uint64_t)temp_hi << 32) | (temp_lo & ~1);
2345 "Found already configured flush page at 0x%jx\n",
2347 sc->sc_bios_allocated_flush_page = 1;
2349 * In the case BIOS initialized the flush pointer (?)
2350 * register, expect that BIOS also set up the resource
2353 error = agp_i915_chipset_flush_alloc_page(dev, temp,
2354 temp + PAGE_SIZE - 1);
2358 sc->sc_bios_allocated_flush_page = 0;
2359 error = agp_i915_chipset_flush_alloc_page(dev, 0, ~0);
2362 temp = rman_get_start(sc->sc_flush_page_res);
2363 pci_write_config(sc->bdev, AGP_I965_IFPADDR + 4,
2364 (temp >> 32) & UINT32_MAX, 4);
2365 pci_write_config(sc->bdev, AGP_I965_IFPADDR,
2366 (temp & UINT32_MAX) | 1, 4);
2372 agp_i965_chipset_flush_teardown(device_t dev)
2374 struct agp_i810_softc *sc;
2377 sc = device_get_softc(dev);
2378 if (sc->sc_flush_page_res == NULL)
2380 if (!sc->sc_bios_allocated_flush_page) {
2381 temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4);
2383 pci_write_config(sc->bdev, AGP_I965_IFPADDR, temp_lo, 4);
2385 agp_i915_chipset_flush_free_page(dev);
2389 agp_i915_chipset_flush(device_t dev)
2391 struct agp_i810_softc *sc;
2393 sc = device_get_softc(dev);
2394 *(uint32_t *)sc->sc_flush_page_vaddr = 1;
2398 agp_intel_gtt_chipset_flush(device_t dev)
2400 struct agp_i810_softc *sc;
2402 sc = device_get_softc(dev);
2403 sc->match->driver->chipset_flush(dev);
2408 agp_intel_gtt_unmap_memory(device_t dev, struct sglist *sg_list)
2413 agp_intel_gtt_map_memory(device_t dev, vm_page_t *pages, u_int num_entries,
2414 struct sglist **sg_list)
2417 struct agp_i810_softc *sc;
2426 if (*sg_list != NULL)
2429 sc = device_get_softc(dev);
2431 sg = sglist_alloc(num_entries, M_WAITOK /* XXXKIB */);
2432 for (i = 0; i < num_entries; i++) {
2433 sg->sg_segs[i].ss_paddr = VM_PAGE_TO_PHYS(pages[i]);
2434 sg->sg_segs[i].ss_len = PAGE_SIZE;
2438 error = bus_dma_tag_create(bus_get_dma_tag(dev),
2439 1 /* alignment */, 0 /* boundary */,
2440 1ULL << sc->match->busdma_addr_mask_sz /* lowaddr */,
2441 BUS_SPACE_MAXADDR /* highaddr */,
2442 NULL /* filtfunc */, NULL /* filtfuncarg */,
2443 BUS_SPACE_MAXADDR /* maxsize */,
2444 BUS_SPACE_UNRESTRICTED /* nsegments */,
2445 BUS_SPACE_MAXADDR /* maxsegsz */,
2446 0 /* flags */, NULL /* lockfunc */, NULL /* lockfuncarg */,
2459 agp_intel_gtt_insert_sg_entries(device_t dev, struct sglist *sg_list,
2460 u_int first_entry, u_int flags)
2462 struct agp_i810_softc *sc;
2467 sc = device_get_softc(dev);
2468 for (i = j = 0; j < sg_list->sg_nseg; j++) {
2469 spaddr = sg_list->sg_segs[i].ss_paddr;
2470 slen = sg_list->sg_segs[i].ss_len;
2471 for (; slen > 0; i++) {
2472 sc->match->driver->install_gtt_pte(dev, first_entry + i,
2474 spaddr += AGP_PAGE_SIZE;
2475 slen -= AGP_PAGE_SIZE;
2478 sc->match->driver->read_gtt_pte(dev, first_entry + i - 1);
2482 intel_gtt_clear_range(u_int first_entry, u_int num_entries)
2485 agp_intel_gtt_clear_range(intel_agp, first_entry, num_entries);
2489 intel_gtt_insert_pages(u_int first_entry, u_int num_entries, vm_page_t *pages,
2493 agp_intel_gtt_insert_pages(intel_agp, first_entry, num_entries,
2501 return (agp_intel_gtt_get(intel_agp));
2505 intel_gtt_chipset_flush(void)
2508 return (agp_intel_gtt_chipset_flush(intel_agp));
2512 intel_gtt_unmap_memory(struct sglist *sg_list)
2515 agp_intel_gtt_unmap_memory(intel_agp, sg_list);
2519 intel_gtt_map_memory(vm_page_t *pages, u_int num_entries,
2520 struct sglist **sg_list)
2523 return (agp_intel_gtt_map_memory(intel_agp, pages, num_entries,
2528 intel_gtt_insert_sg_entries(struct sglist *sg_list, u_int first_entry,
2532 agp_intel_gtt_insert_sg_entries(intel_agp, sg_list, first_entry, flags);
2536 intel_gtt_get_bridge_device(void)
2538 struct agp_i810_softc *sc;
2540 sc = device_get_softc(intel_agp);
2545 intel_gtt_read_pte_paddr(u_int entry)
2547 struct agp_i810_softc *sc;
2549 sc = device_get_softc(intel_agp);
2550 return (sc->match->driver->read_gtt_pte_paddr(intel_agp, entry));
2554 intel_gtt_read_pte(u_int entry)
2556 struct agp_i810_softc *sc;
2558 sc = device_get_softc(intel_agp);
2559 return (sc->match->driver->read_gtt_pte(intel_agp, entry));
2563 intel_gtt_write(u_int entry, uint32_t val)
2565 struct agp_i810_softc *sc;
2567 sc = device_get_softc(intel_agp);
2568 return (sc->match->driver->write_gtt(intel_agp, entry, val));