aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/pci/pci-ip27.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/pci/pci-ip27.c')
-rw-r--r--arch/mips/pci/pci-ip27.c292
1 files changed, 1 insertions, 291 deletions
diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c
index 662196d9fb58..80eb9af9ecdf 100644
--- a/arch/mips/pci/pci-ip27.c
+++ b/arch/mips/pci/pci-ip27.c
@@ -40,297 +40,7 @@ static struct bridge_controller bridges[MAX_PCI_BUSSES];
40struct bridge_controller *irq_to_bridge[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS]; 40struct bridge_controller *irq_to_bridge[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
41int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS]; 41int irq_to_slot[MAX_PCI_BUSSES * MAX_DEVICES_PER_PCIBUS];
42 42
43/* 43extern struct pci_ops bridge_pci_ops;
44 * The Bridge ASIC supports both type 0 and type 1 access. Type 1 is
45 * not really documented, so right now I can't write code which uses it.
46 * Therefore we use type 0 accesses for now even though they won't work
47 * correcly for PCI-to-PCI bridges.
48 *
49 * The function is complicated by the ultimate brokeness of the IOC3 chip
50 * which is used in SGI systems. The IOC3 can only handle 32-bit PCI
51 * accesses and does only decode parts of it's address space.
52 */
53
54static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
55 int where, int size, u32 * value)
56{
57 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
58 bridge_t *bridge = bc->base;
59 int slot = PCI_SLOT(devfn);
60 int fn = PCI_FUNC(devfn);
61 volatile void *addr;
62 u32 cf, shift, mask;
63 int res;
64
65 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
66 if (get_dbe(cf, (u32 *) addr))
67 return PCIBIOS_DEVICE_NOT_FOUND;
68
69 /*
70 * IOC3 is fucked fucked beyond believe ... Don't even give the
71 * generic PCI code a chance to look at it for real ...
72 */
73 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
74 goto oh_my_gawd;
75
76 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
77
78 if (size == 1)
79 res = get_dbe(*value, (u8 *) addr);
80 else if (size == 2)
81 res = get_dbe(*value, (u16 *) addr);
82 else
83 res = get_dbe(*value, (u32 *) addr);
84
85 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
86
87oh_my_gawd:
88
89 /*
90 * IOC3 is fucked fucked beyond believe ... Don't even give the
91 * generic PCI code a chance to look at the wrong register.
92 */
93 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
94 *value = 0;
95 return PCIBIOS_SUCCESSFUL;
96 }
97
98 /*
99 * IOC3 is fucked fucked beyond believe ... Don't try to access
100 * anything but 32-bit words ...
101 */
102 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
103
104 if (get_dbe(cf, (u32 *) addr))
105 return PCIBIOS_DEVICE_NOT_FOUND;
106
107 shift = ((where & 3) << 3);
108 mask = (0xffffffffU >> ((4 - size) << 3));
109 *value = (cf >> shift) & mask;
110
111 return PCIBIOS_SUCCESSFUL;
112}
113
114static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
115 int where, int size, u32 * value)
116{
117 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
118 bridge_t *bridge = bc->base;
119 int busno = bus->number;
120 int slot = PCI_SLOT(devfn);
121 int fn = PCI_FUNC(devfn);
122 volatile void *addr;
123 u32 cf, shift, mask;
124 int res;
125
126 bridge->b_pci_cfg = (busno << 16) | (slot << 11);
127 addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
128 if (get_dbe(cf, (u32 *) addr))
129 return PCIBIOS_DEVICE_NOT_FOUND;
130
131 /*
132 * IOC3 is fucked fucked beyond believe ... Don't even give the
133 * generic PCI code a chance to look at it for real ...
134 */
135 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
136 goto oh_my_gawd;
137
138 bridge->b_pci_cfg = (busno << 16) | (slot << 11);
139 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
140
141 if (size == 1)
142 res = get_dbe(*value, (u8 *) addr);
143 else if (size == 2)
144 res = get_dbe(*value, (u16 *) addr);
145 else
146 res = get_dbe(*value, (u32 *) addr);
147
148 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
149
150oh_my_gawd:
151
152 /*
153 * IOC3 is fucked fucked beyond believe ... Don't even give the
154 * generic PCI code a chance to look at the wrong register.
155 */
156 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
157 *value = 0;
158 return PCIBIOS_SUCCESSFUL;
159 }
160
161 /*
162 * IOC3 is fucked fucked beyond believe ... Don't try to access
163 * anything but 32-bit words ...
164 */
165 bridge->b_pci_cfg = (busno << 16) | (slot << 11);
166 addr = &bridge->b_type1_cfg.c[(fn << 8) | where];
167
168 if (get_dbe(cf, (u32 *) addr))
169 return PCIBIOS_DEVICE_NOT_FOUND;
170
171 shift = ((where & 3) << 3);
172 mask = (0xffffffffU >> ((4 - size) << 3));
173 *value = (cf >> shift) & mask;
174
175 return PCIBIOS_SUCCESSFUL;
176}
177
178static int pci_read_config(struct pci_bus *bus, unsigned int devfn,
179 int where, int size, u32 * value)
180{
181 if (bus->number > 0)
182 return pci_conf1_read_config(bus, devfn, where, size, value);
183
184 return pci_conf0_read_config(bus, devfn, where, size, value);
185}
186
187static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
188 int where, int size, u32 value)
189{
190 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
191 bridge_t *bridge = bc->base;
192 int slot = PCI_SLOT(devfn);
193 int fn = PCI_FUNC(devfn);
194 volatile void *addr;
195 u32 cf, shift, mask, smask;
196 int res;
197
198 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
199 if (get_dbe(cf, (u32 *) addr))
200 return PCIBIOS_DEVICE_NOT_FOUND;
201
202 /*
203 * IOC3 is fucked fucked beyond believe ... Don't even give the
204 * generic PCI code a chance to look at it for real ...
205 */
206 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
207 goto oh_my_gawd;
208
209 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
210
211 if (size == 1) {
212 res = put_dbe(value, (u8 *) addr);
213 } else if (size == 2) {
214 res = put_dbe(value, (u16 *) addr);
215 } else {
216 res = put_dbe(value, (u32 *) addr);
217 }
218
219 if (res)
220 return PCIBIOS_DEVICE_NOT_FOUND;
221
222 return PCIBIOS_SUCCESSFUL;
223
224oh_my_gawd:
225
226 /*
227 * IOC3 is fucked fucked beyond believe ... Don't even give the
228 * generic PCI code a chance to touch the wrong register.
229 */
230 if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
231 return PCIBIOS_SUCCESSFUL;
232
233 /*
234 * IOC3 is fucked fucked beyond believe ... Don't try to access
235 * anything but 32-bit words ...
236 */
237 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
238
239 if (get_dbe(cf, (u32 *) addr))
240 return PCIBIOS_DEVICE_NOT_FOUND;
241
242 shift = ((where & 3) << 3);
243 mask = (0xffffffffU >> ((4 - size) << 3));
244 smask = mask << shift;
245
246 cf = (cf & ~smask) | ((value & mask) << shift);
247 if (put_dbe(cf, (u32 *) addr))
248 return PCIBIOS_DEVICE_NOT_FOUND;
249
250 return PCIBIOS_SUCCESSFUL;
251}
252
253static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
254 int where, int size, u32 value)
255{
256 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
257 bridge_t *bridge = bc->base;
258 int slot = PCI_SLOT(devfn);
259 int fn = PCI_FUNC(devfn);
260 int busno = bus->number;
261 volatile void *addr;
262 u32 cf, shift, mask, smask;
263 int res;
264
265 bridge->b_pci_cfg = (busno << 16) | (slot << 11);
266 addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
267 if (get_dbe(cf, (u32 *) addr))
268 return PCIBIOS_DEVICE_NOT_FOUND;
269
270 /*
271 * IOC3 is fucked fucked beyond believe ... Don't even give the
272 * generic PCI code a chance to look at it for real ...
273 */
274 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
275 goto oh_my_gawd;
276
277 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
278
279 if (size == 1) {
280 res = put_dbe(value, (u8 *) addr);
281 } else if (size == 2) {
282 res = put_dbe(value, (u16 *) addr);
283 } else {
284 res = put_dbe(value, (u32 *) addr);
285 }
286
287 if (res)
288 return PCIBIOS_DEVICE_NOT_FOUND;
289
290 return PCIBIOS_SUCCESSFUL;
291
292oh_my_gawd:
293
294 /*
295 * IOC3 is fucked fucked beyond believe ... Don't even give the
296 * generic PCI code a chance to touch the wrong register.
297 */
298 if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
299 return PCIBIOS_SUCCESSFUL;
300
301 /*
302 * IOC3 is fucked fucked beyond believe ... Don't try to access
303 * anything but 32-bit words ...
304 */
305 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
306
307 if (get_dbe(cf, (u32 *) addr))
308 return PCIBIOS_DEVICE_NOT_FOUND;
309
310 shift = ((where & 3) << 3);
311 mask = (0xffffffffU >> ((4 - size) << 3));
312 smask = mask << shift;
313
314 cf = (cf & ~smask) | ((value & mask) << shift);
315 if (put_dbe(cf, (u32 *) addr))
316 return PCIBIOS_DEVICE_NOT_FOUND;
317
318 return PCIBIOS_SUCCESSFUL;
319}
320
321static int pci_write_config(struct pci_bus *bus, unsigned int devfn,
322 int where, int size, u32 value)
323{
324 if (bus->number > 0)
325 return pci_conf1_write_config(bus, devfn, where, size, value);
326
327 return pci_conf0_write_config(bus, devfn, where, size, value);
328}
329
330static struct pci_ops bridge_pci_ops = {
331 .read = pci_read_config,
332 .write = pci_write_config,
333};
334 44
335int __init bridge_probe(nasid_t nasid, int widget_id, int masterwid) 45int __init bridge_probe(nasid_t nasid, int widget_id, int masterwid)
336{ 46{