2 * Copyright (c) 2000 Doug Rabson
3 * Copyright (c) 2000 Ruslan Ermilov
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * $FreeBSD: src/sys/dev/agp/agp_i810.c,v 1.43 2007/11/12 21:51:36 jhb Exp $
28 * $DragonFly: src/sys/dev/agp/agp_i810.c,v 1.18 2008/08/22 07:08:13 hasso Exp $
32 * Fixes for 830/845G support: David Dawes <dawes@xfree86.org>
33 * 852GM/855GM/865G support added by David Dawes <dawes@xfree86.org>
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/malloc.h>
41 #include <sys/kernel.h>
46 #include <bus/pci/pcivar.h>
47 #include <bus/pci/pcireg.h>
52 #include <vm/vm_object.h>
53 #include <vm/vm_page.h>
54 #include <vm/vm_pageout.h>
57 #include <machine/md_var.h>
59 #define bus_read_1(r, o) \
60 bus_space_read_1((r)->r_bustag, (r)->r_bushandle, (o))
61 #define bus_read_4(r, o) \
62 bus_space_read_4((r)->r_bustag, (r)->r_bushandle, (o))
63 #define bus_write_4(r, o, v) \
64 bus_space_write_4((r)->r_bustag, (r)->r_bushandle, (o), (v))
66 MALLOC_DECLARE(M_AGP
);
69 CHIP_I810
, /* i810/i815 */
70 CHIP_I830
, /* 830M/845G */
71 CHIP_I855
, /* 852GM/855GM/865G */
72 CHIP_I915
, /* 915G/915GM */
74 CHIP_G33
, /* G33/Q33/Q35 */
77 /* The i810 through i855 have the registers at BAR 1, and the GATT gets
78 * allocated by us. The i915 has registers in BAR 0 and the GATT is at the
79 * start of the stolen memory, and should only be accessed by the OS through
80 * BAR 3. The G965 has registers and GATT in the same BAR (0) -- first 512KB
81 * is registers, second 512KB is GATT.
83 static struct resource_spec agp_i810_res_spec
[] = {
84 { SYS_RES_MEMORY
, AGP_I810_MMADR
, RF_ACTIVE
| RF_SHAREABLE
},
88 static struct resource_spec agp_i915_res_spec
[] = {
89 { SYS_RES_MEMORY
, AGP_I915_MMADR
, RF_ACTIVE
| RF_SHAREABLE
},
90 { SYS_RES_MEMORY
, AGP_I915_GTTADR
, RF_ACTIVE
| RF_SHAREABLE
},
94 static struct resource_spec agp_i965_res_spec
[] = {
95 { SYS_RES_MEMORY
, AGP_I965_GTTMMADR
, RF_ACTIVE
| RF_SHAREABLE
},
99 struct agp_i810_softc
{
100 struct agp_softc agp
;
101 u_int32_t initial_aperture
; /* aperture size at startup */
102 struct agp_gatt
*gatt
;
103 int chiptype
; /* i810-like or i830 */
104 u_int32_t dcache_size
; /* i810 only */
105 u_int32_t stolen
; /* number of i830/845 gtt entries for stolen memory */
106 device_t bdev
; /* bridge device */
108 void *argb_cursor
; /* contigmalloc area for ARGB cursor */
110 struct resource_spec
* sc_res_spec
;
111 struct resource
*sc_res
[2];
114 /* For adding new devices, devid is the id of the graphics controller
115 * (pci:0:2:0, for example). The placeholder (usually at pci:0:2:1) for the
116 * second head should never be added. The bridge_offset is the offset to
117 * subtract from devid to get the id of the hostb that the device is on.
119 static const struct agp_i810_match
{
124 } agp_i810_matches
[] = {
125 {0x71218086, CHIP_I810
, 0x00010000,
126 "Intel 82810 (i810 GMCH) SVGA controller"},
127 {0x71238086, CHIP_I810
, 0x00010000,
128 "Intel 82810-DC100 (i810-DC100 GMCH) SVGA controller"},
129 {0x71258086, CHIP_I810
, 0x00010000,
130 "Intel 82810E (i810E GMCH) SVGA controller"},
131 {0x11328086, CHIP_I810
, 0x00020000,
132 "Intel 82815 (i815 GMCH) SVGA controller"},
133 {0x35778086, CHIP_I830
, 0x00020000,
134 "Intel 82830M (830M GMCH) SVGA controller"},
135 {0x25628086, CHIP_I830
, 0x00020000,
136 "Intel 82845M (845M GMCH) SVGA controller"},
137 {0x35828086, CHIP_I855
, 0x00020000,
139 {0x25728086, CHIP_I855
, 0x00020000,
140 "Intel 82865G (865G GMCH) SVGA controller"},
141 {0x25828086, CHIP_I915
, 0x00020000,
142 "Intel 82915G (915G GMCH) SVGA controller"},
143 {0x258A8086, CHIP_I915
, 0x00020000,
144 "Intel E7221 SVGA controller"},
145 {0x25928086, CHIP_I915
, 0x00020000,
146 "Intel 82915GM (915GM GMCH) SVGA controller"},
147 {0x27728086, CHIP_I915
, 0x00020000,
148 "Intel 82945G (945G GMCH) SVGA controller"},
149 {0x27A28086, CHIP_I915
, 0x00020000,
150 "Intel 82945GM (945GM GMCH) SVGA controller"},
151 {0x27AE8086, CHIP_I915
, 0x00020000,
152 "Intel 945GME SVGA controller"},
153 {0x29728086, CHIP_I965
, 0x00020000,
154 "Intel 946GZ SVGA controller"},
155 {0x29828086, CHIP_I965
, 0x00020000,
156 "Intel G965 SVGA controller"},
157 {0x29928086, CHIP_I965
, 0x00020000,
158 "Intel Q965 SVGA controller"},
159 {0x29a28086, CHIP_I965
, 0x00020000,
160 "Intel G965 SVGA controller"},
161 {0x29b28086, CHIP_G33
, 0x00020000,
162 "Intel Q35 SVGA controller"},
163 {0x29c28086, CHIP_G33
, 0x00020000,
164 "Intel G33 SVGA controller"},
165 {0x29d28086, CHIP_G33
, 0x00020000,
166 "Intel Q33 SVGA controller"},
167 {0x2a028086, CHIP_I965
, 0x00020000,
168 "Intel GM965 SVGA controller"},
169 {0x2a128086, CHIP_I965
, 0x00020000,
170 "Intel GME965 SVGA controller"},
174 static const struct agp_i810_match
*
175 agp_i810_match(device_t dev
)
179 if (pci_get_class(dev
) != PCIC_DISPLAY
180 || pci_get_subclass(dev
) != PCIS_DISPLAY_VGA
)
183 devid
= pci_get_devid(dev
);
184 for (i
= 0; agp_i810_matches
[i
].devid
!= 0; i
++) {
185 if (agp_i810_matches
[i
].devid
== devid
)
188 if (agp_i810_matches
[i
].devid
== 0)
191 return &agp_i810_matches
[i
];
195 * Find bridge device.
198 agp_i810_find_bridge(device_t dev
)
200 device_t
*children
, child
;
203 const struct agp_i810_match
*match
;
205 match
= agp_i810_match(dev
);
206 devid
= match
->devid
- match
->bridge_offset
;
208 if (device_get_children(device_get_parent(dev
), &children
, &nchildren
))
211 for (i
= 0; i
< nchildren
; i
++) {
214 if (pci_get_devid(child
) == devid
) {
215 kfree(children
, M_TEMP
);
219 kfree(children
, M_TEMP
);
224 agp_i810_identify(driver_t
*driver
, device_t parent
)
227 if (device_find_child(parent
, "agp", -1) == NULL
&&
228 agp_i810_match(parent
))
229 device_add_child(parent
, "agp", -1);
233 agp_i810_probe(device_t dev
)
236 const struct agp_i810_match
*match
;
240 if (resource_disabled("agp", device_get_unit(dev
)))
242 match
= agp_i810_match(dev
);
246 bdev
= agp_i810_find_bridge(dev
);
249 kprintf("I810: can't find bridge device\n");
254 * checking whether internal graphics device has been activated.
256 switch (match
->chiptype
) {
258 smram
= pci_read_config(bdev
, AGP_I810_SMRAM
, 1);
259 if ((smram
& AGP_I810_SMRAM_GMS
) ==
260 AGP_I810_SMRAM_GMS_DISABLED
) {
262 kprintf("I810: disabled, not probing\n");
268 gcc1
= pci_read_config(bdev
, AGP_I830_GCC1
, 1);
269 if ((gcc1
& AGP_I830_GCC1_DEV2
) ==
270 AGP_I830_GCC1_DEV2_DISABLED
) {
272 kprintf("I830: disabled, not probing\n");
279 deven
= pci_read_config(bdev
, AGP_I915_DEVEN
, 4);
280 if ((deven
& AGP_I915_DEVEN_D2F0
) ==
281 AGP_I915_DEVEN_D2F0_DISABLED
) {
283 kprintf("I915: disabled, not probing\n");
290 if (match
->devid
== 0x35828086) {
291 switch (pci_read_config(dev
, AGP_I85X_CAPID
, 1)) {
294 "Intel 82855GME (855GME GMCH) SVGA controller");
298 "Intel 82855GM (855GM GMCH) SVGA controller");
302 "Intel 82852GME (852GME GMCH) SVGA controller");
306 "Intel 82852GM (852GM GMCH) SVGA controller");
310 "Intel 8285xM (85xGM GMCH) SVGA controller");
314 device_set_desc(dev
, match
->name
);
317 return BUS_PROBE_DEFAULT
;
321 agp_i810_dump_regs(device_t dev
)
323 struct agp_i810_softc
*sc
= device_get_softc(dev
);
325 device_printf(dev
, "AGP_I810_PGTBL_CTL: %08x\n",
326 bus_read_4(sc
->sc_res
[0], AGP_I810_PGTBL_CTL
));
328 switch (sc
->chiptype
) {
330 device_printf(dev
, "AGP_I810_MISCC: 0x%04x\n",
331 pci_read_config(sc
->bdev
, AGP_I810_MISCC
, 2));
334 device_printf(dev
, "AGP_I830_GCC1: 0x%02x\n",
335 pci_read_config(sc
->bdev
, AGP_I830_GCC1
, 1));
338 device_printf(dev
, "AGP_I855_GCC1: 0x%02x\n",
339 pci_read_config(sc
->bdev
, AGP_I855_GCC1
, 1));
344 device_printf(dev
, "AGP_I855_GCC1: 0x%02x\n",
345 pci_read_config(sc
->bdev
, AGP_I855_GCC1
, 1));
346 device_printf(dev
, "AGP_I915_MSAC: 0x%02x\n",
347 pci_read_config(sc
->bdev
, AGP_I915_MSAC
, 1));
350 device_printf(dev
, "Aperture resource size: %d bytes\n",
351 AGP_GET_APERTURE(dev
));
355 agp_i810_attach(device_t dev
)
357 struct agp_i810_softc
*sc
= device_get_softc(dev
);
358 struct agp_gatt
*gatt
;
359 const struct agp_i810_match
*match
;
362 sc
->bdev
= agp_i810_find_bridge(dev
);
366 match
= agp_i810_match(dev
);
367 sc
->chiptype
= match
->chiptype
;
369 switch (sc
->chiptype
) {
373 sc
->sc_res_spec
= agp_i810_res_spec
;
374 agp_set_aperture_resource(dev
, AGP_APBASE
);
378 sc
->sc_res_spec
= agp_i915_res_spec
;
379 agp_set_aperture_resource(dev
, AGP_I915_GMADR
);
382 sc
->sc_res_spec
= agp_i965_res_spec
;
383 agp_set_aperture_resource(dev
, AGP_I915_GMADR
);
387 error
= agp_generic_attach(dev
);
391 if (sc
->chiptype
!= CHIP_I965
&& sc
->chiptype
!= CHIP_G33
&&
392 ptoa((vm_paddr_t
)Maxmem
) > 0xfffffffful
)
394 device_printf(dev
, "agp_i810.c does not support physical "
395 "memory above 4GB.\n");
399 if (bus_alloc_resources(dev
, sc
->sc_res_spec
, sc
->sc_res
)) {
400 agp_generic_detach(dev
);
404 sc
->initial_aperture
= AGP_GET_APERTURE(dev
);
405 if (sc
->initial_aperture
== 0) {
406 device_printf(dev
, "bad initial aperture size, disabling\n");
410 gatt
= kmalloc( sizeof(struct agp_gatt
), M_AGP
, M_INTWAIT
);
413 gatt
->ag_entries
= AGP_GET_APERTURE(dev
) >> AGP_PAGE_SHIFT
;
415 if ( sc
->chiptype
== CHIP_I810
) {
416 /* Some i810s have on-chip memory called dcache */
417 if (bus_read_1(sc
->sc_res
[0], AGP_I810_DRT
) &
418 AGP_I810_DRT_POPULATED
)
419 sc
->dcache_size
= 4 * 1024 * 1024;
423 /* According to the specs the gatt on the i810 must be 64k */
424 gatt
->ag_virtual
= contigmalloc( 64 * 1024, M_AGP
, 0,
425 0, ~0, PAGE_SIZE
, 0);
426 if (!gatt
->ag_virtual
) {
428 device_printf(dev
, "contiguous allocation failed\n");
429 bus_release_resources(dev
, sc
->sc_res_spec
,
432 agp_generic_detach(dev
);
435 bzero(gatt
->ag_virtual
, gatt
->ag_entries
* sizeof(u_int32_t
));
437 gatt
->ag_physical
= vtophys((vm_offset_t
) gatt
->ag_virtual
);
439 /* Install the GATT. */
440 bus_write_4(sc
->sc_res
[0], AGP_I810_PGTBL_CTL
,
441 gatt
->ag_physical
| 1);
442 } else if ( sc
->chiptype
== CHIP_I830
) {
443 /* The i830 automatically initializes the 128k gatt on boot. */
444 unsigned int gcc1
, pgtblctl
;
446 gcc1
= pci_read_config(sc
->bdev
, AGP_I830_GCC1
, 1);
447 switch (gcc1
& AGP_I830_GCC1_GMS
) {
448 case AGP_I830_GCC1_GMS_STOLEN_512
:
449 sc
->stolen
= (512 - 132) * 1024 / 4096;
451 case AGP_I830_GCC1_GMS_STOLEN_1024
:
452 sc
->stolen
= (1024 - 132) * 1024 / 4096;
454 case AGP_I830_GCC1_GMS_STOLEN_8192
:
455 sc
->stolen
= (8192 - 132) * 1024 / 4096;
459 device_printf(dev
, "unknown memory configuration, disabling\n");
460 bus_release_resources(dev
, sc
->sc_res_spec
,
463 agp_generic_detach(dev
);
466 if (sc
->stolen
> 0) {
467 device_printf(dev
, "detected %dk stolen memory\n",
470 device_printf(dev
, "aperture size is %dM\n",
471 sc
->initial_aperture
/ 1024 / 1024);
473 /* GATT address is already in there, make sure it's enabled */
474 pgtblctl
= bus_read_4(sc
->sc_res
[0], AGP_I810_PGTBL_CTL
);
476 bus_write_4(sc
->sc_res
[0], AGP_I810_PGTBL_CTL
, pgtblctl
);
478 gatt
->ag_physical
= pgtblctl
& ~1;
479 } else if (sc
->chiptype
== CHIP_I855
|| sc
->chiptype
== CHIP_I915
||
480 sc
->chiptype
== CHIP_I965
|| sc
->chiptype
== CHIP_G33
) {
481 unsigned int gcc1
, pgtblctl
, stolen
, gtt_size
;
483 /* Stolen memory is set up at the beginning of the aperture by
484 * the BIOS, consisting of the GATT followed by 4kb for the
487 switch (sc
->chiptype
) {
496 switch (bus_read_4(sc
->sc_res
[0], AGP_I810_PGTBL_CTL
) &
497 AGP_I810_PGTBL_SIZE_MASK
) {
498 case AGP_I810_PGTBL_SIZE_128KB
:
501 case AGP_I810_PGTBL_SIZE_256KB
:
504 case AGP_I810_PGTBL_SIZE_512KB
:
508 device_printf(dev
, "Bad PGTBL size\n");
509 bus_release_resources(dev
, sc
->sc_res_spec
,
512 agp_generic_detach(dev
);
517 device_printf(dev
, "Bad chiptype\n");
518 bus_release_resources(dev
, sc
->sc_res_spec
,
521 agp_generic_detach(dev
);
525 /* GCC1 is called MGGC on i915+ */
526 gcc1
= pci_read_config(sc
->bdev
, AGP_I855_GCC1
, 1);
527 switch (gcc1
& AGP_I855_GCC1_GMS
) {
528 case AGP_I855_GCC1_GMS_STOLEN_1M
:
531 case AGP_I855_GCC1_GMS_STOLEN_4M
:
534 case AGP_I855_GCC1_GMS_STOLEN_8M
:
537 case AGP_I855_GCC1_GMS_STOLEN_16M
:
540 case AGP_I855_GCC1_GMS_STOLEN_32M
:
543 case AGP_I915_GCC1_GMS_STOLEN_48M
:
546 case AGP_I915_GCC1_GMS_STOLEN_64M
:
549 case AGP_G33_GCC1_GMS_STOLEN_128M
:
552 case AGP_G33_GCC1_GMS_STOLEN_256M
:
556 device_printf(dev
, "unknown memory configuration, "
558 bus_release_resources(dev
, sc
->sc_res_spec
,
561 agp_generic_detach(dev
);
564 sc
->stolen
= (stolen
- gtt_size
- 4) * 1024 / 4096;
566 device_printf(dev
, "detected %dk stolen memory\n", sc
->stolen
* 4);
567 device_printf(dev
, "aperture size is %dM\n", sc
->initial_aperture
/ 1024 / 1024);
569 /* GATT address is already in there, make sure it's enabled */
570 pgtblctl
= bus_read_4(sc
->sc_res
[0], AGP_I810_PGTBL_CTL
);
572 bus_write_4(sc
->sc_res
[0], AGP_I810_PGTBL_CTL
, pgtblctl
);
574 gatt
->ag_physical
= pgtblctl
& ~1;
577 /* Add a device for the drm to attach to */
578 /* XXX This will go away once we have vgapci */
579 if (!device_add_child(dev
, "drmsub", -1))
580 device_printf(dev
, "could not add drm subdevice\n");
583 agp_i810_dump_regs(dev
);
589 agp_i810_detach(device_t dev
)
591 struct agp_i810_softc
*sc
= device_get_softc(dev
);
596 /* Clear the GATT base. */
597 if ( sc
->chiptype
== CHIP_I810
) {
598 bus_write_4(sc
->sc_res
[0], AGP_I810_PGTBL_CTL
, 0);
600 unsigned int pgtblctl
;
601 pgtblctl
= bus_read_4(sc
->sc_res
[0], AGP_I810_PGTBL_CTL
);
603 bus_write_4(sc
->sc_res
[0], AGP_I810_PGTBL_CTL
, pgtblctl
);
606 /* Put the aperture back the way it started. */
607 AGP_SET_APERTURE(dev
, sc
->initial_aperture
);
609 if ( sc
->chiptype
== CHIP_I810
) {
610 contigfree(sc
->gatt
->ag_virtual
, 64 * 1024, M_AGP
);
612 kfree(sc
->gatt
, M_AGP
);
614 bus_release_resources(dev
, sc
->sc_res_spec
, sc
->sc_res
);
617 /* XXX This will go away once we have vgapci */
618 child
= device_find_child(dev
, "drmsub", 0);
620 device_delete_child(dev
, child
);
626 agp_i810_resume(device_t dev
)
628 struct agp_i810_softc
*sc
;
629 sc
= device_get_softc(dev
);
631 AGP_SET_APERTURE(dev
, sc
->initial_aperture
);
633 /* Install the GATT. */
634 bus_write_4(sc
->sc_res
[0], AGP_I810_PGTBL_CTL
,
635 sc
->gatt
->ag_physical
| 1);
637 return (bus_generic_resume(dev
));
641 * Sets the PCI resource size of the aperture on i830-class and below chipsets,
642 * while returning failure on later chipsets when an actual change is
645 * This whole function is likely bogus, as the kernel would probably need to
646 * reconfigure the placement of the AGP aperture if a larger size is requested,
647 * which doesn't happen currently.
650 agp_i810_set_aperture(device_t dev
, u_int32_t aperture
)
652 struct agp_i810_softc
*sc
= device_get_softc(dev
);
653 u_int16_t miscc
, gcc1
;
655 switch (sc
->chiptype
) {
658 * Double check for sanity.
660 if (aperture
!= 32 * 1024 * 1024 && aperture
!= 64 * 1024 * 1024) {
661 device_printf(dev
, "bad aperture size %d\n", aperture
);
665 miscc
= pci_read_config(sc
->bdev
, AGP_I810_MISCC
, 2);
666 miscc
&= ~AGP_I810_MISCC_WINSIZE
;
667 if (aperture
== 32 * 1024 * 1024)
668 miscc
|= AGP_I810_MISCC_WINSIZE_32
;
670 miscc
|= AGP_I810_MISCC_WINSIZE_64
;
672 pci_write_config(sc
->bdev
, AGP_I810_MISCC
, miscc
, 2);
675 if (aperture
!= 64 * 1024 * 1024 &&
676 aperture
!= 128 * 1024 * 1024) {
677 device_printf(dev
, "bad aperture size %d\n", aperture
);
680 gcc1
= pci_read_config(sc
->bdev
, AGP_I830_GCC1
, 2);
681 gcc1
&= ~AGP_I830_GCC1_GMASIZE
;
682 if (aperture
== 64 * 1024 * 1024)
683 gcc1
|= AGP_I830_GCC1_GMASIZE_64
;
685 gcc1
|= AGP_I830_GCC1_GMASIZE_128
;
687 pci_write_config(sc
->bdev
, AGP_I830_GCC1
, gcc1
, 2);
693 return agp_generic_set_aperture(dev
, aperture
);
700 * Writes a GTT entry mapping the page at the given offset from the beginning
701 * of the aperture to the given physical address.
704 agp_i810_write_gtt_entry(device_t dev
, int offset
, vm_offset_t physical
,
707 struct agp_i810_softc
*sc
= device_get_softc(dev
);
710 pte
= (u_int32_t
)physical
| 1;
711 if (sc
->chiptype
== CHIP_I965
|| sc
->chiptype
== CHIP_G33
) {
712 pte
|= (physical
& 0x0000000f00000000ull
) >> 28;
714 /* If we do actually have memory above 4GB on an older system,
715 * crash cleanly rather than scribble on system memory,
716 * so we know we need to fix it.
718 KASSERT((pte
& 0x0000000f00000000ull
) == 0,
719 (">4GB physical address in agp"));
722 switch (sc
->chiptype
) {
726 bus_write_4(sc
->sc_res
[0],
727 AGP_I810_GTT
+ (offset
>> AGP_PAGE_SHIFT
) * 4, pte
);
731 bus_write_4(sc
->sc_res
[1],
732 (offset
>> AGP_PAGE_SHIFT
) * 4, pte
);
735 bus_write_4(sc
->sc_res
[0],
736 (offset
>> AGP_PAGE_SHIFT
) * 4 + (512 * 1024), pte
);
742 agp_i810_bind_page(device_t dev
, int offset
, vm_offset_t physical
)
744 struct agp_i810_softc
*sc
= device_get_softc(dev
);
746 if (offset
< 0 || offset
>= (sc
->gatt
->ag_entries
<< AGP_PAGE_SHIFT
)) {
747 device_printf(dev
, "failed: offset is 0x%08x, shift is %d, entries is %d\n", offset
, AGP_PAGE_SHIFT
, sc
->gatt
->ag_entries
);
751 if ( sc
->chiptype
!= CHIP_I810
) {
752 if ( (offset
>> AGP_PAGE_SHIFT
) < sc
->stolen
) {
753 device_printf(dev
, "trying to bind into stolen memory");
758 agp_i810_write_gtt_entry(dev
, offset
, physical
, 1);
764 agp_i810_unbind_page(device_t dev
, int offset
)
766 struct agp_i810_softc
*sc
= device_get_softc(dev
);
768 if (offset
< 0 || offset
>= (sc
->gatt
->ag_entries
<< AGP_PAGE_SHIFT
))
771 if ( sc
->chiptype
!= CHIP_I810
) {
772 if ( (offset
>> AGP_PAGE_SHIFT
) < sc
->stolen
) {
773 device_printf(dev
, "trying to unbind from stolen memory");
778 agp_i810_write_gtt_entry(dev
, offset
, 0, 0);
784 * Writing via memory mapped registers already flushes all TLBs.
787 agp_i810_flush_tlb(device_t dev
)
792 agp_i810_enable(device_t dev
, u_int32_t mode
)
798 static struct agp_memory
*
799 agp_i810_alloc_memory(device_t dev
, int type
, vm_size_t size
)
801 struct agp_i810_softc
*sc
= device_get_softc(dev
);
802 struct agp_memory
*mem
;
804 if ((size
& (AGP_PAGE_SIZE
- 1)) != 0)
807 if (sc
->agp
.as_allocated
+ size
> sc
->agp
.as_maxmem
)
812 * Mapping local DRAM into GATT.
814 if ( sc
->chiptype
!= CHIP_I810
)
816 if (size
!= sc
->dcache_size
)
818 } else if (type
== 2) {
820 * Type 2 is the contiguous physical memory type, that hands
821 * back a physical address. This is used for cursors on i810.
822 * Hand back as many single pages with physical as the user
823 * wants, but only allow one larger allocation (ARGB cursor)
826 if (size
!= AGP_PAGE_SIZE
) {
827 if (sc
->argb_cursor
!= NULL
)
830 /* Allocate memory for ARGB cursor, if we can. */
831 sc
->argb_cursor
= contigmalloc(size
, M_AGP
,
832 0, 0, ~0, PAGE_SIZE
, 0);
833 if (sc
->argb_cursor
== NULL
)
838 mem
= kmalloc(sizeof *mem
, M_AGP
, M_INTWAIT
);
839 mem
->am_id
= sc
->agp
.as_nextid
++;
842 if (type
!= 1 && (type
!= 2 || size
== AGP_PAGE_SIZE
))
843 mem
->am_obj
= vm_object_allocate(OBJT_DEFAULT
,
844 atop(round_page(size
)));
849 if (size
== AGP_PAGE_SIZE
) {
851 * Allocate and wire down the page now so that we can
852 * get its physical address.
856 m
= vm_page_grab(mem
->am_obj
, 0,
857 VM_ALLOC_NORMAL
|VM_ALLOC_ZERO
|VM_ALLOC_RETRY
);
858 if ((m
->flags
& PG_ZERO
) == 0)
859 vm_page_zero_fill(m
);
861 mem
->am_physical
= VM_PAGE_TO_PHYS(m
);
864 /* Our allocation is already nicely wired down for us.
865 * Just grab the physical address.
867 mem
->am_physical
= vtophys(sc
->argb_cursor
);
870 mem
->am_physical
= 0;
874 mem
->am_is_bound
= 0;
875 TAILQ_INSERT_TAIL(&sc
->agp
.as_memory
, mem
, am_link
);
876 sc
->agp
.as_allocated
+= size
;
882 agp_i810_free_memory(device_t dev
, struct agp_memory
*mem
)
884 struct agp_i810_softc
*sc
= device_get_softc(dev
);
886 if (mem
->am_is_bound
)
889 if (mem
->am_type
== 2) {
890 if (mem
->am_size
== AGP_PAGE_SIZE
) {
892 * Unwire the page which we wired in alloc_memory.
894 vm_page_t m
= vm_page_lookup(mem
->am_obj
, 0);
895 vm_page_unwire(m
, 0);
897 contigfree(sc
->argb_cursor
, mem
->am_size
, M_AGP
);
898 sc
->argb_cursor
= NULL
;
902 sc
->agp
.as_allocated
-= mem
->am_size
;
903 TAILQ_REMOVE(&sc
->agp
.as_memory
, mem
, am_link
);
905 vm_object_deallocate(mem
->am_obj
);
911 agp_i810_bind_memory(device_t dev
, struct agp_memory
*mem
,
914 struct agp_i810_softc
*sc
= device_get_softc(dev
);
917 /* Do some sanity checks first. */
918 if (offset
< 0 || (offset
& (AGP_PAGE_SIZE
- 1)) != 0 ||
919 offset
+ mem
->am_size
> AGP_GET_APERTURE(dev
)) {
920 device_printf(dev
, "binding memory at bad offset %#x\n",
925 if (mem
->am_type
== 2 && mem
->am_size
!= AGP_PAGE_SIZE
) {
926 lockmgr(&sc
->agp
.as_lock
, LK_EXCLUSIVE
);
927 if (mem
->am_is_bound
) {
928 lockmgr(&sc
->agp
.as_lock
, LK_RELEASE
);
931 /* The memory's already wired down, just stick it in the GTT. */
932 for (i
= 0; i
< mem
->am_size
; i
+= AGP_PAGE_SIZE
) {
933 agp_i810_write_gtt_entry(dev
, offset
+ i
,
934 mem
->am_physical
+ i
, 1);
937 mem
->am_offset
= offset
;
938 mem
->am_is_bound
= 1;
939 lockmgr(&sc
->agp
.as_lock
, LK_RELEASE
);
943 if (mem
->am_type
!= 1)
944 return agp_generic_bind_memory(dev
, mem
, offset
);
946 if ( sc
->chiptype
!= CHIP_I810
)
949 for (i
= 0; i
< mem
->am_size
; i
+= AGP_PAGE_SIZE
) {
950 bus_write_4(sc
->sc_res
[0],
951 AGP_I810_GTT
+ (i
>> AGP_PAGE_SHIFT
) * 4, i
| 3);
958 agp_i810_unbind_memory(device_t dev
, struct agp_memory
*mem
)
960 struct agp_i810_softc
*sc
= device_get_softc(dev
);
963 if (mem
->am_type
== 2 && mem
->am_size
!= AGP_PAGE_SIZE
) {
964 lockmgr(&sc
->agp
.as_lock
, LK_EXCLUSIVE
);
965 if (!mem
->am_is_bound
) {
966 lockmgr(&sc
->agp
.as_lock
, LK_RELEASE
);
970 for (i
= 0; i
< mem
->am_size
; i
+= AGP_PAGE_SIZE
) {
971 agp_i810_write_gtt_entry(dev
, mem
->am_offset
+ i
,
975 mem
->am_is_bound
= 0;
976 lockmgr(&sc
->agp
.as_lock
, LK_RELEASE
);
980 if (mem
->am_type
!= 1)
981 return agp_generic_unbind_memory(dev
, mem
);
983 if ( sc
->chiptype
!= CHIP_I810
)
986 for (i
= 0; i
< mem
->am_size
; i
+= AGP_PAGE_SIZE
) {
987 bus_write_4(sc
->sc_res
[0],
988 AGP_I810_GTT
+ (i
>> AGP_PAGE_SHIFT
) * 4, 0);
994 static device_method_t agp_i810_methods
[] = {
995 /* Device interface */
996 DEVMETHOD(device_identify
, agp_i810_identify
),
997 DEVMETHOD(device_probe
, agp_i810_probe
),
998 DEVMETHOD(device_attach
, agp_i810_attach
),
999 DEVMETHOD(device_detach
, agp_i810_detach
),
1000 DEVMETHOD(device_suspend
, bus_generic_suspend
),
1001 DEVMETHOD(device_resume
, agp_i810_resume
),
1004 DEVMETHOD(agp_get_aperture
, agp_generic_get_aperture
),
1005 DEVMETHOD(agp_set_aperture
, agp_i810_set_aperture
),
1006 DEVMETHOD(agp_bind_page
, agp_i810_bind_page
),
1007 DEVMETHOD(agp_unbind_page
, agp_i810_unbind_page
),
1008 DEVMETHOD(agp_flush_tlb
, agp_i810_flush_tlb
),
1009 DEVMETHOD(agp_enable
, agp_i810_enable
),
1010 DEVMETHOD(agp_alloc_memory
, agp_i810_alloc_memory
),
1011 DEVMETHOD(agp_free_memory
, agp_i810_free_memory
),
1012 DEVMETHOD(agp_bind_memory
, agp_i810_bind_memory
),
1013 DEVMETHOD(agp_unbind_memory
, agp_i810_unbind_memory
),
1018 static driver_t agp_i810_driver
= {
1021 sizeof(struct agp_i810_softc
),
1024 static devclass_t agp_devclass
;
1026 DRIVER_MODULE(agp_i810
, pci
, agp_i810_driver
, agp_devclass
, 0, 0);
1027 MODULE_DEPEND(agp_i810
, agp
, 1, 1, 1);
1028 MODULE_DEPEND(agp_i810
, pci
, 1, 1, 1);