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
6 * Copyright (C) 1999, 2000, 04, 06 Ralf Baechle (ralf@linux-mips.org)
7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
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
);
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)))
49 addr
= &bridge
->b_type0_cfg_dev
[slot
].f
[fn
].c
[where
^ (4 - size
)];
52 res
= get_dbe(*value
, (u8
*) addr
);
54 res
= get_dbe(*value
, (u16
*) addr
);
56 res
= get_dbe(*value
, (u32
*) addr
);
58 return res
? PCIBIOS_DEVICE_NOT_FOUND
: PCIBIOS_SUCCESSFUL
;
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)) {
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
);
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)))
111 bridge
->b_pci_cfg
= (busno
<< 16) | (slot
<< 11);
112 addr
= &bridge
->b_type1_cfg
.c
[(fn
<< 8) | (where
^ (4 - size
))];
115 res
= get_dbe(*value
, (u8
*) addr
);
117 res
= get_dbe(*value
, (u16
*) addr
);
119 res
= get_dbe(*value
, (u32
*) addr
);
121 return res
? PCIBIOS_DEVICE_NOT_FOUND
: PCIBIOS_SUCCESSFUL
;
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)) {
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
)
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
);
168 u32 cf
, shift
, mask
, smask
;
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)))
182 addr
= &bridge
->b_type0_cfg_dev
[slot
].f
[fn
].c
[where
^ (4 - size
)];
185 res
= put_dbe(value
, (u8
*) addr
);
186 } else if (size
== 2) {
187 res
= put_dbe(value
, (u16
*) addr
);
189 res
= put_dbe(value
, (u32
*) addr
);
193 return PCIBIOS_DEVICE_NOT_FOUND
;
195 return PCIBIOS_SUCCESSFUL
;
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
;
235 u32 cf
, shift
, mask
, smask
;
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)))
250 addr
= &bridge
->b_type1_cfg
.c
[(fn
<< 8) | (where
^ (4 - size
))];
253 res
= put_dbe(value
, (u8
*) addr
);
254 } else if (size
== 2) {
255 res
= put_dbe(value
, (u16
*) addr
);
257 res
= put_dbe(value
, (u32
*) addr
);
261 return PCIBIOS_DEVICE_NOT_FOUND
;
263 return PCIBIOS_SUCCESSFUL
;
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
)
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
,