Committer: Michael Beasley <mike@snafu.setup>
[mikesnafu-overlay.git] / arch / mips / pci / ops-bridge.c
blob1fa09929cd7a997391ae35f6f65189c8e0ffba81
1 /*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
6 * Copyright (C) 1999, 2000, 04, 06 Ralf Baechle (ralf@linux-mips.org)
7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8 */
9 #include <linux/pci.h>
10 #include <asm/paccess.h>
11 #include <asm/pci/bridge.h>
12 #include <asm/sn/arch.h>
13 #include <asm/sn/intr.h>
14 #include <asm/sn/sn0/hub.h>
17 * The Bridge ASIC supports both type 0 and type 1 access. Type 1 is
18 * not really documented, so right now I can't write code which uses it.
19 * Therefore we use type 0 accesses for now even though they won't work
20 * correcly for PCI-to-PCI bridges.
22 * The function is complicated by the ultimate brokeness of the IOC3 chip
23 * which is used in SGI systems. The IOC3 can only handle 32-bit PCI
24 * accesses and does only decode parts of it's address space.
27 static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn,
28 int where, int size, u32 * value)
30 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
31 bridge_t *bridge = bc->base;
32 int slot = PCI_SLOT(devfn);
33 int fn = PCI_FUNC(devfn);
34 volatile void *addr;
35 u32 cf, shift, mask;
36 int res;
38 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
39 if (get_dbe(cf, (u32 *) addr))
40 return PCIBIOS_DEVICE_NOT_FOUND;
43 * IOC3 is fucked fucked beyond believe ... Don't even give the
44 * generic PCI code a chance to look at it for real ...
46 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
47 goto oh_my_gawd;
49 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
51 if (size == 1)
52 res = get_dbe(*value, (u8 *) addr);
53 else if (size == 2)
54 res = get_dbe(*value, (u16 *) addr);
55 else
56 res = get_dbe(*value, (u32 *) addr);
58 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
60 oh_my_gawd:
63 * IOC3 is fucked fucked beyond believe ... Don't even give the
64 * generic PCI code a chance to look at the wrong register.
66 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
67 *value = 0;
68 return PCIBIOS_SUCCESSFUL;
72 * IOC3 is fucked fucked beyond believe ... Don't try to access
73 * anything but 32-bit words ...
75 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
77 if (get_dbe(cf, (u32 *) addr))
78 return PCIBIOS_DEVICE_NOT_FOUND;
80 shift = ((where & 3) << 3);
81 mask = (0xffffffffU >> ((4 - size) << 3));
82 *value = (cf >> shift) & mask;
84 return PCIBIOS_SUCCESSFUL;
87 static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn,
88 int where, int size, u32 * value)
90 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
91 bridge_t *bridge = bc->base;
92 int busno = bus->number;
93 int slot = PCI_SLOT(devfn);
94 int fn = PCI_FUNC(devfn);
95 volatile void *addr;
96 u32 cf, shift, mask;
97 int res;
99 bridge->b_pci_cfg = (busno << 16) | (slot << 11);
100 addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
101 if (get_dbe(cf, (u32 *) addr))
102 return PCIBIOS_DEVICE_NOT_FOUND;
105 * IOC3 is fucked fucked beyond believe ... Don't even give the
106 * generic PCI code a chance to look at it for real ...
108 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
109 goto oh_my_gawd;
111 bridge->b_pci_cfg = (busno << 16) | (slot << 11);
112 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
114 if (size == 1)
115 res = get_dbe(*value, (u8 *) addr);
116 else if (size == 2)
117 res = get_dbe(*value, (u16 *) addr);
118 else
119 res = get_dbe(*value, (u32 *) addr);
121 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
123 oh_my_gawd:
126 * IOC3 is fucked fucked beyond believe ... Don't even give the
127 * generic PCI code a chance to look at the wrong register.
129 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) {
130 *value = 0;
131 return PCIBIOS_SUCCESSFUL;
135 * IOC3 is fucked fucked beyond believe ... Don't try to access
136 * anything but 32-bit words ...
138 bridge->b_pci_cfg = (busno << 16) | (slot << 11);
139 addr = &bridge->b_type1_cfg.c[(fn << 8) | where];
141 if (get_dbe(cf, (u32 *) addr))
142 return PCIBIOS_DEVICE_NOT_FOUND;
144 shift = ((where & 3) << 3);
145 mask = (0xffffffffU >> ((4 - size) << 3));
146 *value = (cf >> shift) & mask;
148 return PCIBIOS_SUCCESSFUL;
151 static int pci_read_config(struct pci_bus *bus, unsigned int devfn,
152 int where, int size, u32 * value)
154 if (bus->number > 0)
155 return pci_conf1_read_config(bus, devfn, where, size, value);
157 return pci_conf0_read_config(bus, devfn, where, size, value);
160 static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn,
161 int where, int size, u32 value)
163 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
164 bridge_t *bridge = bc->base;
165 int slot = PCI_SLOT(devfn);
166 int fn = PCI_FUNC(devfn);
167 volatile void *addr;
168 u32 cf, shift, mask, smask;
169 int res;
171 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[PCI_VENDOR_ID];
172 if (get_dbe(cf, (u32 *) addr))
173 return PCIBIOS_DEVICE_NOT_FOUND;
176 * IOC3 is fucked fucked beyond believe ... Don't even give the
177 * generic PCI code a chance to look at it for real ...
179 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
180 goto oh_my_gawd;
182 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)];
184 if (size == 1) {
185 res = put_dbe(value, (u8 *) addr);
186 } else if (size == 2) {
187 res = put_dbe(value, (u16 *) addr);
188 } else {
189 res = put_dbe(value, (u32 *) addr);
192 if (res)
193 return PCIBIOS_DEVICE_NOT_FOUND;
195 return PCIBIOS_SUCCESSFUL;
197 oh_my_gawd:
200 * IOC3 is fucked fucked beyond believe ... Don't even give the
201 * generic PCI code a chance to touch the wrong register.
203 if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
204 return PCIBIOS_SUCCESSFUL;
207 * IOC3 is fucked fucked beyond believe ... Don't try to access
208 * anything but 32-bit words ...
210 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
212 if (get_dbe(cf, (u32 *) addr))
213 return PCIBIOS_DEVICE_NOT_FOUND;
215 shift = ((where & 3) << 3);
216 mask = (0xffffffffU >> ((4 - size) << 3));
217 smask = mask << shift;
219 cf = (cf & ~smask) | ((value & mask) << shift);
220 if (put_dbe(cf, (u32 *) addr))
221 return PCIBIOS_DEVICE_NOT_FOUND;
223 return PCIBIOS_SUCCESSFUL;
226 static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn,
227 int where, int size, u32 value)
229 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus);
230 bridge_t *bridge = bc->base;
231 int slot = PCI_SLOT(devfn);
232 int fn = PCI_FUNC(devfn);
233 int busno = bus->number;
234 volatile void *addr;
235 u32 cf, shift, mask, smask;
236 int res;
238 bridge->b_pci_cfg = (busno << 16) | (slot << 11);
239 addr = &bridge->b_type1_cfg.c[(fn << 8) | PCI_VENDOR_ID];
240 if (get_dbe(cf, (u32 *) addr))
241 return PCIBIOS_DEVICE_NOT_FOUND;
244 * IOC3 is fucked fucked beyond believe ... Don't even give the
245 * generic PCI code a chance to look at it for real ...
247 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16)))
248 goto oh_my_gawd;
250 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))];
252 if (size == 1) {
253 res = put_dbe(value, (u8 *) addr);
254 } else if (size == 2) {
255 res = put_dbe(value, (u16 *) addr);
256 } else {
257 res = put_dbe(value, (u32 *) addr);
260 if (res)
261 return PCIBIOS_DEVICE_NOT_FOUND;
263 return PCIBIOS_SUCCESSFUL;
265 oh_my_gawd:
268 * IOC3 is fucked fucked beyond believe ... Don't even give the
269 * generic PCI code a chance to touch the wrong register.
271 if ((where >= 0x14 && where < 0x40) || (where >= 0x48))
272 return PCIBIOS_SUCCESSFUL;
275 * IOC3 is fucked fucked beyond believe ... Don't try to access
276 * anything but 32-bit words ...
278 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2];
280 if (get_dbe(cf, (u32 *) addr))
281 return PCIBIOS_DEVICE_NOT_FOUND;
283 shift = ((where & 3) << 3);
284 mask = (0xffffffffU >> ((4 - size) << 3));
285 smask = mask << shift;
287 cf = (cf & ~smask) | ((value & mask) << shift);
288 if (put_dbe(cf, (u32 *) addr))
289 return PCIBIOS_DEVICE_NOT_FOUND;
291 return PCIBIOS_SUCCESSFUL;
294 static int pci_write_config(struct pci_bus *bus, unsigned int devfn,
295 int where, int size, u32 value)
297 if (bus->number > 0)
298 return pci_conf1_write_config(bus, devfn, where, size, value);
300 return pci_conf0_write_config(bus, devfn, where, size, value);
303 struct pci_ops bridge_pci_ops = {
304 .read = pci_read_config,
305 .write = pci_write_config,