aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorHauke Mehrtens <hauke@hauke-m.de>2011-07-22 19:20:14 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-08-08 14:29:32 -0400
commitc1d1c5d4213ee96e054c4d195117368972a4c01f (patch)
tree4ce75f49f1b46835ab613bd85084b9ce863c5853 /arch
parenta656ffcbc7a98a80d2136ae6bbdd8ae2eb48c78a (diff)
bcm47xx: add support for bcma bus
This patch add support for the bcma bus. Broadcom uses only Mips 74K CPUs on the new SoC and on the old ons using ssb bus there are no Mips 74K CPUs. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> Acked-by: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/bcm47xx/Kconfig13
-rw-r--r--arch/mips/bcm47xx/gpio.c22
-rw-r--r--arch/mips/bcm47xx/nvram.c10
-rw-r--r--arch/mips/bcm47xx/serial.c29
-rw-r--r--arch/mips/bcm47xx/setup.c53
-rw-r--r--arch/mips/bcm47xx/time.c5
-rw-r--r--arch/mips/include/asm/mach-bcm47xx/bcm47xx.h8
-rw-r--r--arch/mips/include/asm/mach-bcm47xx/gpio.h41
8 files changed, 179 insertions, 2 deletions
diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig
index 0346f92d12a2..6210b8d84109 100644
--- a/arch/mips/bcm47xx/Kconfig
+++ b/arch/mips/bcm47xx/Kconfig
@@ -15,4 +15,17 @@ config BCM47XX_SSB
15 15
16 This will generate an image with support for SSB and MIPS32 R1 instruction set. 16 This will generate an image with support for SSB and MIPS32 R1 instruction set.
17 17
18config BCM47XX_BCMA
19 bool "BCMA Support for Broadcom BCM47XX"
20 select SYS_HAS_CPU_MIPS32_R2
21 select BCMA
22 select BCMA_HOST_SOC
23 select BCMA_DRIVER_MIPS
24 select BCMA_DRIVER_PCI_HOSTMODE if PCI
25 default y
26 help
27 Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
28
29 This will generate an image with support for BCMA and MIPS32 R2 instruction set.
30
18endif 31endif
diff --git a/arch/mips/bcm47xx/gpio.c b/arch/mips/bcm47xx/gpio.c
index 2b804c36750b..57b425fd4d41 100644
--- a/arch/mips/bcm47xx/gpio.c
+++ b/arch/mips/bcm47xx/gpio.c
@@ -36,6 +36,16 @@ int gpio_request(unsigned gpio, const char *tag)
36 36
37 return 0; 37 return 0;
38#endif 38#endif
39#ifdef CONFIG_BCM47XX_BCMA
40 case BCM47XX_BUS_TYPE_BCMA:
41 if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
42 return -EINVAL;
43
44 if (test_and_set_bit(gpio, gpio_in_use))
45 return -EBUSY;
46
47 return 0;
48#endif
39 } 49 }
40 return -EINVAL; 50 return -EINVAL;
41} 51}
@@ -57,6 +67,14 @@ void gpio_free(unsigned gpio)
57 clear_bit(gpio, gpio_in_use); 67 clear_bit(gpio, gpio_in_use);
58 return; 68 return;
59#endif 69#endif
70#ifdef CONFIG_BCM47XX_BCMA
71 case BCM47XX_BUS_TYPE_BCMA:
72 if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
73 return;
74
75 clear_bit(gpio, gpio_in_use);
76 return;
77#endif
60 } 78 }
61} 79}
62EXPORT_SYMBOL(gpio_free); 80EXPORT_SYMBOL(gpio_free);
@@ -73,6 +91,10 @@ int gpio_to_irq(unsigned gpio)
73 else 91 else
74 return -EINVAL; 92 return -EINVAL;
75#endif 93#endif
94#ifdef CONFIG_BCM47XX_BCMA
95 case BCM47XX_BUS_TYPE_BCMA:
96 return bcma_core_mips_irq(bcm47xx_bus.bcma.bus.drv_cc.core) + 2;
97#endif
76 } 98 }
77 return -EINVAL; 99 return -EINVAL;
78} 100}
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c
index 4e994edb1425..a84e3bb7387f 100644
--- a/arch/mips/bcm47xx/nvram.c
+++ b/arch/mips/bcm47xx/nvram.c
@@ -29,6 +29,9 @@ static void early_nvram_init(void)
29#ifdef CONFIG_BCM47XX_SSB 29#ifdef CONFIG_BCM47XX_SSB
30 struct ssb_mipscore *mcore_ssb; 30 struct ssb_mipscore *mcore_ssb;
31#endif 31#endif
32#ifdef CONFIG_BCM47XX_BCMA
33 struct bcma_drv_cc *bcma_cc;
34#endif
32 struct nvram_header *header; 35 struct nvram_header *header;
33 int i; 36 int i;
34 u32 base = 0; 37 u32 base = 0;
@@ -44,6 +47,13 @@ static void early_nvram_init(void)
44 lim = mcore_ssb->flash_window_size; 47 lim = mcore_ssb->flash_window_size;
45 break; 48 break;
46#endif 49#endif
50#ifdef CONFIG_BCM47XX_BCMA
51 case BCM47XX_BUS_TYPE_BCMA:
52 bcma_cc = &bcm47xx_bus.bcma.bus.drv_cc;
53 base = bcma_cc->pflash.window;
54 lim = bcma_cc->pflash.window_size;
55 break;
56#endif
47 } 57 }
48 58
49 off = FLASH_MIN; 59 off = FLASH_MIN;
diff --git a/arch/mips/bcm47xx/serial.c b/arch/mips/bcm47xx/serial.c
index fcef68836979..57981e4fe2bc 100644
--- a/arch/mips/bcm47xx/serial.c
+++ b/arch/mips/bcm47xx/serial.c
@@ -47,6 +47,31 @@ static int __init uart8250_init_ssb(void)
47} 47}
48#endif 48#endif
49 49
50#ifdef CONFIG_BCM47XX_BCMA
51static int __init uart8250_init_bcma(void)
52{
53 int i;
54 struct bcma_drv_cc *cc = &(bcm47xx_bus.bcma.bus.drv_cc);
55
56 memset(&uart8250_data, 0, sizeof(uart8250_data));
57
58 for (i = 0; i < cc->nr_serial_ports; i++) {
59 struct plat_serial8250_port *p = &(uart8250_data[i]);
60 struct bcma_serial_port *bcma_port;
61 bcma_port = &(cc->serial_ports[i]);
62
63 p->mapbase = (unsigned int) bcma_port->regs;
64 p->membase = (void *) bcma_port->regs;
65 p->irq = bcma_port->irq + 2;
66 p->uartclk = bcma_port->baud_base;
67 p->regshift = bcma_port->reg_shift;
68 p->iotype = UPIO_MEM;
69 p->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
70 }
71 return platform_device_register(&uart8250_device);
72}
73#endif
74
50static int __init uart8250_init(void) 75static int __init uart8250_init(void)
51{ 76{
52 switch (bcm47xx_bus_type) { 77 switch (bcm47xx_bus_type) {
@@ -54,6 +79,10 @@ static int __init uart8250_init(void)
54 case BCM47XX_BUS_TYPE_SSB: 79 case BCM47XX_BUS_TYPE_SSB:
55 return uart8250_init_ssb(); 80 return uart8250_init_ssb();
56#endif 81#endif
82#ifdef CONFIG_BCM47XX_BCMA
83 case BCM47XX_BUS_TYPE_BCMA:
84 return uart8250_init_bcma();
85#endif
57 } 86 }
58 return -EINVAL; 87 return -EINVAL;
59} 88}
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index 142cf1bc8884..17c3d14d7c49 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -29,6 +29,7 @@
29#include <linux/types.h> 29#include <linux/types.h>
30#include <linux/ssb/ssb.h> 30#include <linux/ssb/ssb.h>
31#include <linux/ssb/ssb_embedded.h> 31#include <linux/ssb/ssb_embedded.h>
32#include <linux/bcma/bcma_soc.h>
32#include <asm/bootinfo.h> 33#include <asm/bootinfo.h>
33#include <asm/reboot.h> 34#include <asm/reboot.h>
34#include <asm/time.h> 35#include <asm/time.h>
@@ -52,6 +53,11 @@ static void bcm47xx_machine_restart(char *command)
52 ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1); 53 ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
53 break; 54 break;
54#endif 55#endif
56#ifdef CONFIG_BCM47XX_BCMA
57 case BCM47XX_BUS_TYPE_BCMA:
58 bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 1);
59 break;
60#endif
55 } 61 }
56 while (1) 62 while (1)
57 cpu_relax(); 63 cpu_relax();
@@ -67,6 +73,11 @@ static void bcm47xx_machine_halt(void)
67 ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0); 73 ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
68 break; 74 break;
69#endif 75#endif
76#ifdef CONFIG_BCM47XX_BCMA
77 case BCM47XX_BUS_TYPE_BCMA:
78 bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
79 break;
80#endif
70 } 81 }
71 while (1) 82 while (1)
72 cpu_relax(); 83 cpu_relax();
@@ -295,16 +306,54 @@ static void __init bcm47xx_register_ssb(void)
295} 306}
296#endif 307#endif
297 308
309#ifdef CONFIG_BCM47XX_BCMA
310static void __init bcm47xx_register_bcma(void)
311{
312 int err;
313
314 err = bcma_host_soc_register(&bcm47xx_bus.bcma);
315 if (err)
316 panic("Failed to initialize BCMA bus (err %d)\n", err);
317}
318#endif
319
298void __init plat_mem_setup(void) 320void __init plat_mem_setup(void)
299{ 321{
300 struct cpuinfo_mips *c = &current_cpu_data; 322 struct cpuinfo_mips *c = &current_cpu_data;
301 323
324 if (c->cputype == CPU_74K) {
325 printk(KERN_INFO "bcm47xx: using bcma bus\n");
326#ifdef CONFIG_BCM47XX_BCMA
327 bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
328 bcm47xx_register_bcma();
329#endif
330 } else {
331 printk(KERN_INFO "bcm47xx: using ssb bus\n");
302#ifdef CONFIG_BCM47XX_SSB 332#ifdef CONFIG_BCM47XX_SSB
303 bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB; 333 bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
304 bcm47xx_register_ssb(); 334 bcm47xx_register_ssb();
305#endif 335#endif
336 }
306 337
307 _machine_restart = bcm47xx_machine_restart; 338 _machine_restart = bcm47xx_machine_restart;
308 _machine_halt = bcm47xx_machine_halt; 339 _machine_halt = bcm47xx_machine_halt;
309 pm_power_off = bcm47xx_machine_halt; 340 pm_power_off = bcm47xx_machine_halt;
310} 341}
342
343static int __init bcm47xx_register_bus_complete(void)
344{
345 switch (bcm47xx_bus_type) {
346#ifdef CONFIG_BCM47XX_SSB
347 case BCM47XX_BUS_TYPE_SSB:
348 /* Nothing to do */
349 break;
350#endif
351#ifdef CONFIG_BCM47XX_BCMA
352 case BCM47XX_BUS_TYPE_BCMA:
353 bcma_bus_register(&bcm47xx_bus.bcma.bus);
354 break;
355#endif
356 }
357 return 0;
358}
359device_initcall(bcm47xx_register_bus_complete);
diff --git a/arch/mips/bcm47xx/time.c b/arch/mips/bcm47xx/time.c
index 03dfc65b1b60..536374dcba78 100644
--- a/arch/mips/bcm47xx/time.c
+++ b/arch/mips/bcm47xx/time.c
@@ -45,6 +45,11 @@ void __init plat_time_init(void)
45 hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2; 45 hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2;
46 break; 46 break;
47#endif 47#endif
48#ifdef CONFIG_BCM47XX_BCMA
49 case BCM47XX_BUS_TYPE_BCMA:
50 hz = bcma_cpu_clock(&bcm47xx_bus.bcma.bus.drv_mips) / 2;
51 break;
52#endif
48 } 53 }
49 54
50 if (!hz) 55 if (!hz)
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
index d037afb6677e..de95e0723e2b 100644
--- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
+++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
@@ -20,17 +20,25 @@
20#define __ASM_BCM47XX_H 20#define __ASM_BCM47XX_H
21 21
22#include <linux/ssb/ssb.h> 22#include <linux/ssb/ssb.h>
23#include <linux/bcma/bcma.h>
24#include <linux/bcma/bcma_soc.h>
23 25
24enum bcm47xx_bus_type { 26enum bcm47xx_bus_type {
25#ifdef CONFIG_BCM47XX_SSB 27#ifdef CONFIG_BCM47XX_SSB
26 BCM47XX_BUS_TYPE_SSB, 28 BCM47XX_BUS_TYPE_SSB,
27#endif 29#endif
30#ifdef CONFIG_BCM47XX_BCMA
31 BCM47XX_BUS_TYPE_BCMA,
32#endif
28}; 33};
29 34
30union bcm47xx_bus { 35union bcm47xx_bus {
31#ifdef CONFIG_BCM47XX_SSB 36#ifdef CONFIG_BCM47XX_SSB
32 struct ssb_bus ssb; 37 struct ssb_bus ssb;
33#endif 38#endif
39#ifdef CONFIG_BCM47XX_BCMA
40 struct bcma_soc bcma;
41#endif
34}; 42};
35 43
36extern union bcm47xx_bus bcm47xx_bus; 44extern union bcm47xx_bus bcm47xx_bus;
diff --git a/arch/mips/include/asm/mach-bcm47xx/gpio.h b/arch/mips/include/asm/mach-bcm47xx/gpio.h
index 1d5f5af56b5f..76961cabeedf 100644
--- a/arch/mips/include/asm/mach-bcm47xx/gpio.h
+++ b/arch/mips/include/asm/mach-bcm47xx/gpio.h
@@ -10,6 +10,7 @@
10#define __BCM47XX_GPIO_H 10#define __BCM47XX_GPIO_H
11 11
12#include <linux/ssb/ssb_embedded.h> 12#include <linux/ssb/ssb_embedded.h>
13#include <linux/bcma/bcma.h>
13#include <asm/mach-bcm47xx/bcm47xx.h> 14#include <asm/mach-bcm47xx/bcm47xx.h>
14 15
15#define BCM47XX_EXTIF_GPIO_LINES 5 16#define BCM47XX_EXTIF_GPIO_LINES 5
@@ -26,6 +27,11 @@ static inline int gpio_get_value(unsigned gpio)
26 case BCM47XX_BUS_TYPE_SSB: 27 case BCM47XX_BUS_TYPE_SSB:
27 return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio); 28 return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
28#endif 29#endif
30#ifdef CONFIG_BCM47XX_BCMA
31 case BCM47XX_BUS_TYPE_BCMA:
32 return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc,
33 1 << gpio);
34#endif
29 } 35 }
30 return -EINVAL; 36 return -EINVAL;
31} 37}
@@ -37,6 +43,13 @@ static inline void gpio_set_value(unsigned gpio, int value)
37 case BCM47XX_BUS_TYPE_SSB: 43 case BCM47XX_BUS_TYPE_SSB:
38 ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio, 44 ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
39 value ? 1 << gpio : 0); 45 value ? 1 << gpio : 0);
46 return;
47#endif
48#ifdef CONFIG_BCM47XX_BCMA
49 case BCM47XX_BUS_TYPE_BCMA:
50 bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
51 value ? 1 << gpio : 0);
52 return;
40#endif 53#endif
41 } 54 }
42} 55}
@@ -49,6 +62,12 @@ static inline int gpio_direction_input(unsigned gpio)
49 ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0); 62 ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
50 return 0; 63 return 0;
51#endif 64#endif
65#ifdef CONFIG_BCM47XX_BCMA
66 case BCM47XX_BUS_TYPE_BCMA:
67 bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
68 0);
69 return 0;
70#endif
52 } 71 }
53 return -EINVAL; 72 return -EINVAL;
54} 73}
@@ -65,6 +84,16 @@ static inline int gpio_direction_output(unsigned gpio, int value)
65 ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio); 84 ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
66 return 0; 85 return 0;
67#endif 86#endif
87#ifdef CONFIG_BCM47XX_BCMA
88 case BCM47XX_BUS_TYPE_BCMA:
89 /* first set the gpio out value */
90 bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
91 value ? 1 << gpio : 0);
92 /* then set the gpio mode */
93 bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
94 1 << gpio);
95 return 0;
96#endif
68 } 97 }
69 return -EINVAL; 98 return -EINVAL;
70} 99}
@@ -78,6 +107,12 @@ static inline int gpio_intmask(unsigned gpio, int value)
78 value ? 1 << gpio : 0); 107 value ? 1 << gpio : 0);
79 return 0; 108 return 0;
80#endif 109#endif
110#ifdef CONFIG_BCM47XX_BCMA
111 case BCM47XX_BUS_TYPE_BCMA:
112 bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc,
113 1 << gpio, value ? 1 << gpio : 0);
114 return 0;
115#endif
81 } 116 }
82 return -EINVAL; 117 return -EINVAL;
83} 118}
@@ -91,6 +126,12 @@ static inline int gpio_polarity(unsigned gpio, int value)
91 value ? 1 << gpio : 0); 126 value ? 1 << gpio : 0);
92 return 0; 127 return 0;
93#endif 128#endif
129#ifdef CONFIG_BCM47XX_BCMA
130 case BCM47XX_BUS_TYPE_BCMA:
131 bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc,
132 1 << gpio, value ? 1 << gpio : 0);
133 return 0;
134#endif
94 } 135 }
95 return -EINVAL; 136 return -EINVAL;
96} 137}