[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