summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-mx6/mx6q_suspend.S119
-rw-r--r--arch/arm/mach-mx6/pm.c19
2 files changed, 68 insertions, 70 deletions
diff --git a/arch/arm/mach-mx6/mx6q_suspend.S b/arch/arm/mach-mx6/mx6q_suspend.S
index afb6ff565c5a..b1700433d1b4 100644
--- a/arch/arm/mach-mx6/mx6q_suspend.S
+++ b/arch/arm/mach-mx6/mx6q_suspend.S
@@ -223,7 +223,17 @@ suspend mode entry
nop
nop
nop
-
+ /* Due to the L2 cache errata(TKT065875)
+ , need to wait at least 170ns, each IO read
+ takes about 76ns, but the actual wait time
+ to make system more stable is about 380ns */
+ ldr r0, =SRC_BASE_ADDR
+ add r0, r0, #PERIPBASE_VIRT
+ ldr r1, [r0]
+ ldr r1, [r0, #0x4]
+ ldr r1, [r0, #0x8]
+ ldr r1, [r0, #0xc]
+ ldr r1, [r0, #0x10]
/***********************************************************
never run to here
************************************************************/
@@ -310,28 +320,9 @@ ddr_iomux_save:
ldr r7, [r2, #L2X0_DATA_LATENCY_CTRL]
stmfd r0!, {r4-r7}
- ldr r4, [r2, #L2X0_EVENT_CNT_CTRL]
- ldr r5, [r2, #L2X0_EVENT_CNT1_CFG]
- ldr r6, [r2, #L2X0_EVENT_CNT0_CFG]
- ldr r7, [r2, #L2X0_EVENT_CNT1_VAL]
- stmfd r0!, {r4-r7}
-
- ldr r4, [r2, #L2X0_EVENT_CNT0_VAL]
- ldr r5, [r2, #L2X0_INTR_MASK]
- ldr r6, [r2, #L2X0_MASKED_INTR_STAT]
- ldr r7, [r2, #L2X0_RAW_INTR_STAT]
- stmfd r0!, {r4-r7}
-
- ldr r4, [r2, #L2X0_INTR_CLEAR]
- ldr r5, [r2, #L2X0_LOCKDOWN_WAY_D]
- ldr r6, [r2, #L2X0_LOCKDOWN_WAY_I]
- ldr r7, [r2, #L2X0_LINE_DATA]
- stmfd r0!, {r4-r7}
-
- ldr r4, [r2, #L2X0_LINE_TAG]
- ldr r5, [r2, #L2X0_PREFETCH_CTRL]
- ldr r6, [r2, #L2X0_POWER_CTRL]
- stmfd r0!, {r4-r6}
+ ldr r4, [r2, #L2X0_PREFETCH_CTRL]
+ ldr r5, [r2, #L2X0_POWER_CTRL]
+ stmfd r0!, {r4-r5}
#endif
/*
* Flush all data from the L1 data cache before disabling
@@ -377,6 +368,36 @@ ddr_iomux_save:
*/
dsb
dmb
+
+ /* Clean L2 cache to write the dirty data into DRAM to make
+ sure the data alignment between DRAM and L2 cache.
+ */
+#ifdef CONFIG_CACHE_L2X0
+ /* Clean L2 cache here */
+ ldr r1, =L2_BASE_ADDR
+ add r1, r1, #PERIPBASE_VIRT
+ /* Make way to 0xFFFF 16 ways */
+ mov r0, #0x10000
+ sub r0, r0, #0x1
+ /* 0x7BC is L2X0_CLEAN_WAY */
+ mov r4, #0x700
+ orr r4, #0xBC
+ str r0, [r1, r4]
+wait:
+ ldr r2, [r1, r4]
+ ands r2, r2, r0
+ bne wait
+l2x0_sync:
+ mov r2, #0x0
+ /* 0x730 is L2X0_CACHE_SYNC */
+ mov r4, #0x700
+ orr r4, #0x30
+ str r2, [r1, r4]
+sync:
+ ldr r2, [r1, r4]
+ ands r2, r2, #0x1
+ bne sync
+#endif
/****************************************************************
set ddr iomux to low power mode
****************************************************************/
@@ -439,8 +460,17 @@ when SOC exit stop mode, arm core restart from here, currently
are running with MMU off.
****************************************************************/
resume:
- mov r1, #0x0
ldr r0, =SRC_BASE_ADDR
+ /* Due to the L2 cache errata(TKT065875)
+ , need to wait at least 170ns, each IO read
+ takes about 76ns, but the actual wait time
+ to make system more stable is about 380ns */
+ ldr r1, [r0]
+ ldr r1, [r0, #0x4]
+ ldr r1, [r0, #0x8]
+ ldr r1, [r0, #0xc]
+ ldr r1, [r0, #0x10]
+ mov r1, #0x0
str r1, [r0, #SRC_GPR1_OFFSET] /* clear SRC_GPR1 */
ldr r0, [r0, #SRC_GPR2_OFFSET]
@@ -528,8 +558,8 @@ use_ttbr0:
ldr r1, =mmu_on_label
bx r1
mmu_on_label:
- /* Set up the per-CPU stacks */
mov r8, lr
+ /* Set up the per-CPU stacks */
bl cpu_init
#ifdef CONFIG_CACHE_L2X0
@@ -544,35 +574,19 @@ mmu_on_label:
str r6, [r2, #L2X0_TAG_LATENCY_CTRL]
str r7, [r2, #L2X0_DATA_LATENCY_CTRL]
- ldmea r0!, {r4-r7}
- str r4, [r2, #L2X0_EVENT_CNT_CTRL]
- str r5, [r2, #L2X0_EVENT_CNT1_CFG]
- str r6, [r2, #L2X0_EVENT_CNT0_CFG]
- str r7, [r2, #L2X0_EVENT_CNT1_VAL]
-
- ldmea r0!, {r4-r7}
- str r4, [r2, #L2X0_EVENT_CNT0_VAL]
- str r5, [r2, #L2X0_INTR_MASK]
- str r6, [r2, #L2X0_MASKED_INTR_STAT]
- str r7, [r2, #L2X0_RAW_INTR_STAT]
-
- ldmea r0!, {r4-r7}
- str r4, [r2, #L2X0_INTR_CLEAR]
- str r5, [r2, #L2X0_LOCKDOWN_WAY_D]
- str r6, [r2, #L2X0_LOCKDOWN_WAY_I]
- str r7, [r2, #L2X0_LINE_DATA]
-
- ldmea r0!, {r4-r6}
- str r4, [r2, #L2X0_LINE_TAG]
- str r5, [r2, #L2X0_PREFETCH_CTRL]
- str r6, [r2, #L2X0_POWER_CTRL]
+ ldmea r0!, {r4-r5}
+ str r4, [r2, #L2X0_PREFETCH_CTRL]
+ str r5, [r2, #L2X0_POWER_CTRL]
#endif
/*
* Restore the MMU table entry that was modified for
* enabling MMU.
*/
- mov r0, r9
- mov r10, r0
+ ldr r4, =PAGE_OFFSET
+ ldr r5, =MX6_PHYS_OFFSET
+ sub r4, r4, r5
+ add r4, r4, r10
+ str r9, [r4]
mov r0, #0
mcr p15, 0, r0, c7, c1, 6 @ flush TLB and issue barriers
@@ -626,18 +640,19 @@ restore control register to enable cache
dsb
isb
+#ifdef CONFIG_CACHE_L2X0
/* Enable L2 cache here */
- ldr r2, =L2_BASE_ADDR
- add r2, r2, #PERIPBASE_VIRT
+ ldr r2, =L2_BASE_ADDR
+ add r2, r2, #PERIPBASE_VIRT
mov r4, #0x1
str r4, [r2, #L2X0_CTRL]
+#endif
/***********************************************************
return back to mx6_suspend_enter for dormant
***********************************************************/
mov lr, r8
ldmfd sp!, {r0-r12}
mov pc, lr
-
/************************************************
return back to mx6_suspend_enter for suspend
*************************************************/
diff --git a/arch/arm/mach-mx6/pm.c b/arch/arm/mach-mx6/pm.c
index bbde0f97c8a6..2d36c4bffbb9 100644
--- a/arch/arm/mach-mx6/pm.c
+++ b/arch/arm/mach-mx6/pm.c
@@ -65,11 +65,10 @@ extern int set_cpu_freq(int wp);
#endif
extern void mx6q_suspend(suspend_state_t state);
extern void mx6_init_irq(void);
-extern int mxc_init_l2x0(void);
extern unsigned int gpc_wake_irq[4];
+
static struct device *pm_dev;
struct clk *gpc_dvfs_clk;
-
static void __iomem *scu_base;
static void __iomem *gpc_base;
static void __iomem *src_base;
@@ -85,10 +84,6 @@ static unsigned long iram_paddr, cpaddr;
static u32 ccm_clpcr, scu_ctrl;
static u32 gpc_imr[4], gpc_cpu_pup, gpc_cpu_pdn, gpc_cpu;
-#ifdef CONFIG_LOCAL_TIMERS
-static u32 local_timer[4];
-#endif
-
static void mx6_suspend_store(void)
{
/* save some settings before suspend */
@@ -101,12 +96,6 @@ static void mx6_suspend_store(void)
gpc_cpu_pup = __raw_readl(gpc_base + GPC_PGC_CPU_PUPSCR_OFFSET);
gpc_cpu_pdn = __raw_readl(gpc_base + GPC_PGC_CPU_PDNSCR_OFFSET);
gpc_cpu = __raw_readl(gpc_base + GPC_PGC_CPU_PDN_OFFSET);
-#ifdef CONFIG_LOCAL_TIMERS
- local_timer[0] = __raw_readl(local_twd_base + LOCAL_TWD_LOAD_OFFSET);
- local_timer[1] = __raw_readl(local_twd_base + LOCAL_TWD_COUNT_OFFSET);
- local_timer[2] = __raw_readl(local_twd_base + LOCAL_TWD_CONTROL_OFFSET);
- local_timer[3] = __raw_readl(local_twd_base + LOCAL_TWD_INT_OFFSET);
-#endif
}
static void mx6_suspend_restore(void)
@@ -121,12 +110,6 @@ static void mx6_suspend_restore(void)
__raw_writel(gpc_cpu_pup, gpc_base + GPC_PGC_CPU_PUPSCR_OFFSET);
__raw_writel(gpc_cpu_pdn, gpc_base + GPC_PGC_CPU_PDNSCR_OFFSET);
__raw_writel(gpc_cpu, gpc_base + GPC_PGC_CPU_PDN_OFFSET);
-#ifdef CONFIG_LOCAL_TIMERS
- __raw_writel(local_timer[0], local_twd_base + LOCAL_TWD_LOAD_OFFSET);
- __raw_writel(local_timer[1], local_twd_base + LOCAL_TWD_COUNT_OFFSET);
- __raw_writel(local_timer[2], local_twd_base + LOCAL_TWD_CONTROL_OFFSET);
- __raw_writel(local_timer[3], local_twd_base + LOCAL_TWD_INT_OFFSET);
-#endif
}
static int mx6_suspend_enter(suspend_state_t state)