From da06aae8b5cae1bd0ac5b7518c9693fe07c06488 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Fri, 28 Nov 2014 00:27:05 +0100 Subject: [PATCH 01/10] ARM vf610: add compatibilty strings of supported Vybrid SoC's The Vybrid SoC family (in the kernel known as vf610) is a familiy of multiple similar SoC's. The VF5xx series comes without secondary Cortex-M4 core, while the second number VFx1x indicates the presence of a L2 cache controller. Signed-off-by: Stefan Agner Signed-off-by: Shawn Guo --- Documentation/devicetree/bindings/arm/fsl.txt | 12 ++++++++++++ arch/arm/mach-imx/mach-vf610.c | 5 ++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/arm/fsl.txt b/Documentation/devicetree/bindings/arm/fsl.txt index 4e8b7df7fc62..c830b5b65882 100644 --- a/Documentation/devicetree/bindings/arm/fsl.txt +++ b/Documentation/devicetree/bindings/arm/fsl.txt @@ -75,6 +75,18 @@ i.MX6q generic board Required root node properties: - compatible = "fsl,imx6q"; +Freescale Vybrid Platform Device Tree Bindings +---------------------------------------------- + +For the Vybrid SoC familiy all variants with DDR controller are supported, +which is the VF5xx and VF6xx series. Out of historical reasons, in most +places the kernel uses vf610 to refer to the whole familiy. + +Required root node compatible property (one of them): + - compatible = "fsl,vf500"; + - compatible = "fsl,vf510"; + - compatible = "fsl,vf600"; + - compatible = "fsl,vf610"; Freescale LS1021A Platform Device Tree Bindings ------------------------------------------------ diff --git a/arch/arm/mach-imx/mach-vf610.c b/arch/arm/mach-imx/mach-vf610.c index c11ab6a1dc87..2e7c75b66fe0 100644 --- a/arch/arm/mach-imx/mach-vf610.c +++ b/arch/arm/mach-imx/mach-vf610.c @@ -13,11 +13,14 @@ #include static const char * const vf610_dt_compat[] __initconst = { + "fsl,vf500", + "fsl,vf510", + "fsl,vf600", "fsl,vf610", NULL, }; -DT_MACHINE_START(VYBRID_VF610, "Freescale Vybrid VF610 (Device Tree)") +DT_MACHINE_START(VYBRID_VF610, "Freescale Vybrid VF5xx/VF6xx (Device Tree)") .l2c_aux_val = 0, .l2c_aux_mask = ~0, .dt_compat = vf610_dt_compat, From 60ad8467c1bf0cae19ccc9d142914a2288ac85e7 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 2 Dec 2014 17:59:42 +0100 Subject: [PATCH 02/10] ARM: imx: pllv3: add shift for frequency multiplier Add shift capabilties for the frequency multiplier (DIV_SELECT) to support Vybrid's USB PLL oddity. The PLL3 and PLL7 are the only PLL control registers which have the DIV_SELECT bit shifted by one. Be aware, there are known documentation errors in the reference manual too. Signed-off-by: Stefan Agner Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-pllv3.c | 10 +++++++--- arch/arm/mach-imx/clk-vf610.c | 4 ++-- arch/arm/mach-imx/clk.h | 1 + 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c index 0ad6e5442fd8..641ebc508920 100644 --- a/arch/arm/mach-imx/clk-pllv3.c +++ b/arch/arm/mach-imx/clk-pllv3.c @@ -31,6 +31,7 @@ * @base: base address of PLL registers * @powerup_set: set POWER bit to power up the PLL * @div_mask: mask of divider bits + * @div_shift: shift of divider bits * * IMX PLL clock version 3, found on i.MX6 series. Divider for pllv3 * is actually a multiplier, and always sits at bit 0. @@ -40,6 +41,7 @@ struct clk_pllv3 { void __iomem *base; bool powerup_set; u32 div_mask; + u32 div_shift; }; #define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw) @@ -97,7 +99,7 @@ static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct clk_pllv3 *pll = to_clk_pllv3(hw); - u32 div = readl_relaxed(pll->base) & pll->div_mask; + u32 div = (readl_relaxed(pll->base) >> pll->div_shift) & pll->div_mask; return (div == 1) ? parent_rate * 22 : parent_rate * 20; } @@ -125,8 +127,8 @@ static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate, return -EINVAL; val = readl_relaxed(pll->base); - val &= ~pll->div_mask; - val |= div; + val &= ~(pll->div_mask << pll->div_shift); + val |= (div << pll->div_shift); writel_relaxed(val, pll->base); return clk_pllv3_wait_lock(pll); @@ -295,6 +297,8 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, case IMX_PLLV3_SYS: ops = &clk_pllv3_sys_ops; break; + case IMX_PLLV3_USB_VF610: + pll->div_shift = 1; case IMX_PLLV3_USB: ops = &clk_pllv3_ops; pll->powerup_set = true; diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c index 5937ddee1a99..cb21777c3ab6 100644 --- a/arch/arm/mach-imx/clk-vf610.c +++ b/arch/arm/mach-imx/clk-vf610.c @@ -172,11 +172,11 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) clk[VF610_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll1", "pll1_bypass_src", PLL1_CTRL, 0x1); clk[VF610_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", PLL2_CTRL, 0x1); - clk[VF610_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", PLL3_CTRL, 0x1); + clk[VF610_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB_VF610, "pll3", "pll3_bypass_src", PLL3_CTRL, 0x2); clk[VF610_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", PLL4_CTRL, 0x7f); clk[VF610_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll5", "pll5_bypass_src", PLL5_CTRL, 0x3); clk[VF610_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_AV, "pll6", "pll6_bypass_src", PLL6_CTRL, 0x7f); - clk[VF610_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", PLL7_CTRL, 0x1); + clk[VF610_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB_VF610, "pll7", "pll7_bypass_src", PLL7_CTRL, 0x2); clk[VF610_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", PLL1_CTRL, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); clk[VF610_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", PLL2_CTRL, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h index 5ef82e2f8fc5..6a07903a28bc 100644 --- a/arch/arm/mach-imx/clk.h +++ b/arch/arm/mach-imx/clk.h @@ -20,6 +20,7 @@ enum imx_pllv3_type { IMX_PLLV3_GENERIC, IMX_PLLV3_SYS, IMX_PLLV3_USB, + IMX_PLLV3_USB_VF610, IMX_PLLV3_AV, IMX_PLLV3_ENET, }; From 3d27bc5c313ef9f953d1a8eb6927307cdda3aa52 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 10 Dec 2014 17:51:42 +0800 Subject: [PATCH 03/10] ARM: imx: correct the hardware clock gate setting for shared nodes For those clk gates which hold share count, since its is_enabled callback is only checking the share count rather than reading the hardware register setting, in the late phase of kernel bootup, the clk_disable_unused action will NOT handle the scenario of share_count is 0 but the hardware setting is enabled, actually, U-Boot normally enables all clk gates, then those shared clk gates will be always enabled until they are used by some modules. So the problem would be: when kernel boot up, the usecount cat from clk tree is 0, but the clk gates actually is enabled in hardware register, it will confuse user and bring unnecessary power consumption. This patch adds .disable_unused callback and using hardware register check for .is_enabled callback of shared nodes to handle such scenario in late phase of kernel boot up, then the hardware status will match the clk tree info. Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-gate2.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c index 5a75cdc81891..8935bff99fe7 100644 --- a/arch/arm/mach-imx/clk-gate2.c +++ b/arch/arm/mach-imx/clk-gate2.c @@ -96,15 +96,30 @@ static int clk_gate2_is_enabled(struct clk_hw *hw) { struct clk_gate2 *gate = to_clk_gate2(hw); - if (gate->share_count) - return !!__clk_get_enable_count(hw->clk); - else - return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx); + return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx); +} + +static void clk_gate2_disable_unused(struct clk_hw *hw) +{ + struct clk_gate2 *gate = to_clk_gate2(hw); + unsigned long flags = 0; + u32 reg; + + spin_lock_irqsave(gate->lock, flags); + + if (!gate->share_count || *gate->share_count == 0) { + reg = readl(gate->reg); + reg &= ~(3 << gate->bit_idx); + writel(reg, gate->reg); + } + + spin_unlock_irqrestore(gate->lock, flags); } static struct clk_ops clk_gate2_ops = { .enable = clk_gate2_enable, .disable = clk_gate2_disable, + .disable_unused = clk_gate2_disable_unused, .is_enabled = clk_gate2_is_enabled, }; From df096fde0889a7a624fcc9616ff5ebd7446d131e Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 17 Dec 2014 12:23:19 +0800 Subject: [PATCH 04/10] ARM: imx: remove unnecessary setting for DSM Now we support DSM in OCRAM for all i.MX6 SoCs, the resume entry point is set in asm code of suspend-imx6.S, so no need to set the resume entry point for SRC in pre-suspend flow. Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/pm-imx6.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index 5d2c1bd5f5ef..661ffcf1031e 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -362,7 +362,6 @@ static int imx6q_pm_enter(suspend_state_t state) imx6q_enable_rbc(true); imx_gpc_pre_suspend(true); imx_anatop_pre_suspend(); - imx_set_cpu_jump(0, v7_cpu_resume); /* Zzz ... */ cpu_suspend(0, imx6q_suspend_finish); if (cpu_is_imx6q() || cpu_is_imx6dl()) From 05136f0897b526b9cd090c93b95bbd1b67c18cc5 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Wed, 17 Dec 2014 12:24:12 +0800 Subject: [PATCH 05/10] ARM: imx: support arm power off in cpuidle for i.mx6sx This patch introduces an independent cpuidle driver for i.MX6SX, and supports arm power off in idle, totally 3 levels of cpuidle are supported as below: 1. ARM WFI; 2. SOC in WAIT mode; 3. SOC in WAIT mode + ARM power off. ARM power off can save at least 5mW power. This patch also replaces imx6q_enable_rbc with imx6_enable_rbc. Signed-off-by: Anson Huang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/Makefile | 3 +- arch/arm/mach-imx/common.h | 4 ++ arch/arm/mach-imx/cpuidle-imx6sx.c | 107 +++++++++++++++++++++++++++++ arch/arm/mach-imx/cpuidle.h | 5 ++ arch/arm/mach-imx/gpc.c | 25 ++++++- arch/arm/mach-imx/mach-imx6sx.c | 2 +- arch/arm/mach-imx/pm-imx6.c | 6 +- 7 files changed, 144 insertions(+), 8 deletions(-) create mode 100644 arch/arm/mach-imx/cpuidle-imx6sx.c diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index f5ac685a29fc..8d1b10180908 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -32,8 +32,7 @@ ifeq ($(CONFIG_CPU_IDLE),y) obj-$(CONFIG_SOC_IMX5) += cpuidle-imx5.o obj-$(CONFIG_SOC_IMX6Q) += cpuidle-imx6q.o obj-$(CONFIG_SOC_IMX6SL) += cpuidle-imx6sl.o -# i.MX6SX reuses i.MX6Q cpuidle driver -obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6q.o +obj-$(CONFIG_SOC_IMX6SX) += cpuidle-imx6sx.o endif ifdef CONFIG_SND_IMX_SOC diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index cfcdb623d78f..1028b6c505c4 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -70,6 +70,10 @@ void imx_set_soc_revision(unsigned int rev); unsigned int imx_get_soc_revision(void); void imx_init_revision_from_anatop(void); struct device *imx_soc_device_init(void); +void imx6_enable_rbc(bool enable); +void imx_gpc_set_arm_power_in_lpm(bool power_off); +void imx_gpc_set_arm_power_up_timing(u32 sw2iso, u32 sw); +void imx_gpc_set_arm_power_down_timing(u32 sw2iso, u32 sw); enum mxc_cpu_pwr_mode { WAIT_CLOCKED, /* wfi only */ diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c new file mode 100644 index 000000000000..d8a9f219e028 --- /dev/null +++ b/arch/arm/mach-imx/cpuidle-imx6sx.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2014 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "cpuidle.h" + +static int imx6sx_idle_finish(unsigned long val) +{ + cpu_do_idle(); + + return 0; +} + +static int imx6sx_enter_wait(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + imx6q_set_lpm(WAIT_UNCLOCKED); + + switch (index) { + case 1: + cpu_do_idle(); + break; + case 2: + imx6_enable_rbc(true); + imx_gpc_set_arm_power_in_lpm(true); + imx_set_cpu_jump(0, v7_cpu_resume); + /* Need to notify there is a cpu pm operation. */ + cpu_pm_enter(); + cpu_cluster_pm_enter(); + + cpu_suspend(0, imx6sx_idle_finish); + + cpu_cluster_pm_exit(); + cpu_pm_exit(); + imx_gpc_set_arm_power_in_lpm(false); + imx6_enable_rbc(false); + break; + default: + break; + } + + imx6q_set_lpm(WAIT_CLOCKED); + + return index; +} + +static struct cpuidle_driver imx6sx_cpuidle_driver = { + .name = "imx6sx_cpuidle", + .owner = THIS_MODULE, + .states = { + /* WFI */ + ARM_CPUIDLE_WFI_STATE, + /* WAIT */ + { + .exit_latency = 50, + .target_residency = 75, + .flags = CPUIDLE_FLAG_TIME_VALID | + CPUIDLE_FLAG_TIMER_STOP, + .enter = imx6sx_enter_wait, + .name = "WAIT", + .desc = "Clock off", + }, + /* WAIT + ARM power off */ + { + /* + * ARM gating 31us * 5 + RBC clear 65us + * and some margin for SW execution, here set it + * to 300us. + */ + .exit_latency = 300, + .target_residency = 500, + .flags = CPUIDLE_FLAG_TIME_VALID, + .enter = imx6sx_enter_wait, + .name = "LOW-POWER-IDLE", + .desc = "ARM power off", + }, + }, + .state_count = 3, + .safe_state_index = 0, +}; + +int __init imx6sx_cpuidle_init(void) +{ + imx6_enable_rbc(false); + /* + * set ARM power up/down timing to the fastest, + * sw2iso and sw can be set to one 32K cycle = 31us + * except for power up sw2iso which need to be + * larger than LDO ramp up time. + */ + imx_gpc_set_arm_power_up_timing(2, 1); + imx_gpc_set_arm_power_down_timing(1, 1); + + return cpuidle_register(&imx6sx_cpuidle_driver, NULL); +} diff --git a/arch/arm/mach-imx/cpuidle.h b/arch/arm/mach-imx/cpuidle.h index 24e33670417c..f9140128ba05 100644 --- a/arch/arm/mach-imx/cpuidle.h +++ b/arch/arm/mach-imx/cpuidle.h @@ -14,6 +14,7 @@ extern int imx5_cpuidle_init(void); extern int imx6q_cpuidle_init(void); extern int imx6sl_cpuidle_init(void); +extern int imx6sx_cpuidle_init(void); #else static inline int imx5_cpuidle_init(void) { @@ -27,4 +28,8 @@ static inline int imx6sl_cpuidle_init(void) { return 0; } +static inline int imx6sx_cpuidle_init(void) +{ + return 0; +} #endif diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index 5f3602ec74fa..745caa18ab2c 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c @@ -20,6 +20,10 @@ #define GPC_IMR1 0x008 #define GPC_PGC_CPU_PDN 0x2a0 +#define GPC_PGC_CPU_PUPSCR 0x2a4 +#define GPC_PGC_CPU_PDNSCR 0x2a8 +#define GPC_PGC_SW2ISO_SHIFT 0x8 +#define GPC_PGC_SW_SHIFT 0x0 #define IMR_NUM 4 @@ -27,6 +31,23 @@ static void __iomem *gpc_base; static u32 gpc_wake_irqs[IMR_NUM]; static u32 gpc_saved_imrs[IMR_NUM]; +void imx_gpc_set_arm_power_up_timing(u32 sw2iso, u32 sw) +{ + writel_relaxed((sw2iso << GPC_PGC_SW2ISO_SHIFT) | + (sw << GPC_PGC_SW_SHIFT), gpc_base + GPC_PGC_CPU_PUPSCR); +} + +void imx_gpc_set_arm_power_down_timing(u32 sw2iso, u32 sw) +{ + writel_relaxed((sw2iso << GPC_PGC_SW2ISO_SHIFT) | + (sw << GPC_PGC_SW_SHIFT), gpc_base + GPC_PGC_CPU_PDNSCR); +} + +void imx_gpc_set_arm_power_in_lpm(bool power_off) +{ + writel_relaxed(power_off, gpc_base + GPC_PGC_CPU_PDN); +} + void imx_gpc_pre_suspend(bool arm_power_off) { void __iomem *reg_imr1 = gpc_base + GPC_IMR1; @@ -34,7 +55,7 @@ void imx_gpc_pre_suspend(bool arm_power_off) /* Tell GPC to power off ARM core when suspend */ if (arm_power_off) - writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN); + imx_gpc_set_arm_power_in_lpm(arm_power_off); for (i = 0; i < IMR_NUM; i++) { gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4); @@ -48,7 +69,7 @@ void imx_gpc_post_resume(void) int i; /* Keep ARM core powered on for other low-power modes */ - writel_relaxed(0x0, gpc_base + GPC_PGC_CPU_PDN); + imx_gpc_set_arm_power_in_lpm(false); for (i = 0; i < IMR_NUM; i++) writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4); diff --git a/arch/arm/mach-imx/mach-imx6sx.c b/arch/arm/mach-imx/mach-imx6sx.c index 7a96c6577234..66988eb6a3a4 100644 --- a/arch/arm/mach-imx/mach-imx6sx.c +++ b/arch/arm/mach-imx/mach-imx6sx.c @@ -90,7 +90,7 @@ static void __init imx6sx_init_irq(void) static void __init imx6sx_init_late(void) { - imx6q_cpuidle_init(); + imx6sx_cpuidle_init(); if (IS_ENABLED(CONFIG_ARM_IMX6Q_CPUFREQ)) platform_device_register_simple("imx6q-cpufreq", -1, NULL, 0); diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index 661ffcf1031e..46fd695203c7 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -205,7 +205,7 @@ void imx6q_set_int_mem_clk_lpm(bool enable) writel_relaxed(val, ccm_base + CGPR); } -static void imx6q_enable_rbc(bool enable) +void imx6_enable_rbc(bool enable) { u32 val; @@ -359,7 +359,7 @@ static int imx6q_pm_enter(suspend_state_t state) * RBC setting, so we do NOT need to do that here. */ if (!imx6_suspend_in_ocram_fn) - imx6q_enable_rbc(true); + imx6_enable_rbc(true); imx_gpc_pre_suspend(true); imx_anatop_pre_suspend(); /* Zzz ... */ @@ -368,7 +368,7 @@ static int imx6q_pm_enter(suspend_state_t state) imx_smp_prepare(); imx_anatop_post_resume(); imx_gpc_post_resume(); - imx6q_enable_rbc(false); + imx6_enable_rbc(false); imx6q_enable_wb(false); imx6q_set_int_mem_clk_lpm(true); imx6q_set_lpm(WAIT_CLOCKED); From c8aeb7dfe6e815906c3d9c23ce17a00e8d01b3d5 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Tue, 6 Jan 2015 20:06:16 +0800 Subject: [PATCH 06/10] ARM: imx: drop CPUIDLE_FLAG_TIME_VALID from cpuidle-imx6sx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the result of commit b82b6cca4880 ("cpuidle: Invert CPUIDLE_FLAG_TIME_VALID logic"), the flag gets removed and hence we see the compile error below. CC arch/arm/mach-imx/cpuidle-imx6sx.o arch/arm/mach-imx/cpuidle-imx6sx.c:69:13: error: ‘CPUIDLE_FLAG_TIME_VALID’ undeclared here (not in a function) Since the behavior of the original flag has been the default, we can simply drop the flag now. Reported-by: kbuild test robot Signed-off-by: Shawn Guo --- arch/arm/mach-imx/cpuidle-imx6sx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c index d8a9f219e028..5a36722b089d 100644 --- a/arch/arm/mach-imx/cpuidle-imx6sx.c +++ b/arch/arm/mach-imx/cpuidle-imx6sx.c @@ -66,8 +66,7 @@ static struct cpuidle_driver imx6sx_cpuidle_driver = { { .exit_latency = 50, .target_residency = 75, - .flags = CPUIDLE_FLAG_TIME_VALID | - CPUIDLE_FLAG_TIMER_STOP, + .flags = CPUIDLE_FLAG_TIMER_STOP, .enter = imx6sx_enter_wait, .name = "WAIT", .desc = "Clock off", @@ -81,7 +80,6 @@ static struct cpuidle_driver imx6sx_cpuidle_driver = { */ .exit_latency = 300, .target_residency = 500, - .flags = CPUIDLE_FLAG_TIME_VALID, .enter = imx6sx_enter_wait, .name = "LOW-POWER-IDLE", .desc = "ARM power off", From 6f540db781cf4416e348d20d63eb121f5bf1fb24 Mon Sep 17 00:00:00 2001 From: Bhuvanchandra DV Date: Tue, 6 Jan 2015 19:06:56 +0530 Subject: [PATCH 07/10] ARM: imx: clk-vf610: Add clock for UART4 and UART5 Add support for clock gating of UART4 and UART5. We use these UART's in a (not yet mainlined) device tree. Signed-off-by: Bhuvanchandra DV Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-vf610.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c index cb21777c3ab6..af338d23e6e7 100644 --- a/arch/arm/mach-imx/clk-vf610.c +++ b/arch/arm/mach-imx/clk-vf610.c @@ -267,6 +267,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) clk[VF610_CLK_UART1] = imx_clk_gate2("uart1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(8)); clk[VF610_CLK_UART2] = imx_clk_gate2("uart2", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(9)); clk[VF610_CLK_UART3] = imx_clk_gate2("uart3", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(10)); + clk[VF610_CLK_UART4] = imx_clk_gate2("uart4", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(9)); + clk[VF610_CLK_UART5] = imx_clk_gate2("uart5", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(10)); clk[VF610_CLK_I2C0] = imx_clk_gate2("i2c0", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(6)); clk[VF610_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(7)); From c205389557aac828f8403db0368d1fc2ef859213 Mon Sep 17 00:00:00 2001 From: Sanchayan Maity Date: Wed, 7 Jan 2015 12:39:29 +0530 Subject: [PATCH 08/10] ARM: imx: clk-vf610: Add clock for SNVS Add support for clock gating of the SNVS peripheral. Signed-off-by: Sanchayan Maity Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-vf610.c | 2 ++ include/dt-bindings/clock/vf610-clock.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c index af338d23e6e7..61876ed6e11e 100644 --- a/arch/arm/mach-imx/clk-vf610.c +++ b/arch/arm/mach-imx/clk-vf610.c @@ -382,6 +382,8 @@ static void __init vf610_clocks_init(struct device_node *ccm_node) clk[VF610_CLK_DMAMUX2] = imx_clk_gate2("dmamux2", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(1)); clk[VF610_CLK_DMAMUX3] = imx_clk_gate2("dmamux3", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(2)); + clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7)); + imx_check_clocks(clk, ARRAY_SIZE(clk)); clk_set_parent(clk[VF610_CLK_QSPI0_SEL], clk[VF610_CLK_PLL1_PFD4]); diff --git a/include/dt-bindings/clock/vf610-clock.h b/include/dt-bindings/clock/vf610-clock.h index 801c0ac50c47..979d24a6799f 100644 --- a/include/dt-bindings/clock/vf610-clock.h +++ b/include/dt-bindings/clock/vf610-clock.h @@ -192,6 +192,7 @@ #define VF610_PLL5_BYPASS 179 #define VF610_PLL6_BYPASS 180 #define VF610_PLL7_BYPASS 181 -#define VF610_CLK_END 182 +#define VF610_CLK_SNVS 182 +#define VF610_CLK_END 183 #endif /* __DT_BINDINGS_CLOCK_VF610_H */ From 23bec1727505de4adf3f0ed228bcb8b1a3d2e551 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 13 Jan 2015 18:46:53 +0100 Subject: [PATCH 09/10] ARM i.MX6q: unmap memory mapped at imx6q_opp_check_speed_grading() imx6q_opp_check_speed_grading() remaps memory to the base variable and never unmaps it. I can't see how this can be of any use later so here I unmap it. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Shawn Guo --- arch/arm/mach-imx/mach-imx6q.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 5057d61298b7..4ad6e473cf83 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -329,7 +329,7 @@ static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev) if (dev_pm_opp_disable(cpu_dev, 852000000)) pr_warn("failed to disable 852 MHz OPP\n"); } - + iounmap(base); put_node: of_node_put(np); } From ade9233f2e0cf4b7bf10fd122c7e9f9310bfd1a5 Mon Sep 17 00:00:00 2001 From: Shengjiu Wang Date: Fri, 16 Jan 2015 10:57:04 +0800 Subject: [PATCH 10/10] ARM: clk-imx6q: refine esai_ipg's parent esai_ipg clock's parent is ahb, not ipg. Signed-off-by: Shengjiu Wang Signed-off-by: Shawn Guo --- arch/arm/mach-imx/clk-imx6q.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c index 5951660d1bd2..108b80bb048a 100644 --- a/arch/arm/mach-imx/clk-imx6q.c +++ b/arch/arm/mach-imx/clk-imx6q.c @@ -386,7 +386,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8); clk[IMX6QDL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10); clk[IMX6QDL_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai); - clk[IMX6QDL_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ipg", base + 0x6c, 16, &share_count_esai); + clk[IMX6QDL_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai); clk[IMX6QDL_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); clk[IMX6QDL_CLK_GPT_IPG] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20); clk[IMX6QDL_CLK_GPT_IPG_PER] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22);