2 * Sonics Silicon Backplane
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.h>
21 #include <pcmcia/cistpl.h>
22 #include <pcmcia/ds.h>
24 #include "ssb_private.h"
27 const char *ssb_core_name(u16 coreid)
30 case SSB_DEV_CHIPCOMMON:
40 case SSB_DEV_ETHERNET:
41 return "Fast Ethernet";
44 case SSB_DEV_USB11_HOSTDEV:
45 return "USB 1.1 Hostdev";
48 case SSB_DEV_ILINE100:
54 case SSB_DEV_INTERNAL_MEM:
55 return "Internal Memory";
56 case SSB_DEV_MEMC_SDRAM:
62 case SSB_DEV_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:
74 case SSB_DEV_ROBOSWITCH:
76 case SSB_DEV_PARA_ATA:
78 case SSB_DEV_SATA_XORDMA:
79 return "SATA XOR-DMA";
80 case SSB_DEV_ETHERNET_GBIT:
81 return "GBit Ethernet";
84 case SSB_DEV_MIMO_PHY:
86 case SSB_DEV_SRAM_CTRLR:
87 return "SRAM Controller";
88 case SSB_DEV_MINI_MACPHY:
90 case SSB_DEV_ARM_1176:
92 case SSB_DEV_ARM_7TDMI:
98 static u16 pcidev_to_chipid(struct pci_dev *pci_dev)
100 u16 chipid_fallback = 0;
102 switch (pci_dev->device) {
104 chipid_fallback = 0x4301;
106 case 0x4305 ... 0x4307:
107 chipid_fallback = 0x4307;
110 chipid_fallback = 0x4402;
112 case 0x4610 ... 0x4615:
113 chipid_fallback = 0x4610;
115 case 0x4710 ... 0x4715:
116 chipid_fallback = 0x4710;
118 case 0x4320 ... 0x4325:
119 chipid_fallback = 0x4309;
121 case PCI_DEVICE_ID_BCM4401:
122 case PCI_DEVICE_ID_BCM4401B0:
123 case PCI_DEVICE_ID_BCM4401B1:
124 chipid_fallback = 0x4401;
127 ssb_printk(KERN_ERR PFX
128 "PCI-ID not in fallback list\n");
131 return chipid_fallback;
134 static u8 chipid_to_nrcores(u16 chipid)
154 ssb_printk(KERN_ERR PFX
155 "CHIPID not in nrcores fallback list\n");
161 static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
166 switch (bus->bustype) {
167 case SSB_BUSTYPE_SSB:
168 offset += current_coreidx * SSB_CORE_SIZE;
170 case SSB_BUSTYPE_PCI:
172 case SSB_BUSTYPE_PCMCIA:
173 if (offset >= 0x800) {
174 ssb_pcmcia_switch_segment(bus, 1);
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);
185 return readl(bus->mmio + offset);
188 static int scan_switchcore(struct ssb_bus *bus, u8 coreidx)
190 switch (bus->bustype) {
191 case SSB_BUSTYPE_SSB:
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);
203 void ssb_iounmap(struct ssb_bus *bus)
205 switch (bus->bustype) {
206 case SSB_BUSTYPE_SSB:
207 case SSB_BUSTYPE_PCMCIA:
210 case SSB_BUSTYPE_PCI:
211 #ifdef CONFIG_SSB_PCIHOST
212 pci_iounmap(bus->host_pci, bus->mmio);
214 SSB_BUG_ON(1); /* Can't reach this code. */
217 case SSB_BUSTYPE_SDIO:
221 bus->mapped_device = NULL;
224 static void __iomem *ssb_ioremap(struct ssb_bus *bus,
225 unsigned long baseaddr)
227 void __iomem *mmio = NULL;
229 switch (bus->bustype) {
230 case SSB_BUSTYPE_SSB:
231 /* Only map the first core for now. */
233 case SSB_BUSTYPE_PCMCIA:
234 mmio = ioremap(baseaddr, SSB_CORE_SIZE);
236 case SSB_BUSTYPE_PCI:
237 #ifdef CONFIG_SSB_PCIHOST
238 mmio = pci_iomap(bus->host_pci, 0, ~0UL);
240 SSB_BUG_ON(1); /* Can't reach this code. */
243 case SSB_BUSTYPE_SDIO:
244 /* Nothing to ioremap in the SDIO case, just fake it */
245 mmio = (void __iomem *)baseaddr;
252 static int we_support_multiple_80211_cores(struct ssb_bus *bus)
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.
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)
265 #endif /* CONFIG_SSB_PCIHOST */
269 int ssb_bus_scan(struct ssb_bus *bus,
270 unsigned long baseaddr)
274 u32 idhi, cc, rev, tmp;
276 struct ssb_device *dev;
277 int nr_80211_cores = 0;
279 mmio = ssb_ioremap(bus, baseaddr);
284 err = scan_switchcore(bus, 0); /* Switch to first core */
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;
294 if (cc == SSB_DEV_CHIPCOMMON) {
295 tmp = scan_read32(bus, 0, SSB_CHIPCO_CHIPID);
297 bus->chip_id = (tmp & SSB_CHIPCO_IDMASK);
298 bus->chip_rev = (tmp & SSB_CHIPCO_REVMASK) >>
300 bus->chip_package = (tmp & SSB_CHIPCO_PACKMASK) >>
301 SSB_CHIPCO_PACKSHIFT;
303 bus->nr_devices = (tmp & SSB_CHIPCO_NRCORESMASK) >>
304 SSB_CHIPCO_NRCORESSHIFT;
306 tmp = scan_read32(bus, 0, SSB_CHIPCO_CAP);
307 bus->chipco.capabilities = tmp;
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,
313 bus->chip_package = 0;
315 bus->chip_id = 0x4710;
317 bus->chip_package = 0;
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);
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.
334 mmio = ioremap(baseaddr, SSB_CORE_SIZE * bus->nr_devices);
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);
345 dev = &(bus->devices[dev_i]);
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;
356 printk(KERN_DEBUG PFX
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);
362 switch (dev->id.coreid) {
365 if (nr_80211_cores > 1) {
366 if (!we_support_multiple_80211_cores(bus)) {
367 ssb_dprintk(KERN_INFO PFX "Ignoring additional "
374 #ifdef CONFIG_SSB_DRIVER_EXTIF
375 if (bus->extif.dev) {
376 ssb_printk(KERN_WARNING PFX
377 "WARNING: Multiple EXTIFs found\n");
380 bus->extif.dev = dev;
381 #endif /* CONFIG_SSB_DRIVER_EXTIF */
383 case SSB_DEV_CHIPCOMMON:
384 if (bus->chipco.dev) {
385 ssb_printk(KERN_WARNING PFX
386 "WARNING: Multiple ChipCommon found\n");
389 bus->chipco.dev = dev;
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");
399 bus->mipscore.dev = dev;
400 #endif /* CONFIG_SSB_DRIVER_MIPS */
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)
412 if (!bus->host_pci->is_pcie)
416 if (bus->pcicore.dev) {
417 ssb_printk(KERN_WARNING PFX
418 "WARNING: Multiple PCI(E) cores found\n");
421 bus->pcicore.dev = dev;
422 #endif /* CONFIG_SSB_DRIVER_PCICORE */
430 bus->nr_devices = dev_i;