Annotation of sys/arch/macppc/pci/macobio.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: macobio.c,v 1.17 2006/06/19 22:42:35 miod Exp $ */
2: /* $NetBSD: obio.c,v 1.6 1999/05/01 10:36:08 tsubai Exp $ */
3:
4: /*-
5: * Copyright (C) 1998 Internet Research Institute, Inc.
6: * All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
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.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by
19: * Internet Research Institute, Inc.
20: * 4. The name of the author may not be used to endorse or promote products
21: * derived from this software without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33: */
34:
35: #include <sys/types.h>
36: #include <sys/param.h>
37: #include <sys/systm.h>
38: #include <sys/kernel.h>
39: #include <sys/device.h>
40:
41: #include <dev/pci/pcivar.h>
42: #include <dev/pci/pcidevs.h>
43:
44: #include <dev/ofw/openfirm.h>
45:
46: #include <machine/bus.h>
47: #include <machine/autoconf.h>
48:
49: void macobio_attach(struct device *, struct device *, void *);
50: int macobio_match(struct device *, void *, void *);
51: int macobio_print(void *, const char *);
52: void macobio_modem_power(int enable);
53:
54: void *undef_mac_establish(void * lcv, int irq, int type, int level,
55: int (*ih_fun)(void *), void *ih_arg, char *name);
56: void mac_intr_disestab(void *lcp, void *arg);
57:
58: struct macobio_softc {
59: struct device sc_dev;
60: int sc_node;
61: struct ppc_bus_space sc_membus_space;
62: int sc_id; /* copy of the PCI pa_id */
63: u_int8_t *obiomem;
64: };
65: struct cfdriver macobio_cd = {
66: NULL, "macobio", DV_DULL,
67: };
68:
69:
70: struct cfattach macobio_ca = {
71: sizeof(struct macobio_softc), macobio_match, macobio_attach
72: };
73:
74: int
75: macobio_match(struct device *parent, void *cf, void *aux)
76: {
77: struct pci_attach_args *pa = aux;
78:
79: if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_APPLE)
80: switch (PCI_PRODUCT(pa->pa_id)) {
81:
82: case PCI_PRODUCT_APPLE_GC:
83: case PCI_PRODUCT_APPLE_OHARE:
84: case PCI_PRODUCT_APPLE_HEATHROW:
85: case PCI_PRODUCT_APPLE_PADDINGTON:
86: case PCI_PRODUCT_APPLE_KEYLARGO:
87: case PCI_PRODUCT_APPLE_INTREPID:
88: case PCI_PRODUCT_APPLE_PANGEA_MACIO:
89: case PCI_PRODUCT_APPLE_SHASTA:
90: case PCI_PRODUCT_APPLE_K2_MACIO:
91: return 1;
92: }
93:
94: return 0;
95: }
96:
97: #define HEATHROW_FCR_OFFSET 0x38
98: u_int32_t *heathrow_FCR = NULL;
99:
100: /*
101: * Attach all the sub-devices we can find
102: */
103: void
104: macobio_attach(struct device *parent, struct device *self, void *aux)
105: {
106: struct macobio_softc *sc = (struct macobio_softc *)self;
107: struct pci_attach_args *pa = aux;
108: struct confargs ca;
109: int node, child, namelen;
110: u_int32_t reg[20];
111: int32_t intr[8];
112: char name[32];
113: int need_interrupt_controller = 0;
114:
115: sc->sc_id = pa->pa_id; /* save of type for later */
116:
117: switch (PCI_PRODUCT(pa->pa_id)) {
118:
119: /* XXX should not use name */
120: case PCI_PRODUCT_APPLE_GC:
121: node = OF_finddevice("/bandit/gc");
122: need_interrupt_controller = 1;
123: break;
124:
125: case PCI_PRODUCT_APPLE_OHARE:
126: node = OF_finddevice("/bandit/ohare");
127: need_interrupt_controller = 1;
128: break;
129:
130: case PCI_PRODUCT_APPLE_HEATHROW:
131: case PCI_PRODUCT_APPLE_PADDINGTON:
132: node = OF_finddevice("mac-io");
133: if (node == -1)
134: node = OF_finddevice("/pci/mac-io");
135: if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg))
136: == (sizeof (reg[0]) * 5))
137: {
138: /* always ??? */
139: heathrow_FCR = mapiodev(reg[2] + HEATHROW_FCR_OFFSET,
140: 4);
141: }
142: break;
143: case PCI_PRODUCT_APPLE_KEYLARGO:
144: case PCI_PRODUCT_APPLE_INTREPID:
145: case PCI_PRODUCT_APPLE_PANGEA_MACIO:
146: case PCI_PRODUCT_APPLE_SHASTA:
147: case PCI_PRODUCT_APPLE_K2_MACIO:
148: node = OF_finddevice("mac-io");
149: if (node == -1)
150: node = OF_finddevice("/pci/mac-io");
151: if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg))
152: == (sizeof (reg[0]) * 5))
153: sc->obiomem = mapiodev(reg[2], 0x100);
154: break;
155: default:
156: printf(": unknown macobio controller\n");
157: return;
158: }
159: sc->sc_node = node;
160:
161: if (OF_getprop(node, "assigned-addresses", reg, sizeof(reg)) < 12)
162: return;
163:
164: ca.ca_baseaddr = reg[2];
165:
166: sc->sc_membus_space.bus_base = ca.ca_baseaddr;
167:
168: ca.ca_iot = &sc->sc_membus_space;
169: ca.ca_dmat = pa->pa_dmat;
170:
171: printf("\n");
172:
173: /*
174: * This might be a hack, but it makes the interrupt controller
175: * attach as expected if a device node existed in the OF tree.
176: */
177: if (need_interrupt_controller) {
178: /* force attachment of legacy interrupt controllers */
179: ca.ca_name = "legacy-interrupt-controller";
180: ca.ca_node = 0;
181:
182: ca.ca_nreg = 0;
183: ca.ca_nintr = 0;
184:
185: ca.ca_reg = NULL;
186: ca.ca_intr = NULL;
187:
188: config_found(self, &ca, macobio_print);
189: }
190:
191: for (child = OF_child(node); child; child = OF_peer(child)) {
192: namelen = OF_getprop(child, "name", name, sizeof(name));
193: if (namelen < 0)
194: continue;
195: if (namelen >= sizeof(name))
196: continue;
197:
198: name[namelen] = 0;
199: ca.ca_name = name;
200: ca.ca_node = child;
201:
202: ca.ca_nreg = OF_getprop(child, "reg", reg, sizeof(reg));
203: ca.ca_nintr = OF_getprop(child, "AAPL,interrupts", intr,
204: sizeof(intr));
205: if (ca.ca_nintr == -1)
206: ca.ca_nintr = OF_getprop(child, "interrupts", intr,
207: sizeof(intr));
208:
209: ca.ca_reg = reg;
210: ca.ca_intr = intr;
211:
212: config_found(self, &ca, macobio_print);
213: }
214: }
215:
216: int
217: macobio_print(void *aux, const char *macobio)
218: {
219: struct confargs *ca = aux;
220:
221: if (macobio)
222: printf("\"%s\" at %s", ca->ca_name, macobio);
223:
224: if (ca->ca_nreg > 0)
225: printf(" offset 0x%x", ca->ca_reg[0]);
226:
227: return UNCONF;
228: }
229:
230: void *
231: undef_mac_establish(void * lcv, int irq, int type, int level,
232: int (*ih_fun)(void *), void *ih_arg, char *name)
233: {
234: printf("mac_intr_establish called, not yet inited\n");
235: return 0;
236: }
237:
238: void
239: mac_intr_disestab(void *lcp, void *arg)
240: {
241: printf("mac_intr_disestablish called, not yet inited\n");
242: }
243:
244: intr_establish_t *mac_intr_establish_func = undef_mac_establish;
245: intr_disestablish_t *mac_intr_disestablish_func = mac_intr_disestab;
246:
247: void *
248: mac_intr_establish(void * lcv, int irq, int type, int level,
249: int (*ih_fun)(void *), void *ih_arg, char *name)
250: {
251: return (*mac_intr_establish_func)(lcv, irq, type, level, ih_fun,
252: ih_arg, name);
253: }
254: void
255: mac_intr_disestablish(void *lcp, void *arg)
256: {
257: (*mac_intr_disestablish_func)(lcp, arg);
258: }
259:
260: void keylargo_fcr_enable(int offset, u_int32_t bits);
261: void keylargo_fcr_disable(int offset, u_int32_t bits);
262: u_int32_t keylargo_fcr_read(int offset);
263:
264: void
265: keylargo_fcr_enable(int offset, u_int32_t bits)
266: {
267: struct macobio_softc *sc = macobio_cd.cd_devs[0];
268: if (sc->obiomem == 0)
269: return;
270:
271: bits |= in32rb(sc->obiomem + offset);
272: out32rb(sc->obiomem + offset, bits);
273: }
274: void
275: keylargo_fcr_disable(int offset, u_int32_t bits)
276: {
277: struct macobio_softc *sc = macobio_cd.cd_devs[0];
278: if (sc->obiomem == 0)
279: return;
280:
281: bits = in32rb(sc->obiomem + offset) & ~bits;
282: out32rb(sc->obiomem + offset, bits);
283: }
284:
285: u_int32_t
286: keylargo_fcr_read(int offset)
287: {
288: struct macobio_softc *sc = macobio_cd.cd_devs[0];
289: if (sc->obiomem == 0)
290: return -1;
291:
292: return in32rb(sc->obiomem + offset);
293: }
294:
295: void
296: macobio_modem_power(int enable)
297: {
298: u_int32_t val;
299: struct macobio_softc *sc = macobio_cd.cd_devs[0];
300: if (PCI_PRODUCT(sc->sc_id) == PCI_PRODUCT_APPLE_KEYLARGO ||
301: PCI_PRODUCT(sc->sc_id) == PCI_PRODUCT_APPLE_INTREPID) {
302: val = in32rb(sc->obiomem + 0x40);
303: if (enable)
304: val = val & ~((u_int32_t)1<<25);
305: else
306: val = val | ((u_int32_t)1<<25);
307: out32rb(sc->obiomem + 0x40, val);
308: }
309: if (PCI_PRODUCT(sc->sc_id) == PCI_PRODUCT_APPLE_PANGEA_MACIO) {
310: if (enable) {
311: /* set reset */
312: out8(sc->obiomem + 0x006a + 0x03, 0x04);
313: /* power modem on */
314: out8(sc->obiomem + 0x006a + 0x02, 0x04);
315: /* unset reset */
316: out8(sc->obiomem + 0x006a + 0x03, 0x05);
317: } else {
318: /* disable it how? */
319: }
320: }
321: }
CVSweb