From: Martin Michlmayr Date: Thu, 5 Nov 2009 17:45:32 +0000 (+0000) Subject: [ARM] Kirkwood: Add support for QNAP TS-41x Turbo NAS X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=f3a131b90b8f9bbcf46edc3bdd5246a744ba0017;p=openwrt%2Fstaging%2Fblogic.git [ARM] Kirkwood: Add support for QNAP TS-41x Turbo NAS Add support for the QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS. Signed-off-by: Martin Michlmayr Signed-off-by: Nicolas Pitre --- diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig index 0aca451b216d..d58e8b0febe0 100644 --- a/arch/arm/mach-kirkwood/Kconfig +++ b/arch/arm/mach-kirkwood/Kconfig @@ -38,6 +38,13 @@ config MACH_TS219 Say 'Y' here if you want your kernel to support the QNAP TS-119 and TS-219 Turbo NAS devices. +config MACH_TS41X + bool "QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS" + help + Say 'Y' here if you want your kernel to support the + QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS + devices. + config MACH_OPENRD_BASE bool "Marvell OpenRD Base Board" help diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index 80ab0ec90ee1..0c79cedfa64d 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_MACH_RD88F6281) += rd88f6281-setup.o obj-$(CONFIG_MACH_MV88F6281GTW_GE) += mv88f6281gtw_ge-setup.o obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o obj-$(CONFIG_MACH_TS219) += ts219-setup.o +obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o obj-$(CONFIG_MACH_OPENRD_BASE) += openrd_base-setup.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o diff --git a/arch/arm/mach-kirkwood/ts41x-setup.c b/arch/arm/mach-kirkwood/ts41x-setup.c new file mode 100644 index 000000000000..a1972c948503 --- /dev/null +++ b/arch/arm/mach-kirkwood/ts41x-setup.c @@ -0,0 +1,253 @@ +/* + * + * QNAP TS-410, TS-410U, TS-419P and TS-419U Turbo NAS Board Setup + * + * Copyright (C) 2009 Martin Michlmayr + * Copyright (C) 2008 Byron Bradley + * + * 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 +#include +#include +#include "common.h" +#include "mpp.h" + +/**************************************************************************** + * 16 MiB NOR flash. The struct mtd_partition is not in the same order as the + * partitions on the device because we want to keep compatability with + * the QNAP firmware. + * Layout as used by QNAP: + * 0x00000000-0x00080000 : "U-Boot" + * 0x00200000-0x00400000 : "Kernel" + * 0x00400000-0x00d00000 : "RootFS" + * 0x00d00000-0x01000000 : "RootFS2" + * 0x00080000-0x000c0000 : "U-Boot Config" + * 0x000c0000-0x00200000 : "NAS Config" + * + * We'll use "RootFS1" instead of "RootFS" to stay compatible with the layout + * used by the QNAP TS-109/TS-209. + * + ***************************************************************************/ + +static struct mtd_partition qnap_ts41x_partitions[] = { + { + .name = "U-Boot", + .size = 0x00080000, + .offset = 0, + .mask_flags = MTD_WRITEABLE, + }, { + .name = "Kernel", + .size = 0x00200000, + .offset = 0x00200000, + }, { + .name = "RootFS1", + .size = 0x00900000, + .offset = 0x00400000, + }, { + .name = "RootFS2", + .size = 0x00300000, + .offset = 0x00d00000, + }, { + .name = "U-Boot Config", + .size = 0x00040000, + .offset = 0x00080000, + }, { + .name = "NAS Config", + .size = 0x00140000, + .offset = 0x000c0000, + }, +}; + +static const struct flash_platform_data qnap_ts41x_flash = { + .type = "m25p128", + .name = "spi_flash", + .parts = qnap_ts41x_partitions, + .nr_parts = ARRAY_SIZE(qnap_ts41x_partitions), +}; + +static struct spi_board_info __initdata qnap_ts41x_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &qnap_ts41x_flash, + .irq = -1, + .max_speed_hz = 20000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +static struct i2c_board_info __initdata qnap_ts41x_i2c_rtc = { + I2C_BOARD_INFO("s35390a", 0x30), +}; + +static struct mv643xx_eth_platform_data qnap_ts41x_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +static struct mv643xx_eth_platform_data qnap_ts41x_ge01_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), +}; + +static struct mv_sata_platform_data qnap_ts41x_sata_data = { + .n_ports = 2, +}; + +static struct gpio_keys_button qnap_ts41x_buttons[] = { + { + .code = KEY_COPY, + .gpio = 43, + .desc = "USB Copy", + .active_low = 1, + }, + { + .code = KEY_RESTART, + .gpio = 37, + .desc = "Reset", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data qnap_ts41x_button_data = { + .buttons = qnap_ts41x_buttons, + .nbuttons = ARRAY_SIZE(qnap_ts41x_buttons), +}; + +static struct platform_device qnap_ts41x_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &qnap_ts41x_button_data, + } +}; + +static unsigned int qnap_ts41x_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP6_SYSRST_OUTn, + MPP7_PEX_RST_OUTn, + MPP8_TW_SDA, + MPP9_TW_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP13_UART1_TXD, /* PIC controller */ + MPP14_UART1_RXD, /* PIC controller */ + MPP15_SATA0_ACTn, + MPP16_SATA1_ACTn, + MPP20_GE1_0, + MPP21_GE1_1, + MPP22_GE1_2, + MPP23_GE1_3, + MPP24_GE1_4, + MPP25_GE1_5, + MPP26_GE1_6, + MPP27_GE1_7, + MPP30_GE1_10, + MPP31_GE1_11, + MPP32_GE1_12, + MPP33_GE1_13, + MPP36_GPIO, /* RAM: 0: 256 MB, 1: 512 MB */ + MPP37_GPIO, /* Reset button */ + MPP43_GPIO, /* USB Copy button */ + MPP44_GPIO, /* Board ID: 0: TS-419U, 1: TS-419 */ + MPP45_GPIO, /* JP1: 0: console, 1: LCD */ + MPP46_GPIO, /* External SATA HDD1 error indicator */ + MPP47_GPIO, /* External SATA HDD2 error indicator */ + MPP48_GPIO, /* External SATA HDD3 error indicator */ + MPP49_GPIO, /* External SATA HDD4 error indicator */ + 0 +}; + + +/***************************************************************************** + * QNAP TS-x19 specific power off method via UART1-attached PIC + ****************************************************************************/ + +#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2)) + +void qnap_ts41x_power_off(void) +{ + /* 19200 baud divisor */ + const unsigned divisor = ((kirkwood_tclk + (8 * 19200)) / (16 * 19200)); + + pr_info("%s: triggering power-off...\n", __func__); + + /* hijack UART1 and reset into sane state (19200,8n1) */ + writel(0x83, UART1_REG(LCR)); + writel(divisor & 0xff, UART1_REG(DLL)); + writel((divisor >> 8) & 0xff, UART1_REG(DLM)); + writel(0x03, UART1_REG(LCR)); + writel(0x00, UART1_REG(IER)); + writel(0x00, UART1_REG(FCR)); + writel(0x00, UART1_REG(MCR)); + + /* send the power-off command 'A' to PIC */ + writel('A', UART1_REG(TX)); +} + +static void __init qnap_ts41x_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(qnap_ts41x_mpp_config); + + kirkwood_uart0_init(); + kirkwood_uart1_init(); /* A PIC controller is connected here. */ + spi_register_board_info(qnap_ts41x_spi_slave_info, + ARRAY_SIZE(qnap_ts41x_spi_slave_info)); + kirkwood_spi_init(); + kirkwood_i2c_init(); + i2c_register_board_info(0, &qnap_ts41x_i2c_rtc, 1); + kirkwood_ge00_init(&qnap_ts41x_ge00_data); + kirkwood_ge01_init(&qnap_ts41x_ge01_data); + kirkwood_sata_init(&qnap_ts41x_sata_data); + kirkwood_ehci_init(); + platform_device_register(&qnap_ts41x_button_device); + + pm_power_off = qnap_ts41x_power_off; + +} + +static int __init ts41x_pci_init(void) +{ + if (machine_is_ts41x()) + kirkwood_pcie_init(); + + return 0; +} +subsys_initcall(ts41x_pci_init); + +MACHINE_START(TS41X, "QNAP TS-41x") + /* Maintainer: Martin Michlmayr */ + .phys_io = KIRKWOOD_REGS_PHYS_BASE, + .io_pg_offst = ((KIRKWOOD_REGS_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .init_machine = qnap_ts41x_init, + .map_io = kirkwood_map_io, + .init_irq = kirkwood_init_irq, + .timer = &kirkwood_timer, +MACHINE_END