upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / ssb / scan.c
1 /*
2  * Sonics Silicon Backplane
3  * Bus scanning
4  *
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.
11  *
12  * Licensed under the GNU/GPL. See COPYING for details.
13  */
14
15 #include <linux/ssb/ssb.h>
16 #include <linux/ssb/ssb_regs.h>
17 #include <linux/pci.h>
18 #include <linux/io.h>
19
20 #include <pcmcia/cs.h>
21 #include <pcmcia/cistpl.h>
22 #include <pcmcia/ds.h>
23
24 #include "ssb_private.h"
25
26
27 const char *ssb_core_name(u16 coreid)
28 {
29         switch (coreid) {
30         case SSB_DEV_CHIPCOMMON:
31                 return "ChipCommon";
32         case SSB_DEV_ILINE20:
33                 return "ILine 20";
34         case SSB_DEV_SDRAM:
35                 return "SDRAM";
36         case SSB_DEV_PCI:
37                 return "PCI";
38         case SSB_DEV_MIPS:
39                 return "MIPS";
40         case SSB_DEV_ETHERNET:
41                 return "Fast Ethernet";
42         case SSB_DEV_V90:
43                 return "V90";
44         case SSB_DEV_USB11_HOSTDEV:
45                 return "USB 1.1 Hostdev";
46         case SSB_DEV_ADSL:
47                 return "ADSL";
48         case SSB_DEV_ILINE100:
49                 return "ILine 100";
50         case SSB_DEV_IPSEC:
51                 return "IPSEC";
52         case SSB_DEV_PCMCIA:
53                 return "PCMCIA";
54         case SSB_DEV_INTERNAL_MEM:
55                 return "Internal Memory";
56         case SSB_DEV_MEMC_SDRAM:
57                 return "MEMC SDRAM";
58         case SSB_DEV_EXTIF:
59                 return "EXTIF";
60         case SSB_DEV_80211:
61                 return "IEEE 802.11";
62         case SSB_DEV_MIPS_3302:
63                 return "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:
73                 return "SDIO Host";
74         case SSB_DEV_ROBOSWITCH:
75                 return "Roboswitch";
76         case SSB_DEV_PARA_ATA:
77                 return "PATA";
78         case SSB_DEV_SATA_XORDMA:
79                 return "SATA XOR-DMA";
80         case SSB_DEV_ETHERNET_GBIT:
81                 return "GBit Ethernet";
82         case SSB_DEV_PCIE:
83                 return "PCI-E";
84         case SSB_DEV_MIMO_PHY:
85                 return "MIMO PHY";
86         case SSB_DEV_SRAM_CTRLR:
87                 return "SRAM Controller";
88         case SSB_DEV_MINI_MACPHY:
89                 return "Mini MACPHY";
90         case SSB_DEV_ARM_1176:
91                 return "ARM 1176";
92         case SSB_DEV_ARM_7TDMI:
93                 return "ARM 7TDMI";
94         }
95         return "UNKNOWN";
96 }
97
98 static u16 pcidev_to_chipid(struct pci_dev *pci_dev)
99 {
100         u16 chipid_fallback = 0;
101
102         switch (pci_dev->device) {
103         case 0x4301:
104                 chipid_fallback = 0x4301;
105                 break;
106         case 0x4305 ... 0x4307:
107                 chipid_fallback = 0x4307;
108                 break;
109         case 0x4403:
110                 chipid_fallback = 0x4402;
111                 break;
112         case 0x4610 ... 0x4615:
113                 chipid_fallback = 0x4610;
114                 break;
115         case 0x4710 ... 0x4715:
116                 chipid_fallback = 0x4710;
117                 break;
118         case 0x4320 ... 0x4325:
119                 chipid_fallback = 0x4309;
120                 break;
121         case PCI_DEVICE_ID_BCM4401:
122         case PCI_DEVICE_ID_BCM4401B0:
123         case PCI_DEVICE_ID_BCM4401B1:
124                 chipid_fallback = 0x4401;
125                 break;
126         default:
127                 ssb_printk(KERN_ERR PFX
128                            "PCI-ID not in fallback list\n");
129         }
130
131         return chipid_fallback;
132 }
133
134 static u8 chipid_to_nrcores(u16 chipid)
135 {
136         switch (chipid) {
137         case 0x5365:
138                 return 7;
139         case 0x4306:
140                 return 6;
141         case 0x4310:
142                 return 8;
143         case 0x4307:
144         case 0x4301:
145                 return 5;
146         case 0x4401:
147         case 0x4402:
148                 return 3;
149         case 0x4710:
150         case 0x4610:
151         case 0x4704:
152                 return 9;
153         default:
154                 ssb_printk(KERN_ERR PFX
155                            "CHIPID not in nrcores fallback list\n");
156         }
157
158         return 1;
159 }
160
161 static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
162                        u16 offset)
163 {
164         u32 lo, hi;
165
166         switch (bus->bustype) {
167         case SSB_BUSTYPE_SSB:
168                 offset += current_coreidx * SSB_CORE_SIZE;
169                 break;
170         case SSB_BUSTYPE_PCI:
171                 break;
172         case SSB_BUSTYPE_PCMCIA:
173                 if (offset >= 0x800) {
174                         ssb_pcmcia_switch_segment(bus, 1);
175                         offset -= 0x800;
176                 } else
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);
184         }
185         return readl(bus->mmio + offset);
186 }
187
188 static int scan_switchcore(struct ssb_bus *bus, u8 coreidx)
189 {
190         switch (bus->bustype) {
191         case SSB_BUSTYPE_SSB:
192                 break;
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);
199         }
200         return 0;
201 }
202
203 void ssb_iounmap(struct ssb_bus *bus)
204 {
205         switch (bus->bustype) {
206         case SSB_BUSTYPE_SSB:
207         case SSB_BUSTYPE_PCMCIA:
208                 iounmap(bus->mmio);
209                 break;
210         case SSB_BUSTYPE_PCI:
211 #ifdef CONFIG_SSB_PCIHOST
212                 pci_iounmap(bus->host_pci, bus->mmio);
213 #else
214                 SSB_BUG_ON(1); /* Can't reach this code. */
215 #endif
216                 break;
217         case SSB_BUSTYPE_SDIO:
218                 break;
219         }
220         bus->mmio = NULL;
221         bus->mapped_device = NULL;
222 }
223
224 static void __iomem *ssb_ioremap(struct ssb_bus *bus,
225                                  unsigned long baseaddr)
226 {
227         void __iomem *mmio = NULL;
228
229         switch (bus->bustype) {
230         case SSB_BUSTYPE_SSB:
231                 /* Only map the first core for now. */
232                 /* fallthrough... */
233         case SSB_BUSTYPE_PCMCIA:
234                 mmio = ioremap(baseaddr, SSB_CORE_SIZE);
235                 break;
236         case SSB_BUSTYPE_PCI:
237 #ifdef CONFIG_SSB_PCIHOST
238                 mmio = pci_iomap(bus->host_pci, 0, ~0UL);
239 #else
240                 SSB_BUG_ON(1); /* Can't reach this code. */
241 #endif
242                 break;
243         case SSB_BUSTYPE_SDIO:
244                 /* Nothing to ioremap in the SDIO case, just fake it */
245                 mmio = (void __iomem *)baseaddr;
246                 break;
247         }
248
249         return mmio;
250 }
251
252 static int we_support_multiple_80211_cores(struct ssb_bus *bus)
253 {
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.
257          */
258
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)
263                         return 1;
264         }
265 #endif /* CONFIG_SSB_PCIHOST */
266         return 0;
267 }
268
269 int ssb_bus_scan(struct ssb_bus *bus,
270                  unsigned long baseaddr)
271 {
272         int err = -ENOMEM;
273         void __iomem *mmio;
274         u32 idhi, cc, rev, tmp;
275         int dev_i, i;
276         struct ssb_device *dev;
277         int nr_80211_cores = 0;
278
279         mmio = ssb_ioremap(bus, baseaddr);
280         if (!mmio)
281                 goto out;
282         bus->mmio = mmio;
283
284         err = scan_switchcore(bus, 0); /* Switch to first core */
285         if (err)
286                 goto err_unmap;
287
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;
292
293         bus->nr_devices = 0;
294         if (cc == SSB_DEV_CHIPCOMMON) {
295                 tmp = scan_read32(bus, 0, SSB_CHIPCO_CHIPID);
296
297                 bus->chip_id = (tmp & SSB_CHIPCO_IDMASK);
298                 bus->chip_rev = (tmp & SSB_CHIPCO_REVMASK) >>
299                                 SSB_CHIPCO_REVSHIFT;
300                 bus->chip_package = (tmp & SSB_CHIPCO_PACKMASK) >>
301                                     SSB_CHIPCO_PACKSHIFT;
302                 if (rev >= 4) {
303                         bus->nr_devices = (tmp & SSB_CHIPCO_NRCORESMASK) >>
304                                           SSB_CHIPCO_NRCORESSHIFT;
305                 }
306                 tmp = scan_read32(bus, 0, SSB_CHIPCO_CAP);
307                 bus->chipco.capabilities = tmp;
308         } else {
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,
312                                              &bus->chip_rev);
313                         bus->chip_package = 0;
314                 } else {
315                         bus->chip_id = 0x4710;
316                         bus->chip_rev = 0;
317                         bus->chip_package = 0;
318                 }
319         }
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);
326                 goto err_unmap;
327         }
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.
331                  */
332                 err = -ENOMEM;
333                 iounmap(mmio);
334                 mmio = ioremap(baseaddr, SSB_CORE_SIZE * bus->nr_devices);
335                 if (!mmio)
336                         goto out;
337                 bus->mmio = mmio;
338         }
339
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);
343                 if (err)
344                         goto err_unmap;
345                 dev = &(bus->devices[dev_i]);
346
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;
352                 dev->core_index = i;
353                 dev->bus = bus;
354                 dev->ops = bus->ops;
355
356                 printk(KERN_DEBUG PFX
357                             "Core %d found: %s "
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);
361
362                 switch (dev->id.coreid) {
363                 case SSB_DEV_80211:
364                         nr_80211_cores++;
365                         if (nr_80211_cores > 1) {
366                                 if (!we_support_multiple_80211_cores(bus)) {
367                                         ssb_dprintk(KERN_INFO PFX "Ignoring additional "
368                                                     "802.11 core\n");
369                                         continue;
370                                 }
371                         }
372                         break;
373                 case SSB_DEV_EXTIF:
374 #ifdef CONFIG_SSB_DRIVER_EXTIF
375                         if (bus->extif.dev) {
376                                 ssb_printk(KERN_WARNING PFX
377                                            "WARNING: Multiple EXTIFs found\n");
378                                 break;
379                         }
380                         bus->extif.dev = dev;
381 #endif /* CONFIG_SSB_DRIVER_EXTIF */
382                         break;
383                 case SSB_DEV_CHIPCOMMON:
384                         if (bus->chipco.dev) {
385                                 ssb_printk(KERN_WARNING PFX
386                                            "WARNING: Multiple ChipCommon found\n");
387                                 break;
388                         }
389                         bus->chipco.dev = dev;
390                         break;
391                 case SSB_DEV_MIPS:
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");
397                                 break;
398                         }
399                         bus->mipscore.dev = dev;
400 #endif /* CONFIG_SSB_DRIVER_MIPS */
401                         break;
402                 case SSB_DEV_PCI:
403                 case SSB_DEV_PCIE:
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)
410                                                 continue;
411                                 } else {
412                                         if (!bus->host_pci->is_pcie)
413                                                 continue;
414                                 }
415                         }
416                         if (bus->pcicore.dev) {
417                                 ssb_printk(KERN_WARNING PFX
418                                            "WARNING: Multiple PCI(E) cores found\n");
419                                 break;
420                         }
421                         bus->pcicore.dev = dev;
422 #endif /* CONFIG_SSB_DRIVER_PCICORE */
423                         break;
424                 default:
425                         break;
426                 }
427
428                 dev_i++;
429         }
430         bus->nr_devices = dev_i;
431
432         err = 0;
433 out:
434         return err;
435 err_unmap:
436         ssb_iounmap(bus);
437         goto out;
438 }