From eeff6d8600afa69fa06ef69a6ffe427b1189cef4 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Tue, 26 Aug 2008 16:01:21 +0200 Subject: [PATCH 01/17] [ARM] Orion: wire up ethernet error interrupt Wire up the ethernet port's error interrupt so that the mv643xx_eth driver can sleep for SMI event completion instead of having to busy-wait for it. Signed-off-by: Lennert Buytenhek --- arch/arm/mach-orion5x/common.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 7b11e552bc5a..83367265bcf6 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -154,6 +154,10 @@ static struct resource orion5x_eth_shared_resources[] = { .start = ORION5X_ETH_PHYS_BASE + 0x2000, .end = ORION5X_ETH_PHYS_BASE + 0x3fff, .flags = IORESOURCE_MEM, + }, { + .start = IRQ_ORION5X_ETH_ERR, + .end = IRQ_ORION5X_ETH_ERR, + .flags = IORESOURCE_IRQ, }, }; @@ -163,7 +167,7 @@ static struct platform_device orion5x_eth_shared = { .dev = { .platform_data = &orion5x_eth_shared_data, }, - .num_resources = 1, + .num_resources = ARRAY_SIZE(orion5x_eth_shared_resources), .resource = orion5x_eth_shared_resources, }; From 144f814a439ff0b8ad62c51d74e56b490e651ded Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Tue, 26 Aug 2008 16:04:05 +0200 Subject: [PATCH 02/17] [ARM] Kirkwood: wire up ethernet error interrupt Wire up the ethernet port's error interrupt so that the mv643xx_eth driver can sleep for SMI event completion instead of having to busy-wait for it. Signed-off-by: Lennert Buytenhek --- arch/arm/mach-kirkwood/common.c | 7 ++++++- arch/arm/mach-kirkwood/include/mach/irqs.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 189f16f3619d..435fb35a4845 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -108,6 +108,11 @@ static struct resource kirkwood_ge00_shared_resources[] = { .start = GE00_PHYS_BASE + 0x2000, .end = GE00_PHYS_BASE + 0x3fff, .flags = IORESOURCE_MEM, + }, { + .name = "ge00 err irq", + .start = IRQ_KIRKWOOD_GE00_ERR, + .end = IRQ_KIRKWOOD_GE00_ERR, + .flags = IORESOURCE_IRQ, }, }; @@ -117,7 +122,7 @@ static struct platform_device kirkwood_ge00_shared = { .dev = { .platform_data = &kirkwood_ge00_shared_data, }, - .num_resources = 1, + .num_resources = ARRAY_SIZE(kirkwood_ge00_shared_resources), .resource = kirkwood_ge00_shared_resources, }; diff --git a/arch/arm/mach-kirkwood/include/mach/irqs.h b/arch/arm/mach-kirkwood/include/mach/irqs.h index 6fd05838c72d..ffab89f21c11 100644 --- a/arch/arm/mach-kirkwood/include/mach/irqs.h +++ b/arch/arm/mach-kirkwood/include/mach/irqs.h @@ -50,6 +50,7 @@ #define IRQ_KIRKWOOD_GPIO_HIGH_0_7 39 #define IRQ_KIRKWOOD_GPIO_HIGH_8_15 40 #define IRQ_KIRKWOOD_GPIO_HIGH_16_23 41 +#define IRQ_KIRKWOOD_GE00_ERR 46 /* * KIRKWOOD General Purpose Pins From 1f8081f539a80c3d36a17ecd094d104eae60c01c Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Tue, 26 Aug 2008 16:04:05 +0200 Subject: [PATCH 03/17] [ARM] mv78xx0: wire up ethernet error interrupt Wire up the ethernet port's error interrupt so that the mv643xx_eth driver can sleep for SMI event completion instead of having to busy-wait for it. Signed-off-by: Lennert Buytenhek Signed-off-by: Nicolas Pitre --- arch/arm/mach-mv78xx0/common.c | 7 ++++++- .../mach-mv78xx0/include/mach/entry-macro.S | 18 +++++++++++++----- arch/arm/mach-mv78xx0/include/mach/irqs.h | 7 ++++++- arch/arm/mach-mv78xx0/include/mach/mv78xx0.h | 2 ++ arch/arm/mach-mv78xx0/irq.c | 1 + 5 files changed, 28 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-mv78xx0/common.c b/arch/arm/mach-mv78xx0/common.c index 953a26c469cb..d56a05e8356b 100644 --- a/arch/arm/mach-mv78xx0/common.c +++ b/arch/arm/mach-mv78xx0/common.c @@ -285,6 +285,11 @@ static struct resource mv78xx0_ge00_shared_resources[] = { .start = GE00_PHYS_BASE + 0x2000, .end = GE00_PHYS_BASE + 0x3fff, .flags = IORESOURCE_MEM, + }, { + .name = "ge err irq", + .start = IRQ_MV78XX0_GE_ERR, + .end = IRQ_MV78XX0_GE_ERR, + .flags = IORESOURCE_IRQ, }, }; @@ -294,7 +299,7 @@ static struct platform_device mv78xx0_ge00_shared = { .dev = { .platform_data = &mv78xx0_ge00_shared_data, }, - .num_resources = 1, + .num_resources = ARRAY_SIZE(mv78xx0_ge00_shared_resources), .resource = mv78xx0_ge00_shared_resources, }; diff --git a/arch/arm/mach-mv78xx0/include/mach/entry-macro.S b/arch/arm/mach-mv78xx0/include/mach/entry-macro.S index ed4a46bcd3b0..fbfb2693ce6c 100644 --- a/arch/arm/mach-mv78xx0/include/mach/entry-macro.S +++ b/arch/arm/mach-mv78xx0/include/mach/entry-macro.S @@ -26,14 +26,22 @@ ldr \tmp, [\base, #IRQ_MASK_LOW_OFF] mov \irqnr, #31 ands \irqstat, \irqstat, \tmp + bne 1001f @ if no low interrupts set, check high interrupts - ldreq \irqstat, [\base, #IRQ_CAUSE_HIGH_OFF] - ldreq \tmp, [\base, #IRQ_MASK_HIGH_OFF] - moveq \irqnr, #63 - andeqs \irqstat, \irqstat, \tmp + ldr \irqstat, [\base, #IRQ_CAUSE_HIGH_OFF] + ldr \tmp, [\base, #IRQ_MASK_HIGH_OFF] + mov \irqnr, #63 + ands \irqstat, \irqstat, \tmp + bne 1001f + + @ if no high interrupts set, check error interrupts + ldr \irqstat, [\base, #IRQ_CAUSE_ERR_OFF] + ldr \tmp, [\base, #IRQ_MASK_ERR_OFF] + mov \irqnr, #95 + ands \irqstat, \irqstat, \tmp @ find first active interrupt source - clzne \irqstat, \irqstat +1001: clzne \irqstat, \irqstat subne \irqnr, \irqnr, \irqstat .endm diff --git a/arch/arm/mach-mv78xx0/include/mach/irqs.h b/arch/arm/mach-mv78xx0/include/mach/irqs.h index 995d7fb8d06f..bebc330281ec 100644 --- a/arch/arm/mach-mv78xx0/include/mach/irqs.h +++ b/arch/arm/mach-mv78xx0/include/mach/irqs.h @@ -79,10 +79,15 @@ #define IRQ_MV78XX0_DB_IN 60 #define IRQ_MV78XX0_DB_OUT 61 +/* + * MV78xx0 Error Interrupt Controller + */ +#define IRQ_MV78XX0_GE_ERR 70 + /* * MV78XX0 General Purpose Pins */ -#define IRQ_MV78XX0_GPIO_START 64 +#define IRQ_MV78XX0_GPIO_START 96 #define NR_GPIO_IRQS GPIO_MAX #define NR_IRQS (IRQ_MV78XX0_GPIO_START + NR_GPIO_IRQS) diff --git a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h index ad664178d6e1..ee9c5593ee92 100644 --- a/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h +++ b/arch/arm/mach-mv78xx0/include/mach/mv78xx0.h @@ -71,8 +71,10 @@ #define BRIDGE_INT_TIMER1 0x0004 #define BRIDGE_INT_TIMER1_CLR (~0x0004) #define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0200) +#define IRQ_CAUSE_ERR_OFF 0x0000 #define IRQ_CAUSE_LOW_OFF 0x0004 #define IRQ_CAUSE_HIGH_OFF 0x0008 +#define IRQ_MASK_ERR_OFF 0x000c #define IRQ_MASK_LOW_OFF 0x0010 #define IRQ_MASK_HIGH_OFF 0x0014 #define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE | 0x0300) diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c index 28248d37b999..503e5d195ae5 100644 --- a/arch/arm/mach-mv78xx0/irq.c +++ b/arch/arm/mach-mv78xx0/irq.c @@ -19,4 +19,5 @@ void __init mv78xx0_init_irq(void) { orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)); orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)); + orion_irq_init(64, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_ERR_OFF)); } From ebe35aff883496c07248df82c8576c3b6e84bbbe Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Fri, 29 Aug 2008 05:55:51 +0200 Subject: [PATCH 04/17] [ARM] Orion: prepare for runtime-determined timer tick rate Currently, orion5x uses a hardcoded timer tick rate of 166 MHz, but the actual timer tick rate varies between different members of the SoC family (and can vary based on strap pin settings). This patch prepares for runtime determination of the timer tick rate. Signed-off-by: Lennert Buytenhek --- arch/arm/mach-orion5x/common.c | 21 ++++++++++++++++----- arch/arm/mach-orion5x/common.h | 1 + arch/arm/mach-orion5x/include/mach/timex.h | 2 -- arch/arm/mach-orion5x/kurobox_pro-setup.c | 2 +- arch/arm/mach-orion5x/tsx09-common.c | 3 ++- 5 files changed, 20 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 83367265bcf6..8a8b089b8b74 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -146,7 +146,6 @@ void __init orion5x_ehci1_init(void) ****************************************************************************/ struct mv643xx_eth_shared_platform_data orion5x_eth_shared_data = { .dram = &orion5x_mbus_dram_info, - .t_clk = ORION5X_TCLK, }; static struct resource orion5x_eth_shared_resources[] = { @@ -282,7 +281,7 @@ static struct plat_serial8250_port orion5x_uart0_data[] = { .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, .iotype = UPIO_MEM, .regshift = 2, - .uartclk = ORION5X_TCLK, + .uartclk = 0, }, { }, }; @@ -326,7 +325,7 @@ static struct plat_serial8250_port orion5x_uart1_data[] = { .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, .iotype = UPIO_MEM, .regshift = 2, - .uartclk = ORION5X_TCLK, + .uartclk = 0, }, { }, }; @@ -459,9 +458,17 @@ void __init orion5x_xor_init(void) /***************************************************************************** * Time handling ****************************************************************************/ +int orion5x_tclk; + +int __init orion5x_find_tclk(void) +{ + return 166666667; +} + static void orion5x_timer_init(void) { - orion_time_init(IRQ_ORION5X_BRIDGE, ORION5X_TCLK); + orion5x_tclk = orion5x_find_tclk(); + orion_time_init(IRQ_ORION5X_BRIDGE, orion5x_tclk); } struct sys_timer orion5x_timer = { @@ -514,7 +521,11 @@ void __init orion5x_init(void) u32 dev, rev; orion5x_id(&dev, &rev, &dev_name); - printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, ORION5X_TCLK); + printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, orion5x_tclk); + + orion5x_eth_shared_data.t_clk = orion5x_tclk; + orion5x_uart0_data[0].uartclk = orion5x_tclk; + orion5x_uart1_data[0].uartclk = orion5x_tclk; /* * Setup Orion address map diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h index e75bd7004b94..c8598cc7cd58 100644 --- a/arch/arm/mach-orion5x/common.h +++ b/arch/arm/mach-orion5x/common.h @@ -10,6 +10,7 @@ struct mv_sata_platform_data; void orion5x_map_io(void); void orion5x_init_irq(void); void orion5x_init(void); +extern int orion5x_tclk; extern struct sys_timer orion5x_timer; /* diff --git a/arch/arm/mach-orion5x/include/mach/timex.h b/arch/arm/mach-orion5x/include/mach/timex.h index e82e44db7629..4c69820e0810 100644 --- a/arch/arm/mach-orion5x/include/mach/timex.h +++ b/arch/arm/mach-orion5x/include/mach/timex.h @@ -9,5 +9,3 @@ */ #define CLOCK_TICK_RATE (100 * HZ) - -#define ORION5X_TCLK 166666667 diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c index cb72f1bb9cb7..171ffaf98ddf 100644 --- a/arch/arm/mach-orion5x/kurobox_pro-setup.c +++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c @@ -291,7 +291,7 @@ static void kurobox_pro_power_off(void) const unsigned char shutdownwait[] = {0x00, 0x0c}; const unsigned char poweroff[] = {0x00, 0x06}; /* 38400 baud divisor */ - const unsigned divisor = ((ORION5X_TCLK + (8 * 38400)) / (16 * 38400)); + const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400)); pr_info("%s: triggering power-off...\n", __func__); diff --git a/arch/arm/mach-orion5x/tsx09-common.c b/arch/arm/mach-orion5x/tsx09-common.c index 83feac3147a6..5128da1101bf 100644 --- a/arch/arm/mach-orion5x/tsx09-common.c +++ b/arch/arm/mach-orion5x/tsx09-common.c @@ -16,6 +16,7 @@ #include #include #include "tsx09-common.h" +#include "common.h" /***************************************************************************** * QNAP TS-x09 specific power off method via UART1-attached PIC @@ -26,7 +27,7 @@ void qnap_tsx09_power_off(void) { /* 19200 baud divisor */ - const unsigned divisor = ((ORION5X_TCLK + (8 * 19200)) / (16 * 19200)); + const unsigned divisor = ((orion5x_tclk + (8 * 19200)) / (16 * 19200)); pr_info("%s: triggering power-off...\n", __func__); From 0eb66974c089547ed72fe4754076d3b1358b8614 Mon Sep 17 00:00:00 2001 From: Christopher Moore Date: Fri, 18 Jul 2008 00:25:10 +0200 Subject: [PATCH 05/17] [ARM] Orion: add LaCie Ethernet Disk mini V2 support This patch adds support for the LaCie Ethernet Disk mini V2. Signed-off-by: Albert Aribaud Signed-off-by: Christopher Moore Signed-off-by: Lennert Buytenhek --- arch/arm/configs/orion5x_defconfig | 1 + arch/arm/mach-orion5x/Kconfig | 7 + arch/arm/mach-orion5x/Makefile | 1 + arch/arm/mach-orion5x/edmini_v2-setup.c | 202 ++++++++++++++++++++++++ 4 files changed, 211 insertions(+) create mode 100644 arch/arm/mach-orion5x/edmini_v2-setup.c diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig index 1464ffe71717..182031615fba 100644 --- a/arch/arm/configs/orion5x_defconfig +++ b/arch/arm/configs/orion5x_defconfig @@ -170,6 +170,7 @@ CONFIG_MACH_TS409=y CONFIG_MACH_WRT350N_V2=y CONFIG_MACH_TS78XX=y CONFIG_MACH_MV2120=y +CONFIG_MACH_EDMINI_V2=y CONFIG_MACH_MSS2=y CONFIG_MACH_WNR854T=y CONFIG_MACH_RD88F5181L_GE=y diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index ddcd41b15d17..ff405c47490f 100644 --- a/arch/arm/mach-orion5x/Kconfig +++ b/arch/arm/mach-orion5x/Kconfig @@ -68,6 +68,13 @@ config MACH_MV2120 Say 'Y' here if you want your kernel to support the HP Media Vault mv2120 or mv5100. +config MACH_EDMINI_V2 + bool "LaCie Ethernet Disk mini V2" + select I2C_BOARDINFO + help + Say 'Y' here if you want your kernel to support the + LaCie Ethernet Disk mini V2. + config MACH_MSS2 bool "Maxtor Shared Storage II" help diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile index fcc48a8864f3..b6da94bdb3f7 100644 --- a/arch/arm/mach-orion5x/Makefile +++ b/arch/arm/mach-orion5x/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_MACH_TS409) += ts409-setup.o tsx09-common.o obj-$(CONFIG_MACH_WRT350N_V2) += wrt350n-v2-setup.o obj-$(CONFIG_MACH_TS78XX) += ts78xx-setup.o obj-$(CONFIG_MACH_MV2120) += mv2120-setup.o +obj-$(CONFIG_MACH_EDMINI_V2) += edmini_v2-setup.o obj-$(CONFIG_MACH_MSS2) += mss2-setup.o obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o diff --git a/arch/arm/mach-orion5x/edmini_v2-setup.c b/arch/arm/mach-orion5x/edmini_v2-setup.c new file mode 100644 index 000000000000..2d67591dbce6 --- /dev/null +++ b/arch/arm/mach-orion5x/edmini_v2-setup.c @@ -0,0 +1,202 @@ +/* + * arch/arm/mach-orion5x/edmini_v2-setup.c + * + * LaCie Ethernet Disk mini V2 Setup + * + * Copyright (C) 2008 Christopher Moore + * Copyright (C) 2008 Albert Aribaud + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +/* + * TODO: add Orion USB device port init when kernel.org support is added. + * TODO: add flash write support: see below. + * TODO: add power-off support. + * TODO: add I2C EEPROM support. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +/***************************************************************************** + * EDMINI_V2 Info + ****************************************************************************/ + +/* + * 512KB NOR flash Device bus boot chip select + */ + +#define EDMINI_V2_NOR_BOOT_BASE 0xfff80000 +#define EDMINI_V2_NOR_BOOT_SIZE SZ_512K + +/***************************************************************************** + * 512KB NOR Flash on BOOT Device + ****************************************************************************/ + +/* + * Currently the MTD code does not recognize the MX29LV400CBCT as a bottom + * -type device. This could cause risks of accidentally erasing critical + * flash sectors. We thus define a single, write-protected partition covering + * the whole flash. + * TODO: once the flash part TOP/BOTTOM detection issue is sorted out in the MTD + * code, break this into at least three partitions: 'u-boot code', 'u-boot + * environment' and 'whatever is left'. + */ + +static struct mtd_partition edmini_v2_partitions[] = { + { + .name = "Full512kb", + .size = 0x00080000, + .offset = 0x00000000, + .mask_flags = MTD_WRITEABLE, + }, +}; + +static struct physmap_flash_data edmini_v2_nor_flash_data = { + .width = 1, + .parts = edmini_v2_partitions, + .nr_parts = ARRAY_SIZE(edmini_v2_partitions), +}; + +static struct resource edmini_v2_nor_flash_resource = { + .flags = IORESOURCE_MEM, + .start = EDMINI_V2_NOR_BOOT_BASE, + .end = EDMINI_V2_NOR_BOOT_BASE + + EDMINI_V2_NOR_BOOT_SIZE - 1, +}; + +static struct platform_device edmini_v2_nor_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &edmini_v2_nor_flash_data, + }, + .num_resources = 1, + .resource = &edmini_v2_nor_flash_resource, +}; + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data edmini_v2_eth_data = { + .phy_addr = 8, +}; + +/***************************************************************************** + * RTC 5C372a on I2C bus + ****************************************************************************/ + +#define EDMINIV2_RTC_GPIO 3 + +static struct i2c_board_info __initdata edmini_v2_i2c_rtc = { + I2C_BOARD_INFO("rs5c372a", 0x32), + .irq = 0, +}; + +/***************************************************************************** + * Sata + ****************************************************************************/ + +static struct mv_sata_platform_data edmini_v2_sata_data = { + .n_ports = 2, +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ +static struct orion5x_mpp_mode edminiv2_mpp_modes[] __initdata = { + { 0, MPP_UNUSED }, + { 1, MPP_UNUSED }, + { 2, MPP_UNUSED }, + { 3, MPP_GPIO }, /* RTC interrupt */ + { 4, MPP_UNUSED }, + { 5, MPP_UNUSED }, + { 6, MPP_UNUSED }, + { 7, MPP_UNUSED }, + { 8, MPP_UNUSED }, + { 9, MPP_UNUSED }, + { 10, MPP_UNUSED }, + { 11, MPP_UNUSED }, + { 12, MPP_SATA_LED }, /* SATA 0 presence */ + { 13, MPP_SATA_LED }, /* SATA 1 presence */ + { 14, MPP_SATA_LED }, /* SATA 0 active */ + { 15, MPP_SATA_LED }, /* SATA 1 active */ + /* 16: Power LED control (0 = On, 1 = Off) */ + { 16, MPP_GPIO }, + /* 17: Power LED control select (0 = CPLD, 1 = GPIO16) */ + { 17, MPP_GPIO }, + /* 18: Power button status (0 = Released, 1 = Pressed) */ + { 18, MPP_GPIO }, + { 19, MPP_UNUSED }, + { -1 } +}; + +static void __init edmini_v2_init(void) +{ + /* + * Setup basic Orion functions. Need to be called early. + */ + orion5x_init(); + + orion5x_mpp_conf(edminiv2_mpp_modes); + + /* + * Configure peripherals. + */ + orion5x_ehci0_init(); + orion5x_eth_init(&edmini_v2_eth_data); + orion5x_i2c_init(); + orion5x_sata_init(&edmini_v2_sata_data); + orion5x_uart0_init(); + + orion5x_setup_dev_boot_win(EDMINI_V2_NOR_BOOT_BASE, + EDMINI_V2_NOR_BOOT_SIZE); + platform_device_register(&edmini_v2_nor_flash); + + pr_notice("edmini_v2: USB device port, flash write and power-off " + "are not yet supported.\n"); + + /* Get RTC IRQ and register the chip */ + if (gpio_request(EDMINIV2_RTC_GPIO, "rtc") == 0) { + if (gpio_direction_input(EDMINIV2_RTC_GPIO) == 0) + edmini_v2_i2c_rtc.irq = gpio_to_irq(EDMINIV2_RTC_GPIO); + else + gpio_free(EDMINIV2_RTC_GPIO); + } + + if (edmini_v2_i2c_rtc.irq == 0) + pr_warning("edmini_v2: failed to get RTC IRQ\n"); + + i2c_register_board_info(0, &edmini_v2_i2c_rtc, 1); +} + +/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */ +MACHINE_START(EDMINI_V2, "LaCie Ethernet Disk mini V2") + /* Maintainer: Christopher Moore */ + .phys_io = ORION5X_REGS_PHYS_BASE, + .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, + .boot_params = 0x00000100, + .init_machine = edmini_v2_init, + .map_io = orion5x_map_io, + .init_irq = orion5x_init_irq, + .timer = &orion5x_timer, + .fixup = tag_fixup_mem32, +MACHINE_END From 104ea0781a7052e03d731e2ff3df8bde66036bad Mon Sep 17 00:00:00 2001 From: Sylver Bruneau Date: Thu, 28 Aug 2008 22:18:54 +0200 Subject: [PATCH 06/17] [ARM] Orion: add Buffalo Terastation Pro II/Live support This patch adds support for the Buffalo Terastation Pro II/Live. Signed-off-by: Sylver Bruneau Signed-off-by: Lennert Buytenhek --- arch/arm/mach-orion5x/Kconfig | 6 + arch/arm/mach-orion5x/Makefile | 1 + .../arm/mach-orion5x/terastation_pro2-setup.c | 369 ++++++++++++++++++ 3 files changed, 376 insertions(+) create mode 100644 arch/arm/mach-orion5x/terastation_pro2-setup.c diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index ff405c47490f..c738f450f936 100644 --- a/arch/arm/mach-orion5x/Kconfig +++ b/arch/arm/mach-orion5x/Kconfig @@ -36,6 +36,12 @@ config MACH_TS209 Say 'Y' here if you want your kernel to support the QNAP TS-109/TS-209 platform. +config MACH_TERASTATION_PRO2 + bool "Buffalo Terastation Pro II/Live" + help + Say 'Y' here if you want your kernel to support the + Buffalo Terastation Pro II/Live platform. + config MACH_LINKSTATION_PRO bool "Buffalo Linkstation Pro/Live" select I2C_BOARDINFO diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile index b6da94bdb3f7..39e41a6b61e1 100644 --- a/arch/arm/mach-orion5x/Makefile +++ b/arch/arm/mach-orion5x/Makefile @@ -2,6 +2,7 @@ obj-y += common.o addr-map.o pci.o gpio.o irq.o mpp.o obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o +obj-$(CONFIG_MACH_TERASTATION_PRO2) += terastation_pro2-setup.o obj-$(CONFIG_MACH_LINKSTATION_PRO) += kurobox_pro-setup.o obj-$(CONFIG_MACH_DNS323) += dns323-setup.o obj-$(CONFIG_MACH_TS209) += ts209-setup.o tsx09-common.o diff --git a/arch/arm/mach-orion5x/terastation_pro2-setup.c b/arch/arm/mach-orion5x/terastation_pro2-setup.c new file mode 100644 index 000000000000..0b101d7d41c2 --- /dev/null +++ b/arch/arm/mach-orion5x/terastation_pro2-setup.c @@ -0,0 +1,369 @@ +/* + * Buffalo Terastation Pro II/Live Board Setup + * + * Maintainer: Sylver Bruneau + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +/***************************************************************************** + * Terastation Pro 2/Live Info + ****************************************************************************/ + +/* + * Terastation Pro 2 hardware : + * - Marvell 88F5281-D0 + * - Marvell 88SX6042 SATA controller (PCI) + * - Marvell 88E1118 Gigabit Ethernet PHY + * - 256KB NOR flash + * - 128MB of DDR RAM + * - PCIe port (not equipped) + */ + +/* + * 256K NOR flash Device bus boot chip select + */ + +#define TSP2_NOR_BOOT_BASE 0xf4000000 +#define TSP2_NOR_BOOT_SIZE SZ_256K + +/***************************************************************************** + * 256KB NOR Flash on BOOT Device + ****************************************************************************/ + +static struct physmap_flash_data tsp2_nor_flash_data = { + .width = 1, +}; + +static struct resource tsp2_nor_flash_resource = { + .flags = IORESOURCE_MEM, + .start = TSP2_NOR_BOOT_BASE, + .end = TSP2_NOR_BOOT_BASE + TSP2_NOR_BOOT_SIZE - 1, +}; + +static struct platform_device tsp2_nor_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &tsp2_nor_flash_data, + }, + .num_resources = 1, + .resource = &tsp2_nor_flash_resource, +}; + +/***************************************************************************** + * PCI + ****************************************************************************/ +#define TSP2_PCI_SLOT0_OFFS 7 +#define TSP2_PCI_SLOT0_IRQ_PIN 11 + +void __init tsp2_pci_preinit(void) +{ + int pin; + + /* + * Configure PCI GPIO IRQ pins + */ + pin = TSP2_PCI_SLOT0_IRQ_PIN; + if (gpio_request(pin, "PCI Int1") == 0) { + if (gpio_direction_input(pin) == 0) { + set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW); + } else { + printk(KERN_ERR "tsp2_pci_preinit failed " + "to set_irq_type pin %d\n", pin); + gpio_free(pin); + } + } else { + printk(KERN_ERR "tsp2_pci_preinit failed to " + "gpio_request %d\n", pin); + } +} + +static int __init tsp2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + int irq; + + /* + * Check for devices with hard-wired IRQs. + */ + irq = orion5x_pci_map_irq(dev, slot, pin); + if (irq != -1) + return irq; + + /* + * PCI IRQs are connected via GPIOs. + */ + if (slot == TSP2_PCI_SLOT0_OFFS) + return gpio_to_irq(TSP2_PCI_SLOT0_IRQ_PIN); + + return -1; +} + +static struct hw_pci tsp2_pci __initdata = { + .nr_controllers = 2, + .preinit = tsp2_pci_preinit, + .swizzle = pci_std_swizzle, + .setup = orion5x_pci_sys_setup, + .scan = orion5x_pci_sys_scan_bus, + .map_irq = tsp2_pci_map_irq, +}; + +static int __init tsp2_pci_init(void) +{ + if (machine_is_terastation_pro2()) + pci_common_init(&tsp2_pci); + + return 0; +} + +subsys_initcall(tsp2_pci_init); + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data tsp2_eth_data = { + .phy_addr = 0, +}; + +/***************************************************************************** + * RTC 5C372a on I2C bus + ****************************************************************************/ + +#define TSP2_RTC_GPIO 9 + +static struct i2c_board_info __initdata tsp2_i2c_rtc = { + I2C_BOARD_INFO("rs5c372a", 0x32), +}; + +/***************************************************************************** + * Terastation Pro II specific power off method via UART1-attached + * microcontroller + ****************************************************************************/ + +#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2)) + +static int tsp2_miconread(unsigned char *buf, int count) +{ + int i; + int timeout; + + for (i = 0; i < count; i++) { + timeout = 10; + + while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) { + if (--timeout == 0) + break; + udelay(1000); + } + + if (timeout == 0) + break; + buf[i] = readl(UART1_REG(RX)); + } + + /* return read bytes */ + return i; +} + +static int tsp2_miconwrite(const unsigned char *buf, int count) +{ + int i = 0; + + while (count--) { + while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE)) + barrier(); + writel(buf[i++], UART1_REG(TX)); + } + + return 0; +} + +static int tsp2_miconsend(const unsigned char *data, int count) +{ + int i; + unsigned char checksum = 0; + unsigned char recv_buf[40]; + unsigned char send_buf[40]; + unsigned char correct_ack[3]; + int retry = 2; + + /* Generate checksum */ + for (i = 0; i < count; i++) + checksum -= data[i]; + + do { + /* Send data */ + tsp2_miconwrite(data, count); + + /* send checksum */ + tsp2_miconwrite(&checksum, 1); + + if (tsp2_miconread(recv_buf, sizeof(recv_buf)) <= 3) { + printk(KERN_ERR ">%s: receive failed.\n", __func__); + + /* send preamble to clear the receive buffer */ + memset(&send_buf, 0xff, sizeof(send_buf)); + tsp2_miconwrite(send_buf, sizeof(send_buf)); + + /* make dummy reads */ + mdelay(100); + tsp2_miconread(recv_buf, sizeof(recv_buf)); + } else { + /* Generate expected ack */ + correct_ack[0] = 0x01; + correct_ack[1] = data[1]; + correct_ack[2] = 0x00; + + /* checksum Check */ + if ((recv_buf[0] + recv_buf[1] + recv_buf[2] + + recv_buf[3]) & 0xFF) { + printk(KERN_ERR ">%s: Checksum Error : " + "Received data[%02x, %02x, %02x, %02x]" + "\n", __func__, recv_buf[0], + recv_buf[1], recv_buf[2], recv_buf[3]); + } else { + /* Check Received Data */ + if (correct_ack[0] == recv_buf[0] && + correct_ack[1] == recv_buf[1] && + correct_ack[2] == recv_buf[2]) { + /* Interval for next command */ + mdelay(10); + + /* Receive ACK */ + return 0; + } + } + /* Received NAK or illegal Data */ + printk(KERN_ERR ">%s: Error : NAK or Illegal Data " + "Received\n", __func__); + } + } while (retry--); + + /* Interval for next command */ + mdelay(10); + + return -1; +} + +static void tsp2_power_off(void) +{ + const unsigned char watchdogkill[] = {0x01, 0x35, 0x00}; + const unsigned char shutdownwait[] = {0x00, 0x0c}; + const unsigned char poweroff[] = {0x00, 0x06}; + /* 38400 baud divisor */ + const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400)); + + pr_info("%s: triggering power-off...\n", __func__); + + /* hijack uart1 and reset into sane state (38400,8n1,even parity) */ + writel(0x83, UART1_REG(LCR)); + writel(divisor & 0xff, UART1_REG(DLL)); + writel((divisor >> 8) & 0xff, UART1_REG(DLM)); + writel(0x1b, UART1_REG(LCR)); + writel(0x00, UART1_REG(IER)); + writel(0x07, UART1_REG(FCR)); + writel(0x00, UART1_REG(MCR)); + + /* Send the commands to shutdown the Terastation Pro II */ + tsp2_miconsend(watchdogkill, sizeof(watchdogkill)) ; + tsp2_miconsend(shutdownwait, sizeof(shutdownwait)) ; + tsp2_miconsend(poweroff, sizeof(poweroff)); +} + +/***************************************************************************** + * General Setup + ****************************************************************************/ +static struct orion5x_mpp_mode tsp2_mpp_modes[] __initdata = { + { 0, MPP_PCIE_RST_OUTn }, + { 1, MPP_UNUSED }, + { 2, MPP_UNUSED }, + { 3, MPP_UNUSED }, + { 4, MPP_NAND }, /* BOOT NAND Flash REn */ + { 5, MPP_NAND }, /* BOOT NAND Flash WEn */ + { 6, MPP_NAND }, /* BOOT NAND Flash HREn[0] */ + { 7, MPP_NAND }, /* BOOT NAND Flash WEn[0] */ + { 8, MPP_GPIO }, /* MICON int */ + { 9, MPP_GPIO }, /* RTC int */ + { 10, MPP_UNUSED }, + { 11, MPP_GPIO }, /* PCI Int A */ + { 12, MPP_UNUSED }, + { 13, MPP_GPIO }, /* UPS on UART0 enable */ + { 14, MPP_GPIO }, /* UPS low battery detection */ + { 15, MPP_UNUSED }, + { 16, MPP_UART }, /* UART1 RXD */ + { 17, MPP_UART }, /* UART1 TXD */ + { 18, MPP_UART }, /* UART1 CTSn */ + { 19, MPP_UART }, /* UART1 RTSn */ + { -1 }, +}; + +static void __init tsp2_init(void) +{ + /* + * Setup basic Orion functions. Need to be called early. + */ + orion5x_init(); + + orion5x_mpp_conf(tsp2_mpp_modes); + + /* + * Configure peripherals. + */ + orion5x_setup_dev_boot_win(TSP2_NOR_BOOT_BASE, + TSP2_NOR_BOOT_SIZE); + platform_device_register(&tsp2_nor_flash); + + orion5x_ehci0_init(); + orion5x_eth_init(&tsp2_eth_data); + orion5x_i2c_init(); + orion5x_uart0_init(); + orion5x_uart1_init(); + + /* Get RTC IRQ and register the chip */ + if (gpio_request(TSP2_RTC_GPIO, "rtc") == 0) { + if (gpio_direction_input(TSP2_RTC_GPIO) == 0) + tsp2_i2c_rtc.irq = gpio_to_irq(TSP2_RTC_GPIO); + else + gpio_free(TSP2_RTC_GPIO); + } + if (tsp2_i2c_rtc.irq == 0) + pr_warning("tsp2_init: failed to get RTC IRQ\n"); + i2c_register_board_info(0, &tsp2_i2c_rtc, 1); + + /* register Terastation Pro II specific power-off method */ + pm_power_off = tsp2_power_off; +} + +MACHINE_START(TERASTATION_PRO2, "Buffalo Terastation Pro II/Live") + /* Maintainer: Sylver Bruneau */ + .phys_io = ORION5X_REGS_PHYS_BASE, + .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, + .boot_params = 0x00000100, + .init_machine = tsp2_init, + .map_io = orion5x_map_io, + .init_irq = orion5x_init_irq, + .timer = &orion5x_timer, + .fixup = tag_fixup_mem32, +MACHINE_END From d323ade13b959dfcf14bf18902b600c5cc711dea Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Fri, 29 Aug 2008 06:55:06 +0200 Subject: [PATCH 07/17] [ARM] Orion: add 88F6183 (Orion-1-90) support The Orion-1-90 (88F6183) is another member of the Orion SoC family, which has a 16 bit DDR2 interface, one x1 PCIe port (configurable as Root Complex or Endpoint), one 10/100/1000 ethernet interface, one USB 2.0 port with PHY, one SPDIF/I2S interface, one SDIO interface, one TWSI interface, two UARTs, one SPI interface, a NAND controller, a crypto engine, and a 4-channel DMA engine. Signed-off-by: Lennert Buytenhek --- arch/arm/Kconfig | 2 +- arch/arm/mach-orion5x/common.c | 47 ++++++++++++++++++++ arch/arm/mach-orion5x/common.h | 1 + arch/arm/mach-orion5x/include/mach/orion5x.h | 6 ++- 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 4b8acd2851f4..2835fb5d21e2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -434,7 +434,7 @@ config ARCH_ORION5X help Support for the following Marvell Orion 5x series SoCs: Orion-1 (5181), Orion-VoIP (5181L), Orion-NAS (5182), - Orion-2 (5281). + Orion-2 (5281), Orion-1-90 (6183). config ARCH_PNX4008 bool "Philips Nexperia PNX4008 Mobile" diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 8a8b089b8b74..9625ef5975d0 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -270,6 +271,38 @@ void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data) } +/***************************************************************************** + * SPI + ****************************************************************************/ +static struct orion_spi_info orion5x_spi_plat_data = { + .tclk = 0, +}; + +static struct resource orion5x_spi_resources[] = { + { + .name = "spi base", + .start = SPI_PHYS_BASE, + .end = SPI_PHYS_BASE + 0x1f, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device orion5x_spi = { + .name = "orion_spi", + .id = 0, + .dev = { + .platform_data = &orion5x_spi_plat_data, + }, + .num_resources = ARRAY_SIZE(orion5x_spi_resources), + .resource = orion5x_spi_resources, +}; + +void __init orion5x_spi_init() +{ + platform_device_register(&orion5x_spi); +} + + /***************************************************************************** * UART0 ****************************************************************************/ @@ -462,6 +495,13 @@ int orion5x_tclk; int __init orion5x_find_tclk(void) { + u32 dev, rev; + + orion5x_pcie_id(&dev, &rev); + if (dev == MV88F6183_DEV_ID && + (readl(MPP_RESET_SAMPLE) & 0x00000200) == 0) + return 133333333; + return 166666667; } @@ -510,6 +550,12 @@ static void __init orion5x_id(u32 *dev, u32 *rev, char **dev_name) } else { *dev_name = "MV88F5181(L)-Rev-Unsupported"; } + } else if (*dev == MV88F6183_DEV_ID) { + if (*rev == MV88F6183_REV_B0) { + *dev_name = "MV88F6183-Rev-B0"; + } else { + *dev_name = "MV88F6183-Rev-Unsupported"; + } } else { *dev_name = "Device-Unknown"; } @@ -524,6 +570,7 @@ void __init orion5x_init(void) printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, orion5x_tclk); orion5x_eth_shared_data.t_clk = orion5x_tclk; + orion5x_spi_plat_data.tclk = orion5x_tclk; orion5x_uart0_data[0].uartclk = orion5x_tclk; orion5x_uart1_data[0].uartclk = orion5x_tclk; diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h index c8598cc7cd58..af9588d23f29 100644 --- a/arch/arm/mach-orion5x/common.h +++ b/arch/arm/mach-orion5x/common.h @@ -31,6 +31,7 @@ void orion5x_ehci1_init(void); void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data); void orion5x_i2c_init(void); void orion5x_sata_init(struct mv_sata_platform_data *sata_data); +void orion5x_spi_init(void); void orion5x_uart0_init(void); void orion5x_uart1_init(void); void orion5x_xor_init(void); diff --git a/arch/arm/mach-orion5x/include/mach/orion5x.h b/arch/arm/mach-orion5x/include/mach/orion5x.h index 61eb74a88862..e67c843baa02 100644 --- a/arch/arm/mach-orion5x/include/mach/orion5x.h +++ b/arch/arm/mach-orion5x/include/mach/orion5x.h @@ -2,7 +2,7 @@ * arch/arm/mach-orion5x/include/mach/orion5x.h * * Generic definitions of Orion SoC flavors: - * Orion-1, Orion-VoIP, Orion-NAS, and Orion-2. + * Orion-1, Orion-VoIP, Orion-NAS, Orion-2, and Orion-1-90. * * Maintainer: Tzachi Perelstein * @@ -76,6 +76,9 @@ #define MV88F5281_REV_D0 4 #define MV88F5281_REV_D1 5 #define MV88F5281_REV_D2 6 +/* Orion-1-90 (88F6183) */ +#define MV88F6183_DEV_ID 0x6183 +#define MV88F6183_REV_B0 3 /******************************************************************************* * Orion Registers Map @@ -86,6 +89,7 @@ #define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x10000) #define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x10000) #define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE | (x)) +#define SPI_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x0600) #define I2C_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x1000) #define UART0_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x2000) #define UART0_VIRT_BASE (ORION5X_DEV_BUS_VIRT_BASE | 0x2000) From 0b0740c3c120d1fd7b9a04f04ab79bee12c4cc38 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Fri, 29 Aug 2008 06:59:34 +0200 Subject: [PATCH 08/17] [ARM] Orion: add RD88F6183AP-GE support The RD88F6183AP-GE is an access point reference design for the 88F6183 SoC, with a 88E6161 six-port gigabit ethernet switch with five PHYs (providing 1 WAN and 4 LAN ports and an interface to the CPU), and a mini-PCIe slot for a wireless card. Signed-off-by: Lennert Buytenhek --- arch/arm/configs/orion5x_defconfig | 1 + arch/arm/mach-orion5x/Kconfig | 6 + arch/arm/mach-orion5x/Makefile | 1 + arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c | 117 +++++++++++++++++++ 4 files changed, 125 insertions(+) create mode 100644 arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig index 182031615fba..1415cf56022b 100644 --- a/arch/arm/configs/orion5x_defconfig +++ b/arch/arm/configs/orion5x_defconfig @@ -175,6 +175,7 @@ CONFIG_MACH_MSS2=y CONFIG_MACH_WNR854T=y CONFIG_MACH_RD88F5181L_GE=y CONFIG_MACH_RD88F5181L_FXO=y +CONFIG_MACH_RD88F6183AP_GE=y # # Boot options diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index c738f450f936..c0ecf22ae819 100644 --- a/arch/arm/mach-orion5x/Kconfig +++ b/arch/arm/mach-orion5x/Kconfig @@ -105,6 +105,12 @@ config MACH_RD88F5181L_FXO Say 'Y' here if you want your kernel to support the Marvell Orion-VoIP FXO (88F5181L) RD. +config MACH_RD88F6183AP_GE + bool "Marvell Orion-1-90 AP GE Reference Design" + help + Say 'Y' here if you want your kernel to support the + Marvell Orion-1-90 (88F6183) AP GE RD. + endmenu endif diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile index 39e41a6b61e1..30681ed4c751 100644 --- a/arch/arm/mach-orion5x/Makefile +++ b/arch/arm/mach-orion5x/Makefile @@ -15,3 +15,4 @@ obj-$(CONFIG_MACH_MSS2) += mss2-setup.o obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o obj-$(CONFIG_MACH_RD88F5181L_FXO) += rd88f5181l-fxo-setup.o +obj-$(CONFIG_MACH_RD88F6183AP_GE) += rd88f6183ap-ge-setup.o diff --git a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c new file mode 100644 index 000000000000..40e049539091 --- /dev/null +++ b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c @@ -0,0 +1,117 @@ +/* + * arch/arm/mach-orion5x/rd88f6183-ap-ge-setup.c + * + * Marvell Orion-1-90 AP GE Reference Design Setup + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +static struct mv643xx_eth_platform_data rd88f6183ap_ge_eth_data = { + .phy_addr = -1, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, +}; + +static struct mtd_partition rd88f6183ap_ge_partitions[] = { + { + .name = "kernel", + .offset = 0x00000000, + .size = 0x00200000, + }, { + .name = "rootfs", + .offset = 0x00200000, + .size = 0x00500000, + }, { + .name = "nvram", + .offset = 0x00700000, + .size = 0x00080000, + }, +}; + +static struct flash_platform_data rd88f6183ap_ge_spi_slave_data = { + .type = "m25p64", + .nr_parts = ARRAY_SIZE(rd88f6183ap_ge_partitions), + .parts = rd88f6183ap_ge_partitions, +}; + +static struct spi_board_info __initdata rd88f6183ap_ge_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &rd88f6183ap_ge_spi_slave_data, + .irq = NO_IRQ, + .max_speed_hz = 20000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +static void __init rd88f6183ap_ge_init(void) +{ + /* + * Setup basic Orion functions. Need to be called early. + */ + orion5x_init(); + + /* + * Configure peripherals. + */ + orion5x_ehci0_init(); + orion5x_eth_init(&rd88f6183ap_ge_eth_data); + spi_register_board_info(rd88f6183ap_ge_spi_slave_info, + ARRAY_SIZE(rd88f6183ap_ge_spi_slave_info)); + orion5x_spi_init(); + orion5x_uart0_init(); +} + +static struct hw_pci rd88f6183ap_ge_pci __initdata = { + .nr_controllers = 2, + .swizzle = pci_std_swizzle, + .setup = orion5x_pci_sys_setup, + .scan = orion5x_pci_sys_scan_bus, + .map_irq = orion5x_pci_map_irq, +}; + +static int __init rd88f6183ap_ge_pci_init(void) +{ + if (machine_is_rd88f6183ap_ge()) { + orion5x_pci_disable(); + pci_common_init(&rd88f6183ap_ge_pci); + } + + return 0; +} +subsys_initcall(rd88f6183ap_ge_pci_init); + +MACHINE_START(RD88F6183AP_GE, "Marvell Orion-1-90 AP GE Reference Design") + /* Maintainer: Lennert Buytenhek */ + .phys_io = ORION5X_REGS_PHYS_BASE, + .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, + .boot_params = 0x00000100, + .init_machine = rd88f6183ap_ge_init, + .map_io = orion5x_map_io, + .init_irq = orion5x_init_irq, + .timer = &orion5x_timer, + .fixup = tag_fixup_mem32, +MACHINE_END From 79d4dd77f0d86e4315887edaa5dfabb0c2081ba7 Mon Sep 17 00:00:00 2001 From: Ronen Shitrit Date: Mon, 15 Sep 2008 00:56:38 +0200 Subject: [PATCH 09/17] [ARM] Kirkwood: prepare for runtime-determined timer tick rate Currently, kirkwood uses a hardcoded timer tick rate of 166 MHz, but the actual timer tick rate varies between different members of the SoC family. This patch prepares for runtime determination of the timer tick rate. Signed-off-by: Ronen Shitrit --- arch/arm/mach-kirkwood/common.c | 22 +++++++++++++++------ arch/arm/mach-kirkwood/include/mach/timex.h | 1 - 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 435fb35a4845..2e79dabac53c 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -98,7 +98,6 @@ void __init kirkwood_ehci_init(void) * GE00 ****************************************************************************/ struct mv643xx_eth_shared_platform_data kirkwood_ge00_shared_data = { - .t_clk = KIRKWOOD_TCLK, .dram = &kirkwood_mbus_dram_info, }; @@ -206,7 +205,6 @@ void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data) * SPI ****************************************************************************/ static struct orion_spi_info kirkwood_spi_plat_data = { - .tclk = KIRKWOOD_TCLK, }; static struct resource kirkwood_spi_resources[] = { @@ -244,7 +242,7 @@ static struct plat_serial8250_port kirkwood_uart0_data[] = { .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, .iotype = UPIO_MEM, .regshift = 2, - .uartclk = KIRKWOOD_TCLK, + .uartclk = 0, }, { }, }; @@ -288,7 +286,7 @@ static struct plat_serial8250_port kirkwood_uart1_data[] = { .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, .iotype = UPIO_MEM, .regshift = 2, - .uartclk = KIRKWOOD_TCLK, + .uartclk = 0, }, { }, }; @@ -530,9 +528,17 @@ void __init kirkwood_xor1_init(void) /***************************************************************************** * Time handling ****************************************************************************/ +int kirkwood_tclk; + +int __init kirkwood_find_tclk(void) +{ + return 166666667; +} + static void kirkwood_timer_init(void) { - orion_time_init(IRQ_KIRKWOOD_BRIDGE, KIRKWOOD_TCLK); + kirkwood_tclk = kirkwood_find_tclk(); + orion_time_init(IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); } struct sys_timer kirkwood_timer = { @@ -565,7 +571,11 @@ static int __init is_l2_writethrough(void) void __init kirkwood_init(void) { printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n", - kirkwood_id(), KIRKWOOD_TCLK); + kirkwood_id(), kirkwood_tclk); + kirkwood_ge00_shared_data.t_clk = kirkwood_tclk; + kirkwood_spi_plat_data.tclk = kirkwood_tclk; + kirkwood_uart0_data[0].uartclk = kirkwood_tclk; + kirkwood_uart1_data[0].uartclk = kirkwood_tclk; kirkwood_setup_cpu_mbus(); diff --git a/arch/arm/mach-kirkwood/include/mach/timex.h b/arch/arm/mach-kirkwood/include/mach/timex.h index f77ef4a32c5f..c923cd169b9c 100644 --- a/arch/arm/mach-kirkwood/include/mach/timex.h +++ b/arch/arm/mach-kirkwood/include/mach/timex.h @@ -8,4 +8,3 @@ #define CLOCK_TICK_RATE (100 * HZ) -#define KIRKWOOD_TCLK 166666667 From b2b3dc2fc41ef441610d0140f0f5ccacbd43f40c Mon Sep 17 00:00:00 2001 From: Ronen Shitrit Date: Mon, 15 Sep 2008 10:40:35 +0300 Subject: [PATCH 10/17] [ARM] Kirkwood: add support for newer SoC models Add support to the Kirkwood port for newer device models and silicon revisions. Instead of looking at the DEVICE_ID register, the device version is now determined by looking at the PCI-Express device ID and revision registers, as it is done for orion5x, and this information is used to determine the TCLK frequency, again, as it is done for orion5x. Signed-off-by: Ronen Shitrit Signed-off-by: Lennert Buytenhek --- arch/arm/mach-kirkwood/common.c | 43 +++++++++++++++---- arch/arm/mach-kirkwood/common.h | 2 + .../arm/mach-kirkwood/include/mach/kirkwood.h | 14 ++++++ arch/arm/mach-kirkwood/pcie.c | 6 +++ 4 files changed, 56 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 2e79dabac53c..c8516e352d1c 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -532,6 +532,12 @@ int kirkwood_tclk; int __init kirkwood_find_tclk(void) { + u32 dev, rev; + + kirkwood_pcie_id(&dev, &rev); + if (dev == MV88F6281_DEV_ID && rev == MV88F6281_REV_A0) + return 200000000; + return 166666667; } @@ -549,18 +555,37 @@ struct sys_timer kirkwood_timer = { /***************************************************************************** * General ****************************************************************************/ +/* + * Identify device ID and revision. + */ static char * __init kirkwood_id(void) { - switch (readl(DEVICE_ID) & 0x3) { - case 0: - return "88F6180"; - case 1: - return "88F6192"; - case 2: - return "88F6281"; - } + u32 dev, rev; - return "unknown 88F6000 variant"; + kirkwood_pcie_id(&dev, &rev); + + if (dev == MV88F6281_DEV_ID) { + if (rev == MV88F6281_REV_Z0) + return "MV88F6281-Z0"; + else if (rev == MV88F6281_REV_A0) + return "MV88F6281-A0"; + else + return "MV88F6281-Rev-Unsupported"; + } else if (dev == MV88F6192_DEV_ID) { + if (rev == MV88F6192_REV_Z0) + return "MV88F6192-Z0"; + else if (rev == MV88F6192_REV_A0) + return "MV88F6192-A0"; + else + return "MV88F6192-Rev-Unsupported"; + } else if (dev == MV88F6180_DEV_ID) { + if (rev == MV88F6180_REV_A0) + return "MV88F6180-Rev-A0"; + else + return "MV88F6180-Rev-Unsupported"; + } else { + return "Device-Unknown"; + } } static int __init is_l2_writethrough(void) diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h index 69cd113af03a..02abef1b3219 100644 --- a/arch/arm/mach-kirkwood/common.h +++ b/arch/arm/mach-kirkwood/common.h @@ -28,6 +28,8 @@ void kirkwood_setup_pcie_io_win(int window, u32 base, u32 size, void kirkwood_setup_pcie_mem_win(int window, u32 base, u32 size, int maj, int min); +void kirkwood_pcie_id(u32 *dev, u32 *rev); + void kirkwood_ehci_init(void); void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data); void kirkwood_pcie_init(void); diff --git a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h index 5c69992295e8..eae42406fd86 100644 --- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h +++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h @@ -67,6 +67,20 @@ #define L2_CONFIG_REG (BRIDGE_VIRT_BASE | 0x0128) #define L2_WRITETHROUGH 0x00000010 +/* + * Supported devices and revisions. + */ +#define MV88F6281_DEV_ID 0x6281 +#define MV88F6281_REV_Z0 0 +#define MV88F6281_REV_A0 2 + +#define MV88F6192_DEV_ID 0x6192 +#define MV88F6192_REV_Z0 0 +#define MV88F6192_REV_A0 2 + +#define MV88F6180_DEV_ID 0x6180 +#define MV88F6180_REV_A0 2 + /* * Register Map */ diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index 2195fa31f6b7..f6b08f207c89 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c @@ -18,6 +18,12 @@ #define PCIE_BASE ((void __iomem *)PCIE_VIRT_BASE) +void __init kirkwood_pcie_id(u32 *dev, u32 *rev) +{ + *dev = orion_pcie_dev_id(PCIE_BASE); + *rev = orion_pcie_rev(PCIE_BASE); +} + static int pcie_valid_config(int bus, int dev) { /* From 3a64ebc9ce3d5a364b50fe78ca9c2c507b765784 Mon Sep 17 00:00:00 2001 From: Ronen Shitrit Date: Sun, 14 Sep 2008 20:30:27 +0300 Subject: [PATCH 11/17] [ARM] Kirkwood: remove uart1 init calls for boards that don't expose uart1 Remove uart1 init calls for boards that use the physical pins onto which the UART1 signals are multiplexed for different purposes. Signed-off-by: Ronen Shitrit Signed-off-by: Lennert Buytenhek --- arch/arm/mach-kirkwood/db88f6281-bp-setup.c | 1 - arch/arm/mach-kirkwood/rd88f6281-setup.c | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c index 610fb24d8ae2..89d746d13fda 100644 --- a/arch/arm/mach-kirkwood/db88f6281-bp-setup.c +++ b/arch/arm/mach-kirkwood/db88f6281-bp-setup.c @@ -44,7 +44,6 @@ static void __init db88f6281_init(void) kirkwood_rtc_init(); kirkwood_sata_init(&db88f6281_sata_data); kirkwood_uart0_init(); - kirkwood_uart1_init(); } static int __init db88f6281_pci_init(void) diff --git a/arch/arm/mach-kirkwood/rd88f6281-setup.c b/arch/arm/mach-kirkwood/rd88f6281-setup.c index d96487a0f18b..fb8990f9770d 100644 --- a/arch/arm/mach-kirkwood/rd88f6281-setup.c +++ b/arch/arm/mach-kirkwood/rd88f6281-setup.c @@ -90,7 +90,6 @@ static void __init rd88f6281_init(void) kirkwood_rtc_init(); kirkwood_sata_init(&rd88f6281_sata_data); kirkwood_uart0_init(); - kirkwood_uart1_init(); platform_device_register(&rd88f6281_nand_flash); } From 2d0c9e735ab8413d3cf29576ab14e07f7aa8eab9 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Sun, 31 Aug 2008 07:39:19 +0200 Subject: [PATCH 12/17] [ARM] Kirkwood: allow configuring mbus window for on-chip sram Signed-off-by: Lennert Buytenhek --- arch/arm/mach-kirkwood/addr-map.c | 8 ++++++++ arch/arm/mach-kirkwood/common.h | 5 +---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-kirkwood/addr-map.c b/arch/arm/mach-kirkwood/addr-map.c index c79f492072f9..5db4f0bbe5ee 100644 --- a/arch/arm/mach-kirkwood/addr-map.c +++ b/arch/arm/mach-kirkwood/addr-map.c @@ -48,6 +48,7 @@ struct mbus_dram_target_info kirkwood_mbus_dram_info; +static int __initdata win_alloc_count; static int __init cpu_win_can_remap(int win) { @@ -111,6 +112,8 @@ void __init kirkwood_setup_cpu_mbus(void) setup_cpu_win(2, KIRKWOOD_NAND_MEM_PHYS_BASE, KIRKWOOD_NAND_MEM_SIZE, TARGET_DEV_BUS, ATTR_DEV_NAND, -1); + win_alloc_count = 3; + /* * Setup MBUS dram target info. */ @@ -137,3 +140,8 @@ void __init kirkwood_setup_cpu_mbus(void) } kirkwood_mbus_dram_info.num_cs = cs; } + +void __init kirkwood_setup_sram_win(u32 base, u32 size) +{ + setup_cpu_win(win_alloc_count++, base, size, 0x03, 0x00, -1); +} diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h index 02abef1b3219..8fa0f6a27635 100644 --- a/arch/arm/mach-kirkwood/common.h +++ b/arch/arm/mach-kirkwood/common.h @@ -23,10 +23,7 @@ void kirkwood_init_irq(void); extern struct mbus_dram_target_info kirkwood_mbus_dram_info; void kirkwood_setup_cpu_mbus(void); -void kirkwood_setup_pcie_io_win(int window, u32 base, u32 size, - int maj, int min); -void kirkwood_setup_pcie_mem_win(int window, u32 base, u32 size, - int maj, int min); +void kirkwood_setup_sram_win(u32 base, u32 size); void kirkwood_pcie_id(u32 *dev, u32 *rev); From 3d014b01e54ce08d15a598f0bfb3ce597f14ca03 Mon Sep 17 00:00:00 2001 From: Albert Aribaud Date: Fri, 19 Sep 2008 21:06:25 +0200 Subject: [PATCH 13/17] [ARM] EDMINIV2: add support for LED and power button This patch provides standard GPIO LED control for the ED Mini V2, with software blinking only (CPLD hardware blinking capability is not used). This patch also provides status of the power button as a standard GPIO input event. Signed-off-by: Albert Aribaud Signed-off-by: Nicolas Pitre --- arch/arm/mach-orion5x/edmini_v2-setup.c | 60 +++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/arch/arm/mach-orion5x/edmini_v2-setup.c b/arch/arm/mach-orion5x/edmini_v2-setup.c index 2d67591dbce6..b24ee0c2cd61 100644 --- a/arch/arm/mach-orion5x/edmini_v2-setup.c +++ b/arch/arm/mach-orion5x/edmini_v2-setup.c @@ -25,6 +25,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -119,6 +122,61 @@ static struct mv_sata_platform_data edmini_v2_sata_data = { .n_ports = 2, }; +/***************************************************************************** + * GPIO LED (simple - doesn't use hardware blinking support) + ****************************************************************************/ + +#define EDMINI_V2_GPIO_LED_POWER 16 + +static struct gpio_led edmini_v2_leds[] = { + { + .name = "power:blue", + .gpio = EDMINI_V2_GPIO_LED_POWER, + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data edmini_v2_led_data = { + .num_leds = ARRAY_SIZE(edmini_v2_leds), + .leds = edmini_v2_leds, +}; + +static struct platform_device edmini_v2_gpio_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &edmini_v2_led_data, + }, +}; + +/**************************************************************************** + * GPIO key + ****************************************************************************/ + +#define EDMINI_V2_GPIO_KEY_POWER 18 + +static struct gpio_keys_button edmini_v2_buttons[] = { + { + .code = KEY_POWER, + .gpio = EDMINI_V2_GPIO_KEY_POWER, + .desc = "Power Button", + .active_low = 0, + }, +}; + +static struct gpio_keys_platform_data edmini_v2_button_data = { + .buttons = edmini_v2_buttons, + .nbuttons = ARRAY_SIZE(edmini_v2_buttons), +}; + +static struct platform_device edmini_v2_gpio_buttons = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &edmini_v2_button_data, + }, +}; + /***************************************************************************** * General Setup ****************************************************************************/ @@ -170,6 +228,8 @@ static void __init edmini_v2_init(void) orion5x_setup_dev_boot_win(EDMINI_V2_NOR_BOOT_BASE, EDMINI_V2_NOR_BOOT_SIZE); platform_device_register(&edmini_v2_nor_flash); + platform_device_register(&edmini_v2_gpio_leds); + platform_device_register(&edmini_v2_gpio_buttons); pr_notice("edmini_v2: USB device port, flash write and power-off " "are not yet supported.\n"); From 4360bb41920ffacd4a935fa692768129ee5bef4e Mon Sep 17 00:00:00 2001 From: Ronen Shitrit Date: Tue, 23 Sep 2008 15:28:10 +0300 Subject: [PATCH 14/17] [ARM] Kirkwood: add support for L2 cache WB/WT selection Feroceon L2 cache can work in eighther write through or write back mode on Kirkwood. Add the option to configure this mode according to Kconfig. Signed-off-by: Ronen Shitrit Signed-off-by: Nicolas Pitre --- arch/arm/mach-kirkwood/common.c | 12 +++++++++--- arch/arm/mm/Kconfig | 8 ++++++++ arch/arm/mm/proc-feroceon.S | 12 ++++++++---- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index c8516e352d1c..85cad05d8c5b 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -588,9 +588,15 @@ static char * __init kirkwood_id(void) } } -static int __init is_l2_writethrough(void) +static void __init kirkwood_l2_init(void) { - return !!(readl(L2_CONFIG_REG) & L2_WRITETHROUGH); +#ifdef CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH + writel(readl(L2_CONFIG_REG) | L2_WRITETHROUGH, L2_CONFIG_REG); + feroceon_l2_init(1); +#else + writel(readl(L2_CONFIG_REG) & ~L2_WRITETHROUGH, L2_CONFIG_REG); + feroceon_l2_init(0); +#endif } void __init kirkwood_init(void) @@ -605,6 +611,6 @@ void __init kirkwood_init(void) kirkwood_setup_cpu_mbus(); #ifdef CONFIG_CACHE_FEROCEON_L2 - feroceon_l2_init(is_l2_writethrough()); + kirkwood_l2_init(); #endif } diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index ed15f876c725..330814d1ee25 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -735,6 +735,14 @@ config CACHE_FEROCEON_L2 help This option enables the Feroceon L2 cache controller. +config CACHE_FEROCEON_L2_WRITETHROUGH + bool "Force Feroceon L2 cache write through" + depends on CACHE_FEROCEON_L2 + default n + help + Say Y here to use the Feroceon L2 cache in writethrough mode. + Unless you specifically require this, say N for writeback mode. + config CACHE_L2X0 bool "Enable the L2x0 outer cache controller" depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S index f2e5884c513a..207392f1ce8a 100644 --- a/arch/arm/mm/proc-feroceon.S +++ b/arch/arm/mm/proc-feroceon.S @@ -80,7 +80,8 @@ ENTRY(cpu_feroceon_proc_fin) msr cpsr_c, ip bl feroceon_flush_kern_cache_all -#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH) +#if defined(CONFIG_CACHE_FEROCEON_L2) && \ + !defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH) mov r0, #0 mcr p15, 1, r0, c15, c9, 0 @ clean L2 mcr p15, 0, r0, c7, c10, 4 @ drain WB @@ -389,7 +390,8 @@ ENTRY(feroceon_range_cache_fns) .align 5 ENTRY(cpu_feroceon_dcache_clean_area) -#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH) +#if defined(CONFIG_CACHE_FEROCEON_L2) && \ + !defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH) mov r2, r0 mov r3, r1 #endif @@ -397,7 +399,8 @@ ENTRY(cpu_feroceon_dcache_clean_area) add r0, r0, #CACHE_DLINESIZE subs r1, r1, #CACHE_DLINESIZE bhi 1b -#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH) +#if defined(CONFIG_CACHE_FEROCEON_L2) && \ + !defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH) 1: mcr p15, 1, r2, c15, c9, 1 @ clean L2 entry add r2, r2, #CACHE_DLINESIZE subs r3, r3, #CACHE_DLINESIZE @@ -466,7 +469,8 @@ ENTRY(cpu_feroceon_set_pte_ext) str r2, [r0] @ hardware version mov r0, r0 mcr p15, 0, r0, c7, c10, 1 @ clean D entry -#if defined(CONFIG_CACHE_FEROCEON_L2) && !defined(CONFIG_L2_CACHE_WRITETHROUGH) +#if defined(CONFIG_CACHE_FEROCEON_L2) && \ + !defined(CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH) mcr p15, 1, r0, c15, c9, 1 @ clean L2 entry #endif mcr p15, 0, r0, c7, c10, 4 @ drain WB From 7b0a26f2ca0001a13473b874d52b3d557e3d7289 Mon Sep 17 00:00:00 2001 From: Alexey Kopytko Date: Thu, 25 Sep 2008 22:47:30 +0900 Subject: [PATCH 15/17] [ARM] Orion: Add Buffalo Linkstation Mini support This patch adds support for Buffalo Linkstation Mini board. Signed-off-by: Alexey Kopytko Signed-off-by: Nicolas Pitre --- arch/arm/configs/orion5x_defconfig | 1 + arch/arm/mach-orion5x/Kconfig | 7 + arch/arm/mach-orion5x/Makefile | 1 + arch/arm/mach-orion5x/lsmini-setup.c | 259 +++++++++++++++++++++++++++ 4 files changed, 268 insertions(+) create mode 100644 arch/arm/mach-orion5x/lsmini-setup.c diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig index 1415cf56022b..06760f26eace 100644 --- a/arch/arm/configs/orion5x_defconfig +++ b/arch/arm/configs/orion5x_defconfig @@ -166,6 +166,7 @@ CONFIG_MACH_KUROBOX_PRO=y CONFIG_MACH_DNS323=y CONFIG_MACH_TS209=y CONFIG_MACH_LINKSTATION_PRO=y +CONFIG_MACH_LINKSTATION_MINI=y CONFIG_MACH_TS409=y CONFIG_MACH_WRT350N_V2=y CONFIG_MACH_TS78XX=y diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig index c0ecf22ae819..f59a8d0e0824 100644 --- a/arch/arm/mach-orion5x/Kconfig +++ b/arch/arm/mach-orion5x/Kconfig @@ -50,6 +50,13 @@ config MACH_LINKSTATION_PRO Buffalo Linkstation Pro/Live platform. Both v1 and v2 devices are supported. +config MACH_LINKSTATION_MINI + bool "Buffalo Linkstation Mini" + select I2C_BOARDINFO + help + Say 'Y' here if you want your kernel to support the + Buffalo Linkstation Mini platform. + config MACH_TS409 bool "QNAP TS-409" help diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile index 30681ed4c751..3d4a1bc12355 100644 --- a/arch/arm/mach-orion5x/Makefile +++ b/arch/arm/mach-orion5x/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o obj-$(CONFIG_MACH_TERASTATION_PRO2) += terastation_pro2-setup.o obj-$(CONFIG_MACH_LINKSTATION_PRO) += kurobox_pro-setup.o +obj-$(CONFIG_MACH_LINKSTATION_MINI) += lsmini-setup.o obj-$(CONFIG_MACH_DNS323) += dns323-setup.o obj-$(CONFIG_MACH_TS209) += ts209-setup.o tsx09-common.o obj-$(CONFIG_MACH_TS409) += ts409-setup.o tsx09-common.o diff --git a/arch/arm/mach-orion5x/lsmini-setup.c b/arch/arm/mach-orion5x/lsmini-setup.c new file mode 100644 index 000000000000..4311dafd7e26 --- /dev/null +++ b/arch/arm/mach-orion5x/lsmini-setup.c @@ -0,0 +1,259 @@ +/* + * arch/arm/mach-orion5x/lsmini-setup.c + * + * Maintainer: Alexey Kopytko + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" +#include "include/mach/system.h" + +/***************************************************************************** + * Linkstation Mini Info + ****************************************************************************/ + +/* + * 256K NOR flash Device bus boot chip select + */ + +#define LSMINI_NOR_BOOT_BASE 0xf4000000 +#define LSMINI_NOR_BOOT_SIZE SZ_256K + +/***************************************************************************** + * 256KB NOR Flash on BOOT Device + ****************************************************************************/ + +static struct physmap_flash_data lsmini_nor_flash_data = { + .width = 1, +}; + +static struct resource lsmini_nor_flash_resource = { + .flags = IORESOURCE_MEM, + .start = LSMINI_NOR_BOOT_BASE, + .end = LSMINI_NOR_BOOT_BASE + LSMINI_NOR_BOOT_SIZE - 1, +}; + +static struct platform_device lsmini_nor_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &lsmini_nor_flash_data, + }, + .num_resources = 1, + .resource = &lsmini_nor_flash_resource, +}; + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data lsmini_eth_data = { + .phy_addr = 8, +}; + +/***************************************************************************** + * RTC 5C372a on I2C bus + ****************************************************************************/ + +static struct i2c_board_info __initdata lsmini_i2c_rtc = { + I2C_BOARD_INFO("rs5c372a", 0x32), +}; + +/***************************************************************************** + * LEDs attached to GPIO + ****************************************************************************/ + +#define LSMINI_GPIO_LED_ALARM 2 +#define LSMINI_GPIO_LED_INFO 3 +#define LSMINI_GPIO_LED_FUNC 9 +#define LSMINI_GPIO_LED_PWR 14 + +static struct gpio_led lsmini_led_pins[] = { + { + .name = "alarm:red", + .gpio = LSMINI_GPIO_LED_ALARM, + .active_low = 1, + }, { + .name = "info:amber", + .gpio = LSMINI_GPIO_LED_INFO, + .active_low = 1, + }, { + .name = "func:blue:top", + .gpio = LSMINI_GPIO_LED_FUNC, + .active_low = 1, + }, { + .name = "power:blue:bottom", + .gpio = LSMINI_GPIO_LED_PWR, + }, +}; + +static struct gpio_led_platform_data lsmini_led_data = { + .leds = lsmini_led_pins, + .num_leds = ARRAY_SIZE(lsmini_led_pins), +}; + +static struct platform_device lsmini_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &lsmini_led_data, + }, +}; + +/**************************************************************************** + * GPIO Attached Keys + ****************************************************************************/ + +#define LSMINI_GPIO_KEY_FUNC 15 +#define LSMINI_GPIO_KEY_POWER 18 +#define LSMINI_GPIO_KEY_AUTOPOWER 17 + +#define LSMINI_SW_POWER 0x00 +#define LSMINI_SW_AUTOPOWER 0x01 + +static struct gpio_keys_button lsmini_buttons[] = { + { + .code = KEY_OPTION, + .gpio = LSMINI_GPIO_KEY_FUNC, + .desc = "Function Button", + .active_low = 1, + }, { + .type = EV_SW, + .code = LSMINI_SW_POWER, + .gpio = LSMINI_GPIO_KEY_POWER, + .desc = "Power-on Switch", + .active_low = 1, + }, { + .type = EV_SW, + .code = LSMINI_SW_AUTOPOWER, + .gpio = LSMINI_GPIO_KEY_AUTOPOWER, + .desc = "Power-auto Switch", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data lsmini_button_data = { + .buttons = lsmini_buttons, + .nbuttons = ARRAY_SIZE(lsmini_buttons), +}; + +static struct platform_device lsmini_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &lsmini_button_data, + }, +}; + + +/***************************************************************************** + * SATA + ****************************************************************************/ +static struct mv_sata_platform_data lsmini_sata_data = { + .n_ports = 2, +}; + + +/***************************************************************************** + * General Setup + ****************************************************************************/ + +#define LSMINI_GPIO_USB_POWER 16 +#define LSMINI_GPIO_AUTO_POWER 17 +#define LSMINI_GPIO_POWER 18 + +#define LSMINI_GPIO_HDD_POWER0 1 +#define LSMINI_GPIO_HDD_POWER1 19 + +static struct orion5x_mpp_mode lsmini_mpp_modes[] __initdata = { + { 0, MPP_UNUSED }, /* LED_RESERVE1 (unused) */ + { 1, MPP_GPIO }, /* HDD_PWR */ + { 2, MPP_GPIO }, /* LED_ALARM */ + { 3, MPP_GPIO }, /* LED_INFO */ + { 4, MPP_UNUSED }, + { 5, MPP_UNUSED }, + { 6, MPP_UNUSED }, + { 7, MPP_UNUSED }, + { 8, MPP_UNUSED }, + { 9, MPP_GPIO }, /* LED_FUNC */ + { 10, MPP_UNUSED }, + { 11, MPP_UNUSED }, /* LED_ETH (dummy) */ + { 12, MPP_UNUSED }, + { 13, MPP_UNUSED }, + { 14, MPP_GPIO }, /* LED_PWR */ + { 15, MPP_GPIO }, /* FUNC */ + { 16, MPP_GPIO }, /* USB_PWR */ + { 17, MPP_GPIO }, /* AUTO_POWER */ + { 18, MPP_GPIO }, /* POWER */ + { 19, MPP_GPIO }, /* HDD_PWR1 */ + { -1 }, +}; + +static void __init lsmini_init(void) +{ + /* + * Setup basic Orion functions. Need to be called early. + */ + orion5x_init(); + + orion5x_mpp_conf(lsmini_mpp_modes); + + /* + * Configure peripherals. + */ + orion5x_ehci0_init(); + orion5x_ehci1_init(); + orion5x_eth_init(&lsmini_eth_data); + orion5x_i2c_init(); + orion5x_sata_init(&lsmini_sata_data); + orion5x_uart0_init(); + orion5x_xor_init(); + + orion5x_setup_dev_boot_win(LSMINI_NOR_BOOT_BASE, + LSMINI_NOR_BOOT_SIZE); + platform_device_register(&lsmini_nor_flash); + + platform_device_register(&lsmini_button_device); + + platform_device_register(&lsmini_leds); + + i2c_register_board_info(0, &lsmini_i2c_rtc, 1); + + /* enable USB power */ + gpio_set_value(LSMINI_GPIO_USB_POWER, 1); + + pr_info("%s: finished\n", __func__); +} + +#ifdef CONFIG_MACH_LINKSTATION_MINI +MACHINE_START(LINKSTATION_MINI, "Buffalo Linkstation Mini") + /* Maintainer: Alexey Kopytko */ + .phys_io = ORION5X_REGS_PHYS_BASE, + .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, + .boot_params = 0x00000100, + .init_machine = lsmini_init, + .map_io = orion5x_map_io, + .init_irq = orion5x_init_irq, + .timer = &orion5x_timer, + .fixup = tag_fixup_mem32, +MACHINE_END +#endif From 92a5de80e5c53c56d098ea3cb6266138efd892f6 Mon Sep 17 00:00:00 2001 From: Alexey Kopytko Date: Fri, 26 Sep 2008 11:13:39 +0900 Subject: [PATCH 16/17] [ARM] Orion: Add Buffalo Linkstation Mini power-off method This patch adds specific power-off method for Buffalo Linkstation Mini board. The board has a hardware switch which should be monitored from userspace. When the switch is in OFF position the board should be rebooted and U-Boot will start in an idle mode and wait for the user to move the power switch back to ON position. Signed-off-by: Alexey Kopytko Signed-off-by: Nicolas Pitre --- arch/arm/mach-orion5x/lsmini-setup.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/arm/mach-orion5x/lsmini-setup.c b/arch/arm/mach-orion5x/lsmini-setup.c index 4311dafd7e26..e0c43b8beb72 100644 --- a/arch/arm/mach-orion5x/lsmini-setup.c +++ b/arch/arm/mach-orion5x/lsmini-setup.c @@ -173,6 +173,23 @@ static struct mv_sata_platform_data lsmini_sata_data = { }; +/***************************************************************************** + * Linkstation Mini specific power off method: reboot + ****************************************************************************/ +/* + * On the Linkstation Mini, the shutdown process is following: + * - Userland monitors key events until the power switch goes to off position + * - The board reboots + * - U-boot starts and goes into an idle mode waiting for the user + * to move the switch to ON position + */ + +static void lsmini_power_off(void) +{ + arch_reset(0); +} + + /***************************************************************************** * General Setup ****************************************************************************/ @@ -241,6 +258,9 @@ static void __init lsmini_init(void) /* enable USB power */ gpio_set_value(LSMINI_GPIO_USB_POWER, 1); + /* register power-off method */ + pm_power_off = lsmini_power_off; + pr_info("%s: finished\n", __func__); } From 99c6bb390cf599b9e0aa6e69beacc4e5d875bf77 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Thu, 11 Sep 2008 15:14:59 -0400 Subject: [PATCH 17/17] [ARM] Feroceon: small cleanups to L2 cache code - Make sure that coprocessor instructions for range ops are contiguous and not reordered. - s/invalidate_and_disable_dcache/flush_and_disable_dcache/ - Don't re-enable I/D caches if they were not enabled initially. - Change some masks to shifts for better generated code. Signed-off-by: Nicolas Pitre Acked-by: Lennert Buytenhek --- arch/arm/mm/cache-feroceon-l2.c | 42 ++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c index 7b5a25d81576..13cdae8b0d44 100644 --- a/arch/arm/mm/cache-feroceon-l2.c +++ b/arch/arm/mm/cache-feroceon-l2.c @@ -48,11 +48,12 @@ static inline void l2_clean_mva_range(unsigned long start, unsigned long end) * L2 is PIPT and range operations only do a TLB lookup on * the start address. */ - BUG_ON((start ^ end) & ~(PAGE_SIZE - 1)); + BUG_ON((start ^ end) >> PAGE_SHIFT); raw_local_irq_save(flags); - __asm__("mcr p15, 1, %0, c15, c9, 4" : : "r" (start)); - __asm__("mcr p15, 1, %0, c15, c9, 5" : : "r" (end)); + __asm__("mcr p15, 1, %0, c15, c9, 4\n\t" + "mcr p15, 1, %1, c15, c9, 5" + : : "r" (start), "r" (end)); raw_local_irq_restore(flags); } @@ -80,11 +81,12 @@ static inline void l2_inv_mva_range(unsigned long start, unsigned long end) * L2 is PIPT and range operations only do a TLB lookup on * the start address. */ - BUG_ON((start ^ end) & ~(PAGE_SIZE - 1)); + BUG_ON((start ^ end) >> PAGE_SHIFT); raw_local_irq_save(flags); - __asm__("mcr p15, 1, %0, c15, c11, 4" : : "r" (start)); - __asm__("mcr p15, 1, %0, c15, c11, 5" : : "r" (end)); + __asm__("mcr p15, 1, %0, c15, c11, 4\n\t" + "mcr p15, 1, %1, c15, c11, 5" + : : "r" (start), "r" (end)); raw_local_irq_restore(flags); } @@ -205,7 +207,7 @@ static void feroceon_l2_flush_range(unsigned long start, unsigned long end) * time. These are necessary because the L2 cache can only be enabled * or disabled while the L1 Dcache and Icache are both disabled. */ -static void __init invalidate_and_disable_dcache(void) +static int __init flush_and_disable_dcache(void) { u32 cr; @@ -217,7 +219,9 @@ static void __init invalidate_and_disable_dcache(void) flush_cache_all(); set_cr(cr & ~CR_C); raw_local_irq_restore(flags); + return 1; } + return 0; } static void __init enable_dcache(void) @@ -225,18 +229,17 @@ static void __init enable_dcache(void) u32 cr; cr = get_cr(); - if (!(cr & CR_C)) - set_cr(cr | CR_C); + set_cr(cr | CR_C); } static void __init __invalidate_icache(void) { int dummy; - __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0\n" : "=r" (dummy)); + __asm__ __volatile__("mcr p15, 0, %0, c7, c5, 0" : "=r" (dummy)); } -static void __init invalidate_and_disable_icache(void) +static int __init invalidate_and_disable_icache(void) { u32 cr; @@ -244,7 +247,9 @@ static void __init invalidate_and_disable_icache(void) if (cr & CR_I) { set_cr(cr & ~CR_I); __invalidate_icache(); + return 1; } + return 0; } static void __init enable_icache(void) @@ -252,8 +257,7 @@ static void __init enable_icache(void) u32 cr; cr = get_cr(); - if (!(cr & CR_I)) - set_cr(cr | CR_I); + set_cr(cr | CR_I); } static inline u32 read_extra_features(void) @@ -291,13 +295,17 @@ static void __init enable_l2(void) u = read_extra_features(); if (!(u & 0x00400000)) { + int i, d; + printk(KERN_INFO "Feroceon L2: Enabling L2\n"); - invalidate_and_disable_dcache(); - invalidate_and_disable_icache(); + d = flush_and_disable_dcache(); + i = invalidate_and_disable_icache(); write_extra_features(u | 0x00400000); - enable_icache(); - enable_dcache(); + if (i) + enable_icache(); + if (d) + enable_dcache(); } }