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 * Most of the IOC3 PCI config register aren't present
18 * we emulate what is needed for a normal PCI enumeration
20 static u32
emulate_ioc3_cfg(int where
, int size
)
22 if (size
== 1 && where
== 0x3d)
24 else if (size
== 2 && where
== 0x3c)
26 else if (size
== 4 && where
== 0x3c)
33 * The Bridge ASIC supports both type 0 and type 1 access. Type 1 is
34 * not really documented, so right now I can't write code which uses it.
35 * Therefore we use type 0 accesses for now even though they won't work
36 * correctly for PCI-to-PCI bridges.
38 * The function is complicated by the ultimate brokenness of the IOC3 chip
39 * which is used in SGI systems. The IOC3 can only handle 32-bit PCI
40 * accesses and does only decode parts of it's address space.
43 static int pci_conf0_read_config(struct pci_bus
*bus
, unsigned int devfn
,
44 int where
, int size
, u32
* value
)
46 struct bridge_controller
*bc
= BRIDGE_CONTROLLER(bus
);
47 bridge_t
*bridge
= bc
->base
;
48 int slot
= PCI_SLOT(devfn
);
49 int fn
= PCI_FUNC(devfn
);
54 addr
= &bridge
->b_type0_cfg_dev
[slot
].f
[fn
].c
[PCI_VENDOR_ID
];
55 if (get_dbe(cf
, (u32
*) addr
))
56 return PCIBIOS_DEVICE_NOT_FOUND
;
59 * IOC3 is fucking fucked beyond belief ... Don't even give the
60 * generic PCI code a chance to look at it for real ...
62 if (cf
== (PCI_VENDOR_ID_SGI
| (PCI_DEVICE_ID_SGI_IOC3
<< 16)))
65 addr
= &bridge
->b_type0_cfg_dev
[slot
].f
[fn
].c
[where
^ (4 - size
)];
68 res
= get_dbe(*value
, (u8
*) addr
);
70 res
= get_dbe(*value
, (u16
*) addr
);
72 res
= get_dbe(*value
, (u32
*) addr
);
74 return res
? PCIBIOS_DEVICE_NOT_FOUND
: PCIBIOS_SUCCESSFUL
;
79 * IOC3 is fucking fucked beyond belief ... Don't even give the
80 * generic PCI code a chance to look at the wrong register.
82 if ((where
>= 0x14 && where
< 0x40) || (where
>= 0x48)) {
83 *value
= emulate_ioc3_cfg(where
, size
);
84 return PCIBIOS_SUCCESSFUL
;
88 * IOC3 is fucking fucked beyond belief ... Don't try to access
89 * anything but 32-bit words ...
91 addr
= &bridge
->b_type0_cfg_dev
[slot
].f
[fn
].l
[where
>> 2];
93 if (get_dbe(cf
, (u32
*) addr
))
94 return PCIBIOS_DEVICE_NOT_FOUND
;
96 shift
= ((where
& 3) << 3);
97 mask
= (0xffffffffU
>> ((4 - size
) << 3));
98 *value
= (cf
>> shift
) & mask
;
100 return PCIBIOS_SUCCESSFUL
;
103 static int pci_conf1_read_config(struct pci_bus
*bus
, unsigned int devfn
,
104 int where
, int size
, u32
* value
)
106 struct bridge_controller
*bc
= BRIDGE_CONTROLLER(bus
);
107 bridge_t
*bridge
= bc
->base
;
108 int busno
= bus
->number
;
109 int slot
= PCI_SLOT(devfn
);
110 int fn
= PCI_FUNC(devfn
);
115 bridge
->b_pci_cfg
= (busno
<< 16) | (slot
<< 11);
116 addr
= &bridge
->b_type1_cfg
.c
[(fn
<< 8) | PCI_VENDOR_ID
];
117 if (get_dbe(cf
, (u32
*) addr
))
118 return PCIBIOS_DEVICE_NOT_FOUND
;
121 * IOC3 is fucking fucked beyond belief ... Don't even give the
122 * generic PCI code a chance to look at it for real ...
124 if (cf
== (PCI_VENDOR_ID_SGI
| (PCI_DEVICE_ID_SGI_IOC3
<< 16)))
127 bridge
->b_pci_cfg
= (busno
<< 16) | (slot
<< 11);
128 addr
= &bridge
->b_type1_cfg
.c
[(fn
<< 8) | (where
^ (4 - size
))];
131 res
= get_dbe(*value
, (u8
*) addr
);
133 res
= get_dbe(*value
, (u16
*) addr
);
135 res
= get_dbe(*value
, (u32
*) addr
);
137 return res
? PCIBIOS_DEVICE_NOT_FOUND
: PCIBIOS_SUCCESSFUL
;
142 * IOC3 is fucking fucked beyond belief ... Don't even give the
143 * generic PCI code a chance to look at the wrong register.
145 if ((where
>= 0x14 && where
< 0x40) || (where
>= 0x48)) {
146 *value
= emulate_ioc3_cfg(where
, size
);
147 return PCIBIOS_SUCCESSFUL
;
151 * IOC3 is fucking fucked beyond belief ... Don't try to access
152 * anything but 32-bit words ...
154 bridge
->b_pci_cfg
= (busno
<< 16) | (slot
<< 11);
155 addr
= &bridge
->b_type1_cfg
.c
[(fn
<< 8) | where
];
157 if (get_dbe(cf
, (u32
*) addr
))
158 return PCIBIOS_DEVICE_NOT_FOUND
;
160 shift
= ((where
& 3) << 3);
161 mask
= (0xffffffffU
>> ((4 - size
) << 3));
162 *value
= (cf
>> shift
) & mask
;
164 return PCIBIOS_SUCCESSFUL
;
167 static int pci_read_config(struct pci_bus
*bus
, unsigned int devfn
,
168 int where
, int size
, u32
* value
)
171 return pci_conf1_read_config(bus
, devfn
, where
, size
, value
);
173 return pci_conf0_read_config(bus
, devfn
, where
, size
, value
);
176 static int pci_conf0_write_config(struct pci_bus
*bus
, unsigned int devfn
,
177 int where
, int size
, u32 value
)
179 struct bridge_controller
*bc
= BRIDGE_CONTROLLER(bus
);
180 bridge_t
*bridge
= bc
->base
;
181 int slot
= PCI_SLOT(devfn
);
182 int fn
= PCI_FUNC(devfn
);
184 u32 cf
, shift
, mask
, smask
;
187 addr
= &bridge
->b_type0_cfg_dev
[slot
].f
[fn
].c
[PCI_VENDOR_ID
];
188 if (get_dbe(cf
, (u32
*) addr
))
189 return PCIBIOS_DEVICE_NOT_FOUND
;
192 * IOC3 is fucking fucked beyond belief ... Don't even give the
193 * generic PCI code a chance to look at it for real ...
195 if (cf
== (PCI_VENDOR_ID_SGI
| (PCI_DEVICE_ID_SGI_IOC3
<< 16)))
198 addr
= &bridge
->b_type0_cfg_dev
[slot
].f
[fn
].c
[where
^ (4 - size
)];
201 res
= put_dbe(value
, (u8
*) addr
);
202 } else if (size
== 2) {
203 res
= put_dbe(value
, (u16
*) addr
);
205 res
= put_dbe(value
, (u32
*) addr
);
209 return PCIBIOS_DEVICE_NOT_FOUND
;
211 return PCIBIOS_SUCCESSFUL
;
216 * IOC3 is fucking fucked beyond belief ... Don't even give the
217 * generic PCI code a chance to touch the wrong register.
219 if ((where
>= 0x14 && where
< 0x40) || (where
>= 0x48))
220 return PCIBIOS_SUCCESSFUL
;
223 * IOC3 is fucking fucked beyond belief ... Don't try to access
224 * anything but 32-bit words ...
226 addr
= &bridge
->b_type0_cfg_dev
[slot
].f
[fn
].l
[where
>> 2];
228 if (get_dbe(cf
, (u32
*) addr
))
229 return PCIBIOS_DEVICE_NOT_FOUND
;
231 shift
= ((where
& 3) << 3);
232 mask
= (0xffffffffU
>> ((4 - size
) << 3));
233 smask
= mask
<< shift
;
235 cf
= (cf
& ~smask
) | ((value
& mask
) << shift
);
236 if (put_dbe(cf
, (u32
*) addr
))
237 return PCIBIOS_DEVICE_NOT_FOUND
;
239 return PCIBIOS_SUCCESSFUL
;
242 static int pci_conf1_write_config(struct pci_bus
*bus
, unsigned int devfn
,
243 int where
, int size
, u32 value
)
245 struct bridge_controller
*bc
= BRIDGE_CONTROLLER(bus
);
246 bridge_t
*bridge
= bc
->base
;
247 int slot
= PCI_SLOT(devfn
);
248 int fn
= PCI_FUNC(devfn
);
249 int busno
= bus
->number
;
251 u32 cf
, shift
, mask
, smask
;
254 bridge
->b_pci_cfg
= (busno
<< 16) | (slot
<< 11);
255 addr
= &bridge
->b_type1_cfg
.c
[(fn
<< 8) | PCI_VENDOR_ID
];
256 if (get_dbe(cf
, (u32
*) addr
))
257 return PCIBIOS_DEVICE_NOT_FOUND
;
260 * IOC3 is fucking fucked beyond belief ... Don't even give the
261 * generic PCI code a chance to look at it for real ...
263 if (cf
== (PCI_VENDOR_ID_SGI
| (PCI_DEVICE_ID_SGI_IOC3
<< 16)))
266 addr
= &bridge
->b_type1_cfg
.c
[(fn
<< 8) | (where
^ (4 - size
))];
269 res
= put_dbe(value
, (u8
*) addr
);
270 } else if (size
== 2) {
271 res
= put_dbe(value
, (u16
*) addr
);
273 res
= put_dbe(value
, (u32
*) addr
);
277 return PCIBIOS_DEVICE_NOT_FOUND
;
279 return PCIBIOS_SUCCESSFUL
;
284 * IOC3 is fucking fucked beyond belief ... Don't even give the
285 * generic PCI code a chance to touch the wrong register.
287 if ((where
>= 0x14 && where
< 0x40) || (where
>= 0x48))
288 return PCIBIOS_SUCCESSFUL
;
291 * IOC3 is fucking fucked beyond belief ... Don't try to access
292 * anything but 32-bit words ...
294 addr
= &bridge
->b_type0_cfg_dev
[slot
].f
[fn
].l
[where
>> 2];
296 if (get_dbe(cf
, (u32
*) addr
))
297 return PCIBIOS_DEVICE_NOT_FOUND
;
299 shift
= ((where
& 3) << 3);
300 mask
= (0xffffffffU
>> ((4 - size
) << 3));
301 smask
= mask
<< shift
;
303 cf
= (cf
& ~smask
) | ((value
& mask
) << shift
);
304 if (put_dbe(cf
, (u32
*) addr
))
305 return PCIBIOS_DEVICE_NOT_FOUND
;
307 return PCIBIOS_SUCCESSFUL
;
310 static int pci_write_config(struct pci_bus
*bus
, unsigned int devfn
,
311 int where
, int size
, u32 value
)
314 return pci_conf1_write_config(bus
, devfn
, where
, size
, value
);
316 return pci_conf0_write_config(bus
, devfn
, where
, size
, value
);
319 struct pci_ops bridge_pci_ops
= {
320 .read
= pci_read_config
,
321 .write
= pci_write_config
,