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. 5 * 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> 15 16/* 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. 21 * 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. 25 */ 26 27static int pci_conf0_read_config(struct pci_bus *bus, unsigned int devfn, 28 int where, int size, u32 * value) 29{ 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; 37 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; 41 42 /* 43 * IOC3 is fucked fucked beyond believe ... Don't even give the 44 * generic PCI code a chance to look at it for real ... 45 */ 46 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) 47 goto oh_my_gawd; 48 49 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; 50 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); 57 58 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; 59 60oh_my_gawd: 61 62 /* 63 * IOC3 is fucked fucked beyond believe ... Don't even give the 64 * generic PCI code a chance to look at the wrong register. 65 */ 66 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { 67 *value = 0; 68 return PCIBIOS_SUCCESSFUL; 69 } 70 71 /* 72 * IOC3 is fucked fucked beyond believe ... Don't try to access 73 * anything but 32-bit words ... 74 */ 75 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; 76 77 if (get_dbe(cf, (u32 *) addr)) 78 return PCIBIOS_DEVICE_NOT_FOUND; 79 80 shift = ((where & 3) << 3); 81 mask = (0xffffffffU >> ((4 - size) << 3)); 82 *value = (cf >> shift) & mask; 83 84 return PCIBIOS_SUCCESSFUL; 85} 86 87static int pci_conf1_read_config(struct pci_bus *bus, unsigned int devfn, 88 int where, int size, u32 * value) 89{ 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; 98 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; 103 104 /* 105 * IOC3 is fucked fucked beyond believe ... Don't even give the 106 * generic PCI code a chance to look at it for real ... 107 */ 108 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) 109 goto oh_my_gawd; 110 111 bridge->b_pci_cfg = (busno << 16) | (slot << 11); 112 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; 113 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); 120 121 return res ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; 122 123oh_my_gawd: 124 125 /* 126 * IOC3 is fucked fucked beyond believe ... Don't even give the 127 * generic PCI code a chance to look at the wrong register. 128 */ 129 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) { 130 *value = 0; 131 return PCIBIOS_SUCCESSFUL; 132 } 133 134 /* 135 * IOC3 is fucked fucked beyond believe ... Don't try to access 136 * anything but 32-bit words ... 137 */ 138 bridge->b_pci_cfg = (busno << 16) | (slot << 11); 139 addr = &bridge->b_type1_cfg.c[(fn << 8) | where]; 140 141 if (get_dbe(cf, (u32 *) addr)) 142 return PCIBIOS_DEVICE_NOT_FOUND; 143 144 shift = ((where & 3) << 3); 145 mask = (0xffffffffU >> ((4 - size) << 3)); 146 *value = (cf >> shift) & mask; 147 148 return PCIBIOS_SUCCESSFUL; 149} 150 151static int pci_read_config(struct pci_bus *bus, unsigned int devfn, 152 int where, int size, u32 * value) 153{ 154 if (bus->number > 0) 155 return pci_conf1_read_config(bus, devfn, where, size, value); 156 157 return pci_conf0_read_config(bus, devfn, where, size, value); 158} 159 160static int pci_conf0_write_config(struct pci_bus *bus, unsigned int devfn, 161 int where, int size, u32 value) 162{ 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; 170 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; 174 175 /* 176 * IOC3 is fucked fucked beyond believe ... Don't even give the 177 * generic PCI code a chance to look at it for real ... 178 */ 179 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) 180 goto oh_my_gawd; 181 182 addr = &bridge->b_type0_cfg_dev[slot].f[fn].c[where ^ (4 - size)]; 183 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); 190 } 191 192 if (res) 193 return PCIBIOS_DEVICE_NOT_FOUND; 194 195 return PCIBIOS_SUCCESSFUL; 196 197oh_my_gawd: 198 199 /* 200 * IOC3 is fucked fucked beyond believe ... Don't even give the 201 * generic PCI code a chance to touch the wrong register. 202 */ 203 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) 204 return PCIBIOS_SUCCESSFUL; 205 206 /* 207 * IOC3 is fucked fucked beyond believe ... Don't try to access 208 * anything but 32-bit words ... 209 */ 210 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; 211 212 if (get_dbe(cf, (u32 *) addr)) 213 return PCIBIOS_DEVICE_NOT_FOUND; 214 215 shift = ((where & 3) << 3); 216 mask = (0xffffffffU >> ((4 - size) << 3)); 217 smask = mask << shift; 218 219 cf = (cf & ~smask) | ((value & mask) << shift); 220 if (put_dbe(cf, (u32 *) addr)) 221 return PCIBIOS_DEVICE_NOT_FOUND; 222 223 return PCIBIOS_SUCCESSFUL; 224} 225 226static int pci_conf1_write_config(struct pci_bus *bus, unsigned int devfn, 227 int where, int size, u32 value) 228{ 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; 237 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; 242 243 /* 244 * IOC3 is fucked fucked beyond believe ... Don't even give the 245 * generic PCI code a chance to look at it for real ... 246 */ 247 if (cf == (PCI_VENDOR_ID_SGI | (PCI_DEVICE_ID_SGI_IOC3 << 16))) 248 goto oh_my_gawd; 249 250 addr = &bridge->b_type1_cfg.c[(fn << 8) | (where ^ (4 - size))]; 251 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); 258 } 259 260 if (res) 261 return PCIBIOS_DEVICE_NOT_FOUND; 262 263 return PCIBIOS_SUCCESSFUL; 264 265oh_my_gawd: 266 267 /* 268 * IOC3 is fucked fucked beyond believe ... Don't even give the 269 * generic PCI code a chance to touch the wrong register. 270 */ 271 if ((where >= 0x14 && where < 0x40) || (where >= 0x48)) 272 return PCIBIOS_SUCCESSFUL; 273 274 /* 275 * IOC3 is fucked fucked beyond believe ... Don't try to access 276 * anything but 32-bit words ... 277 */ 278 addr = &bridge->b_type0_cfg_dev[slot].f[fn].l[where >> 2]; 279 280 if (get_dbe(cf, (u32 *) addr)) 281 return PCIBIOS_DEVICE_NOT_FOUND; 282 283 shift = ((where & 3) << 3); 284 mask = (0xffffffffU >> ((4 - size) << 3)); 285 smask = mask << shift; 286 287 cf = (cf & ~smask) | ((value & mask) << shift); 288 if (put_dbe(cf, (u32 *) addr)) 289 return PCIBIOS_DEVICE_NOT_FOUND; 290 291 return PCIBIOS_SUCCESSFUL; 292} 293 294static int pci_write_config(struct pci_bus *bus, unsigned int devfn, 295 int where, int size, u32 value) 296{ 297 if (bus->number > 0) 298 return pci_conf1_write_config(bus, devfn, where, size, value); 299 300 return pci_conf0_write_config(bus, devfn, where, size, value); 301} 302 303struct pci_ops bridge_pci_ops = { 304 .read = pci_read_config, 305 .write = pci_write_config, 306}; 307