1 /* $NetBSD: agp_i810.c,v 1.64 2009/05/04 11:05:45 markd Exp $ */
4 * Copyright (c) 2000 Doug Rabson
5 * Copyright (c) 2000 Ruslan Ermilov
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * $FreeBSD: src/sys/pci/agp_i810.c,v 1.4 2001/07/05 21:28:47 jhb Exp $
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.64 2009/05/04 11:05:45 markd Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/malloc.h>
38 #include <sys/kernel.h>
40 #include <sys/device.h>
43 #include <uvm/uvm_extern.h>
45 #include <dev/pci/pcivar.h>
46 #include <dev/pci/pcireg.h>
47 #include <dev/pci/pcidevs.h>
48 #include <dev/pci/agpvar.h>
49 #include <dev/pci/agpreg.h>
51 #include <sys/agpio.h>
55 #include "agp_intel.h"
57 #define READ1(off) bus_space_read_1(isc->bst, isc->bsh, off)
58 #define READ4(off) bus_space_read_4(isc->bst, isc->bsh, off)
59 #define WRITE4(off,v) bus_space_write_4(isc->bst, isc->bsh, off, v)
61 #define CHIP_I810 0 /* i810/i815 */
62 #define CHIP_I830 1 /* 830M/845G */
63 #define CHIP_I855 2 /* 852GM/855GM/865G */
64 #define CHIP_I915 3 /* 915G/915GM/945G/945GM/945GME */
65 #define CHIP_I965 4 /* 965Q/965PM */
66 #define CHIP_G33 5 /* G33/Q33/Q35 */
67 #define CHIP_G4X 6 /* G45/Q45 */
69 struct agp_i810_softc
{
70 u_int32_t initial_aperture
; /* aperture size at startup */
71 struct agp_gatt
*gatt
;
72 int chiptype
; /* i810-like or i830 */
73 u_int32_t dcache_size
; /* i810 only */
74 u_int32_t stolen
; /* number of i830/845 gtt entries
76 bus_space_tag_t bst
; /* register bus_space tag */
77 bus_space_handle_t bsh
; /* register bus_space handle */
78 bus_space_tag_t gtt_bst
; /* GTT bus_space tag */
79 bus_space_handle_t gtt_bsh
; /* GTT bus_space handle */
80 struct pci_attach_args vga_pa
;
85 /* XXX hack, see below */
86 static bus_addr_t agp_i810_vga_regbase
;
87 static bus_space_handle_t agp_i810_vga_bsh
;
89 static u_int32_t
agp_i810_get_aperture(struct agp_softc
*);
90 static int agp_i810_set_aperture(struct agp_softc
*, u_int32_t
);
91 static int agp_i810_bind_page(struct agp_softc
*, off_t
, bus_addr_t
);
92 static int agp_i810_unbind_page(struct agp_softc
*, off_t
);
93 static void agp_i810_flush_tlb(struct agp_softc
*);
94 static int agp_i810_enable(struct agp_softc
*, u_int32_t mode
);
95 static struct agp_memory
*agp_i810_alloc_memory(struct agp_softc
*, int,
97 static int agp_i810_free_memory(struct agp_softc
*, struct agp_memory
*);
98 static int agp_i810_bind_memory(struct agp_softc
*, struct agp_memory
*, off_t
);
99 static int agp_i810_unbind_memory(struct agp_softc
*, struct agp_memory
*);
101 static bool agp_i810_resume(device_t
, pmf_qual_t
);
102 static int agp_i810_init(struct agp_softc
*);
104 static int agp_i810_init(struct agp_softc
*);
105 static void agp_i810_write_gtt_entry(struct agp_i810_softc
*, off_t
,
108 static struct agp_methods agp_i810_methods
= {
109 agp_i810_get_aperture
,
110 agp_i810_set_aperture
,
112 agp_i810_unbind_page
,
115 agp_i810_alloc_memory
,
116 agp_i810_free_memory
,
117 agp_i810_bind_memory
,
118 agp_i810_unbind_memory
,
122 agp_i810_write_gtt_entry(struct agp_i810_softc
*isc
, off_t off
, u_int32_t v
)
128 switch (isc
->chiptype
) {
132 base_off
= AGP_I810_GTT
;
135 base_off
= AGP_I965_GTT
;
138 base_off
= AGP_G4X_GTT
;
142 bus_space_write_4(isc
->gtt_bst
, isc
->gtt_bsh
,
143 (u_int32_t
)((off
) >> AGP_PAGE_SHIFT
) * 4, (v
));
147 WRITE4(base_off
+ (u_int32_t
)(off
>> AGP_PAGE_SHIFT
) * 4, v
);
150 /* XXXthorpej -- duplicated code (see arch/x86/pci/pchb.c) */
152 agp_i810_vgamatch(struct pci_attach_args
*pa
)
155 if (PCI_CLASS(pa
->pa_class
) != PCI_CLASS_DISPLAY
||
156 PCI_SUBCLASS(pa
->pa_class
) != PCI_SUBCLASS_DISPLAY_VGA
)
159 switch (PCI_PRODUCT(pa
->pa_id
)) {
160 case PCI_PRODUCT_INTEL_82810_GC
:
161 case PCI_PRODUCT_INTEL_82810_DC100_GC
:
162 case PCI_PRODUCT_INTEL_82810E_GC
:
163 case PCI_PRODUCT_INTEL_82815_FULL_GRAPH
:
164 case PCI_PRODUCT_INTEL_82830MP_IV
:
165 case PCI_PRODUCT_INTEL_82845G_IGD
:
166 case PCI_PRODUCT_INTEL_82855GM_IGD
:
167 case PCI_PRODUCT_INTEL_82865_IGD
:
168 case PCI_PRODUCT_INTEL_82915G_IGD
:
169 case PCI_PRODUCT_INTEL_82915GM_IGD
:
170 case PCI_PRODUCT_INTEL_82945P_IGD
:
171 case PCI_PRODUCT_INTEL_82945GM_IGD
:
172 case PCI_PRODUCT_INTEL_82945GM_IGD_1
:
173 case PCI_PRODUCT_INTEL_82945GME_IGD
:
174 case PCI_PRODUCT_INTEL_82965Q_IGD
:
175 case PCI_PRODUCT_INTEL_82965Q_IGD_1
:
176 case PCI_PRODUCT_INTEL_82965PM_IGD
:
177 case PCI_PRODUCT_INTEL_82965PM_IGD_1
:
178 case PCI_PRODUCT_INTEL_82G33_IGD
:
179 case PCI_PRODUCT_INTEL_82G33_IGD_1
:
180 case PCI_PRODUCT_INTEL_82965G_IGD
:
181 case PCI_PRODUCT_INTEL_82965G_IGD_1
:
182 case PCI_PRODUCT_INTEL_82Q35_IGD
:
183 case PCI_PRODUCT_INTEL_82Q35_IGD_1
:
184 case PCI_PRODUCT_INTEL_82Q33_IGD
:
185 case PCI_PRODUCT_INTEL_82Q33_IGD_1
:
186 case PCI_PRODUCT_INTEL_82G35_IGD
:
187 case PCI_PRODUCT_INTEL_82G35_IGD_1
:
188 case PCI_PRODUCT_INTEL_82946GZ_IGD
:
189 case PCI_PRODUCT_INTEL_82GM45_IGD
:
190 case PCI_PRODUCT_INTEL_82GM45_IGD_1
:
191 case PCI_PRODUCT_INTEL_82IGD_E_IGD
:
192 case PCI_PRODUCT_INTEL_82Q45_IGD
:
193 case PCI_PRODUCT_INTEL_82G45_IGD
:
201 agp_i965_map_aperture(struct pci_attach_args
*pa
, struct agp_softc
*sc
, int reg
)
204 * Find the aperture. Don't map it (yet), this would
207 if (pci_mapreg_info(pa
->pa_pc
, pa
->pa_tag
, reg
,
208 PCI_MAPREG_TYPE_MEM
|PCI_MAPREG_MEM_TYPE_64BIT
, &sc
->as_apaddr
, &sc
->as_apsize
,
209 &sc
->as_apflags
) != 0)
212 sc
->as_apt
= pa
->pa_memt
;
218 agp_i810_attach(device_t parent
, device_t self
, void *aux
)
220 struct agp_softc
*sc
= device_private(self
);
221 struct agp_i810_softc
*isc
;
222 struct agp_gatt
*gatt
;
225 bus_size_t mmadrsize
;
227 isc
= malloc(sizeof *isc
, M_AGP
, M_NOWAIT
|M_ZERO
);
229 aprint_error(": can't allocate chipset-specific softc\n");
233 sc
->as_methods
= &agp_i810_methods
;
235 if (pci_find_device(&isc
->vga_pa
, agp_i810_vgamatch
) == 0) {
237 const struct pci_attach_args
*pa
= aux
;
239 switch (PCI_PRODUCT(pa
->pa_id
)) {
240 case PCI_PRODUCT_INTEL_82840_HB
:
241 case PCI_PRODUCT_INTEL_82865_HB
:
242 case PCI_PRODUCT_INTEL_82845G_DRAM
:
243 case PCI_PRODUCT_INTEL_82815_FULL_HUB
:
244 return agp_intel_attach(parent
, self
, aux
);
247 aprint_error(": can't find internal VGA device config space\n");
253 sc
->as_dmat
= isc
->vga_pa
.pa_dmat
;
255 switch (PCI_PRODUCT(isc
->vga_pa
.pa_id
)) {
256 case PCI_PRODUCT_INTEL_82810_GC
:
257 case PCI_PRODUCT_INTEL_82810_DC100_GC
:
258 case PCI_PRODUCT_INTEL_82810E_GC
:
259 case PCI_PRODUCT_INTEL_82815_FULL_GRAPH
:
260 isc
->chiptype
= CHIP_I810
;
262 case PCI_PRODUCT_INTEL_82830MP_IV
:
263 case PCI_PRODUCT_INTEL_82845G_IGD
:
264 isc
->chiptype
= CHIP_I830
;
266 case PCI_PRODUCT_INTEL_82855GM_IGD
:
267 case PCI_PRODUCT_INTEL_82865_IGD
:
268 isc
->chiptype
= CHIP_I855
;
270 case PCI_PRODUCT_INTEL_82915G_IGD
:
271 case PCI_PRODUCT_INTEL_82915GM_IGD
:
272 case PCI_PRODUCT_INTEL_82945P_IGD
:
273 case PCI_PRODUCT_INTEL_82945GM_IGD
:
274 case PCI_PRODUCT_INTEL_82945GM_IGD_1
:
275 case PCI_PRODUCT_INTEL_82945GME_IGD
:
276 isc
->chiptype
= CHIP_I915
;
278 case PCI_PRODUCT_INTEL_82965Q_IGD
:
279 case PCI_PRODUCT_INTEL_82965Q_IGD_1
:
280 case PCI_PRODUCT_INTEL_82965PM_IGD
:
281 case PCI_PRODUCT_INTEL_82965PM_IGD_1
:
282 case PCI_PRODUCT_INTEL_82965G_IGD
:
283 case PCI_PRODUCT_INTEL_82965G_IGD_1
:
284 case PCI_PRODUCT_INTEL_82946GZ_IGD
:
285 case PCI_PRODUCT_INTEL_82G35_IGD
:
286 case PCI_PRODUCT_INTEL_82G35_IGD_1
:
287 isc
->chiptype
= CHIP_I965
;
289 case PCI_PRODUCT_INTEL_82Q35_IGD
:
290 case PCI_PRODUCT_INTEL_82Q35_IGD_1
:
291 case PCI_PRODUCT_INTEL_82G33_IGD
:
292 case PCI_PRODUCT_INTEL_82G33_IGD_1
:
293 case PCI_PRODUCT_INTEL_82Q33_IGD
:
294 case PCI_PRODUCT_INTEL_82Q33_IGD_1
:
295 isc
->chiptype
= CHIP_G33
;
297 case PCI_PRODUCT_INTEL_82GM45_IGD
:
298 case PCI_PRODUCT_INTEL_82GM45_IGD_1
:
299 case PCI_PRODUCT_INTEL_82IGD_E_IGD
:
300 case PCI_PRODUCT_INTEL_82Q45_IGD
:
301 case PCI_PRODUCT_INTEL_82G45_IGD
:
302 isc
->chiptype
= CHIP_G4X
;
306 switch (isc
->chiptype
) {
309 apbase
= AGP_I915_GMADR
;
313 apbase
= AGP_I965_GMADR
;
316 apbase
= AGP_I810_GMADR
;
320 if (isc
->chiptype
== CHIP_I965
|| isc
->chiptype
== CHIP_G4X
) {
321 error
= agp_i965_map_aperture(&isc
->vga_pa
, sc
, apbase
);
323 error
= agp_map_aperture(&isc
->vga_pa
, sc
, apbase
);
326 aprint_error(": can't map aperture\n");
331 if (isc
->chiptype
== CHIP_I915
|| isc
->chiptype
== CHIP_G33
) {
332 error
= pci_mapreg_map(&isc
->vga_pa
, AGP_I915_MMADR
,
333 PCI_MAPREG_TYPE_MEM
, 0, &isc
->bst
, &isc
->bsh
,
336 aprint_error(": can't map mmadr registers\n");
337 agp_generic_detach(sc
);
340 error
= pci_mapreg_map(&isc
->vga_pa
, AGP_I915_GTTADR
,
341 PCI_MAPREG_TYPE_MEM
, 0, &isc
->gtt_bst
, &isc
->gtt_bsh
,
344 aprint_error(": can't map gttadr registers\n");
345 /* XXX we should release mmadr here */
346 agp_generic_detach(sc
);
349 } else if (isc
->chiptype
== CHIP_I965
|| isc
->chiptype
== CHIP_G4X
) {
350 error
= pci_mapreg_map(&isc
->vga_pa
, AGP_I965_MMADR
,
351 PCI_MAPREG_TYPE_MEM
, 0, &isc
->bst
, &isc
->bsh
,
354 aprint_error(": can't map mmadr registers\n");
355 agp_generic_detach(sc
);
359 error
= pci_mapreg_map(&isc
->vga_pa
, AGP_I810_MMADR
,
360 PCI_MAPREG_TYPE_MEM
, 0, &isc
->bst
, &isc
->bsh
,
363 aprint_error(": can't map mmadr registers\n");
364 agp_generic_detach(sc
);
369 isc
->initial_aperture
= AGP_GET_APERTURE(sc
);
371 gatt
= malloc(sizeof(struct agp_gatt
), M_AGP
, M_NOWAIT
);
373 agp_generic_detach(sc
);
378 gatt
->ag_entries
= AGP_GET_APERTURE(sc
) >> AGP_PAGE_SHIFT
;
380 if (!pmf_device_register(self
, NULL
, agp_i810_resume
))
381 aprint_error_dev(self
, "couldn't establish power handler\n");
384 * XXX horrible hack to allow drm code to use our mapping
385 * of VGA chip registers
387 agp_i810_vga_regbase
= mmadr
;
388 agp_i810_vga_bsh
= isc
->bsh
;
390 return agp_i810_init(sc
);
394 * XXX horrible hack to allow drm code to use our mapping
395 * of VGA chip registers
398 agp_i810_borrow(bus_addr_t base
, bus_space_handle_t
*hdlp
)
401 if (!agp_i810_vga_regbase
|| base
!= agp_i810_vga_regbase
)
403 *hdlp
= agp_i810_vga_bsh
;
407 static int agp_i810_init(struct agp_softc
*sc
)
409 struct agp_i810_softc
*isc
;
410 struct agp_gatt
*gatt
;
415 if (isc
->chiptype
== CHIP_I810
) {
419 /* Some i810s have on-chip memory called dcache */
420 if (READ1(AGP_I810_DRT
) & AGP_I810_DRT_POPULATED
)
421 isc
->dcache_size
= 4 * 1024 * 1024;
423 isc
->dcache_size
= 0;
425 /* According to the specs the gatt on the i810 must be 64k */
426 if (agp_alloc_dmamem(sc
->as_dmat
, 64 * 1024,
427 0, &gatt
->ag_dmamap
, &virtual, &gatt
->ag_physical
,
428 &gatt
->ag_dmaseg
, 1, &dummyseg
) != 0) {
430 agp_generic_detach(sc
);
433 gatt
->ag_virtual
= (uint32_t *)virtual;
434 gatt
->ag_size
= gatt
->ag_entries
* sizeof(u_int32_t
);
435 memset(gatt
->ag_virtual
, 0, gatt
->ag_size
);
438 /* Install the GATT. */
439 WRITE4(AGP_I810_PGTBL_CTL
, gatt
->ag_physical
| 1);
440 } else if (isc
->chiptype
== CHIP_I830
) {
441 /* The i830 automatically initializes the 128k gatt on boot. */
446 reg
= pci_conf_read(sc
->as_pc
, sc
->as_tag
, AGP_I830_GCC0
);
447 gcc1
= (u_int16_t
)(reg
>> 16);
448 switch (gcc1
& AGP_I830_GCC1_GMS
) {
449 case AGP_I830_GCC1_GMS_STOLEN_512
:
450 isc
->stolen
= (512 - 132) * 1024 / 4096;
452 case AGP_I830_GCC1_GMS_STOLEN_1024
:
453 isc
->stolen
= (1024 - 132) * 1024 / 4096;
455 case AGP_I830_GCC1_GMS_STOLEN_8192
:
456 isc
->stolen
= (8192 - 132) * 1024 / 4096;
461 ": unknown memory configuration, disabling\n");
462 agp_generic_detach(sc
);
466 if (isc
->stolen
> 0) {
467 aprint_normal(": detected %dk stolen memory\n%s",
468 isc
->stolen
* 4, device_xname(sc
->as_dev
));
471 /* GATT address is already in there, make sure it's enabled */
472 pgtblctl
= READ4(AGP_I810_PGTBL_CTL
);
474 WRITE4(AGP_I810_PGTBL_CTL
, pgtblctl
);
476 gatt
->ag_physical
= pgtblctl
& ~1;
477 } else if (isc
->chiptype
== CHIP_I855
|| isc
->chiptype
== CHIP_I915
||
478 isc
->chiptype
== CHIP_I965
|| isc
->chiptype
== CHIP_G33
||
479 isc
->chiptype
== CHIP_G4X
) {
481 u_int32_t pgtblctl
, gtt_size
, stolen
;
484 reg
= pci_conf_read(sc
->as_pc
, sc
->as_tag
, AGP_I855_GCC1
);
485 gcc1
= (u_int16_t
)(reg
>> 16);
487 pgtblctl
= READ4(AGP_I810_PGTBL_CTL
);
489 /* Stolen memory is set up at the beginning of the aperture by
490 * the BIOS, consisting of the GATT followed by 4kb for the
493 switch (isc
->chiptype
) {
501 switch (pgtblctl
& AGP_I810_PGTBL_SIZE_MASK
) {
502 case AGP_I810_PGTBL_SIZE_128KB
:
503 case AGP_I810_PGTBL_SIZE_512KB
:
506 case AGP_I965_PGTBL_SIZE_1MB
:
509 case AGP_I965_PGTBL_SIZE_2MB
:
512 case AGP_I965_PGTBL_SIZE_1_5MB
:
513 gtt_size
= 1024 + 512;
516 aprint_error("Bad PGTBL size\n");
517 agp_generic_detach(sc
);
522 switch (gcc1
& AGP_G33_PGTBL_SIZE_MASK
) {
523 case AGP_G33_PGTBL_SIZE_1M
:
526 case AGP_G33_PGTBL_SIZE_2M
:
530 aprint_error(": Bad PGTBL size\n");
531 agp_generic_detach(sc
);
539 aprint_error(": bad chiptype\n");
540 agp_generic_detach(sc
);
544 switch (gcc1
& AGP_I855_GCC1_GMS
) {
545 case AGP_I855_GCC1_GMS_STOLEN_1M
:
548 case AGP_I855_GCC1_GMS_STOLEN_4M
:
551 case AGP_I855_GCC1_GMS_STOLEN_8M
:
554 case AGP_I855_GCC1_GMS_STOLEN_16M
:
557 case AGP_I855_GCC1_GMS_STOLEN_32M
:
560 case AGP_I915_GCC1_GMS_STOLEN_48M
:
563 case AGP_I915_GCC1_GMS_STOLEN_64M
:
566 case AGP_G33_GCC1_GMS_STOLEN_128M
:
569 case AGP_G33_GCC1_GMS_STOLEN_256M
:
572 case AGP_G4X_GCC1_GMS_STOLEN_96M
:
575 case AGP_G4X_GCC1_GMS_STOLEN_160M
:
578 case AGP_G4X_GCC1_GMS_STOLEN_224M
:
581 case AGP_G4X_GCC1_GMS_STOLEN_352M
:
586 ": unknown memory configuration, disabling\n");
587 agp_generic_detach(sc
);
591 switch (gcc1
& AGP_I855_GCC1_GMS
) {
592 case AGP_I915_GCC1_GMS_STOLEN_48M
:
593 case AGP_I915_GCC1_GMS_STOLEN_64M
:
594 if (isc
->chiptype
!= CHIP_I915
&&
595 isc
->chiptype
!= CHIP_I965
&&
596 isc
->chiptype
!= CHIP_G33
&&
597 isc
->chiptype
!= CHIP_G4X
)
600 case AGP_G33_GCC1_GMS_STOLEN_128M
:
601 case AGP_G33_GCC1_GMS_STOLEN_256M
:
602 if (isc
->chiptype
!= CHIP_I965
&&
603 isc
->chiptype
!= CHIP_G33
&&
604 isc
->chiptype
!= CHIP_G4X
)
607 case AGP_G4X_GCC1_GMS_STOLEN_96M
:
608 case AGP_G4X_GCC1_GMS_STOLEN_160M
:
609 case AGP_G4X_GCC1_GMS_STOLEN_224M
:
610 case AGP_G4X_GCC1_GMS_STOLEN_352M
:
611 if (isc
->chiptype
!= CHIP_I965
&&
612 isc
->chiptype
!= CHIP_G4X
)
620 isc
->stolen
= (stolen
- gtt_size
) * 1024 / 4096;
622 if (isc
->stolen
> 0) {
623 aprint_normal(": detected %dk stolen memory\n%s",
624 isc
->stolen
* 4, device_xname(sc
->as_dev
));
627 /* GATT address is already in there, make sure it's enabled */
629 WRITE4(AGP_I810_PGTBL_CTL
, pgtblctl
);
631 gatt
->ag_physical
= pgtblctl
& ~1;
635 * Make sure the chipset can see everything.
644 agp_i810_detach(struct agp_softc
*sc
)
647 struct agp_i810_softc
*isc
= sc
->as_chipc
;
649 error
= agp_generic_detach(sc
);
653 /* Clear the GATT base. */
654 if (sc
->chiptype
== CHIP_I810
) {
655 WRITE4(AGP_I810_PGTBL_CTL
, 0);
657 unsigned int pgtblctl
;
658 pgtblctl
= READ4(AGP_I810_PGTBL_CTL
);
660 WRITE4(AGP_I810_PGTBL_CTL
, pgtblctl
);
663 /* Put the aperture back the way it started. */
664 AGP_SET_APERTURE(sc
, isc
->initial_aperture
);
666 if (sc
->chiptype
== CHIP_I810
) {
667 agp_free_dmamem(sc
->as_dmat
, gatt
->ag_size
, gatt
->ag_dmamap
,
668 (void *)gatt
->ag_virtual
, &gatt
->ag_dmaseg
, 1);
670 free(sc
->gatt
, M_AGP
);
677 agp_i810_get_aperture(struct agp_softc
*sc
)
679 struct agp_i810_softc
*isc
= sc
->as_chipc
;
682 u_int16_t miscc
, gcc1
, msac
;
686 switch (isc
->chiptype
) {
688 reg
= pci_conf_read(sc
->as_pc
, sc
->as_tag
, AGP_I810_SMRAM
);
689 miscc
= (u_int16_t
)(reg
>> 16);
690 if ((miscc
& AGP_I810_MISCC_WINSIZE
) ==
691 AGP_I810_MISCC_WINSIZE_32
)
692 size
= 32 * 1024 * 1024;
694 size
= 64 * 1024 * 1024;
697 reg
= pci_conf_read(sc
->as_pc
, sc
->as_tag
, AGP_I830_GCC0
);
698 gcc1
= (u_int16_t
)(reg
>> 16);
699 if ((gcc1
& AGP_I830_GCC1_GMASIZE
) == AGP_I830_GCC1_GMASIZE_64
)
700 size
= 64 * 1024 * 1024;
702 size
= 128 * 1024 * 1024;
705 size
= 128 * 1024 * 1024;
710 reg
= pci_conf_read(sc
->as_pc
, sc
->as_tag
, AGP_I915_MSAC
);
711 msac
= (u_int16_t
)(reg
>> 16);
712 if (msac
& AGP_I915_MSAC_APER_128M
)
713 size
= 128 * 1024 * 1024;
715 size
= 256 * 1024 * 1024;
718 size
= 512 * 1024 * 1024;
721 aprint_error(": Unknown chipset\n");
728 agp_i810_set_aperture(struct agp_softc
*sc
, u_int32_t aperture
)
730 struct agp_i810_softc
*isc
= sc
->as_chipc
;
732 u_int16_t miscc
, gcc1
;
734 switch (isc
->chiptype
) {
737 * Double check for sanity.
739 if (aperture
!= (32 * 1024 * 1024) &&
740 aperture
!= (64 * 1024 * 1024)) {
741 aprint_error_dev(sc
->as_dev
, "bad aperture size %d\n",
746 reg
= pci_conf_read(sc
->as_pc
, sc
->as_tag
, AGP_I810_SMRAM
);
747 miscc
= (u_int16_t
)(reg
>> 16);
748 miscc
&= ~AGP_I810_MISCC_WINSIZE
;
749 if (aperture
== 32 * 1024 * 1024)
750 miscc
|= AGP_I810_MISCC_WINSIZE_32
;
752 miscc
|= AGP_I810_MISCC_WINSIZE_64
;
755 reg
|= ((pcireg_t
)miscc
) << 16;
756 pci_conf_write(sc
->as_pc
, sc
->as_tag
, AGP_I810_SMRAM
, reg
);
759 if (aperture
!= (64 * 1024 * 1024) &&
760 aperture
!= (128 * 1024 * 1024)) {
761 aprint_error_dev(sc
->as_dev
, "bad aperture size %d\n",
765 reg
= pci_conf_read(sc
->as_pc
, sc
->as_tag
, AGP_I830_GCC0
);
766 gcc1
= (u_int16_t
)(reg
>> 16);
767 gcc1
&= ~AGP_I830_GCC1_GMASIZE
;
768 if (aperture
== 64 * 1024 * 1024)
769 gcc1
|= AGP_I830_GCC1_GMASIZE_64
;
771 gcc1
|= AGP_I830_GCC1_GMASIZE_128
;
774 reg
|= ((pcireg_t
)gcc1
) << 16;
775 pci_conf_write(sc
->as_pc
, sc
->as_tag
, AGP_I830_GCC0
, reg
);
779 if (aperture
!= agp_i810_get_aperture(sc
)) {
780 aprint_error_dev(sc
->as_dev
, "bad aperture size %d\n",
786 if (aperture
!= 512 * 1024 * 1024) {
787 aprint_error_dev(sc
->as_dev
, "bad aperture size %d\n",
798 agp_i810_bind_page(struct agp_softc
*sc
, off_t offset
, bus_addr_t physical
)
800 struct agp_i810_softc
*isc
= sc
->as_chipc
;
802 if (offset
< 0 || offset
>= (isc
->gatt
->ag_entries
<< AGP_PAGE_SHIFT
)) {
804 printf("%s: failed: offset 0x%08x, shift %d, entries %d\n",
805 device_xname(sc
->as_dev
), (int)offset
, AGP_PAGE_SHIFT
,
806 isc
->gatt
->ag_entries
);
811 if (isc
->chiptype
!= CHIP_I830
) {
812 if ((offset
>> AGP_PAGE_SHIFT
) < isc
->stolen
) {
814 printf("%s: trying to bind into stolen memory",
815 device_xname(sc
->as_dev
));
821 agp_i810_write_gtt_entry(isc
, offset
, physical
| 1);
826 agp_i810_unbind_page(struct agp_softc
*sc
, off_t offset
)
828 struct agp_i810_softc
*isc
= sc
->as_chipc
;
830 if (offset
< 0 || offset
>= (isc
->gatt
->ag_entries
<< AGP_PAGE_SHIFT
))
833 if (isc
->chiptype
!= CHIP_I810
) {
834 if ((offset
>> AGP_PAGE_SHIFT
) < isc
->stolen
) {
836 printf("%s: trying to unbind from stolen memory",
837 device_xname(sc
->as_dev
));
843 agp_i810_write_gtt_entry(isc
, offset
, 0);
848 * Writing via memory mapped registers already flushes all TLBs.
851 agp_i810_flush_tlb(struct agp_softc
*sc
)
856 agp_i810_enable(struct agp_softc
*sc
, u_int32_t mode
)
862 static struct agp_memory
*
863 agp_i810_alloc_memory(struct agp_softc
*sc
, int type
, vsize_t size
)
865 struct agp_i810_softc
*isc
= sc
->as_chipc
;
866 struct agp_memory
*mem
;
869 printf("AGP: alloc(%d, 0x%x)\n", type
, (int) size
);
872 if ((size
& (AGP_PAGE_SIZE
- 1)) != 0)
875 if (sc
->as_allocated
+ size
> sc
->as_maxmem
)
880 * Mapping local DRAM into GATT.
882 if (isc
->chiptype
!= CHIP_I810
)
884 if (size
!= isc
->dcache_size
)
886 } else if (type
== 2) {
888 * Bogus mapping for the hardware cursor.
890 if (size
!= AGP_PAGE_SIZE
&& size
!= 4 * AGP_PAGE_SIZE
)
894 mem
= malloc(sizeof *mem
, M_AGP
, M_WAITOK
|M_ZERO
);
897 mem
->am_id
= sc
->as_nextid
++;
903 * Allocate and wire down the memory now so that we can
904 * get its physical address.
906 mem
->am_dmaseg
= malloc(sizeof *mem
->am_dmaseg
, M_AGP
,
908 if (mem
->am_dmaseg
== NULL
) {
912 if (agp_alloc_dmamem(sc
->as_dmat
, size
, 0,
913 &mem
->am_dmamap
, &mem
->am_virtual
, &mem
->am_physical
,
914 mem
->am_dmaseg
, 1, &mem
->am_nseg
) != 0) {
915 free(mem
->am_dmaseg
, M_AGP
);
919 memset(mem
->am_virtual
, 0, size
);
920 } else if (type
!= 1) {
921 if (bus_dmamap_create(sc
->as_dmat
, size
, size
/ PAGE_SIZE
+ 1,
922 size
, 0, BUS_DMA_NOWAIT
,
923 &mem
->am_dmamap
) != 0) {
929 TAILQ_INSERT_TAIL(&sc
->as_memory
, mem
, am_link
);
930 sc
->as_allocated
+= size
;
936 agp_i810_free_memory(struct agp_softc
*sc
, struct agp_memory
*mem
)
938 if (mem
->am_is_bound
)
941 if (mem
->am_type
== 2) {
942 agp_free_dmamem(sc
->as_dmat
, mem
->am_size
, mem
->am_dmamap
,
943 mem
->am_virtual
, mem
->am_dmaseg
, mem
->am_nseg
);
944 free(mem
->am_dmaseg
, M_AGP
);
947 sc
->as_allocated
-= mem
->am_size
;
948 TAILQ_REMOVE(&sc
->as_memory
, mem
, am_link
);
954 agp_i810_bind_memory(struct agp_softc
*sc
, struct agp_memory
*mem
,
957 struct agp_i810_softc
*isc
= sc
->as_chipc
;
961 * XXX evil hack: the PGTBL_CTL appearently gets overwritten by the
962 * X server for mysterious reasons which leads to crashes if we write
963 * to the GTT through the MMIO window.
964 * Until the issue is solved, simply restore it.
966 regval
= bus_space_read_4(isc
->bst
, isc
->bsh
, AGP_I810_PGTBL_CTL
);
967 if (regval
!= (isc
->gatt
->ag_physical
| 1)) {
968 printf("agp_i810_bind_memory: PGTBL_CTL is 0x%x - fixing\n",
970 bus_space_write_4(isc
->bst
, isc
->bsh
, AGP_I810_PGTBL_CTL
,
971 isc
->gatt
->ag_physical
| 1);
974 if (mem
->am_type
== 2) {
975 agp_i810_write_gtt_entry(isc
, offset
, mem
->am_physical
| 1);
976 mem
->am_offset
= offset
;
977 mem
->am_is_bound
= 1;
981 if (mem
->am_type
!= 1)
982 return agp_generic_bind_memory(sc
, mem
, offset
);
984 if (isc
->chiptype
!= CHIP_I810
)
987 for (i
= 0; i
< mem
->am_size
; i
+= AGP_PAGE_SIZE
)
988 agp_i810_write_gtt_entry(isc
, offset
, i
| 3);
989 mem
->am_is_bound
= 1;
994 agp_i810_unbind_memory(struct agp_softc
*sc
, struct agp_memory
*mem
)
996 struct agp_i810_softc
*isc
= sc
->as_chipc
;
999 if (mem
->am_type
== 2) {
1000 agp_i810_write_gtt_entry(isc
, mem
->am_offset
, 0);
1002 mem
->am_is_bound
= 0;
1006 if (mem
->am_type
!= 1)
1007 return agp_generic_unbind_memory(sc
, mem
);
1009 if (isc
->chiptype
!= CHIP_I810
)
1012 for (i
= 0; i
< mem
->am_size
; i
+= AGP_PAGE_SIZE
)
1013 agp_i810_write_gtt_entry(isc
, i
, 0);
1014 mem
->am_is_bound
= 0;
1019 agp_i810_resume(device_t dv
, pmf_qual_t qual
)
1021 struct agp_softc
*sc
= device_private(dv
);
1022 struct agp_i810_softc
*isc
= sc
->as_chipc
;
1024 isc
->pgtblctl
= READ4(AGP_I810_PGTBL_CTL
);