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 */
This page took 0.072418 seconds and 5 git commands to generate.