diff options
author | Anson Huang <b20788@freescale.com> | 2014-12-16 23:24:12 -0500 |
---|---|---|
committer | Shawn Guo <shawn.guo@linaro.org> | 2015-01-05 08:34:29 -0500 |
commit | 05136f0897b526b9cd090c93b95bbd1b67c18cc5 (patch) | |
tree | a550264eb74fa756155662b4fdd67ed7d147618f /arch/arm/mach-imx/gpc.c | |
parent | df096fde0889a7a624fcc9616ff5ebd7446d131e (diff) |
ARM: imx: support arm power off in cpuidle for i.mx6sx
This patch introduces an independent cpuidle driver for
i.MX6SX, and supports arm power off in idle, totally
3 levels of cpuidle are supported as below:
1. ARM WFI;
2. SOC in WAIT mode;
3. SOC in WAIT mode + ARM power off.
ARM power off can save at least 5mW power.
This patch also replaces imx6q_enable_rbc with imx6_enable_rbc.
Signed-off-by: Anson Huang <b20788@freescale.com>
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Diffstat (limited to 'arch/arm/mach-imx/gpc.c')
-rw-r--r-- | arch/arm/mach-imx/gpc.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index 5f3602ec74fa..745caa18ab2c 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c | |||
@@ -20,6 +20,10 @@ | |||
20 | 20 | ||
21 | #define GPC_IMR1 0x008 | 21 | #define GPC_IMR1 0x008 |
22 | #define GPC_PGC_CPU_PDN 0x2a0 | 22 | #define GPC_PGC_CPU_PDN 0x2a0 |
23 | #define GPC_PGC_CPU_PUPSCR 0x2a4 | ||
24 | #define GPC_PGC_CPU_PDNSCR 0x2a8 | ||
25 | #define GPC_PGC_SW2ISO_SHIFT 0x8 | ||
26 | #define GPC_PGC_SW_SHIFT 0x0 | ||
23 | 27 | ||
24 | #define IMR_NUM 4 | 28 | #define IMR_NUM 4 |
25 | 29 | ||
@@ -27,6 +31,23 @@ static void __iomem *gpc_base; | |||
27 | static u32 gpc_wake_irqs[IMR_NUM]; | 31 | static u32 gpc_wake_irqs[IMR_NUM]; |
28 | static u32 gpc_saved_imrs[IMR_NUM]; | 32 | static u32 gpc_saved_imrs[IMR_NUM]; |
29 | 33 | ||
34 | void imx_gpc_set_arm_power_up_timing(u32 sw2iso, u32 sw) | ||
35 | { | ||
36 | writel_relaxed((sw2iso << GPC_PGC_SW2ISO_SHIFT) | | ||
37 | (sw << GPC_PGC_SW_SHIFT), gpc_base + GPC_PGC_CPU_PUPSCR); | ||
38 | } | ||
39 | |||
40 | void imx_gpc_set_arm_power_down_timing(u32 sw2iso, u32 sw) | ||
41 | { | ||
42 | writel_relaxed((sw2iso << GPC_PGC_SW2ISO_SHIFT) | | ||
43 | (sw << GPC_PGC_SW_SHIFT), gpc_base + GPC_PGC_CPU_PDNSCR); | ||
44 | } | ||
45 | |||
46 | void imx_gpc_set_arm_power_in_lpm(bool power_off) | ||
47 | { | ||
48 | writel_relaxed(power_off, gpc_base + GPC_PGC_CPU_PDN); | ||
49 | } | ||
50 | |||
30 | void imx_gpc_pre_suspend(bool arm_power_off) | 51 | void imx_gpc_pre_suspend(bool arm_power_off) |
31 | { | 52 | { |
32 | void __iomem *reg_imr1 = gpc_base + GPC_IMR1; | 53 | void __iomem *reg_imr1 = gpc_base + GPC_IMR1; |
@@ -34,7 +55,7 @@ void imx_gpc_pre_suspend(bool arm_power_off) | |||
34 | 55 | ||
35 | /* Tell GPC to power off ARM core when suspend */ | 56 | /* Tell GPC to power off ARM core when suspend */ |
36 | if (arm_power_off) | 57 | if (arm_power_off) |
37 | writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN); | 58 | imx_gpc_set_arm_power_in_lpm(arm_power_off); |
38 | 59 | ||
39 | for (i = 0; i < IMR_NUM; i++) { | 60 | for (i = 0; i < IMR_NUM; i++) { |
40 | gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4); | 61 | gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4); |
@@ -48,7 +69,7 @@ void imx_gpc_post_resume(void) | |||
48 | int i; | 69 | int i; |
49 | 70 | ||
50 | /* Keep ARM core powered on for other low-power modes */ | 71 | /* Keep ARM core powered on for other low-power modes */ |
51 | writel_relaxed(0x0, gpc_base + GPC_PGC_CPU_PDN); | 72 | imx_gpc_set_arm_power_in_lpm(false); |
52 | 73 | ||
53 | for (i = 0; i < IMR_NUM; i++) | 74 | for (i = 0; i < IMR_NUM; i++) |
54 | writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4); | 75 | writel_relaxed(gpc_saved_imrs[i], reg_imr1 + i * 4); |