From ec78b412ad8fab85d14ec0d692d1bd6b79561a58 Mon Sep 17 00:00:00 2001 From: Chenhui Zhao Date: Tue, 14 Jul 2015 15:23:34 +0800 Subject: arm: ls1021a: mask interrupts before entering deep sleep Before entering deep sleep, interrupts should be masked. Or, unexpected interrupts may block the process of deep sleep. So, mask interrupts by the following steps: 1. Mask interrupts to RCPM 2. Disable the GIC This will make deep sleep more stable. Signed-off-by: Chenhui Zhao Change-Id: I601062f8406324a308ef44491fed7cf479eaeba9 Reviewed-on: http://git.am.freescale.net:8181/39602 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 8ad1b85..d1af079 100644 --- a/arch/arm/mach-imx/pm-ls1.c +++ b/arch/arm/mach-imx/pm-ls1.c @@ -67,6 +67,9 @@ #define CCSR_RCPM_IPPDEXPCR1_LPUART 0x40000000 #define CCSR_RCPM_IPPDEXPCR1_FLEXTIMER 0x20000000 #define CCSR_RCPM_IPPDEXPCR1_OCRAM1 0x10000000 +#define CCSR_RCPM_NFIQOUTR 0x15c +#define CCSR_RCPM_NIRQOUTR 0x16c +#define CCSR_RCPM_DSIMSKR 0x18c #define QIXIS_CTL_SYS 0x5 #define QIXIS_CTL_SYS_EVTSW_MASK 0x0c @@ -172,10 +175,16 @@ static void ls1_pm_uniomap(int deepsleep) iounmap(ls1_pm_base.sram); } -static void ls1_setup_pmc_int(void) +static void ls1_deepsleep_irq(void) { u32 pmcintecr; + /* mask interrupts from GIC */ + iowrite32be(0x0ffffffff, ls1_pm_base.rcpm + CCSR_RCPM_NFIQOUTR); + iowrite32be(0x0ffffffff, ls1_pm_base.rcpm + CCSR_RCPM_NIRQOUTR); + /* mask deep sleep wake-up interrupts during deep sleep entry */ + iowrite32be(0x0ffffffff, ls1_pm_base.rcpm + CCSR_RCPM_DSIMSKR); + pmcintecr = 0; if (ippdexpcr0 & CCSR_RCPM_IPPDEXPCR0_ETSEC) pmcintecr |= CCSR_SCFG_PMCINTECR_ETSECRXG0 | @@ -345,7 +354,7 @@ static void ls1_enter_deepsleep(void) /* copy the last stage code to sram */ ls1_copy_sram_code(); - ls1_setup_pmc_int(); + ls1_deepsleep_irq(); cpu_suspend(SRAM_CODE_BASE_PHY, ls1_start_deepsleep); diff --git a/arch/arm/mach-imx/sleep-ls1.S b/arch/arm/mach-imx/sleep-ls1.S index b8d7f1a..f8fd8a4 100644 --- a/arch/arm/mach-imx/sleep-ls1.S +++ b/arch/arm/mach-imx/sleep-ls1.S @@ -25,6 +25,10 @@ #define DCSR_EPU_EPECR0 0x300 #define DCSR_EPU_EPECR15 0x33c +#define CCSR_GIC_BASE 0x1400000 +#define CCSR_GICD_CTLR 0x1000 +#define CCSR_GICC_CTLR 0x2000 + /* for big endian registers */ .macro ls1_set_bits, addr, value ldr r4, \addr @@ -85,6 +89,13 @@ ENTRY(ls1_start_fsm) ls1_delay #2000 + mov r7, #0 + ldr r8, ls1_ccsr_gicd_ctlr + str r7, [r8] + ldr r9, ls1_ccsr_gicc_ctlr + str r7, [r9] + dsb + /* Enable all EPU Counters */ ls1_set_bits ls1_dcsr_epu_epgcr_addr, ls1_dcsr_epu_epgcr_val @@ -92,8 +103,10 @@ ENTRY(ls1_start_fsm) ls1_set_bits ls1_dcsr_epu_epecr15, ls1_dcsr_epu_epecr15_val /* Enter WFI mode, and EPU FSM will start */ -20: wfi - b 20b + isb + wfi + nop +20: b 20b ls1_ccsr_scfg_hrstcr_addr: .word CCSR_SCFG_BASE + CCSR_SCFG_HRSTCR @@ -120,6 +133,12 @@ ls1_dcsr_epu_epecr15: ls1_dcsr_epu_epecr15_val: .word 0x90000004 +ls1_ccsr_gicd_ctlr: + .word CCSR_GIC_BASE + CCSR_GICD_CTLR + +ls1_ccsr_gicc_ctlr: + .word CCSR_GIC_BASE + CCSR_GICC_CTLR + ENTRY(ls1_sram_code_size) .word . - ls1_start_fsm -- cgit v0.10.2