summaryrefslogtreecommitdiff
path: root/arch/arm/mach-exynos/cpuidle.c
diff options
context:
space:
mode:
authorAbhilash Kesavan <a.kesavan@samsung.com>2012-11-20 11:34:58 (GMT)
committerKukjin Kim <kgene.kim@samsung.com>2012-11-20 11:34:58 (GMT)
commit0f9e03591f9bbcf205a7fff5b5ae9e445b5c3dc3 (patch)
tree546ee9c0a3936e4b1cfd066789da7382b4aa32a1 /arch/arm/mach-exynos/cpuidle.c
parent86ffb0e83a55aef81e96a9cede28af576c9d5541 (diff)
downloadlinux-fsl-qoriq-0f9e03591f9bbcf205a7fff5b5ae9e445b5c3dc3.tar.xz
ARM: EXYNOS: Add ARM down clock support
In idle state down clocking the arm cores can result in power savings. Program the power control registers to achieve this and save these registers across a suspend/resume cycle. Signed-off-by: Abhilash Kesavan <a.kesavan@samsung.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'arch/arm/mach-exynos/cpuidle.c')
-rw-r--r--arch/arm/mach-exynos/cpuidle.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/arch/arm/mach-exynos/cpuidle.c b/arch/arm/mach-exynos/cpuidle.c
index cff0595..4ddda91 100644
--- a/arch/arm/mach-exynos/cpuidle.c
+++ b/arch/arm/mach-exynos/cpuidle.c
@@ -21,6 +21,7 @@
#include <asm/suspend.h>
#include <asm/unified.h>
#include <asm/cpuidle.h>
+#include <mach/regs-clock.h>
#include <mach/regs-pmu.h>
#include <mach/pmu.h>
@@ -156,12 +157,47 @@ 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)
+{
+ unsigned int tmp;
+
+ /*
+ * Enable arm clock down (in idle) and set arm divider
+ * ratios in WFI/WFE state.
+ */
+ tmp = PWR_CTRL1_CORE2_DOWN_RATIO | \
+ PWR_CTRL1_CORE1_DOWN_RATIO | \
+ PWR_CTRL1_DIV2_DOWN_EN | \
+ PWR_CTRL1_DIV1_DOWN_EN | \
+ PWR_CTRL1_USE_CORE1_WFE | \
+ PWR_CTRL1_USE_CORE0_WFE | \
+ PWR_CTRL1_USE_CORE1_WFI | \
+ PWR_CTRL1_USE_CORE0_WFI;
+ __raw_writel(tmp, EXYNOS5_PWR_CTRL1);
+
+ /*
+ * Enable arm clock up (on exiting idle). Set arm divider
+ * ratios when not in idle along with the standby duration
+ * ratios.
+ */
+ tmp = PWR_CTRL2_DIV2_UP_EN | \
+ PWR_CTRL2_DIV1_UP_EN | \
+ PWR_CTRL2_DUR_STANDBY2_VAL | \
+ PWR_CTRL2_DUR_STANDBY1_VAL | \
+ PWR_CTRL2_CORE2_UP_RATIO | \
+ PWR_CTRL2_CORE1_UP_RATIO;
+ __raw_writel(tmp, EXYNOS5_PWR_CTRL2);
+}
+
static int __init exynos4_init_cpuidle(void)
{
int i, max_cpuidle_state, cpu_id;
struct cpuidle_device *device;
struct cpuidle_driver *drv = &exynos4_idle_driver;
+ if (soc_is_exynos5250())
+ exynos5_core_down_clk();
+
/* Setup cpuidle driver */
drv->state_count = (sizeof(exynos4_cpuidle_set) /
sizeof(struct cpuidle_state));