mirror of
https://github.com/fail0verflow/switch-linux.git
synced 2025-05-04 02:34:21 -04:00
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
3 changed files with 32 additions and 5 deletions
|
@ -106,7 +106,7 @@ static inline void imx_scu_standby_enable(void) {}
|
||||||
#endif
|
#endif
|
||||||
void imx_src_init(void);
|
void imx_src_init(void);
|
||||||
void imx_gpc_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_post_resume(void);
|
||||||
void imx_gpc_mask_all(void);
|
void imx_gpc_mask_all(void);
|
||||||
void imx_gpc_restore_all(void);
|
void imx_gpc_restore_all(void);
|
||||||
|
|
|
@ -27,12 +27,13 @@ static void __iomem *gpc_base;
|
||||||
static u32 gpc_wake_irqs[IMR_NUM];
|
static u32 gpc_wake_irqs[IMR_NUM];
|
||||||
static u32 gpc_saved_imrs[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;
|
void __iomem *reg_imr1 = gpc_base + GPC_IMR1;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Tell GPC to power off ARM core when suspend */
|
/* Tell GPC to power off ARM core when suspend */
|
||||||
|
if (arm_power_off)
|
||||||
writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN);
|
writel_relaxed(0x1, gpc_base + GPC_PGC_CPU_PDN);
|
||||||
|
|
||||||
for (i = 0; i < IMR_NUM; i++) {
|
for (i = 0; i < IMR_NUM; i++) {
|
||||||
|
|
|
@ -274,6 +274,14 @@ int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
|
||||||
break;
|
break;
|
||||||
case STOP_POWER_ON:
|
case STOP_POWER_ON:
|
||||||
val |= 0x2 << BP_CLPCR_LPM;
|
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;
|
break;
|
||||||
case WAIT_UNCLOCKED_POWER_OFF:
|
case WAIT_UNCLOCKED_POWER_OFF:
|
||||||
val |= 0x1 << BP_CLPCR_LPM;
|
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)
|
static int imx6q_pm_enter(suspend_state_t state)
|
||||||
{
|
{
|
||||||
switch (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:
|
case PM_SUSPEND_MEM:
|
||||||
imx6q_set_lpm(STOP_POWER_OFF);
|
imx6q_set_lpm(STOP_POWER_OFF);
|
||||||
imx6q_set_int_mem_clk_lpm(false);
|
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)
|
if (!imx6_suspend_in_ocram_fn)
|
||||||
imx6q_enable_rbc(true);
|
imx6q_enable_rbc(true);
|
||||||
imx_gpc_pre_suspend();
|
imx_gpc_pre_suspend(true);
|
||||||
imx_anatop_pre_suspend();
|
imx_anatop_pre_suspend();
|
||||||
imx_set_cpu_jump(0, v7_cpu_resume);
|
imx_set_cpu_jump(0, v7_cpu_resume);
|
||||||
/* Zzz ... */
|
/* Zzz ... */
|
||||||
|
@ -365,9 +386,14 @@ static int imx6q_pm_enter(suspend_state_t state)
|
||||||
return 0;
|
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 = {
|
static const struct platform_suspend_ops imx6q_pm_ops = {
|
||||||
.enter = imx6q_pm_enter,
|
.enter = imx6q_pm_enter,
|
||||||
.valid = suspend_valid_only_mem,
|
.valid = imx6q_pm_valid,
|
||||||
};
|
};
|
||||||
|
|
||||||
void __init imx6q_pm_set_ccm_base(void __iomem *base)
|
void __init imx6q_pm_set_ccm_base(void __iomem *base)
|
||||||
|
|
Loading…
Add table
Reference in a new issue