Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0f9e0359 authored by Abhilash Kesavan's avatar Abhilash Kesavan Committed by Kukjin Kim
Browse files

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: default avatarAbhilash Kesavan <a.kesavan@samsung.com>
Signed-off-by: default avatarKukjin Kim <kgene.kim@samsung.com>
parent 86ffb0e8
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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

+36 −0
Original line number Diff line number Diff line
@@ -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));
+19 −0
Original line number Diff line number Diff line
@@ -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>