kernel: Add a port of the Linux 4.8 vga_switcheroo module
[dragonfly.git] / sys / dev / agp / agp_i810.c
blob967d08a7fd06d6bda6b409654bc10ffca0b6e34a
1 /*
2 * Copyright (c) 2000 Doug Rabson
3 * Copyright (c) 2000 Ruslan Ermilov
4 * Copyright (c) 2011 The FreeBSD Foundation
5 * All rights reserved.
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
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.
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.
33 * Fixes for 830/845G support: David Dawes <dawes@xfree86.org>
34 * 852GM/855GM/865G support added by David Dawes <dawes@xfree86.org>
36 * This is generic Intel GTT handling code, morphed from the AGP
37 * bridge code.
40 #if 0
41 #define KTR_AGP_I810 KTR_DEV
42 #else
43 #define KTR_AGP_I810 0
44 #endif
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/malloc.h>
49 #include <sys/kernel.h>
50 #include <sys/bus.h>
51 #include <sys/lock.h>
52 #include <sys/rman.h>
54 #include "pcidevs.h"
55 #include <bus/pci/pcivar.h>
56 #include <bus/pci/pcireg.h>
57 #include "agppriv.h"
58 #include "agpreg.h"
60 #include <vm/vm.h>
61 #include <vm/vm_object.h>
62 #include <vm/vm_page.h>
63 #include <vm/vm_param.h>
64 #include <vm/vm_pageout.h>
65 #include <vm/pmap.h>
67 #include <vm/vm_page2.h>
69 #include <machine/md_var.h>
71 #include <linux/slab.h>
72 #include <linux/scatterlist.h>
73 #include <drm/intel-gtt.h>
75 #define bus_read_1(r, o) \
76 bus_space_read_1((r)->r_bustag, (r)->r_bushandle, (o))
77 #define bus_read_4(r, o) \
78 bus_space_read_4((r)->r_bustag, (r)->r_bushandle, (o))
79 #define bus_write_4(r, o, v) \
80 bus_space_write_4((r)->r_bustag, (r)->r_bushandle, (o), (v))
82 struct agp_i810_match;
84 static int agp_i915_check_active(device_t bridge_dev);
86 static void agp_i810_set_desc(device_t dev, const struct agp_i810_match *match);
88 static void agp_i915_dump_regs(device_t dev);
89 static void agp_i965_dump_regs(device_t dev);
91 static int agp_i915_get_stolen_size(device_t dev);
93 static int agp_i915_get_gtt_mappable_entries(device_t dev);
95 static int agp_i810_get_gtt_total_entries(device_t dev);
96 static int agp_i965_get_gtt_total_entries(device_t dev);
97 static int agp_gen5_get_gtt_total_entries(device_t dev);
99 static int agp_i830_install_gatt(device_t dev);
101 static void agp_i830_deinstall_gatt(device_t dev);
103 static void agp_i915_install_gtt_pte(device_t dev, u_int index,
104 vm_offset_t physical, int flags);
105 static void agp_i965_install_gtt_pte(device_t dev, u_int index,
106 vm_offset_t physical, int flags);
107 static void agp_g4x_install_gtt_pte(device_t dev, u_int index,
108 vm_offset_t physical, int flags);
110 static void agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte);
111 static void agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte);
112 static void agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte);
114 static void agp_i915_sync_gtt_pte(device_t dev, u_int index);
115 static void agp_i965_sync_gtt_pte(device_t dev, u_int index);
116 static void agp_g4x_sync_gtt_pte(device_t dev, u_int index);
118 static int agp_i915_set_aperture(device_t dev, u_int32_t aperture);
120 static int agp_i915_chipset_flush_setup(device_t dev);
121 static int agp_i965_chipset_flush_setup(device_t dev);
123 static void agp_i915_chipset_flush_teardown(device_t dev);
124 static void agp_i965_chipset_flush_teardown(device_t dev);
126 static void agp_i915_chipset_flush(device_t dev);
128 enum {
129 CHIP_I810, /* i810/i815 */
130 CHIP_I830, /* 830M/845G */
131 CHIP_I855, /* 852GM/855GM/865G */
132 CHIP_I915, /* 915G/915GM */
133 CHIP_I965, /* G965 */
134 CHIP_G33, /* G33/Q33/Q35 */
135 CHIP_IGD, /* Pineview */
136 CHIP_G4X, /* G45/Q45 */
139 /* The i810 through i855 have the registers at BAR 1, and the GATT gets
140 * allocated by us. The i915 has registers in BAR 0 and the GATT is at the
141 * start of the stolen memory, and should only be accessed by the OS through
142 * BAR 3. The G965 has registers and GATT in the same BAR (0) -- first 512KB
143 * is registers, second 512KB is GATT.
145 static struct resource_spec agp_i915_res_spec[] = {
146 { SYS_RES_MEMORY, AGP_I915_MMADR, RF_ACTIVE | RF_SHAREABLE },
147 { SYS_RES_MEMORY, AGP_I915_GTTADR, RF_ACTIVE | RF_SHAREABLE },
148 { -1, 0 }
151 static struct resource_spec agp_i965_res_spec[] = {
152 { SYS_RES_MEMORY, AGP_I965_GTTMMADR, RF_ACTIVE | RF_SHAREABLE },
153 { -1, 0 }
156 struct agp_i810_softc {
157 struct agp_softc agp;
158 u_int32_t initial_aperture; /* aperture size at startup */
159 struct agp_gatt *gatt;
160 u_int32_t dcache_size; /* i810 only */
161 u_int32_t stolen; /* number of i830/845 gtt
162 entries for stolen memory */
163 u_int stolen_size; /* BIOS-reserved graphics memory */
164 u_int gtt_total_entries; /* Total number of gtt ptes */
165 u_int gtt_mappable_entries; /* Number of gtt ptes mappable by CPU */
166 device_t bdev; /* bridge device */
167 void *argb_cursor; /* contigmalloc area for ARGB cursor */
168 struct resource *sc_res[3];
169 const struct agp_i810_match *match;
170 int sc_flush_page_rid;
171 struct resource *sc_flush_page_res;
172 void *sc_flush_page_vaddr;
173 int sc_bios_allocated_flush_page;
176 static device_t intel_agp;
178 struct agp_i810_driver {
179 int chiptype;
180 int gen;
181 int busdma_addr_mask_sz;
182 struct resource_spec *res_spec;
183 int (*check_active)(device_t);
184 void (*set_desc)(device_t, const struct agp_i810_match *);
185 void (*dump_regs)(device_t);
186 int (*get_stolen_size)(device_t);
187 int (*get_gtt_total_entries)(device_t);
188 int (*get_gtt_mappable_entries)(device_t);
189 int (*install_gatt)(device_t);
190 void (*deinstall_gatt)(device_t);
191 void (*write_gtt)(device_t, u_int, uint32_t);
192 void (*install_gtt_pte)(device_t, u_int, vm_offset_t, int);
193 void (*sync_gtt_pte)(device_t, u_int);
194 int (*set_aperture)(device_t, u_int32_t);
195 int (*chipset_flush_setup)(device_t);
196 void (*chipset_flush_teardown)(device_t);
197 void (*chipset_flush)(device_t);
200 static struct {
201 struct intel_gtt base;
202 } intel_private;
204 static const struct agp_i810_driver agp_i810_i915_driver = {
205 .chiptype = CHIP_I915,
206 .gen = 3,
207 .busdma_addr_mask_sz = 32,
208 .res_spec = agp_i915_res_spec,
209 .check_active = agp_i915_check_active,
210 .set_desc = agp_i810_set_desc,
211 .dump_regs = agp_i915_dump_regs,
212 .get_stolen_size = agp_i915_get_stolen_size,
213 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
214 .get_gtt_total_entries = agp_i810_get_gtt_total_entries,
215 .install_gatt = agp_i830_install_gatt,
216 .deinstall_gatt = agp_i830_deinstall_gatt,
217 .write_gtt = agp_i915_write_gtt,
218 .install_gtt_pte = agp_i915_install_gtt_pte,
219 .sync_gtt_pte = agp_i915_sync_gtt_pte,
220 .set_aperture = agp_i915_set_aperture,
221 .chipset_flush_setup = agp_i915_chipset_flush_setup,
222 .chipset_flush_teardown = agp_i915_chipset_flush_teardown,
223 .chipset_flush = agp_i915_chipset_flush,
226 static const struct agp_i810_driver agp_i810_g965_driver = {
227 .chiptype = CHIP_I965,
228 .gen = 4,
229 .busdma_addr_mask_sz = 36,
230 .res_spec = agp_i965_res_spec,
231 .check_active = agp_i915_check_active,
232 .set_desc = agp_i810_set_desc,
233 .dump_regs = agp_i965_dump_regs,
234 .get_stolen_size = agp_i915_get_stolen_size,
235 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
236 .get_gtt_total_entries = agp_i965_get_gtt_total_entries,
237 .install_gatt = agp_i830_install_gatt,
238 .deinstall_gatt = agp_i830_deinstall_gatt,
239 .write_gtt = agp_i965_write_gtt,
240 .install_gtt_pte = agp_i965_install_gtt_pte,
241 .sync_gtt_pte = agp_i965_sync_gtt_pte,
242 .set_aperture = agp_i915_set_aperture,
243 .chipset_flush_setup = agp_i965_chipset_flush_setup,
244 .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
245 .chipset_flush = agp_i915_chipset_flush,
248 static const struct agp_i810_driver agp_i810_g33_driver = {
249 .chiptype = CHIP_G33,
250 .gen = 3,
251 .busdma_addr_mask_sz = 36,
252 .res_spec = agp_i915_res_spec,
253 .check_active = agp_i915_check_active,
254 .set_desc = agp_i810_set_desc,
255 .dump_regs = agp_i965_dump_regs,
256 .get_stolen_size = agp_i915_get_stolen_size,
257 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
258 .get_gtt_total_entries = agp_i965_get_gtt_total_entries,
259 .install_gatt = agp_i830_install_gatt,
260 .deinstall_gatt = agp_i830_deinstall_gatt,
261 .write_gtt = agp_i915_write_gtt,
262 .install_gtt_pte = agp_i965_install_gtt_pte,
263 .sync_gtt_pte = agp_i915_sync_gtt_pte,
264 .set_aperture = agp_i915_set_aperture,
265 .chipset_flush_setup = agp_i965_chipset_flush_setup,
266 .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
267 .chipset_flush = agp_i915_chipset_flush,
270 static const struct agp_i810_driver pineview_gtt_driver = {
271 .chiptype = CHIP_IGD,
272 .gen = 3,
273 .busdma_addr_mask_sz = 36,
274 .res_spec = agp_i915_res_spec,
275 .check_active = agp_i915_check_active,
276 .set_desc = agp_i810_set_desc,
277 .dump_regs = agp_i915_dump_regs,
278 .get_stolen_size = agp_i915_get_stolen_size,
279 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
280 .get_gtt_total_entries = agp_i965_get_gtt_total_entries,
281 .install_gatt = agp_i830_install_gatt,
282 .deinstall_gatt = agp_i830_deinstall_gatt,
283 .write_gtt = agp_i915_write_gtt,
284 .install_gtt_pte = agp_i965_install_gtt_pte,
285 .sync_gtt_pte = agp_i915_sync_gtt_pte,
286 .set_aperture = agp_i915_set_aperture,
287 .chipset_flush_setup = agp_i965_chipset_flush_setup,
288 .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
289 .chipset_flush = agp_i915_chipset_flush,
292 static const struct agp_i810_driver agp_i810_g4x_driver = {
293 .chiptype = CHIP_G4X,
294 .gen = 5,
295 .busdma_addr_mask_sz = 36,
296 .res_spec = agp_i965_res_spec,
297 .check_active = agp_i915_check_active,
298 .set_desc = agp_i810_set_desc,
299 .dump_regs = agp_i965_dump_regs,
300 .get_stolen_size = agp_i915_get_stolen_size,
301 .get_gtt_mappable_entries = agp_i915_get_gtt_mappable_entries,
302 .get_gtt_total_entries = agp_gen5_get_gtt_total_entries,
303 .install_gatt = agp_i830_install_gatt,
304 .deinstall_gatt = agp_i830_deinstall_gatt,
305 .write_gtt = agp_g4x_write_gtt,
306 .install_gtt_pte = agp_g4x_install_gtt_pte,
307 .sync_gtt_pte = agp_g4x_sync_gtt_pte,
308 .set_aperture = agp_i915_set_aperture,
309 .chipset_flush_setup = agp_i965_chipset_flush_setup,
310 .chipset_flush_teardown = agp_i965_chipset_flush_teardown,
311 .chipset_flush = agp_i915_chipset_flush,
314 /* For adding new devices, devid is the id of the graphics controller
315 * (pci:0:2:0, for example). The placeholder (usually at pci:0:2:1) for the
316 * second head should never be added. The bridge_offset is the offset to
317 * subtract from devid to get the id of the hostb that the device is on.
319 static const struct agp_i810_match {
320 uint16_t devid;
321 char *name;
322 const struct agp_i810_driver *driver;
323 } agp_i810_matches[] = {
325 .devid = 0x2582,
326 .name = "Intel 82915G (915G GMCH) SVGA controller",
327 .driver = &agp_i810_i915_driver
330 .devid = 0x258A,
331 .name = "Intel E7221 SVGA controller",
332 .driver = &agp_i810_i915_driver
335 .devid = 0x2592,
336 .name = "Intel 82915GM (915GM GMCH) SVGA controller",
337 .driver = &agp_i810_i915_driver
340 .devid = 0x2772,
341 .name = "Intel 82945G (945G GMCH) SVGA controller",
342 .driver = &agp_i810_i915_driver
345 .devid = 0x27A2,
346 .name = "Intel 82945GM (945GM GMCH) SVGA controller",
347 .driver = &agp_i810_i915_driver
350 .devid = 0x27AE,
351 .name = "Intel 945GME SVGA controller",
352 .driver = &agp_i810_i915_driver
355 .devid = 0x2972,
356 .name = "Intel 946GZ SVGA controller",
357 .driver = &agp_i810_g965_driver
360 .devid = 0x2982,
361 .name = "Intel G965 SVGA controller",
362 .driver = &agp_i810_g965_driver
365 .devid = 0x2992,
366 .name = "Intel Q965 SVGA controller",
367 .driver = &agp_i810_g965_driver
370 .devid = 0x29A2,
371 .name = "Intel G965 SVGA controller",
372 .driver = &agp_i810_g965_driver
375 .devid = 0x29B2,
376 .name = "Intel Q35 SVGA controller",
377 .driver = &agp_i810_g33_driver
380 .devid = 0x29C2,
381 .name = "Intel G33 SVGA controller",
382 .driver = &agp_i810_g33_driver
385 .devid = 0x29D2,
386 .name = "Intel Q33 SVGA controller",
387 .driver = &agp_i810_g33_driver
390 .devid = 0xA001,
391 .name = "Intel Pineview SVGA controller",
392 .driver = &pineview_gtt_driver
395 .devid = 0xA011,
396 .name = "Intel Pineview (M) SVGA controller",
397 .driver = &pineview_gtt_driver
400 .devid = 0x2A02,
401 .name = "Intel GM965 SVGA controller",
402 .driver = &agp_i810_g965_driver
405 .devid = 0x2A12,
406 .name = "Intel GME965 SVGA controller",
407 .driver = &agp_i810_g965_driver
410 .devid = 0x2A42,
411 .name = "Intel GM45 SVGA controller",
412 .driver = &agp_i810_g4x_driver
415 .devid = 0x2E02,
416 .name = "Intel Eaglelake SVGA controller",
417 .driver = &agp_i810_g4x_driver
420 .devid = 0x2E12,
421 .name = "Intel Q45 SVGA controller",
422 .driver = &agp_i810_g4x_driver
425 .devid = 0x2E22,
426 .name = "Intel G45 SVGA controller",
427 .driver = &agp_i810_g4x_driver
430 .devid = 0x2E32,
431 .name = "Intel G41 SVGA controller",
432 .driver = &agp_i810_g4x_driver
435 .devid = 0x0042,
436 .name = "Intel Ironlake (D) SVGA controller",
437 .driver = &agp_i810_g4x_driver
440 .devid = 0x0046,
441 .name = "Intel Ironlake (M) SVGA controller",
442 .driver = &agp_i810_g4x_driver
446 .devid = 0,
450 static const struct agp_i810_match*
451 agp_i810_match(device_t dev)
453 int i, devid;
455 if (pci_get_vendor(dev) != PCI_VENDOR_INTEL)
456 return (NULL);
458 devid = pci_get_device(dev);
459 for (i = 0; agp_i810_matches[i].devid != 0; i++) {
460 if (agp_i810_matches[i].devid == devid)
461 break;
463 if (agp_i810_matches[i].devid == 0)
464 return (NULL);
465 else
466 return (&agp_i810_matches[i]);
470 * Find bridge device.
472 static device_t
473 agp_i810_find_bridge(device_t dev)
476 return (pci_find_dbsf(0, 0, 0, 0));
479 static void
480 agp_i810_identify(driver_t *driver, device_t parent)
483 if (device_find_child(parent, "agp", -1) == NULL &&
484 agp_i810_match(parent))
485 device_add_child(parent, "agp", -1);
488 static int
489 agp_i915_check_active(device_t bridge_dev)
491 int deven;
493 deven = pci_read_config(bridge_dev, AGP_I915_DEVEN, 4);
494 if ((deven & AGP_I915_DEVEN_D2F0) == AGP_I915_DEVEN_D2F0_DISABLED)
495 return (ENXIO);
496 return (0);
499 static void
500 agp_i810_set_desc(device_t dev, const struct agp_i810_match *match)
503 device_set_desc(dev, match->name);
506 static int
507 agp_i810_probe(device_t dev)
509 device_t bdev;
510 const struct agp_i810_match *match;
511 int err = 0;
513 if (resource_disabled("agp", device_get_unit(dev)))
514 return (ENXIO);
515 match = agp_i810_match(dev);
516 if (match == NULL)
517 return (ENXIO);
519 bdev = agp_i810_find_bridge(dev);
520 if (bdev == NULL) {
521 if (bootverbose)
522 kprintf("I810: can't find bridge device\n");
523 return (ENXIO);
527 * checking whether internal graphics device has been activated.
529 if (match->driver->check_active != NULL) {
530 err = match->driver->check_active(bdev);
531 if (err != 0) {
532 if (bootverbose)
533 kprintf("i810: disabled, not probing\n");
534 return (err);
538 match->driver->set_desc(dev, match);
539 return (BUS_PROBE_DEFAULT);
542 static void
543 agp_i915_dump_regs(device_t dev)
545 struct agp_i810_softc *sc = device_get_softc(dev);
547 device_printf(dev, "AGP_I810_PGTBL_CTL: %08x\n",
548 bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL));
549 device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
550 pci_read_config(sc->bdev, AGP_I855_GCC1, 1));
551 device_printf(dev, "AGP_I915_MSAC: 0x%02x\n",
552 pci_read_config(sc->bdev, AGP_I915_MSAC, 1));
555 static void
556 agp_i965_dump_regs(device_t dev)
558 struct agp_i810_softc *sc = device_get_softc(dev);
560 device_printf(dev, "AGP_I965_PGTBL_CTL2: %08x\n",
561 bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2));
562 device_printf(dev, "AGP_I855_GCC1: 0x%02x\n",
563 pci_read_config(dev, AGP_I855_GCC1, 1));
564 device_printf(dev, "AGP_I965_MSAC: 0x%02x\n",
565 pci_read_config(dev, AGP_I965_MSAC, 1));
568 static int
569 agp_i915_get_stolen_size(device_t dev)
571 struct agp_i810_softc *sc;
572 unsigned int gcc1, stolen, gtt_size;
574 sc = device_get_softc(dev);
577 * Stolen memory is set up at the beginning of the aperture by
578 * the BIOS, consisting of the GATT followed by 4kb for the
579 * BIOS display.
581 switch (sc->match->driver->chiptype) {
582 case CHIP_I855:
583 gtt_size = 128;
584 break;
585 case CHIP_I915:
586 gtt_size = 256;
587 break;
588 case CHIP_I965:
589 switch (bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL) &
590 AGP_I810_PGTBL_SIZE_MASK) {
591 case AGP_I810_PGTBL_SIZE_128KB:
592 gtt_size = 128;
593 break;
594 case AGP_I810_PGTBL_SIZE_256KB:
595 gtt_size = 256;
596 break;
597 case AGP_I810_PGTBL_SIZE_512KB:
598 gtt_size = 512;
599 break;
600 case AGP_I965_PGTBL_SIZE_1MB:
601 gtt_size = 1024;
602 break;
603 case AGP_I965_PGTBL_SIZE_2MB:
604 gtt_size = 2048;
605 break;
606 case AGP_I965_PGTBL_SIZE_1_5MB:
607 gtt_size = 1024 + 512;
608 break;
609 default:
610 device_printf(dev, "Bad PGTBL size\n");
611 return (EINVAL);
613 break;
614 case CHIP_G33:
615 gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 2);
616 switch (gcc1 & AGP_G33_MGGC_GGMS_MASK) {
617 case AGP_G33_MGGC_GGMS_SIZE_1M:
618 gtt_size = 1024;
619 break;
620 case AGP_G33_MGGC_GGMS_SIZE_2M:
621 gtt_size = 2048;
622 break;
623 default:
624 device_printf(dev, "Bad PGTBL size\n");
625 return (EINVAL);
627 break;
628 case CHIP_IGD:
629 case CHIP_G4X:
630 gtt_size = 0;
631 break;
632 default:
633 device_printf(dev, "Bad chiptype\n");
634 return (EINVAL);
637 /* GCC1 is called MGGC on i915+ */
638 gcc1 = pci_read_config(sc->bdev, AGP_I855_GCC1, 1);
639 switch (gcc1 & AGP_I855_GCC1_GMS) {
640 case AGP_I855_GCC1_GMS_STOLEN_1M:
641 stolen = 1024;
642 break;
643 case AGP_I855_GCC1_GMS_STOLEN_4M:
644 stolen = 4 * 1024;
645 break;
646 case AGP_I855_GCC1_GMS_STOLEN_8M:
647 stolen = 8 * 1024;
648 break;
649 case AGP_I855_GCC1_GMS_STOLEN_16M:
650 stolen = 16 * 1024;
651 break;
652 case AGP_I855_GCC1_GMS_STOLEN_32M:
653 stolen = 32 * 1024;
654 break;
655 case AGP_I915_GCC1_GMS_STOLEN_48M:
656 stolen = sc->match->driver->gen > 2 ? 48 * 1024 : 0;
657 break;
658 case AGP_I915_GCC1_GMS_STOLEN_64M:
659 stolen = sc->match->driver->gen > 2 ? 64 * 1024 : 0;
660 break;
661 case AGP_G33_GCC1_GMS_STOLEN_128M:
662 stolen = sc->match->driver->gen > 2 ? 128 * 1024 : 0;
663 break;
664 case AGP_G33_GCC1_GMS_STOLEN_256M:
665 stolen = sc->match->driver->gen > 2 ? 256 * 1024 : 0;
666 break;
667 case AGP_G4X_GCC1_GMS_STOLEN_96M:
668 if (sc->match->driver->chiptype == CHIP_I965 ||
669 sc->match->driver->chiptype == CHIP_G4X)
670 stolen = 96 * 1024;
671 else
672 stolen = 0;
673 break;
674 case AGP_G4X_GCC1_GMS_STOLEN_160M:
675 if (sc->match->driver->chiptype == CHIP_I965 ||
676 sc->match->driver->chiptype == CHIP_G4X)
677 stolen = 160 * 1024;
678 else
679 stolen = 0;
680 break;
681 case AGP_G4X_GCC1_GMS_STOLEN_224M:
682 if (sc->match->driver->chiptype == CHIP_I965 ||
683 sc->match->driver->chiptype == CHIP_G4X)
684 stolen = 224 * 1024;
685 else
686 stolen = 0;
687 break;
688 case AGP_G4X_GCC1_GMS_STOLEN_352M:
689 if (sc->match->driver->chiptype == CHIP_I965 ||
690 sc->match->driver->chiptype == CHIP_G4X)
691 stolen = 352 * 1024;
692 else
693 stolen = 0;
694 break;
695 default:
696 device_printf(dev,
697 "unknown memory configuration, disabling (GCC1 %x)\n",
698 gcc1);
699 return (EINVAL);
702 gtt_size += 4;
703 sc->stolen_size = stolen * 1024;
704 sc->stolen = (stolen - gtt_size) * 1024 / 4096;
706 return (0);
709 static int
710 agp_i915_get_gtt_mappable_entries(device_t dev)
712 struct agp_i810_softc *sc;
713 uint32_t ap;
715 sc = device_get_softc(dev);
716 ap = AGP_GET_APERTURE(dev);
717 sc->gtt_mappable_entries = ap >> AGP_PAGE_SHIFT;
718 return (0);
721 static int
722 agp_i810_get_gtt_total_entries(device_t dev)
724 struct agp_i810_softc *sc;
726 sc = device_get_softc(dev);
727 sc->gtt_total_entries = sc->gtt_mappable_entries;
728 return (0);
731 static int
732 agp_i965_get_gtt_total_entries(device_t dev)
734 struct agp_i810_softc *sc;
735 uint32_t pgetbl_ctl;
736 int error;
738 sc = device_get_softc(dev);
739 error = 0;
740 pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
741 switch (pgetbl_ctl & AGP_I810_PGTBL_SIZE_MASK) {
742 case AGP_I810_PGTBL_SIZE_128KB:
743 sc->gtt_total_entries = 128 * 1024 / 4;
744 break;
745 case AGP_I810_PGTBL_SIZE_256KB:
746 sc->gtt_total_entries = 256 * 1024 / 4;
747 break;
748 case AGP_I810_PGTBL_SIZE_512KB:
749 sc->gtt_total_entries = 512 * 1024 / 4;
750 break;
751 /* GTT pagetable sizes bigger than 512KB are not possible on G33! */
752 case AGP_I810_PGTBL_SIZE_1MB:
753 sc->gtt_total_entries = 1024 * 1024 / 4;
754 break;
755 case AGP_I810_PGTBL_SIZE_2MB:
756 sc->gtt_total_entries = 2 * 1024 * 1024 / 4;
757 break;
758 case AGP_I810_PGTBL_SIZE_1_5MB:
759 sc->gtt_total_entries = (1024 + 512) * 1024 / 4;
760 break;
761 default:
762 device_printf(dev, "Unknown page table size\n");
763 error = ENXIO;
765 return (error);
768 static void
769 agp_gen5_adjust_pgtbl_size(device_t dev, uint32_t sz)
771 struct agp_i810_softc *sc;
772 uint32_t pgetbl_ctl, pgetbl_ctl2;
774 sc = device_get_softc(dev);
776 /* Disable per-process page table. */
777 pgetbl_ctl2 = bus_read_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2);
778 pgetbl_ctl2 &= ~AGP_I810_PGTBL_ENABLED;
779 bus_write_4(sc->sc_res[0], AGP_I965_PGTBL_CTL2, pgetbl_ctl2);
781 /* Write the new ggtt size. */
782 pgetbl_ctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
783 pgetbl_ctl &= ~AGP_I810_PGTBL_SIZE_MASK;
784 pgetbl_ctl |= sz;
785 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgetbl_ctl);
788 static int
789 agp_gen5_get_gtt_total_entries(device_t dev)
791 struct agp_i810_softc *sc;
792 uint16_t gcc1;
794 sc = device_get_softc(dev);
796 gcc1 = pci_read_config(sc->bdev, AGP_I830_GCC1, 2);
797 switch (gcc1 & AGP_G4x_GCC1_SIZE_MASK) {
798 case AGP_G4x_GCC1_SIZE_1M:
799 case AGP_G4x_GCC1_SIZE_VT_1M:
800 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1MB);
801 break;
802 case AGP_G4x_GCC1_SIZE_VT_1_5M:
803 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_1_5MB);
804 break;
805 case AGP_G4x_GCC1_SIZE_2M:
806 case AGP_G4x_GCC1_SIZE_VT_2M:
807 agp_gen5_adjust_pgtbl_size(dev, AGP_I810_PGTBL_SIZE_2MB);
808 break;
809 default:
810 device_printf(dev, "Unknown page table size\n");
811 return (ENXIO);
814 return (agp_i965_get_gtt_total_entries(dev));
817 static int
818 agp_i830_install_gatt(device_t dev)
820 struct agp_i810_softc *sc;
821 uint32_t pgtblctl;
823 sc = device_get_softc(dev);
826 * The i830 automatically initializes the 128k gatt on boot.
827 * GATT address is already in there, make sure it's enabled.
829 pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
830 pgtblctl |= 1;
831 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
833 sc->gatt->ag_physical = pgtblctl & ~1;
834 return (0);
837 static int
838 agp_i810_attach(device_t dev)
840 struct agp_i810_softc *sc;
841 int error;
843 sc = device_get_softc(dev);
844 sc->bdev = agp_i810_find_bridge(dev);
845 if (sc->bdev == NULL)
846 return (ENOENT);
848 sc->match = agp_i810_match(dev);
850 agp_set_aperture_resource(dev, sc->match->driver->gen <= 2 ?
851 AGP_APBASE : AGP_I915_GMADR);
852 error = agp_generic_attach(dev);
853 if (error)
854 return (error);
856 if (ptoa((vm_paddr_t)Maxmem) >
857 (1ULL << sc->match->driver->busdma_addr_mask_sz) - 1) {
858 device_printf(dev, "agp_i810 does not support physical "
859 "memory above %ju.\n", (uintmax_t)(1ULL <<
860 sc->match->driver->busdma_addr_mask_sz) - 1);
861 return (ENOENT);
864 if (bus_alloc_resources(dev, sc->match->driver->res_spec, sc->sc_res)) {
865 agp_generic_detach(dev);
866 return (ENODEV);
869 sc->initial_aperture = AGP_GET_APERTURE(dev);
870 sc->gatt = kmalloc(sizeof(struct agp_gatt), M_DRM, M_WAITOK);
871 sc->gatt->ag_entries = AGP_GET_APERTURE(dev) >> AGP_PAGE_SHIFT;
873 if ((error = sc->match->driver->get_stolen_size(dev)) != 0 ||
874 (error = sc->match->driver->install_gatt(dev)) != 0 ||
875 (error = sc->match->driver->get_gtt_mappable_entries(dev)) != 0 ||
876 (error = sc->match->driver->get_gtt_total_entries(dev)) != 0 ||
877 (error = sc->match->driver->chipset_flush_setup(dev)) != 0) {
878 bus_release_resources(dev, sc->match->driver->res_spec,
879 sc->sc_res);
880 kfree(sc->gatt);
881 agp_generic_detach(dev);
882 return (error);
885 intel_agp = dev;
886 device_printf(dev, "aperture size is %dM",
887 sc->initial_aperture / 1024 / 1024);
888 if (sc->stolen > 0)
889 kprintf(", detected %dk stolen memory\n", sc->stolen * 4);
890 else
891 kprintf("\n");
892 if (bootverbose) {
893 sc->match->driver->dump_regs(dev);
894 device_printf(dev, "Mappable GTT entries: %d\n",
895 sc->gtt_mappable_entries);
896 device_printf(dev, "Total GTT entries: %d\n",
897 sc->gtt_total_entries);
899 return (0);
902 static void
903 agp_i830_deinstall_gatt(device_t dev)
905 struct agp_i810_softc *sc;
906 unsigned int pgtblctl;
908 sc = device_get_softc(dev);
909 pgtblctl = bus_read_4(sc->sc_res[0], AGP_I810_PGTBL_CTL);
910 pgtblctl &= ~1;
911 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL, pgtblctl);
914 static int
915 agp_i810_detach(device_t dev)
917 struct agp_i810_softc *sc;
919 sc = device_get_softc(dev);
920 agp_free_cdev(dev);
922 /* Clear the GATT base. */
923 sc->match->driver->deinstall_gatt(dev);
925 sc->match->driver->chipset_flush_teardown(dev);
927 /* Put the aperture back the way it started. */
928 AGP_SET_APERTURE(dev, sc->initial_aperture);
930 kfree(sc->gatt);
931 bus_release_resources(dev, sc->match->driver->res_spec, sc->sc_res);
932 agp_free_res(dev);
934 return (0);
937 static int
938 agp_i810_resume(device_t dev)
940 struct agp_i810_softc *sc;
941 sc = device_get_softc(dev);
943 AGP_SET_APERTURE(dev, sc->initial_aperture);
945 /* Install the GATT. */
946 bus_write_4(sc->sc_res[0], AGP_I810_PGTBL_CTL,
947 sc->gatt->ag_physical | 1);
949 return (bus_generic_resume(dev));
953 * Sets the PCI resource size of the aperture on i830-class and below chipsets,
954 * while returning failure on later chipsets when an actual change is
955 * requested.
957 * This whole function is likely bogus, as the kernel would probably need to
958 * reconfigure the placement of the AGP aperture if a larger size is requested,
959 * which doesn't happen currently.
962 static int
963 agp_i915_set_aperture(device_t dev, u_int32_t aperture)
966 return (agp_generic_set_aperture(dev, aperture));
969 static int
970 agp_i810_method_set_aperture(device_t dev, u_int32_t aperture)
972 struct agp_i810_softc *sc;
974 sc = device_get_softc(dev);
975 return (sc->match->driver->set_aperture(dev, aperture));
979 * Writes a GTT entry mapping the page at the given offset from the
980 * beginning of the aperture to the given physical address. Setup the
981 * caching mode according to flags.
983 * For gen 1, 2 and 3, GTT start is located at AGP_I810_GTT offset
984 * from corresponding BAR start. For gen 4, offset is 512KB +
985 * AGP_I810_GTT, for gen 5 and 6 it is 2MB + AGP_I810_GTT.
987 * Also, the bits of the physical page address above 4GB needs to be
988 * placed into bits 40-32 of PTE.
990 static void
991 agp_i915_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
992 int flags)
994 uint32_t pte;
996 pte = (u_int32_t)physical | I810_PTE_VALID;
997 if (flags == AGP_USER_CACHED_MEMORY)
998 pte |= I830_PTE_SYSTEM_CACHED;
1000 agp_i915_write_gtt(dev, index, pte);
1003 static void
1004 agp_i915_write_gtt(device_t dev, u_int index, uint32_t pte)
1006 struct agp_i810_softc *sc;
1008 sc = device_get_softc(dev);
1009 bus_write_4(sc->sc_res[0], index * 4, pte);
1012 static void
1013 agp_i965_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1014 int flags)
1016 uint32_t pte;
1018 pte = (u_int32_t)physical | I810_PTE_VALID;
1019 if (flags == AGP_USER_CACHED_MEMORY)
1020 pte |= I830_PTE_SYSTEM_CACHED;
1022 pte |= (physical >> 28) & 0xf0;
1023 agp_i965_write_gtt(dev, index, pte);
1026 static void
1027 agp_i965_write_gtt(device_t dev, u_int index, uint32_t pte)
1029 struct agp_i810_softc *sc;
1031 sc = device_get_softc(dev);
1032 bus_write_4(sc->sc_res[0], index * 4 + (512 * 1024), pte);
1035 static void
1036 agp_g4x_install_gtt_pte(device_t dev, u_int index, vm_offset_t physical,
1037 int flags)
1039 uint32_t pte;
1041 pte = (u_int32_t)physical | I810_PTE_VALID;
1042 if (flags == AGP_USER_CACHED_MEMORY)
1043 pte |= I830_PTE_SYSTEM_CACHED;
1045 pte |= (physical >> 28) & 0xf0;
1046 agp_g4x_write_gtt(dev, index, pte);
1049 static void
1050 agp_g4x_write_gtt(device_t dev, u_int index, uint32_t pte)
1052 struct agp_i810_softc *sc;
1054 sc = device_get_softc(dev);
1055 bus_write_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024), pte);
1058 static int
1059 agp_i810_bind_page(device_t dev, vm_offset_t offset, vm_offset_t physical)
1061 struct agp_i810_softc *sc = device_get_softc(dev);
1062 u_int index;
1064 if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT)) {
1065 device_printf(dev, "failed: offset is 0x%08jx, "
1066 "shift is %d, entries is %d\n", (intmax_t)offset,
1067 AGP_PAGE_SHIFT, sc->gatt->ag_entries);
1068 return (EINVAL);
1070 index = offset >> AGP_PAGE_SHIFT;
1071 if (sc->stolen != 0 && index < sc->stolen) {
1072 device_printf(dev, "trying to bind into stolen memory\n");
1073 return (EINVAL);
1075 sc->match->driver->install_gtt_pte(dev, index, physical, 0);
1076 return (0);
1079 static int
1080 agp_i810_unbind_page(device_t dev, vm_offset_t offset)
1082 struct agp_i810_softc *sc;
1083 u_int index;
1085 sc = device_get_softc(dev);
1086 if (offset >= (sc->gatt->ag_entries << AGP_PAGE_SHIFT))
1087 return (EINVAL);
1088 index = offset >> AGP_PAGE_SHIFT;
1089 if (sc->stolen != 0 && index < sc->stolen) {
1090 device_printf(dev, "trying to unbind from stolen memory\n");
1091 return (EINVAL);
1093 sc->match->driver->install_gtt_pte(dev, index, 0, 0);
1094 return (0);
1097 static void
1098 agp_i915_sync_gtt_pte(device_t dev, u_int index)
1100 struct agp_i810_softc *sc;
1102 sc = device_get_softc(dev);
1103 bus_read_4(sc->sc_res[1], index * 4);
1106 static void
1107 agp_i965_sync_gtt_pte(device_t dev, u_int index)
1109 struct agp_i810_softc *sc;
1111 sc = device_get_softc(dev);
1112 bus_read_4(sc->sc_res[0], index * 4 + (512 * 1024));
1115 static void
1116 agp_g4x_sync_gtt_pte(device_t dev, u_int index)
1118 struct agp_i810_softc *sc;
1120 sc = device_get_softc(dev);
1121 bus_read_4(sc->sc_res[0], index * 4 + (2 * 1024 * 1024));
1125 * Writing via memory mapped registers already flushes all TLBs.
1127 static void
1128 agp_i810_flush_tlb(device_t dev)
1132 static int
1133 agp_i810_enable(device_t dev, u_int32_t mode)
1136 return (0);
1139 static struct agp_memory *
1140 agp_i810_alloc_memory(device_t dev, int type, vm_size_t size)
1142 struct agp_i810_softc *sc;
1143 struct agp_memory *mem;
1144 vm_page_t m;
1146 sc = device_get_softc(dev);
1148 if ((size & (AGP_PAGE_SIZE - 1)) != 0 ||
1149 sc->agp.as_allocated + size > sc->agp.as_maxmem)
1150 return (0);
1152 if (type == 1) {
1154 * Mapping local DRAM into GATT.
1156 if (sc->match->driver->chiptype != CHIP_I810)
1157 return (0);
1158 if (size != sc->dcache_size)
1159 return (0);
1160 } else if (type == 2) {
1162 * Type 2 is the contiguous physical memory type, that hands
1163 * back a physical address. This is used for cursors on i810.
1164 * Hand back as many single pages with physical as the user
1165 * wants, but only allow one larger allocation (ARGB cursor)
1166 * for simplicity.
1168 if (size != AGP_PAGE_SIZE) {
1169 if (sc->argb_cursor != NULL)
1170 return (0);
1172 /* Allocate memory for ARGB cursor, if we can. */
1173 sc->argb_cursor = contigmalloc(size, M_DRM,
1174 0, 0, ~0, PAGE_SIZE, 0);
1175 if (sc->argb_cursor == NULL)
1176 return (0);
1180 mem = kmalloc(sizeof *mem, M_DRM, M_INTWAIT);
1181 mem->am_id = sc->agp.as_nextid++;
1182 mem->am_size = size;
1183 mem->am_type = type;
1184 if (type != 1 && (type != 2 || size == AGP_PAGE_SIZE))
1185 mem->am_obj = vm_object_allocate(OBJT_DEFAULT,
1186 atop(round_page(size)));
1187 else
1188 mem->am_obj = 0;
1190 if (type == 2) {
1191 if (size == AGP_PAGE_SIZE) {
1193 * Allocate and wire down the page now so that we can
1194 * get its physical address.
1196 VM_OBJECT_LOCK(mem->am_obj);
1197 m = vm_page_grab(mem->am_obj, 0, VM_ALLOC_NORMAL |
1198 VM_ALLOC_ZERO |
1199 VM_ALLOC_RETRY);
1200 vm_page_wire(m);
1201 VM_OBJECT_UNLOCK(mem->am_obj);
1202 mem->am_physical = VM_PAGE_TO_PHYS(m);
1203 vm_page_wakeup(m);
1204 } else {
1205 /* Our allocation is already nicely wired down for us.
1206 * Just grab the physical address.
1208 mem->am_physical = vtophys(sc->argb_cursor);
1210 } else
1211 mem->am_physical = 0;
1213 mem->am_offset = 0;
1214 mem->am_is_bound = 0;
1215 TAILQ_INSERT_TAIL(&sc->agp.as_memory, mem, am_link);
1216 sc->agp.as_allocated += size;
1218 return (mem);
1221 static int
1222 agp_i810_free_memory(device_t dev, struct agp_memory *mem)
1224 struct agp_i810_softc *sc;
1226 if (mem->am_is_bound)
1227 return (EBUSY);
1229 sc = device_get_softc(dev);
1231 if (mem->am_type == 2) {
1232 if (mem->am_size == AGP_PAGE_SIZE) {
1234 * Unwire the page which we wired in alloc_memory.
1236 vm_page_t m;
1238 vm_object_hold(mem->am_obj);
1239 m = vm_page_lookup_busy_wait(mem->am_obj, 0,
1240 FALSE, "agppg");
1241 vm_object_drop(mem->am_obj);
1242 vm_page_unwire(m, 0);
1243 vm_page_wakeup(m);
1244 } else {
1245 contigfree(sc->argb_cursor, mem->am_size, M_DRM);
1246 sc->argb_cursor = NULL;
1250 sc->agp.as_allocated -= mem->am_size;
1251 TAILQ_REMOVE(&sc->agp.as_memory, mem, am_link);
1252 if (mem->am_obj)
1253 vm_object_deallocate(mem->am_obj);
1254 kfree(mem);
1255 return (0);
1258 static int
1259 agp_i810_bind_memory(device_t dev, struct agp_memory *mem, vm_offset_t offset)
1261 struct agp_i810_softc *sc;
1262 vm_offset_t i;
1264 /* Do some sanity checks first. */
1265 if ((offset & (AGP_PAGE_SIZE - 1)) != 0 ||
1266 offset + mem->am_size > AGP_GET_APERTURE(dev)) {
1267 device_printf(dev, "binding memory at bad offset %#x\n",
1268 (int)offset);
1269 return (EINVAL);
1272 sc = device_get_softc(dev);
1273 if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
1274 lockmgr(&sc->agp.as_lock, LK_EXCLUSIVE);
1275 if (mem->am_is_bound) {
1276 lockmgr(&sc->agp.as_lock, LK_RELEASE);
1277 return EINVAL;
1279 /* The memory's already wired down, just stick it in the GTT. */
1280 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
1281 sc->match->driver->install_gtt_pte(dev, (offset + i) >>
1282 AGP_PAGE_SHIFT, mem->am_physical + i, 0);
1284 agp_flush_cache();
1285 mem->am_offset = offset;
1286 mem->am_is_bound = 1;
1287 lockmgr(&sc->agp.as_lock, LK_RELEASE);
1288 return (0);
1291 if (mem->am_type != 1)
1292 return (agp_generic_bind_memory(dev, mem, offset));
1295 * Mapping local DRAM into GATT.
1297 if (sc->match->driver->chiptype != CHIP_I810)
1298 return (EINVAL);
1299 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE)
1300 bus_write_4(sc->sc_res[0],
1301 AGP_I810_GTT + (i >> AGP_PAGE_SHIFT) * 4, i | 3);
1303 return (0);
1306 static int
1307 agp_i810_unbind_memory(device_t dev, struct agp_memory *mem)
1309 struct agp_i810_softc *sc;
1310 vm_offset_t i;
1312 sc = device_get_softc(dev);
1314 if (mem->am_type == 2 && mem->am_size != AGP_PAGE_SIZE) {
1315 lockmgr(&sc->agp.as_lock, LK_EXCLUSIVE);
1316 if (!mem->am_is_bound) {
1317 lockmgr(&sc->agp.as_lock, LK_RELEASE);
1318 return (EINVAL);
1321 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
1322 sc->match->driver->install_gtt_pte(dev,
1323 (mem->am_offset + i) >> AGP_PAGE_SHIFT, 0, 0);
1325 agp_flush_cache();
1326 mem->am_is_bound = 0;
1327 lockmgr(&sc->agp.as_lock, LK_RELEASE);
1328 return (0);
1331 if (mem->am_type != 1)
1332 return (agp_generic_unbind_memory(dev, mem));
1334 if (sc->match->driver->chiptype != CHIP_I810)
1335 return (EINVAL);
1336 for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) {
1337 sc->match->driver->install_gtt_pte(dev, i >> AGP_PAGE_SHIFT,
1338 0, 0);
1340 return (0);
1343 static device_method_t agp_i810_methods[] = {
1344 /* Device interface */
1345 DEVMETHOD(device_identify, agp_i810_identify),
1346 DEVMETHOD(device_probe, agp_i810_probe),
1347 DEVMETHOD(device_attach, agp_i810_attach),
1348 DEVMETHOD(device_detach, agp_i810_detach),
1349 DEVMETHOD(device_suspend, bus_generic_suspend),
1350 DEVMETHOD(device_resume, agp_i810_resume),
1352 /* AGP interface */
1353 DEVMETHOD(agp_get_aperture, agp_generic_get_aperture),
1354 DEVMETHOD(agp_set_aperture, agp_i810_method_set_aperture),
1355 DEVMETHOD(agp_bind_page, agp_i810_bind_page),
1356 DEVMETHOD(agp_unbind_page, agp_i810_unbind_page),
1357 DEVMETHOD(agp_flush_tlb, agp_i810_flush_tlb),
1358 DEVMETHOD(agp_enable, agp_i810_enable),
1359 DEVMETHOD(agp_alloc_memory, agp_i810_alloc_memory),
1360 DEVMETHOD(agp_free_memory, agp_i810_free_memory),
1361 DEVMETHOD(agp_bind_memory, agp_i810_bind_memory),
1362 DEVMETHOD(agp_unbind_memory, agp_i810_unbind_memory),
1363 DEVMETHOD(agp_chipset_flush, agp_intel_gtt_chipset_flush),
1365 DEVMETHOD_END
1368 static driver_t agp_i810_driver = {
1369 "agp",
1370 agp_i810_methods,
1371 sizeof(struct agp_i810_softc),
1374 static devclass_t agp_devclass;
1376 DRIVER_MODULE(agp_i810, vgapci, agp_i810_driver, agp_devclass, NULL, NULL);
1377 MODULE_DEPEND(agp_i810, agp, 1, 1, 1);
1378 MODULE_DEPEND(agp_i810, pci, 1, 1, 1);
1380 extern vm_page_t bogus_page;
1382 void
1383 agp_intel_gtt_clear_range(device_t dev, u_int first_entry, u_int num_entries)
1385 struct agp_i810_softc *sc;
1386 u_int i;
1388 sc = device_get_softc(dev);
1389 for (i = 0; i < num_entries; i++)
1390 sc->match->driver->install_gtt_pte(dev, first_entry + i,
1391 VM_PAGE_TO_PHYS(bogus_page), 0);
1392 sc->match->driver->sync_gtt_pte(dev, first_entry + num_entries - 1);
1395 void
1396 agp_intel_gtt_insert_pages(device_t dev, u_int first_entry, u_int num_entries,
1397 vm_page_t *pages, u_int flags)
1399 struct agp_i810_softc *sc;
1400 u_int i;
1402 sc = device_get_softc(dev);
1403 for (i = 0; i < num_entries; i++) {
1404 KKASSERT(pages[i]->valid == VM_PAGE_BITS_ALL);
1405 KKASSERT(pages[i]->wire_count > 0);
1406 sc->match->driver->install_gtt_pte(dev, first_entry + i,
1407 VM_PAGE_TO_PHYS(pages[i]), flags);
1409 sc->match->driver->sync_gtt_pte(dev, first_entry + num_entries - 1);
1412 void
1413 intel_gtt_insert_sg_entries(struct sg_table *st,
1414 unsigned int pg_start,
1415 unsigned int flags)
1417 struct agp_i810_softc *sc = device_get_softc(intel_agp);
1418 struct scatterlist *sg;
1419 dma_addr_t page;
1420 int i, j, npages, subpage;
1422 i = 0;
1423 for_each_sg(st->sgl, sg, st->nents, j) {
1424 npages = sg_dma_len(sg) / PAGE_SIZE;
1425 for (subpage = 0; subpage < npages; subpage++) {
1426 page = sg_dma_address(sg) + subpage * PAGE_SIZE;
1427 sc->match->driver->install_gtt_pte(intel_agp,
1428 pg_start + i, page, flags);
1429 i++;
1432 sc->match->driver->sync_gtt_pte(intel_agp, pg_start + i - 1);
1436 struct intel_gtt
1437 agp_intel_gtt_get(device_t dev)
1439 struct agp_i810_softc *sc;
1440 struct intel_gtt res;
1442 sc = device_get_softc(dev);
1443 res.stolen_size = sc->stolen_size;
1444 res.gtt_total_entries = sc->gtt_total_entries;
1445 res.gtt_mappable_entries = sc->gtt_mappable_entries;
1446 res.do_idle_maps = 0;
1447 res.scratch_page_dma = VM_PAGE_TO_PHYS(bogus_page);
1448 return (res);
1451 static int
1452 agp_i915_chipset_flush_alloc_page(device_t dev, uint64_t start, uint64_t end)
1454 struct agp_i810_softc *sc;
1455 device_t vga;
1457 sc = device_get_softc(dev);
1458 vga = device_get_parent(dev);
1459 sc->sc_flush_page_rid = 100;
1460 sc->sc_flush_page_res = BUS_ALLOC_RESOURCE(device_get_parent(vga), dev,
1461 SYS_RES_MEMORY, &sc->sc_flush_page_rid, start, end, PAGE_SIZE,
1462 RF_ACTIVE, -1);
1463 if (sc->sc_flush_page_res == NULL) {
1464 device_printf(dev, "Failed to allocate flush page at 0x%jx\n",
1465 (uintmax_t)start);
1466 return (EINVAL);
1468 sc->sc_flush_page_vaddr = rman_get_virtual(sc->sc_flush_page_res);
1469 if (bootverbose) {
1470 device_printf(dev, "Allocated flush page phys 0x%jx virt %p\n",
1471 (uintmax_t)rman_get_start(sc->sc_flush_page_res),
1472 sc->sc_flush_page_vaddr);
1474 return (0);
1477 static void
1478 agp_i915_chipset_flush_free_page(device_t dev)
1480 struct agp_i810_softc *sc;
1481 device_t vga;
1483 sc = device_get_softc(dev);
1484 vga = device_get_parent(dev);
1485 if (sc->sc_flush_page_res == NULL)
1486 return;
1487 BUS_DEACTIVATE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY,
1488 sc->sc_flush_page_rid, sc->sc_flush_page_res);
1489 BUS_RELEASE_RESOURCE(device_get_parent(vga), dev, SYS_RES_MEMORY,
1490 sc->sc_flush_page_rid, sc->sc_flush_page_res);
1493 static int
1494 agp_i915_chipset_flush_setup(device_t dev)
1496 struct agp_i810_softc *sc;
1497 uint32_t temp;
1498 int error;
1500 sc = device_get_softc(dev);
1501 temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4);
1502 if ((temp & 1) != 0) {
1503 temp &= ~1;
1504 if (bootverbose)
1505 device_printf(dev,
1506 "Found already configured flush page at 0x%jx\n",
1507 (uintmax_t)temp);
1508 sc->sc_bios_allocated_flush_page = 1;
1510 * In the case BIOS initialized the flush pointer (?)
1511 * register, expect that BIOS also set up the resource
1512 * for the page.
1514 error = agp_i915_chipset_flush_alloc_page(dev, temp,
1515 temp + PAGE_SIZE - 1);
1516 if (error != 0)
1517 return (error);
1518 } else {
1519 sc->sc_bios_allocated_flush_page = 0;
1520 error = agp_i915_chipset_flush_alloc_page(dev, 0, 0xffffffff);
1521 if (error != 0)
1522 return (error);
1523 temp = rman_get_start(sc->sc_flush_page_res);
1524 pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp | 1, 4);
1526 return (0);
1529 static void
1530 agp_i915_chipset_flush_teardown(device_t dev)
1532 struct agp_i810_softc *sc;
1533 uint32_t temp;
1535 sc = device_get_softc(dev);
1536 if (sc->sc_flush_page_res == NULL)
1537 return;
1538 if (!sc->sc_bios_allocated_flush_page) {
1539 temp = pci_read_config(sc->bdev, AGP_I915_IFPADDR, 4);
1540 temp &= ~1;
1541 pci_write_config(sc->bdev, AGP_I915_IFPADDR, temp, 4);
1543 agp_i915_chipset_flush_free_page(dev);
1546 static int
1547 agp_i965_chipset_flush_setup(device_t dev)
1549 struct agp_i810_softc *sc;
1550 uint64_t temp;
1551 uint32_t temp_hi, temp_lo;
1552 int error;
1554 sc = device_get_softc(dev);
1556 temp_hi = pci_read_config(sc->bdev, AGP_I965_IFPADDR + 4, 4);
1557 temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4);
1559 if ((temp_lo & 1) != 0) {
1560 temp = ((uint64_t)temp_hi << 32) | (temp_lo & ~1);
1561 if (bootverbose)
1562 device_printf(dev,
1563 "Found already configured flush page at 0x%jx\n",
1564 (uintmax_t)temp);
1565 sc->sc_bios_allocated_flush_page = 1;
1567 * In the case BIOS initialized the flush pointer (?)
1568 * register, expect that BIOS also set up the resource
1569 * for the page.
1571 error = agp_i915_chipset_flush_alloc_page(dev, temp,
1572 temp + PAGE_SIZE - 1);
1573 if (error != 0)
1574 return (error);
1575 } else {
1576 sc->sc_bios_allocated_flush_page = 0;
1577 error = agp_i915_chipset_flush_alloc_page(dev, 0, ~0);
1578 if (error != 0)
1579 return (error);
1580 temp = rman_get_start(sc->sc_flush_page_res);
1581 pci_write_config(sc->bdev, AGP_I965_IFPADDR + 4,
1582 (temp >> 32) & UINT32_MAX, 4);
1583 pci_write_config(sc->bdev, AGP_I965_IFPADDR,
1584 (temp & UINT32_MAX) | 1, 4);
1586 return (0);
1589 static void
1590 agp_i965_chipset_flush_teardown(device_t dev)
1592 struct agp_i810_softc *sc;
1593 uint32_t temp_lo;
1595 sc = device_get_softc(dev);
1596 if (sc->sc_flush_page_res == NULL)
1597 return;
1598 if (!sc->sc_bios_allocated_flush_page) {
1599 temp_lo = pci_read_config(sc->bdev, AGP_I965_IFPADDR, 4);
1600 temp_lo &= ~1;
1601 pci_write_config(sc->bdev, AGP_I965_IFPADDR, temp_lo, 4);
1603 agp_i915_chipset_flush_free_page(dev);
1606 static void
1607 agp_i915_chipset_flush(device_t dev)
1609 struct agp_i810_softc *sc;
1611 sc = device_get_softc(dev);
1612 *(uint32_t *)sc->sc_flush_page_vaddr = 1;
1616 agp_intel_gtt_chipset_flush(device_t dev)
1618 struct agp_i810_softc *sc;
1620 sc = device_get_softc(dev);
1621 sc->match->driver->chipset_flush(dev);
1622 return (0);
1625 void
1626 intel_gtt_clear_range(u_int first_entry, u_int num_entries)
1629 agp_intel_gtt_clear_range(intel_agp, first_entry, num_entries);
1632 void intel_gtt_get(u64 *gtt_total, size_t *stolen_size,
1633 phys_addr_t *mappable_base, u64 *mappable_end)
1635 struct agp_info ainfo;
1637 intel_private.base = agp_intel_gtt_get(intel_agp);
1639 *gtt_total = intel_private.base.gtt_total_entries << PAGE_SHIFT;
1640 *stolen_size = intel_private.base.stolen_size;
1641 agp_get_info(intel_agp, &ainfo);
1642 *mappable_base = ainfo.ai_aperture_base;
1643 *mappable_end = intel_private.base.gtt_mappable_entries << PAGE_SHIFT;
1647 intel_gtt_chipset_flush(void)
1650 return (agp_intel_gtt_chipset_flush(intel_agp));
1654 * Only used by gen6
1656 void
1657 intel_gtt_sync_pte(u_int entry)
1659 struct agp_i810_softc *sc;
1661 sc = device_get_softc(intel_agp);
1662 sc->match->driver->sync_gtt_pte(intel_agp, entry);
1666 * Only used by gen6
1668 void
1669 intel_gtt_write(u_int entry, uint32_t val)
1671 struct agp_i810_softc *sc;
1673 sc = device_get_softc(intel_agp);
1674 sc->match->driver->write_gtt(intel_agp, entry, val);