aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2007-09-18 15:12:50 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:51:36 -0400
commit61e115a56d1aafd6e6a8a9fee8ac099a6128ac7b (patch)
treeadd97bf6a1207a4caea3a86cf13495ad3dc477de
parent5ee3afba88f5a79d0bff07ddd87af45919259f91 (diff)
[SSB]: add Sonics Silicon Backplane bus support
SSB is an SoC bus used in a number of embedded devices. The most well-known of these devices is probably the Linksys WRT54G, but there are others as well. The bus is also used internally on the BCM43xx and BCM44xx devices from Broadcom. This patch also includes support for SSB ID tables in modules, so that SSB drivers can be loaded automatically. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--MAINTAINERS6
-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
-rw-r--r--include/linux/mod_devicetable.h15
-rw-r--r--include/linux/ssb/ssb.h424
-rw-r--r--include/linux/ssb/ssb_driver_chipcommon.h396
-rw-r--r--include/linux/ssb/ssb_driver_extif.h204
-rw-r--r--include/linux/ssb/ssb_driver_mips.h46
-rw-r--r--include/linux/ssb/ssb_driver_pci.h106
-rw-r--r--include/linux/ssb/ssb_regs.h292
-rw-r--r--scripts/mod/file2alias.c19
24 files changed, 5892 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 3f07d5ff85f1..7524cd802da3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3446,6 +3446,12 @@ M: tsbogend@alpha.franken.de
3446L: netdev@vger.kernel.org 3446L: netdev@vger.kernel.org
3447S: Maintained 3447S: Maintained
3448 3448
3449SONICS SILICON BACKPLANE DRIVER (SSB)
3450P: Michael Buesch
3451M: mb@bu3sch.de
3452L: netdev@vger.kernel.org
3453S: Maintained
3454
3449SONY VAIO CONTROL DEVICE DRIVER 3455SONY VAIO CONTROL DEVICE DRIVER
3450P: Mattia Dongili 3456P: Mattia Dongili
3451M: malattia@linux.it 3457M: malattia@linux.it
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 3e1c442deff9..7bdae47d6b91 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 f0878b2ec55e..a168eacdcd9c 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 000000000000..b4a5e5e9d9fc
--- /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 000000000000..7be397595805
--- /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 000000000000..fa3bd292f5f7
--- /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 000000000000..a890544e8fba
--- /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 000000000000..fe55eb8b038a
--- /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 000000000000..ab8691a32580
--- /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 000000000000..2faaa906d5d6
--- /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 000000000000..74d5182db4b2
--- /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 000000000000..3d23ca4befe3
--- /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 000000000000..82a10abef640
--- /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 000000000000..7c773603b402
--- /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 000000000000..96258c60919d
--- /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 000000000000..a789364264a6
--- /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_ */
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 4dc5fa8be781..0c522e6b0917 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -340,4 +340,19 @@ struct parisc_device_id {
340#define PA_HVERSION_ANY_ID 0xffff 340#define PA_HVERSION_ANY_ID 0xffff
341#define PA_SVERSION_ANY_ID 0xffffffff 341#define PA_SVERSION_ANY_ID 0xffffffff
342 342
343/* SSB core, see drivers/ssb/ */
344struct ssb_device_id {
345 __u16 vendor;
346 __u16 coreid;
347 __u8 revision;
348};
349#define SSB_DEVICE(_vendor, _coreid, _revision) \
350 { .vendor = _vendor, .coreid = _coreid, .revision = _revision, }
351#define SSB_DEVTABLE_END \
352 { 0, },
353
354#define SSB_ANY_VENDOR 0xFFFF
355#define SSB_ANY_ID 0xFFFF
356#define SSB_ANY_REV 0xFF
357
343#endif /* LINUX_MOD_DEVICETABLE_H */ 358#endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
new file mode 100644
index 000000000000..2b5c312c4960
--- /dev/null
+++ b/include/linux/ssb/ssb.h
@@ -0,0 +1,424 @@
1#ifndef LINUX_SSB_H_
2#define LINUX_SSB_H_
3
4#include <linux/device.h>
5#include <linux/list.h>
6#include <linux/types.h>
7#include <linux/spinlock.h>
8#include <linux/pci.h>
9#include <linux/mod_devicetable.h>
10
11#include <linux/ssb/ssb_regs.h>
12
13
14struct pcmcia_device;
15struct ssb_bus;
16struct ssb_driver;
17
18
19struct ssb_sprom_r1 {
20 u16 pci_spid; /* Subsystem Product ID for PCI */
21 u16 pci_svid; /* Subsystem Vendor ID for PCI */
22 u16 pci_pid; /* Product ID for PCI */
23 u8 il0mac[6]; /* MAC address for 802.11b/g */
24 u8 et0mac[6]; /* MAC address for Ethernet */
25 u8 et1mac[6]; /* MAC address for 802.11a */
26 u8 et0phyaddr:5; /* MII address for enet0 */
27 u8 et1phyaddr:5; /* MII address for enet1 */
28 u8 et0mdcport:1; /* MDIO for enet0 */
29 u8 et1mdcport:1; /* MDIO for enet1 */
30 u8 board_rev; /* Board revision */
31 u8 country_code:4; /* Country Code */
32 u8 antenna_a:2; /* Antenna 0/1 available for A-PHY */
33 u8 antenna_bg:2; /* Antenna 0/1 available for B-PHY and G-PHY */
34 u16 pa0b0;
35 u16 pa0b1;
36 u16 pa0b2;
37 u16 pa1b0;
38 u16 pa1b1;
39 u16 pa1b2;
40 u8 gpio0; /* GPIO pin 0 */
41 u8 gpio1; /* GPIO pin 1 */
42 u8 gpio2; /* GPIO pin 2 */
43 u8 gpio3; /* GPIO pin 3 */
44 u16 maxpwr_a; /* A-PHY Power Amplifier Max Power (in dBm Q5.2) */
45 u16 maxpwr_bg; /* B/G-PHY Power Amplifier Max Power (in dBm Q5.2) */
46 u8 itssi_a; /* Idle TSSI Target for A-PHY */
47 u8 itssi_bg; /* Idle TSSI Target for B/G-PHY */
48 u16 boardflags_lo; /* Boardflags (low 16 bits) */
49 u8 antenna_gain_a; /* A-PHY Antenna gain (in dBm Q5.2) */
50 u8 antenna_gain_bg; /* B/G-PHY Antenna gain (in dBm Q5.2) */
51 u8 oem[8]; /* OEM string (rev 1 only) */
52};
53
54struct ssb_sprom_r2 {
55 u16 boardflags_hi; /* Boardflags (high 16 bits) */
56 u8 maxpwr_a_lo; /* A-PHY Max Power Low */
57 u8 maxpwr_a_hi; /* A-PHY Max Power High */
58 u16 pa1lob0; /* A-PHY PA Low Settings */
59 u16 pa1lob1; /* A-PHY PA Low Settings */
60 u16 pa1lob2; /* A-PHY PA Low Settings */
61 u16 pa1hib0; /* A-PHY PA High Settings */
62 u16 pa1hib1; /* A-PHY PA High Settings */
63 u16 pa1hib2; /* A-PHY PA High Settings */
64 u8 ofdm_pwr_off; /* OFDM Power Offset from CCK Level */
65 u8 country_str[2]; /* Two char Country Code */
66};
67
68struct ssb_sprom_r3 {
69 u32 ofdmapo; /* A-PHY OFDM Mid Power Offset */
70 u32 ofdmalpo; /* A-PHY OFDM Low Power Offset */
71 u32 ofdmahpo; /* A-PHY OFDM High Power Offset */
72 u8 gpioldc_on_cnt; /* GPIO LED Powersave Duty Cycle ON count */
73 u8 gpioldc_off_cnt; /* GPIO LED Powersave Duty Cycle OFF count */
74 u8 cckpo_1M:4; /* CCK Power Offset for Rate 1M */
75 u8 cckpo_2M:4; /* CCK Power Offset for Rate 2M */
76 u8 cckpo_55M:4; /* CCK Power Offset for Rate 5.5M */
77 u8 cckpo_11M:4; /* CCK Power Offset for Rate 11M */
78 u32 ofdmgpo; /* G-PHY OFDM Power Offset */
79};
80
81struct ssb_sprom_r4 {
82 /* TODO */
83};
84
85struct ssb_sprom {
86 u8 revision;
87 u8 crc;
88 /* The valid r# fields are selected by the "revision".
89 * Revision 3 and lower inherit from lower revisions.
90 */
91 union {
92 struct {
93 struct ssb_sprom_r1 r1;
94 struct ssb_sprom_r2 r2;
95 struct ssb_sprom_r3 r3;
96 };
97 struct ssb_sprom_r4 r4;
98 };
99};
100
101/* Information about the PCB the circuitry is soldered on. */
102struct ssb_boardinfo {
103 u16 vendor;
104 u16 type;
105 u16 rev;
106};
107
108
109struct ssb_device;
110/* Lowlevel read/write operations on the device MMIO.
111 * Internal, don't use that outside of ssb. */
112struct ssb_bus_ops {
113 u16 (*read16)(struct ssb_device *dev, u16 offset);
114 u32 (*read32)(struct ssb_device *dev, u16 offset);
115 void (*write16)(struct ssb_device *dev, u16 offset, u16 value);
116 void (*write32)(struct ssb_device *dev, u16 offset, u32 value);
117};
118
119
120/* Core-ID values. */
121#define SSB_DEV_CHIPCOMMON 0x800
122#define SSB_DEV_ILINE20 0x801
123#define SSB_DEV_SDRAM 0x803
124#define SSB_DEV_PCI 0x804
125#define SSB_DEV_MIPS 0x805
126#define SSB_DEV_ETHERNET 0x806
127#define SSB_DEV_V90 0x807
128#define SSB_DEV_USB11_HOSTDEV 0x808
129#define SSB_DEV_ADSL 0x809
130#define SSB_DEV_ILINE100 0x80A
131#define SSB_DEV_IPSEC 0x80B
132#define SSB_DEV_PCMCIA 0x80D
133#define SSB_DEV_INTERNAL_MEM 0x80E
134#define SSB_DEV_MEMC_SDRAM 0x80F
135#define SSB_DEV_EXTIF 0x811
136#define SSB_DEV_80211 0x812
137#define SSB_DEV_MIPS_3302 0x816
138#define SSB_DEV_USB11_HOST 0x817
139#define SSB_DEV_USB11_DEV 0x818
140#define SSB_DEV_USB20_HOST 0x819
141#define SSB_DEV_USB20_DEV 0x81A
142#define SSB_DEV_SDIO_HOST 0x81B
143#define SSB_DEV_ROBOSWITCH 0x81C
144#define SSB_DEV_PARA_ATA 0x81D
145#define SSB_DEV_SATA_XORDMA 0x81E
146#define SSB_DEV_ETHERNET_GBIT 0x81F
147#define SSB_DEV_PCIE 0x820
148#define SSB_DEV_MIMO_PHY 0x821
149#define SSB_DEV_SRAM_CTRLR 0x822
150#define SSB_DEV_MINI_MACPHY 0x823
151#define SSB_DEV_ARM_1176 0x824
152#define SSB_DEV_ARM_7TDMI 0x825
153
154/* Vendor-ID values */
155#define SSB_VENDOR_BROADCOM 0x4243
156
157/* Some kernel subsystems poke with dev->drvdata, so we must use the
158 * following ugly workaround to get from struct device to struct ssb_device */
159struct __ssb_dev_wrapper {
160 struct device dev;
161 struct ssb_device *sdev;
162};
163
164struct ssb_device {
165 /* Having a copy of the ops pointer in each dev struct
166 * is an optimization. */
167 const struct ssb_bus_ops *ops;
168
169 struct device *dev;
170 struct ssb_bus *bus;
171 struct ssb_device_id id;
172
173 u8 core_index;
174 unsigned int irq;
175
176 /* Internal-only stuff follows. */
177 void *drvdata; /* Per-device data */
178 void *devtypedata; /* Per-devicetype (eg 802.11) data */
179};
180
181/* Go from struct device to struct ssb_device. */
182static inline
183struct ssb_device * dev_to_ssb_dev(struct device *dev)
184{
185 struct __ssb_dev_wrapper *wrap;
186 wrap = container_of(dev, struct __ssb_dev_wrapper, dev);
187 return wrap->sdev;
188}
189
190/* Device specific user data */
191static inline
192void ssb_set_drvdata(struct ssb_device *dev, void *data)
193{
194 dev->drvdata = data;
195}
196static inline
197void * ssb_get_drvdata(struct ssb_device *dev)
198{
199 return dev->drvdata;
200}
201
202/* Devicetype specific user data. This is per device-type (not per device) */
203void ssb_set_devtypedata(struct ssb_device *dev, void *data);
204static inline
205void * ssb_get_devtypedata(struct ssb_device *dev)
206{
207 return dev->devtypedata;
208}
209
210
211struct ssb_driver {
212 const char *name;
213 const struct ssb_device_id *id_table;
214
215 int (*probe)(struct ssb_device *dev, const struct ssb_device_id *id);
216 void (*remove)(struct ssb_device *dev);
217 int (*suspend)(struct ssb_device *dev, pm_message_t state);
218 int (*resume)(struct ssb_device *dev);
219 void (*shutdown)(struct ssb_device *dev);
220
221 struct device_driver drv;
222};
223#define drv_to_ssb_drv(_drv) container_of(_drv, struct ssb_driver, drv)
224
225extern int __ssb_driver_register(struct ssb_driver *drv, struct module *owner);
226static inline int ssb_driver_register(struct ssb_driver *drv)
227{
228 return __ssb_driver_register(drv, THIS_MODULE);
229}
230extern void ssb_driver_unregister(struct ssb_driver *drv);
231
232
233
234
235enum ssb_bustype {
236 SSB_BUSTYPE_SSB, /* This SSB bus is the system bus */
237 SSB_BUSTYPE_PCI, /* SSB is connected to PCI bus */
238 SSB_BUSTYPE_PCMCIA, /* SSB is connected to PCMCIA bus */
239};
240
241/* board_vendor */
242#define SSB_BOARDVENDOR_BCM 0x14E4 /* Broadcom */
243#define SSB_BOARDVENDOR_DELL 0x1028 /* Dell */
244#define SSB_BOARDVENDOR_HP 0x0E11 /* HP */
245/* board_type */
246#define SSB_BOARD_BCM94306MP 0x0418
247#define SSB_BOARD_BCM4309G 0x0421
248#define SSB_BOARD_BCM4306CB 0x0417
249#define SSB_BOARD_BCM4309MP 0x040C
250#define SSB_BOARD_MP4318 0x044A
251#define SSB_BOARD_BU4306 0x0416
252#define SSB_BOARD_BU4309 0x040A
253/* chip_package */
254#define SSB_CHIPPACK_BCM4712S 1 /* Small 200pin 4712 */
255#define SSB_CHIPPACK_BCM4712M 2 /* Medium 225pin 4712 */
256#define SSB_CHIPPACK_BCM4712L 0 /* Large 340pin 4712 */
257
258#include <linux/ssb/ssb_driver_chipcommon.h>
259#include <linux/ssb/ssb_driver_mips.h>
260#include <linux/ssb/ssb_driver_extif.h>
261#include <linux/ssb/ssb_driver_pci.h>
262
263struct ssb_bus {
264 /* The MMIO area. */
265 void __iomem *mmio;
266
267 const struct ssb_bus_ops *ops;
268
269 /* The core in the basic address register window. (PCI bus only) */
270 struct ssb_device *mapped_device;
271 /* Currently mapped PCMCIA segment. (bustype == SSB_BUSTYPE_PCMCIA only) */
272 u8 mapped_pcmcia_seg;
273 /* Lock for core and segment switching. */
274 spinlock_t bar_lock;
275
276 /* The bus this backplane is running on. */
277 enum ssb_bustype bustype;
278 /* Pointer to the PCI bus (only valid if bustype == SSB_BUSTYPE_PCI). */
279 struct pci_dev *host_pci;
280 /* Pointer to the PCMCIA device (only if bustype == SSB_BUSTYPE_PCMCIA). */
281 struct pcmcia_device *host_pcmcia;
282
283#ifdef CONFIG_SSB_PCIHOST
284 /* Mutex to protect the SPROM writing. */
285 struct mutex pci_sprom_mutex;
286#endif
287
288 /* ID information about the Chip. */
289 u16 chip_id;
290 u16 chip_rev;
291 u8 chip_package;
292
293 /* List of devices (cores) on the backplane. */
294 struct ssb_device devices[SSB_MAX_NR_CORES];
295 u8 nr_devices;
296
297 /* Reference count. Number of suspended devices. */
298 u8 suspend_cnt;
299
300 /* Software ID number for this bus. */
301 unsigned int busnumber;
302
303 /* The ChipCommon device (if available). */
304 struct ssb_chipcommon chipco;
305 /* The PCI-core device (if available). */
306 struct ssb_pcicore pcicore;
307 /* The MIPS-core device (if available). */
308 struct ssb_mipscore mipscore;
309 /* The EXTif-core device (if available). */
310 struct ssb_extif extif;
311
312 /* The following structure elements are not available in early
313 * SSB initialization. Though, they are available for regular
314 * registered drivers at any stage. So be careful when
315 * using them in the ssb core code. */
316
317 /* ID information about the PCB. */
318 struct ssb_boardinfo boardinfo;
319 /* Contents of the SPROM. */
320 struct ssb_sprom sprom;
321
322 /* Internal-only stuff follows. Do not touch. */
323 struct list_head list;
324#ifdef CONFIG_SSB_DEBUG
325 /* Is the bus already powered up? */
326 bool powered_up;
327 int power_warn_count;
328#endif /* DEBUG */
329};
330
331/* The initialization-invariants. */
332struct ssb_init_invariants {
333 struct ssb_boardinfo boardinfo;
334 struct ssb_sprom sprom;
335};
336/* Type of function to fetch the invariants. */
337typedef int (*ssb_invariants_func_t)(struct ssb_bus *bus,
338 struct ssb_init_invariants *iv);
339
340/* Register a SSB system bus. get_invariants() is called after the
341 * basic system devices are initialized.
342 * The invariants are usually fetched from some NVRAM.
343 * Put the invariants into the struct pointed to by iv. */
344extern int ssb_bus_ssbbus_register(struct ssb_bus *bus,
345 unsigned long baseaddr,
346 ssb_invariants_func_t get_invariants);
347#ifdef CONFIG_SSB_PCIHOST
348extern int ssb_bus_pcibus_register(struct ssb_bus *bus,
349 struct pci_dev *host_pci);
350#endif /* CONFIG_SSB_PCIHOST */
351#ifdef CONFIG_SSB_PCMCIAHOST
352extern int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
353 struct pcmcia_device *pcmcia_dev,
354 unsigned long baseaddr);
355#endif /* CONFIG_SSB_PCMCIAHOST */
356
357extern void ssb_bus_unregister(struct ssb_bus *bus);
358
359extern u32 ssb_clockspeed(struct ssb_bus *bus);
360
361/* Is the device enabled in hardware? */
362int ssb_device_is_enabled(struct ssb_device *dev);
363/* Enable a device and pass device-specific SSB_TMSLOW flags.
364 * If no device-specific flags are available, use 0. */
365void ssb_device_enable(struct ssb_device *dev, u32 core_specific_flags);
366/* Disable a device in hardware and pass SSB_TMSLOW flags (if any). */
367void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags);
368
369
370/* Device MMIO register read/write functions. */
371static inline u16 ssb_read16(struct ssb_device *dev, u16 offset)
372{
373 return dev->ops->read16(dev, offset);
374}
375static inline u32 ssb_read32(struct ssb_device *dev, u16 offset)
376{
377 return dev->ops->read32(dev, offset);
378}
379static inline void ssb_write16(struct ssb_device *dev, u16 offset, u16 value)
380{
381 dev->ops->write16(dev, offset, value);
382}
383static inline void ssb_write32(struct ssb_device *dev, u16 offset, u32 value)
384{
385 dev->ops->write32(dev, offset, value);
386}
387
388
389/* Translation (routing) bits that need to be ORed to DMA
390 * addresses before they are given to a device. */
391extern u32 ssb_dma_translation(struct ssb_device *dev);
392#define SSB_DMA_TRANSLATION_MASK 0xC0000000
393#define SSB_DMA_TRANSLATION_SHIFT 30
394
395extern int ssb_dma_set_mask(struct ssb_device *ssb_dev, u64 mask);
396
397
398#ifdef CONFIG_SSB_PCIHOST
399/* PCI-host wrapper driver */
400extern int ssb_pcihost_register(struct pci_driver *driver);
401static inline void ssb_pcihost_unregister(struct pci_driver *driver)
402{
403 pci_unregister_driver(driver);
404}
405#endif /* CONFIG_SSB_PCIHOST */
406
407
408/* If a driver is shutdown or suspended, call this to signal
409 * that the bus may be completely powered down. SSB will decide,
410 * if it's really time to power down the bus, based on if there
411 * are other devices that want to run. */
412extern int ssb_bus_may_powerdown(struct ssb_bus *bus);
413/* Before initializing and enabling a device, call this to power-up the bus.
414 * If you want to allow use of dynamic-power-control, pass the flag.
415 * Otherwise static always-on powercontrol will be used. */
416extern int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl);
417
418
419/* Various helper functions */
420extern u32 ssb_admatch_base(u32 adm);
421extern u32 ssb_admatch_size(u32 adm);
422
423
424#endif /* LINUX_SSB_H_ */
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h
new file mode 100644
index 000000000000..4cb995494662
--- /dev/null
+++ b/include/linux/ssb/ssb_driver_chipcommon.h
@@ -0,0 +1,396 @@
1#ifndef LINUX_SSB_CHIPCO_H_
2#define LINUX_SSB_CHIPCO_H_
3
4/* SonicsSiliconBackplane CHIPCOMMON core hardware definitions
5 *
6 * The chipcommon core provides chip identification, SB control,
7 * jtag, 0/1/2 uarts, clock frequency control, a watchdog interrupt timer,
8 * gpio interface, extbus, and support for serial and parallel flashes.
9 *
10 * Copyright 2005, Broadcom Corporation
11 * Copyright 2006, Michael Buesch <mb@bu3sch.de>
12 *
13 * Licensed under the GPL version 2. See COPYING for details.
14 */
15
16/** ChipCommon core registers. **/
17
18#define SSB_CHIPCO_CHIPID 0x0000
19#define SSB_CHIPCO_IDMASK 0x0000FFFF
20#define SSB_CHIPCO_REVMASK 0x000F0000
21#define SSB_CHIPCO_REVSHIFT 16
22#define SSB_CHIPCO_PACKMASK 0x00F00000
23#define SSB_CHIPCO_PACKSHIFT 20
24#define SSB_CHIPCO_NRCORESMASK 0x0F000000
25#define SSB_CHIPCO_NRCORESSHIFT 24
26#define SSB_CHIPCO_CAP 0x0004 /* Capabilities */
27#define SSB_CHIPCO_CAP_NRUART 0x00000003 /* # of UARTs */
28#define SSB_CHIPCO_CAP_MIPSEB 0x00000004 /* MIPS in BigEndian Mode */
29#define SSB_CHIPCO_CAP_UARTCLK 0x00000018 /* UART clock select */
30#define SSB_CHIPCO_CAP_UARTCLK_INT 0x00000008 /* UARTs are driven by internal divided clock */
31#define SSB_CHIPCO_CAP_UARTGPIO 0x00000020 /* UARTs on GPIO 15-12 */
32#define SSB_CHIPCO_CAP_EXTBUS 0x000000C0 /* External buses present */
33#define SSB_CHIPCO_CAP_FLASHT 0x00000700 /* Flash Type */
34#define SSB_CHIPCO_FLASHT_NONE 0x00000000 /* No flash */
35#define SSB_CHIPCO_FLASHT_STSER 0x00000100 /* ST serial flash */
36#define SSB_CHIPCO_FLASHT_ATSER 0x00000200 /* Atmel serial flash */
37#define SSB_CHIPCO_FLASHT_PARA 0x00000700 /* Parallel flash */
38#define SSB_CHIPCO_CAP_PLLT 0x00038000 /* PLL Type */
39#define SSB_PLLTYPE_NONE 0x00000000
40#define SSB_PLLTYPE_1 0x00010000 /* 48Mhz base, 3 dividers */
41#define SSB_PLLTYPE_2 0x00020000 /* 48Mhz, 4 dividers */
42#define SSB_PLLTYPE_3 0x00030000 /* 25Mhz, 2 dividers */
43#define SSB_PLLTYPE_4 0x00008000 /* 48Mhz, 4 dividers */
44#define SSB_PLLTYPE_5 0x00018000 /* 25Mhz, 4 dividers */
45#define SSB_PLLTYPE_6 0x00028000 /* 100/200 or 120/240 only */
46#define SSB_PLLTYPE_7 0x00038000 /* 25Mhz, 4 dividers */
47#define SSB_CHIPCO_CAP_PCTL 0x00040000 /* Power Control */
48#define SSB_CHIPCO_CAP_OTPS 0x00380000 /* OTP size */
49#define SSB_CHIPCO_CAP_OTPS_SHIFT 19
50#define SSB_CHIPCO_CAP_OTPS_BASE 5
51#define SSB_CHIPCO_CAP_JTAGM 0x00400000 /* JTAG master present */
52#define SSB_CHIPCO_CAP_BROM 0x00800000 /* Internal boot ROM active */
53#define SSB_CHIPCO_CAP_64BIT 0x08000000 /* 64-bit Backplane */
54#define SSB_CHIPCO_CORECTL 0x0008
55#define SSB_CHIPCO_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */
56#define SSB_CHIPCO_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */
57#define SSB_CHIPCO_BIST 0x000C
58#define SSB_CHIPCO_OTPS 0x0010 /* OTP status */
59#define SSB_CHIPCO_OTPS_PROGFAIL 0x80000000
60#define SSB_CHIPCO_OTPS_PROTECT 0x00000007
61#define SSB_CHIPCO_OTPS_HW_PROTECT 0x00000001
62#define SSB_CHIPCO_OTPS_SW_PROTECT 0x00000002
63#define SSB_CHIPCO_OTPS_CID_PROTECT 0x00000004
64#define SSB_CHIPCO_OTPC 0x0014 /* OTP control */
65#define SSB_CHIPCO_OTPC_RECWAIT 0xFF000000
66#define SSB_CHIPCO_OTPC_PROGWAIT 0x00FFFF00
67#define SSB_CHIPCO_OTPC_PRW_SHIFT 8
68#define SSB_CHIPCO_OTPC_MAXFAIL 0x00000038
69#define SSB_CHIPCO_OTPC_VSEL 0x00000006
70#define SSB_CHIPCO_OTPC_SELVL 0x00000001
71#define SSB_CHIPCO_OTPP 0x0018 /* OTP prog */
72#define SSB_CHIPCO_OTPP_COL 0x000000FF
73#define SSB_CHIPCO_OTPP_ROW 0x0000FF00
74#define SSB_CHIPCO_OTPP_ROW_SHIFT 8
75#define SSB_CHIPCO_OTPP_READERR 0x10000000
76#define SSB_CHIPCO_OTPP_VALUE 0x20000000
77#define SSB_CHIPCO_OTPP_READ 0x40000000
78#define SSB_CHIPCO_OTPP_START 0x80000000
79#define SSB_CHIPCO_OTPP_BUSY 0x80000000
80#define SSB_CHIPCO_IRQSTAT 0x0020
81#define SSB_CHIPCO_IRQMASK 0x0024
82#define SSB_CHIPCO_IRQ_GPIO 0x00000001 /* gpio intr */
83#define SSB_CHIPCO_IRQ_EXT 0x00000002 /* ro: ext intr pin (corerev >= 3) */
84#define SSB_CHIPCO_IRQ_WDRESET 0x80000000 /* watchdog reset occurred */
85#define SSB_CHIPCO_CHIPCTL 0x0028 /* Rev >= 11 only */
86#define SSB_CHIPCO_CHIPSTAT 0x002C /* Rev >= 11 only */
87#define SSB_CHIPCO_JCMD 0x0030 /* Rev >= 10 only */
88#define SSB_CHIPCO_JCMD_START 0x80000000
89#define SSB_CHIPCO_JCMD_BUSY 0x80000000
90#define SSB_CHIPCO_JCMD_PAUSE 0x40000000
91#define SSB_CHIPCO_JCMD0_ACC_MASK 0x0000F000
92#define SSB_CHIPCO_JCMD0_ACC_IRDR 0x00000000
93#define SSB_CHIPCO_JCMD0_ACC_DR 0x00001000
94#define SSB_CHIPCO_JCMD0_ACC_IR 0x00002000
95#define SSB_CHIPCO_JCMD0_ACC_RESET 0x00003000
96#define SSB_CHIPCO_JCMD0_ACC_IRPDR 0x00004000
97#define SSB_CHIPCO_JCMD0_ACC_PDR 0x00005000
98#define SSB_CHIPCO_JCMD0_IRW_MASK 0x00000F00
99#define SSB_CHIPCO_JCMD_ACC_MASK 0x000F0000 /* Changes for corerev 11 */
100#define SSB_CHIPCO_JCMD_ACC_IRDR 0x00000000
101#define SSB_CHIPCO_JCMD_ACC_DR 0x00010000
102#define SSB_CHIPCO_JCMD_ACC_IR 0x00020000
103#define SSB_CHIPCO_JCMD_ACC_RESET 0x00030000
104#define SSB_CHIPCO_JCMD_ACC_IRPDR 0x00040000
105#define SSB_CHIPCO_JCMD_ACC_PDR 0x00050000
106#define SSB_CHIPCO_JCMD_IRW_MASK 0x00001F00
107#define SSB_CHIPCO_JCMD_IRW_SHIFT 8
108#define SSB_CHIPCO_JCMD_DRW_MASK 0x0000003F
109#define SSB_CHIPCO_JIR 0x0034 /* Rev >= 10 only */
110#define SSB_CHIPCO_JDR 0x0038 /* Rev >= 10 only */
111#define SSB_CHIPCO_JCTL 0x003C /* Rev >= 10 only */
112#define SSB_CHIPCO_JCTL_FORCE_CLK 4 /* Force clock */
113#define SSB_CHIPCO_JCTL_EXT_EN 2 /* Enable external targets */
114#define SSB_CHIPCO_JCTL_EN 1 /* Enable Jtag master */
115#define SSB_CHIPCO_FLASHCTL 0x0040
116#define SSB_CHIPCO_FLASHCTL_START 0x80000000
117#define SSB_CHIPCO_FLASHCTL_BUSY SSB_CHIPCO_FLASHCTL_START
118#define SSB_CHIPCO_FLASHADDR 0x0044
119#define SSB_CHIPCO_FLASHDATA 0x0048
120#define SSB_CHIPCO_BCAST_ADDR 0x0050
121#define SSB_CHIPCO_BCAST_DATA 0x0054
122#define SSB_CHIPCO_GPIOIN 0x0060
123#define SSB_CHIPCO_GPIOOUT 0x0064
124#define SSB_CHIPCO_GPIOOUTEN 0x0068
125#define SSB_CHIPCO_GPIOCTL 0x006C
126#define SSB_CHIPCO_GPIOPOL 0x0070
127#define SSB_CHIPCO_GPIOIRQ 0x0074
128#define SSB_CHIPCO_WATCHDOG 0x0080
129#define SSB_CHIPCO_GPIOTIMER 0x0088 /* LED powersave (corerev >= 16) */
130#define SSB_CHIPCO_GPIOTIMER_ONTIME_SHIFT 16
131#define SSB_CHIPCO_GPIOTOUTM 0x008C /* LED powersave (corerev >= 16) */
132#define SSB_CHIPCO_CLOCK_N 0x0090
133#define SSB_CHIPCO_CLOCK_SB 0x0094
134#define SSB_CHIPCO_CLOCK_PCI 0x0098
135#define SSB_CHIPCO_CLOCK_M2 0x009C
136#define SSB_CHIPCO_CLOCK_MIPS 0x00A0
137#define SSB_CHIPCO_CLKDIV 0x00A4 /* Rev >= 3 only */
138#define SSB_CHIPCO_CLKDIV_SFLASH 0x0F000000
139#define SSB_CHIPCO_CLKDIV_SFLASH_SHIFT 24
140#define SSB_CHIPCO_CLKDIV_OTP 0x000F0000
141#define SSB_CHIPCO_CLKDIV_OTP_SHIFT 16
142#define SSB_CHIPCO_CLKDIV_JTAG 0x00000F00
143#define SSB_CHIPCO_CLKDIV_JTAG_SHIFT 8
144#define SSB_CHIPCO_CLKDIV_UART 0x000000FF
145#define SSB_CHIPCO_PLLONDELAY 0x00B0 /* Rev >= 4 only */
146#define SSB_CHIPCO_FREFSELDELAY 0x00B4 /* Rev >= 4 only */
147#define SSB_CHIPCO_SLOWCLKCTL 0x00B8 /* 6 <= Rev <= 9 only */
148#define SSB_CHIPCO_SLOWCLKCTL_SRC 0x00000007 /* slow clock source mask */
149#define SSB_CHIPCO_SLOWCLKCTL_SRC_LPO 0x00000000 /* source of slow clock is LPO */
150#define SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL 0x00000001 /* source of slow clock is crystal */
151#define SSB_CHIPCO_SLOECLKCTL_SRC_PCI 0x00000002 /* source of slow clock is PCI */
152#define SSB_CHIPCO_SLOWCLKCTL_LPOFREQ 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
153#define SSB_CHIPCO_SLOWCLKCTL_LPOPD 0x00000400 /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */
154#define SSB_CHIPCO_SLOWCLKCTL_FSLOW 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */
155#define SSB_CHIPCO_SLOWCLKCTL_IPLL 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */
156#define SSB_CHIPCO_SLOWCLKCTL_ENXTAL 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */
157#define SSB_CHIPCO_SLOWCLKCTL_XTALPU 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */
158#define SSB_CHIPCO_SLOWCLKCTL_CLKDIV 0xFFFF0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */
159#define SSB_CHIPCO_SLOWCLKCTL_CLKDIV_SHIFT 16
160#define SSB_CHIPCO_SYSCLKCTL 0x00C0 /* Rev >= 3 only */
161#define SSB_CHIPCO_SYSCLKCTL_IDLPEN 0x00000001 /* ILPen: Enable Idle Low Power */
162#define SSB_CHIPCO_SYSCLKCTL_ALPEN 0x00000002 /* ALPen: Enable Active Low Power */
163#define SSB_CHIPCO_SYSCLKCTL_PLLEN 0x00000004 /* ForcePLLOn */
164#define SSB_CHIPCO_SYSCLKCTL_FORCEALP 0x00000008 /* Force ALP (or HT if ALPen is not set */
165#define SSB_CHIPCO_SYSCLKCTL_FORCEHT 0x00000010 /* Force HT */
166#define SSB_CHIPCO_SYSCLKCTL_CLKDIV 0xFFFF0000 /* ClkDiv (ILP = 1/(4+divisor)) */
167#define SSB_CHIPCO_SYSCLKCTL_CLKDIV_SHIFT 16
168#define SSB_CHIPCO_CLKSTSTR 0x00C4 /* Rev >= 3 only */
169#define SSB_CHIPCO_PCMCIA_CFG 0x0100
170#define SSB_CHIPCO_PCMCIA_MEMWAIT 0x0104
171#define SSB_CHIPCO_PCMCIA_ATTRWAIT 0x0108
172#define SSB_CHIPCO_PCMCIA_IOWAIT 0x010C
173#define SSB_CHIPCO_IDE_CFG 0x0110
174#define SSB_CHIPCO_IDE_MEMWAIT 0x0114
175#define SSB_CHIPCO_IDE_ATTRWAIT 0x0118
176#define SSB_CHIPCO_IDE_IOWAIT 0x011C
177#define SSB_CHIPCO_PROG_CFG 0x0120
178#define SSB_CHIPCO_PROG_WAITCNT 0x0124
179#define SSB_CHIPCO_FLASH_CFG 0x0128
180#define SSB_CHIPCO_FLASH_WAITCNT 0x012C
181#define SSB_CHIPCO_UART0_DATA 0x0300
182#define SSB_CHIPCO_UART0_IMR 0x0304
183#define SSB_CHIPCO_UART0_FCR 0x0308
184#define SSB_CHIPCO_UART0_LCR 0x030C
185#define SSB_CHIPCO_UART0_MCR 0x0310
186#define SSB_CHIPCO_UART0_LSR 0x0314
187#define SSB_CHIPCO_UART0_MSR 0x0318
188#define SSB_CHIPCO_UART0_SCRATCH 0x031C
189#define SSB_CHIPCO_UART1_DATA 0x0400
190#define SSB_CHIPCO_UART1_IMR 0x0404
191#define SSB_CHIPCO_UART1_FCR 0x0408
192#define SSB_CHIPCO_UART1_LCR 0x040C
193#define SSB_CHIPCO_UART1_MCR 0x0410
194#define SSB_CHIPCO_UART1_LSR 0x0414
195#define SSB_CHIPCO_UART1_MSR 0x0418
196#define SSB_CHIPCO_UART1_SCRATCH 0x041C
197
198
199
200/** Clockcontrol masks and values **/
201
202/* SSB_CHIPCO_CLOCK_N */
203#define SSB_CHIPCO_CLK_N1 0x0000003F /* n1 control */
204#define SSB_CHIPCO_CLK_N2 0x00003F00 /* n2 control */
205#define SSB_CHIPCO_CLK_N2_SHIFT 8
206#define SSB_CHIPCO_CLK_PLLC 0x000F0000 /* pll control */
207#define SSB_CHIPCO_CLK_PLLC_SHIFT 16
208
209/* SSB_CHIPCO_CLOCK_SB/PCI/UART */
210#define SSB_CHIPCO_CLK_M1 0x0000003F /* m1 control */
211#define SSB_CHIPCO_CLK_M2 0x00003F00 /* m2 control */
212#define SSB_CHIPCO_CLK_M2_SHIFT 8
213#define SSB_CHIPCO_CLK_M3 0x003F0000 /* m3 control */
214#define SSB_CHIPCO_CLK_M3_SHIFT 16
215#define SSB_CHIPCO_CLK_MC 0x1F000000 /* mux control */
216#define SSB_CHIPCO_CLK_MC_SHIFT 24
217
218/* N3M Clock control magic field values */
219#define SSB_CHIPCO_CLK_F6_2 0x02 /* A factor of 2 in */
220#define SSB_CHIPCO_CLK_F6_3 0x03 /* 6-bit fields like */
221#define SSB_CHIPCO_CLK_F6_4 0x05 /* N1, M1 or M3 */
222#define SSB_CHIPCO_CLK_F6_5 0x09
223#define SSB_CHIPCO_CLK_F6_6 0x11
224#define SSB_CHIPCO_CLK_F6_7 0x21
225
226#define SSB_CHIPCO_CLK_F5_BIAS 5 /* 5-bit fields get this added */
227
228#define SSB_CHIPCO_CLK_MC_BYPASS 0x08
229#define SSB_CHIPCO_CLK_MC_M1 0x04
230#define SSB_CHIPCO_CLK_MC_M1M2 0x02
231#define SSB_CHIPCO_CLK_MC_M1M2M3 0x01
232#define SSB_CHIPCO_CLK_MC_M1M3 0x11
233
234/* Type 2 Clock control magic field values */
235#define SSB_CHIPCO_CLK_T2_BIAS 2 /* n1, n2, m1 & m3 bias */
236#define SSB_CHIPCO_CLK_T2M2_BIAS 3 /* m2 bias */
237
238#define SSB_CHIPCO_CLK_T2MC_M1BYP 1
239#define SSB_CHIPCO_CLK_T2MC_M2BYP 2
240#define SSB_CHIPCO_CLK_T2MC_M3BYP 4
241
242/* Type 6 Clock control magic field values */
243#define SSB_CHIPCO_CLK_T6_MMASK 1 /* bits of interest in m */
244#define SSB_CHIPCO_CLK_T6_M0 120000000 /* sb clock for m = 0 */
245#define SSB_CHIPCO_CLK_T6_M1 100000000 /* sb clock for m = 1 */
246#define SSB_CHIPCO_CLK_SB2MIPS_T6(sb) (2 * (sb))
247
248/* Common clock base */
249#define SSB_CHIPCO_CLK_BASE1 24000000 /* Half the clock freq */
250#define SSB_CHIPCO_CLK_BASE2 12500000 /* Alternate crystal on some PLL's */
251
252/* Clock control values for 200Mhz in 5350 */
253#define SSB_CHIPCO_CLK_5350_N 0x0311
254#define SSB_CHIPCO_CLK_5350_M 0x04020009
255
256
257/** Bits in the config registers **/
258
259#define SSB_CHIPCO_CFG_EN 0x0001 /* Enable */
260#define SSB_CHIPCO_CFG_EXTM 0x000E /* Extif Mode */
261#define SSB_CHIPCO_CFG_EXTM_ASYNC 0x0002 /* Async/Parallel flash */
262#define SSB_CHIPCO_CFG_EXTM_SYNC 0x0004 /* Synchronous */
263#define SSB_CHIPCO_CFG_EXTM_PCMCIA 0x0008 /* PCMCIA */
264#define SSB_CHIPCO_CFG_EXTM_IDE 0x000A /* IDE */
265#define SSB_CHIPCO_CFG_DS16 0x0010 /* Data size, 0=8bit, 1=16bit */
266#define SSB_CHIPCO_CFG_CLKDIV 0x0060 /* Sync: Clock divisor */
267#define SSB_CHIPCO_CFG_CLKEN 0x0080 /* Sync: Clock enable */
268#define SSB_CHIPCO_CFG_BSTRO 0x0100 /* Sync: Size/Bytestrobe */
269
270
271/** Flash-specific control/status values */
272
273/* flashcontrol opcodes for ST flashes */
274#define SSB_CHIPCO_FLASHCTL_ST_WREN 0x0006 /* Write Enable */
275#define SSB_CHIPCO_FLASHCTL_ST_WRDIS 0x0004 /* Write Disable */
276#define SSB_CHIPCO_FLASHCTL_ST_RDSR 0x0105 /* Read Status Register */
277#define SSB_CHIPCO_FLASHCTL_ST_WRSR 0x0101 /* Write Status Register */
278#define SSB_CHIPCO_FLASHCTL_ST_READ 0x0303 /* Read Data Bytes */
279#define SSB_CHIPCO_FLASHCTL_ST_PP 0x0302 /* Page Program */
280#define SSB_CHIPCO_FLASHCTL_ST_SE 0x02D8 /* Sector Erase */
281#define SSB_CHIPCO_FLASHCTL_ST_BE 0x00C7 /* Bulk Erase */
282#define SSB_CHIPCO_FLASHCTL_ST_DP 0x00B9 /* Deep Power-down */
283#define SSB_CHIPCO_FLASHCTL_ST_RSIG 0x03AB /* Read Electronic Signature */
284
285/* Status register bits for ST flashes */
286#define SSB_CHIPCO_FLASHSTA_ST_WIP 0x01 /* Write In Progress */
287#define SSB_CHIPCO_FLASHSTA_ST_WEL 0x02 /* Write Enable Latch */
288#define SSB_CHIPCO_FLASHSTA_ST_BP 0x1C /* Block Protect */
289#define SSB_CHIPCO_FLASHSTA_ST_BP_SHIFT 2
290#define SSB_CHIPCO_FLASHSTA_ST_SRWD 0x80 /* Status Register Write Disable */
291
292/* flashcontrol opcodes for Atmel flashes */
293#define SSB_CHIPCO_FLASHCTL_AT_READ 0x07E8
294#define SSB_CHIPCO_FLASHCTL_AT_PAGE_READ 0x07D2
295#define SSB_CHIPCO_FLASHCTL_AT_BUF1_READ /* FIXME */
296#define SSB_CHIPCO_FLASHCTL_AT_BUF2_READ /* FIXME */
297#define SSB_CHIPCO_FLASHCTL_AT_STATUS 0x01D7
298#define SSB_CHIPCO_FLASHCTL_AT_BUF1_WRITE 0x0384
299#define SSB_CHIPCO_FLASHCTL_AT_BUF2_WRITE 0x0387
300#define SSB_CHIPCO_FLASHCTL_AT_BUF1_ERASE_PRGM 0x0283 /* Erase program */
301#define SSB_CHIPCO_FLASHCTL_AT_BUF2_ERASE_PRGM 0x0286 /* Erase program */
302#define SSB_CHIPCO_FLASHCTL_AT_BUF1_PROGRAM 0x0288
303#define SSB_CHIPCO_FLASHCTL_AT_BUF2_PROGRAM 0x0289
304#define SSB_CHIPCO_FLASHCTL_AT_PAGE_ERASE 0x0281
305#define SSB_CHIPCO_FLASHCTL_AT_BLOCK_ERASE 0x0250
306#define SSB_CHIPCO_FLASHCTL_AT_BUF1_WRER_PRGM 0x0382 /* Write erase program */
307#define SSB_CHIPCO_FLASHCTL_AT_BUF2_WRER_PRGM 0x0385 /* Write erase program */
308#define SSB_CHIPCO_FLASHCTL_AT_BUF1_LOAD 0x0253
309#define SSB_CHIPCO_FLASHCTL_AT_BUF2_LOAD 0x0255
310#define SSB_CHIPCO_FLASHCTL_AT_BUF1_COMPARE 0x0260
311#define SSB_CHIPCO_FLASHCTL_AT_BUF2_COMPARE 0x0261
312#define SSB_CHIPCO_FLASHCTL_AT_BUF1_REPROGRAM 0x0258
313#define SSB_CHIPCO_FLASHCTL_AT_BUF2_REPROGRAM 0x0259
314
315/* Status register bits for Atmel flashes */
316#define SSB_CHIPCO_FLASHSTA_AT_READY 0x80
317#define SSB_CHIPCO_FLASHSTA_AT_MISMATCH 0x40
318#define SSB_CHIPCO_FLASHSTA_AT_ID 0x38
319#define SSB_CHIPCO_FLASHSTA_AT_ID_SHIFT 3
320
321
322/** OTP **/
323
324/* OTP regions */
325#define SSB_CHIPCO_OTP_HW_REGION SSB_CHIPCO_OTPS_HW_PROTECT
326#define SSB_CHIPCO_OTP_SW_REGION SSB_CHIPCO_OTPS_SW_PROTECT
327#define SSB_CHIPCO_OTP_CID_REGION SSB_CHIPCO_OTPS_CID_PROTECT
328
329/* OTP regions (Byte offsets from otp size) */
330#define SSB_CHIPCO_OTP_SWLIM_OFF (-8)
331#define SSB_CHIPCO_OTP_CIDBASE_OFF 0
332#define SSB_CHIPCO_OTP_CIDLIM_OFF 8
333
334/* Predefined OTP words (Word offset from otp size) */
335#define SSB_CHIPCO_OTP_BOUNDARY_OFF (-4)
336#define SSB_CHIPCO_OTP_HWSIGN_OFF (-3)
337#define SSB_CHIPCO_OTP_SWSIGN_OFF (-2)
338#define SSB_CHIPCO_OTP_CIDSIGN_OFF (-1)
339
340#define SSB_CHIPCO_OTP_CID_OFF 0
341#define SSB_CHIPCO_OTP_PKG_OFF 1
342#define SSB_CHIPCO_OTP_FID_OFF 2
343#define SSB_CHIPCO_OTP_RSV_OFF 3
344#define SSB_CHIPCO_OTP_LIM_OFF 4
345
346#define SSB_CHIPCO_OTP_SIGNATURE 0x578A
347#define SSB_CHIPCO_OTP_MAGIC 0x4E56
348
349
350struct ssb_device;
351struct ssb_serial_port;
352
353struct ssb_chipcommon {
354 struct ssb_device *dev;
355 u32 capabilities;
356 /* Fast Powerup Delay constant */
357 u16 fast_pwrup_delay;
358};
359
360extern void ssb_chipcommon_init(struct ssb_chipcommon *cc);
361
362#include <linux/pm.h>
363extern void ssb_chipco_suspend(struct ssb_chipcommon *cc, pm_message_t state);
364extern void ssb_chipco_resume(struct ssb_chipcommon *cc);
365
366extern void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc,
367 u32 *plltype, u32 *n, u32 *m);
368extern void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc,
369 u32 *plltype, u32 *n, u32 *m);
370extern void ssb_chipco_timing_init(struct ssb_chipcommon *cc,
371 unsigned long ns_per_cycle);
372
373enum ssb_clkmode {
374 SSB_CLKMODE_SLOW,
375 SSB_CLKMODE_FAST,
376 SSB_CLKMODE_DYNAMIC,
377};
378
379extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc,
380 enum ssb_clkmode mode);
381
382extern void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc,
383 u32 ticks);
384
385u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask);
386
387void ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value);
388
389void ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value);
390
391#ifdef CONFIG_SSB_SERIAL
392extern int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
393 struct ssb_serial_port *ports);
394#endif /* CONFIG_SSB_SERIAL */
395
396#endif /* LINUX_SSB_CHIPCO_H_ */
diff --git a/include/linux/ssb/ssb_driver_extif.h b/include/linux/ssb/ssb_driver_extif.h
new file mode 100644
index 000000000000..a9164357b5ae
--- /dev/null
+++ b/include/linux/ssb/ssb_driver_extif.h
@@ -0,0 +1,204 @@
1/*
2 * Hardware-specific External Interface I/O core definitions
3 * for the BCM47xx family of SiliconBackplane-based chips.
4 *
5 * The External Interface core supports a total of three external chip selects
6 * supporting external interfaces. One of the external chip selects is
7 * used for Flash, one is used for PCMCIA, and the other may be
8 * programmed to support either a synchronous interface or an
9 * asynchronous interface. The asynchronous interface can be used to
10 * support external devices such as UARTs and the BCM2019 Bluetooth
11 * baseband processor.
12 * The external interface core also contains 2 on-chip 16550 UARTs, clock
13 * frequency control, a watchdog interrupt timer, and a GPIO interface.
14 *
15 * Copyright 2005, Broadcom Corporation
16 * Copyright 2006, Michael Buesch
17 *
18 * Licensed under the GPL version 2. See COPYING for details.
19 */
20#ifndef LINUX_SSB_EXTIFCORE_H_
21#define LINUX_SSB_EXTIFCORE_H_
22
23/* external interface address space */
24#define SSB_EXTIF_PCMCIA_MEMBASE(x) (x)
25#define SSB_EXTIF_PCMCIA_IOBASE(x) ((x) + 0x100000)
26#define SSB_EXTIF_PCMCIA_CFGBASE(x) ((x) + 0x200000)
27#define SSB_EXTIF_CFGIF_BASE(x) ((x) + 0x800000)
28#define SSB_EXTIF_FLASH_BASE(x) ((x) + 0xc00000)
29
30#define SSB_EXTIF_NR_GPIOOUT 5
31/* GPIO NOTE:
32 * The multiple instances of output and output enable registers
33 * are present to allow driver software for multiple cores to control
34 * gpio outputs without needing to share a single register pair.
35 * Use the following helper macro to get a register offset value.
36 */
37#define SSB_EXTIF_GPIO_OUT(index) ({ \
38 BUILD_BUG_ON(index >= SSB_EXTIF_NR_GPIOOUT); \
39 SSB_EXTIF_GPIO_OUT_BASE + ((index) * 8); \
40 })
41#define SSB_EXTIF_GPIO_OUTEN(index) ({ \
42 BUILD_BUG_ON(index >= SSB_EXTIF_NR_GPIOOUT); \
43 SSB_EXTIF_GPIO_OUTEN_BASE + ((index) * 8); \
44 })
45
46/** EXTIF core registers **/
47
48#define SSB_EXTIF_CTL 0x0000
49#define SSB_EXTIF_CTL_UARTEN (1 << 0) /* UART enable */
50#define SSB_EXTIF_EXTSTAT 0x0004
51#define SSB_EXTIF_EXTSTAT_EMODE (1 << 0) /* Endian mode (ro) */
52#define SSB_EXTIF_EXTSTAT_EIRQPIN (1 << 1) /* External interrupt pin (ro) */
53#define SSB_EXTIF_EXTSTAT_GPIOIRQPIN (1 << 2) /* GPIO interrupt pin (ro) */
54#define SSB_EXTIF_PCMCIA_CFG 0x0010
55#define SSB_EXTIF_PCMCIA_MEMWAIT 0x0014
56#define SSB_EXTIF_PCMCIA_ATTRWAIT 0x0018
57#define SSB_EXTIF_PCMCIA_IOWAIT 0x001C
58#define SSB_EXTIF_PROG_CFG 0x0020
59#define SSB_EXTIF_PROG_WAITCNT 0x0024
60#define SSB_EXTIF_FLASH_CFG 0x0028
61#define SSB_EXTIF_FLASH_WAITCNT 0x002C
62#define SSB_EXTIF_WATCHDOG 0x0040
63#define SSB_EXTIF_CLOCK_N 0x0044
64#define SSB_EXTIF_CLOCK_SB 0x0048
65#define SSB_EXTIF_CLOCK_PCI 0x004C
66#define SSB_EXTIF_CLOCK_MII 0x0050
67#define SSB_EXTIF_GPIO_IN 0x0060
68#define SSB_EXTIF_GPIO_OUT_BASE 0x0064
69#define SSB_EXTIF_GPIO_OUTEN_BASE 0x0068
70#define SSB_EXTIF_EJTAG_OUTEN 0x0090
71#define SSB_EXTIF_GPIO_INTPOL 0x0094
72#define SSB_EXTIF_GPIO_INTMASK 0x0098
73#define SSB_EXTIF_UART_DATA 0x0300
74#define SSB_EXTIF_UART_TIMER 0x0310
75#define SSB_EXTIF_UART_FCR 0x0320
76#define SSB_EXTIF_UART_LCR 0x0330
77#define SSB_EXTIF_UART_MCR 0x0340
78#define SSB_EXTIF_UART_LSR 0x0350
79#define SSB_EXTIF_UART_MSR 0x0360
80#define SSB_EXTIF_UART_SCRATCH 0x0370
81
82
83
84
85/* pcmcia/prog/flash_config */
86#define SSB_EXTCFG_EN (1 << 0) /* enable */
87#define SSB_EXTCFG_MODE 0xE /* mode */
88#define SSB_EXTCFG_MODE_SHIFT 1
89#define SSB_EXTCFG_MODE_FLASH 0x0 /* flash/asynchronous mode */
90#define SSB_EXTCFG_MODE_SYNC 0x2 /* synchronous mode */
91#define SSB_EXTCFG_MODE_PCMCIA 0x4 /* pcmcia mode */
92#define SSB_EXTCFG_DS16 (1 << 4) /* destsize: 0=8bit, 1=16bit */
93#define SSB_EXTCFG_BSWAP (1 << 5) /* byteswap */
94#define SSB_EXTCFG_CLKDIV 0xC0 /* clock divider */
95#define SSB_EXTCFG_CLKDIV_SHIFT 6
96#define SSB_EXTCFG_CLKDIV_2 0x0 /* backplane/2 */
97#define SSB_EXTCFG_CLKDIV_3 0x40 /* backplane/3 */
98#define SSB_EXTCFG_CLKDIV_4 0x80 /* backplane/4 */
99#define SSB_EXTCFG_CLKEN (1 << 8) /* clock enable */
100#define SSB_EXTCFG_STROBE (1 << 9) /* size/bytestrobe (synch only) */
101
102/* pcmcia_memwait */
103#define SSB_PCMCIA_MEMW_0 0x0000003F /* waitcount0 */
104#define SSB_PCMCIA_MEMW_1 0x00001F00 /* waitcount1 */
105#define SSB_PCMCIA_MEMW_1_SHIFT 8
106#define SSB_PCMCIA_MEMW_2 0x001F0000 /* waitcount2 */
107#define SSB_PCMCIA_MEMW_2_SHIFT 16
108#define SSB_PCMCIA_MEMW_3 0x1F000000 /* waitcount3 */
109#define SSB_PCMCIA_MEMW_3_SHIFT 24
110
111/* pcmcia_attrwait */
112#define SSB_PCMCIA_ATTW_0 0x0000003F /* waitcount0 */
113#define SSB_PCMCIA_ATTW_1 0x00001F00 /* waitcount1 */
114#define SSB_PCMCIA_ATTW_1_SHIFT 8
115#define SSB_PCMCIA_ATTW_2 0x001F0000 /* waitcount2 */
116#define SSB_PCMCIA_ATTW_2_SHIFT 16
117#define SSB_PCMCIA_ATTW_3 0x1F000000 /* waitcount3 */
118#define SSB_PCMCIA_ATTW_3_SHIFT 24
119
120/* pcmcia_iowait */
121#define SSB_PCMCIA_IOW_0 0x0000003F /* waitcount0 */
122#define SSB_PCMCIA_IOW_1 0x00001F00 /* waitcount1 */
123#define SSB_PCMCIA_IOW_1_SHIFT 8
124#define SSB_PCMCIA_IOW_2 0x001F0000 /* waitcount2 */
125#define SSB_PCMCIA_IOW_2_SHIFT 16
126#define SSB_PCMCIA_IOW_3 0x1F000000 /* waitcount3 */
127#define SSB_PCMCIA_IOW_3_SHIFT 24
128
129/* prog_waitcount */
130#define SSB_PROG_WCNT_0 0x0000001F /* waitcount0 */
131#define SSB_PROG_WCNT_1 0x00001F00 /* waitcount1 */
132#define SSB_PROG_WCNT_1_SHIFT 8
133#define SSB_PROG_WCNT_2 0x001F0000 /* waitcount2 */
134#define SSB_PROG_WCNT_2_SHIFT 16
135#define SSB_PROG_WCNT_3 0x1F000000 /* waitcount3 */
136#define SSB_PROG_WCNT_3_SHIFT 24
137
138#define SSB_PROG_W0 0x0000000C
139#define SSB_PROG_W1 0x00000A00
140#define SSB_PROG_W2 0x00020000
141#define SSB_PROG_W3 0x01000000
142
143/* flash_waitcount */
144#define SSB_FLASH_WCNT_0 0x0000001F /* waitcount0 */
145#define SSB_FLASH_WCNT_1 0x00001F00 /* waitcount1 */
146#define SSB_FLASH_WCNT_1_SHIFT 8
147#define SSB_FLASH_WCNT_2 0x001F0000 /* waitcount2 */
148#define SSB_FLASH_WCNT_2_SHIFT 16
149#define SSB_FLASH_WCNT_3 0x1F000000 /* waitcount3 */
150#define SSB_FLASH_WCNT_3_SHIFT 24
151
152/* watchdog */
153#define SSB_EXTIF_WATCHDOG_CLK 48000000 /* Hz */
154
155
156
157#ifdef CONFIG_SSB_DRIVER_EXTIF
158
159struct ssb_extif {
160 struct ssb_device *dev;
161};
162
163static inline bool ssb_extif_available(struct ssb_extif *extif)
164{
165 return (extif->dev != NULL);
166}
167
168extern void ssb_extif_get_clockcontrol(struct ssb_extif *extif,
169 u32 *plltype, u32 *n, u32 *m);
170
171extern void ssb_extif_timing_init(struct ssb_extif *extif,
172 unsigned long ns);
173
174u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask);
175
176void ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value);
177
178void ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value);
179
180#ifdef CONFIG_SSB_SERIAL
181extern int ssb_extif_serial_init(struct ssb_extif *extif,
182 struct ssb_serial_port *ports);
183#endif /* CONFIG_SSB_SERIAL */
184
185
186#else /* CONFIG_SSB_DRIVER_EXTIF */
187/* extif disabled */
188
189struct ssb_extif {
190};
191
192static inline bool ssb_extif_available(struct ssb_extif *extif)
193{
194 return 0;
195}
196
197static inline
198void ssb_extif_get_clockcontrol(struct ssb_extif *extif,
199 u32 *plltype, u32 *n, u32 *m)
200{
201}
202
203#endif /* CONFIG_SSB_DRIVER_EXTIF */
204#endif /* LINUX_SSB_EXTIFCORE_H_ */
diff --git a/include/linux/ssb/ssb_driver_mips.h b/include/linux/ssb/ssb_driver_mips.h
new file mode 100644
index 000000000000..5f44e9740cd2
--- /dev/null
+++ b/include/linux/ssb/ssb_driver_mips.h
@@ -0,0 +1,46 @@
1#ifndef LINUX_SSB_MIPSCORE_H_
2#define LINUX_SSB_MIPSCORE_H_
3
4#ifdef CONFIG_SSB_DRIVER_MIPS
5
6struct ssb_device;
7
8struct ssb_serial_port {
9 void *regs;
10 unsigned long clockspeed;
11 unsigned int irq;
12 unsigned int baud_base;
13 unsigned int reg_shift;
14};
15
16
17struct ssb_mipscore {
18 struct ssb_device *dev;
19
20 int nr_serial_ports;
21 struct ssb_serial_port serial_ports[4];
22
23 u8 flash_buswidth;
24 u32 flash_window;
25 u32 flash_window_size;
26};
27
28extern void ssb_mipscore_init(struct ssb_mipscore *mcore);
29extern u32 ssb_cpu_clock(struct ssb_mipscore *mcore);
30
31extern unsigned int ssb_mips_irq(struct ssb_device *dev);
32
33
34#else /* CONFIG_SSB_DRIVER_MIPS */
35
36struct ssb_mipscore {
37};
38
39static inline
40void ssb_mipscore_init(struct ssb_mipscore *mcore)
41{
42}
43
44#endif /* CONFIG_SSB_DRIVER_MIPS */
45
46#endif /* LINUX_SSB_MIPSCORE_H_ */
diff --git a/include/linux/ssb/ssb_driver_pci.h b/include/linux/ssb/ssb_driver_pci.h
new file mode 100644
index 000000000000..9cfffb7b1a27
--- /dev/null
+++ b/include/linux/ssb/ssb_driver_pci.h
@@ -0,0 +1,106 @@
1#ifndef LINUX_SSB_PCICORE_H_
2#define LINUX_SSB_PCICORE_H_
3
4#ifdef CONFIG_SSB_DRIVER_PCICORE
5
6/* PCI core registers. */
7#define SSB_PCICORE_CTL 0x0000 /* PCI Control */
8#define SSB_PCICORE_CTL_RST_OE 0x00000001 /* PCI_RESET Output Enable */
9#define SSB_PCICORE_CTL_RST 0x00000002 /* PCI_RESET driven out to pin */
10#define SSB_PCICORE_CTL_CLK_OE 0x00000004 /* Clock gate Output Enable */
11#define SSB_PCICORE_CTL_CLK 0x00000008 /* Gate for clock driven out to pin */
12#define SSB_PCICORE_ARBCTL 0x0010 /* PCI Arbiter Control */
13#define SSB_PCICORE_ARBCTL_INTERN 0x00000001 /* Use internal arbiter */
14#define SSB_PCICORE_ARBCTL_EXTERN 0x00000002 /* Use external arbiter */
15#define SSB_PCICORE_ARBCTL_PARKID 0x00000006 /* Mask, selects which agent is parked on an idle bus */
16#define SSB_PCICORE_ARBCTL_PARKID_LAST 0x00000000 /* Last requestor */
17#define SSB_PCICORE_ARBCTL_PARKID_4710 0x00000002 /* 4710 */
18#define SSB_PCICORE_ARBCTL_PARKID_EXT0 0x00000004 /* External requestor 0 */
19#define SSB_PCICORE_ARBCTL_PARKID_EXT1 0x00000006 /* External requestor 1 */
20#define SSB_PCICORE_ISTAT 0x0020 /* Interrupt status */
21#define SSB_PCICORE_ISTAT_INTA 0x00000001 /* PCI INTA# */
22#define SSB_PCICORE_ISTAT_INTB 0x00000002 /* PCI INTB# */
23#define SSB_PCICORE_ISTAT_SERR 0x00000004 /* PCI SERR# (write to clear) */
24#define SSB_PCICORE_ISTAT_PERR 0x00000008 /* PCI PERR# (write to clear) */
25#define SSB_PCICORE_ISTAT_PME 0x00000010 /* PCI PME# */
26#define SSB_PCICORE_IMASK 0x0024 /* Interrupt mask */
27#define SSB_PCICORE_IMASK_INTA 0x00000001 /* PCI INTA# */
28#define SSB_PCICORE_IMASK_INTB 0x00000002 /* PCI INTB# */
29#define SSB_PCICORE_IMASK_SERR 0x00000004 /* PCI SERR# */
30#define SSB_PCICORE_IMASK_PERR 0x00000008 /* PCI PERR# */
31#define SSB_PCICORE_IMASK_PME 0x00000010 /* PCI PME# */
32#define SSB_PCICORE_MBOX 0x0028 /* Backplane to PCI Mailbox */
33#define SSB_PCICORE_MBOX_F0_0 0x00000100 /* PCI function 0, INT 0 */
34#define SSB_PCICORE_MBOX_F0_1 0x00000200 /* PCI function 0, INT 1 */
35#define SSB_PCICORE_MBOX_F1_0 0x00000400 /* PCI function 1, INT 0 */
36#define SSB_PCICORE_MBOX_F1_1 0x00000800 /* PCI function 1, INT 1 */
37#define SSB_PCICORE_MBOX_F2_0 0x00001000 /* PCI function 2, INT 0 */
38#define SSB_PCICORE_MBOX_F2_1 0x00002000 /* PCI function 2, INT 1 */
39#define SSB_PCICORE_MBOX_F3_0 0x00004000 /* PCI function 3, INT 0 */
40#define SSB_PCICORE_MBOX_F3_1 0x00008000 /* PCI function 3, INT 1 */
41#define SSB_PCICORE_BCAST_ADDR 0x0050 /* Backplane Broadcast Address */
42#define SSB_PCICORE_BCAST_ADDR_MASK 0x000000FF
43#define SSB_PCICORE_BCAST_DATA 0x0054 /* Backplane Broadcast Data */
44#define SSB_PCICORE_GPIO_IN 0x0060 /* rev >= 2 only */
45#define SSB_PCICORE_GPIO_OUT 0x0064 /* rev >= 2 only */
46#define SSB_PCICORE_GPIO_ENABLE 0x0068 /* rev >= 2 only */
47#define SSB_PCICORE_GPIO_CTL 0x006C /* rev >= 2 only */
48#define SSB_PCICORE_SBTOPCI0 0x0100 /* Backplane to PCI translation 0 (sbtopci0) */
49#define SSB_PCICORE_SBTOPCI0_MASK 0xFC000000
50#define SSB_PCICORE_SBTOPCI1 0x0104 /* Backplane to PCI translation 1 (sbtopci1) */
51#define SSB_PCICORE_SBTOPCI1_MASK 0xFC000000
52#define SSB_PCICORE_SBTOPCI2 0x0108 /* Backplane to PCI translation 2 (sbtopci2) */
53#define SSB_PCICORE_SBTOPCI2_MASK 0xC0000000
54
55/* SBtoPCIx */
56#define SSB_PCICORE_SBTOPCI_MEM 0x00000000
57#define SSB_PCICORE_SBTOPCI_IO 0x00000001
58#define SSB_PCICORE_SBTOPCI_CFG0 0x00000002
59#define SSB_PCICORE_SBTOPCI_CFG1 0x00000003
60#define SSB_PCICORE_SBTOPCI_PREF 0x00000004 /* Prefetch enable */
61#define SSB_PCICORE_SBTOPCI_BURST 0x00000008 /* Burst enable */
62#define SSB_PCICORE_SBTOPCI_MRM 0x00000020 /* Memory Read Multiple */
63#define SSB_PCICORE_SBTOPCI_RC 0x00000030 /* Read Command mask (rev >= 11) */
64#define SSB_PCICORE_SBTOPCI_RC_READ 0x00000000 /* Memory read */
65#define SSB_PCICORE_SBTOPCI_RC_READL 0x00000010 /* Memory read line */
66#define SSB_PCICORE_SBTOPCI_RC_READM 0x00000020 /* Memory read multiple */
67
68
69/* PCIcore specific boardflags */
70#define SSB_PCICORE_BFL_NOPCI 0x00000400 /* Board leaves PCI floating */
71
72
73struct ssb_pcicore {
74 struct ssb_device *dev;
75 u8 setup_done:1;
76 u8 hostmode:1;
77 u8 cardbusmode:1;
78};
79
80extern void ssb_pcicore_init(struct ssb_pcicore *pc);
81
82/* Enable IRQ routing for a specific device */
83extern int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
84 struct ssb_device *dev);
85
86
87#else /* CONFIG_SSB_DRIVER_PCICORE */
88
89
90struct ssb_pcicore {
91};
92
93static inline
94void ssb_pcicore_init(struct ssb_pcicore *pc)
95{
96}
97
98static inline
99int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
100 struct ssb_device *dev)
101{
102 return 0;
103}
104
105#endif /* CONFIG_SSB_DRIVER_PCICORE */
106#endif /* LINUX_SSB_PCICORE_H_ */
diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h
new file mode 100644
index 000000000000..47c7c71a5acf
--- /dev/null
+++ b/include/linux/ssb/ssb_regs.h
@@ -0,0 +1,292 @@
1#ifndef LINUX_SSB_REGS_H_
2#define LINUX_SSB_REGS_H_
3
4
5/* SiliconBackplane Address Map.
6 * All regions may not exist on all chips.
7 */
8#define SSB_SDRAM_BASE 0x00000000U /* Physical SDRAM */
9#define SSB_PCI_MEM 0x08000000U /* Host Mode sb2pcitranslation0 (64 MB) */
10#define SSB_PCI_CFG 0x0c000000U /* Host Mode sb2pcitranslation1 (64 MB) */
11#define SSB_SDRAM_SWAPPED 0x10000000U /* Byteswapped Physical SDRAM */
12#define SSB_ENUM_BASE 0x18000000U /* Enumeration space base */
13#define SSB_ENUM_LIMIT 0x18010000U /* Enumeration space limit */
14
15#define SSB_FLASH2 0x1c000000U /* Flash Region 2 (region 1 shadowed here) */
16#define SSB_FLASH2_SZ 0x02000000U /* Size of Flash Region 2 */
17
18#define SSB_EXTIF_BASE 0x1f000000U /* External Interface region base address */
19#define SSB_FLASH1 0x1fc00000U /* Flash Region 1 */
20#define SSB_FLASH1_SZ 0x00400000U /* Size of Flash Region 1 */
21
22#define SSB_PCI_DMA 0x40000000U /* Client Mode sb2pcitranslation2 (1 GB) */
23#define SSB_PCI_DMA_SZ 0x40000000U /* Client Mode sb2pcitranslation2 size in bytes */
24#define SSB_PCIE_DMA_L32 0x00000000U /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */
25#define SSB_PCIE_DMA_H32 0x80000000U /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
26#define SSB_EUART (SSB_EXTIF_BASE + 0x00800000)
27#define SSB_LED (SSB_EXTIF_BASE + 0x00900000)
28
29
30/* Enumeration space constants */
31#define SSB_CORE_SIZE 0x1000 /* Size of a core MMIO area */
32#define SSB_MAX_NR_CORES ((SSB_ENUM_LIMIT - SSB_ENUM_BASE) / SSB_CORE_SIZE)
33
34
35/* mips address */
36#define SSB_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */
37
38
39/* SSB PCI config space registers. */
40#define SSB_PMCSR 0x44
41#define SSB_PE 0x100
42#define SSB_BAR0_WIN 0x80 /* Backplane address space 0 */
43#define SSB_BAR1_WIN 0x84 /* Backplane address space 1 */
44#define SSB_SPROMCTL 0x88 /* SPROM control */
45#define SSB_SPROMCTL_WE 0x10 /* SPROM write enable */
46#define SSB_BAR1_CONTROL 0x8c /* Address space 1 burst control */
47#define SSB_PCI_IRQS 0x90 /* PCI interrupts */
48#define SSB_PCI_IRQMASK 0x94 /* PCI IRQ control and mask (pcirev >= 6 only) */
49#define SSB_BACKPLANE_IRQS 0x98 /* Backplane Interrupts */
50#define SSB_GPIO_IN 0xB0 /* GPIO Input (pcirev >= 3 only) */
51#define SSB_GPIO_OUT 0xB4 /* GPIO Output (pcirev >= 3 only) */
52#define SSB_GPIO_OUT_ENABLE 0xB8 /* GPIO Output Enable/Disable (pcirev >= 3 only) */
53#define SSB_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */
54#define SSB_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */
55#define SSB_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */
56#define SSB_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */
57
58
59#define SSB_BAR0_MAX_RETRIES 50
60
61/* Silicon backplane configuration register definitions */
62#define SSB_IPSFLAG 0x0F08
63#define SSB_IPSFLAG_IRQ1 0x0000003F /* which sbflags get routed to mips interrupt 1 */
64#define SSB_IPSFLAG_IRQ1_SHIFT 0
65#define SSB_IPSFLAG_IRQ2 0x00003F00 /* which sbflags get routed to mips interrupt 2 */
66#define SSB_IPSFLAG_IRQ2_SHIFT 8
67#define SSB_IPSFLAG_IRQ3 0x003F0000 /* which sbflags get routed to mips interrupt 3 */
68#define SSB_IPSFLAG_IRQ3_SHIFT 16
69#define SSB_IPSFLAG_IRQ4 0x3F000000 /* which sbflags get routed to mips interrupt 4 */
70#define SSB_IPSFLAG_IRQ4_SHIFT 24
71#define SSB_TPSFLAG 0x0F18
72#define SSB_TPSFLAG_BPFLAG 0x0000003F /* Backplane flag # */
73#define SSB_TPSFLAG_ALWAYSIRQ 0x00000040 /* IRQ is always sent on the Backplane */
74#define SSB_TMERRLOGA 0x0F48
75#define SSB_TMERRLOG 0x0F50
76#define SSB_ADMATCH3 0x0F60
77#define SSB_ADMATCH2 0x0F68
78#define SSB_ADMATCH1 0x0F70
79#define SSB_IMSTATE 0x0F90 /* SB Initiator Agent State */
80#define SSB_IMSTATE_PC 0x0000000f /* Pipe Count */
81#define SSB_IMSTATE_AP_MASK 0x00000030 /* Arbitration Priority */
82#define SSB_IMSTATE_AP_BOTH 0x00000000 /* Use both timeslices and token */
83#define SSB_IMSTATE_AP_TS 0x00000010 /* Use timeslices only */
84#define SSB_IMSTATE_AP_TK 0x00000020 /* Use token only */
85#define SSB_IMSTATE_AP_RSV 0x00000030 /* Reserved */
86#define SSB_IMSTATE_IBE 0x00020000 /* In Band Error */
87#define SSB_IMSTATE_TO 0x00040000 /* Timeout */
88#define SSB_INTVEC 0x0F94 /* SB Interrupt Mask */
89#define SSB_INTVEC_PCI 0x00000001 /* Enable interrupts for PCI */
90#define SSB_INTVEC_ENET0 0x00000002 /* Enable interrupts for enet 0 */
91#define SSB_INTVEC_ILINE20 0x00000004 /* Enable interrupts for iline20 */
92#define SSB_INTVEC_CODEC 0x00000008 /* Enable interrupts for v90 codec */
93#define SSB_INTVEC_USB 0x00000010 /* Enable interrupts for usb */
94#define SSB_INTVEC_EXTIF 0x00000020 /* Enable interrupts for external i/f */
95#define SSB_INTVEC_ENET1 0x00000040 /* Enable interrupts for enet 1 */
96#define SSB_TMSLOW 0x0F98 /* SB Target State Low */
97#define SSB_TMSLOW_RESET 0x00000001 /* Reset */
98#define SSB_TMSLOW_REJECT_22 0x00000002 /* Reject (Backplane rev 2.2) */
99#define SSB_TMSLOW_REJECT_23 0x00000004 /* Reject (Backplane rev 2.3) */
100#define SSB_TMSLOW_CLOCK 0x00010000 /* Clock Enable */
101#define SSB_TMSLOW_FGC 0x00020000 /* Force Gated Clocks On */
102#define SSB_TMSLOW_PE 0x40000000 /* Power Management Enable */
103#define SSB_TMSLOW_BE 0x80000000 /* BIST Enable */
104#define SSB_TMSHIGH 0x0F9C /* SB Target State High */
105#define SSB_TMSHIGH_SERR 0x00000001 /* S-error */
106#define SSB_TMSHIGH_INT 0x00000002 /* Interrupt */
107#define SSB_TMSHIGH_BUSY 0x00000004 /* Busy */
108#define SSB_TMSHIGH_TO 0x00000020 /* Timeout. Backplane rev >= 2.3 only */
109#define SSB_TMSHIGH_COREFL 0x1FFF0000 /* Core specific flags */
110#define SSB_TMSHIGH_COREFL_SHIFT 16
111#define SSB_TMSHIGH_DMA64 0x10000000 /* 64bit DMA supported */
112#define SSB_TMSHIGH_GCR 0x20000000 /* Gated Clock Request */
113#define SSB_TMSHIGH_BISTF 0x40000000 /* BIST Failed */
114#define SSB_TMSHIGH_BISTD 0x80000000 /* BIST Done */
115#define SSB_BWA0 0x0FA0
116#define SSB_IMCFGLO 0x0FA8
117#define SSB_IMCFGLO_SERTO 0x00000007 /* Service timeout */
118#define SSB_IMCFGLO_REQTO 0x00000070 /* Request timeout */
119#define SSB_IMCFGLO_REQTO_SHIFT 4
120#define SSB_IMCFGLO_CONNID 0x00FF0000 /* Connection ID */
121#define SSB_IMCFGLO_CONNID_SHIFT 16
122#define SSB_IMCFGHI 0x0FAC
123#define SSB_ADMATCH0 0x0FB0
124#define SSB_TMCFGLO 0x0FB8
125#define SSB_TMCFGHI 0x0FBC
126#define SSB_BCONFIG 0x0FC0
127#define SSB_BSTATE 0x0FC8
128#define SSB_ACTCFG 0x0FD8
129#define SSB_FLAGST 0x0FE8
130#define SSB_IDLOW 0x0FF8
131#define SSB_IDLOW_CFGSP 0x00000003 /* Config Space */
132#define SSB_IDLOW_ADDRNGE 0x00000038 /* Address Ranges supported */
133#define SSB_IDLOW_ADDRNGE_SHIFT 3
134#define SSB_IDLOW_SYNC 0x00000040
135#define SSB_IDLOW_INITIATOR 0x00000080
136#define SSB_IDLOW_MIBL 0x00000F00 /* Minimum Backplane latency */
137#define SSB_IDLOW_MIBL_SHIFT 8
138#define SSB_IDLOW_MABL 0x0000F000 /* Maximum Backplane latency */
139#define SSB_IDLOW_MABL_SHIFT 12
140#define SSB_IDLOW_TIF 0x00010000 /* This Initiator is first */
141#define SSB_IDLOW_CCW 0x000C0000 /* Cycle counter width */
142#define SSB_IDLOW_CCW_SHIFT 18
143#define SSB_IDLOW_TPT 0x00F00000 /* Target ports */
144#define SSB_IDLOW_TPT_SHIFT 20
145#define SSB_IDLOW_INITP 0x0F000000 /* Initiator ports */
146#define SSB_IDLOW_INITP_SHIFT 24
147#define SSB_IDLOW_SSBREV 0xF0000000 /* Sonics Backplane Revision code */
148#define SSB_IDLOW_SSBREV_22 0x00000000 /* <= 2.2 */
149#define SSB_IDLOW_SSBREV_23 0x10000000 /* 2.3 */
150#define SSB_IDHIGH 0x0FFC /* SB Identification High */
151#define SSB_IDHIGH_RCLO 0x0000000F /* Revision Code (low part) */
152#define SSB_IDHIGH_CC 0x00008FF0 /* Core Code */
153#define SSB_IDHIGH_CC_SHIFT 4
154#define SSB_IDHIGH_RCHI 0x00007000 /* Revision Code (high part) */
155#define SSB_IDHIGH_RCHI_SHIFT 8 /* yes, shift 8 is right */
156#define SSB_IDHIGH_VC 0xFFFF0000 /* Vendor Code */
157#define SSB_IDHIGH_VC_SHIFT 16
158
159/* SPROM shadow area. If not otherwise noted, fields are
160 * two bytes wide. Note that the SPROM can _only_ be read
161 * in two-byte quantinies.
162 */
163#define SSB_SPROMSIZE_WORDS 64
164#define SSB_SPROMSIZE_BYTES (SSB_SPROMSIZE_WORDS * sizeof(u16))
165#define SSB_SPROM_BASE 0x1000
166#define SSB_SPROM_REVISION 0x107E
167#define SSB_SPROM_REVISION_REV 0x00FF /* SPROM Revision number */
168#define SSB_SPROM_REVISION_CRC 0xFF00 /* SPROM CRC8 value */
169#define SSB_SPROM_REVISION_CRC_SHIFT 8
170/* SPROM Revision 1 */
171#define SSB_SPROM1_SPID 0x1004 /* Subsystem Product ID for PCI */
172#define SSB_SPROM1_SVID 0x1006 /* Subsystem Vendor ID for PCI */
173#define SSB_SPROM1_PID 0x1008 /* Product ID for PCI */
174#define SSB_SPROM1_IL0MAC 0x1048 /* 6 bytes MAC address for 802.11b/g */
175#define SSB_SPROM1_ET0MAC 0x104E /* 6 bytes MAC address for Ethernet */
176#define SSB_SPROM1_ET1MAC 0x1054 /* 6 bytes MAC address for 802.11a */
177#define SSB_SPROM1_ETHPHY 0x105A /* Ethernet PHY settings */
178#define SSB_SPROM1_ETHPHY_ET0A 0x001F /* MII Address for enet0 */
179#define SSB_SPROM1_ETHPHY_ET1A 0x03E0 /* MII Address for enet1 */
180#define SSB_SPROM1_ETHPHY_ET1A_SHIFT 5
181#define SSB_SPROM1_ETHPHY_ET0M (1<<14) /* MDIO for enet0 */
182#define SSB_SPROM1_ETHPHY_ET1M (1<<15) /* MDIO for enet1 */
183#define SSB_SPROM1_BINF 0x105C /* Board info */
184#define SSB_SPROM1_BINF_BREV 0x00FF /* Board Revision */
185#define SSB_SPROM1_BINF_CCODE 0x0F00 /* Country Code */
186#define SSB_SPROM1_BINF_CCODE_SHIFT 8
187#define SSB_SPROM1_BINF_ANTA 0x3000 /* Available A-PHY antennas */
188#define SSB_SPROM1_BINF_ANTA_SHIFT 12
189#define SSB_SPROM1_BINF_ANTBG 0xC000 /* Available B-PHY antennas */
190#define SSB_SPROM1_BINF_ANTBG_SHIFT 14
191#define SSB_SPROM1_PA0B0 0x105E
192#define SSB_SPROM1_PA0B1 0x1060
193#define SSB_SPROM1_PA0B2 0x1062
194#define SSB_SPROM1_GPIOA 0x1064 /* General Purpose IO pins 0 and 1 */
195#define SSB_SPROM1_GPIOA_P0 0x00FF /* Pin 0 */
196#define SSB_SPROM1_GPIOA_P1 0xFF00 /* Pin 1 */
197#define SSB_SPROM1_GPIOA_P1_SHIFT 8
198#define SSB_SPROM1_GPIOB 0x1066 /* General Purpuse IO pins 2 and 3 */
199#define SSB_SPROM1_GPIOB_P2 0x00FF /* Pin 2 */
200#define SSB_SPROM1_GPIOB_P3 0xFF00 /* Pin 3 */
201#define SSB_SPROM1_GPIOB_P3_SHIFT 8
202#define SSB_SPROM1_MAXPWR 0x1068 /* Power Amplifier Max Power */
203#define SSB_SPROM1_MAXPWR_BG 0x00FF /* B-PHY and G-PHY (in dBm Q5.2) */
204#define SSB_SPROM1_MAXPWR_A 0xFF00 /* A-PHY (in dBm Q5.2) */
205#define SSB_SPROM1_MAXPWR_A_SHIFT 8
206#define SSB_SPROM1_PA1B0 0x106A
207#define SSB_SPROM1_PA1B1 0x106C
208#define SSB_SPROM1_PA1B2 0x106E
209#define SSB_SPROM1_ITSSI 0x1070 /* Idle TSSI Target */
210#define SSB_SPROM1_ITSSI_BG 0x00FF /* B-PHY and G-PHY*/
211#define SSB_SPROM1_ITSSI_A 0xFF00 /* A-PHY */
212#define SSB_SPROM1_ITSSI_A_SHIFT 8
213#define SSB_SPROM1_BFLLO 0x1072 /* Boardflags (low 16 bits) */
214#define SSB_SPROM1_AGAIN 0x1074 /* Antenna Gain (in dBm Q5.2) */
215#define SSB_SPROM1_AGAIN_A 0x00FF /* A-PHY */
216#define SSB_SPROM1_AGAIN_BG 0xFF00 /* B-PHY and G-PHY */
217#define SSB_SPROM1_AGAIN_BG_SHIFT 8
218#define SSB_SPROM1_OEM 0x1076 /* 8 bytes OEM string (rev 1 only) */
219/* SPROM Revision 2 (inherits from rev 1) */
220#define SSB_SPROM2_BFLHI 0x1038 /* Boardflags (high 16 bits) */
221#define SSB_SPROM2_MAXP_A 0x103A /* A-PHY Max Power */
222#define SSB_SPROM2_MAXP_A_HI 0x00FF /* Max Power High */
223#define SSB_SPROM2_MAXP_A_LO 0xFF00 /* Max Power Low */
224#define SSB_SPROM2_MAXP_A_LO_SHIFT 8
225#define SSB_SPROM2_PA1LOB0 0x103C /* A-PHY PowerAmplifier Low Settings */
226#define SSB_SPROM2_PA1LOB1 0x103E /* A-PHY PowerAmplifier Low Settings */
227#define SSB_SPROM2_PA1LOB2 0x1040 /* A-PHY PowerAmplifier Low Settings */
228#define SSB_SPROM2_PA1HIB0 0x1042 /* A-PHY PowerAmplifier High Settings */
229#define SSB_SPROM2_PA1HIB1 0x1044 /* A-PHY PowerAmplifier High Settings */
230#define SSB_SPROM2_PA1HIB2 0x1046 /* A-PHY PowerAmplifier High Settings */
231#define SSB_SPROM2_OPO 0x1078 /* OFDM Power Offset from CCK Level */
232#define SSB_SPROM2_OPO_VALUE 0x00FF
233#define SSB_SPROM2_OPO_UNUSED 0xFF00
234#define SSB_SPROM2_CCODE 0x107C /* Two char Country Code */
235/* SPROM Revision 3 (inherits from rev 2) */
236#define SSB_SPROM3_OFDMAPO 0x102C /* A-PHY OFDM Mid Power Offset (4 bytes, BigEndian) */
237#define SSB_SPROM3_OFDMALPO 0x1030 /* A-PHY OFDM Low Power Offset (4 bytes, BigEndian) */
238#define SSB_SPROM3_OFDMAHPO 0x1034 /* A-PHY OFDM High Power Offset (4 bytes, BigEndian) */
239#define SSB_SPROM3_GPIOLDC 0x1042 /* GPIO LED Powersave Duty Cycle (4 bytes, BigEndian) */
240#define SSB_SPROM3_GPIOLDC_OFF 0x0000FF00 /* Off Count */
241#define SSB_SPROM3_GPIOLDC_OFF_SHIFT 8
242#define SSB_SPROM3_GPIOLDC_ON 0x00FF0000 /* On Count */
243#define SSB_SPROM3_GPIOLDC_ON_SHIFT 16
244#define SSB_SPROM3_CCKPO 0x1078 /* CCK Power Offset */
245#define SSB_SPROM3_CCKPO_1M 0x000F /* 1M Rate PO */
246#define SSB_SPROM3_CCKPO_2M 0x00F0 /* 2M Rate PO */
247#define SSB_SPROM3_CCKPO_2M_SHIFT 4
248#define SSB_SPROM3_CCKPO_55M 0x0F00 /* 5.5M Rate PO */
249#define SSB_SPROM3_CCKPO_55M_SHIFT 8
250#define SSB_SPROM3_CCKPO_11M 0xF000 /* 11M Rate PO */
251#define SSB_SPROM3_CCKPO_11M_SHIFT 12
252#define SSB_SPROM3_OFDMGPO 0x107A /* G-PHY OFDM Power Offset (4 bytes, BigEndian) */
253
254/* Values for SSB_SPROM1_BINF_CCODE */
255enum {
256 SSB_SPROM1CCODE_WORLD = 0,
257 SSB_SPROM1CCODE_THAILAND,
258 SSB_SPROM1CCODE_ISRAEL,
259 SSB_SPROM1CCODE_JORDAN,
260 SSB_SPROM1CCODE_CHINA,
261 SSB_SPROM1CCODE_JAPAN,
262 SSB_SPROM1CCODE_USA_CANADA_ANZ,
263 SSB_SPROM1CCODE_EUROPE,
264 SSB_SPROM1CCODE_USA_LOW,
265 SSB_SPROM1CCODE_JAPAN_HIGH,
266 SSB_SPROM1CCODE_ALL,
267 SSB_SPROM1CCODE_NONE,
268};
269
270/* Address-Match values and masks (SSB_ADMATCHxxx) */
271#define SSB_ADM_TYPE 0x00000003 /* Address type */
272#define SSB_ADM_TYPE0 0
273#define SSB_ADM_TYPE1 1
274#define SSB_ADM_TYPE2 2
275#define SSB_ADM_AD64 0x00000004
276#define SSB_ADM_SZ0 0x000000F8 /* Type0 size */
277#define SSB_ADM_SZ0_SHIFT 3
278#define SSB_ADM_SZ1 0x000001F8 /* Type1 size */
279#define SSB_ADM_SZ1_SHIFT 3
280#define SSB_ADM_SZ2 0x000001F8 /* Type2 size */
281#define SSB_ADM_SZ2_SHIFT 3
282#define SSB_ADM_EN 0x00000400 /* Enable */
283#define SSB_ADM_NEG 0x00000800 /* Negative decode */
284#define SSB_ADM_BASE0 0xFFFFFF00 /* Type0 base address */
285#define SSB_ADM_BASE0_SHIFT 8
286#define SSB_ADM_BASE1 0xFFFFF000 /* Type1 base address for the core */
287#define SSB_ADM_BASE1_SHIFT 12
288#define SSB_ADM_BASE2 0xFFFF0000 /* Type2 base address for the core */
289#define SSB_ADM_BASE2_SHIFT 16
290
291
292#endif /* LINUX_SSB_REGS_H_ */
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 8a09021d8c59..895ba3ac6208 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -484,6 +484,21 @@ static int do_parisc_entry(const char *filename, struct parisc_device_id *id,
484 return 1; 484 return 1;
485} 485}
486 486
487/* Looks like: ssb:vNidNrevN. */
488static int do_ssb_entry(const char *filename,
489 struct ssb_device_id *id, char *alias)
490{
491 id->vendor = TO_NATIVE(id->vendor);
492 id->coreid = TO_NATIVE(id->coreid);
493 id->revision = TO_NATIVE(id->revision);
494
495 strcpy(alias, "ssb:");
496 ADD(alias, "v", id->vendor != SSB_ANY_VENDOR, id->vendor);
497 ADD(alias, "id", id->coreid != SSB_ANY_ID, id->coreid);
498 ADD(alias, "rev", id->revision != SSB_ANY_REV, id->revision);
499 return 1;
500}
501
487/* Ignore any prefix, eg. v850 prepends _ */ 502/* Ignore any prefix, eg. v850 prepends _ */
488static inline int sym_is(const char *symbol, const char *name) 503static inline int sym_is(const char *symbol, const char *name)
489{ 504{
@@ -599,6 +614,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
599 do_table(symval, sym->st_size, 614 do_table(symval, sym->st_size,
600 sizeof(struct parisc_device_id), "parisc", 615 sizeof(struct parisc_device_id), "parisc",
601 do_parisc_entry, mod); 616 do_parisc_entry, mod);
617 else if (sym_is(symname, "__mod_ssb_device_table"))
618 do_table(symval, sym->st_size,
619 sizeof(struct ssb_device_id), "ssb",
620 do_ssb_entry, mod);
602} 621}
603 622
604/* Now add out buffered information to the generated C source */ 623/* Now add out buffered information to the generated C source */