
On 07.08.2018 08:46, Anson Huang wrote:
Add i.MX7D GPC initialization for low power mode support like system suspend/resume from linux kernel:
- Pending IOMUXC IRQ to workaround GPC state machine issue;
- Mask all GPC interrupts for M4/C0/C1;
- Configure SCU timing;
- Configure time slot ack;
- Configure C0/C1 power up/down timing;
- Configure wakeup source mechanism;
- Disable DSM/RBC related settings.
Signed-off-by: Anson Huang Anson.Huang@nxp.com
arch/arm/mach-imx/mx7/soc.c | 101 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+)
diff --git a/arch/arm/mach-imx/mx7/soc.c b/arch/arm/mach-imx/mx7/soc.c index 7334ca9..a829da2 100644 --- a/arch/arm/mach-imx/mx7/soc.c +++ b/arch/arm/mach-imx/mx7/soc.c @@ -18,6 +18,37 @@ #include <fsl_sec.h> #include <asm/setup.h>
+#define IOMUXC_GPR1 0x4 +#define BM_IOMUXC_GPR1_IRQ 0x1000
+#define GPC_LPCR_A7_BSC 0x0 +#define GPC_LPCR_M4 0x8 +#define GPC_SLPCR 0x14 +#define GPC_PGC_ACK_SEL_A7 0x24 +#define GPC_IMR1_CORE0 0x30 +#define GPC_IMR1_CORE1 0x40 +#define GPC_IMR1_M4 0x50 +#define GPC_PGC_CPU_MAPPING 0xec +#define GPC_PGC_C0_PUPSCR 0x804 +#define GPC_PGC_SCU_TIMING 0x890 +#define GPC_PGC_C1_PUPSCR 0x844
+#define BM_LPCR_A7_BSC_IRQ_SRC_A7_WAKEUP 0x70000000 +#define BM_LPCR_A7_BSC_CPU_CLK_ON_LPM 0x4000 +#define BM_LPCR_M4_MASK_DSM_TRIGGER 0x80000000 +#define BM_SLPCR_EN_DSM 0x80000000 +#define BM_SLPCR_RBC_EN 0x40000000 +#define BM_SLPCR_REG_BYPASS_COUNT 0x3f000000 +#define BM_SLPCR_VSTBY 0x4 +#define BM_SLPCR_SBYOS 0x2 +#define BM_SLPCR_BYPASS_PMIC_READY 0x1 +#define BM_SLPCR_EN_A7_FASTWUP_WAIT_MODE 0x10000
+#define BM_GPC_PGC_ACK_SEL_A7_DUMMY_PUP_ACK 0x80000000 +#define BM_GPC_PGC_ACK_SEL_A7_DUMMY_PDN_ACK 0x8000
+#define BM_GPC_PGC_CORE_PUPSCR 0x7fff80
#if defined(CONFIG_IMX_THERMAL) static const struct imx_thermal_plat imx7_thermal_plat = { .regs = (void *)ANATOP_BASE_ADDR, @@ -159,6 +190,74 @@ static void imx_enet_mdio_fixup(void) } }
+static void imx_gpcv2_init(void) +{
- u32 val, i;
- /*
* Force IOMUXC irq pending, so that the interrupt to GPC can be
* used to deassert dsm_request signal when the signal gets
* asserted unexpectedly.
*/
Does this issue has an errata associated to it? If yes, could we add then number?
- val = readl(IOMUXC_GPR_BASE_ADDR + IOMUXC_GPR1);
- val |= BM_IOMUXC_GPR1_IRQ;
- writel(val, IOMUXC_GPR_BASE_ADDR + IOMUXC_GPR1);
- /* Initially mask all interrupts */
- for (i = 0; i < 4; i++) {
writel(~0, GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0 + i * 4);
writel(~0, GPC_IPS_BASE_ADDR + GPC_IMR1_CORE1 + i * 4);
writel(~0, GPC_IPS_BASE_ADDR + GPC_IMR1_M4 + i * 4);
- }
- /* set SCU timing */
- writel((0x59 << 10) | 0x5B | (0x2 << 20),
GPC_IPS_BASE_ADDR + GPC_PGC_SCU_TIMING);
- /* only external IRQs to wake up LPM and core 0/1 */
- val = readl(GPC_IPS_BASE_ADDR + GPC_LPCR_A7_BSC);
- val |= BM_LPCR_A7_BSC_IRQ_SRC_A7_WAKEUP;
- writel(val, GPC_IPS_BASE_ADDR + GPC_LPCR_A7_BSC);
- /* set C0 power up timming per design requirement */
- val = readl(GPC_IPS_BASE_ADDR + GPC_PGC_C0_PUPSCR);
- val &= ~BM_GPC_PGC_CORE_PUPSCR;
- val |= (0x1A << 7);
- writel(val, GPC_IPS_BASE_ADDR + GPC_PGC_C0_PUPSCR);
- /* set C1 power up timming per design requirement */
- val = readl(GPC_IPS_BASE_ADDR + GPC_PGC_C1_PUPSCR);
- val &= ~BM_GPC_PGC_CORE_PUPSCR;
- val |= (0x1A << 7);
- writel(val, GPC_IPS_BASE_ADDR + GPC_PGC_C1_PUPSCR);
- /* dummy ack for time slot by default */
- writel(BM_GPC_PGC_ACK_SEL_A7_DUMMY_PUP_ACK |
BM_GPC_PGC_ACK_SEL_A7_DUMMY_PDN_ACK,
GPC_IPS_BASE_ADDR + GPC_PGC_ACK_SEL_A7);
- /* mask M4 DSM trigger */
- writel(readl(GPC_IPS_BASE_ADDR + GPC_LPCR_M4) |
BM_LPCR_M4_MASK_DSM_TRIGGER,
GPC_IPS_BASE_ADDR + GPC_LPCR_M4);
- /* set mega/fast mix in A7 domain */
- writel(0x1, GPC_IPS_BASE_ADDR + GPC_PGC_CPU_MAPPING);
newline...
- /* DSM related settings */
- val = readl(GPC_IPS_BASE_ADDR + GPC_SLPCR);
- val &= ~(BM_SLPCR_EN_DSM | BM_SLPCR_VSTBY | BM_SLPCR_RBC_EN |
BM_SLPCR_SBYOS | BM_SLPCR_BYPASS_PMIC_READY |
BM_SLPCR_REG_BYPASS_COUNT);
I guess BM_SLPCR_RBC_EN is to work around e10133? Maybe we can note that.
- val |= BM_SLPCR_EN_A7_FASTWUP_WAIT_MODE;
- writel(val, GPC_IPS_BASE_ADDR + GPC_SLPCR);
newline...
- /*
* disabling RBC need to delay at least 2 cycles of CKIL(32K)
* due to hardware design requirement, which is
* ~61us, here we use 65us for safe
*/
- udelay(65);
+}
int arch_cpu_init(void) { init_aips(); @@ -180,6 +279,8 @@ int arch_cpu_init(void)
init_snvs();
- imx_gpcv2_init();
- return 0;
}