1 From d3fb63a710e1f04fed2c2703c6dce3531490c451 Mon Sep 17 00:00:00 2001
2 From: Hauke Mehrtens <hauke@hauke-m.de>
3 Date: Mon, 6 Jun 2011 00:07:37 +0200
4 Subject: [PATCH 10/26] bcm47xx: add support for bcma bus
6 This patch add support for the bcma bus. Broadcom uses only Mips 74K
7 CPUs on the new SoC and on the old ons using ssb bus there are no Mips
10 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
12 arch/mips/bcm47xx/Kconfig | 13 ++++++
13 arch/mips/bcm47xx/gpio.c | 22 +++++++++++
14 arch/mips/bcm47xx/nvram.c | 10 +++++
15 arch/mips/bcm47xx/serial.c | 29 ++++++++++++++
16 arch/mips/bcm47xx/setup.c | 53 +++++++++++++++++++++++++-
17 arch/mips/bcm47xx/time.c | 5 ++
18 arch/mips/include/asm/mach-bcm47xx/bcm47xx.h | 8 ++++
19 arch/mips/include/asm/mach-bcm47xx/gpio.h | 41 ++++++++++++++++++++
20 drivers/watchdog/bcm47xx_wdt.c | 11 +++++
21 9 files changed, 190 insertions(+), 2 deletions(-)
23 --- a/arch/mips/bcm47xx/Kconfig
24 +++ b/arch/mips/bcm47xx/Kconfig
25 @@ -15,4 +15,17 @@ config BCM47XX_SSB
27 This will generate an image with support for SSB and MIPS32 R1 instruction set.
30 + bool "BCMA Support for Broadcom BCM47XX"
31 + select SYS_HAS_CPU_MIPS32_R2
33 + select BCMA_HOST_SOC
34 + select BCMA_DRIVER_MIPS
35 + select BCMA_DRIVER_PCI_HOSTMODE if PCI
38 + Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
40 + This will generate an image with support for BCMA and MIPS32 R2 instruction set.
43 --- a/arch/mips/bcm47xx/gpio.c
44 +++ b/arch/mips/bcm47xx/gpio.c
45 @@ -36,6 +36,16 @@ int gpio_request(unsigned gpio, const ch
49 +#ifdef CONFIG_BCM47XX_BCMA
50 + case BCM47XX_BUS_TYPE_BCMA:
51 + if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
54 + if (test_and_set_bit(gpio, gpio_in_use))
62 @@ -57,6 +67,14 @@ void gpio_free(unsigned gpio)
63 clear_bit(gpio, gpio_in_use);
66 +#ifdef CONFIG_BCM47XX_BCMA
67 + case BCM47XX_BUS_TYPE_BCMA:
68 + if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
71 + clear_bit(gpio, gpio_in_use);
76 EXPORT_SYMBOL(gpio_free);
77 @@ -73,6 +91,10 @@ int gpio_to_irq(unsigned gpio)
81 +#ifdef CONFIG_BCM47XX_BCMA
82 + case BCM47XX_BUS_TYPE_BCMA:
83 + return bcma_core_mips_irq(bcm47xx_bus.bcma.bus.drv_cc.core) + 2;
88 --- a/arch/mips/bcm47xx/nvram.c
89 +++ b/arch/mips/bcm47xx/nvram.c
90 @@ -29,6 +29,9 @@ static void early_nvram_init(void)
91 #ifdef CONFIG_BCM47XX_SSB
92 struct ssb_mipscore *mcore_ssb;
94 +#ifdef CONFIG_BCM47XX_BCMA
95 + struct bcma_drv_cc *bcma_cc;
97 struct nvram_header *header;
100 @@ -44,6 +47,13 @@ static void early_nvram_init(void)
101 lim = mcore_ssb->flash_window_size;
104 +#ifdef CONFIG_BCM47XX_BCMA
105 + case BCM47XX_BUS_TYPE_BCMA:
106 + bcma_cc = &bcm47xx_bus.bcma.bus.drv_cc;
107 + base = bcma_cc->pflash.window;
108 + lim = bcma_cc->pflash.window_size;
114 --- a/arch/mips/bcm47xx/serial.c
115 +++ b/arch/mips/bcm47xx/serial.c
116 @@ -47,6 +47,31 @@ static int __init uart8250_init_ssb(void
120 +#ifdef CONFIG_BCM47XX_BCMA
121 +static int __init uart8250_init_bcma(void)
124 + struct bcma_drv_cc *cc = &(bcm47xx_bus.bcma.bus.drv_cc);
126 + memset(&uart8250_data, 0, sizeof(uart8250_data));
128 + for (i = 0; i < cc->nr_serial_ports; i++) {
129 + struct plat_serial8250_port *p = &(uart8250_data[i]);
130 + struct bcma_serial_port *bcma_port;
131 + bcma_port = &(cc->serial_ports[i]);
133 + p->mapbase = (unsigned int) bcma_port->regs;
134 + p->membase = (void *) bcma_port->regs;
135 + p->irq = bcma_port->irq + 2;
136 + p->uartclk = bcma_port->baud_base;
137 + p->regshift = bcma_port->reg_shift;
138 + p->iotype = UPIO_MEM;
139 + p->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
141 + return platform_device_register(&uart8250_device);
145 static int __init uart8250_init(void)
147 switch (bcm47xx_bus_type) {
148 @@ -54,6 +79,10 @@ static int __init uart8250_init(void)
149 case BCM47XX_BUS_TYPE_SSB:
150 return uart8250_init_ssb();
152 +#ifdef CONFIG_BCM47XX_BCMA
153 + case BCM47XX_BUS_TYPE_BCMA:
154 + return uart8250_init_bcma();
159 --- a/arch/mips/bcm47xx/setup.c
160 +++ b/arch/mips/bcm47xx/setup.c
162 #include <linux/types.h>
163 #include <linux/ssb/ssb.h>
164 #include <linux/ssb/ssb_embedded.h>
165 +#include <linux/bcma/bcma_soc.h>
166 #include <asm/bootinfo.h>
167 #include <asm/reboot.h>
168 #include <asm/time.h>
169 @@ -52,6 +53,11 @@ static void bcm47xx_machine_restart(char
170 ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
173 +#ifdef CONFIG_BCM47XX_BCMA
174 + case BCM47XX_BUS_TYPE_BCMA:
175 + bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 1);
181 @@ -67,6 +73,11 @@ static void bcm47xx_machine_halt(void)
182 ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
185 +#ifdef CONFIG_BCM47XX_BCMA
186 + case BCM47XX_BUS_TYPE_BCMA:
187 + bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
193 @@ -295,16 +306,54 @@ static void __init bcm47xx_register_ssb(
197 +#ifdef CONFIG_BCM47XX_BCMA
198 +static void __init bcm47xx_register_bcma(void)
202 + err = bcma_host_soc_register(&bcm47xx_bus.bcma);
204 + panic("Failed to initialize BCMA bus (err %d)\n", err);
208 void __init plat_mem_setup(void)
210 struct cpuinfo_mips *c = ¤t_cpu_data;
212 + if (c->cputype == CPU_74K) {
213 + printk(KERN_INFO "bcm47xx: using bcma bus\n");
214 +#ifdef CONFIG_BCM47XX_BCMA
215 + bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
216 + bcm47xx_register_bcma();
219 + printk(KERN_INFO "bcm47xx: using ssb bus\n");
220 #ifdef CONFIG_BCM47XX_SSB
221 - bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
222 - bcm47xx_register_ssb();
223 + bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
224 + bcm47xx_register_ssb();
228 _machine_restart = bcm47xx_machine_restart;
229 _machine_halt = bcm47xx_machine_halt;
230 pm_power_off = bcm47xx_machine_halt;
233 +static int __init bcm47xx_register_bus_complete(void)
235 + switch (bcm47xx_bus_type) {
236 +#ifdef CONFIG_BCM47XX_SSB
237 + case BCM47XX_BUS_TYPE_SSB:
238 + /* Nothing to do */
241 +#ifdef CONFIG_BCM47XX_BCMA
242 + case BCM47XX_BUS_TYPE_BCMA:
243 + bcma_bus_register(&bcm47xx_bus.bcma.bus);
249 +device_initcall(bcm47xx_register_bus_complete);
250 --- a/arch/mips/bcm47xx/time.c
251 +++ b/arch/mips/bcm47xx/time.c
252 @@ -45,6 +45,11 @@ void __init plat_time_init(void)
253 hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2;
256 +#ifdef CONFIG_BCM47XX_BCMA
257 + case BCM47XX_BUS_TYPE_BCMA:
258 + hz = bcma_cpu_clock(&bcm47xx_bus.bcma.bus.drv_mips) / 2;
264 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
265 +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
267 #define __ASM_BCM47XX_H
269 #include <linux/ssb/ssb.h>
270 +#include <linux/bcma/bcma.h>
271 +#include <linux/bcma/bcma_soc.h>
273 enum bcm47xx_bus_type {
274 #ifdef CONFIG_BCM47XX_SSB
275 BCM47XX_BUS_TYPE_SSB,
277 +#ifdef CONFIG_BCM47XX_BCMA
278 + BCM47XX_BUS_TYPE_BCMA,
283 #ifdef CONFIG_BCM47XX_SSB
286 +#ifdef CONFIG_BCM47XX_BCMA
287 + struct bcma_soc bcma;
291 extern union bcm47xx_bus bcm47xx_bus;
292 --- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
293 +++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
295 #define __BCM47XX_GPIO_H
297 #include <linux/ssb/ssb_embedded.h>
298 +#include <linux/bcma/bcma.h>
299 #include <asm/mach-bcm47xx/bcm47xx.h>
301 #define BCM47XX_EXTIF_GPIO_LINES 5
302 @@ -26,6 +27,11 @@ static inline int gpio_get_value(unsigne
303 case BCM47XX_BUS_TYPE_SSB:
304 return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
306 +#ifdef CONFIG_BCM47XX_BCMA
307 + case BCM47XX_BUS_TYPE_BCMA:
308 + return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc,
314 @@ -37,6 +43,13 @@ static inline void gpio_set_value(unsign
315 case BCM47XX_BUS_TYPE_SSB:
316 ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
317 value ? 1 << gpio : 0);
320 +#ifdef CONFIG_BCM47XX_BCMA
321 + case BCM47XX_BUS_TYPE_BCMA:
322 + bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
323 + value ? 1 << gpio : 0);
328 @@ -49,6 +62,12 @@ static inline int gpio_direction_input(u
329 ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
332 +#ifdef CONFIG_BCM47XX_BCMA
333 + case BCM47XX_BUS_TYPE_BCMA:
334 + bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
341 @@ -65,6 +84,16 @@ static inline int gpio_direction_output(
342 ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
345 +#ifdef CONFIG_BCM47XX_BCMA
346 + case BCM47XX_BUS_TYPE_BCMA:
347 + /* first set the gpio out value */
348 + bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
349 + value ? 1 << gpio : 0);
350 + /* then set the gpio mode */
351 + bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
358 @@ -78,6 +107,12 @@ static inline int gpio_intmask(unsigned
359 value ? 1 << gpio : 0);
362 +#ifdef CONFIG_BCM47XX_BCMA
363 + case BCM47XX_BUS_TYPE_BCMA:
364 + bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc,
365 + 1 << gpio, value ? 1 << gpio : 0);
371 @@ -91,6 +126,12 @@ static inline int gpio_polarity(unsigned
372 value ? 1 << gpio : 0);
375 +#ifdef CONFIG_BCM47XX_BCMA
376 + case BCM47XX_BUS_TYPE_BCMA:
377 + bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc,
378 + 1 << gpio, value ? 1 << gpio : 0);
384 --- a/drivers/watchdog/bcm47xx_wdt.c
385 +++ b/drivers/watchdog/bcm47xx_wdt.c
386 @@ -60,6 +60,12 @@ static inline void bcm47xx_wdt_hw_start(
387 ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
390 +#ifdef CONFIG_BCM47XX_BCMA
391 + case BCM47XX_BUS_TYPE_BCMA:
392 + bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc,
399 @@ -70,6 +76,11 @@ static inline int bcm47xx_wdt_hw_stop(vo
400 case BCM47XX_BUS_TYPE_SSB:
401 return ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
403 +#ifdef CONFIG_BCM47XX_BCMA
404 + case BCM47XX_BUS_TYPE_BCMA:
405 + bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);