2  * Sonics Silicon Backplane
 
   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.
 
  12  * Licensed under the GNU/GPL. See COPYING for details.
 
  15 #include <linux/ssb/ssb.h>
 
  16 #include <linux/ssb/ssb_regs.h>
 
  17 #include <linux/pci.h>
 
  20 #include <pcmcia/cs_types.h>
 
  21 #include <pcmcia/cs.h>
 
  22 #include <pcmcia/cistpl.h>
 
  23 #include <pcmcia/ds.h>
 
  25 #include "ssb_private.h"
 
  28 const char *ssb_core_name(u16 coreid)
 
  31         case SSB_DEV_CHIPCOMMON:
 
  41         case SSB_DEV_ETHERNET:
 
  42                 return "Fast Ethernet";
 
  45         case SSB_DEV_USB11_HOSTDEV:
 
  46                 return "USB 1.1 Hostdev";
 
  49         case SSB_DEV_ILINE100:
 
  55         case SSB_DEV_INTERNAL_MEM:
 
  56                 return "Internal Memory";
 
  57         case SSB_DEV_MEMC_SDRAM:
 
  63         case SSB_DEV_MIPS_3302:
 
  65         case SSB_DEV_USB11_HOST:
 
  66                 return "USB 1.1 Host";
 
  67         case SSB_DEV_USB11_DEV:
 
  68                 return "USB 1.1 Device";
 
  69         case SSB_DEV_USB20_HOST:
 
  70                 return "USB 2.0 Host";
 
  71         case SSB_DEV_USB20_DEV:
 
  72                 return "USB 2.0 Device";
 
  73         case SSB_DEV_SDIO_HOST:
 
  75         case SSB_DEV_ROBOSWITCH:
 
  77         case SSB_DEV_PARA_ATA:
 
  79         case SSB_DEV_SATA_XORDMA:
 
  80                 return "SATA XOR-DMA";
 
  81         case SSB_DEV_ETHERNET_GBIT:
 
  82                 return "GBit Ethernet";
 
  85         case SSB_DEV_MIMO_PHY:
 
  87         case SSB_DEV_SRAM_CTRLR:
 
  88                 return "SRAM Controller";
 
  89         case SSB_DEV_MINI_MACPHY:
 
  91         case SSB_DEV_ARM_1176:
 
  93         case SSB_DEV_ARM_7TDMI:
 
  99 static u16 pcidev_to_chipid(struct pci_dev *pci_dev)
 
 101         u16 chipid_fallback = 0;
 
 103         switch (pci_dev->device) {
 
 105                 chipid_fallback = 0x4301;
 
 107         case 0x4305 ... 0x4307:
 
 108                 chipid_fallback = 0x4307;
 
 111                 chipid_fallback = 0x4402;
 
 113         case 0x4610 ... 0x4615:
 
 114                 chipid_fallback = 0x4610;
 
 116         case 0x4710 ... 0x4715:
 
 117                 chipid_fallback = 0x4710;
 
 119         case 0x4320 ... 0x4325:
 
 120                 chipid_fallback = 0x4309;
 
 122         case PCI_DEVICE_ID_BCM4401:
 
 123         case PCI_DEVICE_ID_BCM4401B0:
 
 124         case PCI_DEVICE_ID_BCM4401B1:
 
 125                 chipid_fallback = 0x4401;
 
 128                 ssb_printk(KERN_ERR PFX
 
 129                            "PCI-ID not in fallback list\n");
 
 132         return chipid_fallback;
 
 135 static u8 chipid_to_nrcores(u16 chipid)
 
 155                 ssb_printk(KERN_ERR PFX
 
 156                            "CHIPID not in nrcores fallback list\n");
 
 162 static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
 
 165         switch (bus->bustype) {
 
 166         case SSB_BUSTYPE_SSB:
 
 167                 offset += current_coreidx * SSB_CORE_SIZE;
 
 169         case SSB_BUSTYPE_PCI:
 
 171         case SSB_BUSTYPE_PCMCIA:
 
 172                 if (offset >= 0x800) {
 
 173                         ssb_pcmcia_switch_segment(bus, 1);
 
 176                         ssb_pcmcia_switch_segment(bus, 0);
 
 179         return readl(bus->mmio + offset);
 
 182 static int scan_switchcore(struct ssb_bus *bus, u8 coreidx)
 
 184         switch (bus->bustype) {
 
 185         case SSB_BUSTYPE_SSB:
 
 187         case SSB_BUSTYPE_PCI:
 
 188                 return ssb_pci_switch_coreidx(bus, coreidx);
 
 189         case SSB_BUSTYPE_PCMCIA:
 
 190                 return ssb_pcmcia_switch_coreidx(bus, coreidx);
 
 195 void ssb_iounmap(struct ssb_bus *bus)
 
 197         switch (bus->bustype) {
 
 198         case SSB_BUSTYPE_SSB:
 
 199         case SSB_BUSTYPE_PCMCIA:
 
 202         case SSB_BUSTYPE_PCI:
 
 203 #ifdef CONFIG_SSB_PCIHOST
 
 204                 pci_iounmap(bus->host_pci, bus->mmio);
 
 206                 SSB_BUG_ON(1); /* Can't reach this code. */
 
 211         bus->mapped_device = NULL;
 
 214 static void __iomem *ssb_ioremap(struct ssb_bus *bus,
 
 215                                  unsigned long baseaddr)
 
 217         void __iomem *mmio = NULL;
 
 219         switch (bus->bustype) {
 
 220         case SSB_BUSTYPE_SSB:
 
 221                 /* Only map the first core for now. */
 
 223         case SSB_BUSTYPE_PCMCIA:
 
 224                 mmio = ioremap(baseaddr, SSB_CORE_SIZE);
 
 226         case SSB_BUSTYPE_PCI:
 
 227 #ifdef CONFIG_SSB_PCIHOST
 
 228                 mmio = pci_iomap(bus->host_pci, 0, ~0UL);
 
 230                 SSB_BUG_ON(1); /* Can't reach this code. */
 
 238 static int we_support_multiple_80211_cores(struct ssb_bus *bus)
 
 240         /* More than one 802.11 core is only supported by special chips.
 
 241          * There are chips with two 802.11 cores, but with dangling
 
 242          * pins on the second core. Be careful and reject them here.
 
 245 #ifdef CONFIG_SSB_PCIHOST
 
 246         if (bus->bustype == SSB_BUSTYPE_PCI) {
 
 247                 if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
 
 248                     bus->host_pci->device == 0x4324)
 
 251 #endif /* CONFIG_SSB_PCIHOST */
 
 255 int ssb_bus_scan(struct ssb_bus *bus,
 
 256                  unsigned long baseaddr)
 
 260         u32 idhi, cc, rev, tmp;
 
 262         struct ssb_device *dev;
 
 263         int nr_80211_cores = 0;
 
 265         mmio = ssb_ioremap(bus, baseaddr);
 
 270         err = scan_switchcore(bus, 0); /* Switch to first core */
 
 274         idhi = scan_read32(bus, 0, SSB_IDHIGH);
 
 275         cc = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
 
 276         rev = (idhi & SSB_IDHIGH_RCLO);
 
 277         rev |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT;
 
 280         if (cc == SSB_DEV_CHIPCOMMON) {
 
 281                 tmp = scan_read32(bus, 0, SSB_CHIPCO_CHIPID);
 
 283                 bus->chip_id = (tmp & SSB_CHIPCO_IDMASK);
 
 284                 bus->chip_rev = (tmp & SSB_CHIPCO_REVMASK) >>
 
 286                 bus->chip_package = (tmp & SSB_CHIPCO_PACKMASK) >>
 
 287                                     SSB_CHIPCO_PACKSHIFT;
 
 289                         bus->nr_devices = (tmp & SSB_CHIPCO_NRCORESMASK) >>
 
 290                                           SSB_CHIPCO_NRCORESSHIFT;
 
 292                 tmp = scan_read32(bus, 0, SSB_CHIPCO_CAP);
 
 293                 bus->chipco.capabilities = tmp;
 
 295                 if (bus->bustype == SSB_BUSTYPE_PCI) {
 
 296                         bus->chip_id = pcidev_to_chipid(bus->host_pci);
 
 297                         pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
 
 299                         bus->chip_package = 0;
 
 301                         bus->chip_id = 0x4710;
 
 303                         bus->chip_package = 0;
 
 306         if (!bus->nr_devices)
 
 307                 bus->nr_devices = chipid_to_nrcores(bus->chip_id);
 
 308         if (bus->nr_devices > ARRAY_SIZE(bus->devices)) {
 
 309                 ssb_printk(KERN_ERR PFX
 
 310                            "More than %d ssb cores found (%d)\n",
 
 311                            SSB_MAX_NR_CORES, bus->nr_devices);
 
 314         if (bus->bustype == SSB_BUSTYPE_SSB) {
 
 315                 /* Now that we know the number of cores,
 
 316                  * remap the whole IO space for all cores.
 
 320                 mmio = ioremap(baseaddr, SSB_CORE_SIZE * bus->nr_devices);
 
 326         /* Fetch basic information about each core/device */
 
 327         for (i = 0, dev_i = 0; i < bus->nr_devices; i++) {
 
 328                 err = scan_switchcore(bus, i);
 
 331                 dev = &(bus->devices[dev_i]);
 
 333                 idhi = scan_read32(bus, i, SSB_IDHIGH);
 
 334                 dev->id.coreid = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
 
 335                 dev->id.revision = (idhi & SSB_IDHIGH_RCLO);
 
 336                 dev->id.revision |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT;
 
 337                 dev->id.vendor = (idhi & SSB_IDHIGH_VC) >> SSB_IDHIGH_VC_SHIFT;
 
 342                 ssb_dprintk(KERN_INFO PFX
 
 344                             "(cc 0x%03X, rev 0x%02X, vendor 0x%04X)\n",
 
 345                             i, ssb_core_name(dev->id.coreid),
 
 346                             dev->id.coreid, dev->id.revision, dev->id.vendor);
 
 348                 switch (dev->id.coreid) {
 
 351                         if (nr_80211_cores > 1) {
 
 352                                 if (!we_support_multiple_80211_cores(bus)) {
 
 353                                         ssb_dprintk(KERN_INFO PFX "Ignoring additional "
 
 360 #ifdef CONFIG_SSB_DRIVER_EXTIF
 
 361                         if (bus->extif.dev) {
 
 362                                 ssb_printk(KERN_WARNING PFX
 
 363                                            "WARNING: Multiple EXTIFs found\n");
 
 366                         bus->extif.dev = dev;
 
 367 #endif /* CONFIG_SSB_DRIVER_EXTIF */
 
 369                 case SSB_DEV_CHIPCOMMON:
 
 370                         if (bus->chipco.dev) {
 
 371                                 ssb_printk(KERN_WARNING PFX
 
 372                                            "WARNING: Multiple ChipCommon found\n");
 
 375                         bus->chipco.dev = dev;
 
 378                 case SSB_DEV_MIPS_3302:
 
 379 #ifdef CONFIG_SSB_DRIVER_MIPS
 
 380                         if (bus->mipscore.dev) {
 
 381                                 ssb_printk(KERN_WARNING PFX
 
 382                                            "WARNING: Multiple MIPS cores found\n");
 
 385                         bus->mipscore.dev = dev;
 
 386 #endif /* CONFIG_SSB_DRIVER_MIPS */
 
 390 #ifdef CONFIG_SSB_DRIVER_PCICORE
 
 391                         if (bus->bustype == SSB_BUSTYPE_PCI) {
 
 392                                 /* Ignore PCI cores on PCI-E cards.
 
 393                                  * Ignore PCI-E cores on PCI cards. */
 
 394                                 if (dev->id.coreid == SSB_DEV_PCI) {
 
 395                                         if (bus->host_pci->is_pcie)
 
 398                                         if (!bus->host_pci->is_pcie)
 
 402                         if (bus->pcicore.dev) {
 
 403                                 ssb_printk(KERN_WARNING PFX
 
 404                                            "WARNING: Multiple PCI(E) cores found\n");
 
 407                         bus->pcicore.dev = dev;
 
 408 #endif /* CONFIG_SSB_DRIVER_PCICORE */
 
 416         bus->nr_devices = dev_i;