FreeBSD/Linux Kernel Cross Reference
sys/dev/puc/puc_pci.c
1 /* $NetBSD: puc.c,v 1.7 2000/07/29 17:43:38 jlam Exp $ */
2
3 /*-
4 * Copyright (c) 2002 JF Hay. All rights reserved.
5 * Copyright (c) 2000 M. Warner Losh. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice unmodified, this list of conditions, and the following
12 * 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.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD: src/sys/dev/puc/puc_pci.c,v 1.10.2.1 2005/01/30 00:59:59 imp Exp $");
31
32 /*-
33 * Copyright (c) 1996, 1998, 1999
34 * Christopher G. Demetriou. All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software
45 * must display the following acknowledgement:
46 * This product includes software developed by Christopher G. Demetriou
47 * for the NetBSD Project.
48 * 4. The name of the author may not be used to endorse or promote products
49 * derived from this software without specific prior written permission
50 *
51 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
52 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
53 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
54 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
55 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
60 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 */
62
63 #include <sys/cdefs.h>
64 __FBSDID("$FreeBSD: src/sys/dev/puc/puc_pci.c,v 1.10.2.1 2005/01/30 00:59:59 imp Exp $");
65
66 #include "opt_puc.h"
67
68 #include <sys/param.h>
69 #include <sys/systm.h>
70 #include <sys/kernel.h>
71 #include <sys/module.h>
72 #include <sys/bus.h>
73 #include <sys/conf.h>
74 #include <sys/malloc.h>
75
76 #include <machine/bus.h>
77 #include <machine/resource.h>
78 #include <sys/rman.h>
79
80 #include <dev/pci/pcireg.h>
81 #include <dev/pci/pcivar.h>
82
83 #define PUC_ENTRAILS 1
84 #include <dev/puc/pucvar.h>
85
86 extern const struct puc_device_description puc_devices[];
87
88 int puc_config_win877(struct puc_softc *);
89
90 static const struct puc_device_description *
91 puc_find_description(uint32_t vend, uint32_t prod, uint32_t svend,
92 uint32_t sprod)
93 {
94 int i;
95
96 #define checkreg(val, index) \
97 (((val) & puc_devices[i].rmask[(index)]) == puc_devices[i].rval[(index)])
98
99 for (i = 0; puc_devices[i].name != NULL; i++) {
100 if (checkreg(vend, PUC_REG_VEND) &&
101 checkreg(prod, PUC_REG_PROD) &&
102 checkreg(svend, PUC_REG_SVEND) &&
103 checkreg(sprod, PUC_REG_SPROD))
104 return (&puc_devices[i]);
105 }
106
107 #undef checkreg
108
109 return (NULL);
110 }
111
112 static int
113 puc_pci_probe(device_t dev)
114 {
115 uint32_t v1, v2, d1, d2;
116 const struct puc_device_description *desc;
117
118 if ((pci_read_config(dev, PCIR_HDRTYPE, 1) & PCIM_HDRTYPE) != 0)
119 return (ENXIO);
120
121 v1 = pci_read_config(dev, PCIR_VENDOR, 2);
122 d1 = pci_read_config(dev, PCIR_DEVICE, 2);
123 v2 = pci_read_config(dev, PCIR_SUBVEND_0, 2);
124 d2 = pci_read_config(dev, PCIR_SUBDEV_0, 2);
125
126 desc = puc_find_description(v1, d1, v2, d2);
127 if (desc == NULL)
128 return (ENXIO);
129 device_set_desc(dev, desc->name);
130 return (0);
131 }
132
133 static int
134 puc_pci_attach(device_t dev)
135 {
136 uint32_t v1, v2, d1, d2;
137
138 v1 = pci_read_config(dev, PCIR_VENDOR, 2);
139 d1 = pci_read_config(dev, PCIR_DEVICE, 2);
140 v2 = pci_read_config(dev, PCIR_SUBVEND_0, 2);
141 d2 = pci_read_config(dev, PCIR_SUBDEV_0, 2);
142 return (puc_attach(dev, puc_find_description(v1, d1, v2, d2)));
143 }
144
145 static device_method_t puc_pci_methods[] = {
146 /* Device interface */
147 DEVMETHOD(device_probe, puc_pci_probe),
148 DEVMETHOD(device_attach, puc_pci_attach),
149
150 DEVMETHOD(bus_alloc_resource, puc_alloc_resource),
151 DEVMETHOD(bus_release_resource, puc_release_resource),
152 DEVMETHOD(bus_get_resource, puc_get_resource),
153 DEVMETHOD(bus_read_ivar, puc_read_ivar),
154 DEVMETHOD(bus_setup_intr, puc_setup_intr),
155 DEVMETHOD(bus_teardown_intr, puc_teardown_intr),
156 DEVMETHOD(bus_print_child, bus_generic_print_child),
157 DEVMETHOD(bus_driver_added, bus_generic_driver_added),
158 { 0, 0 }
159 };
160
161 static driver_t puc_pci_driver = {
162 "puc",
163 puc_pci_methods,
164 sizeof(struct puc_softc),
165 };
166
167 DRIVER_MODULE(puc, pci, puc_pci_driver, puc_devclass, 0, 0);
168 DRIVER_MODULE(puc, cardbus, puc_pci_driver, puc_devclass, 0, 0);
169
170
171 #define rdspio(indx) (bus_space_write_1(bst, bsh, efir, indx), \
172 bus_space_read_1(bst, bsh, efdr))
173 #define wrspio(indx,data) (bus_space_write_1(bst, bsh, efir, indx), \
174 bus_space_write_1(bst, bsh, efdr, data))
175
176 #ifdef PUC_DEBUG
177 static void
178 puc_print_win877(bus_space_tag_t bst, bus_space_handle_t bsh, u_int efir,
179 u_int efdr)
180 {
181 u_char cr00, cr01, cr04, cr09, cr0d, cr14, cr15, cr16, cr17;
182 u_char cr18, cr19, cr24, cr25, cr28, cr2c, cr31, cr32;
183
184 cr00 = rdspio(0x00);
185 cr01 = rdspio(0x01);
186 cr04 = rdspio(0x04);
187 cr09 = rdspio(0x09);
188 cr0d = rdspio(0x0d);
189 cr14 = rdspio(0x14);
190 cr15 = rdspio(0x15);
191 cr16 = rdspio(0x16);
192 cr17 = rdspio(0x17);
193 cr18 = rdspio(0x18);
194 cr19 = rdspio(0x19);
195 cr24 = rdspio(0x24);
196 cr25 = rdspio(0x25);
197 cr28 = rdspio(0x28);
198 cr2c = rdspio(0x2c);
199 cr31 = rdspio(0x31);
200 cr32 = rdspio(0x32);
201 printf("877T: cr00 %x, cr01 %x, cr04 %x, cr09 %x, cr0d %x, cr14 %x, "
202 "cr15 %x, cr16 %x, cr17 %x, cr18 %x, cr19 %x, cr24 %x, cr25 %x, "
203 "cr28 %x, cr2c %x, cr31 %x, cr32 %x\n", cr00, cr01, cr04, cr09,
204 cr0d, cr14, cr15, cr16, cr17,
205 cr18, cr19, cr24, cr25, cr28, cr2c, cr31, cr32);
206 }
207 #endif
208
209 int
210 puc_config_win877(struct puc_softc *sc)
211 {
212 u_char val;
213 u_int efir, efdr;
214 bus_space_tag_t bst;
215 bus_space_handle_t bsh;
216 struct resource *res;
217
218 res = sc->sc_bar_mappings[0].res;
219
220 bst = rman_get_bustag(res);
221 bsh = rman_get_bushandle(res);
222
223 /* configure the first W83877TF */
224 bus_space_write_1(bst, bsh, 0x250, 0x89);
225 efir = 0x251;
226 efdr = 0x252;
227 val = rdspio(0x09) & 0x0f;
228 if (val != 0x0c) {
229 printf("conf_win877: Oops not a W83877TF\n");
230 return (ENXIO);
231 }
232
233 #ifdef PUC_DEBUG
234 printf("before: ");
235 puc_print_win877(bst, bsh, efir, efdr);
236 #endif
237
238 val = rdspio(0x16);
239 val |= 0x04;
240 wrspio(0x16, val);
241 val &= ~0x04;
242 wrspio(0x16, val);
243
244 wrspio(0x24, 0x2e8 >> 2);
245 wrspio(0x25, 0x2f8 >> 2);
246 wrspio(0x17, 0x03);
247 wrspio(0x28, 0x43);
248
249 #ifdef PUC_DEBUG
250 printf("after: ");
251 puc_print_win877(bst, bsh, efir, efdr);
252 #endif
253
254 bus_space_write_1(bst, bsh, 0x250, 0xaa);
255
256 /* configure the second W83877TF */
257 bus_space_write_1(bst, bsh, 0x3f0, 0x87);
258 bus_space_write_1(bst, bsh, 0x3f0, 0x87);
259 efir = 0x3f0;
260 efdr = 0x3f1;
261 val = rdspio(0x09) & 0x0f;
262 if (val != 0x0c) {
263 printf("conf_win877: Oops not a W83877TF\n");
264 return(ENXIO);
265 }
266
267 #ifdef PUC_DEBUG
268 printf("before: ");
269 puc_print_win877(bst, bsh, efir, efdr);
270 #endif
271
272 val = rdspio(0x16);
273 val |= 0x04;
274 wrspio(0x16, val);
275 val &= ~0x04;
276 wrspio(0x16, val);
277
278 wrspio(0x24, 0x3e8 >> 2);
279 wrspio(0x25, 0x3f8 >> 2);
280 wrspio(0x17, 0x03);
281 wrspio(0x28, 0x43);
282
283 #ifdef PUC_DEBUG
284 printf("after: ");
285 puc_print_win877(bst, bsh, efir, efdr);
286 #endif
287
288 bus_space_write_1(bst, bsh, 0x3f0, 0xaa);
289 return (0);
290 }
291
292 #undef rdspio
293 #undef wrspio
294
Cache object: 67047833e0ba2998476d665671fefe75
|