From 75493029a3da1926cbfb79c589fc3c2ba9ae1069 Mon Sep 17 00:00:00 2001 From: Chenhui Zhao Date: Thu, 4 Jun 2015 17:27:23 +0800 Subject: arm: ls1021a: enable sleep and deep sleep for rev 2.0 silicon On the rev 2.0 silicon of LS1021A, set the WFIL2EN bit in the SCFG_CLUSTERPMCR register to enable sleep and deep sleep. Signed-off-by: Chenhui Zhao Change-Id: I0ec6933dc1805749d7e4a815f9049301dfcfb63e Reviewed-on: http://git.am.freescale.net:8181/37396 Tested-by: Review Code-CDREVIEW Reviewed-by: Zhengxiong Jin diff --git a/arch/arm/mach-imx/pm-ls1.c b/arch/arm/mach-imx/pm-ls1.c index 50b0758..67260a5 100644 --- a/arch/arm/mach-imx/pm-ls1.c +++ b/arch/arm/mach-imx/pm-ls1.c @@ -48,6 +48,8 @@ #define CCSR_SCFG_PMCINTSR 0x168 #define CCSR_SCFG_SPARECR2 0x504 #define CCSR_SCFG_SPARECR3 0x508 +#define CCSR_SCFG_CLUSTERPMCR 0x904 +#define CCSR_SCFG_CLUSTERPMCR_WFIL2EN 0x80000000 #define CCSR_DCFG_CRSTSR 0x400 #define CCSR_DCFG_CRSTSR_VAL 0x00000008 @@ -101,11 +103,19 @@ static struct ls1_pm_baseaddr ls1_pm_base; static unsigned int sleep_modes; static suspend_state_t ls1_pm_state; -static int ls1_pm_iomap(void) +static int ls1_pm_iomap(int deepsleep) { struct device_node *np; void *base; + np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-scfg"); + base = of_iomap(np, 0); + BUG_ON(!base); + ls1_pm_base.scfg = base; + + if (!deepsleep) + return 0; + np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcsr-epu"); base = of_iomap(np, 0); BUG_ON(!base); @@ -119,11 +129,6 @@ static int ls1_pm_iomap(void) BUG_ON(!base); ls1_pm_base.dcsr_rcpm2 = base; - np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-scfg"); - base = of_iomap(np, 0); - BUG_ON(!base); - ls1_pm_base.scfg = base; - np = of_find_compatible_node(NULL, NULL, "fsl,ls1021a-dcfg"); base = of_iomap(np, 0); BUG_ON(!base); @@ -150,12 +155,15 @@ static int ls1_pm_iomap(void) return 0; } -static void ls1_pm_uniomap(void) +static void ls1_pm_uniomap(int deepsleep) { + iounmap(ls1_pm_base.scfg); + if (!deepsleep) + return; + iounmap(ls1_pm_base.epu); iounmap(ls1_pm_base.dcsr_rcpm1); iounmap(ls1_pm_base.dcsr_rcpm2); - iounmap(ls1_pm_base.scfg); iounmap(ls1_pm_base.dcfg); if (ls1_pm_base.fpga) @@ -387,11 +395,26 @@ static void ls1_set_wakeup_device(struct device *dev, void *enable) ls1_set_power_except(dev, *((int *)enable)); } +/* enable cluster to enter the PCL10 state */ +void ls1_set_clusterpm(int enable) +{ + u32 val; + + if (enable) + val = CCSR_SCFG_CLUSTERPMCR_WFIL2EN; + else + val = 0; + + BUG_ON(!ls1_pm_base.scfg); + iowrite32be(val, ls1_pm_base.scfg + CCSR_SCFG_CLUSTERPMCR); +} + static int ls1_suspend_enter(suspend_state_t state) { int ret = 0; ls1_set_powerdown(); + ls1_set_clusterpm(1); switch (state) { case PM_SUSPEND_STANDBY: @@ -411,6 +434,7 @@ static int ls1_suspend_enter(suspend_state_t state) ret = -EINVAL; } + ls1_set_clusterpm(0); return ret; } @@ -434,7 +458,9 @@ static int ls1_suspend_begin(suspend_state_t state) dpm_for_each_dev(NULL, ls1_set_wakeup_device); if (ls1_pm_state == PM_SUSPEND_MEM) - return ls1_pm_iomap(); + return ls1_pm_iomap(1); + else if (ls1_pm_state == PM_SUSPEND_STANDBY) + return ls1_pm_iomap(0); return 0; } @@ -442,7 +468,9 @@ static int ls1_suspend_begin(suspend_state_t state) static void ls1_suspend_end(void) { if (ls1_pm_state == PM_SUSPEND_MEM) - ls1_pm_uniomap(); + ls1_pm_uniomap(1); + else if (ls1_pm_state == PM_SUSPEND_STANDBY) + ls1_pm_uniomap(0); } static const struct platform_suspend_ops ls1_suspend_ops = { -- cgit v0.10.2