[U-Boot] [RESEND 2/3] imx: mx7: add gpc initialization for low power mode

Anson Huang anson.huang at nxp.com
Wed Aug 8 00:55:31 UTC 2018


Hi, Stefan

Anson Huang
Best Regards!


> -----Original Message-----
> From: Stefan Agner [mailto:stefan at agner.ch]
> Sent: Tuesday, August 7, 2018 6:56 PM
> To: Anson Huang <anson.huang at nxp.com>
> Cc: sbabic at denx.de; Fabio Estevam <fabio.estevam at nxp.com>;
> albert.u.boot at aribaud.net; bryan.odonoghue at linaro.org; Stefan Agner
> <stefan.agner at toradex.com>; Peng Fan <peng.fan at nxp.com>;
> patrick.delaunay at st.com; sjg at chromium.org; Ye Li <ye.li at nxp.com>;
> u-boot at lists.denx.de; dl-linux-imx <linux-imx at nxp.com>
> Subject: Re: [U-Boot] [RESEND 2/3] imx: mx7: add gpc initialization for low
> power mode
> 
> 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 at 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?
 
I checked latest i.MX7D errata doc, it does NOT include this as an errata, but
this "issue" is existing for all i.MX6 SoCs and i.MX7D, you can refer to the i.MX6Q
errata as below, since there is no errata number for i.MX7D, so I will NOT add the
number.

ERR007265 CCM: When improper low-power sequence is used, the SoC enters
low power mode before the ARM core executes WFI

Workarounds:
Software workaround:
1) Software should trigger IRQ #32 (IOMUX) to be always pending by setting
IOMUX_GPR1_GINT
2) Software should then unmask IRQ #32 in GPC before setting CCM Low-Power mode
3) Software should mask IRQ #32 right after CCM Low-Power mode is set (set bits 0-1 of
CCM_CLPCR)
Proposed Solution:
No fix scheduled

> 
> > +	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.
 
This is just initialization to disable all the low power mode related function, the
work around is implemented in suspend flow right before enter suspend, I will
add the errata number in the 3/3 patch which supports suspend.

> 
> > +	val |= BM_SLPCR_EN_A7_FASTWUP_WAIT_MODE;
> > +	writel(val, GPC_IPS_BASE_ADDR + GPC_SLPCR);
> 
> newline...
 
Will address all comments in V2 patch set. Thanks.

Anson.

> 
> > +	/*
> > +	 * 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;
> >  }


More information about the U-Boot mailing list