bcm47xx: add support for bcma bus
authorHauke Mehrtens <hauke@hauke-m.de>
Fri, 22 Jul 2011 23:20:14 +0000 (01:20 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 8 Aug 2011 18:29:32 +0000 (14:29 -0400)
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>
arch/mips/bcm47xx/Kconfig
arch/mips/bcm47xx/gpio.c
arch/mips/bcm47xx/nvram.c
arch/mips/bcm47xx/serial.c
arch/mips/bcm47xx/setup.c
arch/mips/bcm47xx/time.c
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
arch/mips/include/asm/mach-bcm47xx/gpio.h
drivers/watchdog/bcm47xx_wdt.c

index 0346f92d12a2df78a596f431ef40a0fcf9046a6f..6210b8d841098c5182a7ea986e6ac66c6a02371b 100644 (file)
@@ -15,4 +15,17 @@ config BCM47XX_SSB
 
         This will generate an image with support for SSB and MIPS32 R1 instruction set.
 
+config BCM47XX_BCMA
+       bool "BCMA Support for Broadcom BCM47XX"
+       select SYS_HAS_CPU_MIPS32_R2
+       select BCMA
+       select BCMA_HOST_SOC
+       select BCMA_DRIVER_MIPS
+       select BCMA_DRIVER_PCI_HOSTMODE if PCI
+       default y
+       help
+        Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
+
+        This will generate an image with support for BCMA and MIPS32 R2 instruction set.
+
 endif
index 2b804c36750bb5c7051e2fcc02ae045935490ba4..57b425fd4d412b2e685804065255fef55af7affc 100644 (file)
@@ -36,6 +36,16 @@ int gpio_request(unsigned gpio, const char *tag)
 
                return 0;
 #endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
+                       return -EINVAL;
+
+               if (test_and_set_bit(gpio, gpio_in_use))
+                       return -EBUSY;
+
+               return 0;
+#endif
        }
        return -EINVAL;
 }
@@ -57,6 +67,14 @@ void gpio_free(unsigned gpio)
                clear_bit(gpio, gpio_in_use);
                return;
 #endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
+                       return;
+
+               clear_bit(gpio, gpio_in_use);
+               return;
+#endif
        }
 }
 EXPORT_SYMBOL(gpio_free);
@@ -72,6 +90,10 @@ int gpio_to_irq(unsigned gpio)
                        return ssb_mips_irq(bcm47xx_bus.ssb.extif.dev) + 2;
                else
                        return -EINVAL;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               return bcma_core_mips_irq(bcm47xx_bus.bcma.bus.drv_cc.core) + 2;
 #endif
        }
        return -EINVAL;
index 4e994edb142501a89821fdc5ea28144d30ea3722..a84e3bb7387f685bc7025e689e01e57cfa97bd21 100644 (file)
@@ -28,6 +28,9 @@ static void early_nvram_init(void)
 {
 #ifdef CONFIG_BCM47XX_SSB
        struct ssb_mipscore *mcore_ssb;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       struct bcma_drv_cc *bcma_cc;
 #endif
        struct nvram_header *header;
        int i;
@@ -43,6 +46,13 @@ static void early_nvram_init(void)
                base = mcore_ssb->flash_window;
                lim = mcore_ssb->flash_window_size;
                break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_cc = &bcm47xx_bus.bcma.bus.drv_cc;
+               base = bcma_cc->pflash.window;
+               lim = bcma_cc->pflash.window_size;
+               break;
 #endif
        }
 
index fcef68836979753b7900f46ae5de6bd96d9f03c3..57981e4fe2bc94c143070ee99ecf66d09ceae223 100644 (file)
@@ -47,12 +47,41 @@ static int __init uart8250_init_ssb(void)
 }
 #endif
 
+#ifdef CONFIG_BCM47XX_BCMA
+static int __init uart8250_init_bcma(void)
+{
+       int i;
+       struct bcma_drv_cc *cc = &(bcm47xx_bus.bcma.bus.drv_cc);
+
+       memset(&uart8250_data, 0,  sizeof(uart8250_data));
+
+       for (i = 0; i < cc->nr_serial_ports; i++) {
+               struct plat_serial8250_port *p = &(uart8250_data[i]);
+               struct bcma_serial_port *bcma_port;
+               bcma_port = &(cc->serial_ports[i]);
+
+               p->mapbase = (unsigned int) bcma_port->regs;
+               p->membase = (void *) bcma_port->regs;
+               p->irq = bcma_port->irq + 2;
+               p->uartclk = bcma_port->baud_base;
+               p->regshift = bcma_port->reg_shift;
+               p->iotype = UPIO_MEM;
+               p->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+       }
+       return platform_device_register(&uart8250_device);
+}
+#endif
+
 static int __init uart8250_init(void)
 {
        switch (bcm47xx_bus_type) {
 #ifdef CONFIG_BCM47XX_SSB
        case BCM47XX_BUS_TYPE_SSB:
                return uart8250_init_ssb();
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               return uart8250_init_bcma();
 #endif
        }
        return -EINVAL;
index 142cf1bc8884f8657d0c24052d2127364a9aa6b9..17c3d14d7c4900d5e06c5a0549a27de5db86f06e 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/types.h>
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_embedded.h>
+#include <linux/bcma/bcma_soc.h>
 #include <asm/bootinfo.h>
 #include <asm/reboot.h>
 #include <asm/time.h>
@@ -51,6 +52,11 @@ static void bcm47xx_machine_restart(char *command)
        case BCM47XX_BUS_TYPE_SSB:
                ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
                break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 1);
+               break;
 #endif
        }
        while (1)
@@ -66,6 +72,11 @@ static void bcm47xx_machine_halt(void)
        case BCM47XX_BUS_TYPE_SSB:
                ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
                break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
+               break;
 #endif
        }
        while (1)
@@ -295,16 +306,54 @@ static void __init bcm47xx_register_ssb(void)
 }
 #endif
 
+#ifdef CONFIG_BCM47XX_BCMA
+static void __init bcm47xx_register_bcma(void)
+{
+       int err;
+
+       err = bcma_host_soc_register(&bcm47xx_bus.bcma);
+       if (err)
+               panic("Failed to initialize BCMA bus (err %d)\n", err);
+}
+#endif
+
 void __init plat_mem_setup(void)
 {
        struct cpuinfo_mips *c = &current_cpu_data;
 
+       if (c->cputype == CPU_74K) {
+               printk(KERN_INFO "bcm47xx: using bcma bus\n");
+#ifdef CONFIG_BCM47XX_BCMA
+               bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
+               bcm47xx_register_bcma();
+#endif
+       } else {
+               printk(KERN_INFO "bcm47xx: using ssb bus\n");
 #ifdef CONFIG_BCM47XX_SSB
-       bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
-       bcm47xx_register_ssb();
+               bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
+               bcm47xx_register_ssb();
 #endif
+       }
 
        _machine_restart = bcm47xx_machine_restart;
        _machine_halt = bcm47xx_machine_halt;
        pm_power_off = bcm47xx_machine_halt;
 }
+
+static int __init bcm47xx_register_bus_complete(void)
+{
+       switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+       case BCM47XX_BUS_TYPE_SSB:
+               /* Nothing to do */
+               break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_bus_register(&bcm47xx_bus.bcma.bus);
+               break;
+#endif
+       }
+       return 0;
+}
+device_initcall(bcm47xx_register_bus_complete);
index 03dfc65b1b60f4c3d02558d31f3834d7c9f18a5b..536374dcba78995981b2a0bc04ab7ae62941aa00 100644 (file)
@@ -44,6 +44,11 @@ void __init plat_time_init(void)
        case BCM47XX_BUS_TYPE_SSB:
                hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2;
                break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               hz = bcma_cpu_clock(&bcm47xx_bus.bcma.bus.drv_mips) / 2;
+               break;
 #endif
        }
 
index d037afb6677e186daba8580b68b76812bedbc0a6..de95e0723e2bb058d3164a54c6cc9a1153b9b6e0 100644 (file)
 #define __ASM_BCM47XX_H
 
 #include <linux/ssb/ssb.h>
+#include <linux/bcma/bcma.h>
+#include <linux/bcma/bcma_soc.h>
 
 enum bcm47xx_bus_type {
 #ifdef CONFIG_BCM47XX_SSB
        BCM47XX_BUS_TYPE_SSB,
 #endif
+#ifdef CONFIG_BCM47XX_BCMA
+       BCM47XX_BUS_TYPE_BCMA,
+#endif
 };
 
 union bcm47xx_bus {
 #ifdef CONFIG_BCM47XX_SSB
        struct ssb_bus ssb;
 #endif
+#ifdef CONFIG_BCM47XX_BCMA
+       struct bcma_soc bcma;
+#endif
 };
 
 extern union bcm47xx_bus bcm47xx_bus;
index 1d5f5af56b5fd8e54247e7d0007bf60927f6fd60..76961cabeedfe1cdac4caaef7e9989ca04a345be 100644 (file)
@@ -10,6 +10,7 @@
 #define __BCM47XX_GPIO_H
 
 #include <linux/ssb/ssb_embedded.h>
+#include <linux/bcma/bcma.h>
 #include <asm/mach-bcm47xx/bcm47xx.h>
 
 #define BCM47XX_EXTIF_GPIO_LINES       5
@@ -25,6 +26,11 @@ static inline int gpio_get_value(unsigned gpio)
 #ifdef CONFIG_BCM47XX_SSB
        case BCM47XX_BUS_TYPE_SSB:
                return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc,
+                                          1 << gpio);
 #endif
        }
        return -EINVAL;
@@ -37,6 +43,13 @@ static inline void gpio_set_value(unsigned gpio, int value)
        case BCM47XX_BUS_TYPE_SSB:
                ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
                             value ? 1 << gpio : 0);
+               return;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
+                                    value ? 1 << gpio : 0);
+               return;
 #endif
        }
 }
@@ -48,6 +61,12 @@ static inline int gpio_direction_input(unsigned gpio)
        case BCM47XX_BUS_TYPE_SSB:
                ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
                return 0;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
+                                      0);
+               return 0;
 #endif
        }
        return -EINVAL;
@@ -64,6 +83,16 @@ static inline int gpio_direction_output(unsigned gpio, int value)
                /* then set the gpio mode */
                ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
                return 0;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               /* first set the gpio out value */
+               bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
+                                    value ? 1 << gpio : 0);
+               /* then set the gpio mode */
+               bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
+                                      1 << gpio);
+               return 0;
 #endif
        }
        return -EINVAL;
@@ -77,6 +106,12 @@ static inline int gpio_intmask(unsigned gpio, int value)
                ssb_gpio_intmask(&bcm47xx_bus.ssb, 1 << gpio,
                                 value ? 1 << gpio : 0);
                return 0;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc,
+                                        1 << gpio, value ? 1 << gpio : 0);
+               return 0;
 #endif
        }
        return -EINVAL;
@@ -90,6 +125,12 @@ static inline int gpio_polarity(unsigned gpio, int value)
                ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio,
                                  value ? 1 << gpio : 0);
                return 0;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc,
+                                         1 << gpio, value ? 1 << gpio : 0);
+               return 0;
 #endif
        }
        return -EINVAL;
index 6b037024464f9e0cf156122e571eedd69a564fa1..5c5f4b14fd05aee17e1e6d1f30743f8a3735a1c9 100644 (file)
@@ -59,6 +59,12 @@ static inline void bcm47xx_wdt_hw_start(void)
        case BCM47XX_BUS_TYPE_SSB:
                ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0xfffffff);
                break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc,
+                                              0xfffffff);
+               break;
 #endif
        }
 }
@@ -69,6 +75,11 @@ static inline int bcm47xx_wdt_hw_stop(void)
 #ifdef CONFIG_BCM47XX_SSB
        case BCM47XX_BUS_TYPE_SSB:
                return ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+       case BCM47XX_BUS_TYPE_BCMA:
+               bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
+               return 0;
 #endif
        }
        return -EINVAL;