summaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx/gpcv2.c
diff options
context:
space:
mode:
authorAnson Huang <Anson.Huang@freescale.com>2015-12-15 17:59:11 +0800
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commit770ea7cdfd5106b66c9371c5c10a625d2f61459f (patch)
treed644f1aa320f7b0aa3f37761b1a703e7732c14b8 /arch/arm/mach-imx/gpcv2.c
parentcf4503d18b50123e9ac32ab2e21a279ed04606eb (diff)
MLK-12014 ARM: imx: enable necessary clock for RDC recovery from DSM
1. Per design requirement, EXSC for PCIe will need clock to recover RDC setting on resume when M/F mix is off, so we need to enable PCIe LPCG before entering DSM. 2. As M4 clock is disabled in low power mode, after exit from DSM, A7 needs to restore TCM for M4, but without M4 clock, this operation never success, so we enable A7 wakeup sources for M4 as well during DSM, after exit DSM, M4's original wakeup sources will be restored. Signed-off-by: Anson Huang <Anson.Huang@freescale.com> (cherry picked from commit 847db79957d25545c762670eb1bc003f34cb2592) Signed-off-by: Teo Hall <teo.hall@nxp.com>
Diffstat (limited to 'arch/arm/mach-imx/gpcv2.c')
-rw-r--r--arch/arm/mach-imx/gpcv2.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/arch/arm/mach-imx/gpcv2.c b/arch/arm/mach-imx/gpcv2.c
index aa3f5a9303c5..83c1a30cca2a 100644
--- a/arch/arm/mach-imx/gpcv2.c
+++ b/arch/arm/mach-imx/gpcv2.c
@@ -35,6 +35,7 @@
#define GPC_MISC 0x2c
#define GPC_IMR1_CORE0 0x30
#define GPC_IMR1_CORE1 0x40
+#define GPC_IMR1_M4 0x50
#define GPC_SLOT0_CFG 0xb0
#define GPC_PGC_CPU_MAPPING 0xec
#define GPC_CPU_PGC_SW_PUP_REQ 0xf0
@@ -109,6 +110,7 @@ enum imx_gpc_slot {
static void __iomem *gpc_base;
static u32 gpcv2_wake_irqs[IMR_NUM];
static u32 gpcv2_saved_imrs[IMR_NUM];
+static u32 gpcv2_saved_imrs_m4[IMR_NUM];
static u32 gpcv2_mf_irqs[IMR_NUM];
static u32 gpcv2_mf_request_on[IMR_NUM];
static DEFINE_SPINLOCK(gpcv2_lock);
@@ -510,6 +512,26 @@ void imx_gpcv2_pre_suspend(bool arm_power_off)
}
}
+void imx_gpcv2_enable_wakeup_for_m4(void)
+{
+ void __iomem *reg_imr2 = gpc_base + GPC_IMR1_M4;
+ u32 i;
+
+ for (i = 0; i < IMR_NUM; i++) {
+ gpcv2_saved_imrs_m4[i] = readl_relaxed(reg_imr2 + i * 4);
+ writel_relaxed(~gpcv2_wake_irqs[i], reg_imr2 + i * 4);
+ }
+}
+
+void imx_gpcv2_disable_wakeup_for_m4(void)
+{
+ void __iomem *reg_imr2 = gpc_base + GPC_IMR1_M4;
+ u32 i;
+
+ for (i = 0; i < IMR_NUM; i++)
+ writel_relaxed(gpcv2_saved_imrs_m4[i], reg_imr2 + i * 4);
+}
+
void imx_gpcv2_post_resume(void)
{
void __iomem *reg_imr1 = gpc_base + GPC_IMR1_CORE0;