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 "ssb_private.h"
23 const char * ssb_core_name(u16 coreid)
26 case SSB_DEV_CHIPCOMMON:
36 case SSB_DEV_ETHERNET:
37 return "Fast Ethernet";
40 case SSB_DEV_USB11_HOSTDEV:
41 return "USB 1.1 Hostdev";
44 case SSB_DEV_ILINE100:
50 case SSB_DEV_INTERNAL_MEM:
51 return "Internal Memory";
52 case SSB_DEV_MEMC_SDRAM:
58 case SSB_DEV_MIPS_3302:
60 case SSB_DEV_USB11_HOST:
61 return "USB 1.1 Host";
62 case SSB_DEV_USB11_DEV:
63 return "USB 1.1 Device";
64 case SSB_DEV_USB20_HOST:
65 return "USB 2.0 Host";
66 case SSB_DEV_USB20_DEV:
67 return "USB 2.0 Device";
68 case SSB_DEV_SDIO_HOST:
70 case SSB_DEV_ROBOSWITCH:
72 case SSB_DEV_PARA_ATA:
74 case SSB_DEV_SATA_XORDMA:
75 return "SATA XOR-DMA";
76 case SSB_DEV_ETHERNET_GBIT:
77 return "GBit Ethernet";
80 case SSB_DEV_MIMO_PHY:
82 case SSB_DEV_SRAM_CTRLR:
83 return "SRAM Controller";
84 case SSB_DEV_MINI_MACPHY:
86 case SSB_DEV_ARM_1176:
88 case SSB_DEV_ARM_7TDMI:
94 static u16 pcidev_to_chipid(struct pci_dev *pci_dev)
96 u16 chipid_fallback = 0;
98 switch (pci_dev->device) {
100 chipid_fallback = 0x4301;
102 case 0x4305 ... 0x4307:
103 chipid_fallback = 0x4307;
106 chipid_fallback = 0x4402;
108 case 0x4610 ... 0x4615:
109 chipid_fallback = 0x4610;
111 case 0x4710 ... 0x4715:
112 chipid_fallback = 0x4710;
114 case 0x4320 ... 0x4325:
115 chipid_fallback = 0x4309;
117 case PCI_DEVICE_ID_BCM4401:
118 case PCI_DEVICE_ID_BCM4401B0:
119 case PCI_DEVICE_ID_BCM4401B1:
120 chipid_fallback = 0x4401;
123 ssb_printk(KERN_ERR PFX
124 "PCI-ID not in fallback list\n");
127 return chipid_fallback;
130 static u8 chipid_to_nrcores(u16 chipid)
150 ssb_printk(KERN_ERR PFX
151 "CHIPID not in nrcores fallback list\n");
157 static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
160 switch (bus->bustype) {
161 case SSB_BUSTYPE_SSB:
162 offset += current_coreidx * SSB_CORE_SIZE;
164 case SSB_BUSTYPE_PCI:
166 case SSB_BUSTYPE_PCMCIA:
167 if (offset >= 0x800) {
168 ssb_pcmcia_switch_segment(bus, 1);
171 ssb_pcmcia_switch_segment(bus, 0);
174 return readl(bus->mmio + offset);
177 static int scan_switchcore(struct ssb_bus *bus, u8 coreidx)
179 switch (bus->bustype) {
180 case SSB_BUSTYPE_SSB:
182 case SSB_BUSTYPE_PCI:
183 return ssb_pci_switch_coreidx(bus, coreidx);
184 case SSB_BUSTYPE_PCMCIA:
185 return ssb_pcmcia_switch_coreidx(bus, coreidx);
190 void ssb_iounmap(struct ssb_bus *bus)
192 switch (bus->bustype) {
193 case SSB_BUSTYPE_SSB:
194 case SSB_BUSTYPE_PCMCIA:
197 case SSB_BUSTYPE_PCI:
198 pci_iounmap(bus->host_pci, bus->mmio);
202 bus->mapped_device = NULL;
205 static void __iomem * ssb_ioremap(struct ssb_bus *bus,
206 unsigned long baseaddr)
208 void __iomem *mmio = NULL;
210 switch (bus->bustype) {
211 case SSB_BUSTYPE_SSB:
212 /* Only map the first core for now. */
214 case SSB_BUSTYPE_PCMCIA:
215 mmio = ioremap(baseaddr, SSB_CORE_SIZE);
217 case SSB_BUSTYPE_PCI:
218 mmio = pci_iomap(bus->host_pci, 0, ~0UL);
225 int ssb_bus_scan(struct ssb_bus *bus,
226 unsigned long baseaddr)
230 u32 idhi, cc, rev, tmp;
232 struct ssb_device *dev;
234 mmio = ssb_ioremap(bus, baseaddr);
239 err = scan_switchcore(bus, 0); /* Switch to first core */
243 idhi = scan_read32(bus, 0, SSB_IDHIGH);
244 cc = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
245 rev = (idhi & SSB_IDHIGH_RCLO);
246 rev |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT;
249 if (cc == SSB_DEV_CHIPCOMMON) {
250 tmp = scan_read32(bus, 0, SSB_CHIPCO_CHIPID);
252 bus->chip_id = (tmp & SSB_CHIPCO_IDMASK);
253 bus->chip_rev = (tmp & SSB_CHIPCO_REVMASK) >>
255 bus->chip_package = (tmp & SSB_CHIPCO_PACKMASK) >>
256 SSB_CHIPCO_PACKSHIFT;
258 bus->nr_devices = (tmp & SSB_CHIPCO_NRCORESMASK) >>
259 SSB_CHIPCO_NRCORESSHIFT;
261 tmp = scan_read32(bus, 0, SSB_CHIPCO_CAP);
262 bus->chipco.capabilities = tmp;
264 if (bus->bustype == SSB_BUSTYPE_PCI) {
265 bus->chip_id = pcidev_to_chipid(bus->host_pci);
266 pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
268 bus->chip_package = 0;
270 bus->chip_id = 0x4710;
272 bus->chip_package = 0;
275 if (!bus->nr_devices)
276 bus->nr_devices = chipid_to_nrcores(bus->chip_id);
277 if (bus->nr_devices > ARRAY_SIZE(bus->devices)) {
278 ssb_printk(KERN_ERR PFX
279 "More than %d ssb cores found (%d)\n",
280 SSB_MAX_NR_CORES, bus->nr_devices);
283 if (bus->bustype == SSB_BUSTYPE_SSB) {
284 /* Now that we know the number of cores,
285 * remap the whole IO space for all cores.
289 mmio = ioremap(baseaddr, SSB_CORE_SIZE * bus->nr_devices);
295 /* Fetch basic information about each core/device */
296 for (i = 0; i < bus->nr_devices; i++) {
297 err = scan_switchcore(bus, i);
300 dev = &(bus->devices[i]);
302 idhi = scan_read32(bus, i, SSB_IDHIGH);
303 dev->id.coreid = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
304 dev->id.revision = (idhi & SSB_IDHIGH_RCLO);
305 dev->id.revision |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT;
306 dev->id.vendor = (idhi & SSB_IDHIGH_VC) >> SSB_IDHIGH_VC_SHIFT;
309 if ((dev->bus->bustype == SSB_BUSTYPE_PCI) && (bus->host_pci))
310 dev->irq = bus->host_pci->irq;
312 ssb_dprintk(KERN_INFO PFX
314 "(cc 0x%03X, rev 0x%02X, vendor 0x%04X)\n",
315 i, ssb_core_name(dev->id.coreid),
316 dev->id.coreid, dev->id.revision, dev->id.vendor);
318 dev->dev.bus = &ssb_bustype;
319 snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id),
320 "ssb%02x:%02x", bus->busnumber, i);
322 switch (dev->id.coreid) {
324 #ifdef CONFIG_BCM947XX
325 if (bus->extif.dev) {
326 ssb_printk(KERN_WARNING PFX
327 "WARNING: Multiple EXTIFs found\n");
330 bus->extif.dev = dev;
331 #endif /* CONFIG_SSB_DRIVER_EXTIF */
333 case SSB_DEV_CHIPCOMMON:
334 if (bus->chipco.dev) {
335 ssb_printk(KERN_WARNING PFX
336 "WARNING: Multiple ChipCommon found\n");
339 bus->chipco.dev = dev;
342 case SSB_DEV_MIPS_3302:
343 #ifdef CONFIG_BCM947XX
344 if (bus->mipscore.dev) {
345 ssb_printk(KERN_WARNING PFX
346 "WARNING: Multiple MIPS cores found\n");
349 bus->mipscore.dev = dev;
350 #endif /* CONFIG_BCM947XX */
354 #ifdef CONFIG_SSB_DRIVER_PCICORE
355 if (bus->pcicore.dev) {
356 ssb_printk(KERN_WARNING PFX
357 "WARNING: Multiple PCI(E) cores found\n");
360 bus->pcicore.dev = dev;
361 #endif /* CONFIG_SSB_DRIVER_PCICORE */