1 /* $NetBSD: agp_apple.c,v 1.4 2008/04/29 06:53:03 martin Exp $ */
4 * Copyright (c) 2007 Michael Lorenz
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: agp_apple.c,v 1.4 2008/04/29 06:53:03 martin Exp $");
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/malloc.h>
34 #include <sys/kernel.h>
37 #include <sys/device.h>
38 #include <sys/agpio.h>
40 #include <uvm/uvm_extern.h>
42 #include <dev/pci/pcivar.h>
43 #include <dev/pci/pcireg.h>
44 #include <dev/pci/agpvar.h>
45 #include <dev/pci/agpreg.h>
49 static u_int32_t
agp_apple_get_aperture(struct agp_softc
*);
50 static int agp_apple_set_aperture(struct agp_softc
*, u_int32_t
);
51 static int agp_apple_bind_page(struct agp_softc
*, off_t
, bus_addr_t
);
52 static int agp_apple_unbind_page(struct agp_softc
*, off_t
);
53 static void agp_apple_flush_tlb(struct agp_softc
*);
55 static struct agp_methods agp_apple_methods
= {
56 agp_apple_get_aperture
,
57 agp_apple_set_aperture
,
59 agp_apple_unbind_page
,
62 agp_generic_alloc_memory
,
63 agp_generic_free_memory
,
64 agp_generic_bind_memory
,
65 agp_generic_unbind_memory
,
68 struct agp_apple_softc
{
69 u_int32_t initial_aperture
; /* aperture size at startup */
70 struct agp_gatt
*gatt
;
74 agp_apple_attach(device_t parent
, device_t self
, void *aux
)
76 struct pci_attach_args
*pa
= aux
;
77 struct agp_softc
*sc
= device_private(self
);
78 struct agp_apple_softc
*asc
;
79 struct agp_gatt
*gatt
;
81 asc
= malloc(sizeof *asc
, M_AGP
, M_NOWAIT
|M_ZERO
);
83 aprint_error(": can't allocate chipset-specific softc\n");
87 sc
->as_methods
= &agp_apple_methods
;
88 pci_get_capability(pa
->pa_pc
, pa
->pa_tag
, PCI_CAP_AGP
, &sc
->as_capoff
,
92 sc
->as_apsize
= 8 * 1024 * 1024;
94 sc
->as_pc
= pa
->pa_pc
;
95 sc
->as_tag
= pa
->pa_tag
;
96 sc
->as_apt
= pa
->pa_memt
;
98 asc
->initial_aperture
= sc
->as_apsize
;
101 gatt
= agp_alloc_gatt(sc
);
104 sc
->as_apsize
= sc
->as_apsize
>> 1;
105 if (sc
->as_apsize
== 0) {
106 aprint_error(": can't set aperture size\n");
112 /* Install the gatt. */
113 aprint_error("gatt: %08x %d MB\n", gatt
->ag_physical
, sc
->as_apsize
>> 20);
114 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
, APPLE_UNINORTH_GART_BASE
,
115 (gatt
->ag_physical
& 0xfffff000) |
116 (sc
->as_apsize
>> 22));
118 /* Enable the aperture. */
119 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
, APPLE_UNINORTH_GART_CTRL
,
121 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
, APPLE_UNINORTH_GART_CTRL
,
122 APPLE_GART_EN
| APPLE_GART_INV
);
123 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
, APPLE_UNINORTH_GART_CTRL
,
129 agp_apple_get_aperture(struct agp_softc
*sc
)
132 u_int32_t apsize
= 0;
134 aprint_error("%s: ", __func__
);
135 apsize
= pci_conf_read(sc
->as_pc
, sc
->as_tag
,
136 APPLE_UNINORTH_GART_BASE
) & 0x0000ffff;
137 aprint_error("%08x\n", apsize
);
138 return (apsize
<< 22);
140 return sc
->as_apsize
;
145 agp_apple_set_aperture(struct agp_softc
*sc
, u_int32_t aperture
)
149 aprint_error("%s: %08x\n", __func__
, aperture
);
150 reg
= pci_conf_read(sc
->as_pc
, sc
->as_tag
, APPLE_UNINORTH_GART_BASE
)
152 reg
|= ((aperture
>> 22) & 0xfff);
153 pci_conf_write(sc
->as_pc
, sc
->as_tag
, APPLE_UNINORTH_GART_BASE
, reg
);
154 sc
->as_apsize
= aperture
;
159 agp_apple_bind_page(struct agp_softc
*sc
, off_t offset
, bus_addr_t physical
)
161 struct agp_apple_softc
*asc
= sc
->as_chipc
;
163 if (offset
< 0 || offset
>= (asc
->gatt
->ag_entries
<< AGP_PAGE_SHIFT
))
166 asc
->gatt
->ag_virtual
[offset
>> AGP_PAGE_SHIFT
] = htole32(physical
);
171 agp_apple_unbind_page(struct agp_softc
*sc
, off_t offset
)
173 struct agp_apple_softc
*asc
= sc
->as_chipc
;
175 if (offset
< 0 || offset
>= (asc
->gatt
->ag_entries
<< AGP_PAGE_SHIFT
))
178 asc
->gatt
->ag_virtual
[offset
>> AGP_PAGE_SHIFT
] = 0;
183 agp_apple_flush_tlb(struct agp_softc
*sc
)
186 pci_conf_write(sc
->as_pc
, sc
->as_tag
, APPLE_UNINORTH_GART_CTRL
,
188 pci_conf_write(sc
->as_pc
, sc
->as_tag
, APPLE_UNINORTH_GART_CTRL
,
189 APPLE_GART_EN
| APPLE_GART_INV
);
190 pci_conf_write(sc
->as_pc
, sc
->as_tag
, APPLE_UNINORTH_GART_CTRL
,