aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/ssb/Kconfig117
-rw-r--r--drivers/ssb/Makefile18
-rw-r--r--drivers/ssb/b43_pci_bridge.c46
-rw-r--r--drivers/ssb/driver_chipcommon.c446
-rw-r--r--drivers/ssb/driver_extif.c129
-rw-r--r--drivers/ssb/driver_mipscore.c223
-rw-r--r--drivers/ssb/driver_pcicore.c576
-rw-r--r--drivers/ssb/main.c1162
-rw-r--r--drivers/ssb/pci.c740
-rw-r--r--drivers/ssb/pcihost_wrapper.c104
-rw-r--r--drivers/ssb/pcmcia.c271
-rw-r--r--drivers/ssb/scan.c413
-rw-r--r--drivers/ssb/ssb_private.h136
15 files changed, 4384 insertions, 0 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 3e1c442deff..7bdae47d6b9 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -58,6 +58,8 @@ source "drivers/power/Kconfig"
58 58
59source "drivers/hwmon/Kconfig" 59source "drivers/hwmon/Kconfig"
60 60
61source "drivers/ssb/Kconfig"
62
61source "drivers/mfd/Kconfig" 63source "drivers/mfd/Kconfig"
62 64
63source "drivers/media/Kconfig" 65source "drivers/media/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index f0878b2ec55..a168eacdcd9 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -88,3 +88,4 @@ obj-$(CONFIG_DMA_ENGINE) += dma/
88obj-$(CONFIG_HID) += hid/ 88obj-$(CONFIG_HID) += hid/
89obj-$(CONFIG_PPC_PS3) += ps3/ 89obj-$(CONFIG_PPC_PS3) += ps3/
90obj-$(CONFIG_OF) += of/ 90obj-$(CONFIG_OF) += of/
91obj-$(CONFIG_SSB) += ssb/
diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig
new file mode 100644
index 00000000000..b4a5e5e9d9f
--- /dev/null
+++ b/drivers/ssb/Kconfig
@@ -0,0 +1,117 @@
1menu "Sonics Silicon Backplane"
2
3config SSB_POSSIBLE
4 bool
5 depends on HAS_IOMEM
6 default y
7
8config SSB
9 tristate "Sonics Silicon Backplane support"
10 depends on SSB_POSSIBLE
11 help
12 Support for the Sonics Silicon Backplane bus.
13 You only need to enable this option, if you are
14 configuring a kernel for an embedded system with
15 this bus.
16 It will be auto-selected if needed in other
17 environments.
18
19 The module will be called ssb.
20
21 If unsure, say N.
22
23config SSB_PCIHOST_POSSIBLE
24 bool
25 depends on SSB && PCI
26 default y
27
28config SSB_PCIHOST
29 bool "Support for SSB on PCI-bus host"
30 depends on SSB_PCIHOST_POSSIBLE
31 default y
32 help
33 Support for a Sonics Silicon Backplane on top
34 of a PCI device.
35
36 If unsure, say Y
37
38config SSB_PCMCIAHOST_POSSIBLE
39 bool
40 depends on SSB && PCMCIA && EXPERIMENTAL
41 default y
42
43config SSB_PCMCIAHOST
44 bool "Support for SSB on PCMCIA-bus host (EXPERIMENTAL)"
45 depends on SSB_PCMCIAHOST_POSSIBLE
46 help
47 Support for a Sonics Silicon Backplane on top
48 of a PCMCIA device.
49
50 If unsure, say N
51
52config SSB_SILENT
53 bool "No SSB kernel messages"
54 depends on SSB && EMBEDDED
55 help
56 This option turns off all Sonics Silicon Backplane printks.
57 Note that you won't be able to identify problems, once
58 messages are turned off.
59 This might only be desired for production kernels on
60 embedded devices to reduce the kernel size.
61
62 Say N
63
64config SSB_DEBUG
65 bool "SSB debugging"
66 depends on SSB && !SSB_SILENT
67 help
68 This turns on additional runtime checks and debugging
69 messages. Turn this on for SSB troubleshooting.
70
71 If unsure, say N
72
73config SSB_SERIAL
74 bool
75 depends on SSB
76 # ChipCommon and ExtIf serial support routines.
77
78config SSB_DRIVER_PCICORE_POSSIBLE
79 bool
80 depends on SSB_PCIHOST
81 default y
82
83config SSB_DRIVER_PCICORE
84 bool "SSB PCI core driver"
85 depends on SSB_DRIVER_PCICORE_POSSIBLE
86 help
87 Driver for the Sonics Silicon Backplane attached
88 Broadcom PCI core.
89
90 If unsure, say Y
91
92config SSB_PCICORE_HOSTMODE
93 bool "Hostmode support for SSB PCI core (EXPERIMENTAL)"
94 depends on SSB_DRIVER_PCICORE && SSB_DRIVER_MIPS && EXPERIMENTAL
95 help
96 PCIcore hostmode operation (external PCI bus).
97
98config SSB_DRIVER_MIPS
99 bool "SSB Broadcom MIPS core driver (EXPERIMENTAL)"
100 depends on SSB && MIPS && EXPERIMENTAL
101 select SSB_SERIAL
102 help
103 Driver for the Sonics Silicon Backplane attached
104 Broadcom MIPS core.
105
106 If unsure, say N
107
108config SSB_DRIVER_EXTIF
109 bool "SSB Broadcom EXTIF core driver (EXPERIMENTAL)"
110 depends on SSB_DRIVER_MIPS && EXPERIMENTAL
111 help
112 Driver for the Sonics Silicon Backplane attached
113 Broadcom EXTIF core.
114
115 If unsure, say N
116
117endmenu
diff --git a/drivers/ssb/Makefile b/drivers/ssb/Makefile
new file mode 100644
index 00000000000..7be39759580
--- /dev/null
+++ b/drivers/ssb/Makefile
@@ -0,0 +1,18 @@
1# core
2ssb-y += main.o scan.o
3
4# host support
5ssb-$(CONFIG_SSB_PCIHOST) += pci.o pcihost_wrapper.o
6ssb-$(CONFIG_SSB_PCMCIAHOST) += pcmcia.o
7
8# built-in drivers
9ssb-y += driver_chipcommon.o
10ssb-$(CONFIG_SSB_DRIVER_MIPS) += driver_mipscore.o
11ssb-$(CONFIG_SSB_DRIVER_EXTIF) += driver_extif.o
12ssb-$(CONFIG_SSB_DRIVER_PCICORE) += driver_pcicore.o
13
14# b43 pci-ssb-bridge driver
15# Not strictly a part of SSB, but kept here for convenience
16ssb-$(CONFIG_SSB_PCIHOST) += b43_pci_bridge.o
17
18obj-$(CONFIG_SSB) += ssb.o
diff --git a/drivers/ssb/b43_pci_bridge.c b/drivers/ssb/b43_pci_bridge.c
new file mode 100644
index 00000000000..fa3bd292f5f
--- /dev/null
+++ b/drivers/ssb/b43_pci_bridge.c
@@ -0,0 +1,46 @@
1/*
2 * Broadcom 43xx PCI-SSB bridge module
3 *
4 * This technically is a seperate PCI driver module, but
5 * because of its small size we include it in the SSB core
6 * instead of creating a standalone module.
7 *
8 * Copyright 2007 Michael Buesch <mb@bu3sch.de>
9 *
10 * Licensed under the GNU/GPL. See COPYING for details.
11 */
12
13#include <linux/pci.h>
14#include <linux/ssb/ssb.h>
15
16
17static const struct pci_device_id b43_pci_bridge_tbl[] = {
18 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4301) },
19 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4307) },
20 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4311) },
21 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) },
22 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4318) },
23 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) },
24 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) },
25 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) },
26 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4324) },
27 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4325) },
28 { 0, },
29};
30MODULE_DEVICE_TABLE(pci, b43_pci_bridge_tbl);
31
32static struct pci_driver b43_pci_bridge_driver = {
33 .name = "b43-pci-bridge",
34 .id_table = b43_pci_bridge_tbl,
35};
36
37
38int __init b43_pci_ssb_bridge_init(void)
39{
40 return ssb_pcihost_register(&b43_pci_bridge_driver);
41}
42
43void __exit b43_pci_ssb_bridge_exit(void)
44{
45 ssb_pcihost_unregister(&b43_pci_bridge_driver);
46}
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
new file mode 100644
index 00000000000..a890544e8fb
--- /dev/null
+++ b/drivers/ssb/driver_chipcommon.c
@@ -0,0 +1,446 @@
1/*
2 * Sonics Silicon Backplane
3 * Broadcom ChipCommon core driver
4 *
5 * Copyright 2005, Broadcom Corporation
6 * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
7 *
8 * Licensed under the GNU/GPL. See COPYING for details.
9 */
10
11#include <linux/ssb/ssb.h>
12#include <linux/ssb/ssb_regs.h>
13#include <linux/pci.h>
14
15#include "ssb_private.h"
16
17
18/* Clock sources */
19enum ssb_clksrc {
20 /* PCI clock */
21 SSB_CHIPCO_CLKSRC_PCI,
22 /* Crystal slow clock oscillator */
23 SSB_CHIPCO_CLKSRC_XTALOS,
24 /* Low power oscillator */
25 SSB_CHIPCO_CLKSRC_LOPWROS,
26};
27
28
29static inline u32 chipco_read32(struct ssb_chipcommon *cc,
30 u16 offset)
31{
32 return ssb_read32(cc->dev, offset);
33}
34
35static inline void chipco_write32(struct ssb_chipcommon *cc,
36 u16 offset,
37 u32 value)
38{
39 ssb_write32(cc->dev, offset, value);
40}
41
42static inline void chipco_write32_masked(struct ssb_chipcommon *cc, u16 offset,
43 u32 mask, u32 value)
44{
45 value &= mask;
46 value |= chipco_read32(cc, offset) & ~mask;
47 chipco_write32(cc, offset, value);
48}
49
50void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc,
51 enum ssb_clkmode mode)
52{
53 struct ssb_device *ccdev = cc->dev;
54 struct ssb_bus *bus;
55 u32 tmp;
56
57 if (!ccdev)
58 return;
59 bus = ccdev->bus;
60 /* chipcommon cores prior to rev6 don't support dynamic clock control */
61 if (ccdev->id.revision < 6)
62 return;
63 /* chipcommon cores rev10 are a whole new ball game */
64 if (ccdev->id.revision >= 10)
65 return;
66 if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
67 return;
68
69 switch (mode) {
70 case SSB_CLKMODE_SLOW:
71 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
72 tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW;
73 chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
74 break;
75 case SSB_CLKMODE_FAST:
76 ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
77 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
78 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
79 tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
80 chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
81 break;
82 case SSB_CLKMODE_DYNAMIC:
83 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
84 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
85 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
86 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
87 if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
88 tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
89 chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
90
91 /* for dynamic control, we have to release our xtal_pu "force on" */
92 if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
93 ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
94 break;
95 default:
96 SSB_WARN_ON(1);
97 }
98}
99
100/* Get the Slow Clock Source */
101static enum ssb_clksrc chipco_pctl_get_slowclksrc(struct ssb_chipcommon *cc)
102{
103 struct ssb_bus *bus = cc->dev->bus;
104 u32 uninitialized_var(tmp);
105
106 if (cc->dev->id.revision < 6) {
107 if (bus->bustype == SSB_BUSTYPE_SSB ||
108 bus->bustype == SSB_BUSTYPE_PCMCIA)
109 return SSB_CHIPCO_CLKSRC_XTALOS;
110 if (bus->bustype == SSB_BUSTYPE_PCI) {
111 pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT, &tmp);
112 if (tmp & 0x10)
113 return SSB_CHIPCO_CLKSRC_PCI;
114 return SSB_CHIPCO_CLKSRC_XTALOS;
115 }
116 }
117 if (cc->dev->id.revision < 10) {
118 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
119 tmp &= 0x7;
120 if (tmp == 0)
121 return SSB_CHIPCO_CLKSRC_LOPWROS;
122 if (tmp == 1)
123 return SSB_CHIPCO_CLKSRC_XTALOS;
124 if (tmp == 2)
125 return SSB_CHIPCO_CLKSRC_PCI;
126 }
127
128 return SSB_CHIPCO_CLKSRC_XTALOS;
129}
130
131/* Get maximum or minimum (depending on get_max flag) slowclock frequency. */
132static int chipco_pctl_clockfreqlimit(struct ssb_chipcommon *cc, int get_max)
133{
134 int uninitialized_var(limit);
135 enum ssb_clksrc clocksrc;
136 int divisor = 1;
137 u32 tmp;
138
139 clocksrc = chipco_pctl_get_slowclksrc(cc);
140 if (cc->dev->id.revision < 6) {
141 switch (clocksrc) {
142 case SSB_CHIPCO_CLKSRC_PCI:
143 divisor = 64;
144 break;
145 case SSB_CHIPCO_CLKSRC_XTALOS:
146 divisor = 32;
147 break;
148 default:
149 SSB_WARN_ON(1);
150 }
151 } else if (cc->dev->id.revision < 10) {
152 switch (clocksrc) {
153 case SSB_CHIPCO_CLKSRC_LOPWROS:
154 break;
155 case SSB_CHIPCO_CLKSRC_XTALOS:
156 case SSB_CHIPCO_CLKSRC_PCI:
157 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
158 divisor = (tmp >> 16) + 1;
159 divisor *= 4;
160 break;
161 }
162 } else {
163 tmp = chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL);
164 divisor = (tmp >> 16) + 1;
165 divisor *= 4;
166 }
167
168 switch (clocksrc) {
169 case SSB_CHIPCO_CLKSRC_LOPWROS:
170 if (get_max)
171 limit = 43000;
172 else
173 limit = 25000;
174 break;
175 case SSB_CHIPCO_CLKSRC_XTALOS:
176 if (get_max)
177 limit = 20200000;
178 else
179 limit = 19800000;
180 break;
181 case SSB_CHIPCO_CLKSRC_PCI:
182 if (get_max)
183 limit = 34000000;
184 else
185 limit = 25000000;
186 break;
187 }
188 limit /= divisor;
189
190 return limit;
191}
192
193static void chipco_powercontrol_init(struct ssb_chipcommon *cc)
194{
195 struct ssb_bus *bus = cc->dev->bus;
196
197 if (bus->chip_id == 0x4321) {
198 if (bus->chip_rev == 0)
199 chipco_write32(cc, SSB_CHIPCO_CHIPCTL, 0x3A4);
200 else if (bus->chip_rev == 1)
201 chipco_write32(cc, SSB_CHIPCO_CHIPCTL, 0xA4);
202 }
203
204 if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
205 return;
206
207 if (cc->dev->id.revision >= 10) {
208 /* Set Idle Power clock rate to 1Mhz */
209 chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
210 (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) &
211 0x0000FFFF) | 0x00040000);
212 } else {
213 int maxfreq;
214
215 maxfreq = chipco_pctl_clockfreqlimit(cc, 1);
216 chipco_write32(cc, SSB_CHIPCO_PLLONDELAY,
217 (maxfreq * 150 + 999999) / 1000000);
218 chipco_write32(cc, SSB_CHIPCO_FREFSELDELAY,
219 (maxfreq * 15 + 999999) / 1000000);
220 }
221}
222
223static void calc_fast_powerup_delay(struct ssb_chipcommon *cc)
224{
225 struct ssb_bus *bus = cc->dev->bus;
226 int minfreq;
227 unsigned int tmp;
228 u32 pll_on_delay;
229
230 if (bus->bustype != SSB_BUSTYPE_PCI)
231 return;
232 if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
233 return;
234
235 minfreq = chipco_pctl_clockfreqlimit(cc, 0);
236 pll_on_delay = chipco_read32(cc, SSB_CHIPCO_PLLONDELAY);
237 tmp = (((pll_on_delay + 2) * 1000000) + (minfreq - 1)) / minfreq;
238 SSB_WARN_ON(tmp & ~0xFFFF);
239
240 cc->fast_pwrup_delay = tmp;
241}
242
243void ssb_chipcommon_init(struct ssb_chipcommon *cc)
244{
245 if (!cc->dev)
246 return; /* We don't have a ChipCommon */
247 chipco_powercontrol_init(cc);
248 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
249 calc_fast_powerup_delay(cc);
250}
251
252void ssb_chipco_suspend(struct ssb_chipcommon *cc, pm_message_t state)
253{
254 if (!cc->dev)
255 return;
256 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_SLOW);
257}
258
259void ssb_chipco_resume(struct ssb_chipcommon *cc)
260{
261 if (!cc->dev)
262 return;
263 chipco_powercontrol_init(cc);
264 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
265}
266
267/* Get the processor clock */
268void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc,
269 u32 *plltype, u32 *n, u32 *m)
270{
271 *n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N);
272 *plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);
273 switch (*plltype) {
274 case SSB_PLLTYPE_2:
275 case SSB_PLLTYPE_4:
276 case SSB_PLLTYPE_6:
277 case SSB_PLLTYPE_7:
278 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_MIPS);
279 break;
280 case SSB_PLLTYPE_3:
281 /* 5350 uses m2 to control mips */
282 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_M2);
283 break;
284 default:
285 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_SB);
286 break;
287 }
288}
289
290/* Get the bus clock */
291void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc,
292 u32 *plltype, u32 *n, u32 *m)
293{
294 *n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N);
295 *plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);
296 switch (*plltype) {
297 case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */
298 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_MIPS);
299 break;
300 case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
301 if (cc->dev->bus->chip_id != 0x5365) {
302 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_M2);
303 break;
304 }
305 /* Fallthough */
306 default:
307 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_SB);
308 }
309}
310
311void ssb_chipco_timing_init(struct ssb_chipcommon *cc,
312 unsigned long ns)
313{
314 struct ssb_device *dev = cc->dev;
315 struct ssb_bus *bus = dev->bus;
316 u32 tmp;
317
318 /* set register for external IO to control LED. */
319 chipco_write32(cc, SSB_CHIPCO_PROG_CFG, 0x11);
320 tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT; /* Waitcount-3 = 10ns */
321 tmp |= DIV_ROUND_UP(40, ns) << SSB_PROG_WCNT_1_SHIFT; /* Waitcount-1 = 40ns */
322 tmp |= DIV_ROUND_UP(240, ns); /* Waitcount-0 = 240ns */
323 chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp); /* 0x01020a0c for a 100Mhz clock */
324
325 /* Set timing for the flash */
326 tmp = DIV_ROUND_UP(10, ns) << SSB_FLASH_WCNT_3_SHIFT; /* Waitcount-3 = 10nS */
327 tmp |= DIV_ROUND_UP(10, ns) << SSB_FLASH_WCNT_1_SHIFT; /* Waitcount-1 = 10nS */
328 tmp |= DIV_ROUND_UP(120, ns); /* Waitcount-0 = 120nS */
329 if ((bus->chip_id == 0x5365) ||
330 (dev->id.revision < 9))
331 chipco_write32(cc, SSB_CHIPCO_FLASH_WAITCNT, tmp);
332 if ((bus->chip_id == 0x5365) ||
333 (dev->id.revision < 9) ||
334 ((bus->chip_id == 0x5350) && (bus->chip_rev == 0)))
335 chipco_write32(cc, SSB_CHIPCO_PCMCIA_MEMWAIT, tmp);
336
337 if (bus->chip_id == 0x5350) {
338 /* Enable EXTIF */
339 tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT; /* Waitcount-3 = 10ns */
340 tmp |= DIV_ROUND_UP(20, ns) << SSB_PROG_WCNT_2_SHIFT; /* Waitcount-2 = 20ns */
341 tmp |= DIV_ROUND_UP(100, ns) << SSB_PROG_WCNT_1_SHIFT; /* Waitcount-1 = 100ns */
342 tmp |= DIV_ROUND_UP(120, ns); /* Waitcount-0 = 120ns */
343 chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp); /* 0x01020a0c for a 100Mhz clock */
344 }
345}
346
347/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
348void
349ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks)
350{
351 /* instant NMI */
352 chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks);
353}
354
355u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask)
356{
357 return chipco_read32(cc, SSB_CHIPCO_GPIOIN) & mask;
358}
359
360void ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value)
361{
362 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value);
363}
364
365void ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value)
366{
367 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value);
368}
369
370#ifdef CONFIG_SSB_SERIAL
371int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
372 struct ssb_serial_port *ports)
373{
374 struct ssb_bus *bus = cc->dev->bus;
375 int nr_ports = 0;
376 u32 plltype;
377 unsigned int irq;
378 u32 baud_base, div;
379 u32 i, n;
380
381 plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);
382 irq = ssb_mips_irq(cc->dev);
383
384 if (plltype == SSB_PLLTYPE_1) {
385 /* PLL clock */
386 baud_base = ssb_calc_clock_rate(plltype,
387 chipco_read32(cc, SSB_CHIPCO_CLOCK_N),
388 chipco_read32(cc, SSB_CHIPCO_CLOCK_M2));
389 div = 1;
390 } else {
391 if (cc->dev->id.revision >= 11) {
392 /* Fixed ALP clock */
393 baud_base = 20000000;
394 div = 1;
395 /* Set the override bit so we don't divide it */
396 chipco_write32(cc, SSB_CHIPCO_CORECTL,
397 SSB_CHIPCO_CORECTL_UARTCLK0);
398 } else if (cc->dev->id.revision >= 3) {
399 /* Internal backplane clock */
400 baud_base = ssb_clockspeed(bus);
401 div = chipco_read32(cc, SSB_CHIPCO_CLKDIV)
402 & SSB_CHIPCO_CLKDIV_UART;
403 } else {
404 /* Fixed internal backplane clock */
405 baud_base = 88000000;
406 div = 48;
407 }
408
409 /* Clock source depends on strapping if UartClkOverride is unset */
410 if ((cc->dev->id.revision > 0) &&
411 !(chipco_read32(cc, SSB_CHIPCO_CORECTL) & SSB_CHIPCO_CORECTL_UARTCLK0)) {
412 if ((cc->capabilities & SSB_CHIPCO_CAP_UARTCLK) ==
413 SSB_CHIPCO_CAP_UARTCLK_INT) {
414 /* Internal divided backplane clock */
415 baud_base /= div;
416 } else {
417 /* Assume external clock of 1.8432 MHz */
418 baud_base = 1843200;
419 }
420 }
421 }
422
423 /* Determine the registers of the UARTs */
424 n = (cc->capabilities & SSB_CHIPCO_CAP_NRUART);
425 for (i = 0; i < n; i++) {
426 void __iomem *cc_mmio;
427 void __iomem *uart_regs;
428
429 cc_mmio = cc->dev->bus->mmio + (cc->dev->core_index * SSB_CORE_SIZE);
430 uart_regs = cc_mmio + SSB_CHIPCO_UART0_DATA;
431 /* Offset changed at after rev 0 */
432 if (cc->dev->id.revision == 0)
433 uart_regs += (i * 8);
434 else
435 uart_regs += (i * 256);
436
437 nr_ports++;
438 ports[i].regs = uart_regs;
439 ports[i].irq = irq;
440 ports[i].baud_base = baud_base;
441 ports[i].reg_shift = 0;
442 }
443
444 return nr_ports;
445}
446#endif /* CONFIG_SSB_SERIAL */
diff --git a/drivers/ssb/driver_extif.c b/drivers/ssb/driver_extif.c
new file mode 100644
index 00000000000..fe55eb8b038
--- /dev/null
+++ b/drivers/ssb/driver_extif.c
@@ -0,0 +1,129 @@
1/*
2 * Sonics Silicon Backplane
3 * Broadcom EXTIF core driver
4 *
5 * Copyright 2005, Broadcom Corporation
6 * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
7 * Copyright 2006, 2007, Felix Fietkau <nbd@openwrt.org>
8 * Copyright 2007, Aurelien Jarno <aurelien@aurel32.net>
9 *
10 * Licensed under the GNU/GPL. See COPYING for details.
11 */
12
13#include <linux/serial.h>
14#include <linux/serial_core.h>
15#include <linux/serial_reg.h>
16
17#include "ssb_private.h"
18
19
20static inline u32 extif_read32(struct ssb_extif *extif, u16 offset)
21{
22 return ssb_read32(extif->dev, offset);
23}
24
25static inline void extif_write32(struct ssb_extif *extif, u16 offset, u32 value)
26{
27 ssb_write32(extif->dev, offset, value);
28}
29
30static inline void extif_write32_masked(struct ssb_extif *extif, u16 offset,
31 u32 mask, u32 value)
32{
33 value &= mask;
34 value |= extif_read32(extif, offset) & ~mask;
35 extif_write32(extif, offset, value);
36}
37
38#ifdef CONFIG_SSB_SERIAL
39static bool serial_exists(u8 *regs)
40{
41 u8 save_mcr, msr = 0;
42
43 if (regs) {
44 save_mcr = regs[UART_MCR];
45 regs[UART_MCR] = (UART_MCR_LOOP | UART_MCR_OUT2 | UART_MCR_RTS);
46 msr = regs[UART_MSR] & (UART_MSR_DCD | UART_MSR_RI
47 | UART_MSR_CTS | UART_MSR_DSR);
48 regs[UART_MCR] = save_mcr;
49 }
50 return (msr == (UART_MSR_DCD | UART_MSR_CTS));
51}
52
53int ssb_extif_serial_init(struct ssb_extif *extif, struct ssb_serial_port *ports)
54{
55 u32 i, nr_ports = 0;
56
57 /* Disable GPIO interrupt initially */
58 extif_write32(extif, SSB_EXTIF_GPIO_INTPOL, 0);
59 extif_write32(extif, SSB_EXTIF_GPIO_INTMASK, 0);
60
61 for (i = 0; i < 2; i++) {
62 void __iomem *uart_regs;
63
64 uart_regs = ioremap_nocache(SSB_EUART, 16);
65 if (uart_regs) {
66 uart_regs += (i * 8);
67
68 if (serial_exists(uart_regs) && ports) {
69 extif_write32(extif, SSB_EXTIF_GPIO_INTMASK, 2);
70
71 nr_ports++;
72 ports[i].regs = uart_regs;
73 ports[i].irq = 2;
74 ports[i].baud_base = 13500000;
75 ports[i].reg_shift = 0;
76 }
77 iounmap(uart_regs);
78 }
79 }
80 return nr_ports;
81}
82#endif /* CONFIG_SSB_SERIAL */
83
84void ssb_extif_timing_init(struct ssb_extif *extif, unsigned long ns)
85{
86 u32 tmp;
87
88 /* Initialize extif so we can get to the LEDs and external UART */
89 extif_write32(extif, SSB_EXTIF_PROG_CFG, SSB_EXTCFG_EN);
90
91 /* Set timing for the flash */
92 tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT;
93 tmp |= DIV_ROUND_UP(40, ns) << SSB_PROG_WCNT_1_SHIFT;
94 tmp |= DIV_ROUND_UP(120, ns);
95 extif_write32(extif, SSB_EXTIF_PROG_WAITCNT, tmp);
96
97 /* Set programmable interface timing for external uart */
98 tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT;
99 tmp |= DIV_ROUND_UP(20, ns) << SSB_PROG_WCNT_2_SHIFT;
100 tmp |= DIV_ROUND_UP(100, ns) << SSB_PROG_WCNT_1_SHIFT;
101 tmp |= DIV_ROUND_UP(120, ns);
102 extif_write32(extif, SSB_EXTIF_PROG_WAITCNT, tmp);
103}
104
105void ssb_extif_get_clockcontrol(struct ssb_extif *extif,
106 u32 *pll_type, u32 *n, u32 *m)
107{
108 *pll_type = SSB_PLLTYPE_1;
109 *n = extif_read32(extif, SSB_EXTIF_CLOCK_N);
110 *m = extif_read32(extif, SSB_EXTIF_CLOCK_SB);
111}
112
113u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
114{
115 return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask;
116}
117
118void ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value)
119{
120 return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0),
121 mask, value);
122}
123
124void ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value)
125{
126 return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0),
127 mask, value);
128}
129
diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c
new file mode 100644
index 00000000000..ab8691a3258
--- /dev/null
+++ b/drivers/ssb/driver_mipscore.c
@@ -0,0 +1,223 @@
1/*
2 * Sonics Silicon Backplane
3 * Broadcom MIPS core driver
4 *
5 * Copyright 2005, Broadcom Corporation
6 * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
7 *
8 * Licensed under the GNU/GPL. See COPYING for details.
9 */
10
11#include <linux/ssb/ssb.h>
12
13#include <linux/serial.h>
14#include <linux/serial_core.h>
15#include <linux/serial_reg.h>
16#include <linux/time.h>
17
18#include "ssb_private.h"
19
20
21static inline u32 mips_read32(struct ssb_mipscore *mcore,
22 u16 offset)
23{
24 return ssb_read32(mcore->dev, offset);
25}
26
27static inline void mips_write32(struct ssb_mipscore *mcore,
28 u16 offset,
29 u32 value)
30{
31 ssb_write32(mcore->dev, offset, value);
32}
33
34static const u32 ipsflag_irq_mask[] = {
35 0,
36 SSB_IPSFLAG_IRQ1,
37 SSB_IPSFLAG_IRQ2,
38 SSB_IPSFLAG_IRQ3,
39 SSB_IPSFLAG_IRQ4,
40};
41
42static const u32 ipsflag_irq_shift[] = {
43 0,
44 SSB_IPSFLAG_IRQ1_SHIFT,
45 SSB_IPSFLAG_IRQ2_SHIFT,
46 SSB_IPSFLAG_IRQ3_SHIFT,
47 SSB_IPSFLAG_IRQ4_SHIFT,
48};
49
50static inline u32 ssb_irqflag(struct ssb_device *dev)
51{
52 return ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG;
53}
54
55/* Get the MIPS IRQ assignment for a specified device.
56 * If unassigned, 0 is returned.
57 */
58unsigned int ssb_mips_irq(struct ssb_device *dev)
59{
60 struct ssb_bus *bus = dev->bus;
61 u32 irqflag;
62 u32 ipsflag;
63 u32 tmp;
64 unsigned int irq;
65
66 irqflag = ssb_irqflag(dev);
67 ipsflag = ssb_read32(bus->mipscore.dev, SSB_IPSFLAG);
68 for (irq = 1; irq <= 4; irq++) {
69 tmp = ((ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq]);
70 if (tmp == irqflag)
71 break;
72 }
73 if (irq == 5)
74 irq = 0;
75
76 return irq;
77}
78
79static void clear_irq(struct ssb_bus *bus, unsigned int irq)
80{
81 struct ssb_device *dev = bus->mipscore.dev;
82
83 /* Clear the IRQ in the MIPScore backplane registers */
84 if (irq == 0) {
85 ssb_write32(dev, SSB_INTVEC, 0);
86 } else {
87 ssb_write32(dev, SSB_IPSFLAG,
88 ssb_read32(dev, SSB_IPSFLAG) |
89 ipsflag_irq_mask[irq]);
90 }
91}
92
93static void set_irq(struct ssb_device *dev, unsigned int irq)
94{
95 unsigned int oldirq = ssb_mips_irq(dev);
96 struct ssb_bus *bus = dev->bus;
97 struct ssb_device *mdev = bus->mipscore.dev;
98 u32 irqflag = ssb_irqflag(dev);
99
100 dev->irq = irq + 2;
101
102 ssb_dprintk(KERN_INFO PFX
103 "set_irq: core 0x%04x, irq %d => %d\n",
104 dev->id.coreid, oldirq, irq);
105 /* clear the old irq */
106 if (oldirq == 0)
107 ssb_write32(mdev, SSB_INTVEC, (~(1 << irqflag) & ssb_read32(mdev, SSB_INTVEC)));
108 else
109 clear_irq(bus, oldirq);
110
111 /* assign the new one */
112 if (irq == 0)
113 ssb_write32(mdev, SSB_INTVEC, ((1 << irqflag) & ssb_read32(mdev, SSB_INTVEC)));
114
115 irqflag <<= ipsflag_irq_shift[irq];
116 irqflag |= (ssb_read32(mdev, SSB_IPSFLAG) & ~ipsflag_irq_mask[irq]);
117 ssb_write32(mdev, SSB_IPSFLAG, irqflag);
118}
119
120static void ssb_mips_serial_init(struct ssb_mipscore *mcore)
121{
122 struct ssb_bus *bus = mcore->dev->bus;
123
124 if (bus->extif.dev)
125 mcore->nr_serial_ports = ssb_extif_serial_init(&bus->extif, mcore->serial_ports);
126 else if (bus->chipco.dev)
127 mcore->nr_serial_ports = ssb_chipco_serial_init(&bus->chipco, mcore->serial_ports);
128 else
129 mcore->nr_serial_ports = 0;
130}
131
132static void ssb_mips_flash_detect(struct ssb_mipscore *mcore)
133{
134 struct ssb_bus *bus = mcore->dev->bus;
135
136 mcore->flash_buswidth = 2;
137 if (bus->chipco.dev) {
138 mcore->flash_window = 0x1c000000;
139 mcore->flash_window_size = 0x02000000;
140 if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG)
141 & SSB_CHIPCO_CFG_DS16) == 0)
142 mcore->flash_buswidth = 1;
143 } else {
144 mcore->flash_window = 0x1fc00000;
145 mcore->flash_window_size = 0x00400000;
146 }
147}
148
149u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
150{
151 struct ssb_bus *bus = mcore->dev->bus;
152 u32 pll_type, n, m, rate = 0;
153
154 if (bus->extif.dev) {
155 ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m);
156 } else if (bus->chipco.dev) {
157 ssb_chipco_get_clockcpu(&bus->chipco, &pll_type, &n, &m);
158 } else
159 return 0;
160
161 if ((pll_type == SSB_PLLTYPE_5) || (bus->chip_id == 0x5365)) {
162 rate = 200000000;
163 } else {
164 rate = ssb_calc_clock_rate(pll_type, n, m);
165 }
166
167 if (pll_type == SSB_PLLTYPE_6) {
168 rate *= 2;
169 }
170
171 return rate;
172}
173
174void ssb_mipscore_init(struct ssb_mipscore *mcore)
175{
176 struct ssb_bus *bus = mcore->dev->bus;
177 struct ssb_device *dev;
178 unsigned long hz, ns;
179 unsigned int irq, i;
180
181 if (!mcore->dev)
182 return; /* We don't have a MIPS core */
183
184 ssb_dprintk(KERN_INFO PFX "Initializing MIPS core...\n");
185
186 hz = ssb_clockspeed(bus);
187 if (!hz)
188 hz = 100000000;
189 ns = 1000000000 / hz;
190
191 if (bus->extif.dev)
192 ssb_extif_timing_init(&bus->extif, ns);
193 else if (bus->chipco.dev)
194 ssb_chipco_timing_init(&bus->chipco, ns);
195
196 /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */
197 for (irq = 2, i = 0; i < bus->nr_devices; i++) {
198 dev = &(bus->devices[i]);
199 dev->irq = ssb_mips_irq(dev) + 2;
200 switch (dev->id.coreid) {
201 case SSB_DEV_USB11_HOST:
202 /* shouldn't need a separate irq line for non-4710, most of them have a proper
203 * external usb controller on the pci */
204 if ((bus->chip_id == 0x4710) && (irq <= 4)) {
205 set_irq(dev, irq++);
206 break;
207 }
208 /* fallthrough */
209 case SSB_DEV_PCI:
210 case SSB_DEV_ETHERNET:
211 case SSB_DEV_80211:
212 case SSB_DEV_USB20_HOST:
213 /* These devices get their own IRQ line if available, the rest goes on IRQ0 */
214 if (irq <= 4) {
215 set_irq(dev, irq++);
216 break;
217 }
218 }
219 }
220
221 ssb_mips_serial_init(mcore);
222 ssb_mips_flash_detect(mcore);
223}
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c
new file mode 100644
index 00000000000..2faaa906d5d
--- /dev/null
+++ b/drivers/ssb/driver_pcicore.c
@@ -0,0 +1,576 @@
1/*
2 * Sonics Silicon Backplane
3 * Broadcom PCI-core driver
4 *
5 * Copyright 2005, Broadcom Corporation
6 * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
7 *
8 * Licensed under the GNU/GPL. See COPYING for details.
9 */
10
11#include <linux/ssb/ssb.h>
12#include <linux/pci.h>
13#include <linux/delay.h>
14
15#include "ssb_private.h"
16
17
18static inline
19u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset)
20{
21 return ssb_read32(pc->dev, offset);
22}
23
24static inline
25void pcicore_write32(struct ssb_pcicore *pc, u16 offset, u32 value)
26{
27 ssb_write32(pc->dev, offset, value);
28}
29
30/**************************************************
31 * Code for hostmode operation.
32 **************************************************/
33
34#ifdef CONFIG_SSB_PCICORE_HOSTMODE
35
36#include <asm/paccess.h>
37/* Probe a 32bit value on the bus and catch bus exceptions.
38 * Returns nonzero on a bus exception.
39 * This is MIPS specific */
40#define mips_busprobe32(val, addr) get_dbe((val), ((u32 *)(addr)))
41
42/* Assume one-hot slot wiring */
43#define SSB_PCI_SLOT_MAX 16
44
45/* Global lock is OK, as we won't have more than one extpci anyway. */
46static DEFINE_SPINLOCK(cfgspace_lock);
47/* Core to access the external PCI config space. Can only have one. */
48static struct ssb_pcicore *extpci_core;
49
50static u32 ssb_pcicore_pcibus_iobase = 0x100;
51static u32 ssb_pcicore_pcibus_membase = SSB_PCI_DMA;
52
53int pcibios_plat_dev_init(struct pci_dev *d)
54{
55 struct resource *res;
56 int pos, size;
57 u32 *base;
58
59 ssb_printk(KERN_INFO "PCI: Fixing up device %s\n",
60 pci_name(d));
61
62 /* Fix up resource bases */
63 for (pos = 0; pos < 6; pos++) {
64 res = &d->resource[pos];
65 if (res->flags & IORESOURCE_IO)
66 base = &ssb_pcicore_pcibus_iobase;
67 else
68 base = &ssb_pcicore_pcibus_membase;
69 if (res->end) {
70 size = res->end - res->start + 1;
71 if (*base & (size - 1))
72 *base = (*base + size) & ~(size - 1);
73 res->start = *base;
74 res->end = res->start + size - 1;
75 *base += size;
76 pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
77 }
78 /* Fix up PCI bridge BAR0 only */
79 if (d->bus->number == 0 && PCI_SLOT(d->devfn) == 0)
80 break;
81 }
82 /* Fix up interrupt lines */
83 d->irq = ssb_mips_irq(extpci_core->dev) + 2;
84 pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
85
86 return 0;
87}
88
89static void __init ssb_fixup_pcibridge(struct pci_dev *dev)
90{
91 if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0)
92 return;
93
94 ssb_printk(KERN_INFO "PCI: fixing up bridge\n");
95
96 /* Enable PCI bridge bus mastering and memory space */
97 pci_set_master(dev);
98 pcibios_enable_device(dev, ~0);
99
100 /* Enable PCI bridge BAR1 prefetch and burst */
101 pci_write_config_dword(dev, SSB_BAR1_CONTROL, 3);
102
103 /* Make sure our latency is high enough to handle the devices behind us */
104 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xa8);
105}
106DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_fixup_pcibridge);
107
108int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
109{
110 return ssb_mips_irq(extpci_core->dev) + 2;
111}
112
113static u32 get_cfgspace_addr(struct ssb_pcicore *pc,
114 unsigned int bus, unsigned int dev,
115 unsigned int func, unsigned int off)
116{
117 u32 addr = 0;
118 u32 tmp;
119
120 if (unlikely(pc->cardbusmode && dev > 1))
121 goto out;
122 if (bus == 0) {
123 /* Type 0 transaction */
124 if (unlikely(dev >= SSB_PCI_SLOT_MAX))
125 goto out;
126 /* Slide the window */
127 tmp = SSB_PCICORE_SBTOPCI_CFG0;
128 tmp |= ((1 << (dev + 16)) & SSB_PCICORE_SBTOPCI1_MASK);
129 pcicore_write32(pc, SSB_PCICORE_SBTOPCI1, tmp);
130 /* Calculate the address */
131 addr = SSB_PCI_CFG;
132 addr |= ((1 << (dev + 16)) & ~SSB_PCICORE_SBTOPCI1_MASK);
133 addr |= (func << 8);
134 addr |= (off & ~3);
135 } else {
136 /* Type 1 transaction */
137 pcicore_write32(pc, SSB_PCICORE_SBTOPCI1,
138 SSB_PCICORE_SBTOPCI_CFG1);
139 /* Calculate the address */
140 addr = SSB_PCI_CFG;
141 addr |= (bus << 16);
142 addr |= (dev << 11);
143 addr |= (func << 8);
144 addr |= (off & ~3);
145 }
146out:
147 return addr;
148}
149
150static int ssb_extpci_read_config(struct ssb_pcicore *pc,
151 unsigned int bus, unsigned int dev,
152 unsigned int func, unsigned int off,
153 void *buf, int len)
154{
155 int err = -EINVAL;
156 u32 addr, val;
157 void __iomem *mmio;
158
159 SSB_WARN_ON(!pc->hostmode);
160 if (unlikely(len != 1 && len != 2 && len != 4))
161 goto out;
162 addr = get_cfgspace_addr(pc, bus, dev, func, off);
163 if (unlikely(!addr))
164 goto out;
165 err = -ENOMEM;
166 mmio = ioremap_nocache(addr, len);
167 if (!mmio)
168 goto out;
169
170 if (mips_busprobe32(val, mmio)) {
171 val = 0xffffffff;
172 goto unmap;
173 }
174
175 val = readl(mmio);
176 val >>= (8 * (off & 3));
177
178 switch (len) {
179 case 1:
180 *((u8 *)buf) = (u8)val;
181 break;
182 case 2:
183 *((u16 *)buf) = (u16)val;
184 break;
185 case 4:
186 *((u32 *)buf) = (u32)val;
187 break;
188 }
189 err = 0;
190unmap:
191 iounmap(mmio);
192out:
193 return err;
194}
195
196static int ssb_extpci_write_config(struct ssb_pcicore *pc,
197 unsigned int bus, unsigned int dev,
198 unsigned int func, unsigned int off,
199 const void *buf, int len)
200{
201 int err = -EINVAL;
202 u32 addr, val = 0;
203 void __iomem *mmio;
204
205 SSB_WARN_ON(!pc->hostmode);
206 if (unlikely(len != 1 && len != 2 && len != 4))
207 goto out;
208 addr = get_cfgspace_addr(pc, bus, dev, func, off);
209 if (unlikely(!addr))
210 goto out;
211 err = -ENOMEM;
212 mmio = ioremap_nocache(addr, len);
213 if (!mmio)
214 goto out;
215
216 if (mips_busprobe32(val, mmio)) {
217 val = 0xffffffff;
218 goto unmap;
219 }
220
221 switch (len) {
222 case 1:
223 val = readl(mmio);
224 val &= ~(0xFF << (8 * (off & 3)));
225 val |= *((const u8 *)buf) << (8 * (off & 3));
226 break;
227 case 2:
228 val = readl(mmio);
229 val &= ~(0xFFFF << (8 * (off & 3)));
230 val |= *((const u16 *)buf) << (8 * (off & 3));
231 break;
232 case 4:
233 val = *((const u32 *)buf);
234 break;
235 }
236 writel(val, mmio);
237
238 err = 0;
239unmap:
240 iounmap(mmio);
241out:
242 return err;
243}
244
245static int ssb_pcicore_read_config(struct pci_bus *bus, unsigned int devfn,
246 int reg, int size, u32 *val)
247{
248 unsigned long flags;
249 int err;
250
251 spin_lock_irqsave(&cfgspace_lock, flags);
252 err = ssb_extpci_read_config(extpci_core, bus->number, PCI_SLOT(devfn),
253 PCI_FUNC(devfn), reg, val, size);
254 spin_unlock_irqrestore(&cfgspace_lock, flags);
255
256 return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
257}
258
259static int ssb_pcicore_write_config(struct pci_bus *bus, unsigned int devfn,
260 int reg, int size, u32 val)
261{
262 unsigned long flags;
263 int err;
264
265 spin_lock_irqsave(&cfgspace_lock, flags);
266 err = ssb_extpci_write_config(extpci_core, bus->number, PCI_SLOT(devfn),
267 PCI_FUNC(devfn), reg, &val, size);
268 spin_unlock_irqrestore(&cfgspace_lock, flags);
269
270 return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
271}
272
273static struct pci_ops ssb_pcicore_pciops = {
274 .read = ssb_pcicore_read_config,
275 .write = ssb_pcicore_write_config,
276};
277
278static struct resource ssb_pcicore_mem_resource = {
279 .name = "SSB PCIcore external memory",
280 .start = SSB_PCI_DMA,
281 .end = SSB_PCI_DMA + SSB_PCI_DMA_SZ - 1,
282 .flags = IORESOURCE_MEM,
283};
284
285static struct resource ssb_pcicore_io_resource = {
286 .name = "SSB PCIcore external I/O",
287 .start = 0x100,
288 .end = 0x7FF,
289 .flags = IORESOURCE_IO,
290};
291
292static struct pci_controller ssb_pcicore_controller = {
293 .pci_ops = &ssb_pcicore_pciops,
294 .io_resource = &ssb_pcicore_io_resource,
295 .mem_resource = &ssb_pcicore_mem_resource,
296 .mem_offset = 0x24000000,
297};
298
299static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
300{
301 u32 val;
302
303 if (WARN_ON(extpci_core))
304 return;
305 extpci_core = pc;
306
307 ssb_dprintk(KERN_INFO PFX "PCIcore in host mode found\n");
308 /* Reset devices on the external PCI bus */
309 val = SSB_PCICORE_CTL_RST_OE;
310 val |= SSB_PCICORE_CTL_CLK_OE;
311 pcicore_write32(pc, SSB_PCICORE_CTL, val);
312 val |= SSB_PCICORE_CTL_CLK; /* Clock on */
313 pcicore_write32(pc, SSB_PCICORE_CTL, val);
314 udelay(150); /* Assertion time demanded by the PCI standard */
315 val |= SSB_PCICORE_CTL_RST; /* Deassert RST# */
316 pcicore_write32(pc, SSB_PCICORE_CTL, val);
317 val = SSB_PCICORE_ARBCTL_INTERN;
318 pcicore_write32(pc, SSB_PCICORE_ARBCTL, val);
319 udelay(1); /* Assertion time demanded by the PCI standard */
320
321 /*TODO cardbus mode */
322
323 /* 64MB I/O window */
324 pcicore_write32(pc, SSB_PCICORE_SBTOPCI0,
325 SSB_PCICORE_SBTOPCI_IO);
326 /* 64MB config space */
327 pcicore_write32(pc, SSB_PCICORE_SBTOPCI1,
328 SSB_PCICORE_SBTOPCI_CFG0);
329 /* 1GB memory window */
330 pcicore_write32(pc, SSB_PCICORE_SBTOPCI2,
331 SSB_PCICORE_SBTOPCI_MEM | SSB_PCI_DMA);
332
333 /* Enable PCI bridge BAR0 prefetch and burst */
334 val = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
335 ssb_extpci_write_config(pc, 0, 0, 0, PCI_COMMAND, &val, 2);
336 /* Clear error conditions */
337 val = 0;
338 ssb_extpci_write_config(pc, 0, 0, 0, PCI_STATUS, &val, 2);
339
340 /* Enable PCI interrupts */
341 pcicore_write32(pc, SSB_PCICORE_IMASK,
342 SSB_PCICORE_IMASK_INTA);
343
344 /* Ok, ready to run, register it to the system.
345 * The following needs change, if we want to port hostmode
346 * to non-MIPS platform. */
347 set_io_port_base((unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000));
348 /* Give some time to the PCI controller to configure itself with the new
349 * values. Not waiting at this point causes crashes of the machine. */
350 mdelay(10);
351 register_pci_controller(&ssb_pcicore_controller);
352}
353
354static int pcicore_is_in_hostmode(struct ssb_pcicore *pc)
355{
356 struct ssb_bus *bus = pc->dev->bus;
357 u16 chipid_top;
358 u32 tmp;
359
360 chipid_top = (bus->chip_id & 0xFF00);
361 if (chipid_top != 0x4700 &&
362 chipid_top != 0x5300)
363 return 0;
364
365 if (bus->sprom.r1.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
366 return 0;
367
368 /* The 200-pin BCM4712 package does not bond out PCI. Even when
369 * PCI is bonded out, some boards may leave the pins floating. */
370 if (bus->chip_id == 0x4712) {
371 if (bus->chip_package == SSB_CHIPPACK_BCM4712S)
372 return 0;
373 if (bus->chip_package == SSB_CHIPPACK_BCM4712M)
374 return 0;
375 }
376 if (bus->chip_id == 0x5350)
377 return 0;
378
379 return !mips_busprobe32(tmp, (bus->mmio + (pc->dev->core_index * SSB_CORE_SIZE)));
380}
381#endif /* CONFIG_SSB_PCICORE_HOSTMODE */
382
383
384/**************************************************
385 * Generic and Clientmode operation code.
386 **************************************************/
387
388static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
389{
390 /* Disable PCI interrupts. */
391 ssb_write32(pc->dev, SSB_INTVEC, 0);
392}
393
394void ssb_pcicore_init(struct ssb_pcicore *pc)
395{
396 struct ssb_device *dev = pc->dev;
397 struct ssb_bus *bus;
398
399 if (!dev)
400 return;
401 bus = dev->bus;
402 if (!ssb_device_is_enabled(dev))
403 ssb_device_enable(dev, 0);
404
405#ifdef CONFIG_SSB_PCICORE_HOSTMODE
406 pc->hostmode = pcicore_is_in_hostmode(pc);
407 if (pc->hostmode)
408 ssb_pcicore_init_hostmode(pc);
409#endif /* CONFIG_SSB_PCICORE_HOSTMODE */
410 if (!pc->hostmode)
411 ssb_pcicore_init_clientmode(pc);
412}
413
414static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address)
415{
416 pcicore_write32(pc, 0x130, address);
417 return pcicore_read32(pc, 0x134);
418}
419
420static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data)
421{
422 pcicore_write32(pc, 0x130, address);
423 pcicore_write32(pc, 0x134, data);
424}
425
426static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
427 u8 address, u16 data)
428{
429 const u16 mdio_control = 0x128;
430 const u16 mdio_data = 0x12C;
431 u32 v;
432 int i;
433
434 v = 0x80; /* Enable Preamble Sequence */
435 v |= 0x2; /* MDIO Clock Divisor */
436 pcicore_write32(pc, mdio_control, v);
437
438 v = (1 << 30); /* Start of Transaction */
439 v |= (1 << 28); /* Write Transaction */
440 v |= (1 << 17); /* Turnaround */
441 v |= (u32)device << 22;
442 v |= (u32)address << 18;
443 v |= data;
444 pcicore_write32(pc, mdio_data, v);
445 /* Wait for the device to complete the transaction */
446 udelay(10);
447 for (i = 0; i < 10; i++) {
448 v = pcicore_read32(pc, mdio_control);
449 if (v & 0x100 /* Trans complete */)
450 break;
451 msleep(1);
452 }
453 pcicore_write32(pc, mdio_control, 0);
454}
455
456static void ssb_broadcast_value(struct ssb_device *dev,
457 u32 address, u32 data)
458{
459 /* This is used for both, PCI and ChipCommon core, so be careful. */
460 BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
461 BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
462
463 ssb_write32(dev, SSB_PCICORE_BCAST_ADDR, address);
464 ssb_read32(dev, SSB_PCICORE_BCAST_ADDR); /* flush */
465 ssb_write32(dev, SSB_PCICORE_BCAST_DATA, data);
466 ssb_read32(dev, SSB_PCICORE_BCAST_DATA); /* flush */
467}
468
469static void ssb_commit_settings(struct ssb_bus *bus)
470{
471 struct ssb_device *dev;
472
473 dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
474 if (WARN_ON(!dev))
475 return;
476 /* This forces an update of the cached registers. */
477 ssb_broadcast_value(dev, 0xFD8, 0);
478}
479
480int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
481 struct ssb_device *dev)
482{
483 struct ssb_device *pdev = pc->dev;
484 struct ssb_bus *bus;
485 int err = 0;
486 u32 tmp;
487
488 might_sleep();
489
490 if (!pdev)
491 goto out;
492 bus = pdev->bus;
493
494 /* Enable interrupts for this device. */
495 if (bus->host_pci &&
496 ((pdev->id.revision >= 6) || (pdev->id.coreid == SSB_DEV_PCIE))) {
497 u32 coremask;
498
499 /* Calculate the "coremask" for the device. */
500 coremask = (1 << dev->core_index);
501
502 err = pci_read_config_dword(bus->host_pci, SSB_PCI_IRQMASK, &tmp);
503 if (err)
504 goto out;
505 tmp |= coremask << 8;
506 err = pci_write_config_dword(bus->host_pci, SSB_PCI_IRQMASK, tmp);
507 if (err)
508 goto out;
509 } else {
510 u32 intvec;
511
512 intvec = ssb_read32(pdev, SSB_INTVEC);
513 if ((bus->chip_id & 0xFF00) == 0x4400) {
514 /* Workaround: On the BCM44XX the BPFLAG routing
515 * bit is wrong. Use a hardcoded constant. */
516 intvec |= 0x00000002;
517 } else {
518 tmp = ssb_read32(dev, SSB_TPSFLAG);
519 tmp &= SSB_TPSFLAG_BPFLAG;
520 intvec |= tmp;
521 }
522 ssb_write32(pdev, SSB_INTVEC, intvec);
523 }
524
525 /* Setup PCIcore operation. */
526 if (pc->setup_done)
527 goto out;
528 if (pdev->id.coreid == SSB_DEV_PCI) {
529 tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
530 tmp |= SSB_PCICORE_SBTOPCI_PREF;
531 tmp |= SSB_PCICORE_SBTOPCI_BURST;
532 pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
533
534 if (pdev->id.revision < 5) {
535 tmp = ssb_read32(pdev, SSB_IMCFGLO);
536 tmp &= ~SSB_IMCFGLO_SERTO;
537 tmp |= 2;
538 tmp &= ~SSB_IMCFGLO_REQTO;
539 tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
540 ssb_write32(pdev, SSB_IMCFGLO, tmp);
541 ssb_commit_settings(bus);
542 } else if (pdev->id.revision >= 11) {
543 tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
544 tmp |= SSB_PCICORE_SBTOPCI_MRM;
545 pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
546 }
547 } else {
548 WARN_ON(pdev->id.coreid != SSB_DEV_PCIE);
549 //TODO: Better make defines for all these magic PCIE values.
550 if ((pdev->id.revision == 0) || (pdev->id.revision == 1)) {
551 /* TLP Workaround register. */
552 tmp = ssb_pcie_read(pc, 0x4);
553 tmp |= 0x8;
554 ssb_pcie_write(pc, 0x4, tmp);
555 }
556 if (pdev->id.revision == 0) {
557 const u8 serdes_rx_device = 0x1F;
558
559 ssb_pcie_mdio_write(pc, serdes_rx_device,
560 2 /* Timer */, 0x8128);
561 ssb_pcie_mdio_write(pc, serdes_rx_device,
562 6 /* CDR */, 0x0100);
563 ssb_pcie_mdio_write(pc, serdes_rx_device,
564 7 /* CDR BW */, 0x1466);
565 } else if (pdev->id.revision == 1) {
566 /* DLLP Link Control register. */
567 tmp = ssb_pcie_read(pc, 0x100);
568 tmp |= 0x40;
569 ssb_pcie_write(pc, 0x100, tmp);
570 }
571 }
572 pc->setup_done = 1;
573out:
574 return err;
575}
576EXPORT_SYMBOL(ssb_pcicore_dev_irqvecs_enable);
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
new file mode 100644
index 00000000000..74d5182db4b
--- /dev/null
+++ b/drivers/ssb/main.c
@@ -0,0 +1,1162 @@
1/*
2 * Sonics Silicon Backplane
3 * Subsystem core
4 *
5 * Copyright 2005, Broadcom Corporation
6 * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
7 *
8 * Licensed under the GNU/GPL. See COPYING for details.
9 */
10
11#include "ssb_private.h"
12
13#include <linux/delay.h>
14#include <linux/ssb/ssb.h>
15#include <linux/ssb/ssb_regs.h>
16#include <linux/dma-mapping.h>
17#include <linux/pci.h>
18
19#include <pcmcia/cs_types.h>
20#include <pcmcia/cs.h>
21#include <pcmcia/cistpl.h>
22#include <pcmcia/ds.h>
23
24
25MODULE_DESCRIPTION("Sonics Silicon Backplane driver");
26MODULE_LICENSE("GPL");
27
28
29/* Temporary list of yet-to-be-attached buses */
30static LIST_HEAD(attach_queue);
31/* List if running buses */
32static LIST_HEAD(buses);
33/* Software ID counter */
34static unsigned int next_busnumber;
35/* buses_mutes locks the two buslists and the next_busnumber.
36 * Don't lock this directly, but use ssb_buses_[un]lock() below. */
37static DEFINE_MUTEX(buses_mutex);
38
39/* There are differences in the codeflow, if the bus is
40 * initialized from early boot, as various needed services
41 * are not available early. This is a mechanism to delay
42 * these initializations to after early boot has finished.
43 * It's also used to avoid mutex locking, as that's not
44 * available and needed early. */
45static bool ssb_is_early_boot = 1;
46
47static void ssb_buses_lock(void);
48static void ssb_buses_unlock(void);
49
50
51#ifdef CONFIG_SSB_PCIHOST
52struct ssb_bus *ssb_pci_dev_to_bus(struct pci_dev *pdev)
53{
54 struct ssb_bus *bus;
55
56 ssb_buses_lock();
57 list_for_each_entry(bus, &buses, list) {
58 if (bus->bustype == SSB_BUSTYPE_PCI &&
59 bus->host_pci == pdev)
60 goto found;
61 }
62 bus = NULL;
63found:
64 ssb_buses_unlock();
65
66 return bus;
67}
68#endif /* CONFIG_SSB_PCIHOST */
69
70static struct ssb_device *ssb_device_get(struct ssb_device *dev)
71{
72 if (dev)
73 get_device(dev->dev);
74 return dev;
75}
76
77static void ssb_device_put(struct ssb_device *dev)
78{
79 if (dev)
80 put_device(dev->dev);
81}
82
83static int ssb_bus_resume(struct ssb_bus *bus)
84{
85 int err;
86
87 ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
88 err = ssb_pcmcia_init(bus);
89 if (err) {
90 /* No need to disable XTAL, as we don't have one on PCMCIA. */
91 return err;
92 }
93 ssb_chipco_resume(&bus->chipco);
94
95 return 0;
96}
97
98static int ssb_device_resume(struct device *dev)
99{
100 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
101 struct ssb_driver *ssb_drv;
102 struct ssb_bus *bus;
103 int err = 0;
104
105 bus = ssb_dev->bus;
106 if (bus->suspend_cnt == bus->nr_devices) {
107 err = ssb_bus_resume(bus);
108 if (err)
109 return err;
110 }
111 bus->suspend_cnt--;
112 if (dev->driver) {
113 ssb_drv = drv_to_ssb_drv(dev->driver);
114 if (ssb_drv && ssb_drv->resume)
115 err = ssb_drv->resume(ssb_dev);
116 if (err)
117 goto out;
118 }
119out:
120 return err;
121}
122
123static void ssb_bus_suspend(struct ssb_bus *bus, pm_message_t state)
124{
125 ssb_chipco_suspend(&bus->chipco, state);
126 ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
127
128 /* Reset HW state information in memory, so that HW is
129 * completely reinitialized on resume. */
130 bus->mapped_device = NULL;
131#ifdef CONFIG_SSB_DRIVER_PCICORE
132 bus->pcicore.setup_done = 0;
133#endif
134#ifdef CONFIG_SSB_DEBUG
135 bus->powered_up = 0;
136#endif
137}
138
139static int ssb_device_suspend(struct device *dev, pm_message_t state)
140{
141 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
142 struct ssb_driver *ssb_drv;
143 struct ssb_bus *bus;
144 int err = 0;
145
146 if (dev->driver) {
147 ssb_drv = drv_to_ssb_drv(dev->driver);
148 if (ssb_drv && ssb_drv->suspend)
149 err = ssb_drv->suspend(ssb_dev, state);
150 if (err)
151 goto out;
152 }
153
154 bus = ssb_dev->bus;
155 bus->suspend_cnt++;
156 if (bus->suspend_cnt == bus->nr_devices) {
157 /* All devices suspended. Shutdown the bus. */
158 ssb_bus_suspend(bus, state);
159 }
160
161out:
162 return err;
163}
164
165#ifdef CONFIG_SSB_PCIHOST
166int ssb_devices_freeze(struct ssb_bus *bus)
167{
168 struct ssb_device *dev;
169 struct ssb_driver *drv;
170 int err = 0;
171 int i;
172 pm_message_t state = PMSG_FREEZE;
173
174 /* First check that we are capable to freeze all devices. */
175 for (i = 0; i < bus->nr_devices; i++) {
176 dev = &(bus->devices[i]);
177 if (!dev->dev ||
178 !dev->dev->driver ||
179 !device_is_registered(dev->dev))
180 continue;
181 drv = drv_to_ssb_drv(dev->dev->driver);
182 if (!drv)
183 continue;
184 if (!drv->suspend) {
185 /* Nope, can't suspend this one. */
186 return -EOPNOTSUPP;
187 }
188 }
189 /* Now suspend all devices */
190 for (i = 0; i < bus->nr_devices; i++) {
191 dev = &(bus->devices[i]);
192 if (!dev->dev ||
193 !dev->dev->driver ||
194 !device_is_registered(dev->dev))
195 continue;
196 drv = drv_to_ssb_drv(dev->dev->driver);
197 if (!drv)
198 continue;
199 err = drv->suspend(dev, state);
200 if (err) {
201 ssb_printk(KERN_ERR PFX "Failed to freeze device %s\n",
202 dev->dev->bus_id);
203 goto err_unwind;
204 }
205 }
206
207 return 0;
208err_unwind:
209 for (i--; i >= 0; i--) {
210 dev = &(bus->devices[i]);
211 if (!dev->dev ||
212 !dev->dev->driver ||
213 !device_is_registered(dev->dev))
214 continue;
215 drv = drv_to_ssb_drv(dev->dev->driver);
216 if (!drv)
217 continue;
218 if (drv->resume)
219 drv->resume(dev);
220 }
221 return err;
222}
223
224int ssb_devices_thaw(struct ssb_bus *bus)
225{
226 struct ssb_device *dev;
227 struct ssb_driver *drv;
228 int err;
229 int i;
230
231 for (i = 0; i < bus->nr_devices; i++) {
232 dev = &(bus->devices[i]);
233 if (!dev->dev ||
234 !dev->dev->driver ||
235 !device_is_registered(dev->dev))
236 continue;
237 drv = drv_to_ssb_drv(dev->dev->driver);
238 if (!drv)
239 continue;
240 if (SSB_WARN_ON(!drv->resume))
241 continue;
242 err = drv->resume(dev);
243 if (err) {
244 ssb_printk(KERN_ERR PFX "Failed to thaw device %s\n",
245 dev->dev->bus_id);
246 }
247 }
248
249 return 0;
250}
251#endif /* CONFIG_SSB_PCIHOST */
252
253static void ssb_device_shutdown(struct device *dev)
254{
255 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
256 struct ssb_driver *ssb_drv;
257
258 if (!dev->driver)
259 return;
260 ssb_drv = drv_to_ssb_drv(dev->driver);
261 if (ssb_drv && ssb_drv->shutdown)
262 ssb_drv->shutdown(ssb_dev);
263}
264
265static int ssb_device_remove(struct device *dev)
266{
267 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
268 struct ssb_driver *ssb_drv = drv_to_ssb_drv(dev->driver);
269
270 if (ssb_drv && ssb_drv->remove)
271 ssb_drv->remove(ssb_dev);
272 ssb_device_put(ssb_dev);
273
274 return 0;
275}
276
277static int ssb_device_probe(struct device *dev)
278{
279 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
280 struct ssb_driver *ssb_drv = drv_to_ssb_drv(dev->driver);
281 int err = 0;
282
283 ssb_device_get(ssb_dev);
284 if (ssb_drv && ssb_drv->probe)
285 err = ssb_drv->probe(ssb_dev, &ssb_dev->id);
286 if (err)
287 ssb_device_put(ssb_dev);
288
289 return err;
290}
291
292static int ssb_match_devid(const struct ssb_device_id *tabid,
293 const struct ssb_device_id *devid)
294{
295 if ((tabid->vendor != devid->vendor) &&
296 tabid->vendor != SSB_ANY_VENDOR)
297 return 0;
298 if ((tabid->coreid != devid->coreid) &&
299 tabid->coreid != SSB_ANY_ID)
300 return 0;
301 if ((tabid->revision != devid->revision) &&
302 tabid->revision != SSB_ANY_REV)
303 return 0;
304 return 1;
305}
306
307static int ssb_bus_match(struct device *dev, struct device_driver *drv)
308{
309 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
310 struct ssb_driver *ssb_drv = drv_to_ssb_drv(drv);
311 const struct ssb_device_id *id;
312
313 for (id = ssb_drv->id_table;
314 id->vendor || id->coreid || id->revision;
315 id++) {
316 if (ssb_match_devid(id, &ssb_dev->id))
317 return 1; /* found */
318 }
319
320 return 0;
321}
322
323static int ssb_device_uevent(struct device *dev, char **envp, int num_envp,
324 char *buffer, int buffer_size)
325{
326 struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
327 int ret, i = 0, length = 0;
328
329 if (!dev)
330 return -ENODEV;
331
332 ret = add_uevent_var(envp, num_envp, &i,
333 buffer, buffer_size, &length,
334 "MODALIAS=ssb:v%04Xid%04Xrev%02X",
335 ssb_dev->id.vendor, ssb_dev->id.coreid,
336 ssb_dev->id.revision);
337 envp[i] = NULL;
338
339 return ret;
340}
341
342static struct bus_type ssb_bustype = {
343 .name = "ssb",
344 .match = ssb_bus_match,
345 .probe = ssb_device_probe,
346 .remove = ssb_device_remove,
347 .shutdown = ssb_device_shutdown,
348 .suspend = ssb_device_suspend,
349 .resume = ssb_device_resume,
350 .uevent = ssb_device_uevent,
351};
352
353static void ssb_buses_lock(void)
354{
355 /* See the comment at the ssb_is_early_boot definition */
356 if (!ssb_is_early_boot)
357 mutex_lock(&buses_mutex);
358}
359
360static void ssb_buses_unlock(void)
361{
362 /* See the comment at the ssb_is_early_boot definition */
363 if (!ssb_is_early_boot)
364 mutex_unlock(&buses_mutex);
365}
366
367static void ssb_devices_unregister(struct ssb_bus *bus)
368{
369 struct ssb_device *sdev;
370 int i;
371
372 for (i = bus->nr_devices - 1; i >= 0; i--) {
373 sdev = &(bus->devices[i]);
374 if (sdev->dev)
375 device_unregister(sdev->dev);
376 }
377}
378
379void ssb_bus_unregister(struct ssb_bus *bus)
380{
381 ssb_buses_lock();
382 ssb_devices_unregister(bus);
383 list_del(&bus->list);
384 ssb_buses_unlock();
385
386 /* ssb_pcmcia_exit(bus); */
387 ssb_pci_exit(bus);
388 ssb_iounmap(bus);
389}
390EXPORT_SYMBOL(ssb_bus_unregister);
391
392static void ssb_release_dev(struct device *dev)
393{
394 struct __ssb_dev_wrapper *devwrap;
395
396 devwrap = container_of(dev, struct __ssb_dev_wrapper, dev);
397 kfree(devwrap);
398}
399
400static int ssb_devices_register(struct ssb_bus *bus)
401{
402 struct ssb_device *sdev;
403 struct device *dev;
404 struct __ssb_dev_wrapper *devwrap;
405 int i, err = 0;
406 int dev_idx = 0;
407
408 for (i = 0; i < bus->nr_devices; i++) {
409 sdev = &(bus->devices[i]);
410
411 /* We don't register SSB-system devices to the kernel,
412 * as the drivers for them are built into SSB. */
413 switch (sdev->id.coreid) {
414 case SSB_DEV_CHIPCOMMON:
415 case SSB_DEV_PCI:
416 case SSB_DEV_PCIE:
417 case SSB_DEV_PCMCIA:
418 case SSB_DEV_MIPS:
419 case SSB_DEV_MIPS_3302:
420 case SSB_DEV_EXTIF:
421 continue;
422 }
423
424 devwrap = kzalloc(sizeof(*devwrap), GFP_KERNEL);
425 if (!devwrap) {
426 ssb_printk(KERN_ERR PFX
427 "Could not allocate device\n");
428 err = -ENOMEM;
429 goto error;
430 }
431 dev = &devwrap->dev;
432 devwrap->sdev = sdev;
433
434 dev->release = ssb_release_dev;
435 dev->bus = &ssb_bustype;
436 snprintf(dev->bus_id, sizeof(dev->bus_id),
437 "ssb%u:%d", bus->busnumber, dev_idx);
438
439 switch (bus->bustype) {
440 case SSB_BUSTYPE_PCI:
441#ifdef CONFIG_SSB_PCIHOST
442 sdev->irq = bus->host_pci->irq;
443 dev->parent = &bus->host_pci->dev;
444#endif
445 break;
446 case SSB_BUSTYPE_PCMCIA:
447#ifdef CONFIG_SSB_PCMCIAHOST
448 dev->parent = &bus->host_pcmcia->dev;
449#endif
450 break;
451 case SSB_BUSTYPE_SSB:
452 break;
453 }
454
455 sdev->dev = dev;
456 err = device_register(dev);
457 if (err) {
458 ssb_printk(KERN_ERR PFX
459 "Could not register %s\n",
460 dev->bus_id);
461 /* Set dev to NULL to not unregister
462 * dev on error unwinding. */
463 sdev->dev = NULL;
464 kfree(devwrap);
465 goto error;
466 }
467 dev_idx++;
468 }
469
470 return 0;
471error:
472 /* Unwind the already registered devices. */
473 ssb_devices_unregister(bus);
474 return err;
475}
476
477/* Needs ssb_buses_lock() */
478static int ssb_attach_queued_buses(void)
479{
480 struct ssb_bus *bus, *n;
481 int err = 0;
482 int drop_them_all = 0;
483
484 list_for_each_entry_safe(bus, n, &attach_queue, list) {
485 if (drop_them_all) {
486 list_del(&bus->list);
487 continue;
488 }
489 /* Can't init the PCIcore in ssb_bus_register(), as that
490 * is too early in boot for embedded systems
491 * (no udelay() available). So do it here in attach stage.
492 */
493 err = ssb_bus_powerup(bus, 0);
494 if (err)
495 goto error;
496 ssb_pcicore_init(&bus->pcicore);
497 ssb_bus_may_powerdown(bus);
498
499 err = ssb_devices_register(bus);
500error:
501 if (err) {
502 drop_them_all = 1;
503 list_del(&bus->list);
504 continue;
505 }
506 list_move_tail(&bus->list, &buses);
507 }
508
509 return err;
510}
511
512static u16 ssb_ssb_read16(struct ssb_device *dev, u16 offset)
513{
514 struct ssb_bus *bus = dev->bus;
515
516 offset += dev->core_index * SSB_CORE_SIZE;
517 return readw(bus->mmio + offset);
518}
519
520static u32 ssb_ssb_read32(struct ssb_device *dev, u16 offset)
521{
522 struct ssb_bus *bus = dev->bus;
523
524 offset += dev->core_index * SSB_CORE_SIZE;
525 return readl(bus->mmio + offset);
526}
527
528static void ssb_ssb_write16(struct ssb_device *dev, u16 offset, u16 value)
529{
530 struct ssb_bus *bus = dev->bus;
531
532 offset += dev->core_index * SSB_CORE_SIZE;
533 writew(value, bus->mmio + offset);
534}
535
536static void ssb_ssb_write32(struct ssb_device *dev, u16 offset, u32 value)
537{
538 struct ssb_bus *bus = dev->bus;
539
540 offset += dev->core_index * SSB_CORE_SIZE;
541 writel(value, bus->mmio + offset);
542}
543
544/* Ops for the plain SSB bus without a host-device (no PCI or PCMCIA). */
545static const struct ssb_bus_ops ssb_ssb_ops = {
546 .read16 = ssb_ssb_read16,
547 .read32 = ssb_ssb_read32,
548 .write16 = ssb_ssb_write16,
549 .write32 = ssb_ssb_write32,
550};
551
552static int ssb_fetch_invariants(struct ssb_bus *bus,
553 ssb_invariants_func_t get_invariants)
554{
555 struct ssb_init_invariants iv;
556 int err;
557
558 memset(&iv, 0, sizeof(iv));
559 err = get_invariants(bus, &iv);
560 if (err)
561 goto out;
562 memcpy(&bus->boardinfo, &iv.boardinfo, sizeof(iv.boardinfo));
563 memcpy(&bus->sprom, &iv.sprom, sizeof(iv.sprom));
564out:
565 return err;
566}
567
568static int ssb_bus_register(struct ssb_bus *bus,
569 ssb_invariants_func_t get_invariants,
570 unsigned long baseaddr)
571{
572 int err;
573
574 spin_lock_init(&bus->bar_lock);
575 INIT_LIST_HEAD(&bus->list);
576
577 /* Powerup the bus */
578 err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
579 if (err)
580 goto out;
581 ssb_buses_lock();
582 bus->busnumber = next_busnumber;
583 /* Scan for devices (cores) */
584 err = ssb_bus_scan(bus, baseaddr);
585 if (err)
586 goto err_disable_xtal;
587
588 /* Init PCI-host device (if any) */
589 err = ssb_pci_init(bus);
590 if (err)
591 goto err_unmap;
592 /* Init PCMCIA-host device (if any) */
593 err = ssb_pcmcia_init(bus);
594 if (err)
595 goto err_pci_exit;
596
597 /* Initialize basic system devices (if available) */
598 err = ssb_bus_powerup(bus, 0);
599 if (err)
600 goto err_pcmcia_exit;
601 ssb_chipcommon_init(&bus->chipco);
602 ssb_mipscore_init(&bus->mipscore);
603 err = ssb_fetch_invariants(bus, get_invariants);
604 if (err) {
605 ssb_bus_may_powerdown(bus);
606 goto err_pcmcia_exit;
607 }
608 ssb_bus_may_powerdown(bus);
609
610 /* Queue it for attach.
611 * See the comment at the ssb_is_early_boot definition. */
612 list_add_tail(&bus->list, &attach_queue);
613 if (!ssb_is_early_boot) {
614 /* This is not early boot, so we must attach the bus now */
615 err = ssb_attach_queued_buses();
616 if (err)
617 goto err_dequeue;
618 }
619 next_busnumber++;
620 ssb_buses_unlock();
621
622out:
623 return err;
624
625err_dequeue:
626 list_del(&bus->list);
627err_pcmcia_exit:
628/* ssb_pcmcia_exit(bus); */
629err_pci_exit:
630 ssb_pci_exit(bus);
631err_unmap:
632 ssb_iounmap(bus);
633err_disable_xtal:
634 ssb_buses_unlock();
635 ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
636 return err;
637}
638
639#ifdef CONFIG_SSB_PCIHOST
640int ssb_bus_pcibus_register(struct ssb_bus *bus,
641 struct pci_dev *host_pci)
642{
643 int err;
644
645 bus->bustype = SSB_BUSTYPE_PCI;
646 bus->host_pci = host_pci;
647 bus->ops = &ssb_pci_ops;
648
649 err = ssb_bus_register(bus, ssb_pci_get_invariants, 0);
650 if (!err) {
651 ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on "
652 "PCI device %s\n", host_pci->dev.bus_id);
653 }
654
655 return err;
656}
657EXPORT_SYMBOL(ssb_bus_pcibus_register);
658#endif /* CONFIG_SSB_PCIHOST */
659
660#ifdef CONFIG_SSB_PCMCIAHOST
661int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
662 struct pcmcia_device *pcmcia_dev,
663 unsigned long baseaddr)
664{
665 int err;
666
667 bus->bustype = SSB_BUSTYPE_PCMCIA;
668 bus->host_pcmcia = pcmcia_dev;
669 bus->ops = &ssb_pcmcia_ops;
670
671 err = ssb_bus_register(bus, ssb_pcmcia_get_invariants, baseaddr);
672 if (!err) {
673 ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on "
674 "PCMCIA device %s\n", pcmcia_dev->devname);
675 }
676
677 return err;
678}
679EXPORT_SYMBOL(ssb_bus_pcmciabus_register);
680#endif /* CONFIG_SSB_PCMCIAHOST */
681
682int ssb_bus_ssbbus_register(struct ssb_bus *bus,
683 unsigned long baseaddr,
684 ssb_invariants_func_t get_invariants)
685{
686 int err;
687
688 bus->bustype = SSB_BUSTYPE_SSB;
689 bus->ops = &ssb_ssb_ops;
690
691 err = ssb_bus_register(bus, get_invariants, baseaddr);
692 if (!err) {
693 ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found at "
694 "address 0x%08lX\n", baseaddr);
695 }
696
697 return err;
698}
699
700int __ssb_driver_register(struct ssb_driver *drv, struct module *owner)
701{
702 drv->drv.name = drv->name;
703 drv->drv.bus = &ssb_bustype;
704 drv->drv.owner = owner;
705
706 return driver_register(&drv->drv);
707}
708EXPORT_SYMBOL(__ssb_driver_register);
709
710void ssb_driver_unregister(struct ssb_driver *drv)
711{
712 driver_unregister(&drv->drv);
713}
714EXPORT_SYMBOL(ssb_driver_unregister);
715
716void ssb_set_devtypedata(struct ssb_device *dev, void *data)
717{
718 struct ssb_bus *bus = dev->bus;
719 struct ssb_device *ent;
720 int i;
721
722 for (i = 0; i < bus->nr_devices; i++) {
723 ent = &(bus->devices[i]);
724 if (ent->id.vendor != dev->id.vendor)
725 continue;
726 if (ent->id.coreid != dev->id.coreid)
727 continue;
728
729 ent->devtypedata = data;
730 }
731}
732EXPORT_SYMBOL(ssb_set_devtypedata);
733
734static u32 clkfactor_f6_resolve(u32 v)
735{
736 /* map the magic values */
737 switch (v) {
738 case SSB_CHIPCO_CLK_F6_2:
739 return 2;
740 case SSB_CHIPCO_CLK_F6_3:
741 return 3;
742 case SSB_CHIPCO_CLK_F6_4:
743 return 4;
744 case SSB_CHIPCO_CLK_F6_5:
745 return 5;
746 case SSB_CHIPCO_CLK_F6_6:
747 return 6;
748 case SSB_CHIPCO_CLK_F6_7:
749 return 7;
750 }
751 return 0;
752}
753
754/* Calculate the speed the backplane would run at a given set of clockcontrol values */
755u32 ssb_calc_clock_rate(u32 plltype, u32 n, u32 m)
756{
757 u32 n1, n2, clock, m1, m2, m3, mc;
758
759 n1 = (n & SSB_CHIPCO_CLK_N1);
760 n2 = ((n & SSB_CHIPCO_CLK_N2) >> SSB_CHIPCO_CLK_N2_SHIFT);
761
762 switch (plltype) {
763 case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */
764 if (m & SSB_CHIPCO_CLK_T6_MMASK)
765 return SSB_CHIPCO_CLK_T6_M0;
766 return SSB_CHIPCO_CLK_T6_M1;
767 case SSB_PLLTYPE_1: /* 48Mhz base, 3 dividers */
768 case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
769 case SSB_PLLTYPE_4: /* 48Mhz, 4 dividers */
770 case SSB_PLLTYPE_7: /* 25Mhz, 4 dividers */
771 n1 = clkfactor_f6_resolve(n1);
772 n2 += SSB_CHIPCO_CLK_F5_BIAS;
773 break;
774 case SSB_PLLTYPE_2: /* 48Mhz, 4 dividers */
775 n1 += SSB_CHIPCO_CLK_T2_BIAS;
776 n2 += SSB_CHIPCO_CLK_T2_BIAS;
777 SSB_WARN_ON(!((n1 >= 2) && (n1 <= 7)));
778 SSB_WARN_ON(!((n2 >= 5) && (n2 <= 23)));
779 break;
780 case SSB_PLLTYPE_5: /* 25Mhz, 4 dividers */
781 return 100000000;
782 default:
783 SSB_WARN_ON(1);
784 }
785
786 switch (plltype) {
787 case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
788 case SSB_PLLTYPE_7: /* 25Mhz, 4 dividers */
789 clock = SSB_CHIPCO_CLK_BASE2 * n1 * n2;
790 break;
791 default:
792 clock = SSB_CHIPCO_CLK_BASE1 * n1 * n2;
793 }
794 if (!clock)
795 return 0;
796
797 m1 = (m & SSB_CHIPCO_CLK_M1);
798 m2 = ((m & SSB_CHIPCO_CLK_M2) >> SSB_CHIPCO_CLK_M2_SHIFT);
799 m3 = ((m & SSB_CHIPCO_CLK_M3) >> SSB_CHIPCO_CLK_M3_SHIFT);
800 mc = ((m & SSB_CHIPCO_CLK_MC) >> SSB_CHIPCO_CLK_MC_SHIFT);
801
802 switch (plltype) {
803 case SSB_PLLTYPE_1: /* 48Mhz base, 3 dividers */
804 case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
805 case SSB_PLLTYPE_4: /* 48Mhz, 4 dividers */
806 case SSB_PLLTYPE_7: /* 25Mhz, 4 dividers */
807 m1 = clkfactor_f6_resolve(m1);
808 if ((plltype == SSB_PLLTYPE_1) ||
809 (plltype == SSB_PLLTYPE_3))
810 m2 += SSB_CHIPCO_CLK_F5_BIAS;
811 else
812 m2 = clkfactor_f6_resolve(m2);
813 m3 = clkfactor_f6_resolve(m3);
814
815 switch (mc) {
816 case SSB_CHIPCO_CLK_MC_BYPASS:
817 return clock;
818 case SSB_CHIPCO_CLK_MC_M1:
819 return (clock / m1);
820 case SSB_CHIPCO_CLK_MC_M1M2:
821 return (clock / (m1 * m2));
822 case SSB_CHIPCO_CLK_MC_M1M2M3:
823 return (clock / (m1 * m2 * m3));
824 case SSB_CHIPCO_CLK_MC_M1M3:
825 return (clock / (m1 * m3));
826 }
827 return 0;
828 case SSB_PLLTYPE_2:
829 m1 += SSB_CHIPCO_CLK_T2_BIAS;
830 m2 += SSB_CHIPCO_CLK_T2M2_BIAS;
831 m3 += SSB_CHIPCO_CLK_T2_BIAS;
832 SSB_WARN_ON(!((m1 >= 2) && (m1 <= 7)));
833 SSB_WARN_ON(!((m2 >= 3) && (m2 <= 10)));
834 SSB_WARN_ON(!((m3 >= 2) && (m3 <= 7)));
835
836 if (!(mc & SSB_CHIPCO_CLK_T2MC_M1BYP))
837 clock /= m1;
838 if (!(mc & SSB_CHIPCO_CLK_T2MC_M2BYP))
839 clock /= m2;
840 if (!(mc & SSB_CHIPCO_CLK_T2MC_M3BYP))
841 clock /= m3;
842 return clock;
843 default:
844 SSB_WARN_ON(1);
845 }
846 return 0;
847}
848
849/* Get the current speed the backplane is running at */
850u32 ssb_clockspeed(struct ssb_bus *bus)
851{
852 u32 rate;
853 u32 plltype;
854 u32 clkctl_n, clkctl_m;
855
856 if (ssb_extif_available(&bus->extif))
857 ssb_extif_get_clockcontrol(&bus->extif, &plltype,
858 &clkctl_n, &clkctl_m);
859 else if (bus->chipco.dev)
860 ssb_chipco_get_clockcontrol(&bus->chipco, &plltype,
861 &clkctl_n, &clkctl_m);
862 else
863 return 0;
864
865 if (bus->chip_id == 0x5365) {
866 rate = 100000000;
867 } else {
868 rate = ssb_calc_clock_rate(plltype, clkctl_n, clkctl_m);
869 if (plltype == SSB_PLLTYPE_3) /* 25Mhz, 2 dividers */
870 rate /= 2;
871 }
872
873 return rate;
874}
875EXPORT_SYMBOL(ssb_clockspeed);
876
877static u32 ssb_tmslow_reject_bitmask(struct ssb_device *dev)
878{
879 /* The REJECT bit changed position in TMSLOW between
880 * Backplane revisions. */
881 switch (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV) {
882 case SSB_IDLOW_SSBREV_22:
883 return SSB_TMSLOW_REJECT_22;
884 case SSB_IDLOW_SSBREV_23:
885 return SSB_TMSLOW_REJECT_23;
886 default:
887 WARN_ON(1);
888 }
889 return (SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23);
890}
891
892int ssb_device_is_enabled(struct ssb_device *dev)
893{
894 u32 val;
895 u32 reject;
896
897 reject = ssb_tmslow_reject_bitmask(dev);
898 val = ssb_read32(dev, SSB_TMSLOW);
899 val &= SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET | reject;
900
901 return (val == SSB_TMSLOW_CLOCK);
902}
903EXPORT_SYMBOL(ssb_device_is_enabled);
904
905static void ssb_flush_tmslow(struct ssb_device *dev)
906{
907 /* Make _really_ sure the device has finished the TMSLOW
908 * register write transaction, as we risk running into
909 * a machine check exception otherwise.
910 * Do this by reading the register back to commit the
911 * PCI write and delay an additional usec for the device
912 * to react to the change. */
913 ssb_read32(dev, SSB_TMSLOW);
914 udelay(1);
915}
916
917void ssb_device_enable(struct ssb_device *dev, u32 core_specific_flags)
918{
919 u32 val;
920
921 ssb_device_disable(dev, core_specific_flags);
922 ssb_write32(dev, SSB_TMSLOW,
923 SSB_TMSLOW_RESET | SSB_TMSLOW_CLOCK |
924 SSB_TMSLOW_FGC | core_specific_flags);
925 ssb_flush_tmslow(dev);
926
927 /* Clear SERR if set. This is a hw bug workaround. */
928 if (ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_SERR)
929 ssb_write32(dev, SSB_TMSHIGH, 0);
930
931 val = ssb_read32(dev, SSB_IMSTATE);
932 if (val & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO)) {
933 val &= ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO);
934 ssb_write32(dev, SSB_IMSTATE, val);
935 }
936
937 ssb_write32(dev, SSB_TMSLOW,
938 SSB_TMSLOW_CLOCK | SSB_TMSLOW_FGC |
939 core_specific_flags);
940 ssb_flush_tmslow(dev);
941
942 ssb_write32(dev, SSB_TMSLOW, SSB_TMSLOW_CLOCK |
943 core_specific_flags);
944 ssb_flush_tmslow(dev);
945}
946EXPORT_SYMBOL(ssb_device_enable);
947
948/* Wait for a bit in a register to get set or unset.
949 * timeout is in units of ten-microseconds */
950static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask,
951 int timeout, int set)
952{
953 int i;
954 u32 val;
955
956 for (i = 0; i < timeout; i++) {
957 val = ssb_read32(dev, reg);
958 if (set) {
959 if (val & bitmask)
960 return 0;
961 } else {
962 if (!(val & bitmask))
963 return 0;
964 }
965 udelay(10);
966 }
967 printk(KERN_ERR PFX "Timeout waiting for bitmask %08X on "
968 "register %04X to %s.\n",
969 bitmask, reg, (set ? "set" : "clear"));
970
971 return -ETIMEDOUT;
972}
973
974void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags)
975{
976 u32 reject;
977
978 if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET)
979 return;
980
981 reject = ssb_tmslow_reject_bitmask(dev);
982 ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK);
983 ssb_wait_bit(dev, SSB_TMSLOW, reject, 1000, 1);
984 ssb_wait_bit(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0);
985 ssb_write32(dev, SSB_TMSLOW,
986 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
987 reject | SSB_TMSLOW_RESET |
988 core_specific_flags);
989 ssb_flush_tmslow(dev);
990
991 ssb_write32(dev, SSB_TMSLOW,
992 reject | SSB_TMSLOW_RESET |
993 core_specific_flags);
994 ssb_flush_tmslow(dev);
995}
996EXPORT_SYMBOL(ssb_device_disable);
997
998u32 ssb_dma_translation(struct ssb_device *dev)
999{
1000 switch (dev->bus->bustype) {
1001 case SSB_BUSTYPE_SSB:
1002 return 0;
1003 case SSB_BUSTYPE_PCI:
1004 case SSB_BUSTYPE_PCMCIA:
1005 return SSB_PCI_DMA;
1006 }
1007 return 0;
1008}
1009EXPORT_SYMBOL(ssb_dma_translation);
1010
1011int ssb_dma_set_mask(struct ssb_device *ssb_dev, u64 mask)
1012{
1013 struct device *dev = ssb_dev->dev;
1014
1015#ifdef CONFIG_SSB_PCIHOST
1016 if (ssb_dev->bus->bustype == SSB_BUSTYPE_PCI &&
1017 !dma_supported(dev, mask))
1018 return -EIO;
1019#endif
1020 dev->coherent_dma_mask = mask;
1021 dev->dma_mask = &dev->coherent_dma_mask;
1022
1023 return 0;
1024}
1025EXPORT_SYMBOL(ssb_dma_set_mask);
1026
1027int ssb_bus_may_powerdown(struct ssb_bus *bus)
1028{
1029 struct ssb_chipcommon *cc;
1030 int err = 0;
1031
1032 /* On buses where more than one core may be working
1033 * at a time, we must not powerdown stuff if there are
1034 * still cores that may want to run. */
1035 if (bus->bustype == SSB_BUSTYPE_SSB)
1036 goto out;
1037
1038 cc = &bus->chipco;
1039 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_SLOW);
1040 err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
1041 if (err)
1042 goto error;
1043out:
1044#ifdef CONFIG_SSB_DEBUG
1045 bus->powered_up = 0;
1046#endif
1047 return err;
1048error:
1049 ssb_printk(KERN_ERR PFX "Bus powerdown failed\n");
1050 goto out;
1051}
1052EXPORT_SYMBOL(ssb_bus_may_powerdown);
1053
1054int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl)
1055{
1056 struct ssb_chipcommon *cc;
1057 int err;
1058 enum ssb_clkmode mode;
1059
1060 err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
1061 if (err)
1062 goto error;
1063 cc = &bus->chipco;
1064 mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST;
1065 ssb_chipco_set_clockmode(cc, mode);
1066
1067#ifdef CONFIG_SSB_DEBUG
1068 bus->powered_up = 1;
1069#endif
1070 return 0;
1071error:
1072 ssb_printk(KERN_ERR PFX "Bus powerup failed\n");
1073 return err;
1074}
1075EXPORT_SYMBOL(ssb_bus_powerup);
1076
1077u32 ssb_admatch_base(u32 adm)
1078{
1079 u32 base = 0;
1080
1081 switch (adm & SSB_ADM_TYPE) {
1082 case SSB_ADM_TYPE0:
1083 base = (adm & SSB_ADM_BASE0);
1084 break;
1085 case SSB_ADM_TYPE1:
1086 SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
1087 base = (adm & SSB_ADM_BASE1);
1088 break;
1089 case SSB_ADM_TYPE2:
1090 SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
1091 base = (adm & SSB_ADM_BASE2);
1092 break;
1093 default:
1094 SSB_WARN_ON(1);
1095 }
1096
1097 return base;
1098}
1099EXPORT_SYMBOL(ssb_admatch_base);
1100
1101u32 ssb_admatch_size(u32 adm)
1102{
1103 u32 size = 0;
1104
1105 switch (adm & SSB_ADM_TYPE) {
1106 case SSB_ADM_TYPE0:
1107 size = ((adm & SSB_ADM_SZ0) >> SSB_ADM_SZ0_SHIFT);
1108 break;
1109 case SSB_ADM_TYPE1:
1110 SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
1111 size = ((adm & SSB_ADM_SZ1) >> SSB_ADM_SZ1_SHIFT);
1112 break;
1113 case SSB_ADM_TYPE2:
1114 SSB_WARN_ON(adm & SSB_ADM_NEG); /* unsupported */
1115 size = ((adm & SSB_ADM_SZ2) >> SSB_ADM_SZ2_SHIFT);
1116 break;
1117 default:
1118 SSB_WARN_ON(1);
1119 }
1120 size = (1 << (size + 1));
1121
1122 return size;
1123}
1124EXPORT_SYMBOL(ssb_admatch_size);
1125
1126static int __init ssb_modinit(void)
1127{
1128 int err;
1129
1130 /* See the comment at the ssb_is_early_boot definition */
1131 ssb_is_early_boot = 0;
1132 err = bus_register(&ssb_bustype);
1133 if (err)
1134 return err;
1135
1136 /* Maybe we already registered some buses at early boot.
1137 * Check for this and attach them
1138 */
1139 ssb_buses_lock();
1140 err = ssb_attach_queued_buses();
1141 ssb_buses_unlock();
1142 if (err)
1143 bus_unregister(&ssb_bustype);
1144
1145 err = b43_pci_ssb_bridge_init();
1146 if (err) {
1147 ssb_printk(KERN_ERR "Broadcom 43xx PCI-SSB-bridge "
1148 "initialization failed");
1149 /* don't fail SSB init because of this */
1150 err = 0;
1151 }
1152
1153 return err;
1154}
1155subsys_initcall(ssb_modinit);
1156
1157static void __exit ssb_modexit(void)
1158{
1159 b43_pci_ssb_bridge_exit();
1160 bus_unregister(&ssb_bustype);
1161}
1162module_exit(ssb_modexit)
diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
new file mode 100644
index 00000000000..3d23ca4befe
--- /dev/null
+++ b/drivers/ssb/pci.c
@@ -0,0 +1,740 @@
1/*
2 * Sonics Silicon Backplane PCI-Hostbus related functions.
3 *
4 * Copyright (C) 2005-2006 Michael Buesch <mb@bu3sch.de>
5 * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
6 * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
7 * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
8 * Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
9 *
10 * Derived from the Broadcom 4400 device driver.
11 * Copyright (C) 2002 David S. Miller (davem@redhat.com)
12 * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
13 * Copyright (C) 2006 Broadcom Corporation.
14 *
15 * Licensed under the GNU/GPL. See COPYING for details.
16 */
17
18#include <linux/ssb/ssb.h>
19#include <linux/ssb/ssb_regs.h>
20#include <linux/pci.h>
21#include <linux/delay.h>
22
23#include "ssb_private.h"
24
25
26/* Define the following to 1 to enable a printk on each coreswitch. */
27#define SSB_VERBOSE_PCICORESWITCH_DEBUG 0
28
29
30/* Lowlevel coreswitching */
31int ssb_pci_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
32{
33 int err;
34 int attempts = 0;
35 u32 cur_core;
36
37 while (1) {
38 err = pci_write_config_dword(bus->host_pci, SSB_BAR0_WIN,
39 (coreidx * SSB_CORE_SIZE)
40 + SSB_ENUM_BASE);
41 if (err)
42 goto error;
43 err = pci_read_config_dword(bus->host_pci, SSB_BAR0_WIN,
44 &cur_core);
45 if (err)
46 goto error;
47 cur_core = (cur_core - SSB_ENUM_BASE)
48 / SSB_CORE_SIZE;
49 if (cur_core == coreidx)
50 break;
51
52 if (attempts++ > SSB_BAR0_MAX_RETRIES)
53 goto error;
54 udelay(10);
55 }
56 return 0;
57error:
58 ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
59 return -ENODEV;
60}
61
62int ssb_pci_switch_core(struct ssb_bus *bus,
63 struct ssb_device *dev)
64{
65 int err;
66 unsigned long flags;
67
68#if SSB_VERBOSE_PCICORESWITCH_DEBUG
69 ssb_printk(KERN_INFO PFX
70 "Switching to %s core, index %d\n",
71 ssb_core_name(dev->id.coreid),
72 dev->core_index);
73#endif
74
75 spin_lock_irqsave(&bus->bar_lock, flags);
76 err = ssb_pci_switch_coreidx(bus, dev->core_index);
77 if (!err)
78 bus->mapped_device = dev;
79 spin_unlock_irqrestore(&bus->bar_lock, flags);
80
81 return err;
82}
83
84/* Enable/disable the on board crystal oscillator and/or PLL. */
85int ssb_pci_xtal(struct ssb_bus *bus, u32 what, int turn_on)
86{
87 int err;
88 u32 in, out, outenable;
89 u16 pci_status;
90
91 if (bus->bustype != SSB_BUSTYPE_PCI)
92 return 0;
93
94 err = pci_read_config_dword(bus->host_pci, SSB_GPIO_IN, &in);
95 if (err)
96 goto err_pci;
97 err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT, &out);
98 if (err)
99 goto err_pci;
100 err = pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, &outenable);
101 if (err)
102 goto err_pci;
103
104 outenable |= what;
105
106 if (turn_on) {
107 /* Avoid glitching the clock if GPRS is already using it.
108 * We can't actually read the state of the PLLPD so we infer it
109 * by the value of XTAL_PU which *is* readable via gpioin.
110 */
111 if (!(in & SSB_GPIO_XTAL)) {
112 if (what & SSB_GPIO_XTAL) {
113 /* Turn the crystal on */
114 out |= SSB_GPIO_XTAL;
115 if (what & SSB_GPIO_PLL)
116 out |= SSB_GPIO_PLL;
117 err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
118 if (err)
119 goto err_pci;
120 err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE,
121 outenable);
122 if (err)
123 goto err_pci;
124 msleep(1);
125 }
126 if (what & SSB_GPIO_PLL) {
127 /* Turn the PLL on */
128 out &= ~SSB_GPIO_PLL;
129 err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
130 if (err)
131 goto err_pci;
132 msleep(5);
133 }
134 }
135
136 err = pci_read_config_word(bus->host_pci, PCI_STATUS, &pci_status);
137 if (err)
138 goto err_pci;
139 pci_status &= ~PCI_STATUS_SIG_TARGET_ABORT;
140 err = pci_write_config_word(bus->host_pci, PCI_STATUS, pci_status);
141 if (err)
142 goto err_pci;
143 } else {
144 if (what & SSB_GPIO_XTAL) {
145 /* Turn the crystal off */
146 out &= ~SSB_GPIO_XTAL;
147 }
148 if (what & SSB_GPIO_PLL) {
149 /* Turn the PLL off */
150 out |= SSB_GPIO_PLL;
151 }
152 err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT, out);
153 if (err)
154 goto err_pci;
155 err = pci_write_config_dword(bus->host_pci, SSB_GPIO_OUT_ENABLE, outenable);
156 if (err)
157 goto err_pci;
158 }
159
160out:
161 return err;
162
163err_pci:
164 printk(KERN_ERR PFX "Error: ssb_pci_xtal() could not access PCI config space!\n");
165 err = -EBUSY;
166 goto out;
167}
168
169/* Get the word-offset for a SSB_SPROM_XXX define. */
170#define SPOFF(offset) (((offset) - SSB_SPROM_BASE) / sizeof(u16))
171/* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
172#define SPEX(_outvar, _offset, _mask, _shift) \
173 out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
174
175static inline u8 ssb_crc8(u8 crc, u8 data)
176{
177 /* Polynomial: x^8 + x^7 + x^6 + x^4 + x^2 + 1 */
178 static const u8 t[] = {
179 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
180 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
181 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
182 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
183 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
184 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
185 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
186 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
187 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
188 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
189 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
190 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
191 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
192 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
193 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
194 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
195 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
196 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
197 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
198 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
199 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
200 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
201 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
202 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
203 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
204 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
205 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
206 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
207 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
208 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
209 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
210 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
211 };
212 return t[crc ^ data];
213}
214
215static u8 ssb_sprom_crc(const u16 *sprom)
216{
217 int word;
218 u8 crc = 0xFF;
219
220 for (word = 0; word < SSB_SPROMSIZE_WORDS - 1; word++) {
221 crc = ssb_crc8(crc, sprom[word] & 0x00FF);
222 crc = ssb_crc8(crc, (sprom[word] & 0xFF00) >> 8);
223 }
224 crc = ssb_crc8(crc, sprom[SPOFF(SSB_SPROM_REVISION)] & 0x00FF);
225 crc ^= 0xFF;
226
227 return crc;
228}
229
230static int sprom_check_crc(const u16 *sprom)
231{
232 u8 crc;
233 u8 expected_crc;
234 u16 tmp;
235
236 crc = ssb_sprom_crc(sprom);
237 tmp = sprom[SPOFF(SSB_SPROM_REVISION)] & SSB_SPROM_REVISION_CRC;
238 expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
239 if (crc != expected_crc)
240 return -EPROTO;
241
242 return 0;
243}
244
245static void sprom_do_read(struct ssb_bus *bus, u16 *sprom)
246{
247 int i;
248
249 for (i = 0; i < SSB_SPROMSIZE_WORDS; i++)
250 sprom[i] = readw(bus->mmio + SSB_SPROM_BASE + (i * 2));
251}
252
253static int sprom_do_write(struct ssb_bus *bus, const u16 *sprom)
254{
255 struct pci_dev *pdev = bus->host_pci;
256 int i, err;
257 u32 spromctl;
258
259 ssb_printk(KERN_NOTICE PFX "Writing SPROM. Do NOT turn off the power! Please stand by...\n");
260 err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
261 if (err)
262 goto err_ctlreg;
263 spromctl |= SSB_SPROMCTL_WE;
264 err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl);
265 if (err)
266 goto err_ctlreg;
267 ssb_printk(KERN_NOTICE PFX "[ 0%%");
268 msleep(500);
269 for (i = 0; i < SSB_SPROMSIZE_WORDS; i++) {
270 if (i == SSB_SPROMSIZE_WORDS / 4)
271 ssb_printk("25%%");
272 else if (i == SSB_SPROMSIZE_WORDS / 2)
273 ssb_printk("50%%");
274 else if (i == (SSB_SPROMSIZE_WORDS / 4) * 3)
275 ssb_printk("75%%");
276 else if (i % 2)
277 ssb_printk(".");
278 writew(sprom[i], bus->mmio + SSB_SPROM_BASE + (i * 2));
279 mmiowb();
280 msleep(20);
281 }
282 err = pci_read_config_dword(pdev, SSB_SPROMCTL, &spromctl);
283 if (err)
284 goto err_ctlreg;
285 spromctl &= ~SSB_SPROMCTL_WE;
286 err = pci_write_config_dword(pdev, SSB_SPROMCTL, spromctl);
287 if (err)
288 goto err_ctlreg;
289 msleep(500);
290 ssb_printk("100%% ]\n");
291 ssb_printk(KERN_NOTICE PFX "SPROM written.\n");
292
293 return 0;
294err_ctlreg:
295 ssb_printk(KERN_ERR PFX "Could not access SPROM control register.\n");
296 return err;
297}
298
299static void sprom_extract_r1(struct ssb_sprom_r1 *out, const u16 *in)
300{
301 int i;
302 u16 v;
303
304 SPEX(pci_spid, SSB_SPROM1_SPID, 0xFFFF, 0);
305 SPEX(pci_svid, SSB_SPROM1_SVID, 0xFFFF, 0);
306 SPEX(pci_pid, SSB_SPROM1_PID, 0xFFFF, 0);
307 for (i = 0; i < 3; i++) {
308 v = in[SPOFF(SSB_SPROM1_IL0MAC) + i];
309 *(((u16 *)out->il0mac) + i) = cpu_to_be16(v);
310 }
311 for (i = 0; i < 3; i++) {
312 v = in[SPOFF(SSB_SPROM1_ET0MAC) + i];
313 *(((u16 *)out->et0mac) + i) = cpu_to_be16(v);
314 }
315 for (i = 0; i < 3; i++) {
316 v = in[SPOFF(SSB_SPROM1_ET1MAC) + i];
317 *(((u16 *)out->et1mac) + i) = cpu_to_be16(v);
318 }
319 SPEX(et0phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0A, 0);
320 SPEX(et1phyaddr, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1A,
321 SSB_SPROM1_ETHPHY_ET1A_SHIFT);
322 SPEX(et0mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET0M, 14);
323 SPEX(et1mdcport, SSB_SPROM1_ETHPHY, SSB_SPROM1_ETHPHY_ET1M, 15);
324 SPEX(board_rev, SSB_SPROM1_BINF, SSB_SPROM1_BINF_BREV, 0);
325 SPEX(country_code, SSB_SPROM1_BINF, SSB_SPROM1_BINF_CCODE,
326 SSB_SPROM1_BINF_CCODE_SHIFT);
327 SPEX(antenna_a, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTA,
328 SSB_SPROM1_BINF_ANTA_SHIFT);
329 SPEX(antenna_bg, SSB_SPROM1_BINF, SSB_SPROM1_BINF_ANTBG,
330 SSB_SPROM1_BINF_ANTBG_SHIFT);
331 SPEX(pa0b0, SSB_SPROM1_PA0B0, 0xFFFF, 0);
332 SPEX(pa0b1, SSB_SPROM1_PA0B1, 0xFFFF, 0);
333 SPEX(pa0b2, SSB_SPROM1_PA0B2, 0xFFFF, 0);
334 SPEX(pa1b0, SSB_SPROM1_PA1B0, 0xFFFF, 0);
335 SPEX(pa1b1, SSB_SPROM1_PA1B1, 0xFFFF, 0);
336 SPEX(pa1b2, SSB_SPROM1_PA1B2, 0xFFFF, 0);
337 SPEX(gpio0, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P0, 0);
338 SPEX(gpio1, SSB_SPROM1_GPIOA, SSB_SPROM1_GPIOA_P1,
339 SSB_SPROM1_GPIOA_P1_SHIFT);
340 SPEX(gpio2, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P2, 0);
341 SPEX(gpio3, SSB_SPROM1_GPIOB, SSB_SPROM1_GPIOB_P3,
342 SSB_SPROM1_GPIOB_P3_SHIFT);
343 SPEX(maxpwr_a, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_A,
344 SSB_SPROM1_MAXPWR_A_SHIFT);
345 SPEX(maxpwr_bg, SSB_SPROM1_MAXPWR, SSB_SPROM1_MAXPWR_BG, 0);
346 SPEX(itssi_a, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_A,
347 SSB_SPROM1_ITSSI_A_SHIFT);
348 SPEX(itssi_bg, SSB_SPROM1_ITSSI, SSB_SPROM1_ITSSI_BG, 0);
349 SPEX(boardflags_lo, SSB_SPROM1_BFLLO, 0xFFFF, 0);
350 SPEX(antenna_gain_a, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_A, 0);
351 SPEX(antenna_gain_bg, SSB_SPROM1_AGAIN, SSB_SPROM1_AGAIN_BG,
352 SSB_SPROM1_AGAIN_BG_SHIFT);
353 for (i = 0; i < 4; i++) {
354 v = in[SPOFF(SSB_SPROM1_OEM) + i];
355 *(((u16 *)out->oem) + i) = cpu_to_le16(v);
356 }
357}
358
359static void sprom_extract_r2(struct ssb_sprom_r2 *out, const u16 *in)
360{
361 int i;
362 u16 v;
363
364 SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
365 SPEX(maxpwr_a_hi, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_HI, 0);
366 SPEX(maxpwr_a_lo, SSB_SPROM2_MAXP_A, SSB_SPROM2_MAXP_A_LO,
367 SSB_SPROM2_MAXP_A_LO_SHIFT);
368 SPEX(pa1lob0, SSB_SPROM2_PA1LOB0, 0xFFFF, 0);
369 SPEX(pa1lob1, SSB_SPROM2_PA1LOB1, 0xFFFF, 0);
370 SPEX(pa1lob2, SSB_SPROM2_PA1LOB2, 0xFFFF, 0);
371 SPEX(pa1hib0, SSB_SPROM2_PA1HIB0, 0xFFFF, 0);
372 SPEX(pa1hib1, SSB_SPROM2_PA1HIB1, 0xFFFF, 0);
373 SPEX(pa1hib2, SSB_SPROM2_PA1HIB2, 0xFFFF, 0);
374 SPEX(ofdm_pwr_off, SSB_SPROM2_OPO, SSB_SPROM2_OPO_VALUE, 0);
375 for (i = 0; i < 4; i++) {
376 v = in[SPOFF(SSB_SPROM2_CCODE) + i];
377 *(((u16 *)out->country_str) + i) = cpu_to_le16(v);
378 }
379}
380
381static void sprom_extract_r3(struct ssb_sprom_r3 *out, const u16 *in)
382{
383 out->ofdmapo = (in[SPOFF(SSB_SPROM3_OFDMAPO) + 0] & 0xFF00) >> 8;
384 out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 0] & 0x00FF) << 8;
385 out->ofdmapo <<= 16;
386 out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 1] & 0xFF00) >> 8;
387 out->ofdmapo |= (in[SPOFF(SSB_SPROM3_OFDMAPO) + 1] & 0x00FF) << 8;
388
389 out->ofdmalpo = (in[SPOFF(SSB_SPROM3_OFDMALPO) + 0] & 0xFF00) >> 8;
390 out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 0] & 0x00FF) << 8;
391 out->ofdmalpo <<= 16;
392 out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 1] & 0xFF00) >> 8;
393 out->ofdmalpo |= (in[SPOFF(SSB_SPROM3_OFDMALPO) + 1] & 0x00FF) << 8;
394
395 out->ofdmahpo = (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 0] & 0xFF00) >> 8;
396 out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 0] & 0x00FF) << 8;
397 out->ofdmahpo <<= 16;
398 out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 1] & 0xFF00) >> 8;
399 out->ofdmahpo |= (in[SPOFF(SSB_SPROM3_OFDMAHPO) + 1] & 0x00FF) << 8;
400
401 SPEX(gpioldc_on_cnt, SSB_SPROM3_GPIOLDC, SSB_SPROM3_GPIOLDC_ON,
402 SSB_SPROM3_GPIOLDC_ON_SHIFT);
403 SPEX(gpioldc_off_cnt, SSB_SPROM3_GPIOLDC, SSB_SPROM3_GPIOLDC_OFF,
404 SSB_SPROM3_GPIOLDC_OFF_SHIFT);
405 SPEX(cckpo_1M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_1M, 0);
406 SPEX(cckpo_2M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_2M,
407 SSB_SPROM3_CCKPO_2M_SHIFT);
408 SPEX(cckpo_55M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_55M,
409 SSB_SPROM3_CCKPO_55M_SHIFT);
410 SPEX(cckpo_11M, SSB_SPROM3_CCKPO, SSB_SPROM3_CCKPO_11M,
411 SSB_SPROM3_CCKPO_11M_SHIFT);
412
413 out->ofdmgpo = (in[SPOFF(SSB_SPROM3_OFDMGPO) + 0] & 0xFF00) >> 8;
414 out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 0] & 0x00FF) << 8;
415 out->ofdmgpo <<= 16;
416 out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0xFF00) >> 8;
417 out->ofdmgpo |= (in[SPOFF(SSB_SPROM3_OFDMGPO) + 1] & 0x00FF) << 8;
418}
419
420static int sprom_extract(struct ssb_bus *bus,
421 struct ssb_sprom *out, const u16 *in)
422{
423 memset(out, 0, sizeof(*out));
424
425 SPEX(revision, SSB_SPROM_REVISION, SSB_SPROM_REVISION_REV, 0);
426 SPEX(crc, SSB_SPROM_REVISION, SSB_SPROM_REVISION_CRC,
427 SSB_SPROM_REVISION_CRC_SHIFT);
428
429 if ((bus->chip_id & 0xFF00) == 0x4400) {
430 /* Workaround: The BCM44XX chip has a stupid revision
431 * number stored in the SPROM.
432 * Always extract r1. */
433 sprom_extract_r1(&out->r1, in);
434 } else {
435 if (out->revision == 0)
436 goto unsupported;
437 if (out->revision >= 1 && out->revision <= 3)
438 sprom_extract_r1(&out->r1, in);
439 if (out->revision >= 2 && out->revision <= 3)
440 sprom_extract_r2(&out->r2, in);
441 if (out->revision == 3)
442 sprom_extract_r3(&out->r3, in);
443 if (out->revision >= 4)
444 goto unsupported;
445 }
446
447 return 0;
448unsupported:
449 ssb_printk(KERN_WARNING PFX "Unsupported SPROM revision %d "
450 "detected. Will extract v1\n", out->revision);
451 sprom_extract_r1(&out->r1, in);
452 return 0;
453}
454
455static int ssb_pci_sprom_get(struct ssb_bus *bus,
456 struct ssb_sprom *sprom)
457{
458 int err = -ENOMEM;
459 u16 *buf;
460
461 buf = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL);
462 if (!buf)
463 goto out;
464 sprom_do_read(bus, buf);
465 err = sprom_check_crc(buf);
466 if (err) {
467 ssb_printk(KERN_WARNING PFX
468 "WARNING: Invalid SPROM CRC (corrupt SPROM)\n");
469 }
470 err = sprom_extract(bus, sprom, buf);
471
472 kfree(buf);
473out:
474 return err;
475}
476
477static void ssb_pci_get_boardinfo(struct ssb_bus *bus,
478 struct ssb_boardinfo *bi)
479{
480 pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_VENDOR_ID,
481 &bi->vendor);
482 pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_ID,
483 &bi->type);
484 pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
485 &bi->rev);
486}
487
488int ssb_pci_get_invariants(struct ssb_bus *bus,
489 struct ssb_init_invariants *iv)
490{
491 int err;
492
493 err = ssb_pci_sprom_get(bus, &iv->sprom);
494 if (err)
495 goto out;
496 ssb_pci_get_boardinfo(bus, &iv->boardinfo);
497
498out:
499 return err;
500}
501
502#ifdef CONFIG_SSB_DEBUG
503static int ssb_pci_assert_buspower(struct ssb_bus *bus)
504{
505 if (likely(bus->powered_up))
506 return 0;
507
508 printk(KERN_ERR PFX "FATAL ERROR: Bus powered down "
509 "while accessing PCI MMIO space\n");
510 if (bus->power_warn_count <= 10) {
511 bus->power_warn_count++;
512 dump_stack();
513 }
514
515 return -ENODEV;
516}
517#else /* DEBUG */
518static inline int ssb_pci_assert_buspower(struct ssb_bus *bus)
519{
520 return 0;
521}
522#endif /* DEBUG */
523
524static u16 ssb_pci_read16(struct ssb_device *dev, u16 offset)
525{
526 struct ssb_bus *bus = dev->bus;
527
528 if (unlikely(ssb_pci_assert_buspower(bus)))
529 return 0xFFFF;
530 if (unlikely(bus->mapped_device != dev)) {
531 if (unlikely(ssb_pci_switch_core(bus, dev)))
532 return 0xFFFF;
533 }
534 return readw(bus->mmio + offset);
535}
536
537static u32 ssb_pci_read32(struct ssb_device *dev, u16 offset)
538{
539 struct ssb_bus *bus = dev->bus;
540
541 if (unlikely(ssb_pci_assert_buspower(bus)))
542 return 0xFFFFFFFF;
543 if (unlikely(bus->mapped_device != dev)) {
544 if (unlikely(ssb_pci_switch_core(bus, dev)))
545 return 0xFFFFFFFF;
546 }
547 return readl(bus->mmio + offset);
548}
549
550static void ssb_pci_write16(struct ssb_device *dev, u16 offset, u16 value)
551{
552 struct ssb_bus *bus = dev->bus;
553
554 if (unlikely(ssb_pci_assert_buspower(bus)))
555 return;
556 if (unlikely(bus->mapped_device != dev)) {
557 if (unlikely(ssb_pci_switch_core(bus, dev)))
558 return;
559 }
560 writew(value, bus->mmio + offset);
561}
562
563static void ssb_pci_write32(struct ssb_device *dev, u16 offset, u32 value)
564{
565 struct ssb_bus *bus = dev->bus;
566
567 if (unlikely(ssb_pci_assert_buspower(bus)))
568 return;
569 if (unlikely(bus->mapped_device != dev)) {
570 if (unlikely(ssb_pci_switch_core(bus, dev)))
571 return;
572 }
573 writel(value, bus->mmio + offset);
574}
575
576/* Not "static", as it's used in main.c */
577const struct ssb_bus_ops ssb_pci_ops = {
578 .read16 = ssb_pci_read16,
579 .read32 = ssb_pci_read32,
580 .write16 = ssb_pci_write16,
581 .write32 = ssb_pci_write32,
582};
583
584static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len)
585{
586 int i, pos = 0;
587
588 for (i = 0; i < SSB_SPROMSIZE_WORDS; i++) {
589 pos += snprintf(buf + pos, buf_len - pos - 1,
590 "%04X", swab16(sprom[i]) & 0xFFFF);
591 }
592 pos += snprintf(buf + pos, buf_len - pos - 1, "\n");
593
594 return pos + 1;
595}
596
597static int hex2sprom(u16 *sprom, const char *dump, size_t len)
598{
599 char tmp[5] = { 0 };
600 int cnt = 0;
601 unsigned long parsed;
602
603 if (len < SSB_SPROMSIZE_BYTES * 2)
604 return -EINVAL;
605
606 while (cnt < SSB_SPROMSIZE_WORDS) {
607 memcpy(tmp, dump, 4);
608 dump += 4;
609 parsed = simple_strtoul(tmp, NULL, 16);
610 sprom[cnt++] = swab16((u16)parsed);
611 }
612
613 return 0;
614}
615
616static ssize_t ssb_pci_attr_sprom_show(struct device *pcidev,
617 struct device_attribute *attr,
618 char *buf)
619{
620 struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
621 struct ssb_bus *bus;
622 u16 *sprom;
623 int err = -ENODEV;
624 ssize_t count = 0;
625
626 bus = ssb_pci_dev_to_bus(pdev);
627 if (!bus)
628 goto out;
629 err = -ENOMEM;
630 sprom = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL);
631 if (!sprom)
632 goto out;
633
634 /* Use interruptible locking, as the SPROM write might
635 * be holding the lock for several seconds. So allow userspace
636 * to cancel operation. */
637 err = -ERESTARTSYS;
638 if (mutex_lock_interruptible(&bus->pci_sprom_mutex))
639 goto out_kfree;
640 sprom_do_read(bus, sprom);
641 mutex_unlock(&bus->pci_sprom_mutex);
642
643 count = sprom2hex(sprom, buf, PAGE_SIZE);
644 err = 0;
645
646out_kfree:
647 kfree(sprom);
648out:
649 return err ? err : count;
650}
651
652static ssize_t ssb_pci_attr_sprom_store(struct device *pcidev,
653 struct device_attribute *attr,
654 const char *buf, size_t count)
655{
656 struct pci_dev *pdev = container_of(pcidev, struct pci_dev, dev);
657 struct ssb_bus *bus;
658 u16 *sprom;
659 int res = 0, err = -ENODEV;
660
661 bus = ssb_pci_dev_to_bus(pdev);
662 if (!bus)
663 goto out;
664 err = -ENOMEM;
665 sprom = kcalloc(SSB_SPROMSIZE_WORDS, sizeof(u16), GFP_KERNEL);
666 if (!sprom)
667 goto out;
668 err = hex2sprom(sprom, buf, count);
669 if (err) {
670 err = -EINVAL;
671 goto out_kfree;
672 }
673 err = sprom_check_crc(sprom);
674 if (err) {
675 err = -EINVAL;
676 goto out_kfree;
677 }
678
679 /* Use interruptible locking, as the SPROM write might
680 * be holding the lock for several seconds. So allow userspace
681 * to cancel operation. */
682 err = -ERESTARTSYS;
683 if (mutex_lock_interruptible(&bus->pci_sprom_mutex))
684 goto out_kfree;
685 err = ssb_devices_freeze(bus);
686 if (err == -EOPNOTSUPP) {
687 ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze devices. "
688 "No suspend support. Is CONFIG_PM enabled?\n");
689 goto out_unlock;
690 }
691 if (err) {
692 ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze all devices\n");
693 goto out_unlock;
694 }
695 res = sprom_do_write(bus, sprom);
696 err = ssb_devices_thaw(bus);
697 if (err)
698 ssb_printk(KERN_ERR PFX "SPROM write: Could not thaw all devices\n");
699out_unlock:
700 mutex_unlock(&bus->pci_sprom_mutex);
701out_kfree:
702 kfree(sprom);
703out:
704 if (res)
705 return res;
706 return err ? err : count;
707}
708
709static DEVICE_ATTR(ssb_sprom, 0600,
710 ssb_pci_attr_sprom_show,
711 ssb_pci_attr_sprom_store);
712
713void ssb_pci_exit(struct ssb_bus *bus)
714{
715 struct pci_dev *pdev;
716
717 if (bus->bustype != SSB_BUSTYPE_PCI)
718 return;
719
720 pdev = bus->host_pci;
721 device_remove_file(&pdev->dev, &dev_attr_ssb_sprom);
722}
723
724int ssb_pci_init(struct ssb_bus *bus)
725{
726 struct pci_dev *pdev;
727 int err;
728
729 if (bus->bustype != SSB_BUSTYPE_PCI)
730 return 0;
731
732 pdev = bus->host_pci;
733 mutex_init(&bus->pci_sprom_mutex);
734 err = device_create_file(&pdev->dev, &dev_attr_ssb_sprom);
735 if (err)
736 goto out;
737
738out:
739 return err;
740}
diff --git a/drivers/ssb/pcihost_wrapper.c b/drivers/ssb/pcihost_wrapper.c
new file mode 100644
index 00000000000..82a10abef64
--- /dev/null
+++ b/drivers/ssb/pcihost_wrapper.c
@@ -0,0 +1,104 @@
1/*
2 * Sonics Silicon Backplane
3 * PCI Hostdevice wrapper
4 *
5 * Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>
6 * Copyright (c) 2005 Stefano Brivio <st3@riseup.net>
7 * Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
8 * Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
9 * Copyright (c) 2005-2007 Michael Buesch <mbuesch@freenet.de>
10 *
11 * Licensed under the GNU/GPL. See COPYING for details.
12 */
13
14#include <linux/pci.h>
15#include <linux/ssb/ssb.h>
16
17
18#ifdef CONFIG_PM
19static int ssb_pcihost_suspend(struct pci_dev *dev, pm_message_t state)
20{
21 pci_save_state(dev);
22 pci_disable_device(dev);
23 pci_set_power_state(dev, pci_choose_state(dev, state));
24
25 return 0;
26}
27
28static int ssb_pcihost_resume(struct pci_dev *dev)
29{
30 int err;
31
32 pci_set_power_state(dev, 0);
33 err = pci_enable_device(dev);
34 if (err)
35 return err;
36 pci_restore_state(dev);
37
38 return 0;
39}
40#else /* CONFIG_PM */
41# define ssb_pcihost_suspend NULL
42# define ssb_pcihost_resume NULL
43#endif /* CONFIG_PM */
44
45static int ssb_pcihost_probe(struct pci_dev *dev,
46 const struct pci_device_id *id)
47{
48 struct ssb_bus *ssb;
49 int err = -ENOMEM;
50 const char *name;
51
52 ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
53 if (!ssb)
54 goto out;
55 err = pci_enable_device(dev);
56 if (err)
57 goto err_kfree_ssb;
58 name = dev->dev.bus_id;
59 if (dev->driver && dev->driver->name)
60 name = dev->driver->name;
61 err = pci_request_regions(dev, name);
62 if (err)
63 goto err_pci_disable;
64 pci_set_master(dev);
65
66 err = ssb_bus_pcibus_register(ssb, dev);
67 if (err)
68 goto err_pci_release_regions;
69
70 pci_set_drvdata(dev, ssb);
71
72out:
73 return err;
74
75err_pci_release_regions:
76 pci_release_regions(dev);
77err_pci_disable:
78 pci_disable_device(dev);
79err_kfree_ssb:
80 kfree(ssb);
81 return err;
82}
83
84static void ssb_pcihost_remove(struct pci_dev *dev)
85{
86 struct ssb_bus *ssb = pci_get_drvdata(dev);
87
88 ssb_bus_unregister(ssb);
89 pci_release_regions(dev);
90 pci_disable_device(dev);
91 kfree(ssb);
92 pci_set_drvdata(dev, NULL);
93}
94
95int ssb_pcihost_register(struct pci_driver *driver)
96{
97 driver->probe = ssb_pcihost_probe;
98 driver->remove = ssb_pcihost_remove;
99 driver->suspend = ssb_pcihost_suspend;
100 driver->resume = ssb_pcihost_resume;
101
102 return pci_register_driver(driver);
103}
104EXPORT_SYMBOL(ssb_pcihost_register);
diff --git a/drivers/ssb/pcmcia.c b/drivers/ssb/pcmcia.c
new file mode 100644
index 00000000000..7c773603b40
--- /dev/null
+++ b/drivers/ssb/pcmcia.c
@@ -0,0 +1,271 @@
1/*
2 * Sonics Silicon Backplane
3 * PCMCIA-Hostbus related functions
4 *
5 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
6 * Copyright 2007 Michael Buesch <mb@bu3sch.de>
7 *
8 * Licensed under the GNU/GPL. See COPYING for details.
9 */
10
11#include <linux/ssb/ssb.h>
12#include <linux/delay.h>
13
14#include <pcmcia/cs_types.h>
15#include <pcmcia/cs.h>
16#include <pcmcia/cistpl.h>
17#include <pcmcia/ciscode.h>
18#include <pcmcia/ds.h>
19#include <pcmcia/cisreg.h>
20
21#include "ssb_private.h"
22
23
24/* Define the following to 1 to enable a printk on each coreswitch. */
25#define SSB_VERBOSE_PCMCIACORESWITCH_DEBUG 0
26
27
28int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
29 u8 coreidx)
30{
31 struct pcmcia_device *pdev = bus->host_pcmcia;
32 int err;
33 int attempts = 0;
34 u32 cur_core;
35 conf_reg_t reg;
36 u32 addr;
37 u32 read_addr;
38
39 addr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
40 while (1) {
41 reg.Action = CS_WRITE;
42 reg.Offset = 0x2E;
43 reg.Value = (addr & 0x0000F000) >> 12;
44 err = pcmcia_access_configuration_register(pdev, &reg);
45 if (err != CS_SUCCESS)
46 goto error;
47 reg.Offset = 0x30;
48 reg.Value = (addr & 0x00FF0000) >> 16;
49 err = pcmcia_access_configuration_register(pdev, &reg);
50 if (err != CS_SUCCESS)
51 goto error;
52 reg.Offset = 0x32;
53 reg.Value = (addr & 0xFF000000) >> 24;
54 err = pcmcia_access_configuration_register(pdev, &reg);
55 if (err != CS_SUCCESS)
56 goto error;
57
58 read_addr = 0;
59
60 reg.Action = CS_READ;
61 reg.Offset = 0x2E;
62 err = pcmcia_access_configuration_register(pdev, &reg);
63 if (err != CS_SUCCESS)
64 goto error;
65 read_addr |= (reg.Value & 0xF) << 12;
66 reg.Offset = 0x30;
67 err = pcmcia_access_configuration_register(pdev, &reg);
68 if (err != CS_SUCCESS)
69 goto error;
70 read_addr |= reg.Value << 16;
71 reg.Offset = 0x32;
72 err = pcmcia_access_configuration_register(pdev, &reg);
73 if (err != CS_SUCCESS)
74 goto error;
75 read_addr |= reg.Value << 24;
76
77 cur_core = (read_addr - SSB_ENUM_BASE) / SSB_CORE_SIZE;
78 if (cur_core == coreidx)
79 break;
80
81 if (attempts++ > SSB_BAR0_MAX_RETRIES)
82 goto error;
83 udelay(10);
84 }
85
86 return 0;
87error:
88 ssb_printk(KERN_ERR PFX "Failed to switch to core %u\n", coreidx);
89 return -ENODEV;
90}
91
92int ssb_pcmcia_switch_core(struct ssb_bus *bus,
93 struct ssb_device *dev)
94{
95 int err;
96 unsigned long flags;
97
98#if SSB_VERBOSE_PCMCIACORESWITCH_DEBUG
99 ssb_printk(KERN_INFO PFX
100 "Switching to %s core, index %d\n",
101 ssb_core_name(dev->id.coreid),
102 dev->core_index);
103#endif
104
105 spin_lock_irqsave(&bus->bar_lock, flags);
106 err = ssb_pcmcia_switch_coreidx(bus, dev->core_index);
107 if (!err)
108 bus->mapped_device = dev;
109 spin_unlock_irqrestore(&bus->bar_lock, flags);
110
111 return err;
112}
113
114int ssb_pcmcia_switch_segment(struct ssb_bus *bus, u8 seg)
115{
116 int attempts = 0;
117 unsigned long flags;
118 conf_reg_t reg;
119 int res, err = 0;
120
121 SSB_WARN_ON((seg != 0) && (seg != 1));
122 reg.Offset = 0x34;
123 reg.Function = 0;
124 spin_lock_irqsave(&bus->bar_lock, flags);
125 while (1) {
126 reg.Action = CS_WRITE;
127 reg.Value = seg;
128 res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
129 if (unlikely(res != CS_SUCCESS))
130 goto error;
131 reg.Value = 0xFF;
132 reg.Action = CS_READ;
133 res = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
134 if (unlikely(res != CS_SUCCESS))
135 goto error;
136
137 if (reg.Value == seg)
138 break;
139
140 if (unlikely(attempts++ > SSB_BAR0_MAX_RETRIES))
141 goto error;
142 udelay(10);
143 }
144 bus->mapped_pcmcia_seg = seg;
145out_unlock:
146 spin_unlock_irqrestore(&bus->bar_lock, flags);
147 return err;
148error:
149 ssb_printk(KERN_ERR PFX "Failed to switch pcmcia segment\n");
150 err = -ENODEV;
151 goto out_unlock;
152}
153
154/* These are the main device register access functions.
155 * do_select_core is inline to have the likely hotpath inline.
156 * All unlikely codepaths are out-of-line. */
157static inline int do_select_core(struct ssb_bus *bus,
158 struct ssb_device *dev,
159 u16 *offset)
160{
161 int err;
162 u8 need_seg = (*offset >= 0x800) ? 1 : 0;
163
164 if (unlikely(dev != bus->mapped_device)) {
165 err = ssb_pcmcia_switch_core(bus, dev);
166 if (unlikely(err))
167 return err;
168 }
169 if (unlikely(need_seg != bus->mapped_pcmcia_seg)) {
170 err = ssb_pcmcia_switch_segment(bus, need_seg);
171 if (unlikely(err))
172 return err;
173 }
174 if (need_seg == 1)
175 *offset -= 0x800;
176
177 return 0;
178}
179
180static u16 ssb_pcmcia_read16(struct ssb_device *dev, u16 offset)
181{
182 struct ssb_bus *bus = dev->bus;
183 u16 x;
184
185 if (unlikely(do_select_core(bus, dev, &offset)))
186 return 0xFFFF;
187 x = readw(bus->mmio + offset);
188
189 return x;
190}
191
192static u32 ssb_pcmcia_read32(struct ssb_device *dev, u16 offset)
193{
194 struct ssb_bus *bus = dev->bus;
195 u32 x;
196
197 if (unlikely(do_select_core(bus, dev, &offset)))
198 return 0xFFFFFFFF;
199 x = readl(bus->mmio + offset);
200
201 return x;
202}
203
204static void ssb_pcmcia_write16(struct ssb_device *dev, u16 offset, u16 value)
205{
206 struct ssb_bus *bus = dev->bus;
207
208 if (unlikely(do_select_core(bus, dev, &offset)))
209 return;
210 writew(value, bus->mmio + offset);
211}
212
213static void ssb_pcmcia_write32(struct ssb_device *dev, u16 offset, u32 value)
214{
215 struct ssb_bus *bus = dev->bus;
216
217 if (unlikely(do_select_core(bus, dev, &offset)))
218 return;
219 readw(bus->mmio + offset);
220 writew(value >> 16, bus->mmio + offset + 2);
221 readw(bus->mmio + offset);
222 writew(value, bus->mmio + offset);
223}
224
225/* Not "static", as it's used in main.c */
226const struct ssb_bus_ops ssb_pcmcia_ops = {
227 .read16 = ssb_pcmcia_read16,
228 .read32 = ssb_pcmcia_read32,
229 .write16 = ssb_pcmcia_write16,
230 .write32 = ssb_pcmcia_write32,
231};
232
233int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
234 struct ssb_init_invariants *iv)
235{
236 //TODO
237 return 0;
238}
239
240int ssb_pcmcia_init(struct ssb_bus *bus)
241{
242 conf_reg_t reg;
243 int err;
244
245 if (bus->bustype != SSB_BUSTYPE_PCMCIA)
246 return 0;
247
248 /* Switch segment to a known state and sync
249 * bus->mapped_pcmcia_seg with hardware state. */
250 ssb_pcmcia_switch_segment(bus, 0);
251
252 /* Init IRQ routing */
253 reg.Action = CS_READ;
254 reg.Function = 0;
255 if (bus->chip_id == 0x4306)
256 reg.Offset = 0x00;
257 else
258 reg.Offset = 0x80;
259 err = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
260 if (err != CS_SUCCESS)
261 goto error;
262 reg.Action = CS_WRITE;
263 reg.Value |= 0x04 | 0x01;
264 err = pcmcia_access_configuration_register(bus->host_pcmcia, &reg);
265 if (err != CS_SUCCESS)
266 goto error;
267
268 return 0;
269error:
270 return -ENODEV;
271}
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c
new file mode 100644
index 00000000000..96258c60919
--- /dev/null
+++ b/drivers/ssb/scan.c
@@ -0,0 +1,413 @@
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_types.h>
21#include <pcmcia/cs.h>
22#include <pcmcia/cistpl.h>
23#include <pcmcia/ds.h>
24
25#include "ssb_private.h"
26
27
28const char *ssb_core_name(u16 coreid)
29{
30 switch (coreid) {
31 case SSB_DEV_CHIPCOMMON:
32 return "ChipCommon";
33 case SSB_DEV_ILINE20:
34 return "ILine 20";
35 case SSB_DEV_SDRAM:
36 return "SDRAM";
37 case SSB_DEV_PCI:
38 return "PCI";
39 case SSB_DEV_MIPS:
40 return "MIPS";
41 case SSB_DEV_ETHERNET:
42 return "Fast Ethernet";
43 case SSB_DEV_V90:
44 return "V90";
45 case SSB_DEV_USB11_HOSTDEV:
46 return "USB 1.1 Hostdev";
47 case SSB_DEV_ADSL:
48 return "ADSL";
49 case SSB_DEV_ILINE100:
50 return "ILine 100";
51 case SSB_DEV_IPSEC:
52 return "IPSEC";
53 case SSB_DEV_PCMCIA:
54 return "PCMCIA";
55 case SSB_DEV_INTERNAL_MEM:
56 return "Internal Memory";
57 case SSB_DEV_MEMC_SDRAM:
58 return "MEMC SDRAM";
59 case SSB_DEV_EXTIF:
60 return "EXTIF";
61 case SSB_DEV_80211:
62 return "IEEE 802.11";
63 case SSB_DEV_MIPS_3302:
64 return "MIPS 3302";
65 case SSB_DEV_USB11_HOST:
66 return "USB 1.1 Host";
67 case SSB_DEV_USB11_DEV:
68 return "USB 1.1 Device";
69 case SSB_DEV_USB20_HOST:
70 return "USB 2.0 Host";
71 case SSB_DEV_USB20_DEV:
72 return "USB 2.0 Device";
73 case SSB_DEV_SDIO_HOST:
74 return "SDIO Host";
75 case SSB_DEV_ROBOSWITCH:
76 return "Roboswitch";
77 case SSB_DEV_PARA_ATA:
78 return "PATA";
79 case SSB_DEV_SATA_XORDMA:
80 return "SATA XOR-DMA";
81 case SSB_DEV_ETHERNET_GBIT:
82 return "GBit Ethernet";
83 case SSB_DEV_PCIE:
84 return "PCI-E";
85 case SSB_DEV_MIMO_PHY:
86 return "MIMO PHY";
87 case SSB_DEV_SRAM_CTRLR:
88 return "SRAM Controller";
89 case SSB_DEV_MINI_MACPHY:
90 return "Mini MACPHY";
91 case SSB_DEV_ARM_1176:
92 return "ARM 1176";
93 case SSB_DEV_ARM_7TDMI:
94 return "ARM 7TDMI";
95 }
96 return "UNKNOWN";
97}
98
99static u16 pcidev_to_chipid(struct pci_dev *pci_dev)
100{
101 u16 chipid_fallback = 0;
102
103 switch (pci_dev->device) {
104 case 0x4301:
105 chipid_fallback = 0x4301;
106 break;
107 case 0x4305 ... 0x4307:
108 chipid_fallback = 0x4307;
109 break;
110 case 0x4403:
111 chipid_fallback = 0x4402;
112 break;
113 case 0x4610 ... 0x4615:
114 chipid_fallback = 0x4610;
115 break;
116 case 0x4710 ... 0x4715:
117 chipid_fallback = 0x4710;
118 break;
119 case 0x4320 ... 0x4325:
120 chipid_fallback = 0x4309;
121 break;
122 case PCI_DEVICE_ID_BCM4401:
123 case PCI_DEVICE_ID_BCM4401B0:
124 case PCI_DEVICE_ID_BCM4401B1:
125 chipid_fallback = 0x4401;
126 break;
127 default:
128 ssb_printk(KERN_ERR PFX
129 "PCI-ID not in fallback list\n");
130 }
131
132 return chipid_fallback;
133}
134
135static u8 chipid_to_nrcores(u16 chipid)
136{
137 switch (chipid) {
138 case 0x5365:
139 return 7;
140 case 0x4306:
141 return 6;
142 case 0x4310:
143 return 8;
144 case 0x4307:
145 case 0x4301:
146 return 5;
147 case 0x4401:
148 case 0x4402:
149 return 3;
150 case 0x4710:
151 case 0x4610:
152 case 0x4704:
153 return 9;
154 default:
155 ssb_printk(KERN_ERR PFX
156 "CHIPID not in nrcores fallback list\n");
157 }
158
159 return 1;
160}
161
162static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
163 u16 offset)
164{
165 switch (bus->bustype) {
166 case SSB_BUSTYPE_SSB:
167 offset += current_coreidx * SSB_CORE_SIZE;
168 break;
169 case SSB_BUSTYPE_PCI:
170 break;
171 case SSB_BUSTYPE_PCMCIA:
172 if (offset >= 0x800) {
173 ssb_pcmcia_switch_segment(bus, 1);
174 offset -= 0x800;
175 } else
176 ssb_pcmcia_switch_segment(bus, 0);
177 break;
178 }
179 return readl(bus->mmio + offset);
180}
181
182static int scan_switchcore(struct ssb_bus *bus, u8 coreidx)
183{
184 switch (bus->bustype) {
185 case SSB_BUSTYPE_SSB:
186 break;
187 case SSB_BUSTYPE_PCI:
188 return ssb_pci_switch_coreidx(bus, coreidx);
189 case SSB_BUSTYPE_PCMCIA:
190 return ssb_pcmcia_switch_coreidx(bus, coreidx);
191 }
192 return 0;
193}
194
195void ssb_iounmap(struct ssb_bus *bus)
196{
197 switch (bus->bustype) {
198 case SSB_BUSTYPE_SSB:
199 case SSB_BUSTYPE_PCMCIA:
200 iounmap(bus->mmio);
201 break;
202 case SSB_BUSTYPE_PCI:
203#ifdef CONFIG_SSB_PCIHOST
204 pci_iounmap(bus->host_pci, bus->mmio);
205#else
206 SSB_BUG_ON(1); /* Can't reach this code. */
207#endif
208 break;
209 }
210 bus->mmio = NULL;
211 bus->mapped_device = NULL;
212}
213
214static void __iomem *ssb_ioremap(struct ssb_bus *bus,
215 unsigned long baseaddr)
216{
217 void __iomem *mmio = NULL;
218
219 switch (bus->bustype) {
220 case SSB_BUSTYPE_SSB:
221 /* Only map the first core for now. */
222 /* fallthrough... */
223 case SSB_BUSTYPE_PCMCIA:
224 mmio = ioremap(baseaddr, SSB_CORE_SIZE);
225 break;
226 case SSB_BUSTYPE_PCI:
227#ifdef CONFIG_SSB_PCIHOST
228 mmio = pci_iomap(bus->host_pci, 0, ~0UL);
229#else
230 SSB_BUG_ON(1); /* Can't reach this code. */
231#endif
232 break;
233 }
234
235 return mmio;
236}
237
238static int we_support_multiple_80211_cores(struct ssb_bus *bus)
239{
240 /* More than one 802.11 core is only supported by special chips.
241 * There are chips with two 802.11 cores, but with dangling
242 * pins on the second core. Be careful and reject them here.
243 */
244
245#ifdef CONFIG_SSB_PCIHOST
246 if (bus->bustype == SSB_BUSTYPE_PCI) {
247 if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
248 bus->host_pci->device == 0x4324)
249 return 1;
250 }
251#endif /* CONFIG_SSB_PCIHOST */
252 return 0;
253}
254
255int ssb_bus_scan(struct ssb_bus *bus,
256 unsigned long baseaddr)
257{
258 int err = -ENOMEM;
259 void __iomem *mmio;
260 u32 idhi, cc, rev, tmp;
261 int dev_i, i;
262 struct ssb_device *dev;
263 int nr_80211_cores = 0;
264
265 mmio = ssb_ioremap(bus, baseaddr);
266 if (!mmio)
267 goto out;
268 bus->mmio = mmio;
269
270 err = scan_switchcore(bus, 0); /* Switch to first core */
271 if (err)
272 goto err_unmap;
273
274 idhi = scan_read32(bus, 0, SSB_IDHIGH);
275 cc = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
276 rev = (idhi & SSB_IDHIGH_RCLO);
277 rev |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT;
278
279 bus->nr_devices = 0;
280 if (cc == SSB_DEV_CHIPCOMMON) {
281 tmp = scan_read32(bus, 0, SSB_CHIPCO_CHIPID);
282
283 bus->chip_id = (tmp & SSB_CHIPCO_IDMASK);
284 bus->chip_rev = (tmp & SSB_CHIPCO_REVMASK) >>
285 SSB_CHIPCO_REVSHIFT;
286 bus->chip_package = (tmp & SSB_CHIPCO_PACKMASK) >>
287 SSB_CHIPCO_PACKSHIFT;
288 if (rev >= 4) {
289 bus->nr_devices = (tmp & SSB_CHIPCO_NRCORESMASK) >>
290 SSB_CHIPCO_NRCORESSHIFT;
291 }
292 tmp = scan_read32(bus, 0, SSB_CHIPCO_CAP);
293 bus->chipco.capabilities = tmp;
294 } else {
295 if (bus->bustype == SSB_BUSTYPE_PCI) {
296 bus->chip_id = pcidev_to_chipid(bus->host_pci);
297 pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
298 &bus->chip_rev);
299 bus->chip_package = 0;
300 } else {
301 bus->chip_id = 0x4710;
302 bus->chip_rev = 0;
303 bus->chip_package = 0;
304 }
305 }
306 if (!bus->nr_devices)
307 bus->nr_devices = chipid_to_nrcores(bus->chip_id);
308 if (bus->nr_devices > ARRAY_SIZE(bus->devices)) {
309 ssb_printk(KERN_ERR PFX
310 "More than %d ssb cores found (%d)\n",
311 SSB_MAX_NR_CORES, bus->nr_devices);
312 goto err_unmap;
313 }
314 if (bus->bustype == SSB_BUSTYPE_SSB) {
315 /* Now that we know the number of cores,
316 * remap the whole IO space for all cores.
317 */
318 err = -ENOMEM;
319 iounmap(mmio);
320 mmio = ioremap(baseaddr, SSB_CORE_SIZE * bus->nr_devices);
321 if (!mmio)
322 goto out;
323 bus->mmio = mmio;
324 }
325
326 /* Fetch basic information about each core/device */
327 for (i = 0, dev_i = 0; i < bus->nr_devices; i++) {
328 err = scan_switchcore(bus, i);
329 if (err)
330 goto err_unmap;
331 dev = &(bus->devices[dev_i]);
332
333 idhi = scan_read32(bus, i, SSB_IDHIGH);
334 dev->id.coreid = (idhi & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
335 dev->id.revision = (idhi & SSB_IDHIGH_RCLO);
336 dev->id.revision |= (idhi & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT;
337 dev->id.vendor = (idhi & SSB_IDHIGH_VC) >> SSB_IDHIGH_VC_SHIFT;
338 dev->core_index = i;
339 dev->bus = bus;
340 dev->ops = bus->ops;
341
342 ssb_dprintk(KERN_INFO PFX
343 "Core %d found: %s "
344 "(cc 0x%03X, rev 0x%02X, vendor 0x%04X)\n",
345 i, ssb_core_name(dev->id.coreid),
346 dev->id.coreid, dev->id.revision, dev->id.vendor);
347
348 switch (dev->id.coreid) {
349 case SSB_DEV_80211:
350 nr_80211_cores++;
351 if (nr_80211_cores > 1) {
352 if (!we_support_multiple_80211_cores(bus)) {
353 ssb_dprintk(KERN_INFO PFX "Ignoring additional "
354 "802.11 core\n");
355 continue;
356 }
357 }
358 break;
359 case SSB_DEV_EXTIF:
360#ifdef CONFIG_SSB_DRIVER_EXTIF
361 if (bus->extif.dev) {
362 ssb_printk(KERN_WARNING PFX
363 "WARNING: Multiple EXTIFs found\n");
364 break;
365 }
366 bus->extif.dev = dev;
367#endif /* CONFIG_SSB_DRIVER_EXTIF */
368 break;
369 case SSB_DEV_CHIPCOMMON:
370 if (bus->chipco.dev) {
371 ssb_printk(KERN_WARNING PFX
372 "WARNING: Multiple ChipCommon found\n");
373 break;
374 }
375 bus->chipco.dev = dev;
376 break;
377 case SSB_DEV_MIPS:
378 case SSB_DEV_MIPS_3302:
379#ifdef CONFIG_SSB_DRIVER_MIPS
380 if (bus->mipscore.dev) {
381 ssb_printk(KERN_WARNING PFX
382 "WARNING: Multiple MIPS cores found\n");
383 break;
384 }
385 bus->mipscore.dev = dev;
386#endif /* CONFIG_SSB_DRIVER_MIPS */
387 break;
388 case SSB_DEV_PCI:
389 case SSB_DEV_PCIE:
390#ifdef CONFIG_SSB_DRIVER_PCICORE
391 if (bus->pcicore.dev) {
392 ssb_printk(KERN_WARNING PFX
393 "WARNING: Multiple PCI(E) cores found\n");
394 break;
395 }
396 bus->pcicore.dev = dev;
397#endif /* CONFIG_SSB_DRIVER_PCICORE */
398 break;
399 default:
400 break;
401 }
402
403 dev_i++;
404 }
405 bus->nr_devices = dev_i;
406
407 err = 0;
408out:
409 return err;
410err_unmap:
411 ssb_iounmap(bus);
412 goto out;
413}
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
new file mode 100644
index 00000000000..a789364264a
--- /dev/null
+++ b/drivers/ssb/ssb_private.h
@@ -0,0 +1,136 @@
1#ifndef LINUX_SSB_PRIVATE_H_
2#define LINUX_SSB_PRIVATE_H_
3
4#include <linux/ssb/ssb.h>
5#include <linux/types.h>
6
7
8#define PFX "ssb: "
9
10#ifdef CONFIG_SSB_SILENT
11# define ssb_printk(fmt, x...) do { /* nothing */ } while (0)
12#else
13# define ssb_printk printk
14#endif /* CONFIG_SSB_SILENT */
15
16/* dprintk: Debugging printk; vanishes for non-debug compilation */
17#ifdef CONFIG_SSB_DEBUG
18# define ssb_dprintk(fmt, x...) ssb_printk(fmt , ##x)
19#else
20# define ssb_dprintk(fmt, x...) do { /* nothing */ } while (0)
21#endif
22
23#ifdef CONFIG_SSB_DEBUG
24# define SSB_WARN_ON(x) WARN_ON(x)
25# define SSB_BUG_ON(x) BUG_ON(x)
26#else
27static inline int __ssb_do_nothing(int x) { return x; }
28# define SSB_WARN_ON(x) __ssb_do_nothing(unlikely(!!(x)))
29# define SSB_BUG_ON(x) __ssb_do_nothing(unlikely(!!(x)))
30#endif
31
32
33/* pci.c */
34#ifdef CONFIG_SSB_PCIHOST
35extern int ssb_pci_switch_core(struct ssb_bus *bus,
36 struct ssb_device *dev);
37extern int ssb_pci_switch_coreidx(struct ssb_bus *bus,
38 u8 coreidx);
39extern int ssb_pci_xtal(struct ssb_bus *bus, u32 what,
40 int turn_on);
41extern int ssb_pci_get_invariants(struct ssb_bus *bus,
42 struct ssb_init_invariants *iv);
43extern void ssb_pci_exit(struct ssb_bus *bus);
44extern int ssb_pci_init(struct ssb_bus *bus);
45extern const struct ssb_bus_ops ssb_pci_ops;
46
47#else /* CONFIG_SSB_PCIHOST */
48
49static inline int ssb_pci_switch_core(struct ssb_bus *bus,
50 struct ssb_device *dev)
51{
52 return 0;
53}
54static inline int ssb_pci_switch_coreidx(struct ssb_bus *bus,
55 u8 coreidx)
56{
57 return 0;
58}
59static inline int ssb_pci_xtal(struct ssb_bus *bus, u32 what,
60 int turn_on)
61{
62 return 0;
63}
64static inline void ssb_pci_exit(struct ssb_bus *bus)
65{
66}
67static inline int ssb_pci_init(struct ssb_bus *bus)
68{
69 return 0;
70}
71#endif /* CONFIG_SSB_PCIHOST */
72
73
74/* pcmcia.c */
75#ifdef CONFIG_SSB_PCMCIAHOST
76extern int ssb_pcmcia_switch_core(struct ssb_bus *bus,
77 struct ssb_device *dev);
78extern int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
79 u8 coreidx);
80extern int ssb_pcmcia_switch_segment(struct ssb_bus *bus,
81 u8 seg);
82extern int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
83 struct ssb_init_invariants *iv);
84extern int ssb_pcmcia_init(struct ssb_bus *bus);
85extern const struct ssb_bus_ops ssb_pcmcia_ops;
86#else /* CONFIG_SSB_PCMCIAHOST */
87static inline int ssb_pcmcia_switch_core(struct ssb_bus *bus,
88 struct ssb_device *dev)
89{
90 return 0;
91}
92static inline int ssb_pcmcia_switch_coreidx(struct ssb_bus *bus,
93 u8 coreidx)
94{
95 return 0;
96}
97static inline int ssb_pcmcia_switch_segment(struct ssb_bus *bus,
98 u8 seg)
99{
100 return 0;
101}
102static inline int ssb_pcmcia_init(struct ssb_bus *bus)
103{
104 return 0;
105}
106#endif /* CONFIG_SSB_PCMCIAHOST */
107
108
109/* scan.c */
110extern const char *ssb_core_name(u16 coreid);
111extern int ssb_bus_scan(struct ssb_bus *bus,
112 unsigned long baseaddr);
113extern void ssb_iounmap(struct ssb_bus *ssb);
114
115
116/* core.c */
117extern u32 ssb_calc_clock_rate(u32 plltype, u32 n, u32 m);
118extern int ssb_devices_freeze(struct ssb_bus *bus);
119extern int ssb_devices_thaw(struct ssb_bus *bus);
120extern struct ssb_bus *ssb_pci_dev_to_bus(struct pci_dev *pdev);
121
122/* b43_pci_bridge.c */
123#ifdef CONFIG_SSB_PCIHOST
124extern int __init b43_pci_ssb_bridge_init(void);
125extern void __exit b43_pci_ssb_bridge_exit(void);
126#else /* CONFIG_SSB_PCIHOST */
127static inline int b43_pci_ssb_bridge_init(void)
128{
129 return 0;
130}
131static inline void b43_pci_ssb_bridge_exit(void)
132{
133}
134#endif /* CONFIG_SSB_PCIHOST */
135
136#endif /* LINUX_SSB_PRIVATE_H_ */