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.hu...@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;
>  }
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to