summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnson Huang <b20788@freescale.com>2015-04-20 14:24:28 +0800
committerguoyin.chen <guoyin.chen@freescale.com>2015-05-08 17:26:44 +0800
commitec844786c252379e343c8af04959fa0cb71d7102 (patch)
tree0c60401f9fa6de0528a53cf683886aaf4d69de74
parent8c285bf9aaf4ed763138bd410312ab3402e296d3 (diff)
MLK-10715 ARM: imx: setting gpcv2 wake up mode to only using external irq
Using new wake up mode in gpcv2 bring in system issue, USB and AUDIO meet stress test issue, design team is still checking the root cause, let's use previous work around of GPC wake up to make sure system is stable currently. Signed-off-by: Anson Huang <b20788@freescale.com>
-rw-r--r--arch/arm/mach-imx/gpcv2.c30
-rw-r--r--arch/arm/mach-imx/pm-imx7.c11
2 files changed, 32 insertions, 9 deletions
diff --git a/arch/arm/mach-imx/gpcv2.c b/arch/arm/mach-imx/gpcv2.c
index 7c4691eed110..e11c03b4d294 100644
--- a/arch/arm/mach-imx/gpcv2.c
+++ b/arch/arm/mach-imx/gpcv2.c
@@ -157,6 +157,7 @@ void imx_gpcv2_set_lpm_mode(u32 cpu, enum mxc_cpu_pwr_mode mode)
{
unsigned long flags;
u32 val1, val2;
+ struct irq_desc *iomuxc_irq_desc;
spin_lock_irqsave(&gpcv2_lock, flags);
@@ -164,8 +165,7 @@ void imx_gpcv2_set_lpm_mode(u32 cpu, enum mxc_cpu_pwr_mode mode)
val2 = readl_relaxed(gpc_base + GPC_SLPCR);
/* core 0/1's LPM settings must be same */
- val1 &= ~(BM_LPCR_A7_BSC_LPM0 | BM_LPCR_A7_BSC_LPM1 |
- BM_LPCR_A7_BSC_IRQ_SRC_A7_WAKEUP);
+ val1 &= ~(BM_LPCR_A7_BSC_LPM0 | BM_LPCR_A7_BSC_LPM1);
val1 |= BM_LPCR_A7_BSC_CPU_CLK_ON_LPM;
@@ -174,17 +174,14 @@ void imx_gpcv2_set_lpm_mode(u32 cpu, enum mxc_cpu_pwr_mode mode)
switch (mode) {
case WAIT_CLOCKED:
- val1 |= 0x3 << BP_LPCR_A7_BSC_IRQ_SRC;
break;
case WAIT_UNCLOCKED:
val1 |= A7_LPM_WAIT << BP_LPCR_A7_BSC_LPM0;
val1 &= ~BM_LPCR_A7_BSC_CPU_CLK_ON_LPM;
- val1 |= 0x2 << BP_LPCR_A7_BSC_IRQ_SRC;
break;
case STOP_POWER_OFF:
val1 |= A7_LPM_STOP << BP_LPCR_A7_BSC_LPM0;
val1 &= ~BM_LPCR_A7_BSC_CPU_CLK_ON_LPM;
- val1 |= 0x2 << BP_LPCR_A7_BSC_IRQ_SRC;
val2 |= BM_SLPCR_EN_DSM;
val2 |= BM_SLPCR_RBC_EN;
val2 |= BM_SLPCR_SBYOS;
@@ -194,9 +191,23 @@ void imx_gpcv2_set_lpm_mode(u32 cpu, enum mxc_cpu_pwr_mode mode)
default:
return;
}
-
+ /*
+ * GPC: When improper low-power sequence is used,
+ * the SoC enters low power mode before the ARM core executes WFI.
+ *
+ * Software workaround:
+ * 1) Software should trigger IRQ #32 (IOMUX) to be always pending
+ * by setting IOMUX_GPR1_IRQ.
+ * 2) Software should then unmask IRQ #32 in GPC before setting GPC
+ * Low-Power mode.
+ * 3) Software should mask IRQ #32 right after GPC Low-Power mode
+ * is set.
+ */
+ iomuxc_irq_desc = irq_to_desc(32);
+ imx_gpcv2_irq_unmask(&iomuxc_irq_desc->irq_data);
writel_relaxed(val1, gpc_base + GPC_LPCR_A7_BSC);
writel_relaxed(val2, gpc_base + GPC_SLPCR);
+ imx_gpcv2_irq_mask(&iomuxc_irq_desc->irq_data);
spin_unlock_irqrestore(&gpcv2_lock, flags);
}
@@ -484,7 +495,7 @@ static int imx_pcie_regulator_notify(struct notifier_block *nb,
void __init imx_gpcv2_init(void)
{
struct device_node *np;
- int i;
+ int i, val;
np = of_find_compatible_node(NULL, NULL, "fsl,imx7d-gpc");
gpc_base = of_iomap(np, 0);
@@ -512,8 +523,9 @@ void __init imx_gpcv2_init(void)
}
/* only external IRQs to wake up LPM and core 0/1 */
- writel_relaxed(0x3 << BP_LPCR_A7_BSC_IRQ_SRC,
- gpc_base + GPC_LPCR_A7_BSC);
+ val = readl_relaxed(gpc_base + GPC_LPCR_A7_BSC);
+ val |= BM_LPCR_A7_BSC_IRQ_SRC_A7_WAKEUP;
+ writel_relaxed(val, gpc_base + GPC_LPCR_A7_BSC);
/* mask m4 dsm trigger */
writel_relaxed(readl_relaxed(gpc_base + GPC_LPCR_M4) |
BM_LPCR_M4_MASK_DSM_TRIGGER, gpc_base + GPC_LPCR_M4);
diff --git a/arch/arm/mach-imx/pm-imx7.c b/arch/arm/mach-imx/pm-imx7.c
index f5d0fd575cc0..dc468f8c560f 100644
--- a/arch/arm/mach-imx/pm-imx7.c
+++ b/arch/arm/mach-imx/pm-imx7.c
@@ -577,6 +577,7 @@ static void __init imx7_pm_common_init(const struct imx7_pm_socdata
*socdata)
{
int ret;
+ struct regmap *gpr;
if (IS_ENABLED(CONFIG_SUSPEND)) {
ret = imx7_suspend_init(socdata);
@@ -584,6 +585,16 @@ static void __init imx7_pm_common_init(const struct imx7_pm_socdata
pr_warn("%s: No DDR LPM support with suspend %d!\n",
__func__, ret);
}
+
+ /*
+ * Force IOMUXC irq pending, so that the interrupt to GPC can be
+ * used to deassert dsm_request signal when the signal gets
+ * asserted unexpectedly.
+ */
+ gpr = syscon_regmap_lookup_by_compatible("fsl,imx7d-iomuxc-gpr");
+ if (!IS_ERR(gpr))
+ regmap_update_bits(gpr, IOMUXC_GPR1, IMX7D_GPR1_IRQ_MASK,
+ IMX7D_GPR1_IRQ_MASK);
}
void __init imx7d_pm_init(void)