| @@ -1,1037 +1,1028 @@ | | | @@ -1,1037 +1,1028 @@ |
1 | /* $NetBSD: agp_i810.c,v 1.63 2009/02/19 05:58:37 markd Exp $ */ | | 1 | /* $NetBSD: agp_i810.c,v 1.64 2009/05/04 11:05:45 markd Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2000 Doug Rabson | | 4 | * Copyright (c) 2000 Doug Rabson |
5 | * Copyright (c) 2000 Ruslan Ermilov | | 5 | * Copyright (c) 2000 Ruslan Ermilov |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
15 | * documentation and/or other materials provided with the distribution. | | 15 | * documentation and/or other materials provided with the distribution. |
16 | * | | 16 | * |
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | | 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 | | 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | | 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 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 | | 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 | | 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 | | 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
27 | * SUCH DAMAGE. | | 27 | * SUCH DAMAGE. |
28 | * | | 28 | * |
29 | * $FreeBSD: src/sys/pci/agp_i810.c,v 1.4 2001/07/05 21:28:47 jhb Exp $ | | 29 | * $FreeBSD: src/sys/pci/agp_i810.c,v 1.4 2001/07/05 21:28:47 jhb Exp $ |
30 | */ | | 30 | */ |
31 | | | 31 | |
32 | #include <sys/cdefs.h> | | 32 | #include <sys/cdefs.h> |
33 | __KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.63 2009/02/19 05:58:37 markd Exp $"); | | 33 | __KERNEL_RCSID(0, "$NetBSD: agp_i810.c,v 1.64 2009/05/04 11:05:45 markd Exp $"); |
34 | | | 34 | |
35 | #include <sys/param.h> | | 35 | #include <sys/param.h> |
36 | #include <sys/systm.h> | | 36 | #include <sys/systm.h> |
37 | #include <sys/malloc.h> | | 37 | #include <sys/malloc.h> |
38 | #include <sys/kernel.h> | | 38 | #include <sys/kernel.h> |
39 | #include <sys/proc.h> | | 39 | #include <sys/proc.h> |
40 | #include <sys/device.h> | | 40 | #include <sys/device.h> |
41 | #include <sys/conf.h> | | 41 | #include <sys/conf.h> |
42 | | | 42 | |
43 | #include <uvm/uvm_extern.h> | | 43 | #include <uvm/uvm_extern.h> |
44 | | | 44 | |
45 | #include <dev/pci/pcivar.h> | | 45 | #include <dev/pci/pcivar.h> |
46 | #include <dev/pci/pcireg.h> | | 46 | #include <dev/pci/pcireg.h> |
47 | #include <dev/pci/pcidevs.h> | | 47 | #include <dev/pci/pcidevs.h> |
48 | #include <dev/pci/agpvar.h> | | 48 | #include <dev/pci/agpvar.h> |
49 | #include <dev/pci/agpreg.h> | | 49 | #include <dev/pci/agpreg.h> |
50 | | | 50 | |
51 | #include <sys/agpio.h> | | 51 | #include <sys/agpio.h> |
52 | | | 52 | |
53 | #include <sys/bus.h> | | 53 | #include <sys/bus.h> |
54 | | | 54 | |
55 | #include "agp_intel.h" | | 55 | #include "agp_intel.h" |
56 | | | 56 | |
57 | #define READ1(off) bus_space_read_1(isc->bst, isc->bsh, off) | | 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) | | 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) | | 59 | #define WRITE4(off,v) bus_space_write_4(isc->bst, isc->bsh, off, v) |
60 | | | 60 | |
61 | #define CHIP_I810 0 /* i810/i815 */ | | 61 | #define CHIP_I810 0 /* i810/i815 */ |
62 | #define CHIP_I830 1 /* 830M/845G */ | | 62 | #define CHIP_I830 1 /* 830M/845G */ |
63 | #define CHIP_I855 2 /* 852GM/855GM/865G */ | | 63 | #define CHIP_I855 2 /* 852GM/855GM/865G */ |
64 | #define CHIP_I915 3 /* 915G/915GM/945G/945GM/945GME */ | | 64 | #define CHIP_I915 3 /* 915G/915GM/945G/945GM/945GME */ |
65 | #define CHIP_I965 4 /* 965Q/965PM */ | | 65 | #define CHIP_I965 4 /* 965Q/965PM */ |
66 | #define CHIP_G33 5 /* G33/Q33/Q35 */ | | 66 | #define CHIP_G33 5 /* G33/Q33/Q35 */ |
67 | #define CHIP_G4X 6 /* G45/Q45 */ | | 67 | #define CHIP_G4X 6 /* G45/Q45 */ |
68 | | | 68 | |
69 | struct agp_i810_softc { | | 69 | struct agp_i810_softc { |
70 | u_int32_t initial_aperture; /* aperture size at startup */ | | 70 | u_int32_t initial_aperture; /* aperture size at startup */ |
71 | struct agp_gatt *gatt; | | 71 | struct agp_gatt *gatt; |
72 | int chiptype; /* i810-like or i830 */ | | 72 | int chiptype; /* i810-like or i830 */ |
73 | u_int32_t dcache_size; /* i810 only */ | | 73 | u_int32_t dcache_size; /* i810 only */ |
74 | u_int32_t stolen; /* number of i830/845 gtt entries | | 74 | u_int32_t stolen; /* number of i830/845 gtt entries |
75 | for stolen memory */ | | 75 | for stolen memory */ |
76 | bus_space_tag_t bst; /* register bus_space tag */ | | 76 | bus_space_tag_t bst; /* register bus_space tag */ |
77 | bus_space_handle_t bsh; /* register bus_space handle */ | | 77 | bus_space_handle_t bsh; /* register bus_space handle */ |
78 | bus_space_tag_t gtt_bst; /* GTT bus_space tag */ | | 78 | bus_space_tag_t gtt_bst; /* GTT bus_space tag */ |
79 | bus_space_handle_t gtt_bsh; /* GTT bus_space handle */ | | 79 | bus_space_handle_t gtt_bsh; /* GTT bus_space handle */ |
80 | struct pci_attach_args vga_pa; | | 80 | struct pci_attach_args vga_pa; |
81 | | | 81 | |
82 | u_int32_t pgtblctl; | | 82 | u_int32_t pgtblctl; |
83 | }; | | 83 | }; |
84 | | | 84 | |
85 | /* XXX hack, see below */ | | 85 | /* XXX hack, see below */ |
86 | static bus_addr_t agp_i810_vga_regbase; | | 86 | static bus_addr_t agp_i810_vga_regbase; |
87 | static bus_space_handle_t agp_i810_vga_bsh; | | 87 | static bus_space_handle_t agp_i810_vga_bsh; |
88 | | | 88 | |
89 | static u_int32_t agp_i810_get_aperture(struct agp_softc *); | | 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); | | 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); | | 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); | | 92 | static int agp_i810_unbind_page(struct agp_softc *, off_t); |
93 | static void agp_i810_flush_tlb(struct agp_softc *); | | 93 | static void agp_i810_flush_tlb(struct agp_softc *); |
94 | static int agp_i810_enable(struct agp_softc *, u_int32_t mode); | | 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, | | 95 | static struct agp_memory *agp_i810_alloc_memory(struct agp_softc *, int, |
96 | vsize_t); | | 96 | vsize_t); |
97 | static int agp_i810_free_memory(struct agp_softc *, struct agp_memory *); | | 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); | | 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 *); | | 99 | static int agp_i810_unbind_memory(struct agp_softc *, struct agp_memory *); |
100 | | | 100 | |
101 | static bool agp_i810_resume(device_t PMF_FN_PROTO); | | 101 | static bool agp_i810_resume(device_t PMF_FN_PROTO); |
102 | static int agp_i810_init(struct agp_softc *); | | 102 | static int agp_i810_init(struct agp_softc *); |
103 | | | 103 | |
104 | 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, | | 105 | static void agp_i810_write_gtt_entry(struct agp_i810_softc *, off_t, |
106 | u_int32_t); | | 106 | u_int32_t); |
107 | | | 107 | |
108 | static struct agp_methods agp_i810_methods = { | | 108 | static struct agp_methods agp_i810_methods = { |
109 | agp_i810_get_aperture, | | 109 | agp_i810_get_aperture, |
110 | agp_i810_set_aperture, | | 110 | agp_i810_set_aperture, |
111 | agp_i810_bind_page, | | 111 | agp_i810_bind_page, |
112 | agp_i810_unbind_page, | | 112 | agp_i810_unbind_page, |
113 | agp_i810_flush_tlb, | | 113 | agp_i810_flush_tlb, |
114 | agp_i810_enable, | | 114 | agp_i810_enable, |
115 | agp_i810_alloc_memory, | | 115 | agp_i810_alloc_memory, |
116 | agp_i810_free_memory, | | 116 | agp_i810_free_memory, |
117 | agp_i810_bind_memory, | | 117 | agp_i810_bind_memory, |
118 | agp_i810_unbind_memory, | | 118 | agp_i810_unbind_memory, |
119 | }; | | 119 | }; |
120 | | | 120 | |
121 | static void | | 121 | static void |
122 | agp_i810_write_gtt_entry(struct agp_i810_softc *isc, off_t off, u_int32_t v) | | 122 | agp_i810_write_gtt_entry(struct agp_i810_softc *isc, off_t off, u_int32_t v) |
123 | { | | 123 | { |
124 | u_int32_t base_off; | | 124 | u_int32_t base_off; |
125 | | | 125 | |
126 | base_off = 0; | | 126 | base_off = 0; |
127 | | | 127 | |
128 | switch (isc->chiptype) { | | 128 | switch (isc->chiptype) { |
129 | case CHIP_I810: | | 129 | case CHIP_I810: |
130 | case CHIP_I830: | | 130 | case CHIP_I830: |
131 | case CHIP_I855: | | 131 | case CHIP_I855: |
132 | base_off = AGP_I810_GTT; | | 132 | base_off = AGP_I810_GTT; |
133 | break; | | 133 | break; |
134 | case CHIP_I965: | | 134 | case CHIP_I965: |
135 | base_off = AGP_I965_GTT; | | 135 | base_off = AGP_I965_GTT; |
136 | break; | | 136 | break; |
137 | case CHIP_G4X: | | 137 | case CHIP_G4X: |
138 | base_off = AGP_G4X_GTT; | | 138 | base_off = AGP_G4X_GTT; |
139 | break; | | 139 | break; |
140 | case CHIP_I915: | | 140 | case CHIP_I915: |
141 | case CHIP_G33: | | 141 | case CHIP_G33: |
142 | bus_space_write_4(isc->gtt_bst, isc->gtt_bsh, | | 142 | bus_space_write_4(isc->gtt_bst, isc->gtt_bsh, |
143 | (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, (v)); | | 143 | (u_int32_t)((off) >> AGP_PAGE_SHIFT) * 4, (v)); |
144 | return; | | 144 | return; |
145 | } | | 145 | } |
146 | | | 146 | |
147 | WRITE4(base_off + (u_int32_t)(off >> AGP_PAGE_SHIFT) * 4, v); | | 147 | WRITE4(base_off + (u_int32_t)(off >> AGP_PAGE_SHIFT) * 4, v); |
148 | } | | 148 | } |
149 | | | 149 | |
150 | /* XXXthorpej -- duplicated code (see arch/x86/pci/pchb.c) */ | | 150 | /* XXXthorpej -- duplicated code (see arch/x86/pci/pchb.c) */ |
151 | static int | | 151 | static int |
152 | agp_i810_vgamatch(struct pci_attach_args *pa) | | 152 | agp_i810_vgamatch(struct pci_attach_args *pa) |
153 | { | | 153 | { |
154 | | | 154 | |
155 | if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY || | | 155 | if (PCI_CLASS(pa->pa_class) != PCI_CLASS_DISPLAY || |
156 | PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA) | | 156 | PCI_SUBCLASS(pa->pa_class) != PCI_SUBCLASS_DISPLAY_VGA) |
157 | return (0); | | 157 | return (0); |
158 | | | 158 | |
159 | switch (PCI_PRODUCT(pa->pa_id)) { | | 159 | switch (PCI_PRODUCT(pa->pa_id)) { |
160 | case PCI_PRODUCT_INTEL_82810_GC: | | 160 | case PCI_PRODUCT_INTEL_82810_GC: |
161 | case PCI_PRODUCT_INTEL_82810_DC100_GC: | | 161 | case PCI_PRODUCT_INTEL_82810_DC100_GC: |
162 | case PCI_PRODUCT_INTEL_82810E_GC: | | 162 | case PCI_PRODUCT_INTEL_82810E_GC: |
163 | case PCI_PRODUCT_INTEL_82815_FULL_GRAPH: | | 163 | case PCI_PRODUCT_INTEL_82815_FULL_GRAPH: |
164 | case PCI_PRODUCT_INTEL_82830MP_IV: | | 164 | case PCI_PRODUCT_INTEL_82830MP_IV: |
165 | case PCI_PRODUCT_INTEL_82845G_IGD: | | 165 | case PCI_PRODUCT_INTEL_82845G_IGD: |
166 | case PCI_PRODUCT_INTEL_82855GM_IGD: | | 166 | case PCI_PRODUCT_INTEL_82855GM_IGD: |
167 | case PCI_PRODUCT_INTEL_82865_IGD: | | 167 | case PCI_PRODUCT_INTEL_82865_IGD: |
168 | case PCI_PRODUCT_INTEL_82915G_IGD: | | 168 | case PCI_PRODUCT_INTEL_82915G_IGD: |
169 | case PCI_PRODUCT_INTEL_82915GM_IGD: | | 169 | case PCI_PRODUCT_INTEL_82915GM_IGD: |
170 | case PCI_PRODUCT_INTEL_82945P_IGD: | | 170 | case PCI_PRODUCT_INTEL_82945P_IGD: |
171 | case PCI_PRODUCT_INTEL_82945GM_IGD: | | 171 | case PCI_PRODUCT_INTEL_82945GM_IGD: |
172 | case PCI_PRODUCT_INTEL_82945GM_IGD_1: | | 172 | case PCI_PRODUCT_INTEL_82945GM_IGD_1: |
173 | case PCI_PRODUCT_INTEL_82945GME_IGD: | | 173 | case PCI_PRODUCT_INTEL_82945GME_IGD: |
174 | case PCI_PRODUCT_INTEL_82965Q_IGD: | | 174 | case PCI_PRODUCT_INTEL_82965Q_IGD: |
175 | case PCI_PRODUCT_INTEL_82965Q_IGD_1: | | 175 | case PCI_PRODUCT_INTEL_82965Q_IGD_1: |
176 | case PCI_PRODUCT_INTEL_82965PM_IGD: | | 176 | case PCI_PRODUCT_INTEL_82965PM_IGD: |
177 | case PCI_PRODUCT_INTEL_82965PM_IGD_1: | | 177 | case PCI_PRODUCT_INTEL_82965PM_IGD_1: |
178 | case PCI_PRODUCT_INTEL_82G33_IGD: | | 178 | case PCI_PRODUCT_INTEL_82G33_IGD: |
179 | case PCI_PRODUCT_INTEL_82G33_IGD_1: | | 179 | case PCI_PRODUCT_INTEL_82G33_IGD_1: |
180 | case PCI_PRODUCT_INTEL_82965G_IGD: | | 180 | case PCI_PRODUCT_INTEL_82965G_IGD: |
181 | case PCI_PRODUCT_INTEL_82965G_IGD_1: | | 181 | case PCI_PRODUCT_INTEL_82965G_IGD_1: |
182 | case PCI_PRODUCT_INTEL_82Q35_IGD: | | 182 | case PCI_PRODUCT_INTEL_82Q35_IGD: |
183 | case PCI_PRODUCT_INTEL_82Q35_IGD_1: | | 183 | case PCI_PRODUCT_INTEL_82Q35_IGD_1: |
184 | case PCI_PRODUCT_INTEL_82Q33_IGD: | | 184 | case PCI_PRODUCT_INTEL_82Q33_IGD: |
185 | case PCI_PRODUCT_INTEL_82Q33_IGD_1: | | 185 | case PCI_PRODUCT_INTEL_82Q33_IGD_1: |
186 | case PCI_PRODUCT_INTEL_82G35_IGD: | | 186 | case PCI_PRODUCT_INTEL_82G35_IGD: |
187 | case PCI_PRODUCT_INTEL_82G35_IGD_1: | | 187 | case PCI_PRODUCT_INTEL_82G35_IGD_1: |
188 | case PCI_PRODUCT_INTEL_82946GZ_IGD: | | 188 | case PCI_PRODUCT_INTEL_82946GZ_IGD: |
189 | case PCI_PRODUCT_INTEL_82GM45_IGD: | | 189 | case PCI_PRODUCT_INTEL_82GM45_IGD: |
190 | case PCI_PRODUCT_INTEL_82GM45_IGD_1: | | 190 | case PCI_PRODUCT_INTEL_82GM45_IGD_1: |
191 | case PCI_PRODUCT_INTEL_82IGD_E_IGD: | | 191 | case PCI_PRODUCT_INTEL_82IGD_E_IGD: |
192 | case PCI_PRODUCT_INTEL_82Q45_IGD: | | 192 | case PCI_PRODUCT_INTEL_82Q45_IGD: |
193 | case PCI_PRODUCT_INTEL_82G45_IGD: | | 193 | case PCI_PRODUCT_INTEL_82G45_IGD: |
194 | return (1); | | 194 | return (1); |
195 | } | | 195 | } |
196 | | | 196 | |
197 | return (0); | | 197 | return (0); |
198 | } | | 198 | } |
199 | | | 199 | |
200 | static int | | 200 | static int |
201 | agp_i965_map_aperture(struct pci_attach_args *pa, struct agp_softc *sc, int reg) | | 201 | agp_i965_map_aperture(struct pci_attach_args *pa, struct agp_softc *sc, int reg) |
202 | { | | 202 | { |
203 | /* | | 203 | /* |
204 | * Find the aperture. Don't map it (yet), this would | | 204 | * Find the aperture. Don't map it (yet), this would |
205 | * eat KVA. | | 205 | * eat KVA. |
206 | */ | | 206 | */ |
207 | if (pci_mapreg_info(pa->pa_pc, pa->pa_tag, reg, | | 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, | | 208 | PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_64BIT, &sc->as_apaddr, &sc->as_apsize, |
209 | &sc->as_apflags) != 0) | | 209 | &sc->as_apflags) != 0) |
210 | return ENXIO; | | 210 | return ENXIO; |
211 | | | 211 | |
212 | sc->as_apt = pa->pa_memt; | | 212 | sc->as_apt = pa->pa_memt; |
213 | | | 213 | |
214 | return 0; | | 214 | return 0; |
215 | } | | 215 | } |
216 | | | 216 | |
217 | int | | 217 | int |
218 | agp_i810_attach(device_t parent, device_t self, void *aux) | | 218 | agp_i810_attach(device_t parent, device_t self, void *aux) |
219 | { | | 219 | { |
220 | struct agp_softc *sc = device_private(self); | | 220 | struct agp_softc *sc = device_private(self); |
221 | struct agp_i810_softc *isc; | | 221 | struct agp_i810_softc *isc; |
222 | struct agp_gatt *gatt; | | 222 | struct agp_gatt *gatt; |
223 | int error, apbase; | | 223 | int error, apbase; |
224 | bus_addr_t mmadr; | | 224 | bus_addr_t mmadr; |
225 | bus_size_t mmadrsize; | | 225 | bus_size_t mmadrsize; |
226 | | | 226 | |
227 | isc = malloc(sizeof *isc, M_AGP, M_NOWAIT|M_ZERO); | | 227 | isc = malloc(sizeof *isc, M_AGP, M_NOWAIT|M_ZERO); |
228 | if (isc == NULL) { | | 228 | if (isc == NULL) { |
229 | aprint_error(": can't allocate chipset-specific softc\n"); | | 229 | aprint_error(": can't allocate chipset-specific softc\n"); |
230 | return ENOMEM; | | 230 | return ENOMEM; |
231 | } | | 231 | } |
232 | sc->as_chipc = isc; | | 232 | sc->as_chipc = isc; |
233 | sc->as_methods = &agp_i810_methods; | | 233 | sc->as_methods = &agp_i810_methods; |
234 | | | 234 | |
235 | if (pci_find_device(&isc->vga_pa, agp_i810_vgamatch) == 0) { | | 235 | if (pci_find_device(&isc->vga_pa, agp_i810_vgamatch) == 0) { |
236 | #if NAGP_INTEL > 0 | | 236 | #if NAGP_INTEL > 0 |
237 | const struct pci_attach_args *pa = aux; | | 237 | const struct pci_attach_args *pa = aux; |
238 | | | 238 | |
239 | switch (PCI_PRODUCT(pa->pa_id)) { | | 239 | switch (PCI_PRODUCT(pa->pa_id)) { |
240 | case PCI_PRODUCT_INTEL_82840_HB: | | 240 | case PCI_PRODUCT_INTEL_82840_HB: |
241 | case PCI_PRODUCT_INTEL_82865_HB: | | 241 | case PCI_PRODUCT_INTEL_82865_HB: |
242 | case PCI_PRODUCT_INTEL_82845G_DRAM: | | 242 | case PCI_PRODUCT_INTEL_82845G_DRAM: |
243 | case PCI_PRODUCT_INTEL_82815_FULL_HUB: | | 243 | case PCI_PRODUCT_INTEL_82815_FULL_HUB: |
244 | return agp_intel_attach(parent, self, aux); | | 244 | return agp_intel_attach(parent, self, aux); |
245 | } | | 245 | } |
246 | #endif | | 246 | #endif |
247 | aprint_error(": can't find internal VGA device config space\n"); | | 247 | aprint_error(": can't find internal VGA device config space\n"); |
248 | free(isc, M_AGP); | | 248 | free(isc, M_AGP); |
249 | return ENOENT; | | 249 | return ENOENT; |
250 | } | | 250 | } |
251 | | | 251 | |
252 | /* XXXfvdl */ | | 252 | /* XXXfvdl */ |
253 | sc->as_dmat = isc->vga_pa.pa_dmat; | | 253 | sc->as_dmat = isc->vga_pa.pa_dmat; |
254 | | | 254 | |
255 | switch (PCI_PRODUCT(isc->vga_pa.pa_id)) { | | 255 | switch (PCI_PRODUCT(isc->vga_pa.pa_id)) { |
256 | case PCI_PRODUCT_INTEL_82810_GC: | | 256 | case PCI_PRODUCT_INTEL_82810_GC: |
257 | case PCI_PRODUCT_INTEL_82810_DC100_GC: | | 257 | case PCI_PRODUCT_INTEL_82810_DC100_GC: |
258 | case PCI_PRODUCT_INTEL_82810E_GC: | | 258 | case PCI_PRODUCT_INTEL_82810E_GC: |
259 | case PCI_PRODUCT_INTEL_82815_FULL_GRAPH: | | 259 | case PCI_PRODUCT_INTEL_82815_FULL_GRAPH: |
260 | isc->chiptype = CHIP_I810; | | 260 | isc->chiptype = CHIP_I810; |
261 | break; | | 261 | break; |
262 | case PCI_PRODUCT_INTEL_82830MP_IV: | | 262 | case PCI_PRODUCT_INTEL_82830MP_IV: |
263 | case PCI_PRODUCT_INTEL_82845G_IGD: | | 263 | case PCI_PRODUCT_INTEL_82845G_IGD: |
264 | isc->chiptype = CHIP_I830; | | 264 | isc->chiptype = CHIP_I830; |
265 | break; | | 265 | break; |
266 | case PCI_PRODUCT_INTEL_82855GM_IGD: | | 266 | case PCI_PRODUCT_INTEL_82855GM_IGD: |
267 | case PCI_PRODUCT_INTEL_82865_IGD: | | 267 | case PCI_PRODUCT_INTEL_82865_IGD: |
268 | isc->chiptype = CHIP_I855; | | 268 | isc->chiptype = CHIP_I855; |
269 | break; | | 269 | break; |
270 | case PCI_PRODUCT_INTEL_82915G_IGD: | | 270 | case PCI_PRODUCT_INTEL_82915G_IGD: |
271 | case PCI_PRODUCT_INTEL_82915GM_IGD: | | 271 | case PCI_PRODUCT_INTEL_82915GM_IGD: |
272 | case PCI_PRODUCT_INTEL_82945P_IGD: | | 272 | case PCI_PRODUCT_INTEL_82945P_IGD: |
273 | case PCI_PRODUCT_INTEL_82945GM_IGD: | | 273 | case PCI_PRODUCT_INTEL_82945GM_IGD: |
274 | case PCI_PRODUCT_INTEL_82945GM_IGD_1: | | 274 | case PCI_PRODUCT_INTEL_82945GM_IGD_1: |
275 | case PCI_PRODUCT_INTEL_82945GME_IGD: | | 275 | case PCI_PRODUCT_INTEL_82945GME_IGD: |
276 | isc->chiptype = CHIP_I915; | | 276 | isc->chiptype = CHIP_I915; |
277 | break; | | 277 | break; |
278 | case PCI_PRODUCT_INTEL_82965Q_IGD: | | 278 | case PCI_PRODUCT_INTEL_82965Q_IGD: |
279 | case PCI_PRODUCT_INTEL_82965Q_IGD_1: | | 279 | case PCI_PRODUCT_INTEL_82965Q_IGD_1: |
280 | case PCI_PRODUCT_INTEL_82965PM_IGD: | | 280 | case PCI_PRODUCT_INTEL_82965PM_IGD: |
281 | case PCI_PRODUCT_INTEL_82965PM_IGD_1: | | 281 | case PCI_PRODUCT_INTEL_82965PM_IGD_1: |
282 | case PCI_PRODUCT_INTEL_82965G_IGD: | | 282 | case PCI_PRODUCT_INTEL_82965G_IGD: |
283 | case PCI_PRODUCT_INTEL_82965G_IGD_1: | | 283 | case PCI_PRODUCT_INTEL_82965G_IGD_1: |
284 | case PCI_PRODUCT_INTEL_82946GZ_IGD: | | 284 | case PCI_PRODUCT_INTEL_82946GZ_IGD: |
285 | case PCI_PRODUCT_INTEL_82G35_IGD: | | 285 | case PCI_PRODUCT_INTEL_82G35_IGD: |
286 | case PCI_PRODUCT_INTEL_82G35_IGD_1: | | 286 | case PCI_PRODUCT_INTEL_82G35_IGD_1: |
287 | isc->chiptype = CHIP_I965; | | 287 | isc->chiptype = CHIP_I965; |
288 | break; | | 288 | break; |
289 | case PCI_PRODUCT_INTEL_82Q35_IGD: | | 289 | case PCI_PRODUCT_INTEL_82Q35_IGD: |
290 | case PCI_PRODUCT_INTEL_82Q35_IGD_1: | | 290 | case PCI_PRODUCT_INTEL_82Q35_IGD_1: |
291 | case PCI_PRODUCT_INTEL_82G33_IGD: | | 291 | case PCI_PRODUCT_INTEL_82G33_IGD: |
292 | case PCI_PRODUCT_INTEL_82G33_IGD_1: | | 292 | case PCI_PRODUCT_INTEL_82G33_IGD_1: |
293 | case PCI_PRODUCT_INTEL_82Q33_IGD: | | 293 | case PCI_PRODUCT_INTEL_82Q33_IGD: |
294 | case PCI_PRODUCT_INTEL_82Q33_IGD_1: | | 294 | case PCI_PRODUCT_INTEL_82Q33_IGD_1: |
295 | isc->chiptype = CHIP_G33; | | 295 | isc->chiptype = CHIP_G33; |
296 | break; | | 296 | break; |
297 | case PCI_PRODUCT_INTEL_82GM45_IGD: | | 297 | case PCI_PRODUCT_INTEL_82GM45_IGD: |
298 | case PCI_PRODUCT_INTEL_82GM45_IGD_1: | | 298 | case PCI_PRODUCT_INTEL_82GM45_IGD_1: |
299 | case PCI_PRODUCT_INTEL_82IGD_E_IGD: | | 299 | case PCI_PRODUCT_INTEL_82IGD_E_IGD: |
300 | case PCI_PRODUCT_INTEL_82Q45_IGD: | | 300 | case PCI_PRODUCT_INTEL_82Q45_IGD: |
301 | case PCI_PRODUCT_INTEL_82G45_IGD: | | 301 | case PCI_PRODUCT_INTEL_82G45_IGD: |
302 | isc->chiptype = CHIP_G4X; | | 302 | isc->chiptype = CHIP_G4X; |
303 | break; | | 303 | break; |
304 | } | | 304 | } |
305 | | | 305 | |
306 | switch (isc->chiptype) { | | 306 | switch (isc->chiptype) { |
307 | case CHIP_I915: | | 307 | case CHIP_I915: |
308 | case CHIP_G33: | | 308 | case CHIP_G33: |
309 | apbase = AGP_I915_GMADR; | | 309 | apbase = AGP_I915_GMADR; |
310 | break; | | 310 | break; |
311 | case CHIP_I965: | | 311 | case CHIP_I965: |
312 | case CHIP_G4X: | | 312 | case CHIP_G4X: |
313 | apbase = AGP_I965_GMADR; | | 313 | apbase = AGP_I965_GMADR; |
314 | break; | | 314 | break; |
315 | default: | | 315 | default: |
316 | apbase = AGP_I810_GMADR; | | 316 | apbase = AGP_I810_GMADR; |
317 | break; | | 317 | break; |
318 | } | | 318 | } |
319 | | | 319 | |
320 | if (isc->chiptype == CHIP_I965 || isc->chiptype == CHIP_G4X) { | | 320 | if (isc->chiptype == CHIP_I965 || isc->chiptype == CHIP_G4X) { |
321 | error = agp_i965_map_aperture(&isc->vga_pa, sc, apbase); | | 321 | error = agp_i965_map_aperture(&isc->vga_pa, sc, apbase); |
322 | } else { | | 322 | } else { |
323 | error = agp_map_aperture(&isc->vga_pa, sc, apbase); | | 323 | error = agp_map_aperture(&isc->vga_pa, sc, apbase); |
324 | } | | 324 | } |
325 | if (error != 0) { | | 325 | if (error != 0) { |
326 | aprint_error(": can't map aperture\n"); | | 326 | aprint_error(": can't map aperture\n"); |
327 | free(isc, M_AGP); | | 327 | free(isc, M_AGP); |
328 | return error; | | 328 | return error; |
329 | } | | 329 | } |
330 | | | 330 | |
331 | if (isc->chiptype == CHIP_I915 || isc->chiptype == CHIP_G33) { | | 331 | if (isc->chiptype == CHIP_I915 || isc->chiptype == CHIP_G33) { |
332 | error = pci_mapreg_map(&isc->vga_pa, AGP_I915_MMADR, | | 332 | error = pci_mapreg_map(&isc->vga_pa, AGP_I915_MMADR, |
333 | PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh, | | 333 | PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh, |
334 | &mmadr, &mmadrsize); | | 334 | &mmadr, &mmadrsize); |
335 | if (error != 0) { | | 335 | if (error != 0) { |
336 | aprint_error(": can't map mmadr registers\n"); | | 336 | aprint_error(": can't map mmadr registers\n"); |
337 | agp_generic_detach(sc); | | 337 | agp_generic_detach(sc); |
338 | return error; | | 338 | return error; |
339 | } | | 339 | } |
340 | error = pci_mapreg_map(&isc->vga_pa, AGP_I915_GTTADR, | | 340 | error = pci_mapreg_map(&isc->vga_pa, AGP_I915_GTTADR, |
341 | PCI_MAPREG_TYPE_MEM, 0, &isc->gtt_bst, &isc->gtt_bsh, | | 341 | PCI_MAPREG_TYPE_MEM, 0, &isc->gtt_bst, &isc->gtt_bsh, |
342 | NULL, NULL); | | 342 | NULL, NULL); |
343 | if (error != 0) { | | 343 | if (error != 0) { |
344 | aprint_error(": can't map gttadr registers\n"); | | 344 | aprint_error(": can't map gttadr registers\n"); |
345 | /* XXX we should release mmadr here */ | | 345 | /* XXX we should release mmadr here */ |
346 | agp_generic_detach(sc); | | 346 | agp_generic_detach(sc); |
347 | return error; | | 347 | return error; |
348 | } | | 348 | } |
349 | } else if (isc->chiptype == CHIP_I965 || isc->chiptype == CHIP_G4X) { | | 349 | } else if (isc->chiptype == CHIP_I965 || isc->chiptype == CHIP_G4X) { |
350 | error = pci_mapreg_map(&isc->vga_pa, AGP_I965_MMADR, | | 350 | error = pci_mapreg_map(&isc->vga_pa, AGP_I965_MMADR, |
351 | PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh, | | 351 | PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh, |
352 | &mmadr, &mmadrsize); | | 352 | &mmadr, &mmadrsize); |
353 | if (error != 0) { | | 353 | if (error != 0) { |
354 | aprint_error(": can't map mmadr registers\n"); | | 354 | aprint_error(": can't map mmadr registers\n"); |
355 | agp_generic_detach(sc); | | 355 | agp_generic_detach(sc); |
356 | return error; | | 356 | return error; |
357 | } | | 357 | } |
358 | } else { | | 358 | } else { |
359 | error = pci_mapreg_map(&isc->vga_pa, AGP_I810_MMADR, | | 359 | error = pci_mapreg_map(&isc->vga_pa, AGP_I810_MMADR, |
360 | PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh, | | 360 | PCI_MAPREG_TYPE_MEM, 0, &isc->bst, &isc->bsh, |
361 | &mmadr, &mmadrsize); | | 361 | &mmadr, &mmadrsize); |
362 | if (error != 0) { | | 362 | if (error != 0) { |
363 | aprint_error(": can't map mmadr registers\n"); | | 363 | aprint_error(": can't map mmadr registers\n"); |
364 | agp_generic_detach(sc); | | 364 | agp_generic_detach(sc); |
365 | return error; | | 365 | return error; |
366 | } | | 366 | } |
367 | } | | 367 | } |
368 | | | 368 | |
369 | isc->initial_aperture = AGP_GET_APERTURE(sc); | | 369 | isc->initial_aperture = AGP_GET_APERTURE(sc); |
370 | | | 370 | |
371 | gatt = malloc(sizeof(struct agp_gatt), M_AGP, M_NOWAIT); | | 371 | gatt = malloc(sizeof(struct agp_gatt), M_AGP, M_NOWAIT); |
372 | if (!gatt) { | | 372 | if (!gatt) { |
373 | agp_generic_detach(sc); | | 373 | agp_generic_detach(sc); |
374 | return ENOMEM; | | 374 | return ENOMEM; |
375 | } | | 375 | } |
376 | isc->gatt = gatt; | | 376 | isc->gatt = gatt; |
377 | | | 377 | |
378 | gatt->ag_entries = AGP_GET_APERTURE(sc) >> AGP_PAGE_SHIFT; | | 378 | gatt->ag_entries = AGP_GET_APERTURE(sc) >> AGP_PAGE_SHIFT; |
379 | | | 379 | |
380 | if (!pmf_device_register(self, NULL, agp_i810_resume)) | | 380 | if (!pmf_device_register(self, NULL, agp_i810_resume)) |
381 | aprint_error_dev(self, "couldn't establish power handler\n"); | | 381 | aprint_error_dev(self, "couldn't establish power handler\n"); |
382 | | | 382 | |
383 | /* | | 383 | /* |
384 | * XXX horrible hack to allow drm code to use our mapping | | 384 | * XXX horrible hack to allow drm code to use our mapping |
385 | * of VGA chip registers | | 385 | * of VGA chip registers |
386 | */ | | 386 | */ |
387 | agp_i810_vga_regbase = mmadr; | | 387 | agp_i810_vga_regbase = mmadr; |
388 | agp_i810_vga_bsh = isc->bsh; | | 388 | agp_i810_vga_bsh = isc->bsh; |
389 | | | 389 | |
390 | return agp_i810_init(sc); | | 390 | return agp_i810_init(sc); |
391 | } | | 391 | } |
392 | | | 392 | |
393 | /* | | 393 | /* |
394 | * XXX horrible hack to allow drm code to use our mapping | | 394 | * XXX horrible hack to allow drm code to use our mapping |
395 | * of VGA chip registers | | 395 | * of VGA chip registers |
396 | */ | | 396 | */ |
397 | int | | 397 | int |
398 | agp_i810_borrow(bus_addr_t base, bus_space_handle_t *hdlp) | | 398 | agp_i810_borrow(bus_addr_t base, bus_space_handle_t *hdlp) |
399 | { | | 399 | { |
400 | | | 400 | |
401 | if (!agp_i810_vga_regbase || base != agp_i810_vga_regbase) | | 401 | if (!agp_i810_vga_regbase || base != agp_i810_vga_regbase) |
402 | return 0; | | 402 | return 0; |
403 | *hdlp = agp_i810_vga_bsh; | | 403 | *hdlp = agp_i810_vga_bsh; |
404 | return 1; | | 404 | return 1; |
405 | } | | 405 | } |
406 | | | 406 | |
407 | static int agp_i810_init(struct agp_softc *sc) | | 407 | static int agp_i810_init(struct agp_softc *sc) |
408 | { | | 408 | { |
409 | struct agp_i810_softc *isc; | | 409 | struct agp_i810_softc *isc; |
410 | struct agp_gatt *gatt; | | 410 | struct agp_gatt *gatt; |
411 | | | 411 | |
412 | isc = sc->as_chipc; | | 412 | isc = sc->as_chipc; |
413 | gatt = isc->gatt; | | 413 | gatt = isc->gatt; |
414 | | | 414 | |
415 | if (isc->chiptype == CHIP_I810) { | | 415 | if (isc->chiptype == CHIP_I810) { |
416 | void *virtual; | | 416 | void *virtual; |
417 | int dummyseg; | | 417 | int dummyseg; |
418 | | | 418 | |
419 | /* Some i810s have on-chip memory called dcache */ | | 419 | /* Some i810s have on-chip memory called dcache */ |
420 | if (READ1(AGP_I810_DRT) & AGP_I810_DRT_POPULATED) | | 420 | if (READ1(AGP_I810_DRT) & AGP_I810_DRT_POPULATED) |
421 | isc->dcache_size = 4 * 1024 * 1024; | | 421 | isc->dcache_size = 4 * 1024 * 1024; |
422 | else | | 422 | else |
423 | isc->dcache_size = 0; | | 423 | isc->dcache_size = 0; |
424 | | | 424 | |
425 | /* According to the specs the gatt on the i810 must be 64k */ | | 425 | /* According to the specs the gatt on the i810 must be 64k */ |
426 | if (agp_alloc_dmamem(sc->as_dmat, 64 * 1024, | | 426 | if (agp_alloc_dmamem(sc->as_dmat, 64 * 1024, |
427 | 0, &gatt->ag_dmamap, &virtual, &gatt->ag_physical, | | 427 | 0, &gatt->ag_dmamap, &virtual, &gatt->ag_physical, |
428 | &gatt->ag_dmaseg, 1, &dummyseg) != 0) { | | 428 | &gatt->ag_dmaseg, 1, &dummyseg) != 0) { |
429 | free(gatt, M_AGP); | | 429 | free(gatt, M_AGP); |
430 | agp_generic_detach(sc); | | 430 | agp_generic_detach(sc); |
431 | return ENOMEM; | | 431 | return ENOMEM; |
432 | } | | 432 | } |
433 | gatt->ag_virtual = (uint32_t *)virtual; | | 433 | gatt->ag_virtual = (uint32_t *)virtual; |
434 | gatt->ag_size = gatt->ag_entries * sizeof(u_int32_t); | | 434 | gatt->ag_size = gatt->ag_entries * sizeof(u_int32_t); |
435 | memset(gatt->ag_virtual, 0, gatt->ag_size); | | 435 | memset(gatt->ag_virtual, 0, gatt->ag_size); |
436 | | | 436 | |
437 | agp_flush_cache(); | | 437 | agp_flush_cache(); |
438 | /* Install the GATT. */ | | 438 | /* Install the GATT. */ |
439 | WRITE4(AGP_I810_PGTBL_CTL, gatt->ag_physical | 1); | | 439 | WRITE4(AGP_I810_PGTBL_CTL, gatt->ag_physical | 1); |
440 | } else if (isc->chiptype == CHIP_I830) { | | 440 | } else if (isc->chiptype == CHIP_I830) { |
441 | /* The i830 automatically initializes the 128k gatt on boot. */ | | 441 | /* The i830 automatically initializes the 128k gatt on boot. */ |
442 | pcireg_t reg; | | 442 | pcireg_t reg; |
443 | u_int32_t pgtblctl; | | 443 | u_int32_t pgtblctl; |
444 | u_int16_t gcc1; | | 444 | u_int16_t gcc1; |
445 | | | 445 | |
446 | reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I830_GCC0); | | 446 | reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I830_GCC0); |
447 | gcc1 = (u_int16_t)(reg >> 16); | | 447 | gcc1 = (u_int16_t)(reg >> 16); |
448 | switch (gcc1 & AGP_I830_GCC1_GMS) { | | 448 | switch (gcc1 & AGP_I830_GCC1_GMS) { |
449 | case AGP_I830_GCC1_GMS_STOLEN_512: | | 449 | case AGP_I830_GCC1_GMS_STOLEN_512: |
450 | isc->stolen = (512 - 132) * 1024 / 4096; | | 450 | isc->stolen = (512 - 132) * 1024 / 4096; |
451 | break; | | 451 | break; |
452 | case AGP_I830_GCC1_GMS_STOLEN_1024: | | 452 | case AGP_I830_GCC1_GMS_STOLEN_1024: |
453 | isc->stolen = (1024 - 132) * 1024 / 4096; | | 453 | isc->stolen = (1024 - 132) * 1024 / 4096; |
454 | break; | | 454 | break; |
455 | case AGP_I830_GCC1_GMS_STOLEN_8192: | | 455 | case AGP_I830_GCC1_GMS_STOLEN_8192: |
456 | isc->stolen = (8192 - 132) * 1024 / 4096; | | 456 | isc->stolen = (8192 - 132) * 1024 / 4096; |
457 | break; | | 457 | break; |
458 | default: | | 458 | default: |
459 | isc->stolen = 0; | | 459 | isc->stolen = 0; |
460 | aprint_error( | | 460 | aprint_error( |
461 | ": unknown memory configuration, disabling\n"); | | 461 | ": unknown memory configuration, disabling\n"); |
462 | agp_generic_detach(sc); | | 462 | agp_generic_detach(sc); |
463 | return EINVAL; | | 463 | return EINVAL; |
464 | } | | 464 | } |
465 | | | 465 | |
466 | if (isc->stolen > 0) { | | 466 | if (isc->stolen > 0) { |
467 | aprint_normal(": detected %dk stolen memory\n%s", | | 467 | aprint_normal(": detected %dk stolen memory\n%s", |
468 | isc->stolen * 4, device_xname(sc->as_dev)); | | 468 | isc->stolen * 4, device_xname(sc->as_dev)); |
469 | } | | 469 | } |
470 | | | 470 | |
471 | /* GATT address is already in there, make sure it's enabled */ | | 471 | /* GATT address is already in there, make sure it's enabled */ |
472 | pgtblctl = READ4(AGP_I810_PGTBL_CTL); | | 472 | pgtblctl = READ4(AGP_I810_PGTBL_CTL); |
473 | pgtblctl |= 1; | | 473 | pgtblctl |= 1; |
474 | WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); | | 474 | WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); |
475 | | | 475 | |
476 | gatt->ag_physical = pgtblctl & ~1; | | 476 | gatt->ag_physical = pgtblctl & ~1; |
477 | } else if (isc->chiptype == CHIP_I855 || isc->chiptype == CHIP_I915 || | | 477 | } else if (isc->chiptype == CHIP_I855 || isc->chiptype == CHIP_I915 || |
478 | isc->chiptype == CHIP_I965 || isc->chiptype == CHIP_G33 || | | 478 | isc->chiptype == CHIP_I965 || isc->chiptype == CHIP_G33 || |
479 | isc->chiptype == CHIP_G4X) { | | 479 | isc->chiptype == CHIP_G4X) { |
480 | pcireg_t reg; | | 480 | pcireg_t reg; |
481 | u_int32_t pgtblctl, gtt_size, stolen; | | 481 | u_int32_t pgtblctl, gtt_size, stolen; |
482 | u_int16_t gcc1; | | 482 | u_int16_t gcc1; |
483 | | | 483 | |
484 | reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I855_GCC1); | | 484 | reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I855_GCC1); |
485 | gcc1 = (u_int16_t)(reg >> 16); | | 485 | gcc1 = (u_int16_t)(reg >> 16); |
486 | | | 486 | |
487 | pgtblctl = READ4(AGP_I810_PGTBL_CTL); | | 487 | pgtblctl = READ4(AGP_I810_PGTBL_CTL); |
488 | | | 488 | |
489 | /* Stolen memory is set up at the beginning of the aperture by | | 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 | | 490 | * the BIOS, consisting of the GATT followed by 4kb for the |
491 | * BIOS display. | | 491 | * BIOS display. |
492 | */ | | 492 | */ |
493 | switch (isc->chiptype) { | | 493 | switch (isc->chiptype) { |
494 | case CHIP_I855: | | 494 | case CHIP_I855: |
495 | gtt_size = 128; | | 495 | gtt_size = 128; |
496 | break; | | 496 | break; |
497 | case CHIP_I915: | | 497 | case CHIP_I915: |
498 | gtt_size = 256; | | 498 | gtt_size = 256; |
499 | break; | | 499 | break; |
500 | case CHIP_I965: | | 500 | case CHIP_I965: |
501 | switch (pgtblctl & AGP_I810_PGTBL_SIZE_MASK) { | | 501 | switch (pgtblctl & AGP_I810_PGTBL_SIZE_MASK) { |
502 | case AGP_I810_PGTBL_SIZE_128KB: | | 502 | case AGP_I810_PGTBL_SIZE_128KB: |
503 | case AGP_I810_PGTBL_SIZE_512KB: | | 503 | case AGP_I810_PGTBL_SIZE_512KB: |
504 | gtt_size = 512; | | 504 | gtt_size = 512; |
505 | break; | | 505 | break; |
506 | case AGP_I965_PGTBL_SIZE_1MB: | | 506 | case AGP_I965_PGTBL_SIZE_1MB: |
507 | gtt_size = 1024; | | 507 | gtt_size = 1024; |
508 | break; | | 508 | break; |
509 | case AGP_I965_PGTBL_SIZE_2MB: | | 509 | case AGP_I965_PGTBL_SIZE_2MB: |
510 | gtt_size = 2048; | | 510 | gtt_size = 2048; |
511 | break; | | 511 | break; |
512 | case AGP_I965_PGTBL_SIZE_1_5MB: | | 512 | case AGP_I965_PGTBL_SIZE_1_5MB: |
513 | gtt_size = 1024 + 512; | | 513 | gtt_size = 1024 + 512; |
514 | break; | | 514 | break; |
515 | default: | | 515 | default: |
516 | aprint_error("Bad PGTBL size\n"); | | 516 | aprint_error("Bad PGTBL size\n"); |
517 | agp_generic_detach(sc); | | 517 | agp_generic_detach(sc); |
518 | return EINVAL; | | 518 | return EINVAL; |
519 | } | | 519 | } |
520 | break; | | 520 | break; |
521 | case CHIP_G33: | | 521 | case CHIP_G33: |
522 | switch (gcc1 & AGP_G33_PGTBL_SIZE_MASK) { | | 522 | switch (gcc1 & AGP_G33_PGTBL_SIZE_MASK) { |
523 | case AGP_G33_PGTBL_SIZE_1M: | | 523 | case AGP_G33_PGTBL_SIZE_1M: |
524 | gtt_size = 1024; | | 524 | gtt_size = 1024; |
525 | break; | | 525 | break; |
526 | case AGP_G33_PGTBL_SIZE_2M: | | 526 | case AGP_G33_PGTBL_SIZE_2M: |
527 | gtt_size = 2048; | | 527 | gtt_size = 2048; |
528 | break; | | 528 | break; |
529 | default: | | 529 | default: |
530 | aprint_error(": Bad PGTBL size\n"); | | 530 | aprint_error(": Bad PGTBL size\n"); |
531 | agp_generic_detach(sc); | | 531 | agp_generic_detach(sc); |
532 | return EINVAL; | | 532 | return EINVAL; |
533 | } | | 533 | } |
534 | break; | | 534 | break; |
535 | case CHIP_G4X: | | 535 | case CHIP_G4X: |
536 | gtt_size = 0; | | 536 | gtt_size = 0; |
537 | break; | | 537 | break; |
538 | default: | | 538 | default: |
539 | aprint_error(": bad chiptype\n"); | | 539 | aprint_error(": bad chiptype\n"); |
540 | agp_generic_detach(sc); | | 540 | agp_generic_detach(sc); |
541 | return EINVAL; | | 541 | return EINVAL; |
542 | } | | 542 | } |
543 | | | 543 | |
544 | switch (gcc1 & AGP_I855_GCC1_GMS) { | | 544 | switch (gcc1 & AGP_I855_GCC1_GMS) { |
545 | case AGP_I855_GCC1_GMS_STOLEN_1M: | | 545 | case AGP_I855_GCC1_GMS_STOLEN_1M: |
546 | stolen = 1024; | | 546 | stolen = 1024; |
547 | break; | | 547 | break; |
548 | case AGP_I855_GCC1_GMS_STOLEN_4M: | | 548 | case AGP_I855_GCC1_GMS_STOLEN_4M: |
549 | stolen = 4 * 1024; | | 549 | stolen = 4 * 1024; |
550 | break; | | 550 | break; |
551 | case AGP_I855_GCC1_GMS_STOLEN_8M: | | 551 | case AGP_I855_GCC1_GMS_STOLEN_8M: |
552 | stolen = 8 * 1024; | | 552 | stolen = 8 * 1024; |
553 | break; | | 553 | break; |
554 | case AGP_I855_GCC1_GMS_STOLEN_16M: | | 554 | case AGP_I855_GCC1_GMS_STOLEN_16M: |
555 | stolen = 16 * 1024; | | 555 | stolen = 16 * 1024; |
556 | break; | | 556 | break; |
557 | case AGP_I855_GCC1_GMS_STOLEN_32M: | | 557 | case AGP_I855_GCC1_GMS_STOLEN_32M: |
558 | stolen = 32 * 1024; | | 558 | stolen = 32 * 1024; |
559 | break; | | 559 | break; |
560 | case AGP_I915_GCC1_GMS_STOLEN_48M: | | 560 | case AGP_I915_GCC1_GMS_STOLEN_48M: |
561 | stolen = 48 * 1024; | | 561 | stolen = 48 * 1024; |
562 | break; | | 562 | break; |
563 | case AGP_I915_GCC1_GMS_STOLEN_64M: | | 563 | case AGP_I915_GCC1_GMS_STOLEN_64M: |
564 | stolen = 64 * 1024; | | 564 | stolen = 64 * 1024; |
565 | break; | | 565 | break; |
566 | case AGP_G33_GCC1_GMS_STOLEN_128M: | | 566 | case AGP_G33_GCC1_GMS_STOLEN_128M: |
567 | stolen = 128 * 1024; | | 567 | stolen = 128 * 1024; |
568 | break; | | 568 | break; |
569 | case AGP_G33_GCC1_GMS_STOLEN_256M: | | 569 | case AGP_G33_GCC1_GMS_STOLEN_256M: |
570 | stolen = 256 * 1024; | | 570 | stolen = 256 * 1024; |
571 | break; | | 571 | break; |
572 | case AGP_G4X_GCC1_GMS_STOLEN_96M: | | 572 | case AGP_G4X_GCC1_GMS_STOLEN_96M: |
573 | stolen = 96 * 1024; | | 573 | stolen = 96 * 1024; |
574 | break; | | 574 | break; |
575 | case AGP_G4X_GCC1_GMS_STOLEN_160M: | | 575 | case AGP_G4X_GCC1_GMS_STOLEN_160M: |
576 | stolen = 160 * 1024; | | 576 | stolen = 160 * 1024; |
577 | break; | | 577 | break; |
578 | case AGP_G4X_GCC1_GMS_STOLEN_224M: | | 578 | case AGP_G4X_GCC1_GMS_STOLEN_224M: |
579 | stolen = 224 * 1024; | | 579 | stolen = 224 * 1024; |
580 | break; | | 580 | break; |
581 | case AGP_G4X_GCC1_GMS_STOLEN_352M: | | 581 | case AGP_G4X_GCC1_GMS_STOLEN_352M: |
582 | stolen = 352 * 1024; | | 582 | stolen = 352 * 1024; |
583 | break; | | 583 | break; |
584 | default: | | 584 | default: |
585 | aprint_error( | | 585 | aprint_error( |
586 | ": unknown memory configuration, disabling\n"); | | 586 | ": unknown memory configuration, disabling\n"); |
587 | agp_generic_detach(sc); | | 587 | agp_generic_detach(sc); |
588 | return EINVAL; | | 588 | return EINVAL; |
589 | } | | 589 | } |
590 | | | 590 | |
591 | switch (gcc1 & AGP_I855_GCC1_GMS) { | | 591 | switch (gcc1 & AGP_I855_GCC1_GMS) { |
592 | case AGP_I915_GCC1_GMS_STOLEN_48M: | | 592 | case AGP_I915_GCC1_GMS_STOLEN_48M: |
593 | case AGP_I915_GCC1_GMS_STOLEN_64M: | | 593 | case AGP_I915_GCC1_GMS_STOLEN_64M: |
594 | if (isc->chiptype != CHIP_I915 && | | 594 | if (isc->chiptype != CHIP_I915 && |
595 | isc->chiptype != CHIP_I965 && | | 595 | isc->chiptype != CHIP_I965 && |
596 | isc->chiptype != CHIP_G33 && | | 596 | isc->chiptype != CHIP_G33 && |
597 | isc->chiptype != CHIP_G4X) | | 597 | isc->chiptype != CHIP_G4X) |
598 | stolen = 0; | | 598 | stolen = 0; |
599 | break; | | 599 | break; |
600 | case AGP_G33_GCC1_GMS_STOLEN_128M: | | 600 | case AGP_G33_GCC1_GMS_STOLEN_128M: |
601 | case AGP_G33_GCC1_GMS_STOLEN_256M: | | 601 | case AGP_G33_GCC1_GMS_STOLEN_256M: |
602 | if (isc->chiptype != CHIP_I965 && | | 602 | if (isc->chiptype != CHIP_I965 && |
603 | isc->chiptype != CHIP_G33 && | | 603 | isc->chiptype != CHIP_G33 && |
604 | isc->chiptype != CHIP_G4X) | | 604 | isc->chiptype != CHIP_G4X) |
605 | stolen = 0; | | 605 | stolen = 0; |
606 | break; | | 606 | break; |
607 | case AGP_G4X_GCC1_GMS_STOLEN_96M: | | 607 | case AGP_G4X_GCC1_GMS_STOLEN_96M: |
608 | case AGP_G4X_GCC1_GMS_STOLEN_160M: | | 608 | case AGP_G4X_GCC1_GMS_STOLEN_160M: |
609 | case AGP_G4X_GCC1_GMS_STOLEN_224M: | | 609 | case AGP_G4X_GCC1_GMS_STOLEN_224M: |
610 | case AGP_G4X_GCC1_GMS_STOLEN_352M: | | 610 | case AGP_G4X_GCC1_GMS_STOLEN_352M: |
611 | if (isc->chiptype != CHIP_I965 && | | 611 | if (isc->chiptype != CHIP_I965 && |
612 | isc->chiptype != CHIP_G4X) | | 612 | isc->chiptype != CHIP_G4X) |
613 | stolen = 0; | | 613 | stolen = 0; |
614 | break; | | 614 | break; |
615 | } | | 615 | } |
616 | | | 616 | |
617 | /* BIOS space */ | | 617 | /* BIOS space */ |
618 | gtt_size += 4; | | 618 | gtt_size += 4; |
619 | | | 619 | |
620 | isc->stolen = (stolen - gtt_size) * 1024 / 4096; | | 620 | isc->stolen = (stolen - gtt_size) * 1024 / 4096; |
621 | | | 621 | |
622 | if (isc->stolen > 0) { | | 622 | if (isc->stolen > 0) { |
623 | aprint_normal(": detected %dk stolen memory\n%s", | | 623 | aprint_normal(": detected %dk stolen memory\n%s", |
624 | isc->stolen * 4, device_xname(sc->as_dev)); | | 624 | isc->stolen * 4, device_xname(sc->as_dev)); |
625 | } | | 625 | } |
626 | | | 626 | |
627 | /* GATT address is already in there, make sure it's enabled */ | | 627 | /* GATT address is already in there, make sure it's enabled */ |
628 | pgtblctl |= 1; | | 628 | pgtblctl |= 1; |
629 | WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); | | 629 | WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); |
630 | | | 630 | |
631 | gatt->ag_physical = pgtblctl & ~1; | | 631 | gatt->ag_physical = pgtblctl & ~1; |
632 | } | | 632 | } |
633 | | | 633 | |
634 | /* | | 634 | /* |
635 | * Make sure the chipset can see everything. | | 635 | * Make sure the chipset can see everything. |
636 | */ | | 636 | */ |
637 | agp_flush_cache(); | | 637 | agp_flush_cache(); |
638 | | | 638 | |
639 | return 0; | | 639 | return 0; |
640 | } | | 640 | } |
641 | | | 641 | |
642 | #if 0 | | 642 | #if 0 |
643 | static int | | 643 | static int |
644 | agp_i810_detach(struct agp_softc *sc) | | 644 | agp_i810_detach(struct agp_softc *sc) |
645 | { | | 645 | { |
646 | int error; | | 646 | int error; |
647 | struct agp_i810_softc *isc = sc->as_chipc; | | 647 | struct agp_i810_softc *isc = sc->as_chipc; |
648 | | | 648 | |
649 | error = agp_generic_detach(sc); | | 649 | error = agp_generic_detach(sc); |
650 | if (error) | | 650 | if (error) |
651 | return error; | | 651 | return error; |
652 | | | 652 | |
653 | /* Clear the GATT base. */ | | 653 | /* Clear the GATT base. */ |
654 | if (sc->chiptype == CHIP_I810) { | | 654 | if (sc->chiptype == CHIP_I810) { |
655 | WRITE4(AGP_I810_PGTBL_CTL, 0); | | 655 | WRITE4(AGP_I810_PGTBL_CTL, 0); |
656 | } else { | | 656 | } else { |
657 | unsigned int pgtblctl; | | 657 | unsigned int pgtblctl; |
658 | pgtblctl = READ4(AGP_I810_PGTBL_CTL); | | 658 | pgtblctl = READ4(AGP_I810_PGTBL_CTL); |
659 | pgtblctl &= ~1; | | 659 | pgtblctl &= ~1; |
660 | WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); | | 660 | WRITE4(AGP_I810_PGTBL_CTL, pgtblctl); |
661 | } | | 661 | } |
662 | | | 662 | |
663 | /* Put the aperture back the way it started. */ | | 663 | /* Put the aperture back the way it started. */ |
664 | AGP_SET_APERTURE(sc, isc->initial_aperture); | | 664 | AGP_SET_APERTURE(sc, isc->initial_aperture); |
665 | | | 665 | |
666 | if (sc->chiptype == CHIP_I810) { | | 666 | if (sc->chiptype == CHIP_I810) { |
667 | agp_free_dmamem(sc->as_dmat, gatt->ag_size, gatt->ag_dmamap, | | 667 | agp_free_dmamem(sc->as_dmat, gatt->ag_size, gatt->ag_dmamap, |
668 | (void *)gatt->ag_virtual, &gatt->ag_dmaseg, 1); | | 668 | (void *)gatt->ag_virtual, &gatt->ag_dmaseg, 1); |
669 | } | | 669 | } |
670 | free(sc->gatt, M_AGP); | | 670 | free(sc->gatt, M_AGP); |
671 | | | 671 | |
672 | return 0; | | 672 | return 0; |
673 | } | | 673 | } |
674 | #endif | | 674 | #endif |
675 | | | 675 | |
676 | static u_int32_t | | 676 | static u_int32_t |
677 | agp_i810_get_aperture(struct agp_softc *sc) | | 677 | agp_i810_get_aperture(struct agp_softc *sc) |
678 | { | | 678 | { |
679 | struct agp_i810_softc *isc = sc->as_chipc; | | 679 | struct agp_i810_softc *isc = sc->as_chipc; |
680 | pcireg_t reg; | | 680 | pcireg_t reg; |
681 | u_int32_t size; | | 681 | u_int32_t size; |
682 | u_int16_t miscc, gcc1, msac; | | 682 | u_int16_t miscc, gcc1, msac; |
683 | | | 683 | |
684 | size = 0; | | 684 | size = 0; |
685 | | | 685 | |
686 | switch (isc->chiptype) { | | 686 | switch (isc->chiptype) { |
687 | case CHIP_I810: | | 687 | case CHIP_I810: |
688 | reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I810_SMRAM); | | 688 | reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I810_SMRAM); |
689 | miscc = (u_int16_t)(reg >> 16); | | 689 | miscc = (u_int16_t)(reg >> 16); |
690 | if ((miscc & AGP_I810_MISCC_WINSIZE) == | | 690 | if ((miscc & AGP_I810_MISCC_WINSIZE) == |
691 | AGP_I810_MISCC_WINSIZE_32) | | 691 | AGP_I810_MISCC_WINSIZE_32) |
692 | size = 32 * 1024 * 1024; | | 692 | size = 32 * 1024 * 1024; |
693 | else | | 693 | else |
694 | size = 64 * 1024 * 1024; | | 694 | size = 64 * 1024 * 1024; |
695 | break; | | 695 | break; |
696 | case CHIP_I830: | | 696 | case CHIP_I830: |
697 | reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I830_GCC0); | | 697 | reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I830_GCC0); |
698 | gcc1 = (u_int16_t)(reg >> 16); | | 698 | gcc1 = (u_int16_t)(reg >> 16); |
699 | if ((gcc1 & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64) | | 699 | if ((gcc1 & AGP_I830_GCC1_GMASIZE) == AGP_I830_GCC1_GMASIZE_64) |
700 | size = 64 * 1024 * 1024; | | 700 | size = 64 * 1024 * 1024; |
701 | else | | 701 | else |
702 | size = 128 * 1024 * 1024; | | 702 | size = 128 * 1024 * 1024; |
703 | break; | | 703 | break; |
704 | case CHIP_I855: | | 704 | case CHIP_I855: |
705 | size = 128 * 1024 * 1024; | | 705 | size = 128 * 1024 * 1024; |
706 | break; | | 706 | break; |
707 | case CHIP_I915: | | 707 | case CHIP_I915: |
708 | case CHIP_G33: | | 708 | case CHIP_G33: |
| | | 709 | case CHIP_G4X: |
709 | reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I915_MSAC); | | 710 | reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I915_MSAC); |
710 | msac = (u_int16_t)(reg >> 16); | | 711 | msac = (u_int16_t)(reg >> 16); |
711 | if (msac & AGP_I915_MSAC_APER_128M) | | 712 | if (msac & AGP_I915_MSAC_APER_128M) |
712 | size = 128 * 1024 * 1024; | | 713 | size = 128 * 1024 * 1024; |
713 | else | | 714 | else |
714 | size = 256 * 1024 * 1024; | | 715 | size = 256 * 1024 * 1024; |
715 | break; | | 716 | break; |
716 | case CHIP_I965: | | 717 | case CHIP_I965: |
717 | size = 512 * 1024 * 1024; | | 718 | size = 512 * 1024 * 1024; |
718 | break; | | 719 | break; |
719 | case CHIP_G4X: | | | |
720 | reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_G4X_MSAC); | | | |
721 | msac = (u_int16_t)(reg >> 16); | | | |
722 | switch (msac & AGP_G4X_MSAC_MASK) { | | | |
723 | case AGP_G4X_MSAC_APER_256M: | | | |
724 | size = 256 * 1024 * 1024; | | | |
725 | case AGP_G4X_MSAC_APER_512M: | | | |
726 | size = 512 * 1024 * 1024; | | | |
727 | } | | | |
728 | break; | | | |
729 | default: | | 720 | default: |
730 | aprint_error(": Unknown chipset\n"); | | 721 | aprint_error(": Unknown chipset\n"); |
731 | } | | 722 | } |
732 | | | 723 | |
733 | return size; | | 724 | return size; |
734 | } | | 725 | } |
735 | | | 726 | |
736 | static int | | 727 | static int |
737 | agp_i810_set_aperture(struct agp_softc *sc, u_int32_t aperture) | | 728 | agp_i810_set_aperture(struct agp_softc *sc, u_int32_t aperture) |
738 | { | | 729 | { |
739 | struct agp_i810_softc *isc = sc->as_chipc; | | 730 | struct agp_i810_softc *isc = sc->as_chipc; |
740 | pcireg_t reg; | | 731 | pcireg_t reg; |
741 | u_int16_t miscc, gcc1; | | 732 | u_int16_t miscc, gcc1; |
742 | | | 733 | |
743 | switch (isc->chiptype) { | | 734 | switch (isc->chiptype) { |
744 | case CHIP_I810: | | 735 | case CHIP_I810: |
745 | /* | | 736 | /* |
746 | * Double check for sanity. | | 737 | * Double check for sanity. |
747 | */ | | 738 | */ |
748 | if (aperture != (32 * 1024 * 1024) && | | 739 | if (aperture != (32 * 1024 * 1024) && |
749 | aperture != (64 * 1024 * 1024)) { | | 740 | aperture != (64 * 1024 * 1024)) { |
750 | aprint_error_dev(sc->as_dev, "bad aperture size %d\n", | | 741 | aprint_error_dev(sc->as_dev, "bad aperture size %d\n", |
751 | aperture); | | 742 | aperture); |
752 | return EINVAL; | | 743 | return EINVAL; |
753 | } | | 744 | } |
754 | | | 745 | |
755 | reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I810_SMRAM); | | 746 | reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I810_SMRAM); |
756 | miscc = (u_int16_t)(reg >> 16); | | 747 | miscc = (u_int16_t)(reg >> 16); |
757 | miscc &= ~AGP_I810_MISCC_WINSIZE; | | 748 | miscc &= ~AGP_I810_MISCC_WINSIZE; |
758 | if (aperture == 32 * 1024 * 1024) | | 749 | if (aperture == 32 * 1024 * 1024) |
759 | miscc |= AGP_I810_MISCC_WINSIZE_32; | | 750 | miscc |= AGP_I810_MISCC_WINSIZE_32; |
760 | else | | 751 | else |
761 | miscc |= AGP_I810_MISCC_WINSIZE_64; | | 752 | miscc |= AGP_I810_MISCC_WINSIZE_64; |
762 | | | 753 | |
763 | reg &= 0x0000ffff; | | 754 | reg &= 0x0000ffff; |
764 | reg |= ((pcireg_t)miscc) << 16; | | 755 | reg |= ((pcireg_t)miscc) << 16; |
765 | pci_conf_write(sc->as_pc, sc->as_tag, AGP_I810_SMRAM, reg); | | 756 | pci_conf_write(sc->as_pc, sc->as_tag, AGP_I810_SMRAM, reg); |
766 | break; | | 757 | break; |
767 | case CHIP_I830: | | 758 | case CHIP_I830: |
768 | if (aperture != (64 * 1024 * 1024) && | | 759 | if (aperture != (64 * 1024 * 1024) && |
769 | aperture != (128 * 1024 * 1024)) { | | 760 | aperture != (128 * 1024 * 1024)) { |
770 | aprint_error_dev(sc->as_dev, "bad aperture size %d\n", | | 761 | aprint_error_dev(sc->as_dev, "bad aperture size %d\n", |
771 | aperture); | | 762 | aperture); |
772 | return EINVAL; | | 763 | return EINVAL; |
773 | } | | 764 | } |
774 | reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I830_GCC0); | | 765 | reg = pci_conf_read(sc->as_pc, sc->as_tag, AGP_I830_GCC0); |
775 | gcc1 = (u_int16_t)(reg >> 16); | | 766 | gcc1 = (u_int16_t)(reg >> 16); |
776 | gcc1 &= ~AGP_I830_GCC1_GMASIZE; | | 767 | gcc1 &= ~AGP_I830_GCC1_GMASIZE; |
777 | if (aperture == 64 * 1024 * 1024) | | 768 | if (aperture == 64 * 1024 * 1024) |
778 | gcc1 |= AGP_I830_GCC1_GMASIZE_64; | | 769 | gcc1 |= AGP_I830_GCC1_GMASIZE_64; |
779 | else | | 770 | else |
780 | gcc1 |= AGP_I830_GCC1_GMASIZE_128; | | 771 | gcc1 |= AGP_I830_GCC1_GMASIZE_128; |
781 | | | 772 | |
782 | reg &= 0x0000ffff; | | 773 | reg &= 0x0000ffff; |
783 | reg |= ((pcireg_t)gcc1) << 16; | | 774 | reg |= ((pcireg_t)gcc1) << 16; |
784 | pci_conf_write(sc->as_pc, sc->as_tag, AGP_I830_GCC0, reg); | | 775 | pci_conf_write(sc->as_pc, sc->as_tag, AGP_I830_GCC0, reg); |
785 | break; | | 776 | break; |
786 | case CHIP_I855: | | 777 | case CHIP_I855: |
787 | case CHIP_I915: | | 778 | case CHIP_I915: |
788 | if (aperture != agp_i810_get_aperture(sc)) { | | 779 | if (aperture != agp_i810_get_aperture(sc)) { |
789 | aprint_error_dev(sc->as_dev, "bad aperture size %d\n", | | 780 | aprint_error_dev(sc->as_dev, "bad aperture size %d\n", |
790 | aperture); | | 781 | aperture); |
791 | return EINVAL; | | 782 | return EINVAL; |
792 | } | | 783 | } |
793 | break; | | 784 | break; |
794 | case CHIP_I965: | | 785 | case CHIP_I965: |
795 | if (aperture != 512 * 1024 * 1024) { | | 786 | if (aperture != 512 * 1024 * 1024) { |
796 | aprint_error_dev(sc->as_dev, "bad aperture size %d\n", | | 787 | aprint_error_dev(sc->as_dev, "bad aperture size %d\n", |
797 | aperture); | | 788 | aperture); |
798 | return EINVAL; | | 789 | return EINVAL; |
799 | } | | 790 | } |
800 | break; | | 791 | break; |
801 | } | | 792 | } |
802 | | | 793 | |
803 | return 0; | | 794 | return 0; |
804 | } | | 795 | } |
805 | | | 796 | |
806 | static int | | 797 | static int |
807 | agp_i810_bind_page(struct agp_softc *sc, off_t offset, bus_addr_t physical) | | 798 | agp_i810_bind_page(struct agp_softc *sc, off_t offset, bus_addr_t physical) |
808 | { | | 799 | { |
809 | struct agp_i810_softc *isc = sc->as_chipc; | | 800 | struct agp_i810_softc *isc = sc->as_chipc; |
810 | | | 801 | |
811 | if (offset < 0 || offset >= (isc->gatt->ag_entries << AGP_PAGE_SHIFT)) { | | 802 | if (offset < 0 || offset >= (isc->gatt->ag_entries << AGP_PAGE_SHIFT)) { |
812 | #ifdef AGP_DEBUG | | 803 | #ifdef AGP_DEBUG |
813 | printf("%s: failed: offset 0x%08x, shift %d, entries %d\n", | | 804 | printf("%s: failed: offset 0x%08x, shift %d, entries %d\n", |
814 | device_xname(sc->as_dev), (int)offset, AGP_PAGE_SHIFT, | | 805 | device_xname(sc->as_dev), (int)offset, AGP_PAGE_SHIFT, |
815 | isc->gatt->ag_entries); | | 806 | isc->gatt->ag_entries); |
816 | #endif | | 807 | #endif |
817 | return EINVAL; | | 808 | return EINVAL; |
818 | } | | 809 | } |
819 | | | 810 | |
820 | if (isc->chiptype != CHIP_I830) { | | 811 | if (isc->chiptype != CHIP_I830) { |
821 | if ((offset >> AGP_PAGE_SHIFT) < isc->stolen) { | | 812 | if ((offset >> AGP_PAGE_SHIFT) < isc->stolen) { |
822 | #ifdef AGP_DEBUG | | 813 | #ifdef AGP_DEBUG |
823 | printf("%s: trying to bind into stolen memory", | | 814 | printf("%s: trying to bind into stolen memory", |
824 | device_xname(sc->as_dev)); | | 815 | device_xname(sc->as_dev)); |
825 | #endif | | 816 | #endif |
826 | return EINVAL; | | 817 | return EINVAL; |
827 | } | | 818 | } |
828 | } | | 819 | } |
829 | | | 820 | |
830 | agp_i810_write_gtt_entry(isc, offset, physical | 1); | | 821 | agp_i810_write_gtt_entry(isc, offset, physical | 1); |
831 | return 0; | | 822 | return 0; |
832 | } | | 823 | } |
833 | | | 824 | |
834 | static int | | 825 | static int |
835 | agp_i810_unbind_page(struct agp_softc *sc, off_t offset) | | 826 | agp_i810_unbind_page(struct agp_softc *sc, off_t offset) |
836 | { | | 827 | { |
837 | struct agp_i810_softc *isc = sc->as_chipc; | | 828 | struct agp_i810_softc *isc = sc->as_chipc; |
838 | | | 829 | |
839 | if (offset < 0 || offset >= (isc->gatt->ag_entries << AGP_PAGE_SHIFT)) | | 830 | if (offset < 0 || offset >= (isc->gatt->ag_entries << AGP_PAGE_SHIFT)) |
840 | return EINVAL; | | 831 | return EINVAL; |
841 | | | 832 | |
842 | if (isc->chiptype != CHIP_I810 ) { | | 833 | if (isc->chiptype != CHIP_I810 ) { |
843 | if ((offset >> AGP_PAGE_SHIFT) < isc->stolen) { | | 834 | if ((offset >> AGP_PAGE_SHIFT) < isc->stolen) { |
844 | #ifdef AGP_DEBUG | | 835 | #ifdef AGP_DEBUG |
845 | printf("%s: trying to unbind from stolen memory", | | 836 | printf("%s: trying to unbind from stolen memory", |
846 | device_xname(sc->as_dev)); | | 837 | device_xname(sc->as_dev)); |
847 | #endif | | 838 | #endif |
848 | return EINVAL; | | 839 | return EINVAL; |
849 | } | | 840 | } |
850 | } | | 841 | } |
851 | | | 842 | |
852 | agp_i810_write_gtt_entry(isc, offset, 0); | | 843 | agp_i810_write_gtt_entry(isc, offset, 0); |
853 | return 0; | | 844 | return 0; |
854 | } | | 845 | } |
855 | | | 846 | |
856 | /* | | 847 | /* |
857 | * Writing via memory mapped registers already flushes all TLBs. | | 848 | * Writing via memory mapped registers already flushes all TLBs. |
858 | */ | | 849 | */ |
859 | static void | | 850 | static void |
860 | agp_i810_flush_tlb(struct agp_softc *sc) | | 851 | agp_i810_flush_tlb(struct agp_softc *sc) |
861 | { | | 852 | { |
862 | } | | 853 | } |
863 | | | 854 | |
864 | static int | | 855 | static int |
865 | agp_i810_enable(struct agp_softc *sc, u_int32_t mode) | | 856 | agp_i810_enable(struct agp_softc *sc, u_int32_t mode) |
866 | { | | 857 | { |
867 | | | 858 | |
868 | return 0; | | 859 | return 0; |
869 | } | | 860 | } |
870 | | | 861 | |
871 | static struct agp_memory * | | 862 | static struct agp_memory * |
872 | agp_i810_alloc_memory(struct agp_softc *sc, int type, vsize_t size) | | 863 | agp_i810_alloc_memory(struct agp_softc *sc, int type, vsize_t size) |
873 | { | | 864 | { |
874 | struct agp_i810_softc *isc = sc->as_chipc; | | 865 | struct agp_i810_softc *isc = sc->as_chipc; |
875 | struct agp_memory *mem; | | 866 | struct agp_memory *mem; |
876 | | | 867 | |
877 | #ifdef AGP_DEBUG | | 868 | #ifdef AGP_DEBUG |
878 | printf("AGP: alloc(%d, 0x%x)\n", type, (int) size); | | 869 | printf("AGP: alloc(%d, 0x%x)\n", type, (int) size); |
879 | #endif | | 870 | #endif |
880 | | | 871 | |
881 | if ((size & (AGP_PAGE_SIZE - 1)) != 0) | | 872 | if ((size & (AGP_PAGE_SIZE - 1)) != 0) |
882 | return 0; | | 873 | return 0; |
883 | | | 874 | |
884 | if (sc->as_allocated + size > sc->as_maxmem) | | 875 | if (sc->as_allocated + size > sc->as_maxmem) |
885 | return 0; | | 876 | return 0; |
886 | | | 877 | |
887 | if (type == 1) { | | 878 | if (type == 1) { |
888 | /* | | 879 | /* |
889 | * Mapping local DRAM into GATT. | | 880 | * Mapping local DRAM into GATT. |
890 | */ | | 881 | */ |
891 | if (isc->chiptype != CHIP_I810 ) | | 882 | if (isc->chiptype != CHIP_I810 ) |
892 | return 0; | | 883 | return 0; |
893 | if (size != isc->dcache_size) | | 884 | if (size != isc->dcache_size) |
894 | return 0; | | 885 | return 0; |
895 | } else if (type == 2) { | | 886 | } else if (type == 2) { |
896 | /* | | 887 | /* |
897 | * Bogus mapping for the hardware cursor. | | 888 | * Bogus mapping for the hardware cursor. |
898 | */ | | 889 | */ |
899 | if (size != AGP_PAGE_SIZE && size != 4 * AGP_PAGE_SIZE) | | 890 | if (size != AGP_PAGE_SIZE && size != 4 * AGP_PAGE_SIZE) |
900 | return 0; | | 891 | return 0; |
901 | } | | 892 | } |
902 | | | 893 | |
903 | mem = malloc(sizeof *mem, M_AGP, M_WAITOK|M_ZERO); | | 894 | mem = malloc(sizeof *mem, M_AGP, M_WAITOK|M_ZERO); |
904 | if (mem == NULL) | | 895 | if (mem == NULL) |
905 | return NULL; | | 896 | return NULL; |
906 | mem->am_id = sc->as_nextid++; | | 897 | mem->am_id = sc->as_nextid++; |
907 | mem->am_size = size; | | 898 | mem->am_size = size; |
908 | mem->am_type = type; | | 899 | mem->am_type = type; |
909 | | | 900 | |
910 | if (type == 2) { | | 901 | if (type == 2) { |
911 | /* | | 902 | /* |
912 | * Allocate and wire down the memory now so that we can | | 903 | * Allocate and wire down the memory now so that we can |
913 | * get its physical address. | | 904 | * get its physical address. |
914 | */ | | 905 | */ |
915 | mem->am_dmaseg = malloc(sizeof *mem->am_dmaseg, M_AGP, | | 906 | mem->am_dmaseg = malloc(sizeof *mem->am_dmaseg, M_AGP, |
916 | M_WAITOK); | | 907 | M_WAITOK); |
917 | if (mem->am_dmaseg == NULL) { | | 908 | if (mem->am_dmaseg == NULL) { |
918 | free(mem, M_AGP); | | 909 | free(mem, M_AGP); |
919 | return NULL; | | 910 | return NULL; |
920 | } | | 911 | } |
921 | if (agp_alloc_dmamem(sc->as_dmat, size, 0, | | 912 | if (agp_alloc_dmamem(sc->as_dmat, size, 0, |
922 | &mem->am_dmamap, &mem->am_virtual, &mem->am_physical, | | 913 | &mem->am_dmamap, &mem->am_virtual, &mem->am_physical, |
923 | mem->am_dmaseg, 1, &mem->am_nseg) != 0) { | | 914 | mem->am_dmaseg, 1, &mem->am_nseg) != 0) { |
924 | free(mem->am_dmaseg, M_AGP); | | 915 | free(mem->am_dmaseg, M_AGP); |
925 | free(mem, M_AGP); | | 916 | free(mem, M_AGP); |
926 | return NULL; | | 917 | return NULL; |
927 | } | | 918 | } |
928 | memset(mem->am_virtual, 0, size); | | 919 | memset(mem->am_virtual, 0, size); |
929 | } else if (type != 1) { | | 920 | } else if (type != 1) { |
930 | if (bus_dmamap_create(sc->as_dmat, size, size / PAGE_SIZE + 1, | | 921 | if (bus_dmamap_create(sc->as_dmat, size, size / PAGE_SIZE + 1, |
931 | size, 0, BUS_DMA_NOWAIT, | | 922 | size, 0, BUS_DMA_NOWAIT, |
932 | &mem->am_dmamap) != 0) { | | 923 | &mem->am_dmamap) != 0) { |
933 | free(mem, M_AGP); | | 924 | free(mem, M_AGP); |
934 | return NULL; | | 925 | return NULL; |
935 | } | | 926 | } |
936 | } | | 927 | } |
937 | | | 928 | |
938 | TAILQ_INSERT_TAIL(&sc->as_memory, mem, am_link); | | 929 | TAILQ_INSERT_TAIL(&sc->as_memory, mem, am_link); |
939 | sc->as_allocated += size; | | 930 | sc->as_allocated += size; |
940 | | | 931 | |
941 | return mem; | | 932 | return mem; |
942 | } | | 933 | } |
943 | | | 934 | |
944 | static int | | 935 | static int |
945 | agp_i810_free_memory(struct agp_softc *sc, struct agp_memory *mem) | | 936 | agp_i810_free_memory(struct agp_softc *sc, struct agp_memory *mem) |
946 | { | | 937 | { |
947 | if (mem->am_is_bound) | | 938 | if (mem->am_is_bound) |
948 | return EBUSY; | | 939 | return EBUSY; |
949 | | | 940 | |
950 | if (mem->am_type == 2) { | | 941 | if (mem->am_type == 2) { |
951 | agp_free_dmamem(sc->as_dmat, mem->am_size, mem->am_dmamap, | | 942 | agp_free_dmamem(sc->as_dmat, mem->am_size, mem->am_dmamap, |
952 | mem->am_virtual, mem->am_dmaseg, mem->am_nseg); | | 943 | mem->am_virtual, mem->am_dmaseg, mem->am_nseg); |
953 | free(mem->am_dmaseg, M_AGP); | | 944 | free(mem->am_dmaseg, M_AGP); |
954 | } | | 945 | } |
955 | | | 946 | |
956 | sc->as_allocated -= mem->am_size; | | 947 | sc->as_allocated -= mem->am_size; |
957 | TAILQ_REMOVE(&sc->as_memory, mem, am_link); | | 948 | TAILQ_REMOVE(&sc->as_memory, mem, am_link); |
958 | free(mem, M_AGP); | | 949 | free(mem, M_AGP); |
959 | return 0; | | 950 | return 0; |
960 | } | | 951 | } |
961 | | | 952 | |
962 | static int | | 953 | static int |
963 | agp_i810_bind_memory(struct agp_softc *sc, struct agp_memory *mem, | | 954 | agp_i810_bind_memory(struct agp_softc *sc, struct agp_memory *mem, |
964 | off_t offset) | | 955 | off_t offset) |
965 | { | | 956 | { |
966 | struct agp_i810_softc *isc = sc->as_chipc; | | 957 | struct agp_i810_softc *isc = sc->as_chipc; |
967 | u_int32_t regval, i; | | 958 | u_int32_t regval, i; |
968 | | | 959 | |
969 | /* | | 960 | /* |
970 | * XXX evil hack: the PGTBL_CTL appearently gets overwritten by the | | 961 | * XXX evil hack: the PGTBL_CTL appearently gets overwritten by the |
971 | * X server for mysterious reasons which leads to crashes if we write | | 962 | * X server for mysterious reasons which leads to crashes if we write |
972 | * to the GTT through the MMIO window. | | 963 | * to the GTT through the MMIO window. |
973 | * Until the issue is solved, simply restore it. | | 964 | * Until the issue is solved, simply restore it. |
974 | */ | | 965 | */ |
975 | regval = bus_space_read_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL); | | 966 | regval = bus_space_read_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL); |
976 | if (regval != (isc->gatt->ag_physical | 1)) { | | 967 | if (regval != (isc->gatt->ag_physical | 1)) { |
977 | printf("agp_i810_bind_memory: PGTBL_CTL is 0x%x - fixing\n", | | 968 | printf("agp_i810_bind_memory: PGTBL_CTL is 0x%x - fixing\n", |
978 | regval); | | 969 | regval); |
979 | bus_space_write_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL, | | 970 | bus_space_write_4(isc->bst, isc->bsh, AGP_I810_PGTBL_CTL, |
980 | isc->gatt->ag_physical | 1); | | 971 | isc->gatt->ag_physical | 1); |
981 | } | | 972 | } |
982 | | | 973 | |
983 | if (mem->am_type == 2) { | | 974 | if (mem->am_type == 2) { |
984 | agp_i810_write_gtt_entry(isc, offset, mem->am_physical | 1); | | 975 | agp_i810_write_gtt_entry(isc, offset, mem->am_physical | 1); |
985 | mem->am_offset = offset; | | 976 | mem->am_offset = offset; |
986 | mem->am_is_bound = 1; | | 977 | mem->am_is_bound = 1; |
987 | return 0; | | 978 | return 0; |
988 | } | | 979 | } |
989 | | | 980 | |
990 | if (mem->am_type != 1) | | 981 | if (mem->am_type != 1) |
991 | return agp_generic_bind_memory(sc, mem, offset); | | 982 | return agp_generic_bind_memory(sc, mem, offset); |
992 | | | 983 | |
993 | if (isc->chiptype != CHIP_I810) | | 984 | if (isc->chiptype != CHIP_I810) |
994 | return EINVAL; | | 985 | return EINVAL; |
995 | | | 986 | |
996 | for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) | | 987 | for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) |
997 | agp_i810_write_gtt_entry(isc, offset, i | 3); | | 988 | agp_i810_write_gtt_entry(isc, offset, i | 3); |
998 | mem->am_is_bound = 1; | | 989 | mem->am_is_bound = 1; |
999 | return 0; | | 990 | return 0; |
1000 | } | | 991 | } |
1001 | | | 992 | |
1002 | static int | | 993 | static int |
1003 | agp_i810_unbind_memory(struct agp_softc *sc, struct agp_memory *mem) | | 994 | agp_i810_unbind_memory(struct agp_softc *sc, struct agp_memory *mem) |
1004 | { | | 995 | { |
1005 | struct agp_i810_softc *isc = sc->as_chipc; | | 996 | struct agp_i810_softc *isc = sc->as_chipc; |
1006 | u_int32_t i; | | 997 | u_int32_t i; |
1007 | | | 998 | |
1008 | if (mem->am_type == 2) { | | 999 | if (mem->am_type == 2) { |
1009 | agp_i810_write_gtt_entry(isc, mem->am_offset, 0); | | 1000 | agp_i810_write_gtt_entry(isc, mem->am_offset, 0); |
1010 | mem->am_offset = 0; | | 1001 | mem->am_offset = 0; |
1011 | mem->am_is_bound = 0; | | 1002 | mem->am_is_bound = 0; |
1012 | return 0; | | 1003 | return 0; |
1013 | } | | 1004 | } |
1014 | | | 1005 | |
1015 | if (mem->am_type != 1) | | 1006 | if (mem->am_type != 1) |
1016 | return agp_generic_unbind_memory(sc, mem); | | 1007 | return agp_generic_unbind_memory(sc, mem); |
1017 | | | 1008 | |
1018 | if (isc->chiptype != CHIP_I810) | | 1009 | if (isc->chiptype != CHIP_I810) |
1019 | return EINVAL; | | 1010 | return EINVAL; |
1020 | | | 1011 | |
1021 | for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) | | 1012 | for (i = 0; i < mem->am_size; i += AGP_PAGE_SIZE) |
1022 | agp_i810_write_gtt_entry(isc, i, 0); | | 1013 | agp_i810_write_gtt_entry(isc, i, 0); |
1023 | mem->am_is_bound = 0; | | 1014 | mem->am_is_bound = 0; |
1024 | return 0; | | 1015 | return 0; |
1025 | } | | 1016 | } |
1026 | | | 1017 | |
1027 | static bool | | 1018 | static bool |
1028 | agp_i810_resume(device_t dv PMF_FN_ARGS) | | 1019 | agp_i810_resume(device_t dv PMF_FN_ARGS) |
1029 | { | | 1020 | { |
1030 | struct agp_softc *sc = device_private(dv); | | 1021 | struct agp_softc *sc = device_private(dv); |
1031 | struct agp_i810_softc *isc = sc->as_chipc; | | 1022 | struct agp_i810_softc *isc = sc->as_chipc; |
1032 | | | 1023 | |
1033 | isc->pgtblctl = READ4(AGP_I810_PGTBL_CTL); | | 1024 | isc->pgtblctl = READ4(AGP_I810_PGTBL_CTL); |
1034 | agp_flush_cache(); | | 1025 | agp_flush_cache(); |
1035 | | | 1026 | |
1036 | return true; | | 1027 | return true; |
1037 | } | | 1028 | } |