linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ARM: EXYNOS5: Add arm down clock support
@ 2012-11-09 12:14 Abhilash Kesavan
  2012-11-20 12:18 ` Kukjin Kim
  0 siblings, 1 reply; 2+ messages in thread
From: Abhilash Kesavan @ 2012-11-09 12:14 UTC (permalink / raw)
  To: linux-arm-kernel

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>
---
 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 <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));
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 <mach/regs-pmu.h>
-- 
1.6.6.1

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [PATCH] ARM: EXYNOS5: Add arm down clock support
  2012-11-09 12:14 [PATCH] ARM: EXYNOS5: Add arm down clock support Abhilash Kesavan
@ 2012-11-20 12:18 ` Kukjin Kim
  0 siblings, 0 replies; 2+ messages in thread
From: Kukjin Kim @ 2012-11-20 12:18 UTC (permalink / raw)
  To: linux-arm-kernel

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 <a.kesavan@samsung.com>
> ---
>  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 <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));
> 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 <mach/regs-pmu.h>
> --
> 1.6.6.1

Applied, thanks.

K-Gene <kgene@kernel.org>

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2012-11-20 12:18 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-09 12:14 [PATCH] ARM: EXYNOS5: Add arm down clock support Abhilash Kesavan
2012-11-20 12:18 ` Kukjin Kim

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).