kernel: update bcma and ssb to version master-2012-04-12 from wireless-testing
[openwrt/svn-archive/archive.git] / target / linux / generic / patches-3.0 / 025-bcma_backport.patch
1 --- a/drivers/bcma/Kconfig
2 +++ b/drivers/bcma/Kconfig
3 @@ -13,6 +13,11 @@ config BCMA
4 Bus driver for Broadcom specific Advanced Microcontroller Bus
5 Architecture.
6
7 +# Support for Block-I/O. SELECT this from the driver that needs it.
8 +config BCMA_BLOCKIO
9 + bool
10 + depends on BCMA
11 +
12 config BCMA_HOST_PCI_POSSIBLE
13 bool
14 depends on BCMA && PCI = y
15 @@ -22,6 +27,25 @@ config BCMA_HOST_PCI
16 bool "Support for BCMA on PCI-host bus"
17 depends on BCMA_HOST_PCI_POSSIBLE
18
19 +config BCMA_DRIVER_PCI_HOSTMODE
20 + bool "Driver for PCI core working in hostmode"
21 + depends on BCMA && MIPS && BCMA_HOST_PCI
22 + help
23 + PCI core hostmode operation (external PCI bus).
24 +
25 +config BCMA_HOST_SOC
26 + bool
27 + depends on BCMA_DRIVER_MIPS
28 +
29 +config BCMA_DRIVER_MIPS
30 + bool "BCMA Broadcom MIPS core driver"
31 + depends on BCMA && MIPS
32 + help
33 + Driver for the Broadcom MIPS core attached to Broadcom specific
34 + Advanced Microcontroller Bus.
35 +
36 + If unsure, say N
37 +
38 config BCMA_DEBUG
39 bool "BCMA debugging"
40 depends on BCMA
41 --- a/drivers/bcma/Makefile
42 +++ b/drivers/bcma/Makefile
43 @@ -1,7 +1,10 @@
44 -bcma-y += main.o scan.o core.o
45 +bcma-y += main.o scan.o core.o sprom.o
46 bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
47 bcma-y += driver_pci.o
48 +bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o
49 +bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o
50 bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
51 +bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o
52 obj-$(CONFIG_BCMA) += bcma.o
53
54 ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG
55 --- a/drivers/bcma/bcma_private.h
56 +++ b/drivers/bcma/bcma_private.h
57 @@ -13,11 +13,34 @@
58 struct bcma_bus;
59
60 /* main.c */
61 -extern int bcma_bus_register(struct bcma_bus *bus);
62 -extern void bcma_bus_unregister(struct bcma_bus *bus);
63 +int __devinit bcma_bus_register(struct bcma_bus *bus);
64 +void bcma_bus_unregister(struct bcma_bus *bus);
65 +int __init bcma_bus_early_register(struct bcma_bus *bus,
66 + struct bcma_device *core_cc,
67 + struct bcma_device *core_mips);
68 +#ifdef CONFIG_PM
69 +int bcma_bus_suspend(struct bcma_bus *bus);
70 +int bcma_bus_resume(struct bcma_bus *bus);
71 +#endif
72
73 /* scan.c */
74 int bcma_bus_scan(struct bcma_bus *bus);
75 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
76 + struct bcma_device_id *match,
77 + struct bcma_device *core);
78 +void bcma_init_bus(struct bcma_bus *bus);
79 +
80 +/* sprom.c */
81 +int bcma_sprom_get(struct bcma_bus *bus);
82 +
83 +/* driver_chipcommon.c */
84 +#ifdef CONFIG_BCMA_DRIVER_MIPS
85 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
86 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
87 +
88 +/* driver_chipcommon_pmu.c */
89 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc);
90 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
91
92 #ifdef CONFIG_BCMA_HOST_PCI
93 /* host_pci.c */
94 @@ -25,4 +48,12 @@ extern int __init bcma_host_pci_init(voi
95 extern void __exit bcma_host_pci_exit(void);
96 #endif /* CONFIG_BCMA_HOST_PCI */
97
98 +/* driver_pci.c */
99 +u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
100 +
101 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
102 +bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc);
103 +void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
104 +#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
105 +
106 #endif
107 --- a/drivers/bcma/core.c
108 +++ b/drivers/bcma/core.c
109 @@ -19,7 +19,7 @@ bool bcma_core_is_enabled(struct bcma_de
110 }
111 EXPORT_SYMBOL_GPL(bcma_core_is_enabled);
112
113 -static void bcma_core_disable(struct bcma_device *core, u32 flags)
114 +void bcma_core_disable(struct bcma_device *core, u32 flags)
115 {
116 if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
117 return;
118 @@ -31,6 +31,7 @@ static void bcma_core_disable(struct bcm
119 bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
120 udelay(1);
121 }
122 +EXPORT_SYMBOL_GPL(bcma_core_disable);
123
124 int bcma_core_enable(struct bcma_device *core, u32 flags)
125 {
126 @@ -49,3 +50,77 @@ int bcma_core_enable(struct bcma_device
127 return 0;
128 }
129 EXPORT_SYMBOL_GPL(bcma_core_enable);
130 +
131 +void bcma_core_set_clockmode(struct bcma_device *core,
132 + enum bcma_clkmode clkmode)
133 +{
134 + u16 i;
135 +
136 + WARN_ON(core->id.id != BCMA_CORE_CHIPCOMMON &&
137 + core->id.id != BCMA_CORE_PCIE &&
138 + core->id.id != BCMA_CORE_80211);
139 +
140 + switch (clkmode) {
141 + case BCMA_CLKMODE_FAST:
142 + bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
143 + udelay(64);
144 + for (i = 0; i < 1500; i++) {
145 + if (bcma_read32(core, BCMA_CLKCTLST) &
146 + BCMA_CLKCTLST_HAVEHT) {
147 + i = 0;
148 + break;
149 + }
150 + udelay(10);
151 + }
152 + if (i)
153 + pr_err("HT force timeout\n");
154 + break;
155 + case BCMA_CLKMODE_DYNAMIC:
156 + pr_warn("Dynamic clockmode not supported yet!\n");
157 + break;
158 + }
159 +}
160 +EXPORT_SYMBOL_GPL(bcma_core_set_clockmode);
161 +
162 +void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on)
163 +{
164 + u16 i;
165 +
166 + WARN_ON(req & ~BCMA_CLKCTLST_EXTRESREQ);
167 + WARN_ON(status & ~BCMA_CLKCTLST_EXTRESST);
168 +
169 + if (on) {
170 + bcma_set32(core, BCMA_CLKCTLST, req);
171 + for (i = 0; i < 10000; i++) {
172 + if ((bcma_read32(core, BCMA_CLKCTLST) & status) ==
173 + status) {
174 + i = 0;
175 + break;
176 + }
177 + udelay(10);
178 + }
179 + if (i)
180 + pr_err("PLL enable timeout\n");
181 + } else {
182 + pr_warn("Disabling PLL not supported yet!\n");
183 + }
184 +}
185 +EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
186 +
187 +u32 bcma_core_dma_translation(struct bcma_device *core)
188 +{
189 + switch (core->bus->hosttype) {
190 + case BCMA_HOSTTYPE_SOC:
191 + return 0;
192 + case BCMA_HOSTTYPE_PCI:
193 + if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
194 + return BCMA_DMA_TRANSLATION_DMA64_CMT;
195 + else
196 + return BCMA_DMA_TRANSLATION_DMA32_CMT;
197 + default:
198 + pr_err("DMA translation unknown for host %d\n",
199 + core->bus->hosttype);
200 + }
201 + return BCMA_DMA_TRANSLATION_NONE;
202 +}
203 +EXPORT_SYMBOL(bcma_core_dma_translation);
204 --- a/drivers/bcma/driver_chipcommon.c
205 +++ b/drivers/bcma/driver_chipcommon.c
206 @@ -3,7 +3,7 @@
207 * ChipCommon core driver
208 *
209 * Copyright 2005, Broadcom Corporation
210 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
211 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
212 *
213 * Licensed under the GNU/GPL. See COPYING for details.
214 */
215 @@ -23,6 +23,12 @@ static inline u32 bcma_cc_write32_masked
216
217 void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
218 {
219 + u32 leddc_on = 10;
220 + u32 leddc_off = 90;
221 +
222 + if (cc->setup_done)
223 + return;
224 +
225 if (cc->core->id.rev >= 11)
226 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
227 cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
228 @@ -38,6 +44,19 @@ void bcma_core_chipcommon_init(struct bc
229 bcma_pmu_init(cc);
230 if (cc->capabilities & BCMA_CC_CAP_PCTL)
231 pr_err("Power control not implemented!\n");
232 +
233 + if (cc->core->id.rev >= 16) {
234 + if (cc->core->bus->sprom.leddc_on_time &&
235 + cc->core->bus->sprom.leddc_off_time) {
236 + leddc_on = cc->core->bus->sprom.leddc_on_time;
237 + leddc_off = cc->core->bus->sprom.leddc_off_time;
238 + }
239 + bcma_cc_write32(cc, BCMA_CC_GPIOTIMER,
240 + ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
241 + (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
242 + }
243 +
244 + cc->setup_done = true;
245 }
246
247 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
248 @@ -87,3 +106,51 @@ u32 bcma_chipco_gpio_polarity(struct bcm
249 {
250 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
251 }
252 +
253 +#ifdef CONFIG_BCMA_DRIVER_MIPS
254 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
255 +{
256 + unsigned int irq;
257 + u32 baud_base;
258 + u32 i;
259 + unsigned int ccrev = cc->core->id.rev;
260 + struct bcma_serial_port *ports = cc->serial_ports;
261 +
262 + if (ccrev >= 11 && ccrev != 15) {
263 + /* Fixed ALP clock */
264 + baud_base = bcma_pmu_alp_clock(cc);
265 + if (ccrev >= 21) {
266 + /* Turn off UART clock before switching clocksource. */
267 + bcma_cc_write32(cc, BCMA_CC_CORECTL,
268 + bcma_cc_read32(cc, BCMA_CC_CORECTL)
269 + & ~BCMA_CC_CORECTL_UARTCLKEN);
270 + }
271 + /* Set the override bit so we don't divide it */
272 + bcma_cc_write32(cc, BCMA_CC_CORECTL,
273 + bcma_cc_read32(cc, BCMA_CC_CORECTL)
274 + | BCMA_CC_CORECTL_UARTCLK0);
275 + if (ccrev >= 21) {
276 + /* Re-enable the UART clock. */
277 + bcma_cc_write32(cc, BCMA_CC_CORECTL,
278 + bcma_cc_read32(cc, BCMA_CC_CORECTL)
279 + | BCMA_CC_CORECTL_UARTCLKEN);
280 + }
281 + } else {
282 + pr_err("serial not supported on this device ccrev: 0x%x\n",
283 + ccrev);
284 + return;
285 + }
286 +
287 + irq = bcma_core_mips_irq(cc->core);
288 +
289 + /* Determine the registers of the UARTs */
290 + cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
291 + for (i = 0; i < cc->nr_serial_ports; i++) {
292 + ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
293 + (i * 256);
294 + ports[i].irq = irq;
295 + ports[i].baud_base = baud_base;
296 + ports[i].reg_shift = 0;
297 + }
298 +}
299 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
300 --- a/drivers/bcma/driver_chipcommon_pmu.c
301 +++ b/drivers/bcma/driver_chipcommon_pmu.c
302 @@ -2,7 +2,7 @@
303 * Broadcom specific AMBA
304 * ChipCommon Power Management Unit driver
305 *
306 - * Copyright 2009, Michael Buesch <mb@bu3sch.de>
307 + * Copyright 2009, Michael Buesch <m@bues.ch>
308 * Copyright 2007, Broadcom Corporation
309 *
310 * Licensed under the GNU/GPL. See COPYING for details.
311 @@ -11,20 +11,47 @@
312 #include "bcma_private.h"
313 #include <linux/bcma/bcma.h>
314
315 -static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
316 - u32 offset, u32 mask, u32 set)
317 +static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
318 {
319 - u32 value;
320 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
321 + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
322 + return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
323 +}
324
325 - bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
326 +void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
327 +{
328 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
329 + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
330 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
331 +}
332 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_write);
333 +
334 +void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
335 + u32 set)
336 +{
337 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
338 + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
339 + bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set);
340 +}
341 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset);
342 +
343 +void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
344 + u32 offset, u32 mask, u32 set)
345 +{
346 bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
347 bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
348 - value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
349 - value &= mask;
350 - value |= set;
351 - bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
352 - bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
353 + bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set);
354 +}
355 +EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset);
356 +
357 +void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
358 + u32 set)
359 +{
360 + bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset);
361 + bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR);
362 + bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set);
363 }
364 +EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
365
366 static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
367 {
368 @@ -52,7 +79,9 @@ static void bcma_pmu_resources_init(stru
369 min_msk = 0x200D;
370 max_msk = 0xFFFF;
371 break;
372 + case 0x4331:
373 case 43224:
374 + case 43225:
375 break;
376 default:
377 pr_err("PMU resource config unknown for device 0x%04X\n",
378 @@ -74,6 +103,7 @@ void bcma_pmu_swreg_init(struct bcma_drv
379 case 0x4313:
380 case 0x4331:
381 case 43224:
382 + case 43225:
383 break;
384 default:
385 pr_err("PMU switch/regulators init unknown for device "
386 @@ -81,6 +111,24 @@ void bcma_pmu_swreg_init(struct bcma_drv
387 }
388 }
389
390 +/* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
391 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
392 +{
393 + struct bcma_bus *bus = cc->core->bus;
394 + u32 val;
395 +
396 + val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL);
397 + if (enable) {
398 + val |= BCMA_CHIPCTL_4331_EXTPA_EN;
399 + if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
400 + val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
401 + } else {
402 + val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
403 + val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
404 + }
405 + bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
406 +}
407 +
408 void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
409 {
410 struct bcma_bus *bus = cc->core->bus;
411 @@ -90,17 +138,19 @@ void bcma_pmu_workarounds(struct bcma_dr
412 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
413 break;
414 case 0x4331:
415 - pr_err("Enabling Ext PA lines not implemented\n");
416 + /* BCM4331 workaround is SPROM-related, we put it in sprom.c */
417 break;
418 case 43224:
419 if (bus->chipinfo.rev == 0) {
420 pr_err("Workarounds for 43224 rev 0 not fully "
421 "implemented\n");
422 - bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
423 + bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x00F000F0);
424 } else {
425 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
426 }
427 break;
428 + case 43225:
429 + break;
430 default:
431 pr_err("Workarounds unknown for device 0x%04X\n",
432 bus->chipinfo.id);
433 @@ -132,3 +182,129 @@ void bcma_pmu_init(struct bcma_drv_cc *c
434 bcma_pmu_swreg_init(cc);
435 bcma_pmu_workarounds(cc);
436 }
437 +
438 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
439 +{
440 + struct bcma_bus *bus = cc->core->bus;
441 +
442 + switch (bus->chipinfo.id) {
443 + case 0x4716:
444 + case 0x4748:
445 + case 47162:
446 + case 0x4313:
447 + case 0x5357:
448 + case 0x4749:
449 + case 53572:
450 + /* always 20Mhz */
451 + return 20000 * 1000;
452 + case 0x5356:
453 + case 0x5300:
454 + /* always 25Mhz */
455 + return 25000 * 1000;
456 + default:
457 + pr_warn("No ALP clock specified for %04X device, "
458 + "pmu rev. %d, using default %d Hz\n",
459 + bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
460 + }
461 + return BCMA_CC_PMU_ALP_CLOCK;
462 +}
463 +
464 +/* Find the output of the "m" pll divider given pll controls that start with
465 + * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
466 + */
467 +static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
468 +{
469 + u32 tmp, div, ndiv, p1, p2, fc;
470 + struct bcma_bus *bus = cc->core->bus;
471 +
472 + BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
473 +
474 + BUG_ON(!m || m > 4);
475 +
476 + if (bus->chipinfo.id == 0x5357 || bus->chipinfo.id == 0x4749) {
477 + /* Detect failure in clock setting */
478 + tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
479 + if (tmp & 0x40000)
480 + return 133 * 1000000;
481 + }
482 +
483 + tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
484 + p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
485 + p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
486 +
487 + tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
488 + div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
489 + BCMA_CC_PPL_MDIV_MASK;
490 +
491 + tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
492 + ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
493 +
494 + /* Do calculation in Mhz */
495 + fc = bcma_pmu_alp_clock(cc) / 1000000;
496 + fc = (p1 * ndiv * fc) / p2;
497 +
498 + /* Return clock in Hertz */
499 + return (fc / div) * 1000000;
500 +}
501 +
502 +/* query bus clock frequency for PMU-enabled chipcommon */
503 +u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
504 +{
505 + struct bcma_bus *bus = cc->core->bus;
506 +
507 + switch (bus->chipinfo.id) {
508 + case 0x4716:
509 + case 0x4748:
510 + case 47162:
511 + return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
512 + BCMA_CC_PMU5_MAINPLL_SSB);
513 + case 0x5356:
514 + return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
515 + BCMA_CC_PMU5_MAINPLL_SSB);
516 + case 0x5357:
517 + case 0x4749:
518 + return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
519 + BCMA_CC_PMU5_MAINPLL_SSB);
520 + case 0x5300:
521 + return bcma_pmu_clock(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
522 + BCMA_CC_PMU5_MAINPLL_SSB);
523 + case 53572:
524 + return 75000000;
525 + default:
526 + pr_warn("No backplane clock specified for %04X device, "
527 + "pmu rev. %d, using default %d Hz\n",
528 + bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
529 + }
530 + return BCMA_CC_PMU_HT_CLOCK;
531 +}
532 +
533 +/* query cpu clock frequency for PMU-enabled chipcommon */
534 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
535 +{
536 + struct bcma_bus *bus = cc->core->bus;
537 +
538 + if (bus->chipinfo.id == 53572)
539 + return 300000000;
540 +
541 + if (cc->pmu.rev >= 5) {
542 + u32 pll;
543 + switch (bus->chipinfo.id) {
544 + case 0x5356:
545 + pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
546 + break;
547 + case 0x5357:
548 + case 0x4749:
549 + pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
550 + break;
551 + default:
552 + pll = BCMA_CC_PMU4716_MAINPLL_PLL0;
553 + break;
554 + }
555 +
556 + /* TODO: if (bus->chipinfo.id == 0x5300)
557 + return si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); */
558 + return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
559 + }
560 +
561 + return bcma_pmu_get_clockcontrol(cc);
562 +}
563 --- /dev/null
564 +++ b/drivers/bcma/driver_mips.c
565 @@ -0,0 +1,256 @@
566 +/*
567 + * Broadcom specific AMBA
568 + * Broadcom MIPS32 74K core driver
569 + *
570 + * Copyright 2009, Broadcom Corporation
571 + * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
572 + * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
573 + * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
574 + *
575 + * Licensed under the GNU/GPL. See COPYING for details.
576 + */
577 +
578 +#include "bcma_private.h"
579 +
580 +#include <linux/bcma/bcma.h>
581 +
582 +#include <linux/serial.h>
583 +#include <linux/serial_core.h>
584 +#include <linux/serial_reg.h>
585 +#include <linux/time.h>
586 +
587 +/* The 47162a0 hangs when reading MIPS DMP registers registers */
588 +static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
589 +{
590 + return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
591 + dev->id.id == BCMA_CORE_MIPS_74K;
592 +}
593 +
594 +/* The 5357b0 hangs when reading USB20H DMP registers */
595 +static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
596 +{
597 + return (dev->bus->chipinfo.id == 0x5357 ||
598 + dev->bus->chipinfo.id == 0x4749) &&
599 + dev->bus->chipinfo.pkg == 11 &&
600 + dev->id.id == BCMA_CORE_USB20_HOST;
601 +}
602 +
603 +static inline u32 mips_read32(struct bcma_drv_mips *mcore,
604 + u16 offset)
605 +{
606 + return bcma_read32(mcore->core, offset);
607 +}
608 +
609 +static inline void mips_write32(struct bcma_drv_mips *mcore,
610 + u16 offset,
611 + u32 value)
612 +{
613 + bcma_write32(mcore->core, offset, value);
614 +}
615 +
616 +static const u32 ipsflag_irq_mask[] = {
617 + 0,
618 + BCMA_MIPS_IPSFLAG_IRQ1,
619 + BCMA_MIPS_IPSFLAG_IRQ2,
620 + BCMA_MIPS_IPSFLAG_IRQ3,
621 + BCMA_MIPS_IPSFLAG_IRQ4,
622 +};
623 +
624 +static const u32 ipsflag_irq_shift[] = {
625 + 0,
626 + BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
627 + BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
628 + BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
629 + BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
630 +};
631 +
632 +static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
633 +{
634 + u32 flag;
635 +
636 + if (bcma_core_mips_bcm47162a0_quirk(dev))
637 + return dev->core_index;
638 + if (bcma_core_mips_bcm5357b0_quirk(dev))
639 + return dev->core_index;
640 + flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
641 +
642 + return flag & 0x1F;
643 +}
644 +
645 +/* Get the MIPS IRQ assignment for a specified device.
646 + * If unassigned, 0 is returned.
647 + */
648 +unsigned int bcma_core_mips_irq(struct bcma_device *dev)
649 +{
650 + struct bcma_device *mdev = dev->bus->drv_mips.core;
651 + u32 irqflag;
652 + unsigned int irq;
653 +
654 + irqflag = bcma_core_mips_irqflag(dev);
655 +
656 + for (irq = 1; irq <= 4; irq++)
657 + if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
658 + (1 << irqflag))
659 + return irq;
660 +
661 + return 0;
662 +}
663 +EXPORT_SYMBOL(bcma_core_mips_irq);
664 +
665 +static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
666 +{
667 + unsigned int oldirq = bcma_core_mips_irq(dev);
668 + struct bcma_bus *bus = dev->bus;
669 + struct bcma_device *mdev = bus->drv_mips.core;
670 + u32 irqflag;
671 +
672 + irqflag = bcma_core_mips_irqflag(dev);
673 + BUG_ON(oldirq == 6);
674 +
675 + dev->irq = irq + 2;
676 +
677 + /* clear the old irq */
678 + if (oldirq == 0)
679 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
680 + bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
681 + ~(1 << irqflag));
682 + else
683 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
684 +
685 + /* assign the new one */
686 + if (irq == 0) {
687 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
688 + bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
689 + (1 << irqflag));
690 + } else {
691 + u32 oldirqflag = bcma_read32(mdev,
692 + BCMA_MIPS_MIPS74K_INTMASK(irq));
693 + if (oldirqflag) {
694 + struct bcma_device *core;
695 +
696 + /* backplane irq line is in use, find out who uses
697 + * it and set user to irq 0
698 + */
699 + list_for_each_entry_reverse(core, &bus->cores, list) {
700 + if ((1 << bcma_core_mips_irqflag(core)) ==
701 + oldirqflag) {
702 + bcma_core_mips_set_irq(core, 0);
703 + break;
704 + }
705 + }
706 + }
707 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
708 + 1 << irqflag);
709 + }
710 +
711 + pr_info("set_irq: core 0x%04x, irq %d => %d\n",
712 + dev->id.id, oldirq + 2, irq + 2);
713 +}
714 +
715 +static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
716 +{
717 + int i;
718 + static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
719 + printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
720 + for (i = 0; i <= 6; i++)
721 + printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
722 + printk("\n");
723 +}
724 +
725 +static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
726 +{
727 + struct bcma_device *core;
728 +
729 + list_for_each_entry_reverse(core, &bus->cores, list) {
730 + bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
731 + }
732 +}
733 +
734 +u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
735 +{
736 + struct bcma_bus *bus = mcore->core->bus;
737 +
738 + if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
739 + return bcma_pmu_get_clockcpu(&bus->drv_cc);
740 +
741 + pr_err("No PMU available, need this to get the cpu clock\n");
742 + return 0;
743 +}
744 +EXPORT_SYMBOL(bcma_cpu_clock);
745 +
746 +static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
747 +{
748 + struct bcma_bus *bus = mcore->core->bus;
749 +
750 + switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
751 + case BCMA_CC_FLASHT_STSER:
752 + case BCMA_CC_FLASHT_ATSER:
753 + pr_err("Serial flash not supported.\n");
754 + break;
755 + case BCMA_CC_FLASHT_PARA:
756 + pr_info("found parallel flash.\n");
757 + bus->drv_cc.pflash.window = 0x1c000000;
758 + bus->drv_cc.pflash.window_size = 0x02000000;
759 +
760 + if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
761 + BCMA_CC_FLASH_CFG_DS) == 0)
762 + bus->drv_cc.pflash.buswidth = 1;
763 + else
764 + bus->drv_cc.pflash.buswidth = 2;
765 + break;
766 + default:
767 + pr_err("flash not supported.\n");
768 + }
769 +}
770 +
771 +void bcma_core_mips_init(struct bcma_drv_mips *mcore)
772 +{
773 + struct bcma_bus *bus;
774 + struct bcma_device *core;
775 + bus = mcore->core->bus;
776 +
777 + pr_info("Initializing MIPS core...\n");
778 +
779 + if (!mcore->setup_done)
780 + mcore->assigned_irqs = 1;
781 +
782 + /* Assign IRQs to all cores on the bus */
783 + list_for_each_entry_reverse(core, &bus->cores, list) {
784 + int mips_irq;
785 + if (core->irq)
786 + continue;
787 +
788 + mips_irq = bcma_core_mips_irq(core);
789 + if (mips_irq > 4)
790 + core->irq = 0;
791 + else
792 + core->irq = mips_irq + 2;
793 + if (core->irq > 5)
794 + continue;
795 + switch (core->id.id) {
796 + case BCMA_CORE_PCI:
797 + case BCMA_CORE_PCIE:
798 + case BCMA_CORE_ETHERNET:
799 + case BCMA_CORE_ETHERNET_GBIT:
800 + case BCMA_CORE_MAC_GBIT:
801 + case BCMA_CORE_80211:
802 + case BCMA_CORE_USB20_HOST:
803 + /* These devices get their own IRQ line if available,
804 + * the rest goes on IRQ0
805 + */
806 + if (mcore->assigned_irqs <= 4)
807 + bcma_core_mips_set_irq(core,
808 + mcore->assigned_irqs++);
809 + break;
810 + }
811 + }
812 + pr_info("IRQ reconfiguration done\n");
813 + bcma_core_mips_dump_irq(bus);
814 +
815 + if (mcore->setup_done)
816 + return;
817 +
818 + bcma_chipco_serial_init(&bus->drv_cc);
819 + bcma_core_mips_flash_detect(mcore);
820 + mcore->setup_done = true;
821 +}
822 --- a/drivers/bcma/driver_pci.c
823 +++ b/drivers/bcma/driver_pci.c
824 @@ -2,8 +2,9 @@
825 * Broadcom specific AMBA
826 * PCI Core
827 *
828 - * Copyright 2005, Broadcom Corporation
829 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
830 + * Copyright 2005, 2011, Broadcom Corporation
831 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
832 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
833 *
834 * Licensed under the GNU/GPL. See COPYING for details.
835 */
836 @@ -15,40 +16,41 @@
837 * R/W ops.
838 **************************************************/
839
840 -static u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
841 +u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
842 {
843 - pcicore_write32(pc, 0x130, address);
844 - pcicore_read32(pc, 0x130);
845 - return pcicore_read32(pc, 0x134);
846 + pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
847 + pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
848 + return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA);
849 }
850
851 #if 0
852 static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
853 {
854 - pcicore_write32(pc, 0x130, address);
855 - pcicore_read32(pc, 0x130);
856 - pcicore_write32(pc, 0x134, data);
857 + pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
858 + pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
859 + pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
860 }
861 #endif
862
863 static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
864 {
865 - const u16 mdio_control = 0x128;
866 - const u16 mdio_data = 0x12C;
867 u32 v;
868 int i;
869
870 - v = (1 << 30); /* Start of Transaction */
871 - v |= (1 << 28); /* Write Transaction */
872 - v |= (1 << 17); /* Turnaround */
873 - v |= (0x1F << 18);
874 + v = BCMA_CORE_PCI_MDIODATA_START;
875 + v |= BCMA_CORE_PCI_MDIODATA_WRITE;
876 + v |= (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
877 + BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
878 + v |= (BCMA_CORE_PCI_MDIODATA_BLK_ADDR <<
879 + BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
880 + v |= BCMA_CORE_PCI_MDIODATA_TA;
881 v |= (phy << 4);
882 - pcicore_write32(pc, mdio_data, v);
883 + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
884
885 udelay(10);
886 for (i = 0; i < 200; i++) {
887 - v = pcicore_read32(pc, mdio_control);
888 - if (v & 0x100 /* Trans complete */)
889 + v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
890 + if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
891 break;
892 msleep(1);
893 }
894 @@ -56,79 +58,84 @@ static void bcma_pcie_mdio_set_phy(struc
895
896 static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
897 {
898 - const u16 mdio_control = 0x128;
899 - const u16 mdio_data = 0x12C;
900 int max_retries = 10;
901 u16 ret = 0;
902 u32 v;
903 int i;
904
905 - v = 0x80; /* Enable Preamble Sequence */
906 - v |= 0x2; /* MDIO Clock Divisor */
907 - pcicore_write32(pc, mdio_control, v);
908 + /* enable mdio access to SERDES */
909 + v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
910 + v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
911 + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
912
913 if (pc->core->id.rev >= 10) {
914 max_retries = 200;
915 bcma_pcie_mdio_set_phy(pc, device);
916 + v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
917 + BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
918 + v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
919 + } else {
920 + v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
921 + v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
922 }
923
924 - v = (1 << 30); /* Start of Transaction */
925 - v |= (1 << 29); /* Read Transaction */
926 - v |= (1 << 17); /* Turnaround */
927 - if (pc->core->id.rev < 10)
928 - v |= (u32)device << 22;
929 - v |= (u32)address << 18;
930 - pcicore_write32(pc, mdio_data, v);
931 + v = BCMA_CORE_PCI_MDIODATA_START;
932 + v |= BCMA_CORE_PCI_MDIODATA_READ;
933 + v |= BCMA_CORE_PCI_MDIODATA_TA;
934 +
935 + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
936 /* Wait for the device to complete the transaction */
937 udelay(10);
938 for (i = 0; i < max_retries; i++) {
939 - v = pcicore_read32(pc, mdio_control);
940 - if (v & 0x100 /* Trans complete */) {
941 + v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
942 + if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) {
943 udelay(10);
944 - ret = pcicore_read32(pc, mdio_data);
945 + ret = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_DATA);
946 break;
947 }
948 msleep(1);
949 }
950 - pcicore_write32(pc, mdio_control, 0);
951 + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
952 return ret;
953 }
954
955 static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
956 u8 address, u16 data)
957 {
958 - const u16 mdio_control = 0x128;
959 - const u16 mdio_data = 0x12C;
960 int max_retries = 10;
961 u32 v;
962 int i;
963
964 - v = 0x80; /* Enable Preamble Sequence */
965 - v |= 0x2; /* MDIO Clock Divisor */
966 - pcicore_write32(pc, mdio_control, v);
967 + /* enable mdio access to SERDES */
968 + v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
969 + v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
970 + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
971
972 if (pc->core->id.rev >= 10) {
973 max_retries = 200;
974 bcma_pcie_mdio_set_phy(pc, device);
975 + v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
976 + BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
977 + v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
978 + } else {
979 + v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
980 + v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
981 }
982
983 - v = (1 << 30); /* Start of Transaction */
984 - v |= (1 << 28); /* Write Transaction */
985 - v |= (1 << 17); /* Turnaround */
986 - if (pc->core->id.rev < 10)
987 - v |= (u32)device << 22;
988 - v |= (u32)address << 18;
989 + v = BCMA_CORE_PCI_MDIODATA_START;
990 + v |= BCMA_CORE_PCI_MDIODATA_WRITE;
991 + v |= BCMA_CORE_PCI_MDIODATA_TA;
992 v |= data;
993 - pcicore_write32(pc, mdio_data, v);
994 + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
995 /* Wait for the device to complete the transaction */
996 udelay(10);
997 for (i = 0; i < max_retries; i++) {
998 - v = pcicore_read32(pc, mdio_control);
999 - if (v & 0x100 /* Trans complete */)
1000 + v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
1001 + if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
1002 break;
1003 msleep(1);
1004 }
1005 - pcicore_write32(pc, mdio_control, 0);
1006 + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
1007 }
1008
1009 /**************************************************
1010 @@ -137,27 +144,82 @@ static void bcma_pcie_mdio_write(struct
1011
1012 static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
1013 {
1014 - return (bcma_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
1015 + u32 tmp;
1016 +
1017 + tmp = bcma_pcie_read(pc, BCMA_CORE_PCI_PLP_STATUSREG);
1018 + if (tmp & BCMA_CORE_PCI_PLP_POLARITYINV_STAT)
1019 + return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE |
1020 + BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY;
1021 + else
1022 + return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE;
1023 }
1024
1025 static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
1026 {
1027 - const u8 serdes_pll_device = 0x1D;
1028 - const u8 serdes_rx_device = 0x1F;
1029 u16 tmp;
1030
1031 - bcma_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
1032 - bcma_pcicore_polarity_workaround(pc));
1033 - tmp = bcma_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
1034 - if (tmp & 0x4000)
1035 - bcma_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
1036 + bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_RX,
1037 + BCMA_CORE_PCI_SERDES_RX_CTRL,
1038 + bcma_pcicore_polarity_workaround(pc));
1039 + tmp = bcma_pcie_mdio_read(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
1040 + BCMA_CORE_PCI_SERDES_PLL_CTRL);
1041 + if (tmp & BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN)
1042 + bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
1043 + BCMA_CORE_PCI_SERDES_PLL_CTRL,
1044 + tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN);
1045 }
1046
1047 /**************************************************
1048 * Init.
1049 **************************************************/
1050
1051 -void bcma_core_pci_init(struct bcma_drv_pci *pc)
1052 +static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
1053 {
1054 bcma_pcicore_serdes_workaround(pc);
1055 }
1056 +
1057 +void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc)
1058 +{
1059 + if (pc->setup_done)
1060 + return;
1061 +
1062 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
1063 + pc->hostmode = bcma_core_pci_is_in_hostmode(pc);
1064 + if (pc->hostmode)
1065 + bcma_core_pci_hostmode_init(pc);
1066 +#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
1067 +
1068 + if (!pc->hostmode)
1069 + bcma_core_pci_clientmode_init(pc);
1070 +}
1071 +
1072 +int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
1073 + bool enable)
1074 +{
1075 + struct pci_dev *pdev = pc->core->bus->host_pci;
1076 + u32 coremask, tmp;
1077 + int err = 0;
1078 +
1079 + if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
1080 + /* This bcma device is not on a PCI host-bus. So the IRQs are
1081 + * not routed through the PCI core.
1082 + * So we must not enable routing through the PCI core. */
1083 + goto out;
1084 + }
1085 +
1086 + err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
1087 + if (err)
1088 + goto out;
1089 +
1090 + coremask = BIT(core->core_index) << 8;
1091 + if (enable)
1092 + tmp |= coremask;
1093 + else
1094 + tmp &= ~coremask;
1095 +
1096 + err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp);
1097 +
1098 +out:
1099 + return err;
1100 +}
1101 +EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
1102 --- /dev/null
1103 +++ b/drivers/bcma/driver_pci_host.c
1104 @@ -0,0 +1,589 @@
1105 +/*
1106 + * Broadcom specific AMBA
1107 + * PCI Core in hostmode
1108 + *
1109 + * Copyright 2005 - 2011, Broadcom Corporation
1110 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
1111 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
1112 + *
1113 + * Licensed under the GNU/GPL. See COPYING for details.
1114 + */
1115 +
1116 +#include "bcma_private.h"
1117 +#include <linux/pci.h>
1118 +#include <linux/export.h>
1119 +#include <linux/bcma/bcma.h>
1120 +#include <asm/paccess.h>
1121 +
1122 +/* Probe a 32bit value on the bus and catch bus exceptions.
1123 + * Returns nonzero on a bus exception.
1124 + * This is MIPS specific */
1125 +#define mips_busprobe32(val, addr) get_dbe((val), ((u32 *)(addr)))
1126 +
1127 +/* Assume one-hot slot wiring */
1128 +#define BCMA_PCI_SLOT_MAX 16
1129 +#define PCI_CONFIG_SPACE_SIZE 256
1130 +
1131 +bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
1132 +{
1133 + struct bcma_bus *bus = pc->core->bus;
1134 + u16 chipid_top;
1135 + u32 tmp;
1136 +
1137 + chipid_top = (bus->chipinfo.id & 0xFF00);
1138 + if (chipid_top != 0x4700 &&
1139 + chipid_top != 0x5300)
1140 + return false;
1141 +
1142 + if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) {
1143 + pr_info("This PCI core is disabled and not working\n");
1144 + return false;
1145 + }
1146 +
1147 + bcma_core_enable(pc->core, 0);
1148 +
1149 + return !mips_busprobe32(tmp, pc->core->io_addr);
1150 +}
1151 +
1152 +static u32 bcma_pcie_read_config(struct bcma_drv_pci *pc, u32 address)
1153 +{
1154 + pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
1155 + pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
1156 + return pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_DATA);
1157 +}
1158 +
1159 +static void bcma_pcie_write_config(struct bcma_drv_pci *pc, u32 address,
1160 + u32 data)
1161 +{
1162 + pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
1163 + pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
1164 + pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_DATA, data);
1165 +}
1166 +
1167 +static u32 bcma_get_cfgspace_addr(struct bcma_drv_pci *pc, unsigned int dev,
1168 + unsigned int func, unsigned int off)
1169 +{
1170 + u32 addr = 0;
1171 +
1172 + /* Issue config commands only when the data link is up (atleast
1173 + * one external pcie device is present).
1174 + */
1175 + if (dev >= 2 || !(bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_LSREG)
1176 + & BCMA_CORE_PCI_DLLP_LSREG_LINKUP))
1177 + goto out;
1178 +
1179 + /* Type 0 transaction */
1180 + /* Slide the PCI window to the appropriate slot */
1181 + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
1182 + /* Calculate the address */
1183 + addr = pc->host_controller->host_cfg_addr;
1184 + addr |= (dev << BCMA_CORE_PCI_CFG_SLOT_SHIFT);
1185 + addr |= (func << BCMA_CORE_PCI_CFG_FUN_SHIFT);
1186 + addr |= (off & ~3);
1187 +
1188 +out:
1189 + return addr;
1190 +}
1191 +
1192 +static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev,
1193 + unsigned int func, unsigned int off,
1194 + void *buf, int len)
1195 +{
1196 + int err = -EINVAL;
1197 + u32 addr, val;
1198 + void __iomem *mmio = 0;
1199 +
1200 + WARN_ON(!pc->hostmode);
1201 + if (unlikely(len != 1 && len != 2 && len != 4))
1202 + goto out;
1203 + if (dev == 0) {
1204 + /* we support only two functions on device 0 */
1205 + if (func > 1)
1206 + return -EINVAL;
1207 +
1208 + /* accesses to config registers with offsets >= 256
1209 + * requires indirect access.
1210 + */
1211 + if (off >= PCI_CONFIG_SPACE_SIZE) {
1212 + addr = (func << 12);
1213 + addr |= (off & 0x0FFF);
1214 + val = bcma_pcie_read_config(pc, addr);
1215 + } else {
1216 + addr = BCMA_CORE_PCI_PCICFG0;
1217 + addr |= (func << 8);
1218 + addr |= (off & 0xfc);
1219 + val = pcicore_read32(pc, addr);
1220 + }
1221 + } else {
1222 + addr = bcma_get_cfgspace_addr(pc, dev, func, off);
1223 + if (unlikely(!addr))
1224 + goto out;
1225 + err = -ENOMEM;
1226 + mmio = ioremap_nocache(addr, len);
1227 + if (!mmio)
1228 + goto out;
1229 +
1230 + if (mips_busprobe32(val, mmio)) {
1231 + val = 0xffffffff;
1232 + goto unmap;
1233 + }
1234 +
1235 + val = readl(mmio);
1236 + }
1237 + val >>= (8 * (off & 3));
1238 +
1239 + switch (len) {
1240 + case 1:
1241 + *((u8 *)buf) = (u8)val;
1242 + break;
1243 + case 2:
1244 + *((u16 *)buf) = (u16)val;
1245 + break;
1246 + case 4:
1247 + *((u32 *)buf) = (u32)val;
1248 + break;
1249 + }
1250 + err = 0;
1251 +unmap:
1252 + if (mmio)
1253 + iounmap(mmio);
1254 +out:
1255 + return err;
1256 +}
1257 +
1258 +static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
1259 + unsigned int func, unsigned int off,
1260 + const void *buf, int len)
1261 +{
1262 + int err = -EINVAL;
1263 + u32 addr = 0, val = 0;
1264 + void __iomem *mmio = 0;
1265 + u16 chipid = pc->core->bus->chipinfo.id;
1266 +
1267 + WARN_ON(!pc->hostmode);
1268 + if (unlikely(len != 1 && len != 2 && len != 4))
1269 + goto out;
1270 + if (dev == 0) {
1271 + /* accesses to config registers with offsets >= 256
1272 + * requires indirect access.
1273 + */
1274 + if (off < PCI_CONFIG_SPACE_SIZE) {
1275 + addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
1276 + addr |= (func << 8);
1277 + addr |= (off & 0xfc);
1278 + mmio = ioremap_nocache(addr, len);
1279 + if (!mmio)
1280 + goto out;
1281 + }
1282 + } else {
1283 + addr = bcma_get_cfgspace_addr(pc, dev, func, off);
1284 + if (unlikely(!addr))
1285 + goto out;
1286 + err = -ENOMEM;
1287 + mmio = ioremap_nocache(addr, len);
1288 + if (!mmio)
1289 + goto out;
1290 +
1291 + if (mips_busprobe32(val, mmio)) {
1292 + val = 0xffffffff;
1293 + goto unmap;
1294 + }
1295 + }
1296 +
1297 + switch (len) {
1298 + case 1:
1299 + val = readl(mmio);
1300 + val &= ~(0xFF << (8 * (off & 3)));
1301 + val |= *((const u8 *)buf) << (8 * (off & 3));
1302 + break;
1303 + case 2:
1304 + val = readl(mmio);
1305 + val &= ~(0xFFFF << (8 * (off & 3)));
1306 + val |= *((const u16 *)buf) << (8 * (off & 3));
1307 + break;
1308 + case 4:
1309 + val = *((const u32 *)buf);
1310 + break;
1311 + }
1312 + if (dev == 0 && !addr) {
1313 + /* accesses to config registers with offsets >= 256
1314 + * requires indirect access.
1315 + */
1316 + addr = (func << 12);
1317 + addr |= (off & 0x0FFF);
1318 + bcma_pcie_write_config(pc, addr, val);
1319 + } else {
1320 + writel(val, mmio);
1321 +
1322 + if (chipid == 0x4716 || chipid == 0x4748)
1323 + readl(mmio);
1324 + }
1325 +
1326 + err = 0;
1327 +unmap:
1328 + if (mmio)
1329 + iounmap(mmio);
1330 +out:
1331 + return err;
1332 +}
1333 +
1334 +static int bcma_core_pci_hostmode_read_config(struct pci_bus *bus,
1335 + unsigned int devfn,
1336 + int reg, int size, u32 *val)
1337 +{
1338 + unsigned long flags;
1339 + int err;
1340 + struct bcma_drv_pci *pc;
1341 + struct bcma_drv_pci_host *pc_host;
1342 +
1343 + pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
1344 + pc = pc_host->pdev;
1345 +
1346 + spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
1347 + err = bcma_extpci_read_config(pc, PCI_SLOT(devfn),
1348 + PCI_FUNC(devfn), reg, val, size);
1349 + spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
1350 +
1351 + return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
1352 +}
1353 +
1354 +static int bcma_core_pci_hostmode_write_config(struct pci_bus *bus,
1355 + unsigned int devfn,
1356 + int reg, int size, u32 val)
1357 +{
1358 + unsigned long flags;
1359 + int err;
1360 + struct bcma_drv_pci *pc;
1361 + struct bcma_drv_pci_host *pc_host;
1362 +
1363 + pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
1364 + pc = pc_host->pdev;
1365 +
1366 + spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
1367 + err = bcma_extpci_write_config(pc, PCI_SLOT(devfn),
1368 + PCI_FUNC(devfn), reg, &val, size);
1369 + spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
1370 +
1371 + return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
1372 +}
1373 +
1374 +/* return cap_offset if requested capability exists in the PCI config space */
1375 +static u8 __devinit bcma_find_pci_capability(struct bcma_drv_pci *pc,
1376 + unsigned int dev,
1377 + unsigned int func, u8 req_cap_id,
1378 + unsigned char *buf, u32 *buflen)
1379 +{
1380 + u8 cap_id;
1381 + u8 cap_ptr = 0;
1382 + u32 bufsize;
1383 + u8 byte_val;
1384 +
1385 + /* check for Header type 0 */
1386 + bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val,
1387 + sizeof(u8));
1388 + if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
1389 + return cap_ptr;
1390 +
1391 + /* check if the capability pointer field exists */
1392 + bcma_extpci_read_config(pc, dev, func, PCI_STATUS, &byte_val,
1393 + sizeof(u8));
1394 + if (!(byte_val & PCI_STATUS_CAP_LIST))
1395 + return cap_ptr;
1396 +
1397 + /* check if the capability pointer is 0x00 */
1398 + bcma_extpci_read_config(pc, dev, func, PCI_CAPABILITY_LIST, &cap_ptr,
1399 + sizeof(u8));
1400 + if (cap_ptr == 0x00)
1401 + return cap_ptr;
1402 +
1403 + /* loop thr'u the capability list and see if the requested capabilty
1404 + * exists */
1405 + bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id, sizeof(u8));
1406 + while (cap_id != req_cap_id) {
1407 + bcma_extpci_read_config(pc, dev, func, cap_ptr + 1, &cap_ptr,
1408 + sizeof(u8));
1409 + if (cap_ptr == 0x00)
1410 + return cap_ptr;
1411 + bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id,
1412 + sizeof(u8));
1413 + }
1414 +
1415 + /* found the caller requested capability */
1416 + if ((buf != NULL) && (buflen != NULL)) {
1417 + u8 cap_data;
1418 +
1419 + bufsize = *buflen;
1420 + if (!bufsize)
1421 + return cap_ptr;
1422 +
1423 + *buflen = 0;
1424 +
1425 + /* copy the cpability data excluding cap ID and next ptr */
1426 + cap_data = cap_ptr + 2;
1427 + if ((bufsize + cap_data) > PCI_CONFIG_SPACE_SIZE)
1428 + bufsize = PCI_CONFIG_SPACE_SIZE - cap_data;
1429 + *buflen = bufsize;
1430 + while (bufsize--) {
1431 + bcma_extpci_read_config(pc, dev, func, cap_data, buf,
1432 + sizeof(u8));
1433 + cap_data++;
1434 + buf++;
1435 + }
1436 + }
1437 +
1438 + return cap_ptr;
1439 +}
1440 +
1441 +/* If the root port is capable of returning Config Request
1442 + * Retry Status (CRS) Completion Status to software then
1443 + * enable the feature.
1444 + */
1445 +static void __devinit bcma_core_pci_enable_crs(struct bcma_drv_pci *pc)
1446 +{
1447 + u8 cap_ptr, root_ctrl, root_cap, dev;
1448 + u16 val16;
1449 + int i;
1450 +
1451 + cap_ptr = bcma_find_pci_capability(pc, 0, 0, PCI_CAP_ID_EXP, NULL,
1452 + NULL);
1453 + root_cap = cap_ptr + PCI_EXP_RTCAP;
1454 + bcma_extpci_read_config(pc, 0, 0, root_cap, &val16, sizeof(u16));
1455 + if (val16 & BCMA_CORE_PCI_RC_CRS_VISIBILITY) {
1456 + /* Enable CRS software visibility */
1457 + root_ctrl = cap_ptr + PCI_EXP_RTCTL;
1458 + val16 = PCI_EXP_RTCTL_CRSSVE;
1459 + bcma_extpci_read_config(pc, 0, 0, root_ctrl, &val16,
1460 + sizeof(u16));
1461 +
1462 + /* Initiate a configuration request to read the vendor id
1463 + * field of the device function's config space header after
1464 + * 100 ms wait time from the end of Reset. If the device is
1465 + * not done with its internal initialization, it must at
1466 + * least return a completion TLP, with a completion status
1467 + * of "Configuration Request Retry Status (CRS)". The root
1468 + * complex must complete the request to the host by returning
1469 + * a read-data value of 0001h for the Vendor ID field and
1470 + * all 1s for any additional bytes included in the request.
1471 + * Poll using the config reads for max wait time of 1 sec or
1472 + * until we receive the successful completion status. Repeat
1473 + * the procedure for all the devices.
1474 + */
1475 + for (dev = 1; dev < BCMA_PCI_SLOT_MAX; dev++) {
1476 + for (i = 0; i < 100000; i++) {
1477 + bcma_extpci_read_config(pc, dev, 0,
1478 + PCI_VENDOR_ID, &val16,
1479 + sizeof(val16));
1480 + if (val16 != 0x1)
1481 + break;
1482 + udelay(10);
1483 + }
1484 + if (val16 == 0x1)
1485 + pr_err("PCI: Broken device in slot %d\n", dev);
1486 + }
1487 + }
1488 +}
1489 +
1490 +void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
1491 +{
1492 + struct bcma_bus *bus = pc->core->bus;
1493 + struct bcma_drv_pci_host *pc_host;
1494 + u32 tmp;
1495 + u32 pci_membase_1G;
1496 + unsigned long io_map_base;
1497 +
1498 + pr_info("PCIEcore in host mode found\n");
1499 +
1500 + pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL);
1501 + if (!pc_host) {
1502 + pr_err("can not allocate memory");
1503 + return;
1504 + }
1505 +
1506 + pc->host_controller = pc_host;
1507 + pc_host->pci_controller.io_resource = &pc_host->io_resource;
1508 + pc_host->pci_controller.mem_resource = &pc_host->mem_resource;
1509 + pc_host->pci_controller.pci_ops = &pc_host->pci_ops;
1510 + pc_host->pdev = pc;
1511 +
1512 + pci_membase_1G = BCMA_SOC_PCI_DMA;
1513 + pc_host->host_cfg_addr = BCMA_SOC_PCI_CFG;
1514 +
1515 + pc_host->pci_ops.read = bcma_core_pci_hostmode_read_config;
1516 + pc_host->pci_ops.write = bcma_core_pci_hostmode_write_config;
1517 +
1518 + pc_host->mem_resource.name = "BCMA PCIcore external memory",
1519 + pc_host->mem_resource.start = BCMA_SOC_PCI_DMA;
1520 + pc_host->mem_resource.end = BCMA_SOC_PCI_DMA + BCMA_SOC_PCI_DMA_SZ - 1;
1521 + pc_host->mem_resource.flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED;
1522 +
1523 + pc_host->io_resource.name = "BCMA PCIcore external I/O",
1524 + pc_host->io_resource.start = 0x100;
1525 + pc_host->io_resource.end = 0x7FF;
1526 + pc_host->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED;
1527 +
1528 + /* Reset RC */
1529 + udelay(3000);
1530 + pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE);
1531 + udelay(1000);
1532 + pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST |
1533 + BCMA_CORE_PCI_CTL_RST_OE);
1534 +
1535 + /* 64 MB I/O access window. On 4716, use
1536 + * sbtopcie0 to access the device registers. We
1537 + * can't use address match 2 (1 GB window) region
1538 + * as mips can't generate 64-bit address on the
1539 + * backplane.
1540 + */
1541 + if (bus->chipinfo.id == 0x4716 || bus->chipinfo.id == 0x4748) {
1542 + pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
1543 + pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
1544 + BCMA_SOC_PCI_MEM_SZ - 1;
1545 + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
1546 + BCMA_CORE_PCI_SBTOPCI_MEM | BCMA_SOC_PCI_MEM);
1547 + } else if (bus->chipinfo.id == 0x5300) {
1548 + tmp = BCMA_CORE_PCI_SBTOPCI_MEM;
1549 + tmp |= BCMA_CORE_PCI_SBTOPCI_PREF;
1550 + tmp |= BCMA_CORE_PCI_SBTOPCI_BURST;
1551 + if (pc->core->core_unit == 0) {
1552 + pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
1553 + pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
1554 + BCMA_SOC_PCI_MEM_SZ - 1;
1555 + pci_membase_1G = BCMA_SOC_PCIE_DMA_H32;
1556 + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
1557 + tmp | BCMA_SOC_PCI_MEM);
1558 + } else if (pc->core->core_unit == 1) {
1559 + pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM;
1560 + pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM +
1561 + BCMA_SOC_PCI_MEM_SZ - 1;
1562 + pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32;
1563 + pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG;
1564 + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
1565 + tmp | BCMA_SOC_PCI1_MEM);
1566 + }
1567 + } else
1568 + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
1569 + BCMA_CORE_PCI_SBTOPCI_IO);
1570 +
1571 + /* 64 MB configuration access window */
1572 + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
1573 +
1574 + /* 1 GB memory access window */
1575 + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI2,
1576 + BCMA_CORE_PCI_SBTOPCI_MEM | pci_membase_1G);
1577 +
1578 +
1579 + /* As per PCI Express Base Spec 1.1 we need to wait for
1580 + * at least 100 ms from the end of a reset (cold/warm/hot)
1581 + * before issuing configuration requests to PCI Express
1582 + * devices.
1583 + */
1584 + udelay(100000);
1585 +
1586 + bcma_core_pci_enable_crs(pc);
1587 +
1588 + /* Enable PCI bridge BAR0 memory & master access */
1589 + tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
1590 + bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp));
1591 +
1592 + /* Enable PCI interrupts */
1593 + pcicore_write32(pc, BCMA_CORE_PCI_IMASK, BCMA_CORE_PCI_IMASK_INTA);
1594 +
1595 + /* Ok, ready to run, register it to the system.
1596 + * The following needs change, if we want to port hostmode
1597 + * to non-MIPS platform. */
1598 + io_map_base = (unsigned long)ioremap_nocache(BCMA_SOC_PCI_MEM,
1599 + 0x04000000);
1600 + pc_host->pci_controller.io_map_base = io_map_base;
1601 + set_io_port_base(pc_host->pci_controller.io_map_base);
1602 + /* Give some time to the PCI controller to configure itself with the new
1603 + * values. Not waiting at this point causes crashes of the machine. */
1604 + mdelay(10);
1605 + register_pci_controller(&pc_host->pci_controller);
1606 + return;
1607 +}
1608 +
1609 +/* Early PCI fixup for a device on the PCI-core bridge. */
1610 +static void bcma_core_pci_fixup_pcibridge(struct pci_dev *dev)
1611 +{
1612 + if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
1613 + /* This is not a device on the PCI-core bridge. */
1614 + return;
1615 + }
1616 + if (PCI_SLOT(dev->devfn) != 0)
1617 + return;
1618 +
1619 + pr_info("PCI: Fixing up bridge %s\n", pci_name(dev));
1620 +
1621 + /* Enable PCI bridge bus mastering and memory space */
1622 + pci_set_master(dev);
1623 + if (pcibios_enable_device(dev, ~0) < 0) {
1624 + pr_err("PCI: BCMA bridge enable failed\n");
1625 + return;
1626 + }
1627 +
1628 + /* Enable PCI bridge BAR1 prefetch and burst */
1629 + pci_write_config_dword(dev, BCMA_PCI_BAR1_CONTROL, 3);
1630 +}
1631 +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_pcibridge);
1632 +
1633 +/* Early PCI fixup for all PCI-cores to set the correct memory address. */
1634 +static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
1635 +{
1636 + struct resource *res;
1637 + int pos;
1638 +
1639 + if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
1640 + /* This is not a device on the PCI-core bridge. */
1641 + return;
1642 + }
1643 + if (PCI_SLOT(dev->devfn) == 0)
1644 + return;
1645 +
1646 + pr_info("PCI: Fixing up addresses %s\n", pci_name(dev));
1647 +
1648 + for (pos = 0; pos < 6; pos++) {
1649 + res = &dev->resource[pos];
1650 + if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM))
1651 + pci_assign_resource(dev, pos);
1652 + }
1653 +}
1654 +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses);
1655 +
1656 +/* This function is called when doing a pci_enable_device().
1657 + * We must first check if the device is a device on the PCI-core bridge. */
1658 +int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
1659 +{
1660 + struct bcma_drv_pci_host *pc_host;
1661 +
1662 + if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
1663 + /* This is not a device on the PCI-core bridge. */
1664 + return -ENODEV;
1665 + }
1666 + pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
1667 + pci_ops);
1668 +
1669 + pr_info("PCI: Fixing up device %s\n", pci_name(dev));
1670 +
1671 + /* Fix up interrupt lines */
1672 + dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2;
1673 + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
1674 +
1675 + return 0;
1676 +}
1677 +EXPORT_SYMBOL(bcma_core_pci_plat_dev_init);
1678 +
1679 +/* PCI device IRQ mapping. */
1680 +int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev)
1681 +{
1682 + struct bcma_drv_pci_host *pc_host;
1683 +
1684 + if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
1685 + /* This is not a device on the PCI-core bridge. */
1686 + return -ENODEV;
1687 + }
1688 +
1689 + pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
1690 + pci_ops);
1691 + return bcma_core_mips_irq(pc_host->pdev->core) + 2;
1692 +}
1693 +EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq);
1694 --- a/drivers/bcma/host_pci.c
1695 +++ b/drivers/bcma/host_pci.c
1696 @@ -9,6 +9,7 @@
1697 #include <linux/slab.h>
1698 #include <linux/bcma/bcma.h>
1699 #include <linux/pci.h>
1700 +#include <linux/module.h>
1701
1702 static void bcma_host_pci_switch_core(struct bcma_device *core)
1703 {
1704 @@ -20,50 +21,108 @@ static void bcma_host_pci_switch_core(st
1705 pr_debug("Switched to core: 0x%X\n", core->id.id);
1706 }
1707
1708 -static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
1709 -{
1710 +/* Provides access to the requested core. Returns base offset that has to be
1711 + * used. It makes use of fixed windows when possible. */
1712 +static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core)
1713 +{
1714 + switch (core->id.id) {
1715 + case BCMA_CORE_CHIPCOMMON:
1716 + return 3 * BCMA_CORE_SIZE;
1717 + case BCMA_CORE_PCIE:
1718 + return 2 * BCMA_CORE_SIZE;
1719 + }
1720 +
1721 if (core->bus->mapped_core != core)
1722 bcma_host_pci_switch_core(core);
1723 + return 0;
1724 +}
1725 +
1726 +static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
1727 +{
1728 + offset += bcma_host_pci_provide_access_to_core(core);
1729 return ioread8(core->bus->mmio + offset);
1730 }
1731
1732 static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
1733 {
1734 - if (core->bus->mapped_core != core)
1735 - bcma_host_pci_switch_core(core);
1736 + offset += bcma_host_pci_provide_access_to_core(core);
1737 return ioread16(core->bus->mmio + offset);
1738 }
1739
1740 static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
1741 {
1742 - if (core->bus->mapped_core != core)
1743 - bcma_host_pci_switch_core(core);
1744 + offset += bcma_host_pci_provide_access_to_core(core);
1745 return ioread32(core->bus->mmio + offset);
1746 }
1747
1748 static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
1749 u8 value)
1750 {
1751 - if (core->bus->mapped_core != core)
1752 - bcma_host_pci_switch_core(core);
1753 + offset += bcma_host_pci_provide_access_to_core(core);
1754 iowrite8(value, core->bus->mmio + offset);
1755 }
1756
1757 static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
1758 u16 value)
1759 {
1760 - if (core->bus->mapped_core != core)
1761 - bcma_host_pci_switch_core(core);
1762 + offset += bcma_host_pci_provide_access_to_core(core);
1763 iowrite16(value, core->bus->mmio + offset);
1764 }
1765
1766 static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
1767 u32 value)
1768 {
1769 + offset += bcma_host_pci_provide_access_to_core(core);
1770 + iowrite32(value, core->bus->mmio + offset);
1771 +}
1772 +
1773 +#ifdef CONFIG_BCMA_BLOCKIO
1774 +void bcma_host_pci_block_read(struct bcma_device *core, void *buffer,
1775 + size_t count, u16 offset, u8 reg_width)
1776 +{
1777 + void __iomem *addr = core->bus->mmio + offset;
1778 if (core->bus->mapped_core != core)
1779 bcma_host_pci_switch_core(core);
1780 - iowrite32(value, core->bus->mmio + offset);
1781 + switch (reg_width) {
1782 + case sizeof(u8):
1783 + ioread8_rep(addr, buffer, count);
1784 + break;
1785 + case sizeof(u16):
1786 + WARN_ON(count & 1);
1787 + ioread16_rep(addr, buffer, count >> 1);
1788 + break;
1789 + case sizeof(u32):
1790 + WARN_ON(count & 3);
1791 + ioread32_rep(addr, buffer, count >> 2);
1792 + break;
1793 + default:
1794 + WARN_ON(1);
1795 + }
1796 +}
1797 +
1798 +void bcma_host_pci_block_write(struct bcma_device *core, const void *buffer,
1799 + size_t count, u16 offset, u8 reg_width)
1800 +{
1801 + void __iomem *addr = core->bus->mmio + offset;
1802 + if (core->bus->mapped_core != core)
1803 + bcma_host_pci_switch_core(core);
1804 + switch (reg_width) {
1805 + case sizeof(u8):
1806 + iowrite8_rep(addr, buffer, count);
1807 + break;
1808 + case sizeof(u16):
1809 + WARN_ON(count & 1);
1810 + iowrite16_rep(addr, buffer, count >> 1);
1811 + break;
1812 + case sizeof(u32):
1813 + WARN_ON(count & 3);
1814 + iowrite32_rep(addr, buffer, count >> 2);
1815 + break;
1816 + default:
1817 + WARN_ON(1);
1818 + }
1819 }
1820 +#endif
1821
1822 static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset)
1823 {
1824 @@ -87,12 +146,16 @@ const struct bcma_host_ops bcma_host_pci
1825 .write8 = bcma_host_pci_write8,
1826 .write16 = bcma_host_pci_write16,
1827 .write32 = bcma_host_pci_write32,
1828 +#ifdef CONFIG_BCMA_BLOCKIO
1829 + .block_read = bcma_host_pci_block_read,
1830 + .block_write = bcma_host_pci_block_write,
1831 +#endif
1832 .aread32 = bcma_host_pci_aread32,
1833 .awrite32 = bcma_host_pci_awrite32,
1834 };
1835
1836 -static int bcma_host_pci_probe(struct pci_dev *dev,
1837 - const struct pci_device_id *id)
1838 +static int __devinit bcma_host_pci_probe(struct pci_dev *dev,
1839 + const struct pci_device_id *id)
1840 {
1841 struct bcma_bus *bus;
1842 int err = -ENOMEM;
1843 @@ -171,10 +234,40 @@ static void bcma_host_pci_remove(struct
1844 pci_set_drvdata(dev, NULL);
1845 }
1846
1847 +#ifdef CONFIG_PM
1848 +static int bcma_host_pci_suspend(struct device *dev)
1849 +{
1850 + struct pci_dev *pdev = to_pci_dev(dev);
1851 + struct bcma_bus *bus = pci_get_drvdata(pdev);
1852 +
1853 + bus->mapped_core = NULL;
1854 +
1855 + return bcma_bus_suspend(bus);
1856 +}
1857 +
1858 +static int bcma_host_pci_resume(struct device *dev)
1859 +{
1860 + struct pci_dev *pdev = to_pci_dev(dev);
1861 + struct bcma_bus *bus = pci_get_drvdata(pdev);
1862 +
1863 + return bcma_bus_resume(bus);
1864 +}
1865 +
1866 +static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend,
1867 + bcma_host_pci_resume);
1868 +#define BCMA_PM_OPS (&bcma_pm_ops)
1869 +
1870 +#else /* CONFIG_PM */
1871 +
1872 +#define BCMA_PM_OPS NULL
1873 +
1874 +#endif /* CONFIG_PM */
1875 +
1876 static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
1877 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
1878 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
1879 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
1880 + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
1881 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
1882 { 0, },
1883 };
1884 @@ -185,6 +278,7 @@ static struct pci_driver bcma_pci_bridge
1885 .id_table = bcma_pci_bridge_tbl,
1886 .probe = bcma_host_pci_probe,
1887 .remove = bcma_host_pci_remove,
1888 + .driver.pm = BCMA_PM_OPS,
1889 };
1890
1891 int __init bcma_host_pci_init(void)
1892 --- /dev/null
1893 +++ b/drivers/bcma/host_soc.c
1894 @@ -0,0 +1,183 @@
1895 +/*
1896 + * Broadcom specific AMBA
1897 + * System on Chip (SoC) Host
1898 + *
1899 + * Licensed under the GNU/GPL. See COPYING for details.
1900 + */
1901 +
1902 +#include "bcma_private.h"
1903 +#include "scan.h"
1904 +#include <linux/bcma/bcma.h>
1905 +#include <linux/bcma/bcma_soc.h>
1906 +
1907 +static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
1908 +{
1909 + return readb(core->io_addr + offset);
1910 +}
1911 +
1912 +static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
1913 +{
1914 + return readw(core->io_addr + offset);
1915 +}
1916 +
1917 +static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
1918 +{
1919 + return readl(core->io_addr + offset);
1920 +}
1921 +
1922 +static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
1923 + u8 value)
1924 +{
1925 + writeb(value, core->io_addr + offset);
1926 +}
1927 +
1928 +static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
1929 + u16 value)
1930 +{
1931 + writew(value, core->io_addr + offset);
1932 +}
1933 +
1934 +static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
1935 + u32 value)
1936 +{
1937 + writel(value, core->io_addr + offset);
1938 +}
1939 +
1940 +#ifdef CONFIG_BCMA_BLOCKIO
1941 +static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
1942 + size_t count, u16 offset, u8 reg_width)
1943 +{
1944 + void __iomem *addr = core->io_addr + offset;
1945 +
1946 + switch (reg_width) {
1947 + case sizeof(u8): {
1948 + u8 *buf = buffer;
1949 +
1950 + while (count) {
1951 + *buf = __raw_readb(addr);
1952 + buf++;
1953 + count--;
1954 + }
1955 + break;
1956 + }
1957 + case sizeof(u16): {
1958 + __le16 *buf = buffer;
1959 +
1960 + WARN_ON(count & 1);
1961 + while (count) {
1962 + *buf = (__force __le16)__raw_readw(addr);
1963 + buf++;
1964 + count -= 2;
1965 + }
1966 + break;
1967 + }
1968 + case sizeof(u32): {
1969 + __le32 *buf = buffer;
1970 +
1971 + WARN_ON(count & 3);
1972 + while (count) {
1973 + *buf = (__force __le32)__raw_readl(addr);
1974 + buf++;
1975 + count -= 4;
1976 + }
1977 + break;
1978 + }
1979 + default:
1980 + WARN_ON(1);
1981 + }
1982 +}
1983 +
1984 +static void bcma_host_soc_block_write(struct bcma_device *core,
1985 + const void *buffer,
1986 + size_t count, u16 offset, u8 reg_width)
1987 +{
1988 + void __iomem *addr = core->io_addr + offset;
1989 +
1990 + switch (reg_width) {
1991 + case sizeof(u8): {
1992 + const u8 *buf = buffer;
1993 +
1994 + while (count) {
1995 + __raw_writeb(*buf, addr);
1996 + buf++;
1997 + count--;
1998 + }
1999 + break;
2000 + }
2001 + case sizeof(u16): {
2002 + const __le16 *buf = buffer;
2003 +
2004 + WARN_ON(count & 1);
2005 + while (count) {
2006 + __raw_writew((__force u16)(*buf), addr);
2007 + buf++;
2008 + count -= 2;
2009 + }
2010 + break;
2011 + }
2012 + case sizeof(u32): {
2013 + const __le32 *buf = buffer;
2014 +
2015 + WARN_ON(count & 3);
2016 + while (count) {
2017 + __raw_writel((__force u32)(*buf), addr);
2018 + buf++;
2019 + count -= 4;
2020 + }
2021 + break;
2022 + }
2023 + default:
2024 + WARN_ON(1);
2025 + }
2026 +}
2027 +#endif /* CONFIG_BCMA_BLOCKIO */
2028 +
2029 +static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
2030 +{
2031 + return readl(core->io_wrap + offset);
2032 +}
2033 +
2034 +static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
2035 + u32 value)
2036 +{
2037 + writel(value, core->io_wrap + offset);
2038 +}
2039 +
2040 +const struct bcma_host_ops bcma_host_soc_ops = {
2041 + .read8 = bcma_host_soc_read8,
2042 + .read16 = bcma_host_soc_read16,
2043 + .read32 = bcma_host_soc_read32,
2044 + .write8 = bcma_host_soc_write8,
2045 + .write16 = bcma_host_soc_write16,
2046 + .write32 = bcma_host_soc_write32,
2047 +#ifdef CONFIG_BCMA_BLOCKIO
2048 + .block_read = bcma_host_soc_block_read,
2049 + .block_write = bcma_host_soc_block_write,
2050 +#endif
2051 + .aread32 = bcma_host_soc_aread32,
2052 + .awrite32 = bcma_host_soc_awrite32,
2053 +};
2054 +
2055 +int __init bcma_host_soc_register(struct bcma_soc *soc)
2056 +{
2057 + struct bcma_bus *bus = &soc->bus;
2058 + int err;
2059 +
2060 + /* iomap only first core. We have to read some register on this core
2061 + * to scan the bus.
2062 + */
2063 + bus->mmio = ioremap_nocache(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
2064 + if (!bus->mmio)
2065 + return -ENOMEM;
2066 +
2067 + /* Host specific */
2068 + bus->hosttype = BCMA_HOSTTYPE_SOC;
2069 + bus->ops = &bcma_host_soc_ops;
2070 +
2071 + /* Register */
2072 + err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
2073 + if (err)
2074 + iounmap(bus->mmio);
2075 +
2076 + return err;
2077 +}
2078 --- a/drivers/bcma/main.c
2079 +++ b/drivers/bcma/main.c
2080 @@ -6,14 +6,23 @@
2081 */
2082
2083 #include "bcma_private.h"
2084 +#include <linux/module.h>
2085 #include <linux/bcma/bcma.h>
2086 +#include <linux/slab.h>
2087
2088 MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
2089 MODULE_LICENSE("GPL");
2090
2091 +/* contains the number the next bus should get. */
2092 +static unsigned int bcma_bus_next_num = 0;
2093 +
2094 +/* bcma_buses_mutex locks the bcma_bus_next_num */
2095 +static DEFINE_MUTEX(bcma_buses_mutex);
2096 +
2097 static int bcma_bus_match(struct device *dev, struct device_driver *drv);
2098 static int bcma_device_probe(struct device *dev);
2099 static int bcma_device_remove(struct device *dev);
2100 +static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env);
2101
2102 static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
2103 {
2104 @@ -48,10 +57,11 @@ static struct bus_type bcma_bus_type = {
2105 .match = bcma_bus_match,
2106 .probe = bcma_device_probe,
2107 .remove = bcma_device_remove,
2108 + .uevent = bcma_device_uevent,
2109 .dev_attrs = bcma_device_attrs,
2110 };
2111
2112 -static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
2113 +struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
2114 {
2115 struct bcma_device *core;
2116
2117 @@ -61,10 +71,15 @@ static struct bcma_device *bcma_find_cor
2118 }
2119 return NULL;
2120 }
2121 +EXPORT_SYMBOL_GPL(bcma_find_core);
2122
2123 static void bcma_release_core_dev(struct device *dev)
2124 {
2125 struct bcma_device *core = container_of(dev, struct bcma_device, dev);
2126 + if (core->io_addr)
2127 + iounmap(core->io_addr);
2128 + if (core->io_wrap)
2129 + iounmap(core->io_wrap);
2130 kfree(core);
2131 }
2132
2133 @@ -79,18 +94,24 @@ static int bcma_register_cores(struct bc
2134 case BCMA_CORE_CHIPCOMMON:
2135 case BCMA_CORE_PCI:
2136 case BCMA_CORE_PCIE:
2137 + case BCMA_CORE_MIPS_74K:
2138 continue;
2139 }
2140
2141 core->dev.release = bcma_release_core_dev;
2142 core->dev.bus = &bcma_bus_type;
2143 - dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
2144 + dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
2145
2146 switch (bus->hosttype) {
2147 case BCMA_HOSTTYPE_PCI:
2148 core->dev.parent = &bus->host_pci->dev;
2149 + core->dma_dev = &bus->host_pci->dev;
2150 + core->irq = bus->host_pci->irq;
2151 + break;
2152 + case BCMA_HOSTTYPE_SOC:
2153 + core->dev.dma_mask = &core->dev.coherent_dma_mask;
2154 + core->dma_dev = &core->dev;
2155 break;
2156 - case BCMA_HOSTTYPE_NONE:
2157 case BCMA_HOSTTYPE_SDIO:
2158 break;
2159 }
2160 @@ -118,11 +139,15 @@ static void bcma_unregister_cores(struct
2161 }
2162 }
2163
2164 -int bcma_bus_register(struct bcma_bus *bus)
2165 +int __devinit bcma_bus_register(struct bcma_bus *bus)
2166 {
2167 int err;
2168 struct bcma_device *core;
2169
2170 + mutex_lock(&bcma_buses_mutex);
2171 + bus->num = bcma_bus_next_num++;
2172 + mutex_unlock(&bcma_buses_mutex);
2173 +
2174 /* Scan for devices (cores) */
2175 err = bcma_bus_scan(bus);
2176 if (err) {
2177 @@ -137,6 +162,13 @@ int bcma_bus_register(struct bcma_bus *b
2178 bcma_core_chipcommon_init(&bus->drv_cc);
2179 }
2180
2181 + /* Init MIPS core */
2182 + core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
2183 + if (core) {
2184 + bus->drv_mips.core = core;
2185 + bcma_core_mips_init(&bus->drv_mips);
2186 + }
2187 +
2188 /* Init PCIE core */
2189 core = bcma_find_core(bus, BCMA_CORE_PCIE);
2190 if (core) {
2191 @@ -144,6 +176,13 @@ int bcma_bus_register(struct bcma_bus *b
2192 bcma_core_pci_init(&bus->drv_pci);
2193 }
2194
2195 + /* Try to get SPROM */
2196 + err = bcma_sprom_get(bus);
2197 + if (err == -ENOENT) {
2198 + pr_err("No SPROM available\n");
2199 + } else if (err)
2200 + pr_err("Failed to get SPROM: %d\n", err);
2201 +
2202 /* Register found cores */
2203 bcma_register_cores(bus);
2204
2205 @@ -151,13 +190,104 @@ int bcma_bus_register(struct bcma_bus *b
2206
2207 return 0;
2208 }
2209 -EXPORT_SYMBOL_GPL(bcma_bus_register);
2210
2211 void bcma_bus_unregister(struct bcma_bus *bus)
2212 {
2213 bcma_unregister_cores(bus);
2214 }
2215 -EXPORT_SYMBOL_GPL(bcma_bus_unregister);
2216 +
2217 +int __init bcma_bus_early_register(struct bcma_bus *bus,
2218 + struct bcma_device *core_cc,
2219 + struct bcma_device *core_mips)
2220 +{
2221 + int err;
2222 + struct bcma_device *core;
2223 + struct bcma_device_id match;
2224 +
2225 + bcma_init_bus(bus);
2226 +
2227 + match.manuf = BCMA_MANUF_BCM;
2228 + match.id = BCMA_CORE_CHIPCOMMON;
2229 + match.class = BCMA_CL_SIM;
2230 + match.rev = BCMA_ANY_REV;
2231 +
2232 + /* Scan for chip common core */
2233 + err = bcma_bus_scan_early(bus, &match, core_cc);
2234 + if (err) {
2235 + pr_err("Failed to scan for common core: %d\n", err);
2236 + return -1;
2237 + }
2238 +
2239 + match.manuf = BCMA_MANUF_MIPS;
2240 + match.id = BCMA_CORE_MIPS_74K;
2241 + match.class = BCMA_CL_SIM;
2242 + match.rev = BCMA_ANY_REV;
2243 +
2244 + /* Scan for mips core */
2245 + err = bcma_bus_scan_early(bus, &match, core_mips);
2246 + if (err) {
2247 + pr_err("Failed to scan for mips core: %d\n", err);
2248 + return -1;
2249 + }
2250 +
2251 + /* Init CC core */
2252 + core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
2253 + if (core) {
2254 + bus->drv_cc.core = core;
2255 + bcma_core_chipcommon_init(&bus->drv_cc);
2256 + }
2257 +
2258 + /* Init MIPS core */
2259 + core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
2260 + if (core) {
2261 + bus->drv_mips.core = core;
2262 + bcma_core_mips_init(&bus->drv_mips);
2263 + }
2264 +
2265 + pr_info("Early bus registered\n");
2266 +
2267 + return 0;
2268 +}
2269 +
2270 +#ifdef CONFIG_PM
2271 +int bcma_bus_suspend(struct bcma_bus *bus)
2272 +{
2273 + struct bcma_device *core;
2274 +
2275 + list_for_each_entry(core, &bus->cores, list) {
2276 + struct device_driver *drv = core->dev.driver;
2277 + if (drv) {
2278 + struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
2279 + if (adrv->suspend)
2280 + adrv->suspend(core);
2281 + }
2282 + }
2283 + return 0;
2284 +}
2285 +
2286 +int bcma_bus_resume(struct bcma_bus *bus)
2287 +{
2288 + struct bcma_device *core;
2289 +
2290 + /* Init CC core */
2291 + core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
2292 + if (core) {
2293 + bus->drv_cc.setup_done = false;
2294 + bcma_core_chipcommon_init(&bus->drv_cc);
2295 + }
2296 +
2297 + list_for_each_entry(core, &bus->cores, list) {
2298 + struct device_driver *drv = core->dev.driver;
2299 + if (drv) {
2300 + struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
2301 + if (adrv->resume)
2302 + adrv->resume(core);
2303 + }
2304 + }
2305 +
2306 + return 0;
2307 +}
2308 +#endif
2309
2310 int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
2311 {
2312 @@ -217,6 +347,16 @@ static int bcma_device_remove(struct dev
2313 return 0;
2314 }
2315
2316 +static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env)
2317 +{
2318 + struct bcma_device *core = container_of(dev, struct bcma_device, dev);
2319 +
2320 + return add_uevent_var(env,
2321 + "MODALIAS=bcma:m%04Xid%04Xrev%02Xcl%02X",
2322 + core->id.manuf, core->id.id,
2323 + core->id.rev, core->id.class);
2324 +}
2325 +
2326 static int __init bcma_modinit(void)
2327 {
2328 int err;
2329 --- a/drivers/bcma/scan.c
2330 +++ b/drivers/bcma/scan.c
2331 @@ -200,18 +200,174 @@ static s32 bcma_erom_get_addr_desc(struc
2332 return addrl;
2333 }
2334
2335 -int bcma_bus_scan(struct bcma_bus *bus)
2336 +static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
2337 + u16 index)
2338 {
2339 - u32 erombase;
2340 - u32 __iomem *eromptr, *eromend;
2341 + struct bcma_device *core;
2342 +
2343 + list_for_each_entry(core, &bus->cores, list) {
2344 + if (core->core_index == index)
2345 + return core;
2346 + }
2347 + return NULL;
2348 +}
2349 +
2350 +static struct bcma_device *bcma_find_core_reverse(struct bcma_bus *bus, u16 coreid)
2351 +{
2352 + struct bcma_device *core;
2353 +
2354 + list_for_each_entry_reverse(core, &bus->cores, list) {
2355 + if (core->id.id == coreid)
2356 + return core;
2357 + }
2358 + return NULL;
2359 +}
2360
2361 +static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
2362 + struct bcma_device_id *match, int core_num,
2363 + struct bcma_device *core)
2364 +{
2365 + s32 tmp;
2366 + u8 i, j;
2367 s32 cia, cib;
2368 u8 ports[2], wrappers[2];
2369
2370 + /* get CIs */
2371 + cia = bcma_erom_get_ci(bus, eromptr);
2372 + if (cia < 0) {
2373 + bcma_erom_push_ent(eromptr);
2374 + if (bcma_erom_is_end(bus, eromptr))
2375 + return -ESPIPE;
2376 + return -EILSEQ;
2377 + }
2378 + cib = bcma_erom_get_ci(bus, eromptr);
2379 + if (cib < 0)
2380 + return -EILSEQ;
2381 +
2382 + /* parse CIs */
2383 + core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
2384 + core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
2385 + core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
2386 + ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
2387 + ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
2388 + wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
2389 + wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
2390 + core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
2391 +
2392 + if (((core->id.manuf == BCMA_MANUF_ARM) &&
2393 + (core->id.id == 0xFFF)) ||
2394 + (ports[1] == 0)) {
2395 + bcma_erom_skip_component(bus, eromptr);
2396 + return -ENXIO;
2397 + }
2398 +
2399 + /* check if component is a core at all */
2400 + if (wrappers[0] + wrappers[1] == 0) {
2401 + /* we could save addrl of the router
2402 + if (cid == BCMA_CORE_OOB_ROUTER)
2403 + */
2404 + bcma_erom_skip_component(bus, eromptr);
2405 + return -ENXIO;
2406 + }
2407 +
2408 + if (bcma_erom_is_bridge(bus, eromptr)) {
2409 + bcma_erom_skip_component(bus, eromptr);
2410 + return -ENXIO;
2411 + }
2412 +
2413 + if (bcma_find_core_by_index(bus, core_num)) {
2414 + bcma_erom_skip_component(bus, eromptr);
2415 + return -ENODEV;
2416 + }
2417 +
2418 + if (match && ((match->manuf != BCMA_ANY_MANUF &&
2419 + match->manuf != core->id.manuf) ||
2420 + (match->id != BCMA_ANY_ID && match->id != core->id.id) ||
2421 + (match->rev != BCMA_ANY_REV && match->rev != core->id.rev) ||
2422 + (match->class != BCMA_ANY_CLASS && match->class != core->id.class)
2423 + )) {
2424 + bcma_erom_skip_component(bus, eromptr);
2425 + return -ENODEV;
2426 + }
2427 +
2428 + /* get & parse master ports */
2429 + for (i = 0; i < ports[0]; i++) {
2430 + s32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
2431 + if (mst_port_d < 0)
2432 + return -EILSEQ;
2433 + }
2434 +
2435 + /* get & parse slave ports */
2436 + for (i = 0; i < ports[1]; i++) {
2437 + for (j = 0; ; j++) {
2438 + tmp = bcma_erom_get_addr_desc(bus, eromptr,
2439 + SCAN_ADDR_TYPE_SLAVE, i);
2440 + if (tmp < 0) {
2441 + /* no more entries for port _i_ */
2442 + /* pr_debug("erom: slave port %d "
2443 + * "has %d descriptors\n", i, j); */
2444 + break;
2445 + } else {
2446 + if (i == 0 && j == 0)
2447 + core->addr = tmp;
2448 + }
2449 + }
2450 + }
2451 +
2452 + /* get & parse master wrappers */
2453 + for (i = 0; i < wrappers[0]; i++) {
2454 + for (j = 0; ; j++) {
2455 + tmp = bcma_erom_get_addr_desc(bus, eromptr,
2456 + SCAN_ADDR_TYPE_MWRAP, i);
2457 + if (tmp < 0) {
2458 + /* no more entries for port _i_ */
2459 + /* pr_debug("erom: master wrapper %d "
2460 + * "has %d descriptors\n", i, j); */
2461 + break;
2462 + } else {
2463 + if (i == 0 && j == 0)
2464 + core->wrap = tmp;
2465 + }
2466 + }
2467 + }
2468 +
2469 + /* get & parse slave wrappers */
2470 + for (i = 0; i < wrappers[1]; i++) {
2471 + u8 hack = (ports[1] == 1) ? 0 : 1;
2472 + for (j = 0; ; j++) {
2473 + tmp = bcma_erom_get_addr_desc(bus, eromptr,
2474 + SCAN_ADDR_TYPE_SWRAP, i + hack);
2475 + if (tmp < 0) {
2476 + /* no more entries for port _i_ */
2477 + /* pr_debug("erom: master wrapper %d "
2478 + * has %d descriptors\n", i, j); */
2479 + break;
2480 + } else {
2481 + if (wrappers[0] == 0 && !i && !j)
2482 + core->wrap = tmp;
2483 + }
2484 + }
2485 + }
2486 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
2487 + core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE);
2488 + if (!core->io_addr)
2489 + return -ENOMEM;
2490 + core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE);
2491 + if (!core->io_wrap) {
2492 + iounmap(core->io_addr);
2493 + return -ENOMEM;
2494 + }
2495 + }
2496 + return 0;
2497 +}
2498 +
2499 +void bcma_init_bus(struct bcma_bus *bus)
2500 +{
2501 s32 tmp;
2502 - u8 i, j;
2503 + struct bcma_chipinfo *chipinfo = &(bus->chipinfo);
2504
2505 - int err;
2506 + if (bus->init_done)
2507 + return;
2508
2509 INIT_LIST_HEAD(&bus->cores);
2510 bus->nr_cores = 0;
2511 @@ -219,142 +375,133 @@ int bcma_bus_scan(struct bcma_bus *bus)
2512 bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
2513
2514 tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
2515 - bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
2516 - bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
2517 - bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
2518 + chipinfo->id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
2519 + chipinfo->rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
2520 + chipinfo->pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
2521 + pr_info("Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n",
2522 + chipinfo->id, chipinfo->rev, chipinfo->pkg);
2523 +
2524 + bus->init_done = true;
2525 +}
2526 +
2527 +int bcma_bus_scan(struct bcma_bus *bus)
2528 +{
2529 + u32 erombase;
2530 + u32 __iomem *eromptr, *eromend;
2531 +
2532 + int err, core_num = 0;
2533 +
2534 + bcma_init_bus(bus);
2535
2536 erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
2537 - eromptr = bus->mmio;
2538 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
2539 + eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
2540 + if (!eromptr)
2541 + return -ENOMEM;
2542 + } else {
2543 + eromptr = bus->mmio;
2544 + }
2545 +
2546 eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
2547
2548 bcma_scan_switch_core(bus, erombase);
2549
2550 while (eromptr < eromend) {
2551 + struct bcma_device *other_core;
2552 struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
2553 if (!core)
2554 return -ENOMEM;
2555 INIT_LIST_HEAD(&core->list);
2556 core->bus = bus;
2557
2558 - /* get CIs */
2559 - cia = bcma_erom_get_ci(bus, &eromptr);
2560 - if (cia < 0) {
2561 - bcma_erom_push_ent(&eromptr);
2562 - if (bcma_erom_is_end(bus, &eromptr))
2563 + err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
2564 + if (err < 0) {
2565 + kfree(core);
2566 + if (err == -ENODEV) {
2567 + core_num++;
2568 + continue;
2569 + } else if (err == -ENXIO) {
2570 + continue;
2571 + } else if (err == -ESPIPE) {
2572 break;
2573 - err= -EILSEQ;
2574 - goto out;
2575 - }
2576 - cib = bcma_erom_get_ci(bus, &eromptr);
2577 - if (cib < 0) {
2578 - err= -EILSEQ;
2579 - goto out;
2580 + }
2581 + return err;
2582 }
2583
2584 - /* parse CIs */
2585 - core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
2586 - core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
2587 - core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
2588 - ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
2589 - ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
2590 - wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
2591 - wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
2592 - core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
2593 -
2594 - if (((core->id.manuf == BCMA_MANUF_ARM) &&
2595 - (core->id.id == 0xFFF)) ||
2596 - (ports[1] == 0)) {
2597 - bcma_erom_skip_component(bus, &eromptr);
2598 - continue;
2599 - }
2600 + core->core_index = core_num++;
2601 + bus->nr_cores++;
2602 + other_core = bcma_find_core_reverse(bus, core->id.id);
2603 + core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1;
2604
2605 - /* check if component is a core at all */
2606 - if (wrappers[0] + wrappers[1] == 0) {
2607 - /* we could save addrl of the router
2608 - if (cid == BCMA_CORE_OOB_ROUTER)
2609 - */
2610 - bcma_erom_skip_component(bus, &eromptr);
2611 - continue;
2612 - }
2613 + pr_info("Core %d found: %s "
2614 + "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
2615 + core->core_index, bcma_device_name(&core->id),
2616 + core->id.manuf, core->id.id, core->id.rev,
2617 + core->id.class);
2618
2619 - if (bcma_erom_is_bridge(bus, &eromptr)) {
2620 - bcma_erom_skip_component(bus, &eromptr);
2621 - continue;
2622 - }
2623 + list_add(&core->list, &bus->cores);
2624 + }
2625
2626 - /* get & parse master ports */
2627 - for (i = 0; i < ports[0]; i++) {
2628 - u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
2629 - if (mst_port_d < 0) {
2630 - err= -EILSEQ;
2631 - goto out;
2632 - }
2633 - }
2634 + if (bus->hosttype == BCMA_HOSTTYPE_SOC)
2635 + iounmap(eromptr);
2636
2637 - /* get & parse slave ports */
2638 - for (i = 0; i < ports[1]; i++) {
2639 - for (j = 0; ; j++) {
2640 - tmp = bcma_erom_get_addr_desc(bus, &eromptr,
2641 - SCAN_ADDR_TYPE_SLAVE, i);
2642 - if (tmp < 0) {
2643 - /* no more entries for port _i_ */
2644 - /* pr_debug("erom: slave port %d "
2645 - * "has %d descriptors\n", i, j); */
2646 - break;
2647 - } else {
2648 - if (i == 0 && j == 0)
2649 - core->addr = tmp;
2650 - }
2651 - }
2652 - }
2653 + return 0;
2654 +}
2655
2656 - /* get & parse master wrappers */
2657 - for (i = 0; i < wrappers[0]; i++) {
2658 - for (j = 0; ; j++) {
2659 - tmp = bcma_erom_get_addr_desc(bus, &eromptr,
2660 - SCAN_ADDR_TYPE_MWRAP, i);
2661 - if (tmp < 0) {
2662 - /* no more entries for port _i_ */
2663 - /* pr_debug("erom: master wrapper %d "
2664 - * "has %d descriptors\n", i, j); */
2665 - break;
2666 - } else {
2667 - if (i == 0 && j == 0)
2668 - core->wrap = tmp;
2669 - }
2670 - }
2671 - }
2672 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
2673 + struct bcma_device_id *match,
2674 + struct bcma_device *core)
2675 +{
2676 + u32 erombase;
2677 + u32 __iomem *eromptr, *eromend;
2678
2679 - /* get & parse slave wrappers */
2680 - for (i = 0; i < wrappers[1]; i++) {
2681 - u8 hack = (ports[1] == 1) ? 0 : 1;
2682 - for (j = 0; ; j++) {
2683 - tmp = bcma_erom_get_addr_desc(bus, &eromptr,
2684 - SCAN_ADDR_TYPE_SWRAP, i + hack);
2685 - if (tmp < 0) {
2686 - /* no more entries for port _i_ */
2687 - /* pr_debug("erom: master wrapper %d "
2688 - * has %d descriptors\n", i, j); */
2689 - break;
2690 - } else {
2691 - if (wrappers[0] == 0 && !i && !j)
2692 - core->wrap = tmp;
2693 - }
2694 - }
2695 - }
2696 + int err = -ENODEV;
2697 + int core_num = 0;
2698 +
2699 + erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
2700 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
2701 + eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
2702 + if (!eromptr)
2703 + return -ENOMEM;
2704 + } else {
2705 + eromptr = bus->mmio;
2706 + }
2707
2708 + eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
2709 +
2710 + bcma_scan_switch_core(bus, erombase);
2711 +
2712 + while (eromptr < eromend) {
2713 + memset(core, 0, sizeof(*core));
2714 + INIT_LIST_HEAD(&core->list);
2715 + core->bus = bus;
2716 +
2717 + err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
2718 + if (err == -ENODEV) {
2719 + core_num++;
2720 + continue;
2721 + } else if (err == -ENXIO)
2722 + continue;
2723 + else if (err == -ESPIPE)
2724 + break;
2725 + else if (err < 0)
2726 + return err;
2727 +
2728 + core->core_index = core_num++;
2729 + bus->nr_cores++;
2730 pr_info("Core %d found: %s "
2731 "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
2732 - bus->nr_cores, bcma_device_name(&core->id),
2733 + core->core_index, bcma_device_name(&core->id),
2734 core->id.manuf, core->id.id, core->id.rev,
2735 core->id.class);
2736
2737 - core->core_index = bus->nr_cores++;
2738 list_add(&core->list, &bus->cores);
2739 - continue;
2740 -out:
2741 - return err;
2742 + err = 0;
2743 + break;
2744 }
2745
2746 - return 0;
2747 + if (bus->hosttype == BCMA_HOSTTYPE_SOC)
2748 + iounmap(eromptr);
2749 +
2750 + return err;
2751 }
2752 --- /dev/null
2753 +++ b/drivers/bcma/sprom.c
2754 @@ -0,0 +1,450 @@
2755 +/*
2756 + * Broadcom specific AMBA
2757 + * SPROM reading
2758 + *
2759 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
2760 + *
2761 + * Licensed under the GNU/GPL. See COPYING for details.
2762 + */
2763 +
2764 +#include "bcma_private.h"
2765 +
2766 +#include <linux/bcma/bcma.h>
2767 +#include <linux/bcma/bcma_regs.h>
2768 +#include <linux/pci.h>
2769 +#include <linux/io.h>
2770 +#include <linux/dma-mapping.h>
2771 +#include <linux/slab.h>
2772 +
2773 +static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out);
2774 +
2775 +/**
2776 + * bcma_arch_register_fallback_sprom - Registers a method providing a
2777 + * fallback SPROM if no SPROM is found.
2778 + *
2779 + * @sprom_callback: The callback function.
2780 + *
2781 + * With this function the architecture implementation may register a
2782 + * callback handler which fills the SPROM data structure. The fallback is
2783 + * used for PCI based BCMA devices, where no valid SPROM can be found
2784 + * in the shadow registers and to provide the SPROM for SoCs where BCMA is
2785 + * to controll the system bus.
2786 + *
2787 + * This function is useful for weird architectures that have a half-assed
2788 + * BCMA device hardwired to their PCI bus.
2789 + *
2790 + * This function is available for architecture code, only. So it is not
2791 + * exported.
2792 + */
2793 +int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus,
2794 + struct ssb_sprom *out))
2795 +{
2796 + if (get_fallback_sprom)
2797 + return -EEXIST;
2798 + get_fallback_sprom = sprom_callback;
2799 +
2800 + return 0;
2801 +}
2802 +
2803 +static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus,
2804 + struct ssb_sprom *out)
2805 +{
2806 + int err;
2807 +
2808 + if (!get_fallback_sprom) {
2809 + err = -ENOENT;
2810 + goto fail;
2811 + }
2812 +
2813 + err = get_fallback_sprom(bus, out);
2814 + if (err)
2815 + goto fail;
2816 +
2817 + pr_debug("Using SPROM revision %d provided by"
2818 + " platform.\n", bus->sprom.revision);
2819 + return 0;
2820 +fail:
2821 + pr_warn("Using fallback SPROM failed (err %d)\n", err);
2822 + return err;
2823 +}
2824 +
2825 +/**************************************************
2826 + * R/W ops.
2827 + **************************************************/
2828 +
2829 +static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom)
2830 +{
2831 + int i;
2832 + for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
2833 + sprom[i] = bcma_read16(bus->drv_cc.core,
2834 + offset + (i * 2));
2835 +}
2836 +
2837 +/**************************************************
2838 + * Validation.
2839 + **************************************************/
2840 +
2841 +static inline u8 bcma_crc8(u8 crc, u8 data)
2842 +{
2843 + /* Polynomial: x^8 + x^7 + x^6 + x^4 + x^2 + 1 */
2844 + static const u8 t[] = {
2845 + 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
2846 + 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
2847 + 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
2848 + 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
2849 + 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
2850 + 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
2851 + 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
2852 + 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
2853 + 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
2854 + 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
2855 + 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
2856 + 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
2857 + 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
2858 + 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
2859 + 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
2860 + 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
2861 + 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
2862 + 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
2863 + 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
2864 + 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
2865 + 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
2866 + 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
2867 + 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
2868 + 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
2869 + 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
2870 + 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
2871 + 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
2872 + 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
2873 + 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
2874 + 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
2875 + 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
2876 + 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
2877 + };
2878 + return t[crc ^ data];
2879 +}
2880 +
2881 +static u8 bcma_sprom_crc(const u16 *sprom)
2882 +{
2883 + int word;
2884 + u8 crc = 0xFF;
2885 +
2886 + for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) {
2887 + crc = bcma_crc8(crc, sprom[word] & 0x00FF);
2888 + crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
2889 + }
2890 + crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF);
2891 + crc ^= 0xFF;
2892 +
2893 + return crc;
2894 +}
2895 +
2896 +static int bcma_sprom_check_crc(const u16 *sprom)
2897 +{
2898 + u8 crc;
2899 + u8 expected_crc;
2900 + u16 tmp;
2901 +
2902 + crc = bcma_sprom_crc(sprom);
2903 + tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC;
2904 + expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
2905 + if (crc != expected_crc)
2906 + return -EPROTO;
2907 +
2908 + return 0;
2909 +}
2910 +
2911 +static int bcma_sprom_valid(const u16 *sprom)
2912 +{
2913 + u16 revision;
2914 + int err;
2915 +
2916 + err = bcma_sprom_check_crc(sprom);
2917 + if (err)
2918 + return err;
2919 +
2920 + revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
2921 + if (revision != 8 && revision != 9) {
2922 + pr_err("Unsupported SPROM revision: %d\n", revision);
2923 + return -ENOENT;
2924 + }
2925 +
2926 + return 0;
2927 +}
2928 +
2929 +/**************************************************
2930 + * SPROM extraction.
2931 + **************************************************/
2932 +
2933 +#define SPOFF(offset) ((offset) / sizeof(u16))
2934 +
2935 +#define SPEX(_field, _offset, _mask, _shift) \
2936 + bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift))
2937 +
2938 +static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
2939 +{
2940 + u16 v, o;
2941 + int i;
2942 + u16 pwr_info_offset[] = {
2943 + SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
2944 + SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
2945 + };
2946 + BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
2947 + ARRAY_SIZE(bus->sprom.core_pwr_info));
2948 +
2949 + bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
2950 + SSB_SPROM_REVISION_REV;
2951 +
2952 + for (i = 0; i < 3; i++) {
2953 + v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
2954 + *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
2955 + }
2956 +
2957 + SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0);
2958 +
2959 + SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0,
2960 + SSB_SPROM4_TXPID2G0_SHIFT);
2961 + SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G1,
2962 + SSB_SPROM4_TXPID2G1_SHIFT);
2963 + SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G2,
2964 + SSB_SPROM4_TXPID2G2_SHIFT);
2965 + SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G3,
2966 + SSB_SPROM4_TXPID2G3_SHIFT);
2967 +
2968 + SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL0,
2969 + SSB_SPROM4_TXPID5GL0_SHIFT);
2970 + SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL1,
2971 + SSB_SPROM4_TXPID5GL1_SHIFT);
2972 + SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL2,
2973 + SSB_SPROM4_TXPID5GL2_SHIFT);
2974 + SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL3,
2975 + SSB_SPROM4_TXPID5GL3_SHIFT);
2976 +
2977 + SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G0,
2978 + SSB_SPROM4_TXPID5G0_SHIFT);
2979 + SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G1,
2980 + SSB_SPROM4_TXPID5G1_SHIFT);
2981 + SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G2,
2982 + SSB_SPROM4_TXPID5G2_SHIFT);
2983 + SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G3,
2984 + SSB_SPROM4_TXPID5G3_SHIFT);
2985 +
2986 + SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH0,
2987 + SSB_SPROM4_TXPID5GH0_SHIFT);
2988 + SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH1,
2989 + SSB_SPROM4_TXPID5GH1_SHIFT);
2990 + SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH2,
2991 + SSB_SPROM4_TXPID5GH2_SHIFT);
2992 + SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH3,
2993 + SSB_SPROM4_TXPID5GH3_SHIFT);
2994 +
2995 + SPEX(boardflags_lo, SSB_SPROM8_BFLLO, ~0, 0);
2996 + SPEX(boardflags_hi, SSB_SPROM8_BFLHI, ~0, 0);
2997 + SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0);
2998 + SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0);
2999 +
3000 + SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0);
3001 +
3002 + /* Extract cores power info info */
3003 + for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
3004 + o = pwr_info_offset[i];
3005 + SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
3006 + SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
3007 + SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
3008 + SSB_SPROM8_2G_MAXP, 0);
3009 +
3010 + SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
3011 + SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
3012 + SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
3013 +
3014 + SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
3015 + SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
3016 + SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
3017 + SSB_SPROM8_5G_MAXP, 0);
3018 + SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
3019 + SSB_SPROM8_5GH_MAXP, 0);
3020 + SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
3021 + SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
3022 +
3023 + SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
3024 + SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
3025 + SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
3026 + SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
3027 + SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
3028 + SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
3029 + SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
3030 + SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
3031 + SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
3032 + }
3033 +
3034 + SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS,
3035 + SSB_SROM8_FEM_TSSIPOS_SHIFT);
3036 + SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN,
3037 + SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
3038 + SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_PDET_RANGE,
3039 + SSB_SROM8_FEM_PDET_RANGE_SHIFT);
3040 + SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TR_ISO,
3041 + SSB_SROM8_FEM_TR_ISO_SHIFT);
3042 + SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_ANTSWLUT,
3043 + SSB_SROM8_FEM_ANTSWLUT_SHIFT);
3044 +
3045 + SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TSSIPOS,
3046 + SSB_SROM8_FEM_TSSIPOS_SHIFT);
3047 + SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_EXTPA_GAIN,
3048 + SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
3049 + SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_PDET_RANGE,
3050 + SSB_SROM8_FEM_PDET_RANGE_SHIFT);
3051 + SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TR_ISO,
3052 + SSB_SROM8_FEM_TR_ISO_SHIFT);
3053 + SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT,
3054 + SSB_SROM8_FEM_ANTSWLUT_SHIFT);
3055 +}
3056 +
3057 +/*
3058 + * Indicates the presence of external SPROM.
3059 + */
3060 +static bool bcma_sprom_ext_available(struct bcma_bus *bus)
3061 +{
3062 + u32 chip_status;
3063 + u32 srom_control;
3064 + u32 present_mask;
3065 +
3066 + if (bus->drv_cc.core->id.rev >= 31) {
3067 + if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
3068 + return false;
3069 +
3070 + srom_control = bcma_read32(bus->drv_cc.core,
3071 + BCMA_CC_SROM_CONTROL);
3072 + return srom_control & BCMA_CC_SROM_CONTROL_PRESENT;
3073 + }
3074 +
3075 + /* older chipcommon revisions use chip status register */
3076 + chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
3077 + switch (bus->chipinfo.id) {
3078 + case 0x4313:
3079 + present_mask = BCMA_CC_CHIPST_4313_SPROM_PRESENT;
3080 + break;
3081 +
3082 + case 0x4331:
3083 + present_mask = BCMA_CC_CHIPST_4331_SPROM_PRESENT;
3084 + break;
3085 +
3086 + default:
3087 + return true;
3088 + }
3089 +
3090 + return chip_status & present_mask;
3091 +}
3092 +
3093 +/*
3094 + * Indicates that on-chip OTP memory is present and enabled.
3095 + */
3096 +static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
3097 +{
3098 + u32 chip_status;
3099 + u32 otpsize = 0;
3100 + bool present;
3101 +
3102 + chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
3103 + switch (bus->chipinfo.id) {
3104 + case 0x4313:
3105 + present = chip_status & BCMA_CC_CHIPST_4313_OTP_PRESENT;
3106 + break;
3107 +
3108 + case 0x4331:
3109 + present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
3110 + break;
3111 +
3112 + case 43224:
3113 + case 43225:
3114 + /* for these chips OTP is always available */
3115 + present = true;
3116 + break;
3117 +
3118 + default:
3119 + present = false;
3120 + break;
3121 + }
3122 +
3123 + if (present) {
3124 + otpsize = bus->drv_cc.capabilities & BCMA_CC_CAP_OTPS;
3125 + otpsize >>= BCMA_CC_CAP_OTPS_SHIFT;
3126 + }
3127 +
3128 + return otpsize != 0;
3129 +}
3130 +
3131 +/*
3132 + * Verify OTP is filled and determine the byte
3133 + * offset where SPROM data is located.
3134 + *
3135 + * On error, returns 0; byte offset otherwise.
3136 + */
3137 +static int bcma_sprom_onchip_offset(struct bcma_bus *bus)
3138 +{
3139 + struct bcma_device *cc = bus->drv_cc.core;
3140 + u32 offset;
3141 +
3142 + /* verify OTP status */
3143 + if ((bcma_read32(cc, BCMA_CC_OTPS) & BCMA_CC_OTPS_GU_PROG_HW) == 0)
3144 + return 0;
3145 +
3146 + /* obtain bit offset from otplayout register */
3147 + offset = (bcma_read32(cc, BCMA_CC_OTPL) & BCMA_CC_OTPL_GURGN_OFFSET);
3148 + return BCMA_CC_SPROM + (offset >> 3);
3149 +}
3150 +
3151 +int bcma_sprom_get(struct bcma_bus *bus)
3152 +{
3153 + u16 offset = BCMA_CC_SPROM;
3154 + u16 *sprom;
3155 + int err = 0;
3156 +
3157 + if (!bus->drv_cc.core)
3158 + return -EOPNOTSUPP;
3159 +
3160 + if (!bcma_sprom_ext_available(bus)) {
3161 + /*
3162 + * External SPROM takes precedence so check
3163 + * on-chip OTP only when no external SPROM
3164 + * is present.
3165 + */
3166 + if (bcma_sprom_onchip_available(bus)) {
3167 + /* determine offset */
3168 + offset = bcma_sprom_onchip_offset(bus);
3169 + }
3170 + if (!offset) {
3171 + /*
3172 + * Maybe there is no SPROM on the device?
3173 + * Now we ask the arch code if there is some sprom
3174 + * available for this device in some other storage.
3175 + */
3176 + err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
3177 + return err;
3178 + }
3179 + }
3180 +
3181 + sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
3182 + GFP_KERNEL);
3183 + if (!sprom)
3184 + return -ENOMEM;
3185 +
3186 + if (bus->chipinfo.id == 0x4331)
3187 + bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
3188 +
3189 + pr_debug("SPROM offset 0x%x\n", offset);
3190 + bcma_sprom_read(bus, offset, sprom);
3191 +
3192 + if (bus->chipinfo.id == 0x4331)
3193 + bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
3194 +
3195 + err = bcma_sprom_valid(sprom);
3196 + if (err)
3197 + goto out;
3198 +
3199 + bcma_sprom_extract_r8(bus, sprom);
3200 +
3201 +out:
3202 + kfree(sprom);
3203 + return err;
3204 +}
3205 --- a/include/linux/bcma/bcma.h
3206 +++ b/include/linux/bcma/bcma.h
3207 @@ -6,6 +6,8 @@
3208
3209 #include <linux/bcma/bcma_driver_chipcommon.h>
3210 #include <linux/bcma/bcma_driver_pci.h>
3211 +#include <linux/bcma/bcma_driver_mips.h>
3212 +#include <linux/ssb/ssb.h> /* SPROM sharing */
3213
3214 #include "bcma_regs.h"
3215
3216 @@ -13,9 +15,9 @@ struct bcma_device;
3217 struct bcma_bus;
3218
3219 enum bcma_hosttype {
3220 - BCMA_HOSTTYPE_NONE,
3221 BCMA_HOSTTYPE_PCI,
3222 BCMA_HOSTTYPE_SDIO,
3223 + BCMA_HOSTTYPE_SOC,
3224 };
3225
3226 struct bcma_chipinfo {
3227 @@ -24,6 +26,11 @@ struct bcma_chipinfo {
3228 u8 pkg;
3229 };
3230
3231 +enum bcma_clkmode {
3232 + BCMA_CLKMODE_FAST,
3233 + BCMA_CLKMODE_DYNAMIC,
3234 +};
3235 +
3236 struct bcma_host_ops {
3237 u8 (*read8)(struct bcma_device *core, u16 offset);
3238 u16 (*read16)(struct bcma_device *core, u16 offset);
3239 @@ -31,6 +38,12 @@ struct bcma_host_ops {
3240 void (*write8)(struct bcma_device *core, u16 offset, u8 value);
3241 void (*write16)(struct bcma_device *core, u16 offset, u16 value);
3242 void (*write32)(struct bcma_device *core, u16 offset, u32 value);
3243 +#ifdef CONFIG_BCMA_BLOCKIO
3244 + void (*block_read)(struct bcma_device *core, void *buffer,
3245 + size_t count, u16 offset, u8 reg_width);
3246 + void (*block_write)(struct bcma_device *core, const void *buffer,
3247 + size_t count, u16 offset, u8 reg_width);
3248 +#endif
3249 /* Agent ops */
3250 u32 (*aread32)(struct bcma_device *core, u16 offset);
3251 void (*awrite32)(struct bcma_device *core, u16 offset, u32 value);
3252 @@ -117,13 +130,20 @@ struct bcma_device {
3253 struct bcma_device_id id;
3254
3255 struct device dev;
3256 + struct device *dma_dev;
3257 +
3258 + unsigned int irq;
3259 bool dev_registered;
3260
3261 u8 core_index;
3262 + u8 core_unit;
3263
3264 u32 addr;
3265 u32 wrap;
3266
3267 + void __iomem *io_addr;
3268 + void __iomem *io_wrap;
3269 +
3270 void *drvdata;
3271 struct list_head list;
3272 };
3273 @@ -143,7 +163,7 @@ struct bcma_driver {
3274
3275 int (*probe)(struct bcma_device *dev);
3276 void (*remove)(struct bcma_device *dev);
3277 - int (*suspend)(struct bcma_device *dev, pm_message_t state);
3278 + int (*suspend)(struct bcma_device *dev);
3279 int (*resume)(struct bcma_device *dev);
3280 void (*shutdown)(struct bcma_device *dev);
3281
3282 @@ -151,12 +171,17 @@ struct bcma_driver {
3283 };
3284 extern
3285 int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
3286 -static inline int bcma_driver_register(struct bcma_driver *drv)
3287 -{
3288 - return __bcma_driver_register(drv, THIS_MODULE);
3289 -}
3290 +#define bcma_driver_register(drv) \
3291 + __bcma_driver_register(drv, THIS_MODULE)
3292 +
3293 extern void bcma_driver_unregister(struct bcma_driver *drv);
3294
3295 +/* Set a fallback SPROM.
3296 + * See kdoc at the function definition for complete documentation. */
3297 +extern int bcma_arch_register_fallback_sprom(
3298 + int (*sprom_callback)(struct bcma_bus *bus,
3299 + struct ssb_sprom *out));
3300 +
3301 struct bcma_bus {
3302 /* The MMIO area. */
3303 void __iomem *mmio;
3304 @@ -176,49 +201,107 @@ struct bcma_bus {
3305 struct bcma_device *mapped_core;
3306 struct list_head cores;
3307 u8 nr_cores;
3308 + u8 init_done:1;
3309 + u8 num;
3310
3311 struct bcma_drv_cc drv_cc;
3312 struct bcma_drv_pci drv_pci;
3313 + struct bcma_drv_mips drv_mips;
3314 +
3315 + /* We decided to share SPROM struct with SSB as long as we do not need
3316 + * any hacks for BCMA. This simplifies drivers code. */
3317 + struct ssb_sprom sprom;
3318 };
3319
3320 -extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
3321 +static inline u32 bcma_read8(struct bcma_device *core, u16 offset)
3322 {
3323 return core->bus->ops->read8(core, offset);
3324 }
3325 -extern inline u32 bcma_read16(struct bcma_device *core, u16 offset)
3326 +static inline u32 bcma_read16(struct bcma_device *core, u16 offset)
3327 {
3328 return core->bus->ops->read16(core, offset);
3329 }
3330 -extern inline u32 bcma_read32(struct bcma_device *core, u16 offset)
3331 +static inline u32 bcma_read32(struct bcma_device *core, u16 offset)
3332 {
3333 return core->bus->ops->read32(core, offset);
3334 }
3335 -extern inline
3336 +static inline
3337 void bcma_write8(struct bcma_device *core, u16 offset, u32 value)
3338 {
3339 core->bus->ops->write8(core, offset, value);
3340 }
3341 -extern inline
3342 +static inline
3343 void bcma_write16(struct bcma_device *core, u16 offset, u32 value)
3344 {
3345 core->bus->ops->write16(core, offset, value);
3346 }
3347 -extern inline
3348 +static inline
3349 void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
3350 {
3351 core->bus->ops->write32(core, offset, value);
3352 }
3353 -extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
3354 +#ifdef CONFIG_BCMA_BLOCKIO
3355 +static inline void bcma_block_read(struct bcma_device *core, void *buffer,
3356 + size_t count, u16 offset, u8 reg_width)
3357 +{
3358 + core->bus->ops->block_read(core, buffer, count, offset, reg_width);
3359 +}
3360 +static inline void bcma_block_write(struct bcma_device *core,
3361 + const void *buffer, size_t count,
3362 + u16 offset, u8 reg_width)
3363 +{
3364 + core->bus->ops->block_write(core, buffer, count, offset, reg_width);
3365 +}
3366 +#endif
3367 +static inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
3368 {
3369 return core->bus->ops->aread32(core, offset);
3370 }
3371 -extern inline
3372 +static inline
3373 void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
3374 {
3375 core->bus->ops->awrite32(core, offset, value);
3376 }
3377
3378 +static inline void bcma_mask32(struct bcma_device *cc, u16 offset, u32 mask)
3379 +{
3380 + bcma_write32(cc, offset, bcma_read32(cc, offset) & mask);
3381 +}
3382 +static inline void bcma_set32(struct bcma_device *cc, u16 offset, u32 set)
3383 +{
3384 + bcma_write32(cc, offset, bcma_read32(cc, offset) | set);
3385 +}
3386 +static inline void bcma_maskset32(struct bcma_device *cc,
3387 + u16 offset, u32 mask, u32 set)
3388 +{
3389 + bcma_write32(cc, offset, (bcma_read32(cc, offset) & mask) | set);
3390 +}
3391 +static inline void bcma_mask16(struct bcma_device *cc, u16 offset, u16 mask)
3392 +{
3393 + bcma_write16(cc, offset, bcma_read16(cc, offset) & mask);
3394 +}
3395 +static inline void bcma_set16(struct bcma_device *cc, u16 offset, u16 set)
3396 +{
3397 + bcma_write16(cc, offset, bcma_read16(cc, offset) | set);
3398 +}
3399 +static inline void bcma_maskset16(struct bcma_device *cc,
3400 + u16 offset, u16 mask, u16 set)
3401 +{
3402 + bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
3403 +}
3404 +
3405 +extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid);
3406 extern bool bcma_core_is_enabled(struct bcma_device *core);
3407 +extern void bcma_core_disable(struct bcma_device *core, u32 flags);
3408 extern int bcma_core_enable(struct bcma_device *core, u32 flags);
3409 +extern void bcma_core_set_clockmode(struct bcma_device *core,
3410 + enum bcma_clkmode clkmode);
3411 +extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status,
3412 + bool on);
3413 +#define BCMA_DMA_TRANSLATION_MASK 0xC0000000
3414 +#define BCMA_DMA_TRANSLATION_NONE 0x00000000
3415 +#define BCMA_DMA_TRANSLATION_DMA32_CMT 0x40000000 /* Client Mode Translation for 32-bit DMA */
3416 +#define BCMA_DMA_TRANSLATION_DMA64_CMT 0x80000000 /* Client Mode Translation for 64-bit DMA */
3417 +extern u32 bcma_core_dma_translation(struct bcma_device *core);
3418
3419 #endif /* LINUX_BCMA_H_ */
3420 --- a/include/linux/bcma/bcma_driver_chipcommon.h
3421 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
3422 @@ -24,6 +24,7 @@
3423 #define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */
3424 #define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */
3425 #define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */
3426 +#define BCMA_CC_FLASHT_NFLASH 0x00000200
3427 #define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */
3428 #define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */
3429 #define BCMA_PLLTYPE_NONE 0x00000000
3430 @@ -55,6 +56,9 @@
3431 #define BCMA_CC_OTPS_HW_PROTECT 0x00000001
3432 #define BCMA_CC_OTPS_SW_PROTECT 0x00000002
3433 #define BCMA_CC_OTPS_CID_PROTECT 0x00000004
3434 +#define BCMA_CC_OTPS_GU_PROG_IND 0x00000F00 /* General Use programmed indication */
3435 +#define BCMA_CC_OTPS_GU_PROG_IND_SHIFT 8
3436 +#define BCMA_CC_OTPS_GU_PROG_HW 0x00000100 /* HW region programmed */
3437 #define BCMA_CC_OTPC 0x0014 /* OTP control */
3438 #define BCMA_CC_OTPC_RECWAIT 0xFF000000
3439 #define BCMA_CC_OTPC_PROGWAIT 0x00FFFF00
3440 @@ -71,6 +75,8 @@
3441 #define BCMA_CC_OTPP_READ 0x40000000
3442 #define BCMA_CC_OTPP_START 0x80000000
3443 #define BCMA_CC_OTPP_BUSY 0x80000000
3444 +#define BCMA_CC_OTPL 0x001C /* OTP layout */
3445 +#define BCMA_CC_OTPL_GURGN_OFFSET 0x00000FFF /* offset of general use region */
3446 #define BCMA_CC_IRQSTAT 0x0020
3447 #define BCMA_CC_IRQMASK 0x0024
3448 #define BCMA_CC_IRQ_GPIO 0x00000001 /* gpio intr */
3449 @@ -78,6 +84,10 @@
3450 #define BCMA_CC_IRQ_WDRESET 0x80000000 /* watchdog reset occurred */
3451 #define BCMA_CC_CHIPCTL 0x0028 /* Rev >= 11 only */
3452 #define BCMA_CC_CHIPSTAT 0x002C /* Rev >= 11 only */
3453 +#define BCMA_CC_CHIPST_4313_SPROM_PRESENT 1
3454 +#define BCMA_CC_CHIPST_4313_OTP_PRESENT 2
3455 +#define BCMA_CC_CHIPST_4331_SPROM_PRESENT 2
3456 +#define BCMA_CC_CHIPST_4331_OTP_PRESENT 4
3457 #define BCMA_CC_JCMD 0x0030 /* Rev >= 10 only */
3458 #define BCMA_CC_JCMD_START 0x80000000
3459 #define BCMA_CC_JCMD_BUSY 0x80000000
3460 @@ -178,16 +188,25 @@
3461 #define BCMA_CC_PROG_CFG 0x0120
3462 #define BCMA_CC_PROG_WAITCNT 0x0124
3463 #define BCMA_CC_FLASH_CFG 0x0128
3464 +#define BCMA_CC_FLASH_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */
3465 #define BCMA_CC_FLASH_WAITCNT 0x012C
3466 -#define BCMA_CC_CLKCTLST 0x01E0 /* Clock control and status (rev >= 20) */
3467 -#define BCMA_CC_CLKCTLST_FORCEALP 0x00000001 /* Force ALP request */
3468 -#define BCMA_CC_CLKCTLST_FORCEHT 0x00000002 /* Force HT request */
3469 -#define BCMA_CC_CLKCTLST_FORCEILP 0x00000004 /* Force ILP request */
3470 -#define BCMA_CC_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */
3471 -#define BCMA_CC_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
3472 -#define BCMA_CC_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
3473 -#define BCMA_CC_CLKCTLST_HAVEHT 0x00010000 /* HT available */
3474 -#define BCMA_CC_CLKCTLST_HAVEALP 0x00020000 /* APL available */
3475 +#define BCMA_CC_SROM_CONTROL 0x0190
3476 +#define BCMA_CC_SROM_CONTROL_START 0x80000000
3477 +#define BCMA_CC_SROM_CONTROL_BUSY 0x80000000
3478 +#define BCMA_CC_SROM_CONTROL_OPCODE 0x60000000
3479 +#define BCMA_CC_SROM_CONTROL_OP_READ 0x00000000
3480 +#define BCMA_CC_SROM_CONTROL_OP_WRITE 0x20000000
3481 +#define BCMA_CC_SROM_CONTROL_OP_WRDIS 0x40000000
3482 +#define BCMA_CC_SROM_CONTROL_OP_WREN 0x60000000
3483 +#define BCMA_CC_SROM_CONTROL_OTPSEL 0x00000010
3484 +#define BCMA_CC_SROM_CONTROL_LOCK 0x00000008
3485 +#define BCMA_CC_SROM_CONTROL_SIZE_MASK 0x00000006
3486 +#define BCMA_CC_SROM_CONTROL_SIZE_1K 0x00000000
3487 +#define BCMA_CC_SROM_CONTROL_SIZE_4K 0x00000002
3488 +#define BCMA_CC_SROM_CONTROL_SIZE_16K 0x00000004
3489 +#define BCMA_CC_SROM_CONTROL_SIZE_SHIFT 1
3490 +#define BCMA_CC_SROM_CONTROL_PRESENT 0x00000001
3491 +/* 0x1E0 is defined as shared BCMA_CLKCTLST */
3492 #define BCMA_CC_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */
3493 #define BCMA_CC_UART0_DATA 0x0300
3494 #define BCMA_CC_UART0_IMR 0x0304
3495 @@ -209,6 +228,7 @@
3496 #define BCMA_CC_PMU_CTL 0x0600 /* PMU control */
3497 #define BCMA_CC_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */
3498 #define BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16
3499 +#define BCMA_CC_PMU_CTL_PLL_UPD 0x00000400
3500 #define BCMA_CC_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */
3501 #define BCMA_CC_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */
3502 #define BCMA_CC_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */
3503 @@ -244,6 +264,65 @@
3504 #define BCMA_CC_REGCTL_DATA 0x065C
3505 #define BCMA_CC_PLLCTL_ADDR 0x0660
3506 #define BCMA_CC_PLLCTL_DATA 0x0664
3507 +#define BCMA_CC_SPROM 0x0800 /* SPROM beginning */
3508 +
3509 +/* Divider allocation in 4716/47162/5356 */
3510 +#define BCMA_CC_PMU5_MAINPLL_CPU 1
3511 +#define BCMA_CC_PMU5_MAINPLL_MEM 2
3512 +#define BCMA_CC_PMU5_MAINPLL_SSB 3
3513 +
3514 +/* PLL usage in 4716/47162 */
3515 +#define BCMA_CC_PMU4716_MAINPLL_PLL0 12
3516 +
3517 +/* PLL usage in 5356/5357 */
3518 +#define BCMA_CC_PMU5356_MAINPLL_PLL0 0
3519 +#define BCMA_CC_PMU5357_MAINPLL_PLL0 0
3520 +
3521 +/* 4706 PMU */
3522 +#define BCMA_CC_PMU4706_MAINPLL_PLL0 0
3523 +
3524 +/* ALP clock on pre-PMU chips */
3525 +#define BCMA_CC_PMU_ALP_CLOCK 20000000
3526 +/* HT clock for systems with PMU-enabled chipcommon */
3527 +#define BCMA_CC_PMU_HT_CLOCK 80000000
3528 +
3529 +/* PMU rev 5 (& 6) */
3530 +#define BCMA_CC_PPL_P1P2_OFF 0
3531 +#define BCMA_CC_PPL_P1_MASK 0x0f000000
3532 +#define BCMA_CC_PPL_P1_SHIFT 24
3533 +#define BCMA_CC_PPL_P2_MASK 0x00f00000
3534 +#define BCMA_CC_PPL_P2_SHIFT 20
3535 +#define BCMA_CC_PPL_M14_OFF 1
3536 +#define BCMA_CC_PPL_MDIV_MASK 0x000000ff
3537 +#define BCMA_CC_PPL_MDIV_WIDTH 8
3538 +#define BCMA_CC_PPL_NM5_OFF 2
3539 +#define BCMA_CC_PPL_NDIV_MASK 0xfff00000
3540 +#define BCMA_CC_PPL_NDIV_SHIFT 20
3541 +#define BCMA_CC_PPL_FMAB_OFF 3
3542 +#define BCMA_CC_PPL_MRAT_MASK 0xf0000000
3543 +#define BCMA_CC_PPL_MRAT_SHIFT 28
3544 +#define BCMA_CC_PPL_ABRAT_MASK 0x08000000
3545 +#define BCMA_CC_PPL_ABRAT_SHIFT 27
3546 +#define BCMA_CC_PPL_FDIV_MASK 0x07ffffff
3547 +#define BCMA_CC_PPL_PLLCTL_OFF 4
3548 +#define BCMA_CC_PPL_PCHI_OFF 5
3549 +#define BCMA_CC_PPL_PCHI_MASK 0x0000003f
3550 +
3551 +/* BCM4331 ChipControl numbers. */
3552 +#define BCMA_CHIPCTL_4331_BT_COEXIST BIT(0) /* 0 disable */
3553 +#define BCMA_CHIPCTL_4331_SECI BIT(1) /* 0 SECI is disabled (JATG functional) */
3554 +#define BCMA_CHIPCTL_4331_EXT_LNA BIT(2) /* 0 disable */
3555 +#define BCMA_CHIPCTL_4331_SPROM_GPIO13_15 BIT(3) /* sprom/gpio13-15 mux */
3556 +#define BCMA_CHIPCTL_4331_EXTPA_EN BIT(4) /* 0 ext pa disable, 1 ext pa enabled */
3557 +#define BCMA_CHIPCTL_4331_GPIOCLK_ON_SPROMCS BIT(5) /* set drive out GPIO_CLK on sprom_cs pin */
3558 +#define BCMA_CHIPCTL_4331_PCIE_MDIO_ON_SPROMCS BIT(6) /* use sprom_cs pin as PCIE mdio interface */
3559 +#define BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5 BIT(7) /* aband extpa will be at gpio2/5 and sprom_dout */
3560 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXCLKEN BIT(8) /* override core control on pipe_AuxClkEnable */
3561 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN BIT(9) /* override core control on pipe_AuxPowerDown */
3562 +#define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN BIT(10) /* pcie_auxclkenable */
3563 +#define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN BIT(11) /* pcie_pipe_pllpowerdown */
3564 +#define BCMA_CHIPCTL_4331_BT_SHD0_ON_GPIO4 BIT(16) /* enable bt_shd0 at gpio4 */
3565 +#define BCMA_CHIPCTL_4331_BT_SHD1_ON_GPIO5 BIT(17) /* enable bt_shd1 at gpio5 */
3566
3567 /* Data for the PMU, if available.
3568 * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
3569 @@ -253,14 +332,37 @@ struct bcma_chipcommon_pmu {
3570 u32 crystalfreq; /* The active crystal frequency (in kHz) */
3571 };
3572
3573 +#ifdef CONFIG_BCMA_DRIVER_MIPS
3574 +struct bcma_pflash {
3575 + u8 buswidth;
3576 + u32 window;
3577 + u32 window_size;
3578 +};
3579 +
3580 +struct bcma_serial_port {
3581 + void *regs;
3582 + unsigned long clockspeed;
3583 + unsigned int irq;
3584 + unsigned int baud_base;
3585 + unsigned int reg_shift;
3586 +};
3587 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
3588 +
3589 struct bcma_drv_cc {
3590 struct bcma_device *core;
3591 u32 status;
3592 u32 capabilities;
3593 u32 capabilities_ext;
3594 + u8 setup_done:1;
3595 /* Fast Powerup Delay constant */
3596 u16 fast_pwrup_delay;
3597 struct bcma_chipcommon_pmu pmu;
3598 +#ifdef CONFIG_BCMA_DRIVER_MIPS
3599 + struct bcma_pflash pflash;
3600 +
3601 + int nr_serial_ports;
3602 + struct bcma_serial_port serial_ports[4];
3603 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
3604 };
3605
3606 /* Register access */
3607 @@ -281,6 +383,8 @@ extern void bcma_core_chipcommon_init(st
3608 extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
3609 extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
3610
3611 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
3612 +
3613 extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
3614 u32 ticks);
3615
3616 @@ -299,4 +403,13 @@ u32 bcma_chipco_gpio_polarity(struct bcm
3617 /* PMU support */
3618 extern void bcma_pmu_init(struct bcma_drv_cc *cc);
3619
3620 +extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset,
3621 + u32 value);
3622 +extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset,
3623 + u32 mask, u32 set);
3624 +extern void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
3625 + u32 offset, u32 mask, u32 set);
3626 +extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc,
3627 + u32 offset, u32 mask, u32 set);
3628 +
3629 #endif /* LINUX_BCMA_DRIVER_CC_H_ */
3630 --- /dev/null
3631 +++ b/include/linux/bcma/bcma_driver_mips.h
3632 @@ -0,0 +1,51 @@
3633 +#ifndef LINUX_BCMA_DRIVER_MIPS_H_
3634 +#define LINUX_BCMA_DRIVER_MIPS_H_
3635 +
3636 +#define BCMA_MIPS_IPSFLAG 0x0F08
3637 +/* which sbflags get routed to mips interrupt 1 */
3638 +#define BCMA_MIPS_IPSFLAG_IRQ1 0x0000003F
3639 +#define BCMA_MIPS_IPSFLAG_IRQ1_SHIFT 0
3640 +/* which sbflags get routed to mips interrupt 2 */
3641 +#define BCMA_MIPS_IPSFLAG_IRQ2 0x00003F00
3642 +#define BCMA_MIPS_IPSFLAG_IRQ2_SHIFT 8
3643 +/* which sbflags get routed to mips interrupt 3 */
3644 +#define BCMA_MIPS_IPSFLAG_IRQ3 0x003F0000
3645 +#define BCMA_MIPS_IPSFLAG_IRQ3_SHIFT 16
3646 +/* which sbflags get routed to mips interrupt 4 */
3647 +#define BCMA_MIPS_IPSFLAG_IRQ4 0x3F000000
3648 +#define BCMA_MIPS_IPSFLAG_IRQ4_SHIFT 24
3649 +
3650 +/* MIPS 74K core registers */
3651 +#define BCMA_MIPS_MIPS74K_CORECTL 0x0000
3652 +#define BCMA_MIPS_MIPS74K_EXCEPTBASE 0x0004
3653 +#define BCMA_MIPS_MIPS74K_BIST 0x000C
3654 +#define BCMA_MIPS_MIPS74K_INTMASK_INT0 0x0014
3655 +#define BCMA_MIPS_MIPS74K_INTMASK(int) \
3656 + ((int) * 4 + BCMA_MIPS_MIPS74K_INTMASK_INT0)
3657 +#define BCMA_MIPS_MIPS74K_NMIMASK 0x002C
3658 +#define BCMA_MIPS_MIPS74K_GPIOSEL 0x0040
3659 +#define BCMA_MIPS_MIPS74K_GPIOOUT 0x0044
3660 +#define BCMA_MIPS_MIPS74K_GPIOEN 0x0048
3661 +#define BCMA_MIPS_MIPS74K_CLKCTLST 0x01E0
3662 +
3663 +#define BCMA_MIPS_OOBSELOUTA30 0x100
3664 +
3665 +struct bcma_device;
3666 +
3667 +struct bcma_drv_mips {
3668 + struct bcma_device *core;
3669 + u8 setup_done:1;
3670 + unsigned int assigned_irqs;
3671 +};
3672 +
3673 +#ifdef CONFIG_BCMA_DRIVER_MIPS
3674 +extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
3675 +#else
3676 +static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { }
3677 +#endif
3678 +
3679 +extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
3680 +
3681 +extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
3682 +
3683 +#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
3684 --- a/include/linux/bcma/bcma_driver_pci.h
3685 +++ b/include/linux/bcma/bcma_driver_pci.h
3686 @@ -53,6 +53,35 @@ struct pci_dev;
3687 #define BCMA_CORE_PCI_SBTOPCI1_MASK 0xFC000000
3688 #define BCMA_CORE_PCI_SBTOPCI2 0x0108 /* Backplane to PCI translation 2 (sbtopci2) */
3689 #define BCMA_CORE_PCI_SBTOPCI2_MASK 0xC0000000
3690 +#define BCMA_CORE_PCI_CONFIG_ADDR 0x0120 /* pcie config space access */
3691 +#define BCMA_CORE_PCI_CONFIG_DATA 0x0124 /* pcie config space access */
3692 +#define BCMA_CORE_PCI_MDIO_CONTROL 0x0128 /* controls the mdio access */
3693 +#define BCMA_CORE_PCI_MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */
3694 +#define BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL 0x2
3695 +#define BCMA_CORE_PCI_MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */
3696 +#define BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE 0x100 /* Tranaction complete */
3697 +#define BCMA_CORE_PCI_MDIO_DATA 0x012c /* Data to the mdio access */
3698 +#define BCMA_CORE_PCI_MDIODATA_MASK 0x0000ffff /* data 2 bytes */
3699 +#define BCMA_CORE_PCI_MDIODATA_TA 0x00020000 /* Turnaround */
3700 +#define BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD 18 /* Regaddr shift (rev < 10) */
3701 +#define BCMA_CORE_PCI_MDIODATA_REGADDR_MASK_OLD 0x003c0000 /* Regaddr Mask (rev < 10) */
3702 +#define BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD 22 /* Physmedia devaddr shift (rev < 10) */
3703 +#define BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK_OLD 0x0fc00000 /* Physmedia devaddr Mask (rev < 10) */
3704 +#define BCMA_CORE_PCI_MDIODATA_REGADDR_SHF 18 /* Regaddr shift */
3705 +#define BCMA_CORE_PCI_MDIODATA_REGADDR_MASK 0x007c0000 /* Regaddr Mask */
3706 +#define BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF 23 /* Physmedia devaddr shift */
3707 +#define BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK 0x0f800000 /* Physmedia devaddr Mask */
3708 +#define BCMA_CORE_PCI_MDIODATA_WRITE 0x10000000 /* write Transaction */
3709 +#define BCMA_CORE_PCI_MDIODATA_READ 0x20000000 /* Read Transaction */
3710 +#define BCMA_CORE_PCI_MDIODATA_START 0x40000000 /* start of Transaction */
3711 +#define BCMA_CORE_PCI_MDIODATA_DEV_ADDR 0x0 /* dev address for serdes */
3712 +#define BCMA_CORE_PCI_MDIODATA_BLK_ADDR 0x1F /* blk address for serdes */
3713 +#define BCMA_CORE_PCI_MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */
3714 +#define BCMA_CORE_PCI_MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */
3715 +#define BCMA_CORE_PCI_MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */
3716 +#define BCMA_CORE_PCI_PCIEIND_ADDR 0x0130 /* indirect access to the internal register */
3717 +#define BCMA_CORE_PCI_PCIEIND_DATA 0x0134 /* Data to/from the internal regsiter */
3718 +#define BCMA_CORE_PCI_CLKREQENCTRL 0x0138 /* >= rev 6, Clkreq rdma control */
3719 #define BCMA_CORE_PCI_PCICFG0 0x0400 /* PCI config space 0 (rev >= 8) */
3720 #define BCMA_CORE_PCI_PCICFG1 0x0500 /* PCI config space 1 (rev >= 8) */
3721 #define BCMA_CORE_PCI_PCICFG2 0x0600 /* PCI config space 2 (rev >= 8) */
3722 @@ -72,18 +101,114 @@ struct pci_dev;
3723 #define BCMA_CORE_PCI_SBTOPCI_RC_READL 0x00000010 /* Memory read line */
3724 #define BCMA_CORE_PCI_SBTOPCI_RC_READM 0x00000020 /* Memory read multiple */
3725
3726 +/* PCIE protocol PHY diagnostic registers */
3727 +#define BCMA_CORE_PCI_PLP_MODEREG 0x200 /* Mode */
3728 +#define BCMA_CORE_PCI_PLP_STATUSREG 0x204 /* Status */
3729 +#define BCMA_CORE_PCI_PLP_POLARITYINV_STAT 0x10 /* Status reg PCIE_PLP_STATUSREG */
3730 +#define BCMA_CORE_PCI_PLP_LTSSMCTRLREG 0x208 /* LTSSM control */
3731 +#define BCMA_CORE_PCI_PLP_LTLINKNUMREG 0x20c /* Link Training Link number */
3732 +#define BCMA_CORE_PCI_PLP_LTLANENUMREG 0x210 /* Link Training Lane number */
3733 +#define BCMA_CORE_PCI_PLP_LTNFTSREG 0x214 /* Link Training N_FTS */
3734 +#define BCMA_CORE_PCI_PLP_ATTNREG 0x218 /* Attention */
3735 +#define BCMA_CORE_PCI_PLP_ATTNMASKREG 0x21C /* Attention Mask */
3736 +#define BCMA_CORE_PCI_PLP_RXERRCTR 0x220 /* Rx Error */
3737 +#define BCMA_CORE_PCI_PLP_RXFRMERRCTR 0x224 /* Rx Framing Error */
3738 +#define BCMA_CORE_PCI_PLP_RXERRTHRESHREG 0x228 /* Rx Error threshold */
3739 +#define BCMA_CORE_PCI_PLP_TESTCTRLREG 0x22C /* Test Control reg */
3740 +#define BCMA_CORE_PCI_PLP_SERDESCTRLOVRDREG 0x230 /* SERDES Control Override */
3741 +#define BCMA_CORE_PCI_PLP_TIMINGOVRDREG 0x234 /* Timing param override */
3742 +#define BCMA_CORE_PCI_PLP_RXTXSMDIAGREG 0x238 /* RXTX State Machine Diag */
3743 +#define BCMA_CORE_PCI_PLP_LTSSMDIAGREG 0x23C /* LTSSM State Machine Diag */
3744 +
3745 +/* PCIE protocol DLLP diagnostic registers */
3746 +#define BCMA_CORE_PCI_DLLP_LCREG 0x100 /* Link Control */
3747 +#define BCMA_CORE_PCI_DLLP_LSREG 0x104 /* Link Status */
3748 +#define BCMA_CORE_PCI_DLLP_LAREG 0x108 /* Link Attention */
3749 +#define BCMA_CORE_PCI_DLLP_LSREG_LINKUP (1 << 16)
3750 +#define BCMA_CORE_PCI_DLLP_LAMASKREG 0x10C /* Link Attention Mask */
3751 +#define BCMA_CORE_PCI_DLLP_NEXTTXSEQNUMREG 0x110 /* Next Tx Seq Num */
3752 +#define BCMA_CORE_PCI_DLLP_ACKEDTXSEQNUMREG 0x114 /* Acked Tx Seq Num */
3753 +#define BCMA_CORE_PCI_DLLP_PURGEDTXSEQNUMREG 0x118 /* Purged Tx Seq Num */
3754 +#define BCMA_CORE_PCI_DLLP_RXSEQNUMREG 0x11C /* Rx Sequence Number */
3755 +#define BCMA_CORE_PCI_DLLP_LRREG 0x120 /* Link Replay */
3756 +#define BCMA_CORE_PCI_DLLP_LACKTOREG 0x124 /* Link Ack Timeout */
3757 +#define BCMA_CORE_PCI_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */
3758 +#define BCMA_CORE_PCI_DLLP_RTRYWPREG 0x12C /* Retry buffer write ptr */
3759 +#define BCMA_CORE_PCI_DLLP_RTRYRPREG 0x130 /* Retry buffer Read ptr */
3760 +#define BCMA_CORE_PCI_DLLP_RTRYPPREG 0x134 /* Retry buffer Purged ptr */
3761 +#define BCMA_CORE_PCI_DLLP_RTRRWREG 0x138 /* Retry buffer Read/Write */
3762 +#define BCMA_CORE_PCI_DLLP_ECTHRESHREG 0x13C /* Error Count Threshold */
3763 +#define BCMA_CORE_PCI_DLLP_TLPERRCTRREG 0x140 /* TLP Error Counter */
3764 +#define BCMA_CORE_PCI_DLLP_ERRCTRREG 0x144 /* Error Counter */
3765 +#define BCMA_CORE_PCI_DLLP_NAKRXCTRREG 0x148 /* NAK Received Counter */
3766 +#define BCMA_CORE_PCI_DLLP_TESTREG 0x14C /* Test */
3767 +#define BCMA_CORE_PCI_DLLP_PKTBIST 0x150 /* Packet BIST */
3768 +#define BCMA_CORE_PCI_DLLP_PCIE11 0x154 /* DLLP PCIE 1.1 reg */
3769 +
3770 +/* SERDES RX registers */
3771 +#define BCMA_CORE_PCI_SERDES_RX_CTRL 1 /* Rx cntrl */
3772 +#define BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE 0x80 /* rxpolarity_force */
3773 +#define BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY 0x40 /* rxpolarity_value */
3774 +#define BCMA_CORE_PCI_SERDES_RX_TIMER1 2 /* Rx Timer1 */
3775 +#define BCMA_CORE_PCI_SERDES_RX_CDR 6 /* CDR */
3776 +#define BCMA_CORE_PCI_SERDES_RX_CDRBW 7 /* CDR BW */
3777 +
3778 +/* SERDES PLL registers */
3779 +#define BCMA_CORE_PCI_SERDES_PLL_CTRL 1 /* PLL control reg */
3780 +#define BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN 0x4000 /* bit 14 is FREQDET on */
3781 +
3782 /* PCIcore specific boardflags */
3783 #define BCMA_CORE_PCI_BFL_NOPCI 0x00000400 /* Board leaves PCI floating */
3784
3785 +/* PCIE Config space accessing MACROS */
3786 +#define BCMA_CORE_PCI_CFG_BUS_SHIFT 24 /* Bus shift */
3787 +#define BCMA_CORE_PCI_CFG_SLOT_SHIFT 19 /* Slot/Device shift */
3788 +#define BCMA_CORE_PCI_CFG_FUN_SHIFT 16 /* Function shift */
3789 +#define BCMA_CORE_PCI_CFG_OFF_SHIFT 0 /* Register shift */
3790 +
3791 +#define BCMA_CORE_PCI_CFG_BUS_MASK 0xff /* Bus mask */
3792 +#define BCMA_CORE_PCI_CFG_SLOT_MASK 0x1f /* Slot/Device mask */
3793 +#define BCMA_CORE_PCI_CFG_FUN_MASK 7 /* Function mask */
3794 +#define BCMA_CORE_PCI_CFG_OFF_MASK 0xfff /* Register mask */
3795 +
3796 +/* PCIE Root Capability Register bits (Host mode only) */
3797 +#define BCMA_CORE_PCI_RC_CRS_VISIBILITY 0x0001
3798 +
3799 +struct bcma_drv_pci;
3800 +
3801 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
3802 +struct bcma_drv_pci_host {
3803 + struct bcma_drv_pci *pdev;
3804 +
3805 + u32 host_cfg_addr;
3806 + spinlock_t cfgspace_lock;
3807 +
3808 + struct pci_controller pci_controller;
3809 + struct pci_ops pci_ops;
3810 + struct resource mem_resource;
3811 + struct resource io_resource;
3812 +};
3813 +#endif
3814 +
3815 struct bcma_drv_pci {
3816 struct bcma_device *core;
3817 u8 setup_done:1;
3818 + u8 hostmode:1;
3819 +
3820 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
3821 + struct bcma_drv_pci_host *host_controller;
3822 +#endif
3823 };
3824
3825 /* Register access */
3826 #define pcicore_read32(pc, offset) bcma_read32((pc)->core, offset)
3827 #define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val)
3828
3829 -extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
3830 +extern void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc);
3831 +extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
3832 + struct bcma_device *core, bool enable);
3833 +
3834 +extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
3835 +extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
3836
3837 #endif /* LINUX_BCMA_DRIVER_PCI_H_ */
3838 --- a/include/linux/bcma/bcma_regs.h
3839 +++ b/include/linux/bcma/bcma_regs.h
3840 @@ -1,13 +1,38 @@
3841 #ifndef LINUX_BCMA_REGS_H_
3842 #define LINUX_BCMA_REGS_H_
3843
3844 +/* Some single registers are shared between many cores */
3845 +/* BCMA_CLKCTLST: ChipCommon (rev >= 20), PCIe, 80211 */
3846 +#define BCMA_CLKCTLST 0x01E0 /* Clock control and status */
3847 +#define BCMA_CLKCTLST_FORCEALP 0x00000001 /* Force ALP request */
3848 +#define BCMA_CLKCTLST_FORCEHT 0x00000002 /* Force HT request */
3849 +#define BCMA_CLKCTLST_FORCEILP 0x00000004 /* Force ILP request */
3850 +#define BCMA_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */
3851 +#define BCMA_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
3852 +#define BCMA_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
3853 +#define BCMA_CLKCTLST_EXTRESREQ 0x00000700 /* Mask of external resource requests */
3854 +#define BCMA_CLKCTLST_HAVEALP 0x00010000 /* ALP available */
3855 +#define BCMA_CLKCTLST_HAVEHT 0x00020000 /* HT available */
3856 +#define BCMA_CLKCTLST_BP_ON_ALP 0x00040000 /* RO: running on ALP clock */
3857 +#define BCMA_CLKCTLST_BP_ON_HT 0x00080000 /* RO: running on HT clock */
3858 +#define BCMA_CLKCTLST_EXTRESST 0x07000000 /* Mask of external resource status */
3859 +/* Is there any BCM4328 on BCMA bus? */
3860 +#define BCMA_CLKCTLST_4328A0_HAVEHT 0x00010000 /* 4328a0 has reversed bits */
3861 +#define BCMA_CLKCTLST_4328A0_HAVEALP 0x00020000 /* 4328a0 has reversed bits */
3862 +
3863 /* Agent registers (common for every core) */
3864 -#define BCMA_IOCTL 0x0408
3865 +#define BCMA_IOCTL 0x0408 /* IO control */
3866 #define BCMA_IOCTL_CLK 0x0001
3867 #define BCMA_IOCTL_FGC 0x0002
3868 #define BCMA_IOCTL_CORE_BITS 0x3FFC
3869 #define BCMA_IOCTL_PME_EN 0x4000
3870 #define BCMA_IOCTL_BIST_EN 0x8000
3871 +#define BCMA_IOST 0x0500 /* IO status */
3872 +#define BCMA_IOST_CORE_BITS 0x0FFF
3873 +#define BCMA_IOST_DMA64 0x1000
3874 +#define BCMA_IOST_GATED_CLK 0x2000
3875 +#define BCMA_IOST_BIST_ERROR 0x4000
3876 +#define BCMA_IOST_BIST_DONE 0x8000
3877 #define BCMA_RESET_CTL 0x0800
3878 #define BCMA_RESET_CTL_RESET 0x0001
3879
3880 @@ -31,4 +56,31 @@
3881 #define BCMA_PCI_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */
3882 #define BCMA_PCI_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */
3883
3884 +/* SiliconBackplane Address Map.
3885 + * All regions may not exist on all chips.
3886 + */
3887 +#define BCMA_SOC_SDRAM_BASE 0x00000000U /* Physical SDRAM */
3888 +#define BCMA_SOC_PCI_MEM 0x08000000U /* Host Mode sb2pcitranslation0 (64 MB) */
3889 +#define BCMA_SOC_PCI_MEM_SZ (64 * 1024 * 1024)
3890 +#define BCMA_SOC_PCI_CFG 0x0c000000U /* Host Mode sb2pcitranslation1 (64 MB) */
3891 +#define BCMA_SOC_SDRAM_SWAPPED 0x10000000U /* Byteswapped Physical SDRAM */
3892 +#define BCMA_SOC_SDRAM_R2 0x80000000U /* Region 2 for sdram (512 MB) */
3893 +
3894 +
3895 +#define BCMA_SOC_PCI_DMA 0x40000000U /* Client Mode sb2pcitranslation2 (1 GB) */
3896 +#define BCMA_SOC_PCI_DMA2 0x80000000U /* Client Mode sb2pcitranslation2 (1 GB) */
3897 +#define BCMA_SOC_PCI_DMA_SZ 0x40000000U /* Client Mode sb2pcitranslation2 size in bytes */
3898 +#define BCMA_SOC_PCIE_DMA_L32 0x00000000U /* PCIE Client Mode sb2pcitranslation2
3899 + * (2 ZettaBytes), low 32 bits
3900 + */
3901 +#define BCMA_SOC_PCIE_DMA_H32 0x80000000U /* PCIE Client Mode sb2pcitranslation2
3902 + * (2 ZettaBytes), high 32 bits
3903 + */
3904 +
3905 +#define BCMA_SOC_PCI1_MEM 0x40000000U /* Host Mode sb2pcitranslation0 (64 MB) */
3906 +#define BCMA_SOC_PCI1_CFG 0x44000000U /* Host Mode sb2pcitranslation1 (64 MB) */
3907 +#define BCMA_SOC_PCIE1_DMA_H32 0xc0000000U /* PCIE Client Mode sb2pcitranslation2
3908 + * (2 ZettaBytes), high 32 bits
3909 + */
3910 +
3911 #endif /* LINUX_BCMA_REGS_H_ */
3912 --- /dev/null
3913 +++ b/include/linux/bcma/bcma_soc.h
3914 @@ -0,0 +1,16 @@
3915 +#ifndef LINUX_BCMA_SOC_H_
3916 +#define LINUX_BCMA_SOC_H_
3917 +
3918 +#include <linux/bcma/bcma.h>
3919 +
3920 +struct bcma_soc {
3921 + struct bcma_bus bus;
3922 + struct bcma_device core_cc;
3923 + struct bcma_device core_mips;
3924 +};
3925 +
3926 +int __init bcma_host_soc_register(struct bcma_soc *soc);
3927 +
3928 +int bcma_bus_register(struct bcma_bus *bus);
3929 +
3930 +#endif /* LINUX_BCMA_SOC_H_ */