From e1cb367de27ca5c186b0f120c3c10a4a0e8edd2e Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Thu, 22 Aug 2013 12:49:07 -0300 Subject: ARM: kirkwood: Add standby support Implements standby support for Kirkwood SoC. When the SoC enters standby state the memory PM units are disabled, the DDR is set in self-refresh mode, and the CPU is set in WFI. At this point there's no clock gating, as that is considered each driver's task. Signed-off-by: Simon Guinot Signed-off-by: Ezequiel Garcia Signed-off-by: Jason Cooper --- arch/arm/mach-kirkwood/Makefile | 2 + arch/arm/mach-kirkwood/board-dt.c | 1 + arch/arm/mach-kirkwood/common.c | 1 + arch/arm/mach-kirkwood/common.h | 6 ++ arch/arm/mach-kirkwood/include/mach/bridge-regs.h | 2 + arch/arm/mach-kirkwood/pm.c | 73 +++++++++++++++++++++++ 6 files changed, 85 insertions(+) create mode 100644 arch/arm/mach-kirkwood/pm.c diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index d1f8e3d0793b..144b51102939 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile @@ -1,5 +1,7 @@ obj-y += common.o pcie.o obj-$(CONFIG_KIRKWOOD_LEGACY) += irq.o mpp.o +obj-$(CONFIG_PM) += pm.o + obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c index 82d3ad8e87cf..cdde73a07c1b 100644 --- a/arch/arm/mach-kirkwood/board-dt.c +++ b/arch/arm/mach-kirkwood/board-dt.c @@ -101,6 +101,7 @@ static void __init kirkwood_dt_init(void) /* Setup clocks for legacy devices */ kirkwood_legacy_clk_init(); + kirkwood_pm_init(); kirkwood_cpuidle_init(); #ifdef CONFIG_KEXEC diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index 176761134a66..f3407a5db216 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c @@ -721,6 +721,7 @@ void __init kirkwood_init(void) kirkwood_xor1_init(); kirkwood_crypto_init(); + kirkwood_pm_init(); kirkwood_cpuidle_init(); #ifdef CONFIG_KEXEC kexec_reinit = kirkwood_enable_pcie; diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h index 1296de94febf..05fd648df543 100644 --- a/arch/arm/mach-kirkwood/common.h +++ b/arch/arm/mach-kirkwood/common.h @@ -58,6 +58,12 @@ void kirkwood_cpufreq_init(void); void kirkwood_restart(enum reboot_mode, const char *); void kirkwood_clk_init(void); +#ifdef CONFIG_PM +void kirkwood_pm_init(void); +#else +static inline void kirkwood_pm_init(void) {}; +#endif + /* board init functions for boards not fully converted to fdt */ #ifdef CONFIG_MACH_MV88F6281GTW_GE_DT void mv88f6281gtw_ge_init(void); diff --git a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h index 91242c944d7a..8b9d1c9ff199 100644 --- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h +++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h @@ -78,4 +78,6 @@ #define CGC_TDM (1 << 20) #define CGC_RESERVED (0x6 << 21) +#define MEMORY_PM_CTRL (BRIDGE_VIRT_BASE + 0x118) + #endif diff --git a/arch/arm/mach-kirkwood/pm.c b/arch/arm/mach-kirkwood/pm.c new file mode 100644 index 000000000000..8783a7184e73 --- /dev/null +++ b/arch/arm/mach-kirkwood/pm.c @@ -0,0 +1,73 @@ +/* + * Power Management driver for Marvell Kirkwood SoCs + * + * Copyright (C) 2013 Ezequiel Garcia + * Copyright (C) 2010 Simon Guinot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License, + * version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + +static void __iomem *ddr_operation_base; + +static void kirkwood_low_power(void) +{ + u32 mem_pm_ctrl; + + mem_pm_ctrl = readl(MEMORY_PM_CTRL); + + /* Set peripherals to low-power mode */ + writel_relaxed(~0, MEMORY_PM_CTRL); + + /* Set DDR in self-refresh */ + writel_relaxed(0x7, ddr_operation_base); + + /* + * Set CPU in wait-for-interrupt state. + * This disables the CPU core clocks, + * the array clocks, and also the L2 controller. + */ + cpu_do_idle(); + + writel_relaxed(mem_pm_ctrl, MEMORY_PM_CTRL); +} + +static int kirkwood_suspend_enter(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_STANDBY: + kirkwood_low_power(); + break; + default: + return -EINVAL; + } + return 0; +} + +static int kirkwood_pm_valid_standby(suspend_state_t state) +{ + return state == PM_SUSPEND_STANDBY; +} + +static const struct platform_suspend_ops kirkwood_suspend_ops = { + .enter = kirkwood_suspend_enter, + .valid = kirkwood_pm_valid_standby, +}; + +int __init kirkwood_pm_init(void) +{ + ddr_operation_base = ioremap(DDR_OPERATION_BASE, 4); + suspend_set_ops(&kirkwood_suspend_ops); + return 0; +} -- cgit v1.2.3 From 511aaab0c41bef55e7a2b2b279c96c4d9a1cbfaa Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Mon, 30 Sep 2013 18:03:27 -0300 Subject: ARM: kirkwood: Remove unneeded MBus initialization Since the MBus is initialized from the DT, it's not necessary to call the legacy initialization. Signed-off-by: Ezequiel Garcia Signed-off-by: Jason Cooper --- arch/arm/mach-kirkwood/board-dt.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c index cdde73a07c1b..334439d8069c 100644 --- a/arch/arm/mach-kirkwood/board-dt.c +++ b/arch/arm/mach-kirkwood/board-dt.c @@ -72,13 +72,6 @@ static void __init kirkwood_dt_time_init(void) clocksource_of_init(); } -static void __init kirkwood_dt_init_early(void) -{ - mvebu_mbus_init("marvell,kirkwood-mbus", - BRIDGE_WINS_BASE, BRIDGE_WINS_SZ, - DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ); -} - static void __init kirkwood_dt_init(void) { pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk); @@ -122,7 +115,6 @@ static const char * const kirkwood_dt_board_compat[] = { DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)") /* Maintainer: Jason Cooper */ .map_io = kirkwood_map_io, - .init_early = kirkwood_dt_init_early, .init_time = kirkwood_dt_time_init, .init_machine = kirkwood_dt_init, .restart = kirkwood_restart, -- cgit v1.2.3 From 3839c08d3ae44cf39b26eecefdae07f7b2443e7e Mon Sep 17 00:00:00 2001 From: Ezequiel Garcia Date: Mon, 30 Sep 2013 18:03:28 -0300 Subject: ARM: kirkwood: Remove unneeded PCIe clock adding Since the PCIe devices is properly initialized from the DT, the clocks are now referenced in the device tree nodes, and it's not needed to have this hack to add them explicitly. Signed-off-by: Ezequiel Garcia Tested-by: Jason Gunthorpe Tested-by: Arnaud Ebalard Signed-off-by: Jason Cooper --- arch/arm/mach-kirkwood/board-dt.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c index 334439d8069c..d8b666c39fd1 100644 --- a/arch/arm/mach-kirkwood/board-dt.c +++ b/arch/arm/mach-kirkwood/board-dt.c @@ -44,14 +44,6 @@ static void __init kirkwood_legacy_clk_init(void) clkspec.np = np; clkspec.args_count = 1; - clkspec.args[0] = CGC_BIT_PEX0; - orion_clkdev_add("0", "pcie", - of_clk_get_from_provider(&clkspec)); - - clkspec.args[0] = CGC_BIT_PEX1; - orion_clkdev_add("1", "pcie", - of_clk_get_from_provider(&clkspec)); - /* * The ethernet interfaces forget the MAC address assigned by * u-boot if the clocks are turned off. Until proper DT support -- cgit v1.2.3 From ebd7d3ab50f960e780e7c825a42b5cb6e21ee376 Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Mon, 7 Oct 2013 22:25:11 +0200 Subject: ARM: kirkwood: retain MAC address for DT ethernet Ethernet IP on Kirkwood SoCs loose their MAC address register content if clock gated. To allow modular ethernet driver setups and gated clocks also on non-DT capable bootloaders, we fixup port device nodes with no valid MAC address property. This patch copies MAC address register contents set up by bootloaders early, notably before ethernet clocks are gated. While at it, also reorder call sequence in _dt_init. Signed-off-by: Sebastian Hesselbarth Reviewed-by: Jason Gunthorpe Reviewed-by: Ezequiel Garcia Reviewed-by: Mike Turquette Tested-by: Andrew Lunn Signed-off-by: Jason Cooper --- arch/arm/mach-kirkwood/board-dt.c | 85 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c index d8b666c39fd1..27c1877e6dda 100644 --- a/arch/arm/mach-kirkwood/board-dt.c +++ b/arch/arm/mach-kirkwood/board-dt.c @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #include @@ -58,6 +60,85 @@ static void __init kirkwood_legacy_clk_init(void) clk_prepare_enable(clk); } +#define MV643XX_ETH_MAC_ADDR_LOW 0x0414 +#define MV643XX_ETH_MAC_ADDR_HIGH 0x0418 + +static void __init kirkwood_dt_eth_fixup(void) +{ + struct device_node *np; + + /* + * The ethernet interfaces forget the MAC address assigned by u-boot + * if the clocks are turned off. Usually, u-boot on kirkwood boards + * has no DT support to properly set local-mac-address property. + * As a workaround, we get the MAC address from mv643xx_eth registers + * and update the port device node if no valid MAC address is set. + */ + for_each_compatible_node(np, NULL, "marvell,kirkwood-eth-port") { + struct device_node *pnp = of_get_parent(np); + struct clk *clk; + struct property *pmac; + void __iomem *io; + u8 *macaddr; + u32 reg; + + if (!pnp) + continue; + + /* skip disabled nodes or nodes with valid MAC address*/ + if (!of_device_is_available(pnp) || of_get_mac_address(np)) + goto eth_fixup_skip; + + clk = of_clk_get(pnp, 0); + if (IS_ERR(clk)) + goto eth_fixup_skip; + + io = of_iomap(pnp, 0); + if (!io) + goto eth_fixup_no_map; + + /* ensure port clock is not gated to not hang CPU */ + clk_prepare_enable(clk); + + /* store MAC address register contents in local-mac-address */ + pr_err(FW_INFO "%s: local-mac-address is not set\n", + np->full_name); + + pmac = kzalloc(sizeof(*pmac) + 6, GFP_KERNEL); + if (!pmac) + goto eth_fixup_no_mem; + + pmac->value = pmac + 1; + pmac->length = 6; + pmac->name = kstrdup("local-mac-address", GFP_KERNEL); + if (!pmac->name) { + kfree(pmac); + goto eth_fixup_no_mem; + } + + macaddr = pmac->value; + reg = readl(io + MV643XX_ETH_MAC_ADDR_HIGH); + macaddr[0] = (reg >> 24) & 0xff; + macaddr[1] = (reg >> 16) & 0xff; + macaddr[2] = (reg >> 8) & 0xff; + macaddr[3] = reg & 0xff; + + reg = readl(io + MV643XX_ETH_MAC_ADDR_LOW); + macaddr[4] = (reg >> 8) & 0xff; + macaddr[5] = reg & 0xff; + + of_update_property(np, pmac); + +eth_fixup_no_mem: + iounmap(io); + clk_disable_unprepare(clk); +eth_fixup_no_map: + clk_put(clk); +eth_fixup_skip: + of_node_put(pnp); + } +} + static void __init kirkwood_dt_time_init(void) { of_clk_init(NULL); @@ -82,12 +163,12 @@ static void __init kirkwood_dt_init(void) kirkwood_l2_init(); kirkwood_cpufreq_init(); - + kirkwood_cpuidle_init(); /* Setup clocks for legacy devices */ kirkwood_legacy_clk_init(); kirkwood_pm_init(); - kirkwood_cpuidle_init(); + kirkwood_dt_eth_fixup(); #ifdef CONFIG_KEXEC kexec_reinit = kirkwood_enable_pcie; -- cgit v1.2.3 From d7f5baeedbdb48d4f5bb2b4f6f56f32b7f2f7aff Mon Sep 17 00:00:00 2001 From: Kevin Hilman Date: Mon, 7 Oct 2013 07:52:33 -0700 Subject: Documentation: arm/Marvell: clarify Armada SoCs that match 78xx0 pattern New users of Marvell SoCs will potentially be confused by the MVEBU SoCs that match the 78xx0 pattern and thus which defconfig and mach-* directory to be looking at. Add a bit of clarification to README for this. Signed-off-by: Kevin Hilman Acked-by: Thomas Petazzoni Signed-off-by: Jason Cooper --- Documentation/arm/Marvell/README | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/arm/Marvell/README b/Documentation/arm/Marvell/README index 8f08a86e03b7..da0151db9964 100644 --- a/Documentation/arm/Marvell/README +++ b/Documentation/arm/Marvell/README @@ -88,6 +88,7 @@ EBU Armada family MV78230 MV78260 MV78460 + NOTE: not to be confused with the non-SMP 78xx0 SoCs Product Brief: http://www.marvell.com/embedded-processors/armada-xp/assets/Marvell-ArmadaXP-SoC-product%20brief.pdf No public datasheet available. -- cgit v1.2.3