From mboxrd@z Thu Jan 1 00:00:00 1970 From: kgene@kernel.org (Kukjin Kim) Date: Tue, 20 Nov 2012 21:18:17 +0900 Subject: [PATCH] ARM: EXYNOS5: Add arm down clock support In-Reply-To: <1352463254-28423-1-git-send-email-a.kesavan@samsung.com> References: <1352463254-28423-1-git-send-email-a.kesavan@samsung.com> Message-ID: <0c9f01cdc719$1f5b2830$5e117890$@org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org Abhilash Kesavan wrote: > > 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 > --- > arch/arm/mach-exynos/clock-exynos5.c | 2 + > arch/arm/mach-exynos/cpuidle.c | 36 ++++++++++++++++++++++++ > arch/arm/mach-exynos/include/mach/regs-clock.h | 19 ++++++++++++ > 3 files changed, 57 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach- > exynos/clock-exynos5.c > index a88e0d9..9bb6567 100644 > --- a/arch/arm/mach-exynos/clock-exynos5.c > +++ b/arch/arm/mach-exynos/clock-exynos5.c > @@ -80,6 +80,8 @@ static struct sleep_save exynos5_clock_save[] = { > SAVE_ITEM(EXYNOS5_VPLL_CON0), > SAVE_ITEM(EXYNOS5_VPLL_CON1), > SAVE_ITEM(EXYNOS5_VPLL_CON2), > + SAVE_ITEM(EXYNOS5_PWR_CTRL1), > + SAVE_ITEM(EXYNOS5_PWR_CTRL2), > }; > #endif > > 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 > #include > #include > +#include > #include > #include > > @@ -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)); > diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h > b/arch/arm/mach-exynos/include/mach/regs-clock.h > index 8c9b38c..d36ad76 100644 > --- a/arch/arm/mach-exynos/include/mach/regs-clock.h > +++ b/arch/arm/mach-exynos/include/mach/regs-clock.h > @@ -267,6 +267,9 @@ > #define EXYNOS5_CLKDIV_STATCPU0 EXYNOS_CLKREG(0x00600) > #define EXYNOS5_CLKDIV_STATCPU1 EXYNOS_CLKREG(0x00604) > > +#define EXYNOS5_PWR_CTRL1 EXYNOS_CLKREG(0x01020) > +#define EXYNOS5_PWR_CTRL2 EXYNOS_CLKREG(0x01024) > + > #define EXYNOS5_MPLL_CON0 EXYNOS_CLKREG(0x04100) > #define EXYNOS5_CLKSRC_CORE1 EXYNOS_CLKREG(0x04204) > > @@ -344,6 +347,22 @@ > > #define EXYNOS5_EPLLCON0_LOCKED_SHIFT (29) > > +#define PWR_CTRL1_CORE2_DOWN_RATIO (7 << 28) > +#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_CORE1_WFE (1 << 5) > +#define PWR_CTRL1_USE_CORE0_WFE (1 << 4) > +#define PWR_CTRL1_USE_CORE1_WFI (1 << 1) > +#define PWR_CTRL1_USE_CORE0_WFI (1 << 0) > + > +#define PWR_CTRL2_DIV2_UP_EN (1 << 25) > +#define PWR_CTRL2_DIV1_UP_EN (1 << 24) > +#define PWR_CTRL2_DUR_STANDBY2_VAL (1 << 16) > +#define PWR_CTRL2_DUR_STANDBY1_VAL (1 << 8) > +#define PWR_CTRL2_CORE2_UP_RATIO (1 << 4) > +#define PWR_CTRL2_CORE1_UP_RATIO (1 << 0) > + > /* Compatibility defines and inclusion */ > > #include > -- > 1.6.6.1 Applied, thanks. K-Gene