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