From d3e9d8f604f036d32d1511430f14705fb5cdef30 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Thu, 10 Apr 2014 16:46:08 +0200 Subject: cpuidle:clk:Exynos4412: Enable support for clock down when WFI cpuidle state is entered This patch adds support for setting ARM cores' clock frequency down when entering WFI/WFE based cpuidle state. On the Trats2 device: performance governor, 1.4 GHz frequency, no extra load, 4 cores enabled: Without core clock down feature: 395 mA With core clock down feature: 337 mA Power consumption reduction around 15% Change-Id: I7bae29b0332a97c7b18ffb79f4b0a5ff3d70b7ce Signed-off-by: Lukasz Majewski --- arch/arm/mach-exynos/cpuidle.c | 20 +++++++++++++++----- arch/arm/mach-exynos/include/mach/regs-clock.h | 7 +++++++ 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c index df195ed0891..11c3db7b165 100644 --- a/arch/arm/mach-exynos/cpuidle.c +++ b/arch/arm/mach-exynos/cpuidle.c @@ -167,7 +167,7 @@ static int exynos4_enter_lowpower(struct cpuidle_device *dev, return exynos4_enter_core0_aftr(dev, drv, new_index); } -static void __init exynos5_core_down_clk(void) +static void __init exynos_core_down_clk(void) { unsigned int tmp; @@ -183,7 +183,15 @@ static void __init exynos5_core_down_clk(void) PWR_CTRL1_USE_CORE0_WFE | \ PWR_CTRL1_USE_CORE1_WFI | \ PWR_CTRL1_USE_CORE0_WFI; - __raw_writel(tmp, EXYNOS5_PWR_CTRL1); + + if (soc_is_exynos4412()) + tmp |= PWR_CTRL1_USE_CORE3_WFE | \ + PWR_CTRL1_USE_CORE2_WFE | \ + PWR_CTRL1_USE_CORE3_WFI | \ + PWR_CTRL1_USE_CORE2_WFI; + + __raw_writel(tmp, soc_is_exynos5250() ? EXYNOS5_PWR_CTRL1 + : EXYNOS4_PWR_CTRL1); /* * Enable arm clock up (on exiting idle). Set arm divider @@ -196,7 +204,9 @@ static void __init exynos5_core_down_clk(void) PWR_CTRL2_DUR_STANDBY1_VAL | \ PWR_CTRL2_CORE2_UP_RATIO | \ PWR_CTRL2_CORE1_UP_RATIO; - __raw_writel(tmp, EXYNOS5_PWR_CTRL2); + + __raw_writel(tmp, soc_is_exynos5250() ? EXYNOS5_PWR_CTRL2 + : EXYNOS4_PWR_CTRL2); } static int __init exynos4_init_cpuidle(void) @@ -204,8 +214,8 @@ static int __init exynos4_init_cpuidle(void) int cpu_id, ret; struct cpuidle_device *device; - if (soc_is_exynos5250()) - exynos5_core_down_clk(); + if (soc_is_exynos4412() || soc_is_exynos5250()) + exynos_core_down_clk(); ret = cpuidle_register_driver(&exynos4_idle_driver); if (ret) { diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h index d36ad76ad6a..0cf9ad0af65 100644 --- a/arch/arm/mach-exynos/include/mach/regs-clock.h +++ b/arch/arm/mach-exynos/include/mach/regs-clock.h @@ -138,6 +138,9 @@ #define EXYNOS4_CLKGATE_IP_ISP0 EXYNOS_CLKREG(0x18800) #define EXYNOS4_CLKGATE_IP_ISP1 EXYNOS_CLKREG(0x18804) +#define EXYNOS4_PWR_CTRL1 EXYNOS_CLKREG(0x15020) +#define EXYNOS4_PWR_CTRL2 EXYNOS_CLKREG(0x15024) + #define EXYNOS4_APLL_LOCKTIME (0x1C20) /* 300us */ #define EXYNOS4_APLLCON0_ENABLE_SHIFT (31) @@ -351,8 +354,12 @@ #define PWR_CTRL1_CORE1_DOWN_RATIO (7 << 16) #define PWR_CTRL1_DIV2_DOWN_EN (1 << 9) #define PWR_CTRL1_DIV1_DOWN_EN (1 << 8) +#define PWR_CTRL1_USE_CORE3_WFE (1 << 7) +#define PWR_CTRL1_USE_CORE2_WFE (1 << 6) #define PWR_CTRL1_USE_CORE1_WFE (1 << 5) #define PWR_CTRL1_USE_CORE0_WFE (1 << 4) +#define PWR_CTRL1_USE_CORE3_WFI (1 << 3) +#define PWR_CTRL1_USE_CORE2_WFI (1 << 2) #define PWR_CTRL1_USE_CORE1_WFI (1 << 1) #define PWR_CTRL1_USE_CORE0_WFI (1 << 0) -- cgit v1.2.3