1 --- a/drivers/bcma/Kconfig
2 +++ b/drivers/bcma/Kconfig
3 @@ -29,10 +29,23 @@ config BCMA_HOST_PCI
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
10 PCI core hostmode operation (external PCI bus).
14 + depends on BCMA_DRIVER_MIPS
16 +config BCMA_DRIVER_MIPS
17 + bool "BCMA Broadcom MIPS core driver"
18 + depends on BCMA && MIPS
20 + Driver for the Broadcom MIPS core attached to Broadcom specific
21 + Advanced Microcontroller Bus.
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
39 ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG
40 --- a/drivers/bcma/bcma_private.h
41 +++ b/drivers/bcma/bcma_private.h
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);
53 +int bcma_bus_suspend(struct bcma_bus *bus);
54 +int bcma_bus_resume(struct bcma_bus *bus);
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);
65 int bcma_sprom_get(struct bcma_bus *bus);
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 */
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);
76 #ifdef CONFIG_BCMA_HOST_PCI
78 extern int __init bcma_host_pci_init(void);
79 extern void __exit bcma_host_pci_exit(void);
80 #endif /* CONFIG_BCMA_HOST_PCI */
83 +u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
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 */
92 --- a/drivers/bcma/core.c
93 +++ b/drivers/bcma/core.c
94 @@ -110,6 +110,8 @@ EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
95 u32 bcma_core_dma_translation(struct bcma_device *core)
97 switch (core->bus->hosttype) {
98 + case BCMA_HOSTTYPE_SOC:
100 case BCMA_HOSTTYPE_PCI:
101 if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
102 return BCMA_DMA_TRANSLATION_DMA64_CMT;
103 --- a/drivers/bcma/driver_chipcommon.c
104 +++ b/drivers/bcma/driver_chipcommon.c
105 @@ -26,6 +26,9 @@ void bcma_core_chipcommon_init(struct bc
109 + if (cc->setup_done)
112 if (cc->core->id.rev >= 11)
113 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
114 cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
115 @@ -52,6 +55,8 @@ void bcma_core_chipcommon_init(struct bc
116 ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
117 (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
120 + cc->setup_done = true;
123 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
124 @@ -101,3 +106,51 @@ u32 bcma_chipco_gpio_polarity(struct bcm
126 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
129 +#ifdef CONFIG_BCMA_DRIVER_MIPS
130 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
135 + unsigned int ccrev = cc->core->id.rev;
136 + struct bcma_serial_port *ports = cc->serial_ports;
138 + if (ccrev >= 11 && ccrev != 15) {
139 + /* Fixed ALP clock */
140 + baud_base = bcma_pmu_alp_clock(cc);
142 + /* Turn off UART clock before switching clocksource. */
143 + bcma_cc_write32(cc, BCMA_CC_CORECTL,
144 + bcma_cc_read32(cc, BCMA_CC_CORECTL)
145 + & ~BCMA_CC_CORECTL_UARTCLKEN);
147 + /* Set the override bit so we don't divide it */
148 + bcma_cc_write32(cc, BCMA_CC_CORECTL,
149 + bcma_cc_read32(cc, BCMA_CC_CORECTL)
150 + | BCMA_CC_CORECTL_UARTCLK0);
152 + /* Re-enable the UART clock. */
153 + bcma_cc_write32(cc, BCMA_CC_CORECTL,
154 + bcma_cc_read32(cc, BCMA_CC_CORECTL)
155 + | BCMA_CC_CORECTL_UARTCLKEN);
158 + pr_err("serial not supported on this device ccrev: 0x%x\n",
163 + irq = bcma_core_mips_irq(cc->core);
165 + /* Determine the registers of the UARTs */
166 + cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
167 + for (i = 0; i < cc->nr_serial_ports; i++) {
168 + ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
170 + ports[i].irq = irq;
171 + ports[i].baud_base = baud_base;
172 + ports[i].reg_shift = 0;
175 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
176 --- a/drivers/bcma/driver_chipcommon_pmu.c
177 +++ b/drivers/bcma/driver_chipcommon_pmu.c
179 #include "bcma_private.h"
180 #include <linux/bcma/bcma.h>
182 -static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
183 - u32 offset, u32 mask, u32 set)
184 +static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
187 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
188 + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
189 + return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
192 - bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
193 +void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
195 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
196 + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
197 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
199 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_write);
201 +void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
204 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
205 + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
206 + bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set);
208 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset);
210 +void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
211 + u32 offset, u32 mask, u32 set)
213 bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
214 bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
215 - value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
218 - bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
219 - bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
220 + bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set);
222 +EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset);
224 +void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
227 + bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset);
228 + bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR);
229 + bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set);
231 +EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
233 static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
235 @@ -52,6 +79,7 @@ static void bcma_pmu_resources_init(stru
243 @@ -83,6 +111,24 @@ void bcma_pmu_swreg_init(struct bcma_drv
247 +/* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
248 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
250 + struct bcma_bus *bus = cc->core->bus;
253 + val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL);
255 + val |= BCMA_CHIPCTL_4331_EXTPA_EN;
256 + if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
257 + val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
259 + val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
260 + val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
262 + bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
265 void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
267 struct bcma_bus *bus = cc->core->bus;
268 @@ -92,7 +138,7 @@ void bcma_pmu_workarounds(struct bcma_dr
269 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
272 - pr_err("Enabling Ext PA lines not implemented\n");
273 + /* BCM4331 workaround is SPROM-related, we put it in sprom.c */
276 if (bus->chipinfo.rev == 0) {
277 @@ -136,3 +182,129 @@ void bcma_pmu_init(struct bcma_drv_cc *c
278 bcma_pmu_swreg_init(cc);
279 bcma_pmu_workarounds(cc);
282 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
284 + struct bcma_bus *bus = cc->core->bus;
286 + switch (bus->chipinfo.id) {
295 + return 20000 * 1000;
299 + return 25000 * 1000;
301 + pr_warn("No ALP clock specified for %04X device, "
302 + "pmu rev. %d, using default %d Hz\n",
303 + bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
305 + return BCMA_CC_PMU_ALP_CLOCK;
308 +/* Find the output of the "m" pll divider given pll controls that start with
309 + * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
311 +static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
313 + u32 tmp, div, ndiv, p1, p2, fc;
314 + struct bcma_bus *bus = cc->core->bus;
316 + BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
318 + BUG_ON(!m || m > 4);
320 + if (bus->chipinfo.id == 0x5357 || bus->chipinfo.id == 0x4749) {
321 + /* Detect failure in clock setting */
322 + tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
324 + return 133 * 1000000;
327 + tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
328 + p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
329 + p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
331 + tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
332 + div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
333 + BCMA_CC_PPL_MDIV_MASK;
335 + tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
336 + ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
338 + /* Do calculation in Mhz */
339 + fc = bcma_pmu_alp_clock(cc) / 1000000;
340 + fc = (p1 * ndiv * fc) / p2;
342 + /* Return clock in Hertz */
343 + return (fc / div) * 1000000;
346 +/* query bus clock frequency for PMU-enabled chipcommon */
347 +u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
349 + struct bcma_bus *bus = cc->core->bus;
351 + switch (bus->chipinfo.id) {
355 + return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
356 + BCMA_CC_PMU5_MAINPLL_SSB);
358 + return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
359 + BCMA_CC_PMU5_MAINPLL_SSB);
362 + return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
363 + BCMA_CC_PMU5_MAINPLL_SSB);
365 + return bcma_pmu_clock(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
366 + BCMA_CC_PMU5_MAINPLL_SSB);
370 + pr_warn("No backplane clock specified for %04X device, "
371 + "pmu rev. %d, using default %d Hz\n",
372 + bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
374 + return BCMA_CC_PMU_HT_CLOCK;
377 +/* query cpu clock frequency for PMU-enabled chipcommon */
378 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
380 + struct bcma_bus *bus = cc->core->bus;
382 + if (bus->chipinfo.id == 53572)
385 + if (cc->pmu.rev >= 5) {
387 + switch (bus->chipinfo.id) {
389 + pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
393 + pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
396 + pll = BCMA_CC_PMU4716_MAINPLL_PLL0;
400 + /* TODO: if (bus->chipinfo.id == 0x5300)
401 + return si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); */
402 + return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
405 + return bcma_pmu_get_clockcontrol(cc);
408 +++ b/drivers/bcma/driver_mips.c
411 + * Broadcom specific AMBA
412 + * Broadcom MIPS32 74K core driver
414 + * Copyright 2009, Broadcom Corporation
415 + * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
416 + * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
417 + * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
419 + * Licensed under the GNU/GPL. See COPYING for details.
422 +#include "bcma_private.h"
424 +#include <linux/bcma/bcma.h>
426 +#include <linux/serial.h>
427 +#include <linux/serial_core.h>
428 +#include <linux/serial_reg.h>
429 +#include <linux/time.h>
431 +/* The 47162a0 hangs when reading MIPS DMP registers registers */
432 +static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
434 + return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
435 + dev->id.id == BCMA_CORE_MIPS_74K;
438 +/* The 5357b0 hangs when reading USB20H DMP registers */
439 +static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
441 + return (dev->bus->chipinfo.id == 0x5357 ||
442 + dev->bus->chipinfo.id == 0x4749) &&
443 + dev->bus->chipinfo.pkg == 11 &&
444 + dev->id.id == BCMA_CORE_USB20_HOST;
447 +static inline u32 mips_read32(struct bcma_drv_mips *mcore,
450 + return bcma_read32(mcore->core, offset);
453 +static inline void mips_write32(struct bcma_drv_mips *mcore,
457 + bcma_write32(mcore->core, offset, value);
460 +static const u32 ipsflag_irq_mask[] = {
462 + BCMA_MIPS_IPSFLAG_IRQ1,
463 + BCMA_MIPS_IPSFLAG_IRQ2,
464 + BCMA_MIPS_IPSFLAG_IRQ3,
465 + BCMA_MIPS_IPSFLAG_IRQ4,
468 +static const u32 ipsflag_irq_shift[] = {
470 + BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
471 + BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
472 + BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
473 + BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
476 +static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
480 + if (bcma_core_mips_bcm47162a0_quirk(dev))
481 + return dev->core_index;
482 + if (bcma_core_mips_bcm5357b0_quirk(dev))
483 + return dev->core_index;
484 + flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
486 + return flag & 0x1F;
489 +/* Get the MIPS IRQ assignment for a specified device.
490 + * If unassigned, 0 is returned.
492 +unsigned int bcma_core_mips_irq(struct bcma_device *dev)
494 + struct bcma_device *mdev = dev->bus->drv_mips.core;
498 + irqflag = bcma_core_mips_irqflag(dev);
500 + for (irq = 1; irq <= 4; irq++)
501 + if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
507 +EXPORT_SYMBOL(bcma_core_mips_irq);
509 +static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
511 + unsigned int oldirq = bcma_core_mips_irq(dev);
512 + struct bcma_bus *bus = dev->bus;
513 + struct bcma_device *mdev = bus->drv_mips.core;
516 + irqflag = bcma_core_mips_irqflag(dev);
517 + BUG_ON(oldirq == 6);
519 + dev->irq = irq + 2;
521 + /* clear the old irq */
523 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
524 + bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
527 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
529 + /* assign the new one */
531 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
532 + bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
535 + u32 oldirqflag = bcma_read32(mdev,
536 + BCMA_MIPS_MIPS74K_INTMASK(irq));
538 + struct bcma_device *core;
540 + /* backplane irq line is in use, find out who uses
541 + * it and set user to irq 0
543 + list_for_each_entry_reverse(core, &bus->cores, list) {
544 + if ((1 << bcma_core_mips_irqflag(core)) ==
546 + bcma_core_mips_set_irq(core, 0);
551 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
555 + pr_info("set_irq: core 0x%04x, irq %d => %d\n",
556 + dev->id.id, oldirq + 2, irq + 2);
559 +static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
562 + static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
563 + printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
564 + for (i = 0; i <= 6; i++)
565 + printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
569 +static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
571 + struct bcma_device *core;
573 + list_for_each_entry_reverse(core, &bus->cores, list) {
574 + bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
578 +u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
580 + struct bcma_bus *bus = mcore->core->bus;
582 + if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
583 + return bcma_pmu_get_clockcpu(&bus->drv_cc);
585 + pr_err("No PMU available, need this to get the cpu clock\n");
588 +EXPORT_SYMBOL(bcma_cpu_clock);
590 +static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
592 + struct bcma_bus *bus = mcore->core->bus;
594 + switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
595 + case BCMA_CC_FLASHT_STSER:
596 + case BCMA_CC_FLASHT_ATSER:
597 + pr_err("Serial flash not supported.\n");
599 + case BCMA_CC_FLASHT_PARA:
600 + pr_info("found parallel flash.\n");
601 + bus->drv_cc.pflash.window = 0x1c000000;
602 + bus->drv_cc.pflash.window_size = 0x02000000;
604 + if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
605 + BCMA_CC_FLASH_CFG_DS) == 0)
606 + bus->drv_cc.pflash.buswidth = 1;
608 + bus->drv_cc.pflash.buswidth = 2;
611 + pr_err("flash not supported.\n");
615 +void bcma_core_mips_init(struct bcma_drv_mips *mcore)
617 + struct bcma_bus *bus;
618 + struct bcma_device *core;
619 + bus = mcore->core->bus;
621 + pr_info("Initializing MIPS core...\n");
623 + if (!mcore->setup_done)
624 + mcore->assigned_irqs = 1;
626 + /* Assign IRQs to all cores on the bus */
627 + list_for_each_entry_reverse(core, &bus->cores, list) {
632 + mips_irq = bcma_core_mips_irq(core);
636 + core->irq = mips_irq + 2;
639 + switch (core->id.id) {
640 + case BCMA_CORE_PCI:
641 + case BCMA_CORE_PCIE:
642 + case BCMA_CORE_ETHERNET:
643 + case BCMA_CORE_ETHERNET_GBIT:
644 + case BCMA_CORE_MAC_GBIT:
645 + case BCMA_CORE_80211:
646 + case BCMA_CORE_USB20_HOST:
647 + /* These devices get their own IRQ line if available,
648 + * the rest goes on IRQ0
650 + if (mcore->assigned_irqs <= 4)
651 + bcma_core_mips_set_irq(core,
652 + mcore->assigned_irqs++);
656 + pr_info("IRQ reconfiguration done\n");
657 + bcma_core_mips_dump_irq(bus);
659 + if (mcore->setup_done)
662 + bcma_chipco_serial_init(&bus->drv_cc);
663 + bcma_core_mips_flash_detect(mcore);
664 + mcore->setup_done = true;
666 --- a/drivers/bcma/driver_pci.c
667 +++ b/drivers/bcma/driver_pci.c
669 * Broadcom specific AMBA
672 - * Copyright 2005, Broadcom Corporation
673 + * Copyright 2005, 2011, Broadcom Corporation
674 * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
675 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
677 * Licensed under the GNU/GPL. See COPYING for details.
681 **************************************************/
683 -static u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
684 +u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
686 - pcicore_write32(pc, 0x130, address);
687 - pcicore_read32(pc, 0x130);
688 - return pcicore_read32(pc, 0x134);
689 + pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
690 + pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
691 + return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA);
695 static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
697 - pcicore_write32(pc, 0x130, address);
698 - pcicore_read32(pc, 0x130);
699 - pcicore_write32(pc, 0x134, data);
700 + pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
701 + pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
702 + pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
706 static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
708 - const u16 mdio_control = 0x128;
709 - const u16 mdio_data = 0x12C;
713 - v = (1 << 30); /* Start of Transaction */
714 - v |= (1 << 28); /* Write Transaction */
715 - v |= (1 << 17); /* Turnaround */
717 + v = BCMA_CORE_PCI_MDIODATA_START;
718 + v |= BCMA_CORE_PCI_MDIODATA_WRITE;
719 + v |= (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
720 + BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
721 + v |= (BCMA_CORE_PCI_MDIODATA_BLK_ADDR <<
722 + BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
723 + v |= BCMA_CORE_PCI_MDIODATA_TA;
725 - pcicore_write32(pc, mdio_data, v);
726 + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
729 for (i = 0; i < 200; i++) {
730 - v = pcicore_read32(pc, mdio_control);
731 - if (v & 0x100 /* Trans complete */)
732 + v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
733 + if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
737 @@ -56,79 +58,84 @@ static void bcma_pcie_mdio_set_phy(struc
739 static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
741 - const u16 mdio_control = 0x128;
742 - const u16 mdio_data = 0x12C;
743 int max_retries = 10;
748 - v = 0x80; /* Enable Preamble Sequence */
749 - v |= 0x2; /* MDIO Clock Divisor */
750 - pcicore_write32(pc, mdio_control, v);
751 + /* enable mdio access to SERDES */
752 + v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
753 + v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
754 + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
756 if (pc->core->id.rev >= 10) {
758 bcma_pcie_mdio_set_phy(pc, device);
759 + v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
760 + BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
761 + v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
763 + v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
764 + v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
767 - v = (1 << 30); /* Start of Transaction */
768 - v |= (1 << 29); /* Read Transaction */
769 - v |= (1 << 17); /* Turnaround */
770 - if (pc->core->id.rev < 10)
771 - v |= (u32)device << 22;
772 - v |= (u32)address << 18;
773 - pcicore_write32(pc, mdio_data, v);
774 + v = BCMA_CORE_PCI_MDIODATA_START;
775 + v |= BCMA_CORE_PCI_MDIODATA_READ;
776 + v |= BCMA_CORE_PCI_MDIODATA_TA;
778 + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
779 /* Wait for the device to complete the transaction */
781 for (i = 0; i < max_retries; i++) {
782 - v = pcicore_read32(pc, mdio_control);
783 - if (v & 0x100 /* Trans complete */) {
784 + v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
785 + if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) {
787 - ret = pcicore_read32(pc, mdio_data);
788 + ret = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_DATA);
793 - pcicore_write32(pc, mdio_control, 0);
794 + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
798 static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
799 u8 address, u16 data)
801 - const u16 mdio_control = 0x128;
802 - const u16 mdio_data = 0x12C;
803 int max_retries = 10;
807 - v = 0x80; /* Enable Preamble Sequence */
808 - v |= 0x2; /* MDIO Clock Divisor */
809 - pcicore_write32(pc, mdio_control, v);
810 + /* enable mdio access to SERDES */
811 + v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
812 + v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
813 + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
815 if (pc->core->id.rev >= 10) {
817 bcma_pcie_mdio_set_phy(pc, device);
818 + v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
819 + BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
820 + v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
822 + v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
823 + v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
826 - v = (1 << 30); /* Start of Transaction */
827 - v |= (1 << 28); /* Write Transaction */
828 - v |= (1 << 17); /* Turnaround */
829 - if (pc->core->id.rev < 10)
830 - v |= (u32)device << 22;
831 - v |= (u32)address << 18;
832 + v = BCMA_CORE_PCI_MDIODATA_START;
833 + v |= BCMA_CORE_PCI_MDIODATA_WRITE;
834 + v |= BCMA_CORE_PCI_MDIODATA_TA;
836 - pcicore_write32(pc, mdio_data, v);
837 + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
838 /* Wait for the device to complete the transaction */
840 for (i = 0; i < max_retries; i++) {
841 - v = pcicore_read32(pc, mdio_control);
842 - if (v & 0x100 /* Trans complete */)
843 + v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
844 + if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
848 - pcicore_write32(pc, mdio_control, 0);
849 + pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
852 /**************************************************
853 @@ -137,67 +144,53 @@ static void bcma_pcie_mdio_write(struct
855 static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
857 - return (bcma_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
860 + tmp = bcma_pcie_read(pc, BCMA_CORE_PCI_PLP_STATUSREG);
861 + if (tmp & BCMA_CORE_PCI_PLP_POLARITYINV_STAT)
862 + return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE |
863 + BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY;
865 + return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE;
868 static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
870 - const u8 serdes_pll_device = 0x1D;
871 - const u8 serdes_rx_device = 0x1F;
874 - bcma_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
875 - bcma_pcicore_polarity_workaround(pc));
876 - tmp = bcma_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
878 - bcma_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
879 + bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_RX,
880 + BCMA_CORE_PCI_SERDES_RX_CTRL,
881 + bcma_pcicore_polarity_workaround(pc));
882 + tmp = bcma_pcie_mdio_read(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
883 + BCMA_CORE_PCI_SERDES_PLL_CTRL);
884 + if (tmp & BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN)
885 + bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
886 + BCMA_CORE_PCI_SERDES_PLL_CTRL,
887 + tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN);
890 /**************************************************
892 **************************************************/
894 -static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
895 +static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
897 bcma_pcicore_serdes_workaround(pc);
900 -static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
901 +void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc)
903 - struct bcma_bus *bus = pc->core->bus;
906 - chipid_top = (bus->chipinfo.id & 0xFF00);
907 - if (chipid_top != 0x4700 &&
908 - chipid_top != 0x5300)
911 -#ifdef CONFIG_SSB_DRIVER_PCICORE
912 - if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
914 -#endif /* CONFIG_SSB_DRIVER_PCICORE */
917 - /* TODO: on BCMA we use address from EROM instead of magic formula */
919 - return !mips_busprobe32(tmp, (bus->mmio +
920 - (pc->core->core_index * BCMA_CORE_SIZE)));
925 + if (pc->setup_done)
928 -void bcma_core_pci_init(struct bcma_drv_pci *pc)
930 - if (bcma_core_pci_is_in_hostmode(pc)) {
931 #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
932 + pc->hostmode = bcma_core_pci_is_in_hostmode(pc);
934 bcma_core_pci_hostmode_init(pc);
936 - pr_err("Driver compiled without support for hostmode PCI\n");
937 #endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
941 bcma_core_pci_clientmode_init(pc);
945 int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
946 @@ -205,7 +198,14 @@ int bcma_core_pci_irq_ctl(struct bcma_dr
948 struct pci_dev *pdev = pc->core->bus->host_pci;
953 + if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
954 + /* This bcma device is not on a PCI host-bus. So the IRQs are
955 + * not routed through the PCI core.
956 + * So we must not enable routing through the PCI core. */
960 err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
962 --- a/drivers/bcma/driver_pci_host.c
963 +++ b/drivers/bcma/driver_pci_host.c
965 * Broadcom specific AMBA
966 * PCI Core in hostmode
968 + * Copyright 2005 - 2011, Broadcom Corporation
969 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
970 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
972 * Licensed under the GNU/GPL. See COPYING for details.
975 #include "bcma_private.h"
976 +#include <linux/pci.h>
977 #include <linux/bcma/bcma.h>
978 +#include <asm/paccess.h>
980 +/* Probe a 32bit value on the bus and catch bus exceptions.
981 + * Returns nonzero on a bus exception.
982 + * This is MIPS specific */
983 +#define mips_busprobe32(val, addr) get_dbe((val), ((u32 *)(addr)))
985 +/* Assume one-hot slot wiring */
986 +#define BCMA_PCI_SLOT_MAX 16
987 +#define PCI_CONFIG_SPACE_SIZE 256
989 +bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
991 + struct bcma_bus *bus = pc->core->bus;
995 + chipid_top = (bus->chipinfo.id & 0xFF00);
996 + if (chipid_top != 0x4700 &&
997 + chipid_top != 0x5300)
1000 + if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) {
1001 + pr_info("This PCI core is disabled and not working\n");
1005 + bcma_core_enable(pc->core, 0);
1007 + return !mips_busprobe32(tmp, pc->core->io_addr);
1010 +static u32 bcma_pcie_read_config(struct bcma_drv_pci *pc, u32 address)
1012 + pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
1013 + pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
1014 + return pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_DATA);
1017 +static void bcma_pcie_write_config(struct bcma_drv_pci *pc, u32 address,
1020 + pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
1021 + pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
1022 + pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_DATA, data);
1025 +static u32 bcma_get_cfgspace_addr(struct bcma_drv_pci *pc, unsigned int dev,
1026 + unsigned int func, unsigned int off)
1030 + /* Issue config commands only when the data link is up (atleast
1031 + * one external pcie device is present).
1033 + if (dev >= 2 || !(bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_LSREG)
1034 + & BCMA_CORE_PCI_DLLP_LSREG_LINKUP))
1037 + /* Type 0 transaction */
1038 + /* Slide the PCI window to the appropriate slot */
1039 + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
1040 + /* Calculate the address */
1041 + addr = pc->host_controller->host_cfg_addr;
1042 + addr |= (dev << BCMA_CORE_PCI_CFG_SLOT_SHIFT);
1043 + addr |= (func << BCMA_CORE_PCI_CFG_FUN_SHIFT);
1044 + addr |= (off & ~3);
1050 -void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
1051 +static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev,
1052 + unsigned int func, unsigned int off,
1053 + void *buf, int len)
1055 - pr_err("No support for PCI core in hostmode yet\n");
1056 + int err = -EINVAL;
1058 + void __iomem *mmio = 0;
1060 + WARN_ON(!pc->hostmode);
1061 + if (unlikely(len != 1 && len != 2 && len != 4))
1064 + /* we support only two functions on device 0 */
1068 + /* accesses to config registers with offsets >= 256
1069 + * requires indirect access.
1071 + if (off >= PCI_CONFIG_SPACE_SIZE) {
1072 + addr = (func << 12);
1073 + addr |= (off & 0x0FFF);
1074 + val = bcma_pcie_read_config(pc, addr);
1076 + addr = BCMA_CORE_PCI_PCICFG0;
1077 + addr |= (func << 8);
1078 + addr |= (off & 0xfc);
1079 + val = pcicore_read32(pc, addr);
1082 + addr = bcma_get_cfgspace_addr(pc, dev, func, off);
1083 + if (unlikely(!addr))
1086 + mmio = ioremap_nocache(addr, len);
1090 + if (mips_busprobe32(val, mmio)) {
1095 + val = readl(mmio);
1097 + val >>= (8 * (off & 3));
1101 + *((u8 *)buf) = (u8)val;
1104 + *((u16 *)buf) = (u16)val;
1107 + *((u32 *)buf) = (u32)val;
1118 +static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
1119 + unsigned int func, unsigned int off,
1120 + const void *buf, int len)
1122 + int err = -EINVAL;
1123 + u32 addr = 0, val = 0;
1124 + void __iomem *mmio = 0;
1125 + u16 chipid = pc->core->bus->chipinfo.id;
1127 + WARN_ON(!pc->hostmode);
1128 + if (unlikely(len != 1 && len != 2 && len != 4))
1131 + /* accesses to config registers with offsets >= 256
1132 + * requires indirect access.
1134 + if (off < PCI_CONFIG_SPACE_SIZE) {
1135 + addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
1136 + addr |= (func << 8);
1137 + addr |= (off & 0xfc);
1138 + mmio = ioremap_nocache(addr, len);
1143 + addr = bcma_get_cfgspace_addr(pc, dev, func, off);
1144 + if (unlikely(!addr))
1147 + mmio = ioremap_nocache(addr, len);
1151 + if (mips_busprobe32(val, mmio)) {
1159 + val = readl(mmio);
1160 + val &= ~(0xFF << (8 * (off & 3)));
1161 + val |= *((const u8 *)buf) << (8 * (off & 3));
1164 + val = readl(mmio);
1165 + val &= ~(0xFFFF << (8 * (off & 3)));
1166 + val |= *((const u16 *)buf) << (8 * (off & 3));
1169 + val = *((const u32 *)buf);
1172 + if (dev == 0 && !addr) {
1173 + /* accesses to config registers with offsets >= 256
1174 + * requires indirect access.
1176 + addr = (func << 12);
1177 + addr |= (off & 0x0FFF);
1178 + bcma_pcie_write_config(pc, addr, val);
1180 + writel(val, mmio);
1182 + if (chipid == 0x4716 || chipid == 0x4748)
1194 +static int bcma_core_pci_hostmode_read_config(struct pci_bus *bus,
1195 + unsigned int devfn,
1196 + int reg, int size, u32 *val)
1198 + unsigned long flags;
1200 + struct bcma_drv_pci *pc;
1201 + struct bcma_drv_pci_host *pc_host;
1203 + pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
1204 + pc = pc_host->pdev;
1206 + spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
1207 + err = bcma_extpci_read_config(pc, PCI_SLOT(devfn),
1208 + PCI_FUNC(devfn), reg, val, size);
1209 + spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
1211 + return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
1214 +static int bcma_core_pci_hostmode_write_config(struct pci_bus *bus,
1215 + unsigned int devfn,
1216 + int reg, int size, u32 val)
1218 + unsigned long flags;
1220 + struct bcma_drv_pci *pc;
1221 + struct bcma_drv_pci_host *pc_host;
1223 + pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
1224 + pc = pc_host->pdev;
1226 + spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
1227 + err = bcma_extpci_write_config(pc, PCI_SLOT(devfn),
1228 + PCI_FUNC(devfn), reg, &val, size);
1229 + spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
1231 + return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
1234 +/* return cap_offset if requested capability exists in the PCI config space */
1235 +static u8 __devinit bcma_find_pci_capability(struct bcma_drv_pci *pc,
1237 + unsigned int func, u8 req_cap_id,
1238 + unsigned char *buf, u32 *buflen)
1245 + /* check for Header type 0 */
1246 + bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val,
1248 + if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
1251 + /* check if the capability pointer field exists */
1252 + bcma_extpci_read_config(pc, dev, func, PCI_STATUS, &byte_val,
1254 + if (!(byte_val & PCI_STATUS_CAP_LIST))
1257 + /* check if the capability pointer is 0x00 */
1258 + bcma_extpci_read_config(pc, dev, func, PCI_CAPABILITY_LIST, &cap_ptr,
1260 + if (cap_ptr == 0x00)
1263 + /* loop thr'u the capability list and see if the requested capabilty
1265 + bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id, sizeof(u8));
1266 + while (cap_id != req_cap_id) {
1267 + bcma_extpci_read_config(pc, dev, func, cap_ptr + 1, &cap_ptr,
1269 + if (cap_ptr == 0x00)
1271 + bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id,
1275 + /* found the caller requested capability */
1276 + if ((buf != NULL) && (buflen != NULL)) {
1279 + bufsize = *buflen;
1285 + /* copy the cpability data excluding cap ID and next ptr */
1286 + cap_data = cap_ptr + 2;
1287 + if ((bufsize + cap_data) > PCI_CONFIG_SPACE_SIZE)
1288 + bufsize = PCI_CONFIG_SPACE_SIZE - cap_data;
1289 + *buflen = bufsize;
1290 + while (bufsize--) {
1291 + bcma_extpci_read_config(pc, dev, func, cap_data, buf,
1301 +/* If the root port is capable of returning Config Request
1302 + * Retry Status (CRS) Completion Status to software then
1303 + * enable the feature.
1305 +static void __devinit bcma_core_pci_enable_crs(struct bcma_drv_pci *pc)
1307 + u8 cap_ptr, root_ctrl, root_cap, dev;
1311 + cap_ptr = bcma_find_pci_capability(pc, 0, 0, PCI_CAP_ID_EXP, NULL,
1313 + root_cap = cap_ptr + PCI_EXP_RTCAP;
1314 + bcma_extpci_read_config(pc, 0, 0, root_cap, &val16, sizeof(u16));
1315 + if (val16 & BCMA_CORE_PCI_RC_CRS_VISIBILITY) {
1316 + /* Enable CRS software visibility */
1317 + root_ctrl = cap_ptr + PCI_EXP_RTCTL;
1318 + val16 = PCI_EXP_RTCTL_CRSSVE;
1319 + bcma_extpci_read_config(pc, 0, 0, root_ctrl, &val16,
1322 + /* Initiate a configuration request to read the vendor id
1323 + * field of the device function's config space header after
1324 + * 100 ms wait time from the end of Reset. If the device is
1325 + * not done with its internal initialization, it must at
1326 + * least return a completion TLP, with a completion status
1327 + * of "Configuration Request Retry Status (CRS)". The root
1328 + * complex must complete the request to the host by returning
1329 + * a read-data value of 0001h for the Vendor ID field and
1330 + * all 1s for any additional bytes included in the request.
1331 + * Poll using the config reads for max wait time of 1 sec or
1332 + * until we receive the successful completion status. Repeat
1333 + * the procedure for all the devices.
1335 + for (dev = 1; dev < BCMA_PCI_SLOT_MAX; dev++) {
1336 + for (i = 0; i < 100000; i++) {
1337 + bcma_extpci_read_config(pc, dev, 0,
1338 + PCI_VENDOR_ID, &val16,
1345 + pr_err("PCI: Broken device in slot %d\n", dev);
1350 +void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
1352 + struct bcma_bus *bus = pc->core->bus;
1353 + struct bcma_drv_pci_host *pc_host;
1355 + u32 pci_membase_1G;
1356 + unsigned long io_map_base;
1358 + pr_info("PCIEcore in host mode found\n");
1360 + pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL);
1362 + pr_err("can not allocate memory");
1366 + pc->host_controller = pc_host;
1367 + pc_host->pci_controller.io_resource = &pc_host->io_resource;
1368 + pc_host->pci_controller.mem_resource = &pc_host->mem_resource;
1369 + pc_host->pci_controller.pci_ops = &pc_host->pci_ops;
1370 + pc_host->pdev = pc;
1372 + pci_membase_1G = BCMA_SOC_PCI_DMA;
1373 + pc_host->host_cfg_addr = BCMA_SOC_PCI_CFG;
1375 + pc_host->pci_ops.read = bcma_core_pci_hostmode_read_config;
1376 + pc_host->pci_ops.write = bcma_core_pci_hostmode_write_config;
1378 + pc_host->mem_resource.name = "BCMA PCIcore external memory",
1379 + pc_host->mem_resource.start = BCMA_SOC_PCI_DMA;
1380 + pc_host->mem_resource.end = BCMA_SOC_PCI_DMA + BCMA_SOC_PCI_DMA_SZ - 1;
1381 + pc_host->mem_resource.flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED;
1383 + pc_host->io_resource.name = "BCMA PCIcore external I/O",
1384 + pc_host->io_resource.start = 0x100;
1385 + pc_host->io_resource.end = 0x7FF;
1386 + pc_host->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED;
1390 + pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE);
1392 + pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST |
1393 + BCMA_CORE_PCI_CTL_RST_OE);
1395 + /* 64 MB I/O access window. On 4716, use
1396 + * sbtopcie0 to access the device registers. We
1397 + * can't use address match 2 (1 GB window) region
1398 + * as mips can't generate 64-bit address on the
1401 + if (bus->chipinfo.id == 0x4716 || bus->chipinfo.id == 0x4748) {
1402 + pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
1403 + pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
1404 + BCMA_SOC_PCI_MEM_SZ - 1;
1405 + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
1406 + BCMA_CORE_PCI_SBTOPCI_MEM | BCMA_SOC_PCI_MEM);
1407 + } else if (bus->chipinfo.id == 0x5300) {
1408 + tmp = BCMA_CORE_PCI_SBTOPCI_MEM;
1409 + tmp |= BCMA_CORE_PCI_SBTOPCI_PREF;
1410 + tmp |= BCMA_CORE_PCI_SBTOPCI_BURST;
1411 + if (pc->core->core_unit == 0) {
1412 + pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
1413 + pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
1414 + BCMA_SOC_PCI_MEM_SZ - 1;
1415 + pci_membase_1G = BCMA_SOC_PCIE_DMA_H32;
1416 + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
1417 + tmp | BCMA_SOC_PCI_MEM);
1418 + } else if (pc->core->core_unit == 1) {
1419 + pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM;
1420 + pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM +
1421 + BCMA_SOC_PCI_MEM_SZ - 1;
1422 + pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32;
1423 + pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG;
1424 + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
1425 + tmp | BCMA_SOC_PCI1_MEM);
1428 + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
1429 + BCMA_CORE_PCI_SBTOPCI_IO);
1431 + /* 64 MB configuration access window */
1432 + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
1434 + /* 1 GB memory access window */
1435 + pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI2,
1436 + BCMA_CORE_PCI_SBTOPCI_MEM | pci_membase_1G);
1439 + /* As per PCI Express Base Spec 1.1 we need to wait for
1440 + * at least 100 ms from the end of a reset (cold/warm/hot)
1441 + * before issuing configuration requests to PCI Express
1446 + bcma_core_pci_enable_crs(pc);
1448 + /* Enable PCI bridge BAR0 memory & master access */
1449 + tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
1450 + bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp));
1452 + /* Enable PCI interrupts */
1453 + pcicore_write32(pc, BCMA_CORE_PCI_IMASK, BCMA_CORE_PCI_IMASK_INTA);
1455 + /* Ok, ready to run, register it to the system.
1456 + * The following needs change, if we want to port hostmode
1457 + * to non-MIPS platform. */
1458 + io_map_base = (unsigned long)ioremap_nocache(BCMA_SOC_PCI_MEM,
1460 + pc_host->pci_controller.io_map_base = io_map_base;
1461 + set_io_port_base(pc_host->pci_controller.io_map_base);
1462 + /* Give some time to the PCI controller to configure itself with the new
1463 + * values. Not waiting at this point causes crashes of the machine. */
1465 + register_pci_controller(&pc_host->pci_controller);
1469 +/* Early PCI fixup for a device on the PCI-core bridge. */
1470 +static void bcma_core_pci_fixup_pcibridge(struct pci_dev *dev)
1472 + if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
1473 + /* This is not a device on the PCI-core bridge. */
1476 + if (PCI_SLOT(dev->devfn) != 0)
1479 + pr_info("PCI: Fixing up bridge %s\n", pci_name(dev));
1481 + /* Enable PCI bridge bus mastering and memory space */
1482 + pci_set_master(dev);
1483 + if (pcibios_enable_device(dev, ~0) < 0) {
1484 + pr_err("PCI: BCMA bridge enable failed\n");
1488 + /* Enable PCI bridge BAR1 prefetch and burst */
1489 + pci_write_config_dword(dev, BCMA_PCI_BAR1_CONTROL, 3);
1491 +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_pcibridge);
1493 +/* Early PCI fixup for all PCI-cores to set the correct memory address. */
1494 +static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
1496 + struct resource *res;
1499 + if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
1500 + /* This is not a device on the PCI-core bridge. */
1503 + if (PCI_SLOT(dev->devfn) == 0)
1506 + pr_info("PCI: Fixing up addresses %s\n", pci_name(dev));
1508 + for (pos = 0; pos < 6; pos++) {
1509 + res = &dev->resource[pos];
1510 + if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM))
1511 + pci_assign_resource(dev, pos);
1514 +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses);
1516 +/* This function is called when doing a pci_enable_device().
1517 + * We must first check if the device is a device on the PCI-core bridge. */
1518 +int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
1520 + struct bcma_drv_pci_host *pc_host;
1522 + if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
1523 + /* This is not a device on the PCI-core bridge. */
1526 + pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
1529 + pr_info("PCI: Fixing up device %s\n", pci_name(dev));
1531 + /* Fix up interrupt lines */
1532 + dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2;
1533 + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
1537 +EXPORT_SYMBOL(bcma_core_pci_plat_dev_init);
1539 +/* PCI device IRQ mapping. */
1540 +int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev)
1542 + struct bcma_drv_pci_host *pc_host;
1544 + if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
1545 + /* This is not a device on the PCI-core bridge. */
1549 + pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
1551 + return bcma_core_mips_irq(pc_host->pdev->core) + 2;
1553 +EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq);
1554 --- a/drivers/bcma/host_pci.c
1555 +++ b/drivers/bcma/host_pci.c
1557 #include <linux/slab.h>
1558 #include <linux/bcma/bcma.h>
1559 #include <linux/pci.h>
1560 +#include <linux/module.h>
1562 static void bcma_host_pci_switch_core(struct bcma_device *core)
1564 @@ -20,48 +21,58 @@ static void bcma_host_pci_switch_core(st
1565 pr_debug("Switched to core: 0x%X\n", core->id.id);
1568 -static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
1570 +/* Provides access to the requested core. Returns base offset that has to be
1571 + * used. It makes use of fixed windows when possible. */
1572 +static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core)
1574 + switch (core->id.id) {
1575 + case BCMA_CORE_CHIPCOMMON:
1576 + return 3 * BCMA_CORE_SIZE;
1577 + case BCMA_CORE_PCIE:
1578 + return 2 * BCMA_CORE_SIZE;
1581 if (core->bus->mapped_core != core)
1582 bcma_host_pci_switch_core(core);
1586 +static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
1588 + offset += bcma_host_pci_provide_access_to_core(core);
1589 return ioread8(core->bus->mmio + offset);
1592 static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
1594 - if (core->bus->mapped_core != core)
1595 - bcma_host_pci_switch_core(core);
1596 + offset += bcma_host_pci_provide_access_to_core(core);
1597 return ioread16(core->bus->mmio + offset);
1600 static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
1602 - if (core->bus->mapped_core != core)
1603 - bcma_host_pci_switch_core(core);
1604 + offset += bcma_host_pci_provide_access_to_core(core);
1605 return ioread32(core->bus->mmio + offset);
1608 static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
1611 - if (core->bus->mapped_core != core)
1612 - bcma_host_pci_switch_core(core);
1613 + offset += bcma_host_pci_provide_access_to_core(core);
1614 iowrite8(value, core->bus->mmio + offset);
1617 static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
1620 - if (core->bus->mapped_core != core)
1621 - bcma_host_pci_switch_core(core);
1622 + offset += bcma_host_pci_provide_access_to_core(core);
1623 iowrite16(value, core->bus->mmio + offset);
1626 static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
1629 - if (core->bus->mapped_core != core)
1630 - bcma_host_pci_switch_core(core);
1631 + offset += bcma_host_pci_provide_access_to_core(core);
1632 iowrite32(value, core->bus->mmio + offset);
1635 @@ -143,8 +154,8 @@ const struct bcma_host_ops bcma_host_pci
1636 .awrite32 = bcma_host_pci_awrite32,
1639 -static int bcma_host_pci_probe(struct pci_dev *dev,
1640 - const struct pci_device_id *id)
1641 +static int __devinit bcma_host_pci_probe(struct pci_dev *dev,
1642 + const struct pci_device_id *id)
1644 struct bcma_bus *bus;
1646 @@ -223,6 +234,35 @@ static void bcma_host_pci_remove(struct
1647 pci_set_drvdata(dev, NULL);
1651 +static int bcma_host_pci_suspend(struct device *dev)
1653 + struct pci_dev *pdev = to_pci_dev(dev);
1654 + struct bcma_bus *bus = pci_get_drvdata(pdev);
1656 + bus->mapped_core = NULL;
1658 + return bcma_bus_suspend(bus);
1661 +static int bcma_host_pci_resume(struct device *dev)
1663 + struct pci_dev *pdev = to_pci_dev(dev);
1664 + struct bcma_bus *bus = pci_get_drvdata(pdev);
1666 + return bcma_bus_resume(bus);
1669 +static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend,
1670 + bcma_host_pci_resume);
1671 +#define BCMA_PM_OPS (&bcma_pm_ops)
1673 +#else /* CONFIG_PM */
1675 +#define BCMA_PM_OPS NULL
1677 +#endif /* CONFIG_PM */
1679 static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
1680 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
1681 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
1682 @@ -238,6 +278,7 @@ static struct pci_driver bcma_pci_bridge
1683 .id_table = bcma_pci_bridge_tbl,
1684 .probe = bcma_host_pci_probe,
1685 .remove = bcma_host_pci_remove,
1686 + .driver.pm = BCMA_PM_OPS,
1689 int __init bcma_host_pci_init(void)
1691 +++ b/drivers/bcma/host_soc.c
1694 + * Broadcom specific AMBA
1695 + * System on Chip (SoC) Host
1697 + * Licensed under the GNU/GPL. See COPYING for details.
1700 +#include "bcma_private.h"
1702 +#include <linux/bcma/bcma.h>
1703 +#include <linux/bcma/bcma_soc.h>
1705 +static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
1707 + return readb(core->io_addr + offset);
1710 +static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
1712 + return readw(core->io_addr + offset);
1715 +static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
1717 + return readl(core->io_addr + offset);
1720 +static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
1723 + writeb(value, core->io_addr + offset);
1726 +static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
1729 + writew(value, core->io_addr + offset);
1732 +static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
1735 + writel(value, core->io_addr + offset);
1738 +#ifdef CONFIG_BCMA_BLOCKIO
1739 +static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
1740 + size_t count, u16 offset, u8 reg_width)
1742 + void __iomem *addr = core->io_addr + offset;
1744 + switch (reg_width) {
1745 + case sizeof(u8): {
1749 + *buf = __raw_readb(addr);
1755 + case sizeof(u16): {
1756 + __le16 *buf = buffer;
1758 + WARN_ON(count & 1);
1760 + *buf = (__force __le16)__raw_readw(addr);
1766 + case sizeof(u32): {
1767 + __le32 *buf = buffer;
1769 + WARN_ON(count & 3);
1771 + *buf = (__force __le32)__raw_readl(addr);
1782 +static void bcma_host_soc_block_write(struct bcma_device *core,
1783 + const void *buffer,
1784 + size_t count, u16 offset, u8 reg_width)
1786 + void __iomem *addr = core->io_addr + offset;
1788 + switch (reg_width) {
1789 + case sizeof(u8): {
1790 + const u8 *buf = buffer;
1793 + __raw_writeb(*buf, addr);
1799 + case sizeof(u16): {
1800 + const __le16 *buf = buffer;
1802 + WARN_ON(count & 1);
1804 + __raw_writew((__force u16)(*buf), addr);
1810 + case sizeof(u32): {
1811 + const __le32 *buf = buffer;
1813 + WARN_ON(count & 3);
1815 + __raw_writel((__force u32)(*buf), addr);
1825 +#endif /* CONFIG_BCMA_BLOCKIO */
1827 +static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
1829 + return readl(core->io_wrap + offset);
1832 +static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
1835 + writel(value, core->io_wrap + offset);
1838 +const struct bcma_host_ops bcma_host_soc_ops = {
1839 + .read8 = bcma_host_soc_read8,
1840 + .read16 = bcma_host_soc_read16,
1841 + .read32 = bcma_host_soc_read32,
1842 + .write8 = bcma_host_soc_write8,
1843 + .write16 = bcma_host_soc_write16,
1844 + .write32 = bcma_host_soc_write32,
1845 +#ifdef CONFIG_BCMA_BLOCKIO
1846 + .block_read = bcma_host_soc_block_read,
1847 + .block_write = bcma_host_soc_block_write,
1849 + .aread32 = bcma_host_soc_aread32,
1850 + .awrite32 = bcma_host_soc_awrite32,
1853 +int __init bcma_host_soc_register(struct bcma_soc *soc)
1855 + struct bcma_bus *bus = &soc->bus;
1858 + /* iomap only first core. We have to read some register on this core
1859 + * to scan the bus.
1861 + bus->mmio = ioremap_nocache(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
1865 + /* Host specific */
1866 + bus->hosttype = BCMA_HOSTTYPE_SOC;
1867 + bus->ops = &bcma_host_soc_ops;
1870 + err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
1872 + iounmap(bus->mmio);
1876 --- a/drivers/bcma/main.c
1877 +++ b/drivers/bcma/main.c
1881 #include "bcma_private.h"
1882 +#include <linux/module.h>
1883 #include <linux/bcma/bcma.h>
1884 #include <linux/slab.h>
1886 MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
1887 MODULE_LICENSE("GPL");
1889 +/* contains the number the next bus should get. */
1890 +static unsigned int bcma_bus_next_num = 0;
1892 +/* bcma_buses_mutex locks the bcma_bus_next_num */
1893 +static DEFINE_MUTEX(bcma_buses_mutex);
1895 static int bcma_bus_match(struct device *dev, struct device_driver *drv);
1896 static int bcma_device_probe(struct device *dev);
1897 static int bcma_device_remove(struct device *dev);
1898 @@ -54,7 +61,7 @@ static struct bus_type bcma_bus_type = {
1899 .dev_attrs = bcma_device_attrs,
1902 -static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
1903 +struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
1905 struct bcma_device *core;
1907 @@ -64,10 +71,15 @@ static struct bcma_device *bcma_find_cor
1911 +EXPORT_SYMBOL_GPL(bcma_find_core);
1913 static void bcma_release_core_dev(struct device *dev)
1915 struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1916 + if (core->io_addr)
1917 + iounmap(core->io_addr);
1918 + if (core->io_wrap)
1919 + iounmap(core->io_wrap);
1923 @@ -82,12 +94,13 @@ static int bcma_register_cores(struct bc
1924 case BCMA_CORE_CHIPCOMMON:
1926 case BCMA_CORE_PCIE:
1927 + case BCMA_CORE_MIPS_74K:
1931 core->dev.release = bcma_release_core_dev;
1932 core->dev.bus = &bcma_bus_type;
1933 - dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
1934 + dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
1936 switch (bus->hosttype) {
1937 case BCMA_HOSTTYPE_PCI:
1938 @@ -95,7 +108,10 @@ static int bcma_register_cores(struct bc
1939 core->dma_dev = &bus->host_pci->dev;
1940 core->irq = bus->host_pci->irq;
1942 - case BCMA_HOSTTYPE_NONE:
1943 + case BCMA_HOSTTYPE_SOC:
1944 + core->dev.dma_mask = &core->dev.coherent_dma_mask;
1945 + core->dma_dev = &core->dev;
1947 case BCMA_HOSTTYPE_SDIO:
1950 @@ -123,11 +139,15 @@ static void bcma_unregister_cores(struct
1954 -int bcma_bus_register(struct bcma_bus *bus)
1955 +int __devinit bcma_bus_register(struct bcma_bus *bus)
1958 struct bcma_device *core;
1960 + mutex_lock(&bcma_buses_mutex);
1961 + bus->num = bcma_bus_next_num++;
1962 + mutex_unlock(&bcma_buses_mutex);
1964 /* Scan for devices (cores) */
1965 err = bcma_bus_scan(bus);
1967 @@ -142,6 +162,13 @@ int bcma_bus_register(struct bcma_bus *b
1968 bcma_core_chipcommon_init(&bus->drv_cc);
1971 + /* Init MIPS core */
1972 + core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
1974 + bus->drv_mips.core = core;
1975 + bcma_core_mips_init(&bus->drv_mips);
1978 /* Init PCIE core */
1979 core = bcma_find_core(bus, BCMA_CORE_PCIE);
1981 @@ -153,10 +180,8 @@ int bcma_bus_register(struct bcma_bus *b
1982 err = bcma_sprom_get(bus);
1983 if (err == -ENOENT) {
1984 pr_err("No SPROM available\n");
1987 pr_err("Failed to get SPROM: %d\n", err);
1991 /* Register found cores */
1992 bcma_register_cores(bus);
1993 @@ -171,6 +196,99 @@ void bcma_bus_unregister(struct bcma_bus
1994 bcma_unregister_cores(bus);
1997 +int __init bcma_bus_early_register(struct bcma_bus *bus,
1998 + struct bcma_device *core_cc,
1999 + struct bcma_device *core_mips)
2002 + struct bcma_device *core;
2003 + struct bcma_device_id match;
2005 + bcma_init_bus(bus);
2007 + match.manuf = BCMA_MANUF_BCM;
2008 + match.id = BCMA_CORE_CHIPCOMMON;
2009 + match.class = BCMA_CL_SIM;
2010 + match.rev = BCMA_ANY_REV;
2012 + /* Scan for chip common core */
2013 + err = bcma_bus_scan_early(bus, &match, core_cc);
2015 + pr_err("Failed to scan for common core: %d\n", err);
2019 + match.manuf = BCMA_MANUF_MIPS;
2020 + match.id = BCMA_CORE_MIPS_74K;
2021 + match.class = BCMA_CL_SIM;
2022 + match.rev = BCMA_ANY_REV;
2024 + /* Scan for mips core */
2025 + err = bcma_bus_scan_early(bus, &match, core_mips);
2027 + pr_err("Failed to scan for mips core: %d\n", err);
2031 + /* Init CC core */
2032 + core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
2034 + bus->drv_cc.core = core;
2035 + bcma_core_chipcommon_init(&bus->drv_cc);
2038 + /* Init MIPS core */
2039 + core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
2041 + bus->drv_mips.core = core;
2042 + bcma_core_mips_init(&bus->drv_mips);
2045 + pr_info("Early bus registered\n");
2051 +int bcma_bus_suspend(struct bcma_bus *bus)
2053 + struct bcma_device *core;
2055 + list_for_each_entry(core, &bus->cores, list) {
2056 + struct device_driver *drv = core->dev.driver;
2058 + struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
2059 + if (adrv->suspend)
2060 + adrv->suspend(core);
2066 +int bcma_bus_resume(struct bcma_bus *bus)
2068 + struct bcma_device *core;
2070 + /* Init CC core */
2071 + core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
2073 + bus->drv_cc.setup_done = false;
2074 + bcma_core_chipcommon_init(&bus->drv_cc);
2077 + list_for_each_entry(core, &bus->cores, list) {
2078 + struct device_driver *drv = core->dev.driver;
2080 + struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
2082 + adrv->resume(core);
2090 int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
2092 drv->drv.name = drv->name;
2093 --- a/drivers/bcma/scan.c
2094 +++ b/drivers/bcma/scan.c
2095 @@ -200,18 +200,174 @@ static s32 bcma_erom_get_addr_desc(struc
2099 -int bcma_bus_scan(struct bcma_bus *bus)
2100 +static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
2104 - u32 __iomem *eromptr, *eromend;
2105 + struct bcma_device *core;
2107 + list_for_each_entry(core, &bus->cores, list) {
2108 + if (core->core_index == index)
2114 +static struct bcma_device *bcma_find_core_reverse(struct bcma_bus *bus, u16 coreid)
2116 + struct bcma_device *core;
2118 + list_for_each_entry_reverse(core, &bus->cores, list) {
2119 + if (core->id.id == coreid)
2125 +static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
2126 + struct bcma_device_id *match, int core_num,
2127 + struct bcma_device *core)
2132 u8 ports[2], wrappers[2];
2135 + cia = bcma_erom_get_ci(bus, eromptr);
2137 + bcma_erom_push_ent(eromptr);
2138 + if (bcma_erom_is_end(bus, eromptr))
2142 + cib = bcma_erom_get_ci(bus, eromptr);
2147 + core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
2148 + core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
2149 + core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
2150 + ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
2151 + ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
2152 + wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
2153 + wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
2154 + core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
2156 + if (((core->id.manuf == BCMA_MANUF_ARM) &&
2157 + (core->id.id == 0xFFF)) ||
2158 + (ports[1] == 0)) {
2159 + bcma_erom_skip_component(bus, eromptr);
2163 + /* check if component is a core at all */
2164 + if (wrappers[0] + wrappers[1] == 0) {
2165 + /* we could save addrl of the router
2166 + if (cid == BCMA_CORE_OOB_ROUTER)
2168 + bcma_erom_skip_component(bus, eromptr);
2172 + if (bcma_erom_is_bridge(bus, eromptr)) {
2173 + bcma_erom_skip_component(bus, eromptr);
2177 + if (bcma_find_core_by_index(bus, core_num)) {
2178 + bcma_erom_skip_component(bus, eromptr);
2182 + if (match && ((match->manuf != BCMA_ANY_MANUF &&
2183 + match->manuf != core->id.manuf) ||
2184 + (match->id != BCMA_ANY_ID && match->id != core->id.id) ||
2185 + (match->rev != BCMA_ANY_REV && match->rev != core->id.rev) ||
2186 + (match->class != BCMA_ANY_CLASS && match->class != core->id.class)
2188 + bcma_erom_skip_component(bus, eromptr);
2192 + /* get & parse master ports */
2193 + for (i = 0; i < ports[0]; i++) {
2194 + s32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
2195 + if (mst_port_d < 0)
2199 + /* get & parse slave ports */
2200 + for (i = 0; i < ports[1]; i++) {
2201 + for (j = 0; ; j++) {
2202 + tmp = bcma_erom_get_addr_desc(bus, eromptr,
2203 + SCAN_ADDR_TYPE_SLAVE, i);
2205 + /* no more entries for port _i_ */
2206 + /* pr_debug("erom: slave port %d "
2207 + * "has %d descriptors\n", i, j); */
2210 + if (i == 0 && j == 0)
2216 + /* get & parse master wrappers */
2217 + for (i = 0; i < wrappers[0]; i++) {
2218 + for (j = 0; ; j++) {
2219 + tmp = bcma_erom_get_addr_desc(bus, eromptr,
2220 + SCAN_ADDR_TYPE_MWRAP, i);
2222 + /* no more entries for port _i_ */
2223 + /* pr_debug("erom: master wrapper %d "
2224 + * "has %d descriptors\n", i, j); */
2227 + if (i == 0 && j == 0)
2233 + /* get & parse slave wrappers */
2234 + for (i = 0; i < wrappers[1]; i++) {
2235 + u8 hack = (ports[1] == 1) ? 0 : 1;
2236 + for (j = 0; ; j++) {
2237 + tmp = bcma_erom_get_addr_desc(bus, eromptr,
2238 + SCAN_ADDR_TYPE_SWRAP, i + hack);
2240 + /* no more entries for port _i_ */
2241 + /* pr_debug("erom: master wrapper %d "
2242 + * has %d descriptors\n", i, j); */
2245 + if (wrappers[0] == 0 && !i && !j)
2250 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
2251 + core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE);
2252 + if (!core->io_addr)
2254 + core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE);
2255 + if (!core->io_wrap) {
2256 + iounmap(core->io_addr);
2263 +void bcma_init_bus(struct bcma_bus *bus)
2267 + struct bcma_chipinfo *chipinfo = &(bus->chipinfo);
2270 + if (bus->init_done)
2273 INIT_LIST_HEAD(&bus->cores);
2275 @@ -219,142 +375,133 @@ int bcma_bus_scan(struct bcma_bus *bus)
2276 bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
2278 tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
2279 - bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
2280 - bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
2281 - bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
2282 + chipinfo->id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
2283 + chipinfo->rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
2284 + chipinfo->pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
2285 + pr_info("Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n",
2286 + chipinfo->id, chipinfo->rev, chipinfo->pkg);
2288 + bus->init_done = true;
2291 +int bcma_bus_scan(struct bcma_bus *bus)
2294 + u32 __iomem *eromptr, *eromend;
2296 + int err, core_num = 0;
2298 + bcma_init_bus(bus);
2300 erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
2301 - eromptr = bus->mmio;
2302 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
2303 + eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
2307 + eromptr = bus->mmio;
2310 eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
2312 bcma_scan_switch_core(bus, erombase);
2314 while (eromptr < eromend) {
2315 + struct bcma_device *other_core;
2316 struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
2319 INIT_LIST_HEAD(&core->list);
2323 - cia = bcma_erom_get_ci(bus, &eromptr);
2325 - bcma_erom_push_ent(&eromptr);
2326 - if (bcma_erom_is_end(bus, &eromptr))
2327 + err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
2330 + if (err == -ENODEV) {
2333 + } else if (err == -ENXIO) {
2335 + } else if (err == -ESPIPE) {
2340 - cib = bcma_erom_get_ci(bus, &eromptr);
2349 - core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
2350 - core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
2351 - core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
2352 - ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
2353 - ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
2354 - wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
2355 - wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
2356 - core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
2358 - if (((core->id.manuf == BCMA_MANUF_ARM) &&
2359 - (core->id.id == 0xFFF)) ||
2360 - (ports[1] == 0)) {
2361 - bcma_erom_skip_component(bus, &eromptr);
2364 + core->core_index = core_num++;
2366 + other_core = bcma_find_core_reverse(bus, core->id.id);
2367 + core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1;
2369 - /* check if component is a core at all */
2370 - if (wrappers[0] + wrappers[1] == 0) {
2371 - /* we could save addrl of the router
2372 - if (cid == BCMA_CORE_OOB_ROUTER)
2374 - bcma_erom_skip_component(bus, &eromptr);
2377 + pr_info("Core %d found: %s "
2378 + "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
2379 + core->core_index, bcma_device_name(&core->id),
2380 + core->id.manuf, core->id.id, core->id.rev,
2383 - if (bcma_erom_is_bridge(bus, &eromptr)) {
2384 - bcma_erom_skip_component(bus, &eromptr);
2387 + list_add(&core->list, &bus->cores);
2390 - /* get & parse master ports */
2391 - for (i = 0; i < ports[0]; i++) {
2392 - u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
2393 - if (mst_port_d < 0) {
2398 + if (bus->hosttype == BCMA_HOSTTYPE_SOC)
2401 - /* get & parse slave ports */
2402 - for (i = 0; i < ports[1]; i++) {
2403 - for (j = 0; ; j++) {
2404 - tmp = bcma_erom_get_addr_desc(bus, &eromptr,
2405 - SCAN_ADDR_TYPE_SLAVE, i);
2407 - /* no more entries for port _i_ */
2408 - /* pr_debug("erom: slave port %d "
2409 - * "has %d descriptors\n", i, j); */
2412 - if (i == 0 && j == 0)
2420 - /* get & parse master wrappers */
2421 - for (i = 0; i < wrappers[0]; i++) {
2422 - for (j = 0; ; j++) {
2423 - tmp = bcma_erom_get_addr_desc(bus, &eromptr,
2424 - SCAN_ADDR_TYPE_MWRAP, i);
2426 - /* no more entries for port _i_ */
2427 - /* pr_debug("erom: master wrapper %d "
2428 - * "has %d descriptors\n", i, j); */
2431 - if (i == 0 && j == 0)
2436 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
2437 + struct bcma_device_id *match,
2438 + struct bcma_device *core)
2441 + u32 __iomem *eromptr, *eromend;
2443 - /* get & parse slave wrappers */
2444 - for (i = 0; i < wrappers[1]; i++) {
2445 - u8 hack = (ports[1] == 1) ? 0 : 1;
2446 - for (j = 0; ; j++) {
2447 - tmp = bcma_erom_get_addr_desc(bus, &eromptr,
2448 - SCAN_ADDR_TYPE_SWRAP, i + hack);
2450 - /* no more entries for port _i_ */
2451 - /* pr_debug("erom: master wrapper %d "
2452 - * has %d descriptors\n", i, j); */
2455 - if (wrappers[0] == 0 && !i && !j)
2460 + int err = -ENODEV;
2463 + erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
2464 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
2465 + eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
2469 + eromptr = bus->mmio;
2472 + eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
2474 + bcma_scan_switch_core(bus, erombase);
2476 + while (eromptr < eromend) {
2477 + memset(core, 0, sizeof(*core));
2478 + INIT_LIST_HEAD(&core->list);
2481 + err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
2482 + if (err == -ENODEV) {
2485 + } else if (err == -ENXIO)
2487 + else if (err == -ESPIPE)
2492 + core->core_index = core_num++;
2494 pr_info("Core %d found: %s "
2495 "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
2496 - bus->nr_cores, bcma_device_name(&core->id),
2497 + core->core_index, bcma_device_name(&core->id),
2498 core->id.manuf, core->id.id, core->id.rev,
2501 - core->core_index = bus->nr_cores++;
2502 list_add(&core->list, &bus->cores);
2511 + if (bus->hosttype == BCMA_HOSTTYPE_SOC)
2516 --- a/drivers/bcma/sprom.c
2517 +++ b/drivers/bcma/sprom.c
2519 * Broadcom specific AMBA
2522 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
2524 * Licensed under the GNU/GPL. See COPYING for details.
2528 #include <linux/dma-mapping.h>
2529 #include <linux/slab.h>
2531 -#define SPOFF(offset) ((offset) / sizeof(u16))
2532 +static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out);
2535 + * bcma_arch_register_fallback_sprom - Registers a method providing a
2536 + * fallback SPROM if no SPROM is found.
2538 + * @sprom_callback: The callback function.
2540 + * With this function the architecture implementation may register a
2541 + * callback handler which fills the SPROM data structure. The fallback is
2542 + * used for PCI based BCMA devices, where no valid SPROM can be found
2543 + * in the shadow registers and to provide the SPROM for SoCs where BCMA is
2544 + * to controll the system bus.
2546 + * This function is useful for weird architectures that have a half-assed
2547 + * BCMA device hardwired to their PCI bus.
2549 + * This function is available for architecture code, only. So it is not
2552 +int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus,
2553 + struct ssb_sprom *out))
2555 + if (get_fallback_sprom)
2557 + get_fallback_sprom = sprom_callback;
2562 +static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus,
2563 + struct ssb_sprom *out)
2567 + if (!get_fallback_sprom) {
2572 + err = get_fallback_sprom(bus, out);
2576 + pr_debug("Using SPROM revision %d provided by"
2577 + " platform.\n", bus->sprom.revision);
2580 + pr_warn("Using fallback SPROM failed (err %d)\n", err);
2584 /**************************************************
2586 @@ -124,41 +176,268 @@ static int bcma_sprom_valid(const u16 *s
2588 **************************************************/
2590 +#define SPOFF(offset) ((offset) / sizeof(u16))
2592 +#define SPEX(_field, _offset, _mask, _shift) \
2593 + bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift))
2595 static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
2600 + u16 pwr_info_offset[] = {
2601 + SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
2602 + SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
2604 + BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
2605 + ARRAY_SIZE(bus->sprom.core_pwr_info));
2607 + bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
2608 + SSB_SPROM_REVISION_REV;
2610 for (i = 0; i < 3; i++) {
2611 v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
2612 *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
2615 + SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0);
2617 + SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0,
2618 + SSB_SPROM4_TXPID2G0_SHIFT);
2619 + SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G1,
2620 + SSB_SPROM4_TXPID2G1_SHIFT);
2621 + SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G2,
2622 + SSB_SPROM4_TXPID2G2_SHIFT);
2623 + SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G3,
2624 + SSB_SPROM4_TXPID2G3_SHIFT);
2626 + SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL0,
2627 + SSB_SPROM4_TXPID5GL0_SHIFT);
2628 + SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL1,
2629 + SSB_SPROM4_TXPID5GL1_SHIFT);
2630 + SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL2,
2631 + SSB_SPROM4_TXPID5GL2_SHIFT);
2632 + SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL3,
2633 + SSB_SPROM4_TXPID5GL3_SHIFT);
2635 + SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G0,
2636 + SSB_SPROM4_TXPID5G0_SHIFT);
2637 + SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G1,
2638 + SSB_SPROM4_TXPID5G1_SHIFT);
2639 + SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G2,
2640 + SSB_SPROM4_TXPID5G2_SHIFT);
2641 + SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G3,
2642 + SSB_SPROM4_TXPID5G3_SHIFT);
2644 + SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH0,
2645 + SSB_SPROM4_TXPID5GH0_SHIFT);
2646 + SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH1,
2647 + SSB_SPROM4_TXPID5GH1_SHIFT);
2648 + SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH2,
2649 + SSB_SPROM4_TXPID5GH2_SHIFT);
2650 + SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH3,
2651 + SSB_SPROM4_TXPID5GH3_SHIFT);
2653 + SPEX(boardflags_lo, SSB_SPROM8_BFLLO, ~0, 0);
2654 + SPEX(boardflags_hi, SSB_SPROM8_BFLHI, ~0, 0);
2655 + SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0);
2656 + SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0);
2658 + SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0);
2660 + /* Extract cores power info info */
2661 + for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
2662 + o = pwr_info_offset[i];
2663 + SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
2664 + SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
2665 + SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
2666 + SSB_SPROM8_2G_MAXP, 0);
2668 + SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
2669 + SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
2670 + SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
2672 + SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
2673 + SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
2674 + SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
2675 + SSB_SPROM8_5G_MAXP, 0);
2676 + SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
2677 + SSB_SPROM8_5GH_MAXP, 0);
2678 + SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
2679 + SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
2681 + SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
2682 + SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
2683 + SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
2684 + SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
2685 + SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
2686 + SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
2687 + SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
2688 + SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
2689 + SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
2692 + SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS,
2693 + SSB_SROM8_FEM_TSSIPOS_SHIFT);
2694 + SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN,
2695 + SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
2696 + SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_PDET_RANGE,
2697 + SSB_SROM8_FEM_PDET_RANGE_SHIFT);
2698 + SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TR_ISO,
2699 + SSB_SROM8_FEM_TR_ISO_SHIFT);
2700 + SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_ANTSWLUT,
2701 + SSB_SROM8_FEM_ANTSWLUT_SHIFT);
2703 + SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TSSIPOS,
2704 + SSB_SROM8_FEM_TSSIPOS_SHIFT);
2705 + SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_EXTPA_GAIN,
2706 + SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
2707 + SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_PDET_RANGE,
2708 + SSB_SROM8_FEM_PDET_RANGE_SHIFT);
2709 + SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TR_ISO,
2710 + SSB_SROM8_FEM_TR_ISO_SHIFT);
2711 + SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT,
2712 + SSB_SROM8_FEM_ANTSWLUT_SHIFT);
2716 + * Indicates the presence of external SPROM.
2718 +static bool bcma_sprom_ext_available(struct bcma_bus *bus)
2724 + if (bus->drv_cc.core->id.rev >= 31) {
2725 + if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
2728 + srom_control = bcma_read32(bus->drv_cc.core,
2729 + BCMA_CC_SROM_CONTROL);
2730 + return srom_control & BCMA_CC_SROM_CONTROL_PRESENT;
2733 + /* older chipcommon revisions use chip status register */
2734 + chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
2735 + switch (bus->chipinfo.id) {
2737 + present_mask = BCMA_CC_CHIPST_4313_SPROM_PRESENT;
2741 + present_mask = BCMA_CC_CHIPST_4331_SPROM_PRESENT;
2748 + return chip_status & present_mask;
2752 + * Indicates that on-chip OTP memory is present and enabled.
2754 +static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
2760 + chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
2761 + switch (bus->chipinfo.id) {
2763 + present = chip_status & BCMA_CC_CHIPST_4313_OTP_PRESENT;
2767 + present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
2772 + /* for these chips OTP is always available */
2782 + otpsize = bus->drv_cc.capabilities & BCMA_CC_CAP_OTPS;
2783 + otpsize >>= BCMA_CC_CAP_OTPS_SHIFT;
2786 + return otpsize != 0;
2790 + * Verify OTP is filled and determine the byte
2791 + * offset where SPROM data is located.
2793 + * On error, returns 0; byte offset otherwise.
2795 +static int bcma_sprom_onchip_offset(struct bcma_bus *bus)
2797 + struct bcma_device *cc = bus->drv_cc.core;
2800 + /* verify OTP status */
2801 + if ((bcma_read32(cc, BCMA_CC_OTPS) & BCMA_CC_OTPS_GU_PROG_HW) == 0)
2804 + /* obtain bit offset from otplayout register */
2805 + offset = (bcma_read32(cc, BCMA_CC_OTPL) & BCMA_CC_OTPL_GURGN_OFFSET);
2806 + return BCMA_CC_SPROM + (offset >> 3);
2809 int bcma_sprom_get(struct bcma_bus *bus)
2812 + u16 offset = BCMA_CC_SPROM;
2816 if (!bus->drv_cc.core)
2819 - if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
2821 + if (!bcma_sprom_ext_available(bus)) {
2823 + * External SPROM takes precedence so check
2824 + * on-chip OTP only when no external SPROM
2827 + if (bcma_sprom_onchip_available(bus)) {
2828 + /* determine offset */
2829 + offset = bcma_sprom_onchip_offset(bus);
2833 + * Maybe there is no SPROM on the device?
2834 + * Now we ask the arch code if there is some sprom
2835 + * available for this device in some other storage.
2837 + err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
2842 sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
2847 - /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
2848 - * According to brcm80211 this applies to cards with PCIe rev >= 6
2849 - * TODO: understand this condition and use it */
2850 - offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM :
2851 - BCMA_CC_SPROM_PCIE6;
2852 + if (bus->chipinfo.id == 0x4331)
2853 + bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
2855 + pr_debug("SPROM offset 0x%x\n", offset);
2856 bcma_sprom_read(bus, offset, sprom);
2858 + if (bus->chipinfo.id == 0x4331)
2859 + bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
2861 err = bcma_sprom_valid(sprom);
2864 --- a/include/linux/bcma/bcma.h
2865 +++ b/include/linux/bcma/bcma.h
2868 #include <linux/bcma/bcma_driver_chipcommon.h>
2869 #include <linux/bcma/bcma_driver_pci.h>
2870 +#include <linux/bcma/bcma_driver_mips.h>
2871 #include <linux/ssb/ssb.h> /* SPROM sharing */
2873 #include "bcma_regs.h"
2874 @@ -14,9 +15,9 @@ struct bcma_device;
2877 enum bcma_hosttype {
2878 - BCMA_HOSTTYPE_NONE,
2881 + BCMA_HOSTTYPE_SOC,
2884 struct bcma_chipinfo {
2885 @@ -130,14 +131,19 @@ struct bcma_device {
2888 struct device *dma_dev;
2891 bool dev_registered;
2899 + void __iomem *io_addr;
2900 + void __iomem *io_wrap;
2903 struct list_head list;
2905 @@ -157,7 +163,7 @@ struct bcma_driver {
2907 int (*probe)(struct bcma_device *dev);
2908 void (*remove)(struct bcma_device *dev);
2909 - int (*suspend)(struct bcma_device *dev, pm_message_t state);
2910 + int (*suspend)(struct bcma_device *dev);
2911 int (*resume)(struct bcma_device *dev);
2912 void (*shutdown)(struct bcma_device *dev);
2914 @@ -165,12 +171,17 @@ struct bcma_driver {
2917 int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
2918 -static inline int bcma_driver_register(struct bcma_driver *drv)
2920 - return __bcma_driver_register(drv, THIS_MODULE);
2922 +#define bcma_driver_register(drv) \
2923 + __bcma_driver_register(drv, THIS_MODULE)
2925 extern void bcma_driver_unregister(struct bcma_driver *drv);
2927 +/* Set a fallback SPROM.
2928 + * See kdoc at the function definition for complete documentation. */
2929 +extern int bcma_arch_register_fallback_sprom(
2930 + int (*sprom_callback)(struct bcma_bus *bus,
2931 + struct ssb_sprom *out));
2934 /* The MMIO area. */
2936 @@ -190,71 +201,96 @@ struct bcma_bus {
2937 struct bcma_device *mapped_core;
2938 struct list_head cores;
2943 struct bcma_drv_cc drv_cc;
2944 struct bcma_drv_pci drv_pci;
2945 + struct bcma_drv_mips drv_mips;
2947 /* We decided to share SPROM struct with SSB as long as we do not need
2948 * any hacks for BCMA. This simplifies drivers code. */
2949 struct ssb_sprom sprom;
2952 -extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
2953 +static inline u32 bcma_read8(struct bcma_device *core, u16 offset)
2955 return core->bus->ops->read8(core, offset);
2957 -extern inline u32 bcma_read16(struct bcma_device *core, u16 offset)
2958 +static inline u32 bcma_read16(struct bcma_device *core, u16 offset)
2960 return core->bus->ops->read16(core, offset);
2962 -extern inline u32 bcma_read32(struct bcma_device *core, u16 offset)
2963 +static inline u32 bcma_read32(struct bcma_device *core, u16 offset)
2965 return core->bus->ops->read32(core, offset);
2969 void bcma_write8(struct bcma_device *core, u16 offset, u32 value)
2971 core->bus->ops->write8(core, offset, value);
2975 void bcma_write16(struct bcma_device *core, u16 offset, u32 value)
2977 core->bus->ops->write16(core, offset, value);
2981 void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
2983 core->bus->ops->write32(core, offset, value);
2985 #ifdef CONFIG_BCMA_BLOCKIO
2986 -extern inline void bcma_block_read(struct bcma_device *core, void *buffer,
2987 +static inline void bcma_block_read(struct bcma_device *core, void *buffer,
2988 size_t count, u16 offset, u8 reg_width)
2990 core->bus->ops->block_read(core, buffer, count, offset, reg_width);
2992 -extern inline void bcma_block_write(struct bcma_device *core, const void *buffer,
2993 - size_t count, u16 offset, u8 reg_width)
2994 +static inline void bcma_block_write(struct bcma_device *core,
2995 + const void *buffer, size_t count,
2996 + u16 offset, u8 reg_width)
2998 core->bus->ops->block_write(core, buffer, count, offset, reg_width);
3001 -extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
3002 +static inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
3004 return core->bus->ops->aread32(core, offset);
3008 void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
3010 core->bus->ops->awrite32(core, offset, value);
3013 -#define bcma_mask32(cc, offset, mask) \
3014 - bcma_write32(cc, offset, bcma_read32(cc, offset) & (mask))
3015 -#define bcma_set32(cc, offset, set) \
3016 - bcma_write32(cc, offset, bcma_read32(cc, offset) | (set))
3017 -#define bcma_maskset32(cc, offset, mask, set) \
3018 - bcma_write32(cc, offset, (bcma_read32(cc, offset) & (mask)) | (set))
3019 +static inline void bcma_mask32(struct bcma_device *cc, u16 offset, u32 mask)
3021 + bcma_write32(cc, offset, bcma_read32(cc, offset) & mask);
3023 +static inline void bcma_set32(struct bcma_device *cc, u16 offset, u32 set)
3025 + bcma_write32(cc, offset, bcma_read32(cc, offset) | set);
3027 +static inline void bcma_maskset32(struct bcma_device *cc,
3028 + u16 offset, u32 mask, u32 set)
3030 + bcma_write32(cc, offset, (bcma_read32(cc, offset) & mask) | set);
3032 +static inline void bcma_mask16(struct bcma_device *cc, u16 offset, u16 mask)
3034 + bcma_write16(cc, offset, bcma_read16(cc, offset) & mask);
3036 +static inline void bcma_set16(struct bcma_device *cc, u16 offset, u16 set)
3038 + bcma_write16(cc, offset, bcma_read16(cc, offset) | set);
3040 +static inline void bcma_maskset16(struct bcma_device *cc,
3041 + u16 offset, u16 mask, u16 set)
3043 + bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
3046 +extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid);
3047 extern bool bcma_core_is_enabled(struct bcma_device *core);
3048 extern void bcma_core_disable(struct bcma_device *core, u32 flags);
3049 extern int bcma_core_enable(struct bcma_device *core, u32 flags);
3050 --- a/include/linux/bcma/bcma_driver_chipcommon.h
3051 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
3053 #define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */
3054 #define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */
3055 #define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */
3056 +#define BCMA_CC_FLASHT_NFLASH 0x00000200
3057 #define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */
3058 #define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */
3059 #define BCMA_PLLTYPE_NONE 0x00000000
3061 #define BCMA_CC_OTPS_HW_PROTECT 0x00000001
3062 #define BCMA_CC_OTPS_SW_PROTECT 0x00000002
3063 #define BCMA_CC_OTPS_CID_PROTECT 0x00000004
3064 +#define BCMA_CC_OTPS_GU_PROG_IND 0x00000F00 /* General Use programmed indication */
3065 +#define BCMA_CC_OTPS_GU_PROG_IND_SHIFT 8
3066 +#define BCMA_CC_OTPS_GU_PROG_HW 0x00000100 /* HW region programmed */
3067 #define BCMA_CC_OTPC 0x0014 /* OTP control */
3068 #define BCMA_CC_OTPC_RECWAIT 0xFF000000
3069 #define BCMA_CC_OTPC_PROGWAIT 0x00FFFF00
3071 #define BCMA_CC_OTPP_READ 0x40000000
3072 #define BCMA_CC_OTPP_START 0x80000000
3073 #define BCMA_CC_OTPP_BUSY 0x80000000
3074 +#define BCMA_CC_OTPL 0x001C /* OTP layout */
3075 +#define BCMA_CC_OTPL_GURGN_OFFSET 0x00000FFF /* offset of general use region */
3076 #define BCMA_CC_IRQSTAT 0x0020
3077 #define BCMA_CC_IRQMASK 0x0024
3078 #define BCMA_CC_IRQ_GPIO 0x00000001 /* gpio intr */
3080 #define BCMA_CC_IRQ_WDRESET 0x80000000 /* watchdog reset occurred */
3081 #define BCMA_CC_CHIPCTL 0x0028 /* Rev >= 11 only */
3082 #define BCMA_CC_CHIPSTAT 0x002C /* Rev >= 11 only */
3083 +#define BCMA_CC_CHIPST_4313_SPROM_PRESENT 1
3084 +#define BCMA_CC_CHIPST_4313_OTP_PRESENT 2
3085 +#define BCMA_CC_CHIPST_4331_SPROM_PRESENT 2
3086 +#define BCMA_CC_CHIPST_4331_OTP_PRESENT 4
3087 #define BCMA_CC_JCMD 0x0030 /* Rev >= 10 only */
3088 #define BCMA_CC_JCMD_START 0x80000000
3089 #define BCMA_CC_JCMD_BUSY 0x80000000
3090 @@ -178,7 +188,24 @@
3091 #define BCMA_CC_PROG_CFG 0x0120
3092 #define BCMA_CC_PROG_WAITCNT 0x0124
3093 #define BCMA_CC_FLASH_CFG 0x0128
3094 +#define BCMA_CC_FLASH_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */
3095 #define BCMA_CC_FLASH_WAITCNT 0x012C
3096 +#define BCMA_CC_SROM_CONTROL 0x0190
3097 +#define BCMA_CC_SROM_CONTROL_START 0x80000000
3098 +#define BCMA_CC_SROM_CONTROL_BUSY 0x80000000
3099 +#define BCMA_CC_SROM_CONTROL_OPCODE 0x60000000
3100 +#define BCMA_CC_SROM_CONTROL_OP_READ 0x00000000
3101 +#define BCMA_CC_SROM_CONTROL_OP_WRITE 0x20000000
3102 +#define BCMA_CC_SROM_CONTROL_OP_WRDIS 0x40000000
3103 +#define BCMA_CC_SROM_CONTROL_OP_WREN 0x60000000
3104 +#define BCMA_CC_SROM_CONTROL_OTPSEL 0x00000010
3105 +#define BCMA_CC_SROM_CONTROL_LOCK 0x00000008
3106 +#define BCMA_CC_SROM_CONTROL_SIZE_MASK 0x00000006
3107 +#define BCMA_CC_SROM_CONTROL_SIZE_1K 0x00000000
3108 +#define BCMA_CC_SROM_CONTROL_SIZE_4K 0x00000002
3109 +#define BCMA_CC_SROM_CONTROL_SIZE_16K 0x00000004
3110 +#define BCMA_CC_SROM_CONTROL_SIZE_SHIFT 1
3111 +#define BCMA_CC_SROM_CONTROL_PRESENT 0x00000001
3112 /* 0x1E0 is defined as shared BCMA_CLKCTLST */
3113 #define BCMA_CC_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */
3114 #define BCMA_CC_UART0_DATA 0x0300
3116 #define BCMA_CC_PMU_CTL 0x0600 /* PMU control */
3117 #define BCMA_CC_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */
3118 #define BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16
3119 +#define BCMA_CC_PMU_CTL_PLL_UPD 0x00000400
3120 #define BCMA_CC_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */
3121 #define BCMA_CC_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */
3122 #define BCMA_CC_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */
3123 @@ -237,7 +265,64 @@
3124 #define BCMA_CC_PLLCTL_ADDR 0x0660
3125 #define BCMA_CC_PLLCTL_DATA 0x0664
3126 #define BCMA_CC_SPROM 0x0800 /* SPROM beginning */
3127 -#define BCMA_CC_SPROM_PCIE6 0x0830 /* SPROM beginning on PCIe rev >= 6 */
3129 +/* Divider allocation in 4716/47162/5356 */
3130 +#define BCMA_CC_PMU5_MAINPLL_CPU 1
3131 +#define BCMA_CC_PMU5_MAINPLL_MEM 2
3132 +#define BCMA_CC_PMU5_MAINPLL_SSB 3
3134 +/* PLL usage in 4716/47162 */
3135 +#define BCMA_CC_PMU4716_MAINPLL_PLL0 12
3137 +/* PLL usage in 5356/5357 */
3138 +#define BCMA_CC_PMU5356_MAINPLL_PLL0 0
3139 +#define BCMA_CC_PMU5357_MAINPLL_PLL0 0
3142 +#define BCMA_CC_PMU4706_MAINPLL_PLL0 0
3144 +/* ALP clock on pre-PMU chips */
3145 +#define BCMA_CC_PMU_ALP_CLOCK 20000000
3146 +/* HT clock for systems with PMU-enabled chipcommon */
3147 +#define BCMA_CC_PMU_HT_CLOCK 80000000
3149 +/* PMU rev 5 (& 6) */
3150 +#define BCMA_CC_PPL_P1P2_OFF 0
3151 +#define BCMA_CC_PPL_P1_MASK 0x0f000000
3152 +#define BCMA_CC_PPL_P1_SHIFT 24
3153 +#define BCMA_CC_PPL_P2_MASK 0x00f00000
3154 +#define BCMA_CC_PPL_P2_SHIFT 20
3155 +#define BCMA_CC_PPL_M14_OFF 1
3156 +#define BCMA_CC_PPL_MDIV_MASK 0x000000ff
3157 +#define BCMA_CC_PPL_MDIV_WIDTH 8
3158 +#define BCMA_CC_PPL_NM5_OFF 2
3159 +#define BCMA_CC_PPL_NDIV_MASK 0xfff00000
3160 +#define BCMA_CC_PPL_NDIV_SHIFT 20
3161 +#define BCMA_CC_PPL_FMAB_OFF 3
3162 +#define BCMA_CC_PPL_MRAT_MASK 0xf0000000
3163 +#define BCMA_CC_PPL_MRAT_SHIFT 28
3164 +#define BCMA_CC_PPL_ABRAT_MASK 0x08000000
3165 +#define BCMA_CC_PPL_ABRAT_SHIFT 27
3166 +#define BCMA_CC_PPL_FDIV_MASK 0x07ffffff
3167 +#define BCMA_CC_PPL_PLLCTL_OFF 4
3168 +#define BCMA_CC_PPL_PCHI_OFF 5
3169 +#define BCMA_CC_PPL_PCHI_MASK 0x0000003f
3171 +/* BCM4331 ChipControl numbers. */
3172 +#define BCMA_CHIPCTL_4331_BT_COEXIST BIT(0) /* 0 disable */
3173 +#define BCMA_CHIPCTL_4331_SECI BIT(1) /* 0 SECI is disabled (JATG functional) */
3174 +#define BCMA_CHIPCTL_4331_EXT_LNA BIT(2) /* 0 disable */
3175 +#define BCMA_CHIPCTL_4331_SPROM_GPIO13_15 BIT(3) /* sprom/gpio13-15 mux */
3176 +#define BCMA_CHIPCTL_4331_EXTPA_EN BIT(4) /* 0 ext pa disable, 1 ext pa enabled */
3177 +#define BCMA_CHIPCTL_4331_GPIOCLK_ON_SPROMCS BIT(5) /* set drive out GPIO_CLK on sprom_cs pin */
3178 +#define BCMA_CHIPCTL_4331_PCIE_MDIO_ON_SPROMCS BIT(6) /* use sprom_cs pin as PCIE mdio interface */
3179 +#define BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5 BIT(7) /* aband extpa will be at gpio2/5 and sprom_dout */
3180 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXCLKEN BIT(8) /* override core control on pipe_AuxClkEnable */
3181 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN BIT(9) /* override core control on pipe_AuxPowerDown */
3182 +#define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN BIT(10) /* pcie_auxclkenable */
3183 +#define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN BIT(11) /* pcie_pipe_pllpowerdown */
3184 +#define BCMA_CHIPCTL_4331_BT_SHD0_ON_GPIO4 BIT(16) /* enable bt_shd0 at gpio4 */
3185 +#define BCMA_CHIPCTL_4331_BT_SHD1_ON_GPIO5 BIT(17) /* enable bt_shd1 at gpio5 */
3187 /* Data for the PMU, if available.
3188 * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
3189 @@ -247,14 +332,37 @@ struct bcma_chipcommon_pmu {
3190 u32 crystalfreq; /* The active crystal frequency (in kHz) */
3193 +#ifdef CONFIG_BCMA_DRIVER_MIPS
3194 +struct bcma_pflash {
3200 +struct bcma_serial_port {
3202 + unsigned long clockspeed;
3204 + unsigned int baud_base;
3205 + unsigned int reg_shift;
3207 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
3209 struct bcma_drv_cc {
3210 struct bcma_device *core;
3213 u32 capabilities_ext;
3215 /* Fast Powerup Delay constant */
3216 u16 fast_pwrup_delay;
3217 struct bcma_chipcommon_pmu pmu;
3218 +#ifdef CONFIG_BCMA_DRIVER_MIPS
3219 + struct bcma_pflash pflash;
3221 + int nr_serial_ports;
3222 + struct bcma_serial_port serial_ports[4];
3223 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
3226 /* Register access */
3227 @@ -275,6 +383,8 @@ extern void bcma_core_chipcommon_init(st
3228 extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
3229 extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
3231 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
3233 extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
3236 @@ -293,4 +403,13 @@ u32 bcma_chipco_gpio_polarity(struct bcm
3238 extern void bcma_pmu_init(struct bcma_drv_cc *cc);
3240 +extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset,
3242 +extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset,
3243 + u32 mask, u32 set);
3244 +extern void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
3245 + u32 offset, u32 mask, u32 set);
3246 +extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc,
3247 + u32 offset, u32 mask, u32 set);
3249 #endif /* LINUX_BCMA_DRIVER_CC_H_ */
3251 +++ b/include/linux/bcma/bcma_driver_mips.h
3253 +#ifndef LINUX_BCMA_DRIVER_MIPS_H_
3254 +#define LINUX_BCMA_DRIVER_MIPS_H_
3256 +#define BCMA_MIPS_IPSFLAG 0x0F08
3257 +/* which sbflags get routed to mips interrupt 1 */
3258 +#define BCMA_MIPS_IPSFLAG_IRQ1 0x0000003F
3259 +#define BCMA_MIPS_IPSFLAG_IRQ1_SHIFT 0
3260 +/* which sbflags get routed to mips interrupt 2 */
3261 +#define BCMA_MIPS_IPSFLAG_IRQ2 0x00003F00
3262 +#define BCMA_MIPS_IPSFLAG_IRQ2_SHIFT 8
3263 +/* which sbflags get routed to mips interrupt 3 */
3264 +#define BCMA_MIPS_IPSFLAG_IRQ3 0x003F0000
3265 +#define BCMA_MIPS_IPSFLAG_IRQ3_SHIFT 16
3266 +/* which sbflags get routed to mips interrupt 4 */
3267 +#define BCMA_MIPS_IPSFLAG_IRQ4 0x3F000000
3268 +#define BCMA_MIPS_IPSFLAG_IRQ4_SHIFT 24
3270 +/* MIPS 74K core registers */
3271 +#define BCMA_MIPS_MIPS74K_CORECTL 0x0000
3272 +#define BCMA_MIPS_MIPS74K_EXCEPTBASE 0x0004
3273 +#define BCMA_MIPS_MIPS74K_BIST 0x000C
3274 +#define BCMA_MIPS_MIPS74K_INTMASK_INT0 0x0014
3275 +#define BCMA_MIPS_MIPS74K_INTMASK(int) \
3276 + ((int) * 4 + BCMA_MIPS_MIPS74K_INTMASK_INT0)
3277 +#define BCMA_MIPS_MIPS74K_NMIMASK 0x002C
3278 +#define BCMA_MIPS_MIPS74K_GPIOSEL 0x0040
3279 +#define BCMA_MIPS_MIPS74K_GPIOOUT 0x0044
3280 +#define BCMA_MIPS_MIPS74K_GPIOEN 0x0048
3281 +#define BCMA_MIPS_MIPS74K_CLKCTLST 0x01E0
3283 +#define BCMA_MIPS_OOBSELOUTA30 0x100
3285 +struct bcma_device;
3287 +struct bcma_drv_mips {
3288 + struct bcma_device *core;
3290 + unsigned int assigned_irqs;
3293 +#ifdef CONFIG_BCMA_DRIVER_MIPS
3294 +extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
3296 +static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { }
3299 +extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
3301 +extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
3303 +#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
3304 --- a/include/linux/bcma/bcma_driver_pci.h
3305 +++ b/include/linux/bcma/bcma_driver_pci.h
3306 @@ -53,6 +53,35 @@ struct pci_dev;
3307 #define BCMA_CORE_PCI_SBTOPCI1_MASK 0xFC000000
3308 #define BCMA_CORE_PCI_SBTOPCI2 0x0108 /* Backplane to PCI translation 2 (sbtopci2) */
3309 #define BCMA_CORE_PCI_SBTOPCI2_MASK 0xC0000000
3310 +#define BCMA_CORE_PCI_CONFIG_ADDR 0x0120 /* pcie config space access */
3311 +#define BCMA_CORE_PCI_CONFIG_DATA 0x0124 /* pcie config space access */
3312 +#define BCMA_CORE_PCI_MDIO_CONTROL 0x0128 /* controls the mdio access */
3313 +#define BCMA_CORE_PCI_MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */
3314 +#define BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL 0x2
3315 +#define BCMA_CORE_PCI_MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */
3316 +#define BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE 0x100 /* Tranaction complete */
3317 +#define BCMA_CORE_PCI_MDIO_DATA 0x012c /* Data to the mdio access */
3318 +#define BCMA_CORE_PCI_MDIODATA_MASK 0x0000ffff /* data 2 bytes */
3319 +#define BCMA_CORE_PCI_MDIODATA_TA 0x00020000 /* Turnaround */
3320 +#define BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD 18 /* Regaddr shift (rev < 10) */
3321 +#define BCMA_CORE_PCI_MDIODATA_REGADDR_MASK_OLD 0x003c0000 /* Regaddr Mask (rev < 10) */
3322 +#define BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD 22 /* Physmedia devaddr shift (rev < 10) */
3323 +#define BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK_OLD 0x0fc00000 /* Physmedia devaddr Mask (rev < 10) */
3324 +#define BCMA_CORE_PCI_MDIODATA_REGADDR_SHF 18 /* Regaddr shift */
3325 +#define BCMA_CORE_PCI_MDIODATA_REGADDR_MASK 0x007c0000 /* Regaddr Mask */
3326 +#define BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF 23 /* Physmedia devaddr shift */
3327 +#define BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK 0x0f800000 /* Physmedia devaddr Mask */
3328 +#define BCMA_CORE_PCI_MDIODATA_WRITE 0x10000000 /* write Transaction */
3329 +#define BCMA_CORE_PCI_MDIODATA_READ 0x20000000 /* Read Transaction */
3330 +#define BCMA_CORE_PCI_MDIODATA_START 0x40000000 /* start of Transaction */
3331 +#define BCMA_CORE_PCI_MDIODATA_DEV_ADDR 0x0 /* dev address for serdes */
3332 +#define BCMA_CORE_PCI_MDIODATA_BLK_ADDR 0x1F /* blk address for serdes */
3333 +#define BCMA_CORE_PCI_MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */
3334 +#define BCMA_CORE_PCI_MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */
3335 +#define BCMA_CORE_PCI_MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */
3336 +#define BCMA_CORE_PCI_PCIEIND_ADDR 0x0130 /* indirect access to the internal register */
3337 +#define BCMA_CORE_PCI_PCIEIND_DATA 0x0134 /* Data to/from the internal regsiter */
3338 +#define BCMA_CORE_PCI_CLKREQENCTRL 0x0138 /* >= rev 6, Clkreq rdma control */
3339 #define BCMA_CORE_PCI_PCICFG0 0x0400 /* PCI config space 0 (rev >= 8) */
3340 #define BCMA_CORE_PCI_PCICFG1 0x0500 /* PCI config space 1 (rev >= 8) */
3341 #define BCMA_CORE_PCI_PCICFG2 0x0600 /* PCI config space 2 (rev >= 8) */
3342 @@ -72,20 +101,114 @@ struct pci_dev;
3343 #define BCMA_CORE_PCI_SBTOPCI_RC_READL 0x00000010 /* Memory read line */
3344 #define BCMA_CORE_PCI_SBTOPCI_RC_READM 0x00000020 /* Memory read multiple */
3346 +/* PCIE protocol PHY diagnostic registers */
3347 +#define BCMA_CORE_PCI_PLP_MODEREG 0x200 /* Mode */
3348 +#define BCMA_CORE_PCI_PLP_STATUSREG 0x204 /* Status */
3349 +#define BCMA_CORE_PCI_PLP_POLARITYINV_STAT 0x10 /* Status reg PCIE_PLP_STATUSREG */
3350 +#define BCMA_CORE_PCI_PLP_LTSSMCTRLREG 0x208 /* LTSSM control */
3351 +#define BCMA_CORE_PCI_PLP_LTLINKNUMREG 0x20c /* Link Training Link number */
3352 +#define BCMA_CORE_PCI_PLP_LTLANENUMREG 0x210 /* Link Training Lane number */
3353 +#define BCMA_CORE_PCI_PLP_LTNFTSREG 0x214 /* Link Training N_FTS */
3354 +#define BCMA_CORE_PCI_PLP_ATTNREG 0x218 /* Attention */
3355 +#define BCMA_CORE_PCI_PLP_ATTNMASKREG 0x21C /* Attention Mask */
3356 +#define BCMA_CORE_PCI_PLP_RXERRCTR 0x220 /* Rx Error */
3357 +#define BCMA_CORE_PCI_PLP_RXFRMERRCTR 0x224 /* Rx Framing Error */
3358 +#define BCMA_CORE_PCI_PLP_RXERRTHRESHREG 0x228 /* Rx Error threshold */
3359 +#define BCMA_CORE_PCI_PLP_TESTCTRLREG 0x22C /* Test Control reg */
3360 +#define BCMA_CORE_PCI_PLP_SERDESCTRLOVRDREG 0x230 /* SERDES Control Override */
3361 +#define BCMA_CORE_PCI_PLP_TIMINGOVRDREG 0x234 /* Timing param override */
3362 +#define BCMA_CORE_PCI_PLP_RXTXSMDIAGREG 0x238 /* RXTX State Machine Diag */
3363 +#define BCMA_CORE_PCI_PLP_LTSSMDIAGREG 0x23C /* LTSSM State Machine Diag */
3365 +/* PCIE protocol DLLP diagnostic registers */
3366 +#define BCMA_CORE_PCI_DLLP_LCREG 0x100 /* Link Control */
3367 +#define BCMA_CORE_PCI_DLLP_LSREG 0x104 /* Link Status */
3368 +#define BCMA_CORE_PCI_DLLP_LAREG 0x108 /* Link Attention */
3369 +#define BCMA_CORE_PCI_DLLP_LSREG_LINKUP (1 << 16)
3370 +#define BCMA_CORE_PCI_DLLP_LAMASKREG 0x10C /* Link Attention Mask */
3371 +#define BCMA_CORE_PCI_DLLP_NEXTTXSEQNUMREG 0x110 /* Next Tx Seq Num */
3372 +#define BCMA_CORE_PCI_DLLP_ACKEDTXSEQNUMREG 0x114 /* Acked Tx Seq Num */
3373 +#define BCMA_CORE_PCI_DLLP_PURGEDTXSEQNUMREG 0x118 /* Purged Tx Seq Num */
3374 +#define BCMA_CORE_PCI_DLLP_RXSEQNUMREG 0x11C /* Rx Sequence Number */
3375 +#define BCMA_CORE_PCI_DLLP_LRREG 0x120 /* Link Replay */
3376 +#define BCMA_CORE_PCI_DLLP_LACKTOREG 0x124 /* Link Ack Timeout */
3377 +#define BCMA_CORE_PCI_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */
3378 +#define BCMA_CORE_PCI_DLLP_RTRYWPREG 0x12C /* Retry buffer write ptr */
3379 +#define BCMA_CORE_PCI_DLLP_RTRYRPREG 0x130 /* Retry buffer Read ptr */
3380 +#define BCMA_CORE_PCI_DLLP_RTRYPPREG 0x134 /* Retry buffer Purged ptr */
3381 +#define BCMA_CORE_PCI_DLLP_RTRRWREG 0x138 /* Retry buffer Read/Write */
3382 +#define BCMA_CORE_PCI_DLLP_ECTHRESHREG 0x13C /* Error Count Threshold */
3383 +#define BCMA_CORE_PCI_DLLP_TLPERRCTRREG 0x140 /* TLP Error Counter */
3384 +#define BCMA_CORE_PCI_DLLP_ERRCTRREG 0x144 /* Error Counter */
3385 +#define BCMA_CORE_PCI_DLLP_NAKRXCTRREG 0x148 /* NAK Received Counter */
3386 +#define BCMA_CORE_PCI_DLLP_TESTREG 0x14C /* Test */
3387 +#define BCMA_CORE_PCI_DLLP_PKTBIST 0x150 /* Packet BIST */
3388 +#define BCMA_CORE_PCI_DLLP_PCIE11 0x154 /* DLLP PCIE 1.1 reg */
3390 +/* SERDES RX registers */
3391 +#define BCMA_CORE_PCI_SERDES_RX_CTRL 1 /* Rx cntrl */
3392 +#define BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE 0x80 /* rxpolarity_force */
3393 +#define BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY 0x40 /* rxpolarity_value */
3394 +#define BCMA_CORE_PCI_SERDES_RX_TIMER1 2 /* Rx Timer1 */
3395 +#define BCMA_CORE_PCI_SERDES_RX_CDR 6 /* CDR */
3396 +#define BCMA_CORE_PCI_SERDES_RX_CDRBW 7 /* CDR BW */
3398 +/* SERDES PLL registers */
3399 +#define BCMA_CORE_PCI_SERDES_PLL_CTRL 1 /* PLL control reg */
3400 +#define BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN 0x4000 /* bit 14 is FREQDET on */
3402 /* PCIcore specific boardflags */
3403 #define BCMA_CORE_PCI_BFL_NOPCI 0x00000400 /* Board leaves PCI floating */
3405 +/* PCIE Config space accessing MACROS */
3406 +#define BCMA_CORE_PCI_CFG_BUS_SHIFT 24 /* Bus shift */
3407 +#define BCMA_CORE_PCI_CFG_SLOT_SHIFT 19 /* Slot/Device shift */
3408 +#define BCMA_CORE_PCI_CFG_FUN_SHIFT 16 /* Function shift */
3409 +#define BCMA_CORE_PCI_CFG_OFF_SHIFT 0 /* Register shift */
3411 +#define BCMA_CORE_PCI_CFG_BUS_MASK 0xff /* Bus mask */
3412 +#define BCMA_CORE_PCI_CFG_SLOT_MASK 0x1f /* Slot/Device mask */
3413 +#define BCMA_CORE_PCI_CFG_FUN_MASK 7 /* Function mask */
3414 +#define BCMA_CORE_PCI_CFG_OFF_MASK 0xfff /* Register mask */
3416 +/* PCIE Root Capability Register bits (Host mode only) */
3417 +#define BCMA_CORE_PCI_RC_CRS_VISIBILITY 0x0001
3419 +struct bcma_drv_pci;
3421 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
3422 +struct bcma_drv_pci_host {
3423 + struct bcma_drv_pci *pdev;
3425 + u32 host_cfg_addr;
3426 + spinlock_t cfgspace_lock;
3428 + struct pci_controller pci_controller;
3429 + struct pci_ops pci_ops;
3430 + struct resource mem_resource;
3431 + struct resource io_resource;
3435 struct bcma_drv_pci {
3436 struct bcma_device *core;
3440 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
3441 + struct bcma_drv_pci_host *host_controller;
3445 /* Register access */
3446 #define pcicore_read32(pc, offset) bcma_read32((pc)->core, offset)
3447 #define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val)
3449 -extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
3450 +extern void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc);
3451 extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
3452 struct bcma_device *core, bool enable);
3454 +extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
3455 +extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
3457 #endif /* LINUX_BCMA_DRIVER_PCI_H_ */
3458 --- a/include/linux/bcma/bcma_regs.h
3459 +++ b/include/linux/bcma/bcma_regs.h
3461 #define BCMA_PCI_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */
3462 #define BCMA_PCI_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */
3464 +/* SiliconBackplane Address Map.
3465 + * All regions may not exist on all chips.
3467 +#define BCMA_SOC_SDRAM_BASE 0x00000000U /* Physical SDRAM */
3468 +#define BCMA_SOC_PCI_MEM 0x08000000U /* Host Mode sb2pcitranslation0 (64 MB) */
3469 +#define BCMA_SOC_PCI_MEM_SZ (64 * 1024 * 1024)
3470 +#define BCMA_SOC_PCI_CFG 0x0c000000U /* Host Mode sb2pcitranslation1 (64 MB) */
3471 +#define BCMA_SOC_SDRAM_SWAPPED 0x10000000U /* Byteswapped Physical SDRAM */
3472 +#define BCMA_SOC_SDRAM_R2 0x80000000U /* Region 2 for sdram (512 MB) */
3475 +#define BCMA_SOC_PCI_DMA 0x40000000U /* Client Mode sb2pcitranslation2 (1 GB) */
3476 +#define BCMA_SOC_PCI_DMA2 0x80000000U /* Client Mode sb2pcitranslation2 (1 GB) */
3477 +#define BCMA_SOC_PCI_DMA_SZ 0x40000000U /* Client Mode sb2pcitranslation2 size in bytes */
3478 +#define BCMA_SOC_PCIE_DMA_L32 0x00000000U /* PCIE Client Mode sb2pcitranslation2
3479 + * (2 ZettaBytes), low 32 bits
3481 +#define BCMA_SOC_PCIE_DMA_H32 0x80000000U /* PCIE Client Mode sb2pcitranslation2
3482 + * (2 ZettaBytes), high 32 bits
3485 +#define BCMA_SOC_PCI1_MEM 0x40000000U /* Host Mode sb2pcitranslation0 (64 MB) */
3486 +#define BCMA_SOC_PCI1_CFG 0x44000000U /* Host Mode sb2pcitranslation1 (64 MB) */
3487 +#define BCMA_SOC_PCIE1_DMA_H32 0xc0000000U /* PCIE Client Mode sb2pcitranslation2
3488 + * (2 ZettaBytes), high 32 bits
3491 #endif /* LINUX_BCMA_REGS_H_ */
3493 +++ b/include/linux/bcma/bcma_soc.h
3495 +#ifndef LINUX_BCMA_SOC_H_
3496 +#define LINUX_BCMA_SOC_H_
3498 +#include <linux/bcma/bcma.h>
3501 + struct bcma_bus bus;
3502 + struct bcma_device core_cc;
3503 + struct bcma_device core_mips;
3506 +int __init bcma_host_soc_register(struct bcma_soc *soc);
3508 +int bcma_bus_register(struct bcma_bus *bus);
3510 +#endif /* LINUX_BCMA_SOC_H_ */