mx7ulp: Introduce the CONFIG_LDO_ENABLED_MODE option
authorFabio Estevam <festevam@gmail.com>
Tue, 5 Nov 2019 12:47:51 +0000 (09:47 -0300)
committerStefano Babic <sbabic@denx.de>
Fri, 6 Dec 2019 11:05:08 +0000 (12:05 +0100)
Introduce the CONFIG_LDO_ENABLED_MODE option so that i.MX7ULP boards
designed to operate with LDO enabled mode can work with 0.95V at LDO
output in RUN mode as per the datasheet.

Signed-off-by: Fabio Estevam <festevam@gmail.com>
arch/arm/mach-imx/mx7ulp/Kconfig
arch/arm/mach-imx/mx7ulp/soc.c

index ed5f0aeb2d5ee7496651a063fe2bafadbdbc5862..138c58363f53f7fcaea6157222531e051a3cdd43 100644 (file)
@@ -3,6 +3,11 @@ if ARCH_MX7ULP
 config SYS_SOC
        default "mx7ulp"
 
+config LDO_ENABLED_MODE
+       bool "i.MX7ULP LDO Enabled Mode"
+       help
+         Select this option to enable the PMC1 LDO.
+
 config MX7ULP
        bool
 
index 4343cac99c745d1592b0b31c597202afca5eb494..fd40af73052c45eb053dbedd66ba7f78ba6b9e79 100644 (file)
 #include <asm/mach-imx/boot_mode.h>
 #include <asm/mach-imx/hab.h>
 
+#define PMC0_BASE_ADDR         0x410a1000
+#define PMC0_CTRL              0x28
+#define PMC0_CTRL_LDOEN                BIT(31)
+#define PMC0_CTRL_LDOOKDIS     BIT(30)
+#define PMC0_CTRL_PMC1ON       BIT(24)
+#define PMC1_BASE_ADDR         0x40400000
+#define PMC1_RUN               0x8
+#define PMC1_STOP              0x10
+#define PMC1_VLPS              0x14
+#define PMC1_RUN_LDOVL_SHIFT   16
+#define PMC1_RUN_LDOVL_MASK    (0x3f << PMC1_RUN_LDOVL_SHIFT)
+#define PMC1_RUN_LDOVL_900     0x1e
+#define PMC1_RUN_LDOVL_950     0x23
+#define PMC1_STATUS            0x20
+#define PMC1_STATUS_LDOVLF     BIT(8)
+
 static char *get_reset_cause(char *);
 
 #if defined(CONFIG_IMX_HAB)
@@ -101,6 +117,44 @@ void init_wdog(void)
        disable_wdog(WDG2_RBASE);
 }
 
+#if defined(CONFIG_LDO_ENABLED_MODE)
+static void init_ldo_mode(void)
+{
+       unsigned int reg;
+
+       /* Set LDOOKDIS */
+       setbits_le32(PMC0_BASE_ADDR + PMC0_CTRL, PMC0_CTRL_LDOOKDIS);
+
+       /* Set LDOVL to 0.95V in PMC1_RUN */
+       reg = readl(PMC1_BASE_ADDR + PMC1_RUN);
+       reg &= ~PMC1_RUN_LDOVL_MASK;
+       reg |= (PMC1_RUN_LDOVL_950 << PMC1_RUN_LDOVL_SHIFT);
+       writel(PMC1_BASE_ADDR + PMC1_RUN, reg);
+
+       /* Wait for LDOVLF to be cleared */
+       reg = readl(PMC1_BASE_ADDR + PMC1_STATUS);
+       while (reg & PMC1_STATUS_LDOVLF)
+               ;
+
+       /* Set LDOVL to 0.95V in PMC1_STOP */
+       reg = readl(PMC1_BASE_ADDR + PMC1_STOP);
+       reg &= ~PMC1_RUN_LDOVL_MASK;
+       reg |= (PMC1_RUN_LDOVL_950 << PMC1_RUN_LDOVL_SHIFT);
+       writel(PMC1_BASE_ADDR + PMC1_STOP, reg);
+
+       /* Set LDOVL to 0.90V in PMC1_VLPS */
+       reg = readl(PMC1_BASE_ADDR + PMC1_VLPS);
+       reg &= ~PMC1_RUN_LDOVL_MASK;
+       reg |= (PMC1_RUN_LDOVL_900 << PMC1_RUN_LDOVL_SHIFT);
+       writel(PMC1_BASE_ADDR + PMC1_VLPS, reg);
+
+       /* Set LDOEN bit */
+       setbits_le32(PMC0_BASE_ADDR + PMC0_CTRL, PMC0_CTRL_LDOEN);
+
+       /* Set the PMC1ON bit */
+       setbits_le32(PMC0_BASE_ADDR + PMC0_CTRL, PMC0_CTRL_PMC1ON);
+}
+#endif
 
 void s_init(void)
 {
@@ -114,6 +168,10 @@ void s_init(void)
                /* enable dumb pmic */
                writel((readl(SNVS_LP_LPCR) | SNVS_LPCR_DPEN), SNVS_LP_LPCR);
        }
+
+#if defined(CONFIG_LDO_ENABLED_MODE)
+       init_ldo_mode();
+#endif
        return;
 }