0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include "ssb_private.h"
0016
0017 #include <linux/ssb/ssb.h>
0018 #include <linux/ssb/ssb_regs.h>
0019 #include <linux/pci.h>
0020 #include <linux/io.h>
0021
0022 #include <pcmcia/cistpl.h>
0023 #include <pcmcia/ds.h>
0024
0025
0026 const char *ssb_core_name(u16 coreid)
0027 {
0028 switch (coreid) {
0029 case SSB_DEV_CHIPCOMMON:
0030 return "ChipCommon";
0031 case SSB_DEV_ILINE20:
0032 return "ILine 20";
0033 case SSB_DEV_SDRAM:
0034 return "SDRAM";
0035 case SSB_DEV_PCI:
0036 return "PCI";
0037 case SSB_DEV_MIPS:
0038 return "MIPS";
0039 case SSB_DEV_ETHERNET:
0040 return "Fast Ethernet";
0041 case SSB_DEV_V90:
0042 return "V90";
0043 case SSB_DEV_USB11_HOSTDEV:
0044 return "USB 1.1 Hostdev";
0045 case SSB_DEV_ADSL:
0046 return "ADSL";
0047 case SSB_DEV_ILINE100:
0048 return "ILine 100";
0049 case SSB_DEV_IPSEC:
0050 return "IPSEC";
0051 case SSB_DEV_PCMCIA:
0052 return "PCMCIA";
0053 case SSB_DEV_INTERNAL_MEM:
0054 return "Internal Memory";
0055 case SSB_DEV_MEMC_SDRAM:
0056 return "MEMC SDRAM";
0057 case SSB_DEV_EXTIF:
0058 return "EXTIF";
0059 case SSB_DEV_80211:
0060 return "IEEE 802.11";
0061 case SSB_DEV_MIPS_3302:
0062 return "MIPS 3302";
0063 case SSB_DEV_USB11_HOST:
0064 return "USB 1.1 Host";
0065 case SSB_DEV_USB11_DEV:
0066 return "USB 1.1 Device";
0067 case SSB_DEV_USB20_HOST:
0068 return "USB 2.0 Host";
0069 case SSB_DEV_USB20_DEV:
0070 return "USB 2.0 Device";
0071 case SSB_DEV_SDIO_HOST:
0072 return "SDIO Host";
0073 case SSB_DEV_ROBOSWITCH:
0074 return "Roboswitch";
0075 case SSB_DEV_PARA_ATA:
0076 return "PATA";
0077 case SSB_DEV_SATA_XORDMA:
0078 return "SATA XOR-DMA";
0079 case SSB_DEV_ETHERNET_GBIT:
0080 return "GBit Ethernet";
0081 case SSB_DEV_PCIE:
0082 return "PCI-E";
0083 case SSB_DEV_MIMO_PHY:
0084 return "MIMO PHY";
0085 case SSB_DEV_SRAM_CTRLR:
0086 return "SRAM Controller";
0087 case SSB_DEV_MINI_MACPHY:
0088 return "Mini MACPHY";
0089 case SSB_DEV_ARM_1176:
0090 return "ARM 1176";
0091 case SSB_DEV_ARM_7TDMI:
0092 return "ARM 7TDMI";
0093 case SSB_DEV_ARM_CM3:
0094 return "ARM Cortex M3";
0095 }
0096 return "UNKNOWN";
0097 }
0098
0099 static u16 pcidev_to_chipid(struct pci_dev *pci_dev)
0100 {
0101 u16 chipid_fallback = 0;
0102
0103 switch (pci_dev->device) {
0104 case 0x4301:
0105 chipid_fallback = 0x4301;
0106 break;
0107 case 0x4305 ... 0x4307:
0108 chipid_fallback = 0x4307;
0109 break;
0110 case 0x4403:
0111 chipid_fallback = 0x4402;
0112 break;
0113 case 0x4610 ... 0x4615:
0114 chipid_fallback = 0x4610;
0115 break;
0116 case 0x4710 ... 0x4715:
0117 chipid_fallback = 0x4710;
0118 break;
0119 case 0x4320 ... 0x4325:
0120 chipid_fallback = 0x4309;
0121 break;
0122 case PCI_DEVICE_ID_BCM4401:
0123 case PCI_DEVICE_ID_BCM4401B0:
0124 case PCI_DEVICE_ID_BCM4401B1:
0125 chipid_fallback = 0x4401;
0126 break;
0127 default:
0128 dev_err(&pci_dev->dev, "PCI-ID not in fallback list\n");
0129 }
0130
0131 return chipid_fallback;
0132 }
0133
0134 static u8 chipid_to_nrcores(u16 chipid)
0135 {
0136 switch (chipid) {
0137 case 0x5365:
0138 return 7;
0139 case 0x4306:
0140 return 6;
0141 case 0x4310:
0142 return 8;
0143 case 0x4307:
0144 case 0x4301:
0145 return 5;
0146 case 0x4401:
0147 case 0x4402:
0148 return 3;
0149 case 0x4710:
0150 case 0x4610:
0151 case 0x4704:
0152 return 9;
0153 default:
0154 pr_err("CHIPID not in nrcores fallback list\n");
0155 }
0156
0157 return 1;
0158 }
0159
0160 static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
0161 u16 offset)
0162 {
0163 u32 lo, hi;
0164
0165 switch (bus->bustype) {
0166 case SSB_BUSTYPE_SSB:
0167 offset += current_coreidx * SSB_CORE_SIZE;
0168 break;
0169 case SSB_BUSTYPE_PCI:
0170 break;
0171 case SSB_BUSTYPE_PCMCIA:
0172 if (offset >= 0x800) {
0173 ssb_pcmcia_switch_segment(bus, 1);
0174 offset -= 0x800;
0175 } else
0176 ssb_pcmcia_switch_segment(bus, 0);
0177 lo = readw(bus->mmio + offset);
0178 hi = readw(bus->mmio + offset + 2);
0179 return lo | (hi << 16);
0180 case SSB_BUSTYPE_SDIO:
0181 offset += current_coreidx * SSB_CORE_SIZE;
0182 return ssb_sdio_scan_read32(bus, offset);
0183 }
0184 return readl(bus->mmio + offset);
0185 }
0186
0187 static int scan_switchcore(struct ssb_bus *bus, u8 coreidx)
0188 {
0189 switch (bus->bustype) {
0190 case SSB_BUSTYPE_SSB:
0191 break;
0192 case SSB_BUSTYPE_PCI:
0193 return ssb_pci_switch_coreidx(bus, coreidx);
0194 case SSB_BUSTYPE_PCMCIA:
0195 return ssb_pcmcia_switch_coreidx(bus, coreidx);
0196 case SSB_BUSTYPE_SDIO:
0197 return ssb_sdio_scan_switch_coreidx(bus, coreidx);
0198 }
0199 return 0;
0200 }
0201
0202 void ssb_iounmap(struct ssb_bus *bus)
0203 {
0204 switch (bus->bustype) {
0205 case SSB_BUSTYPE_SSB:
0206 case SSB_BUSTYPE_PCMCIA:
0207 iounmap(bus->mmio);
0208 break;
0209 case SSB_BUSTYPE_PCI:
0210 #ifdef CONFIG_SSB_PCIHOST
0211 pci_iounmap(bus->host_pci, bus->mmio);
0212 #else
0213 WARN_ON(1);
0214 #endif
0215 break;
0216 case SSB_BUSTYPE_SDIO:
0217 break;
0218 }
0219 bus->mmio = NULL;
0220 bus->mapped_device = NULL;
0221 }
0222
0223 static void __iomem *ssb_ioremap(struct ssb_bus *bus,
0224 unsigned long baseaddr)
0225 {
0226 void __iomem *mmio = NULL;
0227
0228 switch (bus->bustype) {
0229 case SSB_BUSTYPE_SSB:
0230
0231 fallthrough;
0232 case SSB_BUSTYPE_PCMCIA:
0233 mmio = ioremap(baseaddr, SSB_CORE_SIZE);
0234 break;
0235 case SSB_BUSTYPE_PCI:
0236 #ifdef CONFIG_SSB_PCIHOST
0237 mmio = pci_iomap(bus->host_pci, 0, ~0UL);
0238 #else
0239 WARN_ON(1);
0240 #endif
0241 break;
0242 case SSB_BUSTYPE_SDIO:
0243
0244 mmio = (void __iomem *)baseaddr;
0245 break;
0246 }
0247
0248 return mmio;
0249 }
0250
0251 static int we_support_multiple_80211_cores(struct ssb_bus *bus)
0252 {
0253
0254
0255
0256
0257
0258 #ifdef CONFIG_SSB_PCIHOST
0259 if (bus->bustype == SSB_BUSTYPE_PCI) {
0260 if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
0261 ((bus->host_pci->device == 0x4313) ||
0262 (bus->host_pci->device == 0x431A) ||
0263 (bus->host_pci->device == 0x4321) ||
0264 (bus->host_pci->device == 0x4324)))
0265 return 1;
0266 }
0267 #endif
0268 return 0;
0269 }
0270
0271 int ssb_bus_scan(struct ssb_bus *bus,
0272 unsigned long baseaddr)
0273 {
0274 int err = -ENOMEM;
0275 void __iomem *mmio;
0276 u32 idhi, cc, rev, tmp;
0277 int dev_i, i;
0278 struct ssb_device *dev;
0279 int nr_80211_cores = 0;
0280
0281 mmio = ssb_ioremap(bus, baseaddr);
0282 if (!mmio)
0283 goto out;
0284 bus->mmio = mmio;
0285
0286 err = scan_switchcore(bus, 0);
0287 if (err)
0288 goto err_unmap;
0289
0290 idhi = scan_read32(bus, 0, SSB_IDHIGH);
0291 cc = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
0292 rev = (idhi & SSB_IDHIGH_RCLO);
0293 rev |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT;
0294
0295 bus->nr_devices = 0;
0296 if (cc == SSB_DEV_CHIPCOMMON) {
0297 tmp = scan_read32(bus, 0, SSB_CHIPCO_CHIPID);
0298
0299 bus->chip_id = (tmp & SSB_CHIPCO_IDMASK);
0300 bus->chip_rev = (tmp & SSB_CHIPCO_REVMASK) >>
0301 SSB_CHIPCO_REVSHIFT;
0302 bus->chip_package = (tmp & SSB_CHIPCO_PACKMASK) >>
0303 SSB_CHIPCO_PACKSHIFT;
0304 if (rev >= 4) {
0305 bus->nr_devices = (tmp & SSB_CHIPCO_NRCORESMASK) >>
0306 SSB_CHIPCO_NRCORESSHIFT;
0307 }
0308 tmp = scan_read32(bus, 0, SSB_CHIPCO_CAP);
0309 bus->chipco.capabilities = tmp;
0310 } else {
0311 if (bus->bustype == SSB_BUSTYPE_PCI) {
0312 bus->chip_id = pcidev_to_chipid(bus->host_pci);
0313 bus->chip_rev = bus->host_pci->revision;
0314 bus->chip_package = 0;
0315 } else {
0316 bus->chip_id = 0x4710;
0317 bus->chip_rev = 0;
0318 bus->chip_package = 0;
0319 }
0320 }
0321 pr_info("Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n",
0322 bus->chip_id, bus->chip_rev, bus->chip_package);
0323 if (!bus->nr_devices)
0324 bus->nr_devices = chipid_to_nrcores(bus->chip_id);
0325 if (bus->nr_devices > ARRAY_SIZE(bus->devices)) {
0326 pr_err("More than %d ssb cores found (%d)\n",
0327 SSB_MAX_NR_CORES, bus->nr_devices);
0328 err = -EINVAL;
0329 goto err_unmap;
0330 }
0331 if (bus->bustype == SSB_BUSTYPE_SSB) {
0332
0333
0334
0335 err = -ENOMEM;
0336 iounmap(mmio);
0337 mmio = ioremap(baseaddr, SSB_CORE_SIZE * bus->nr_devices);
0338 if (!mmio)
0339 goto out;
0340 bus->mmio = mmio;
0341 }
0342
0343
0344 for (i = 0, dev_i = 0; i < bus->nr_devices; i++) {
0345 err = scan_switchcore(bus, i);
0346 if (err)
0347 goto err_unmap;
0348 dev = &(bus->devices[dev_i]);
0349
0350 idhi = scan_read32(bus, i, SSB_IDHIGH);
0351 dev->id.coreid = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
0352 dev->id.revision = (idhi & SSB_IDHIGH_RCLO);
0353 dev->id.revision |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT;
0354 dev->id.vendor = (idhi & SSB_IDHIGH_VC) >> SSB_IDHIGH_VC_SHIFT;
0355 dev->core_index = i;
0356 dev->bus = bus;
0357 dev->ops = bus->ops;
0358
0359 pr_debug("Core %d found: %s (cc 0x%03X, rev 0x%02X, vendor 0x%04X)\n",
0360 i, ssb_core_name(dev->id.coreid),
0361 dev->id.coreid, dev->id.revision, dev->id.vendor);
0362
0363 switch (dev->id.coreid) {
0364 case SSB_DEV_80211:
0365 nr_80211_cores++;
0366 if (nr_80211_cores > 1) {
0367 if (!we_support_multiple_80211_cores(bus)) {
0368 pr_debug("Ignoring additional 802.11 core\n");
0369 continue;
0370 }
0371 }
0372 break;
0373 case SSB_DEV_EXTIF:
0374 #ifdef CONFIG_SSB_DRIVER_EXTIF
0375 if (bus->extif.dev) {
0376 pr_warn("WARNING: Multiple EXTIFs found\n");
0377 break;
0378 }
0379 bus->extif.dev = dev;
0380 #endif
0381 break;
0382 case SSB_DEV_CHIPCOMMON:
0383 if (bus->chipco.dev) {
0384 pr_warn("WARNING: Multiple ChipCommon found\n");
0385 break;
0386 }
0387 bus->chipco.dev = dev;
0388 break;
0389 case SSB_DEV_MIPS:
0390 case SSB_DEV_MIPS_3302:
0391 #ifdef CONFIG_SSB_DRIVER_MIPS
0392 if (bus->mipscore.dev) {
0393 pr_warn("WARNING: Multiple MIPS cores found\n");
0394 break;
0395 }
0396 bus->mipscore.dev = dev;
0397 #endif
0398 break;
0399 case SSB_DEV_PCI:
0400 case SSB_DEV_PCIE:
0401 #ifdef CONFIG_SSB_DRIVER_PCICORE
0402 if (bus->bustype == SSB_BUSTYPE_PCI) {
0403
0404
0405
0406 if (dev->id.coreid == SSB_DEV_PCI) {
0407 if (pci_is_pcie(bus->host_pci))
0408 continue;
0409 } else {
0410 if (!pci_is_pcie(bus->host_pci))
0411 continue;
0412 }
0413 }
0414 if (bus->pcicore.dev) {
0415 pr_warn("WARNING: Multiple PCI(E) cores found\n");
0416 break;
0417 }
0418 bus->pcicore.dev = dev;
0419 #endif
0420 break;
0421 case SSB_DEV_ETHERNET:
0422 if (bus->bustype == SSB_BUSTYPE_PCI) {
0423 if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
0424 (bus->host_pci->device & 0xFF00) == 0x4300) {
0425
0426
0427
0428 continue;
0429 }
0430 }
0431 break;
0432 default:
0433 break;
0434 }
0435
0436 dev_i++;
0437 }
0438 bus->nr_devices = dev_i;
0439
0440 err = 0;
0441 out:
0442 return err;
0443 err_unmap:
0444 ssb_iounmap(bus);
0445 goto out;
0446 }