From b89d17b8297e8bd1b423041ba34d10a1a17a3b77 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Fri, 17 Oct 2008 22:53:56 +0000 Subject: New Broadcom BCM63xx codebase, huge thanks to Maxime ;) git-svn-id: svn://svn.openwrt.org/openwrt/trunk@13001 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../011-add_preliminary_board_support.patch | 539 +++++++++++++++++++++ 1 file changed, 539 insertions(+) create mode 100644 target/linux/brcm63xx/patches-2.6.27/011-add_preliminary_board_support.patch (limited to 'target/linux/brcm63xx/patches-2.6.27/011-add_preliminary_board_support.patch') diff --git a/target/linux/brcm63xx/patches-2.6.27/011-add_preliminary_board_support.patch b/target/linux/brcm63xx/patches-2.6.27/011-add_preliminary_board_support.patch new file mode 100644 index 0000000000..a738bcc7ce --- /dev/null +++ b/target/linux/brcm63xx/patches-2.6.27/011-add_preliminary_board_support.patch @@ -0,0 +1,539 @@ +From b95a2bbbcae5423e5404a7b3c8dd1685e1786f13 Mon Sep 17 00:00:00 2001 +From: Maxime Bizon +Date: Wed, 17 Sep 2008 15:55:36 +0200 +Subject: [PATCH] [MIPS] BCM63XX: Add preliminary board support. + +Signed-off-by: Maxime Bizon +--- + arch/mips/bcm63xx/Kconfig | 2 + + arch/mips/bcm63xx/Makefile | 2 + + arch/mips/bcm63xx/boards/Kconfig | 10 + + arch/mips/bcm63xx/boards/Makefile | 1 + + arch/mips/bcm63xx/boards/board_bcm963xx.c | 322 ++++++++++++++++++++++++ + arch/mips/bcm63xx/prom.c | 4 + + arch/mips/bcm63xx/setup.c | 16 +- + include/asm-mips/mach-bcm63xx/bcm63xx_board.h | 12 + + include/asm-mips/mach-bcm63xx/board_bcm963xx.h | 50 ++++ + 9 files changed, 417 insertions(+), 2 deletions(-) + create mode 100644 arch/mips/bcm63xx/boards/Kconfig + create mode 100644 arch/mips/bcm63xx/boards/Makefile + create mode 100644 arch/mips/bcm63xx/boards/board_bcm963xx.c + create mode 100644 include/asm-mips/mach-bcm63xx/bcm63xx_board.h + create mode 100644 include/asm-mips/mach-bcm63xx/board_bcm963xx.h + +diff --git a/arch/mips/bcm63xx/Kconfig b/arch/mips/bcm63xx/Kconfig +index be120f7..8c192e7 100644 +--- a/arch/mips/bcm63xx/Kconfig ++++ b/arch/mips/bcm63xx/Kconfig +@@ -17,3 +17,5 @@ config BCM63XX_CPU_6358 + select USB_ARCH_HAS_EHCI + select USB_EHCI_BIG_ENDIAN_MMIO + endmenu ++ ++source "arch/mips/bcm63xx/boards/Kconfig" +diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile +index 5358093..10462ae 100644 +--- a/arch/mips/bcm63xx/Makefile ++++ b/arch/mips/bcm63xx/Makefile +@@ -5,3 +5,5 @@ obj-y += dev-usb-ohci.o + obj-y += dev-usb-ehci.o + obj-y += dev-enet.o + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o ++ ++obj-y += boards/ +diff --git a/arch/mips/bcm63xx/boards/Kconfig b/arch/mips/bcm63xx/boards/Kconfig +new file mode 100644 +index 0000000..da5eeaa +--- /dev/null ++++ b/arch/mips/bcm63xx/boards/Kconfig +@@ -0,0 +1,10 @@ ++choice ++ prompt "Board support" ++ depends on BCM63XX ++ default BOARD_BCM963XX ++ ++config BOARD_BCM963XX ++ bool "Generic Broadcom 963xx boards" ++ help ++ ++endchoice +diff --git a/arch/mips/bcm63xx/boards/Makefile b/arch/mips/bcm63xx/boards/Makefile +new file mode 100644 +index 0000000..af07c1a +--- /dev/null ++++ b/arch/mips/bcm63xx/boards/Makefile +@@ -0,0 +1 @@ ++obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o +diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c +new file mode 100644 +index 0000000..de52a2a +--- /dev/null ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -0,0 +1,322 @@ ++/* ++ * 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 Maxime Bizon ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define PFX "board_bcm963xx: " ++ ++static struct bcm963xx_nvram nvram; ++static unsigned int mac_addr_used = 0; ++static struct board_info board; ++ ++/* ++ * known 6348 boards ++ */ ++#ifdef CONFIG_BCM63XX_CPU_6348 ++static struct board_info __initdata board_96348r = { ++ .name = "96348R", ++ .expected_cpu_id = 0x6348, ++ ++ .has_enet0 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++}; ++ ++static struct board_info __initdata board_96348gw = { ++ .name = "96348GW", ++ .expected_cpu_id = 0x6348, ++ ++ .has_enet0 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++}; ++#endif ++ ++/* ++ * known 6358 boards ++ */ ++#ifdef CONFIG_BCM63XX_CPU_6358 ++static struct board_info __initdata board_96358vw2 = { ++ .name = "96358VW2", ++ .expected_cpu_id = 0x6358, ++ ++ .has_enet0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++ ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ ++ .has_ohci0 = 1, ++ .has_pccard = 1, ++ .has_ehci0 = 1, ++}; ++#endif ++ ++/* ++ * all boards ++ */ ++static const struct board_info __initdata *bcm963xx_boards[] = { ++#ifdef CONFIG_BCM63XX_CPU_6348 ++ &board_96348r, ++ &board_96348gw, ++#endif ++ ++#ifdef CONFIG_BCM63XX_CPU_6358 ++ &board_96358vw2, ++#endif ++}; ++ ++/* ++ * early init callback, read nvram data from flash and checksum it ++ */ ++void __init board_prom_init(void) ++{ ++ unsigned int check_len, i; ++ u8 *boot_addr, *cfe, *p; ++ char cfe_version[32]; ++ u32 val; ++ ++ /* read base address of boot chip select (0) */ ++ val = bcm_mpi_readl(MPI_CSBASE_REG(0)); ++ val &= MPI_CSBASE_BASE_MASK; ++ boot_addr = (u8 *)KSEG1ADDR(val); ++ ++ /* dump cfe version */ ++ cfe = boot_addr + BCM963XX_CFE_VERSION_OFFSET; ++ if (!memcmp(cfe, "cfe-v", 5)) ++ snprintf(cfe_version, sizeof(cfe_version), "%u.%u.%u-%u.%u", ++ cfe[5], cfe[6], cfe[7], cfe[8], cfe[9]); ++ else ++ strcpy(cfe_version, "unknown"); ++ printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); ++ ++ /* extract nvram data */ ++ memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram)); ++ ++ /* check checksum before using data */ ++ if (nvram.version <= 4) ++ check_len = offsetof(struct bcm963xx_nvram, checksum_old); ++ else ++ check_len = sizeof(nvram); ++ val = 0; ++ p = (u8 *)&nvram; ++ while (check_len--) ++ val += *p; ++ if (val) { ++ printk(KERN_ERR PFX "invalid nvram checksum\n"); ++ return; ++ } ++ ++ /* find board by name */ ++ for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { ++ if (strncmp(nvram.name, bcm963xx_boards[i]->name, ++ sizeof(nvram.name))) ++ continue; ++ /* copy, board desc array is marked initdata */ ++ memcpy(&board, bcm963xx_boards[i], sizeof(board)); ++ break; ++ } ++ ++ /* bail out if board is not found, will complain later */ ++ if (!board.name) ++ return; ++ ++ /* 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) ++ 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 ++ */ ++const char *board_get_name(void) ++{ ++ return board.name; ++} ++ ++/* ++ * register & return a new board mac address ++ */ ++static int board_get_mac_address(u8 *mac) ++{ ++ u8 *p; ++ int count; ++ ++ if (mac_addr_used >= nvram.mac_addr_count) { ++ printk(KERN_ERR PFX "not enough mac address\n"); ++ return -ENODEV; ++ } ++ ++ memcpy(mac, nvram.mac_addr_base, 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; ++} ++ ++static struct mtd_partition mtd_partitions[] = { ++ { ++ .name = "cfe", ++ .offset = 0x0, ++ .size = 0x40000, ++ } ++}; ++ ++static struct physmap_flash_data flash_data = { ++ .width = 2, ++ .nr_parts = ARRAY_SIZE(mtd_partitions), ++ .parts = mtd_partitions, ++}; ++ ++static struct resource mtd_resources[] = { ++ { ++ .start = 0, /* filled at runtime */ ++ .end = 0, /* filled at runtime */ ++ .flags = IORESOURCE_MEM, ++ } ++}; ++ ++static struct platform_device mtd_dev = { ++ .name = "physmap-flash", ++ .resource = mtd_resources, ++ .num_resources = ARRAY_SIZE(mtd_resources), ++ .dev = { ++ .platform_data = &flash_data, ++ }, ++}; ++ ++/* ++ * third stage init callback, register all board devices. ++ */ ++int __init board_register_devices(void) ++{ ++ u32 val; ++ ++ bcm63xx_uart_register(); ++ ++ if (board.has_pccard) ++ bcm63xx_pcmcia_register(); ++ ++ if (board.has_enet0 && ++ !board_get_mac_address(board.enet0.mac_addr)) ++ bcm63xx_enet_register(0, &board.enet0); ++ ++ if (board.has_enet1 && ++ !board_get_mac_address(board.enet1.mac_addr)) ++ bcm63xx_enet_register(1, &board.enet1); ++ ++ if (board.has_ohci0) ++ bcm63xx_ohci_register(); ++ ++ if (board.has_ehci0) ++ bcm63xx_ehci_register(); ++ ++ ++ /* 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; ++ ++ platform_device_register(&mtd_dev); ++ ++ return 0; ++} ++ +diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c +index f0b49e8..d97ceed 100644 +--- a/arch/mips/bcm63xx/prom.c ++++ b/arch/mips/bcm63xx/prom.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -36,6 +37,9 @@ void __init prom_init(void) + + /* assign command line from kernel config */ + strcpy(arcs_cmdline, CONFIG_CMDLINE); ++ ++ /* do low level board init */ ++ board_prom_init(); + } + + void __init prom_free_prom_memory(void) +diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c +index 4d8b127..c4516fb 100644 +--- a/arch/mips/bcm63xx/setup.c ++++ b/arch/mips/bcm63xx/setup.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -87,8 +88,9 @@ static void __bcm63xx_machine_reboot(char *p) + const char *get_system_type(void) + { + static char buf[128]; +- sprintf(buf, "bcm963xx (0x%04x/0x%04X)", +- bcm63xx_get_cpu_id(), bcm63xx_get_cpu_rev()); ++ snprintf(buf, sizeof (buf), "bcm63xx/%s (0x%04x/0x%04X)", ++ board_get_name(), ++ bcm63xx_get_cpu_id(), bcm63xx_get_cpu_rev()); + return buf; + } + +@@ -96,6 +98,7 @@ void __init plat_time_init(void) + { + mips_hpt_frequency = bcm63xx_get_cpu_freq() / 2; + } ++ + void __init plat_mem_setup(void) + { + add_memory_region(0, bcm63xx_get_memory_size(), BOOT_MEM_RAM); +@@ -107,4 +110,13 @@ void __init plat_mem_setup(void) + set_io_port_base(0); + ioport_resource.start = 0; + ioport_resource.end = ~0; ++ ++ board_setup(); ++} ++ ++int __init bcm63xx_register_devices(void) ++{ ++ return board_register_devices(); + } ++ ++device_initcall(bcm63xx_register_devices); +diff --git a/include/asm-mips/mach-bcm63xx/bcm63xx_board.h b/include/asm-mips/mach-bcm63xx/bcm63xx_board.h +new file mode 100644 +index 0000000..fa3e7e6 +--- /dev/null ++++ b/include/asm-mips/mach-bcm63xx/bcm63xx_board.h +@@ -0,0 +1,12 @@ ++#ifndef BCM63XX_BOARD_H_ ++#define BCM63XX_BOARD_H_ ++ ++const char *board_get_name(void); ++ ++void board_prom_init(void); ++ ++void board_setup(void); ++ ++int board_register_devices(void); ++ ++#endif /* ! BCM63XX_BOARD_H_ */ +diff --git a/include/asm-mips/mach-bcm63xx/board_bcm963xx.h b/include/asm-mips/mach-bcm63xx/board_bcm963xx.h +new file mode 100644 +index 0000000..17e4e7e +--- /dev/null ++++ b/include/asm-mips/mach-bcm63xx/board_bcm963xx.h +@@ -0,0 +1,50 @@ ++#ifndef BOARD_BCM963XX_H_ ++#define BOARD_BCM963XX_H_ ++ ++#include ++#include ++ ++/* ++ * flash mapping ++ */ ++#define BCM963XX_CFE_VERSION_OFFSET 0x570 ++#define BCM963XX_NVRAM_OFFSET 0x580 ++ ++/* ++ * nvram structure ++ */ ++struct bcm963xx_nvram { ++ u32 version; ++ u8 reserved1[256]; ++ u8 name[16]; ++ u32 main_tp_number; ++ u32 psi_size; ++ u32 mac_addr_count; ++ u8 mac_addr_base[6]; ++ u8 reserved2[2]; ++ u32 checksum_old; ++ u8 reserved3[720]; ++ u32 checksum_high; ++}; ++ ++/* ++ * board definition ++ */ ++struct board_info { ++ u8 name[16]; ++ unsigned int expected_cpu_id; ++ ++ /* enabled feature/device */ ++ unsigned int has_enet0:1; ++ unsigned int has_enet1:1; ++ unsigned int has_pci:1; ++ unsigned int has_pccard:1; ++ unsigned int has_ohci0:1; ++ unsigned int has_ehci0:1; ++ ++ /* ethernet config */ ++ struct bcm63xx_enet_platform_data enet0; ++ struct bcm63xx_enet_platform_data enet1; ++}; ++ ++#endif /* ! BOARD_BCM963XX_H_ */ +-- +1.5.4.3 + -- cgit v1.2.3