From e796582b499f0ba6acaa1ac3a10c09cceaab7702 Mon Sep 17 00:00:00 2001 From: Jonas Gorski <jogo@openwrt.org> Date: Sun, 9 Mar 2014 04:55:52 +0100 Subject: [PATCH] MIPS: BCM63XX: add inventel Livebox support --- arch/mips/bcm63xx/boards/Kconfig | 6 + arch/mips/bcm63xx/boards/Makefile | 1 + arch/mips/bcm63xx/boards/board_common.c | 2 +- arch/mips/bcm63xx/boards/board_common.h | 6 + arch/mips/bcm63xx/boards/board_livebox.c | 215 ++++++++++++++++++++++++++++++ 5 files changed, 229 insertions(+), 1 deletion(-) create mode 100644 arch/mips/bcm63xx/boards/board_livebox.c --- a/arch/mips/bcm63xx/boards/Kconfig +++ b/arch/mips/bcm63xx/boards/Kconfig @@ -12,4 +12,10 @@ config BOARD_BCM963XX default y help +config BOARD_LIVEBOX + bool "Inventel Livebox(es) boards" + select SSB + help + Inventel Livebox boards using the RedBoot bootloader. + endmenu --- a/arch/mips/bcm63xx/boards/Makefile +++ b/arch/mips/bcm63xx/boards/Makefile @@ -1,2 +1,3 @@ obj-y += board_common.o obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o +obj-$(CONFIG_BOARD_LIVEBOX) += board_livebox.o --- a/arch/mips/bcm63xx/boards/board_common.c +++ b/arch/mips/bcm63xx/boards/board_common.c @@ -61,7 +61,7 @@ void __init board_prom_init(void) if (fw_arg3 == CFE_EPTSEAL) board_bcm963xx_init(); else - panic("unsupported bootloader detected"); + board_livebox_init(); } static int (*board_get_mac_address)(u8 mac[ETH_ALEN]); --- a/arch/mips/bcm63xx/boards/board_common.h +++ b/arch/mips/bcm63xx/boards/board_common.h @@ -24,4 +24,10 @@ static inline void board_of_device_prese } #endif +#if defined(CONFIG_BOARD_LIVEBOX) +void board_livebox_init(void); +#else +static inline void board_livebox_init(void) { } +#endif + #endif /* __BOARD_COMMON_H */ --- /dev/null +++ b/arch/mips/bcm63xx/boards/board_livebox.c @@ -0,0 +1,164 @@ +/* + * 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 + * for more details. + * + * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org> + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/input.h> +#include <asm/addrspace.h> +#include <bcm63xx_board.h> +#include <bcm63xx_cpu.h> +#include <bcm63xx_regs.h> +#include <bcm63xx_io.h> +#include <bcm63xx_dev_flash.h> +#include <board_bcm963xx.h> + +#include "board_common.h" + +#define PFX "board_livebox: " + +static unsigned int mac_addr_used = 0; + +/* + * known 6348 boards + */ +#ifdef CONFIG_BCM63XX_CPU_6348 +static struct board_info __initdata board_livebox_blue5g = { + .name = "Livebox-blue-5g", + .expected_cpu_id = 0x6348, + + .has_uart0 = 1, + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, + + .enet0 = { + .has_phy = 1, + .use_internal_phy = 1, + }, + + .enet1 = { + .has_phy = 1, + .phy_id = 31, + }, + + .ephy_reset_gpio = 6, + .ephy_reset_gpio_flags = GPIO_ACTIVE_LOW, + + .has_ohci0 = 1, + .has_pccard = 1, + + .has_dsp = 0, /*TODO some Liveboxes have dsp*/ + .dsp = { + .gpio_rst = 6, + .gpio_int = 35, + .cs = 2, + .ext_irq = 2, + }, +}; +#endif + +/* + * all boards + */ +static const struct board_info __initdata *bcm963xx_boards[] = { +#ifdef CONFIG_BCM63XX_CPU_6348 + &board_livebox_blue5g +#endif +}; + +static struct of_device_id const livebox_boards_dt[] = { + { .compatible = "inventel,livebox-blue-5g", .data = &board_livebox_blue5g, }, + { } +}; + +/* + * register & return a new board mac address + */ +static int livebox_get_mac_address(u8 *mac) +{ + u8 *p; + int count; + + memcpy(mac, (u8 *)0xBEBFF377, ETH_ALEN); + + p = mac + ETH_ALEN - 1; + count = mac_addr_used; + + while (count--) { + do { + (*p)++; + if (*p != 0) + break; + p--; + } while (p != mac); + } + + if (p == mac) { + printk(KERN_ERR PFX "unable to fetch mac address\n"); + return -ENODEV; + } + mac_addr_used++; + + 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_livebox_init(void) +{ + u32 val; + u8 hw_version; + const struct board_info *board; + const struct of_device_id *board_match; + + /* find board by compat */ + board_match = bcm63xx_match_board(livebox_boards_dt); + if (board_match) { + board = board_match->data; + } else { + /* 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); + hw_version &= LIVEBOX_GPIO_DETECT_MASK; + + switch (hw_version) { + case LIVEBOX_HW_BLUE5G_9: + printk(KERN_INFO PFX "Livebox BLUE5G.9\n"); + board = bcm963xx_boards[0]; + break; + default: + printk(KERN_INFO PFX "Unknown livebox version: %02x\n", + hw_version); + /* use default livebox configuration */ + board = bcm963xx_boards[0]; + break; + } + } + + /* use default livebox configuration */ + board_early_setup(board, livebox_get_mac_address); + + /* read base address of boot chip select (0) */ + val = bcm_mpi_readl(MPI_CSBASE_REG(0)); + val &= MPI_CSBASE_BASE_MASK; + if (val != LIVEBOX_BOOT_ADDR) { + printk(KERN_NOTICE PFX "flash address is: 0x%08x, forcing to: 0x%08x\n", + val, LIVEBOX_BOOT_ADDR); + bcm63xx_flash_force_phys_base_address(LIVEBOX_BOOT_ADDR, 0x1ebfffff); + } +}