From 72b58f2eb12ad4aa0c59481d0911dc5e39180eb5 Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 26 Nov 2014 09:00:08 +0000 Subject: add new target 'oxnas' This is the oxnas target previously developed at http://gitorious.org/openwrt-oxnas Basically, this consolidates the changes and addtionas from http://github.org/kref/linux-oxnas into a new OpenWrt hardware target 'oxnas' adding support for PLX Technology NAS7820/NAS7821/NAS7825/... formally known as Oxford Semiconductor OXE810SE/OXE815/OX820/... For now there are 4 supported boards: Cloud Engines Pogoplug V3 (without PCIe) fully supported Cloud Engines Pogoplug Pro (with PCIe) fully supported MitraStar STG-212 aka ZyXEL NSA-212, aka Medion Akoya P89625 / P89636 / P89626 / P89630, aka Medion MD 86407 / MD 86805 / MD 86517 / MD 86587 fully supported, see http://wiki.openwrt.org/toh/medion/md86587 Shuttle KD-20 partially supported (S-ATA driver lacks support for 2nd port) Signed-off-by: Daniel Golle SVN-Revision: 43388 --- .../oxnas/files/arch/arm/mach-oxnas/mach-ox820.c | 284 +++++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 target/linux/oxnas/files/arch/arm/mach-oxnas/mach-ox820.c (limited to 'target/linux/oxnas/files/arch/arm/mach-oxnas/mach-ox820.c') diff --git a/target/linux/oxnas/files/arch/arm/mach-oxnas/mach-ox820.c b/target/linux/oxnas/files/arch/arm/mach-oxnas/mach-ox820.c new file mode 100644 index 0000000000..4b247b6b56 --- /dev/null +++ b/target/linux/oxnas/files/arch/arm/mach-oxnas/mach-ox820.c @@ -0,0 +1,284 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct map_desc ox820_io_desc[] __initdata = { + { + .virtual = (unsigned long)OXNAS_PERCPU_BASE_VA, + .pfn = __phys_to_pfn(OXNAS_PERCPU_BASE), + .length = OXNAS_PERCPU_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = (unsigned long)OXNAS_SYSCRTL_BASE_VA, + .pfn = __phys_to_pfn(OXNAS_SYSCRTL_BASE), + .length = OXNAS_SYSCRTL_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = (unsigned long)OXNAS_SECCRTL_BASE_VA, + .pfn = __phys_to_pfn(OXNAS_SECCRTL_BASE), + .length = OXNAS_SECCRTL_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = (unsigned long)OXNAS_RPSA_BASE_VA, + .pfn = __phys_to_pfn(OXNAS_RPSA_BASE), + .length = OXNAS_RPSA_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = (unsigned long)OXNAS_RPSC_BASE_VA, + .pfn = __phys_to_pfn(OXNAS_RPSC_BASE), + .length = OXNAS_RPSC_SIZE, + .type = MT_DEVICE, + }, +}; + +void __init ox820_map_common_io(void) +{ + debug_ll_io_init(); + iotable_init(ox820_io_desc, ARRAY_SIZE(ox820_io_desc)); +} + +struct plat_gmac_data { + struct plat_stmmacenet_data stmmac; + struct clk *clk; +}; + +void *ox820_gmac_setup(struct platform_device *pdev) +{ + struct plat_gmac_data *pdata = pdev->dev.platform_data; + + pdata->clk = clk_get(&pdev->dev, "gmac"); + return (void *) pdata->clk; +}; + +int ox820_gmac_init(struct platform_device *pdev, void *priv) +{ + int ret; + unsigned value; + + ret = device_reset(&pdev->dev); + if (ret) + return ret; + + if (IS_ERR(priv)) + return PTR_ERR(priv); + clk_prepare_enable(priv); + + value = readl(SYS_CTRL_GMAC_CTRL); + + /* Enable GMII_GTXCLK to follow GMII_REFCLK, required for gigabit PHY */ + value |= BIT(SYS_CTRL_GMAC_CKEN_GTX); + /* Use simple mux for 25/125 Mhz clock switching */ + value |= BIT(SYS_CTRL_GMAC_SIMPLE_MUX); + /* set auto switch tx clock source */ + value |= BIT(SYS_CTRL_GMAC_AUTO_TX_SOURCE); + /* enable tx & rx vardelay */ + value |= BIT(SYS_CTRL_GMAC_CKEN_TX_OUT); + value |= BIT(SYS_CTRL_GMAC_CKEN_TXN_OUT); + value |= BIT(SYS_CTRL_GMAC_CKEN_TX_IN); + value |= BIT(SYS_CTRL_GMAC_CKEN_RX_OUT); + value |= BIT(SYS_CTRL_GMAC_CKEN_RXN_OUT); + value |= BIT(SYS_CTRL_GMAC_CKEN_RX_IN); + writel(value, SYS_CTRL_GMAC_CTRL); + + /* set tx & rx vardelay */ + value = 0; + value |= SYS_CTRL_GMAC_TX_VARDELAY(4); + value |= SYS_CTRL_GMAC_TXN_VARDELAY(2); + value |= SYS_CTRL_GMAC_RX_VARDELAY(10); + value |= SYS_CTRL_GMAC_RXN_VARDELAY(8); + writel(value, SYS_CTRL_GMAC_DELAY_CTRL); + + return 0; +} + +void ox820_gmac_exit(struct platform_device *pdev, void *priv) +{ + struct reset_control *rstc; + + clk_disable_unprepare(priv); + clk_put(priv); + + rstc = reset_control_get(&pdev->dev, NULL); + if (!IS_ERR(rstc)) { + reset_control_assert(rstc); + reset_control_put(rstc); + } +} + +static int __init ox820_ether_init(void) +{ + struct device_node *node; + struct platform_device *pdev; + struct plat_gmac_data *pdata; + + node = of_find_compatible_node(NULL, NULL, "plxtech,nas782x-gmac"); + if (!node) + return -ENOENT; + + pdev = of_find_device_by_node(node); + of_node_put(node); + + if (!pdev) + return -EINVAL; + + pdata = kzalloc(sizeof(struct plat_gmac_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + pdata->stmmac.setup = ox820_gmac_setup; + pdata->stmmac.init = ox820_gmac_init; + pdata->stmmac.exit = ox820_gmac_exit; + pdev->dev.platform_data = pdata; + + return 0; +} + +static void __init ox820_dt_init(void) +{ + int ret; + + ret = of_platform_populate(NULL, of_default_bus_match_table, NULL, + NULL); + + if (ret) { + pr_err("of_platform_populate failed: %d\n", ret); + BUG(); + } + + ret = ox820_ether_init(); + + if (ret) + pr_info("ox820_ether_init failed: %d\n", ret); +} + +static void __init ox820_timer_init(void) +{ + of_clk_init(NULL); + clocksource_of_init(); +} + +void ox820_init_early(void) +{ + +} + +void ox820_assert_system_reset(enum reboot_mode mode, const char *cmd) +{ + u32 value; + +/* Assert reset to cores as per power on defaults + * Don't touch the DDR interface as things will come to an impromptu stop + * NB Possibly should be asserting reset for PLLB, but there are timing + * concerns here according to the docs */ + value = BIT(SYS_CTRL_RST_COPRO) | + BIT(SYS_CTRL_RST_USBHS) | + BIT(SYS_CTRL_RST_USBHSPHYA) | + BIT(SYS_CTRL_RST_MACA) | + BIT(SYS_CTRL_RST_PCIEA) | + BIT(SYS_CTRL_RST_SGDMA) | + BIT(SYS_CTRL_RST_CIPHER) | + BIT(SYS_CTRL_RST_SATA) | + BIT(SYS_CTRL_RST_SATA_LINK) | + BIT(SYS_CTRL_RST_SATA_PHY) | + BIT(SYS_CTRL_RST_PCIEPHY) | + BIT(SYS_CTRL_RST_STATIC) | + BIT(SYS_CTRL_RST_UART1) | + BIT(SYS_CTRL_RST_UART2) | + BIT(SYS_CTRL_RST_MISC) | + BIT(SYS_CTRL_RST_I2S) | + BIT(SYS_CTRL_RST_SD) | + BIT(SYS_CTRL_RST_MACB) | + BIT(SYS_CTRL_RST_PCIEB) | + BIT(SYS_CTRL_RST_VIDEO) | + BIT(SYS_CTRL_RST_USBHSPHYB) | + BIT(SYS_CTRL_RST_USBDEV); + + writel(value, SYS_CTRL_RST_SET_CTRL); + + /* Release reset to cores as per power on defaults */ + writel(BIT(SYS_CTRL_RST_GPIO), SYS_CTRL_RST_CLR_CTRL); + + /* Disable clocks to cores as per power-on defaults - must leave DDR + * related clocks enabled otherwise we'll stop rather abruptly. */ + value = + BIT(SYS_CTRL_CLK_COPRO) | + BIT(SYS_CTRL_CLK_DMA) | + BIT(SYS_CTRL_CLK_CIPHER) | + BIT(SYS_CTRL_CLK_SD) | + BIT(SYS_CTRL_CLK_SATA) | + BIT(SYS_CTRL_CLK_I2S) | + BIT(SYS_CTRL_CLK_USBHS) | + BIT(SYS_CTRL_CLK_MAC) | + BIT(SYS_CTRL_CLK_PCIEA) | + BIT(SYS_CTRL_CLK_STATIC) | + BIT(SYS_CTRL_CLK_MACB) | + BIT(SYS_CTRL_CLK_PCIEB) | + BIT(SYS_CTRL_CLK_REF600) | + BIT(SYS_CTRL_CLK_USBDEV); + + writel(value, SYS_CTRL_CLK_CLR_CTRL); + + /* Enable clocks to cores as per power-on defaults */ + + /* Set sys-control pin mux'ing as per power-on defaults */ + writel(0, SYS_CTRL_SECONDARY_SEL); + writel(0, SYS_CTRL_TERTIARY_SEL); + writel(0, SYS_CTRL_QUATERNARY_SEL); + writel(0, SYS_CTRL_DEBUG_SEL); + writel(0, SYS_CTRL_ALTERNATIVE_SEL); + writel(0, SYS_CTRL_PULLUP_SEL); + + writel(0, SYS_CTRL_SECONDARY_SEL); + writel(0, SYS_CTRL_TERTIARY_SEL); + writel(0, SYS_CTRL_QUATERNARY_SEL); + writel(0, SYS_CTRL_DEBUG_SEL); + writel(0, SYS_CTRL_ALTERNATIVE_SEL); + writel(0, SYS_CTRL_PULLUP_SEL); + + /* No need to save any state, as the ROM loader can determine whether + * reset is due to power cycling or programatic action, just hit the + * (self-clearing) CPU reset bit of the block reset register */ + value = + BIT(SYS_CTRL_RST_SCU) | + BIT(SYS_CTRL_RST_ARM0) | + BIT(SYS_CTRL_RST_ARM1); + + writel(value, SYS_CTRL_RST_SET_CTRL); +} + +static const char * const ox820_dt_board_compat[] = { + "plxtech,nas7820", + "plxtech,nas7821", + "plxtech,nas7825", + NULL +}; + +DT_MACHINE_START(OX820_DT, "PLXTECH NAS782X SoC (Flattened Device Tree)") + .map_io = ox820_map_common_io, + .smp = smp_ops(ox820_smp_ops), + .init_early = ox820_init_early, + .init_time = ox820_timer_init, + .init_machine = ox820_dt_init, + .restart = ox820_assert_system_reset, + .dt_compat = ox820_dt_board_compat, +MACHINE_END -- cgit v1.2.3