bandit.c revision 1.2 1 /* $NetBSD: bandit.c,v 1.2 1998/07/13 19:27:13 tsubai Exp $ */
2
3 /*
4 * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
5 * All Rights Reserved
6 *
7 * Permission to use, copy, modify, and distribute this software and
8 * its documentation for any purpose and without fee is hereby granted,
9 * provided that the above copyright notice appears in all copies and
10 * that both the copyright notice and this permission notice appear in
11 * supporting documentation.
12 *
13 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
14 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
15 * FOR A PARTICULAR PURPOSE.
16 *
17 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
19 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
20 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
21 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 */
23 /*
24 * Copyright 1996 1995 by Apple Computer, Inc. 1997 1996 1995 1994 1993 1992 1991
25 * All Rights Reserved
26 *
27 * Permission to use, copy, modify, and distribute this software and
28 * its documentation for any purpose and without fee is hereby granted,
29 * provided that the above copyright notice appears in all copies and
30 * that both the copyright notice and this permission notice appear in
31 * supporting documentation.
32 *
33 * APPLE COMPUTER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
34 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
35 * FOR A PARTICULAR PURPOSE.
36 *
37 * IN NO EVENT SHALL APPLE COMPUTER BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
38 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
39 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
40 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
41 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
42 */
43
44 #include <sys/param.h>
45 #include <sys/device.h>
46
47 #include <dev/pci/pcireg.h>
48 #include <dev/pci/pcivar.h>
49 #include <dev/ofw/openfirm.h>
50
51 #include <machine/bus.h>
52
53 #define PCI_BANDIT 11
54
55 #define PCI_REG_BANDIT_CFG 0x40
56 #define PCI_REG_ADDR_MASK 0x48
57 #define PCI_REG_MODE_SELECT 0x50
58 #define PCI_REG_ARBUS_HOLDOFF 0x58
59
60 #define PCI_MS_BYTESWAP 0x001 /* Enable Big Endian mode. (R/W)*/
61 #define PCI_MS_PASSATOMIC 0x002 /* PCI Bus to ARBus Lock are always allowed (R)*/
62 #define PCI_MS_NUMBER_MASK 0x00C /* PCI Bus Number (R) */
63 #define PCI_MS_IS_SYNC 0x010 /* Is Synchronous (1) or Async (0) ? (R)*/
64 #define PCI_MS_VGA_SPACE 0x020 /* Map VGA I/O space (R/W) */
65 #define PCI_MS_IO_COHERENT 0x040 /* I/O Coherent (R/W) */
66 #define PCI_MS_INT_ENABLE 0x080 /* Allow TEA or PCI Abort INT to pass to Grand Central (R/W) */
67
68 static void bandit_init __P((pci_chipset_tag_t));
69 static void scan_pci_devs __P((void));
70 static void config_slot __P((int));
71
72 void
73 pci_init()
74 {
75 scan_pci_devs();
76 }
77
78 void
79 bandit_init(pc)
80 pci_chipset_tag_t pc;
81 {
82 u_int status;
83 pcitag_t tag;
84
85 tag = pci_make_tag(pc, 0, PCI_BANDIT, 0);
86 if ((pci_conf_read(pc, tag, PCI_ID_REG) & 0xffff) == 0xffff)
87 return;
88
89 status = pci_conf_read(pc, tag, PCI_REG_MODE_SELECT);
90
91 if ((status & PCI_MS_IO_COHERENT) == 0) {
92 status |= PCI_MS_IO_COHERENT;
93 pci_conf_write(pc, tag, PCI_REG_MODE_SELECT, status);
94 }
95
96 return;
97 }
98
99
100 void
101 scan_pci_devs()
102 {
103 int node;
104 char name[64];
105 int n = 0;
106 u_int reg[2];
107
108 bzero(pci_bridges, sizeof(pci_bridges));
109
110 node = OF_peer(0);
111 node = OF_child(node);
112
113 while (node) {
114 if (OF_getprop(node, "name", name, sizeof(name)) <= 0)
115 continue;
116 if (strcmp(name, "bandit") == 0) {
117 int child;
118
119 if (OF_getprop(node, "reg", reg, sizeof(reg)) != 8)
120 continue;
121
122 pci_bridges[n].iot = (bus_space_tag_t)reg[0];
123 pci_bridges[n].addr = mapiodev(reg[0] + 0x800000, 4);
124 pci_bridges[n].data = mapiodev(reg[0] + 0xc00000, 4);
125 pci_bridges[n].pc = n;
126 bandit_init(n++);
127
128 child = OF_child(node);
129 while (child) {
130 config_slot(child);
131 child = OF_peer(child);
132 }
133 }
134 if (strcmp(name, "pci") == 0) { /* XXX This is not a bandit :) */
135 int child;
136
137 if (OF_getprop(node, "reg", reg, sizeof(reg)) != 8)
138 continue;
139
140 pci_bridges[n].iot = (bus_space_tag_t)reg[0];
141 pci_bridges[n].addr = mapiodev(0xfec00000, 4); /* XXX */
142 pci_bridges[n].data = mapiodev(0xfee00000, 4); /* XXX */
143 pci_bridges[n].pc = PCI_CHIPSET_MPC106; /* for now */
144 }
145
146 node = OF_peer(node);
147 }
148 }
149
150 void
151 config_slot(node)
152 int node;
153 {
154 pci_chipset_tag_t pc;
155 pcitag_t tag;
156 int dev, irq, intr, csr;
157 char slotname[8];
158
159 if (OF_getprop(node, "AAPL,slot-name", slotname, sizeof(slotname)) < 2)
160 return;
161
162 slotname[2] = 0;
163
164 /*
165 * slot A1 pci0 dev 13 irq 23
166 * B1 pci0 dev 14 irq 24
167 * C1 pci0 dev 15 irq 25
168 * D2 pci1 dev 13 irq 27
169 * E2 pci1 dev 14 irq 28
170 * F2 pci1 dev 15 irq 29
171 *
172 * XXX Is this TRUE on all PowerMacs?
173 */
174 pc = slotname[1] - '1';
175 dev = slotname[0] - 'A' + 13 - pc * 3;
176
177 if (OF_getprop(node, "AAPL,interrupts", &irq, sizeof(irq)) ==
178 sizeof(irq)) {
179
180 tag = pci_make_tag(pc, 0, dev, 0);
181 csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
182 intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
183
184 #ifdef BANDIT_DEBUG
185 printf(" pc=%d, dev=%d\n", pc, dev);
186 printf(" OLD csr=0x%x, intr=0x%x\n", csr, intr);
187 #endif
188
189 intr = (intr & 0xffffff00) | (irq & 0xff);
190 pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr);
191
192 /* XXX */
193 csr |= (PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_IO_ENABLE);
194 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr);
195
196 #ifdef BANDIT_DEBUG
197 printf(" NEW csr=0x%x, intr=0x%x\n", csr, intr);
198 #endif
199 }
200 }
201