mirror of https://gitee.com/openkylin/linux.git
ARM: imx: add standby mode support for suspend
Add standby mode support for suspend, to enter standby mode: echo standby > /sys/power/state; Use UART or RTC alarm to wake up system, when system enters standby mode, SOC will enter STOP mode with ARM core kept power on and 24M XTAL on. Signed-off-by: Anson Huang <b20788@freescale.com> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
This commit is contained in:
parent
dfea953ae2
commit
80c0ecdce8
|
@ -106,7 +106,7 @@ static inline void imx_scu_standby_enable(void) {}
|
|||
#endif
|
||||
void imx_src_init(void);
|
||||
void imx_gpc_init(void);
|
||||
void imx_gpc_pre_suspend(void);
|
||||
void imx_gpc_pre_suspend(bool arm_power_off);
|
||||
void imx_gpc_post_resume(void);
|
||||
void imx_gpc_mask_all(void);
|
||||
void imx_gpc_restore_all(void);
|
||||
|
|
|
@ -27,13 +27,14 @@ static void __iomem *gpc_base;
|
|||
static u32 gpc_wake_irqs[IMR_NUM];
|
||||
static u32 gpc_saved_imrs[IMR_NUM];
|
||||
|
||||
void imx_gpc_pre_suspend(void)
|
||||
void imx_gpc_pre_suspend(bool arm_power_off)
|
||||
{
|
||||
void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
|
||||
int i;
|
||||
|
||||
/* Tell GPC to power off ARM core when suspend */
|
||||
writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN);
|
||||
if (arm_power_off)
|
||||
writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN);
|
||||
|
||||
for (i = 0; i < IMR_NUM; i++) {
|
||||
gpc_saved_imrs[i] = readl_relaxed(reg_imr1 + i * 4);
|
||||
|
|
|
@ -274,6 +274,14 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
|
|||
break;
|
||||
case STOP_POWER_ON:
|
||||
val |= 0x2 << BP_CLPCR_LPM;
|
||||
val &= ~BM_CLPCR_VSTBY;
|
||||
val &= ~BM_CLPCR_SBYOS;
|
||||
if (cpu_is_imx6sl())
|
||||
val |= BM_CLPCR_BYPASS_PMIC_READY;
|
||||
if (cpu_is_imx6sl() || cpu_is_imx6sx())
|
||||
val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
|
||||
else
|
||||
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
|
||||
break;
|
||||
case WAIT_UNCLOCKED_POWER_OFF:
|
||||
val |= 0x1 << BP_CLPCR_LPM;
|
||||
|
@ -334,6 +342,19 @@ static int imx6q_suspend_finish(unsigned long val)
|
|||
static int imx6q_pm_enter(suspend_state_t state)
|
||||
{
|
||||
switch (state) {
|
||||
case PM_SUSPEND_STANDBY:
|
||||
imx6q_set_lpm(STOP_POWER_ON);
|
||||
imx6q_set_int_mem_clk_lpm(true);
|
||||
imx_gpc_pre_suspend(false);
|
||||
if (cpu_is_imx6sl())
|
||||
imx6sl_set_wait_clk(true);
|
||||
/* Zzz ... */
|
||||
cpu_do_idle();
|
||||
if (cpu_is_imx6sl())
|
||||
imx6sl_set_wait_clk(false);
|
||||
imx_gpc_post_resume();
|
||||
imx6q_set_lpm(WAIT_CLOCKED);
|
||||
break;
|
||||
case PM_SUSPEND_MEM:
|
||||
imx6q_set_lpm(STOP_POWER_OFF);
|
||||
imx6q_set_int_mem_clk_lpm(false);
|
||||
|
@ -344,7 +365,7 @@ static int imx6q_pm_enter(suspend_state_t state)
|
|||
*/
|
||||
if (!imx6_suspend_in_ocram_fn)
|
||||
imx6q_enable_rbc(true);
|
||||
imx_gpc_pre_suspend();
|
||||
imx_gpc_pre_suspend(true);
|
||||
imx_anatop_pre_suspend();
|
||||
imx_set_cpu_jump(0, v7_cpu_resume);
|
||||
/* Zzz ... */
|
||||
|
@ -365,9 +386,14 @@ static int imx6q_pm_enter(suspend_state_t state)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int imx6q_pm_valid(suspend_state_t state)
|
||||
{
|
||||
return (state == PM_SUSPEND_STANDBY || state == PM_SUSPEND_MEM);
|
||||
}
|
||||
|
||||
static const struct platform_suspend_ops imx6q_pm_ops = {
|
||||
.enter = imx6q_pm_enter,
|
||||
.valid = suspend_valid_only_mem,
|
||||
.valid = imx6q_pm_valid,
|
||||
};
|
||||
|
||||
void __init imx6q_pm_set_ccm_base(void __iomem *base)
|
||||
|
|
Loading…
Reference in New Issue