1 /* 2 * Sonics Silicon Backplane 3 * Bus scanning 4 * 5 * Copyright (C) 2005-2007 Michael Buesch <mb@bu3sch.de> 6 * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de> 7 * Copyright (C) 2005 Stefano Brivio <st3@riseup.net> 8 * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org> 9 * Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch> 10 * Copyright (C) 2006 Broadcom Corporation. 11 * 12 * Licensed under the GNU/GPL. See COPYING for details. 13 */ 14 15 #include <linux/ssb/ssb.h> 16 #include <linux/ssb/ssb_regs.h> 17 #include <linux/pci.h> 18 #include <linux/io.h> 19 20 #include <pcmcia/cs.h> 21 #include <pcmcia/cistpl.h> 22 #include <pcmcia/ds.h> 23 24 #include "ssb_private.h" 25 26 27 const char *ssb_core_name(u16 coreid) 28 { 29 switch (coreid) { 30 case SSB_DEV_CHIPCOMMON: 31 return "ChipCommon"; 32 case SSB_DEV_ILINE20: 33 return "ILine 20"; 34 case SSB_DEV_SDRAM: 35 return "SDRAM"; 36 case SSB_DEV_PCI: 37 return "PCI"; 38 case SSB_DEV_MIPS: 39 return "MIPS"; 40 case SSB_DEV_ETHERNET: 41 return "Fast Ethernet"; 42 case SSB_DEV_V90: 43 return "V90"; 44 case SSB_DEV_USB11_HOSTDEV: 45 return "USB 1.1 Hostdev"; 46 case SSB_DEV_ADSL: 47 return "ADSL"; 48 case SSB_DEV_ILINE100: 49 return "ILine 100"; 50 case SSB_DEV_IPSEC: 51 return "IPSEC"; 52 case SSB_DEV_PCMCIA: 53 return "PCMCIA"; 54 case SSB_DEV_INTERNAL_MEM: 55 return "Internal Memory"; 56 case SSB_DEV_MEMC_SDRAM: 57 return "MEMC SDRAM"; 58 case SSB_DEV_EXTIF: 59 return "EXTIF"; 60 case SSB_DEV_80211: 61 return "IEEE 802.11"; 62 case SSB_DEV_MIPS_3302: 63 return "MIPS 3302"; 64 case SSB_DEV_USB11_HOST: 65 return "USB 1.1 Host"; 66 case SSB_DEV_USB11_DEV: 67 return "USB 1.1 Device"; 68 case SSB_DEV_USB20_HOST: 69 return "USB 2.0 Host"; 70 case SSB_DEV_USB20_DEV: 71 return "USB 2.0 Device"; 72 case SSB_DEV_SDIO_HOST: 73 return "SDIO Host"; 74 case SSB_DEV_ROBOSWITCH: 75 return "Roboswitch"; 76 case SSB_DEV_PARA_ATA: 77 return "PATA"; 78 case SSB_DEV_SATA_XORDMA: 79 return "SATA XOR-DMA"; 80 case SSB_DEV_ETHERNET_GBIT: 81 return "GBit Ethernet"; 82 case SSB_DEV_PCIE: 83 return "PCI-E"; 84 case SSB_DEV_MIMO_PHY: 85 return "MIMO PHY"; 86 case SSB_DEV_SRAM_CTRLR: 87 return "SRAM Controller"; 88 case SSB_DEV_MINI_MACPHY: 89 return "Mini MACPHY"; 90 case SSB_DEV_ARM_1176: 91 return "ARM 1176"; 92 case SSB_DEV_ARM_7TDMI: 93 return "ARM 7TDMI"; 94 } 95 return "UNKNOWN"; 96 } 97 98 static u16 pcidev_to_chipid(struct pci_dev *pci_dev) 99 { 100 u16 chipid_fallback = 0; 101 102 switch (pci_dev->device) { 103 case 0x4301: 104 chipid_fallback = 0x4301; 105 break; 106 case 0x4305 ... 0x4307: 107 chipid_fallback = 0x4307; 108 break; 109 case 0x4403: 110 chipid_fallback = 0x4402; 111 break; 112 case 0x4610 ... 0x4615: 113 chipid_fallback = 0x4610; 114 break; 115 case 0x4710 ... 0x4715: 116 chipid_fallback = 0x4710; 117 break; 118 case 0x4320 ... 0x4325: 119 chipid_fallback = 0x4309; 120 break; 121 case PCI_DEVICE_ID_BCM4401: 122 case PCI_DEVICE_ID_BCM4401B0: 123 case PCI_DEVICE_ID_BCM4401B1: 124 chipid_fallback = 0x4401; 125 break; 126 default: 127 ssb_printk(KERN_ERR PFX 128 "PCI-ID not in fallback list\n"); 129 } 130 131 return chipid_fallback; 132 } 133 134 static u8 chipid_to_nrcores(u16 chipid) 135 { 136 switch (chipid) { 137 case 0x5365: 138 return 7; 139 case 0x4306: 140 return 6; 141 case 0x4310: 142 return 8; 143 case 0x4307: 144 case 0x4301: 145 return 5; 146 case 0x4401: 147 case 0x4402: 148 return 3; 149 case 0x4710: 150 case 0x4610: 151 case 0x4704: 152 return 9; 153 default: 154 ssb_printk(KERN_ERR PFX 155 "CHIPID not in nrcores fallback list\n"); 156 } 157 158 return 1; 159 } 160 161 static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx, 162 u16 offset) 163 { 164 u32 lo, hi; 165 166 switch (bus->bustype) { 167 case SSB_BUSTYPE_SSB: 168 offset += current_coreidx * SSB_CORE_SIZE; 169 break; 170 case SSB_BUSTYPE_PCI: 171 break; 172 case SSB_BUSTYPE_PCMCIA: 173 if (offset >= 0x800) { 174 ssb_pcmcia_switch_segment(bus, 1); 175 offset -= 0x800; 176 } else 177 ssb_pcmcia_switch_segment(bus, 0); 178 lo = readw(bus->mmio + offset); 179 hi = readw(bus->mmio + offset + 2); 180 return lo | (hi << 16); 181 case SSB_BUSTYPE_SDIO: 182 offset += current_coreidx * SSB_CORE_SIZE; 183 return ssb_sdio_scan_read32(bus, offset); 184 } 185 return readl(bus->mmio + offset); 186 } 187 188 static int scan_switchcore(struct ssb_bus *bus, u8 coreidx) 189 { 190 switch (bus->bustype) { 191 case SSB_BUSTYPE_SSB: 192 break; 193 case SSB_BUSTYPE_PCI: 194 return ssb_pci_switch_coreidx(bus, coreidx); 195 case SSB_BUSTYPE_PCMCIA: 196 return ssb_pcmcia_switch_coreidx(bus, coreidx); 197 case SSB_BUSTYPE_SDIO: 198 return ssb_sdio_scan_switch_coreidx(bus, coreidx); 199 } 200 return 0; 201 } 202 203 void ssb_iounmap(struct ssb_bus *bus) 204 { 205 switch (bus->bustype) { 206 case SSB_BUSTYPE_SSB: 207 case SSB_BUSTYPE_PCMCIA: 208 iounmap(bus->mmio); 209 break; 210 case SSB_BUSTYPE_PCI: 211 #ifdef CONFIG_SSB_PCIHOST 212 pci_iounmap(bus->host_pci, bus->mmio); 213 #else 214 SSB_BUG_ON(1); /* Can't reach this code. */ 215 #endif 216 break; 217 case SSB_BUSTYPE_SDIO: 218 break; 219 } 220 bus->mmio = NULL; 221 bus->mapped_device = NULL; 222 } 223 224 static void __iomem *ssb_ioremap(struct ssb_bus *bus, 225 unsigned long baseaddr) 226 { 227 void __iomem *mmio = NULL; 228 229 switch (bus->bustype) { 230 case SSB_BUSTYPE_SSB: 231 /* Only map the first core for now. */ 232 /* fallthrough... */ 233 case SSB_BUSTYPE_PCMCIA: 234 mmio = ioremap(baseaddr, SSB_CORE_SIZE); 235 break; 236 case SSB_BUSTYPE_PCI: 237 #ifdef CONFIG_SSB_PCIHOST 238 mmio = pci_iomap(bus->host_pci, 0, ~0UL); 239 #else 240 SSB_BUG_ON(1); /* Can't reach this code. */ 241 #endif 242 break; 243 case SSB_BUSTYPE_SDIO: 244 /* Nothing to ioremap in the SDIO case, just fake it */ 245 mmio = (void __iomem *)baseaddr; 246 break; 247 } 248 249 return mmio; 250 } 251 252 static int we_support_multiple_80211_cores(struct ssb_bus *bus) 253 { 254 /* More than one 802.11 core is only supported by special chips. 255 * There are chips with two 802.11 cores, but with dangling 256 * pins on the second core. Be careful and reject them here. 257 */ 258 259 #ifdef CONFIG_SSB_PCIHOST 260 if (bus->bustype == SSB_BUSTYPE_PCI) { 261 if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM && 262 bus->host_pci->device == 0x4324) 263 return 1; 264 } 265 #endif /* CONFIG_SSB_PCIHOST */ 266 return 0; 267 } 268 269 int ssb_bus_scan(struct ssb_bus *bus, 270 unsigned long baseaddr) 271 { 272 int err = -ENOMEM; 273 void __iomem *mmio; 274 u32 idhi, cc, rev, tmp; 275 int dev_i, i; 276 struct ssb_device *dev; 277 int nr_80211_cores = 0; 278 279 mmio = ssb_ioremap(bus, baseaddr); 280 if (!mmio) 281 goto out; 282 bus->mmio = mmio; 283 284 err = scan_switchcore(bus, 0); /* Switch to first core */ 285 if (err) 286 goto err_unmap; 287 288 idhi = scan_read32(bus, 0, SSB_IDHIGH); 289 cc = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT; 290 rev = (idhi & SSB_IDHIGH_RCLO); 291 rev |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT; 292 293 bus->nr_devices = 0; 294 if (cc == SSB_DEV_CHIPCOMMON) { 295 tmp = scan_read32(bus, 0, SSB_CHIPCO_CHIPID); 296 297 bus->chip_id = (tmp & SSB_CHIPCO_IDMASK); 298 bus->chip_rev = (tmp & SSB_CHIPCO_REVMASK) >> 299 SSB_CHIPCO_REVSHIFT; 300 bus->chip_package = (tmp & SSB_CHIPCO_PACKMASK) >> 301 SSB_CHIPCO_PACKSHIFT; 302 if (rev >= 4) { 303 bus->nr_devices = (tmp & SSB_CHIPCO_NRCORESMASK) >> 304 SSB_CHIPCO_NRCORESSHIFT; 305 } 306 tmp = scan_read32(bus, 0, SSB_CHIPCO_CAP); 307 bus->chipco.capabilities = tmp; 308 } else { 309 if (bus->bustype == SSB_BUSTYPE_PCI) { 310 bus->chip_id = pcidev_to_chipid(bus->host_pci); 311 pci_read_config_word(bus->host_pci, PCI_REVISION_ID, 312 &bus->chip_rev); 313 bus->chip_package = 0; 314 } else { 315 bus->chip_id = 0x4710; 316 bus->chip_rev = 0; 317 bus->chip_package = 0; 318 } 319 } 320 if (!bus->nr_devices) 321 bus->nr_devices = chipid_to_nrcores(bus->chip_id); 322 if (bus->nr_devices > ARRAY_SIZE(bus->devices)) { 323 ssb_printk(KERN_ERR PFX 324 "More than %d ssb cores found (%d)\n", 325 SSB_MAX_NR_CORES, bus->nr_devices); 326 goto err_unmap; 327 } 328 if (bus->bustype == SSB_BUSTYPE_SSB) { 329 /* Now that we know the number of cores, 330 * remap the whole IO space for all cores. 331 */ 332 err = -ENOMEM; 333 iounmap(mmio); 334 mmio = ioremap(baseaddr, SSB_CORE_SIZE * bus->nr_devices); 335 if (!mmio) 336 goto out; 337 bus->mmio = mmio; 338 } 339 340 /* Fetch basic information about each core/device */ 341 for (i = 0, dev_i = 0; i < bus->nr_devices; i++) { 342 err = scan_switchcore(bus, i); 343 if (err) 344 goto err_unmap; 345 dev = &(bus->devices[dev_i]); 346 347 idhi = scan_read32(bus, i, SSB_IDHIGH); 348 dev->id.coreid = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT; 349 dev->id.revision = (idhi & SSB_IDHIGH_RCLO); 350 dev->id.revision |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT; 351 dev->id.vendor = (idhi & SSB_IDHIGH_VC) >> SSB_IDHIGH_VC_SHIFT; 352 dev->core_index = i; 353 dev->bus = bus; 354 dev->ops = bus->ops; 355 356 printk(KERN_DEBUG PFX 357 "Core %d found: %s " 358 "(cc 0x%03X, rev 0x%02X, vendor 0x%04X)\n", 359 i, ssb_core_name(dev->id.coreid), 360 dev->id.coreid, dev->id.revision, dev->id.vendor); 361 362 switch (dev->id.coreid) { 363 case SSB_DEV_80211: 364 nr_80211_cores++; 365 if (nr_80211_cores > 1) { 366 if (!we_support_multiple_80211_cores(bus)) { 367 ssb_dprintk(KERN_INFO PFX "Ignoring additional " 368 "802.11 core\n"); 369 continue; 370 } 371 } 372 break; 373 case SSB_DEV_EXTIF: 374 #ifdef CONFIG_SSB_DRIVER_EXTIF 375 if (bus->extif.dev) { 376 ssb_printk(KERN_WARNING PFX 377 "WARNING: Multiple EXTIFs found\n"); 378 break; 379 } 380 bus->extif.dev = dev; 381 #endif /* CONFIG_SSB_DRIVER_EXTIF */ 382 break; 383 case SSB_DEV_CHIPCOMMON: 384 if (bus->chipco.dev) { 385 ssb_printk(KERN_WARNING PFX 386 "WARNING: Multiple ChipCommon found\n"); 387 break; 388 } 389 bus->chipco.dev = dev; 390 break; 391 case SSB_DEV_MIPS: 392 case SSB_DEV_MIPS_3302: 393 #ifdef CONFIG_SSB_DRIVER_MIPS 394 if (bus->mipscore.dev) { 395 ssb_printk(KERN_WARNING PFX 396 "WARNING: Multiple MIPS cores found\n"); 397 break; 398 } 399 bus->mipscore.dev = dev; 400 #endif /* CONFIG_SSB_DRIVER_MIPS */ 401 break; 402 case SSB_DEV_PCI: 403 case SSB_DEV_PCIE: 404 #ifdef CONFIG_SSB_DRIVER_PCICORE 405 if (bus->bustype == SSB_BUSTYPE_PCI) { 406 /* Ignore PCI cores on PCI-E cards. 407 * Ignore PCI-E cores on PCI cards. */ 408 if (dev->id.coreid == SSB_DEV_PCI) { 409 if (bus->host_pci->is_pcie) 410 continue; 411 } else { 412 if (!bus->host_pci->is_pcie) 413 continue; 414 } 415 } 416 if (bus->pcicore.dev) { 417 ssb_printk(KERN_WARNING PFX 418 "WARNING: Multiple PCI(E) cores found\n"); 419 break; 420 } 421 bus->pcicore.dev = dev; 422 #endif /* CONFIG_SSB_DRIVER_PCICORE */ 423 break; 424 default: 425 break; 426 } 427 428 dev_i++; 429 } 430 bus->nr_devices = dev_i; 431 432 err = 0; 433 out: 434 return err; 435 err_unmap: 436 ssb_iounmap(bus); 437 goto out; 438 } 439