From 2e63f6da683d88c2436d441227da14a67f422867 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Wed, 6 Jun 2012 15:44:56 +0000 Subject: [PATCH] [brcm63xx] update livebox board support (#8677) Merge most fixes from #8677: - add basic hardware detection of Livebox Blue 5g revisions - register leds and gpio buttons - fix boot address location - properly parse mac addresses Plus some more fixes: - make board_livebox.c more in line with board_bcm963xx.c git-svn-id: svn://svn.openwrt.org/openwrt/trunk@32087 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../patches-3.3/513-board_livebox.patch | 294 +++++++++++++----- 1 file changed, 216 insertions(+), 78 deletions(-) diff --git a/target/linux/brcm63xx/patches-3.3/513-board_livebox.patch b/target/linux/brcm63xx/patches-3.3/513-board_livebox.patch index b00c1529d4..d336420690 100644 --- a/target/linux/brcm63xx/patches-3.3/513-board_livebox.patch +++ b/target/linux/brcm63xx/patches-3.3/513-board_livebox.patch @@ -20,7 +20,7 @@ ccflags-y := -Werror --- /dev/null +++ b/arch/mips/bcm63xx/boards/board_livebox.c -@@ -0,0 +1,228 @@ +@@ -0,0 +1,366 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive @@ -36,23 +36,30 @@ +#include +#include +#include ++#include ++#include +#include -+#include ++#include +#include +#include +#include ++#include +#include +#include -+#include +#include +#include ++#include +#include +#include +#include ++#include +#include + +#define PFX "board_livebox: " + ++#define LIVEBOX_KEYS_POLL_INTERVAL 20 ++#define LIVEBOX_KEYS_DEBOUNCE_INTERVAL (LIVEBOX_KEYS_POLL_INTERVAL * 3) ++ +static unsigned int mac_addr_used = 0; +static struct board_info board; + @@ -60,8 +67,8 @@ + * known 6348 boards + */ +#ifdef CONFIG_BCM63XX_CPU_6348 -+static struct board_info __initdata board_livebox = { -+ .name = "Livebox", ++static struct board_info __initdata board_livebox_blue5g = { ++ .name = "Livebox-blue-5g", + .expected_cpu_id = 0x6348, + + .has_uart0 = 1, @@ -75,13 +82,65 @@ + }, + + .enet1 = { -+ .force_speed_100 = 1, -+ .force_duplex_full = 1, ++ .has_phy = 1, ++ .phy_id = 31, + }, + + .has_ohci0 = 1, + .has_pccard = 1, -+ .has_ehci0 = 1, ++ ++ .has_dsp = 0, /*TODO some Liveboxes have dsp*/ ++ .dsp = { ++ .gpio_rst = 6, /*FIXME eth1 shares gpio6 with dsp?*/ ++ .gpio_int = 35, ++ .cs = 2, ++ .ext_irq = 2, ++ }, ++ ++ .leds = { ++ { ++ .name = "Livebox-blue-5g::adsl-fail", ++ .gpio = 0, ++ .active_low = 0, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "Livebox-blue-5g::adsl", ++ .gpio = 1, ++ }, ++ { ++ .name = "Livebox-blue-5g::traffic", ++ .gpio = 2, ++ }, ++ { ++ .name = "Livebox-blue-5g::phone", ++ .gpio = 3, ++ }, ++ { ++ .name = "Livebox-blue-5g::wifi", ++ .gpio = 4, ++ }, ++ }, ++ ++ .buttons = { ++ { ++ .desc = "BTN_1", ++ .gpio = 36, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = BTN_1, ++ .debounce_interval = LIVEBOX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "BTN_2", ++ .gpio = 7, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = BTN_2, ++ .debounce_interval = LIVEBOX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ ++ }, +}; +#endif + @@ -90,70 +149,9 @@ + */ +static const struct board_info __initdata *bcm963xx_boards[] = { +#ifdef CONFIG_BCM63XX_CPU_6348 -+ &board_livebox ++ &board_livebox_blue5g +#endif +}; -+ -+/* -+ * early init callback -+ */ -+void __init board_prom_init(void) -+{ -+ u32 val; -+ -+ /* read base address of boot chip select (0) */ -+ val = bcm_mpi_readl(MPI_CSBASE_REG(0)); -+ val &= MPI_CSBASE_BASE_MASK; -+ -+ /* assume board is a Livebox */ -+ memcpy(&board, bcm963xx_boards[0], sizeof(board)); -+ -+ /* setup pin multiplexing depending on board enabled device, -+ * this has to be done this early since PCI init is done -+ * inside arch_initcall */ -+ val = 0; -+ -+ if (board.has_pci) { -+ bcm63xx_pci_enabled = 1; -+ if (BCMCPU_IS_6348()) -+ val |= GPIO_MODE_6348_G2_PCI; -+ } -+ -+ if (board.has_pccard) { -+ if (BCMCPU_IS_6348()) -+ val |= GPIO_MODE_6348_G1_MII_PCCARD; -+ } -+ -+ if (board.has_enet0 && !board.enet0.use_internal_phy) { -+ if (BCMCPU_IS_6348()) -+ val |= GPIO_MODE_6348_G3_EXT_MII | -+ GPIO_MODE_6348_G0_EXT_MII; -+ } -+ -+ if (board.has_enet1 && !board.enet1.use_internal_phy) { -+ if (BCMCPU_IS_6348()) -+ val |= GPIO_MODE_6348_G3_EXT_MII | -+ GPIO_MODE_6348_G0_EXT_MII; -+ } -+ -+ bcm_gpio_writel(val, GPIO_MODE_REG); -+} -+ -+/* -+ * second stage init callback, good time to panic if we couldn't -+ * identify on which board we're running since early printk is working -+ */ -+void __init board_setup(void) -+{ -+ if (!board.name[0]) -+ panic("unable to detect bcm963xx board"); -+ printk(KERN_INFO PFX "board name: %s\n", board.name); -+ -+ /* make sure we're running on expected cpu */ -+ if (bcm63xx_get_cpu_id() != board.expected_cpu_id) -+ panic("unexpected CPU for bcm963xx board"); -+} -+ +/* + * return board name for /proc/cpuinfo + */ @@ -165,14 +163,12 @@ +/* + * register & return a new board mac address + */ -+ +static int board_get_mac_address(u8 *mac) +{ -+ u8 default_mac[ETH_ALEN] = {0x00, 0x07, 0x3A, 0x00, 0x00, 0x00}; + u8 *p; + int count; + -+ memcpy(mac, default_mac, ETH_ALEN); ++ memcpy(mac, (u8 *)0xBEBFF377, ETH_ALEN); + + p = mac + ETH_ALEN - 1; + count = mac_addr_used; @@ -195,6 +191,88 @@ + return 0; +} + ++/* ++ * early init callback ++ */ ++#define LIVEBOX_GPIO_DETECT_MASK 0x000000ff ++#define LIVEBOX_BOOT_ADDR 0x1e400000 ++ ++#define LIVEBOX_HW_BLUE5G_9 0x90 ++ ++void __init board_prom_init(void) ++{ ++ u32 val; ++ u8 hw_version; ++ ++ /* Get hardware version */ ++ val = bcm_gpio_readl(GPIO_CTL_LO_REG); ++ val &= ~LIVEBOX_GPIO_DETECT_MASK; ++ bcm_gpio_writel(val, GPIO_CTL_LO_REG); ++ ++ hw_version = bcm_gpio_readl(GPIO_DATA_LO_REG) & LIVEBOX_GPIO_DETECT_MASK; ++ switch (hw_version) { ++ case LIVEBOX_HW_BLUE5G_9: ++ printk(KERN_INFO PFX "Livebox BLUE5G.9\n"); ++ memcpy(&board, bcm963xx_boards[0], sizeof(board)); ++ break; ++ default: ++ printk(KERN_INFO PFX "Unknown livebox version: %02x\n", hw_version); ++ break; ++ } ++ ++ /* use default livebox configuration */ ++ memcpy(&board, bcm963xx_boards[0], sizeof(board)); ++ ++ /* setup pin multiplexing depending on board enabled device, ++ * this has to be done this early since PCI init is done ++ * inside arch_initcall */ ++ val = 0; ++ ++#ifdef CONFIG_PCI ++ if (board.has_pci) { ++ if (BCMCPU_IS_6348()) ++ val |= GPIO_MODE_6348_G2_PCI; ++ } ++#endif ++ if (board.has_pccard) { ++ if (BCMCPU_IS_6348()) ++ val |= GPIO_MODE_6348_G1_MII_PCCARD; ++ } ++ ++ if (board.has_enet0 && !board.enet0.use_internal_phy) { ++ if (BCMCPU_IS_6348()) ++ val |= GPIO_MODE_6348_G3_EXT_MII | ++ GPIO_MODE_6348_G0_EXT_MII; ++ } ++ ++ if (board.has_enet1 && !board.enet1.use_internal_phy) { ++ if (BCMCPU_IS_6348()) ++ val |= GPIO_MODE_6348_G3_EXT_MII | ++ GPIO_MODE_6348_G0_EXT_MII; ++ printk(KERN_INFO PFX "resetting gpio6 for eth1...\n"); ++ gpio_request(6, "dsp_eth_rst"); ++ gpio_direction_output(6, 0); ++ gpio_set_value(6, 1); ++ } ++ ++ bcm_gpio_writel(val, GPIO_MODE_REG); ++} ++ ++/* ++ * second stage init callback, good time to panic if we couldn't ++ * identify on which board we're running since early printk is working ++ */ ++void __init board_setup(void) ++{ ++ if (!board.name[0]) ++ panic("unable to detect bcm963xx board"); ++ printk(KERN_INFO PFX "board name: %s\n", board.name); ++ ++ /* make sure we're running on expected cpu */ ++ if (bcm63xx_get_cpu_id() != board.expected_cpu_id) ++ panic("unexpected CPU for bcm963xx board"); ++} ++ +static struct resource mtd_resources[] = { + { + .start = 0, /* filled at runtime */ @@ -209,6 +287,23 @@ + .num_resources = ARRAY_SIZE(mtd_resources), +}; + ++static struct gpio_led_platform_data bcm63xx_led_data; ++ ++static struct platform_device bcm63xx_gpio_leds = { ++ .name = "leds-gpio", ++ .id = 0, ++ .dev.platform_data = &bcm63xx_led_data, ++}; ++ ++static struct gpio_keys_platform_data bcm63xx_gpio_keys_data = { ++ .poll_interval = LIVEBOX_KEYS_POLL_INTERVAL, ++}; ++ ++static struct platform_device bcm63xx_gpio_keys_device = { ++ .name = "gpio-keys-polled", ++ .id = 0, ++ .dev.platform_data = &bcm63xx_gpio_keys_data, ++}; + +/* + * third stage init callback, register all board devices. @@ -216,10 +311,15 @@ +int __init board_register_devices(void) +{ + u32 val; ++ int led_count = 0; ++ int button_count = 0; + + if (board.has_uart0) + bcm63xx_uart_register(0); + ++ if (board.has_uart1) ++ bcm63xx_uart_register(1); ++ + if (board.has_pccard) + bcm63xx_pcmcia_register(); + @@ -231,21 +331,59 @@ + !board_get_mac_address(board.enet1.mac_addr)) + bcm63xx_enet_register(1, &board.enet1); + ++ if (board.has_ehci0) ++ bcm63xx_ehci_register(); ++ + if (board.has_ohci0) + bcm63xx_ohci_register(); + -+ if (board.has_ehci0) -+ bcm63xx_ehci_register(); ++ if (board.has_dsp) ++ bcm63xx_dsp_register(&board.dsp); ++ ++ bcm63xx_spi_register(); ++ ++ if (board.num_devs) ++ platform_add_devices(board.devs, board.num_devs); ++ ++ if (board.num_spis) ++ spi_register_board_info(board.spis, board.num_spis); + + + /* read base address of boot chip select (0) */ + val = bcm_mpi_readl(MPI_CSBASE_REG(0)); + val &= MPI_CSBASE_BASE_MASK; -+ mtd_resources[0].start = val; -+ mtd_resources[0].end = 0x1FFFFFFF; ++ if (val != LIVEBOX_BOOT_ADDR) ++ printk(KERN_NOTICE PFX "flash address is: 0x%08x, forcing to: 0x%08x\n", ++ val, LIVEBOX_BOOT_ADDR); ++ mtd_resources[0].start = LIVEBOX_BOOT_ADDR; ++ mtd_resources[0].end = 0x1ebfffff; + + platform_device_register(&mtd_dev); + ++ /* count number of LEDs defined by this device */ ++ while (led_count < ARRAY_SIZE(board.leds) && board.leds[led_count].name) ++ led_count++; ++ ++ bcm63xx_led_data.num_leds = led_count; ++ bcm63xx_led_data.leds = board.leds; ++ ++ platform_device_register(&bcm63xx_gpio_leds); ++ ++ /* count number of BUTTONs defined by this device */ ++ while (button_count < ARRAY_SIZE(board.buttons) && board.buttons[button_count].desc) ++ button_count++; ++ ++ if (button_count) { ++ bcm63xx_gpio_keys_data.nbuttons = button_count; ++ bcm63xx_gpio_keys_data.buttons = board.buttons; ++ ++ platform_device_register(&bcm63xx_gpio_keys_device); ++ } ++ ++#ifdef CONFIG_PCI ++ if (board.has_pci) ++ bcm63xx_pci_register(); ++#endif ++ + return 0; +} -+