summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/cpu/armv7/mx6/Kconfig7
-rw-r--r--arch/arm/cpu/armv7/mx6/soc.c144
-rw-r--r--arch/arm/imx-common/cpu.c3
-rw-r--r--arch/arm/include/asm/arch-mx6/sys_proto.h10
-rw-r--r--board/freescale/mx6qarm2/mx6qarm2.c8
-rw-r--r--board/freescale/mx6qsabreauto/mx6qsabreauto.c38
-rw-r--r--board/freescale/mx6sabresd/mx6sabresd.c191
-rw-r--r--board/freescale/mx6slevk/mx6slevk.c54
-rw-r--r--board/freescale/mx6sxsabreauto/mx6sxsabreauto.c27
-rw-r--r--board/freescale/mx6sxsabresd/mx6sxsabresd.c51
-rw-r--r--board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c37
-rw-r--r--include/configs/mx6_common.h4
-rw-r--r--include/configs/mx6ul_14x14_evk.h2
13 files changed, 574 insertions, 2 deletions
diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig
index d34a7cd..801a929 100644
--- a/arch/arm/cpu/armv7/mx6/Kconfig
+++ b/arch/arm/cpu/armv7/mx6/Kconfig
@@ -54,6 +54,13 @@ config MX6_DDRCAL
Say "Y" if your board uses dynamic (per-boot) DDR calibration.
If unsure, say N.
+config LDO_BYPASS_CHECK
+ bool "Enable the LDO bypass checking and setting"
+ help
+ This feature searches the gpc node in loaded DTB and checking the
+ "fsl,ldo-bypass" property. When the property is set, board relevant
+ PMIC settings are called to adjust for LDO bypass.
+
config CMD_BEE
bool "Enable commands for Bus Encryption Engine(BEE)"
depends on MX6UL
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
index 61b7498..6d46713 100644
--- a/arch/arm/cpu/armv7/mx6/soc.c
+++ b/arch/arm/cpu/armv7/mx6/soc.c
@@ -675,7 +675,7 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
value = readl(&fuse->mac_addr1);
mac[4] = value >> 24 ;
mac[5] = value >> 16 ;
-
+
} else {
u32 value = readl(&fuse->mac_addr1);
mac[0] = (value >> 8);
@@ -687,7 +687,6 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
mac[4] = value >> 8 ;
mac[5] = value ;
}
-
}
#endif
@@ -714,6 +713,28 @@ const struct boot_mode soc_boot_modes[] = {
{NULL, 0},
};
+void set_wdog_reset(struct wdog_regs *wdog)
+{
+ u32 reg = readw(&wdog->wcr);
+ /*
+ * use WDOG_B mode to reset external pmic because it's risky for the
+ * following watchdog reboot in case of cpu freq at lowest 400Mhz with
+ * ldo-bypass mode. Because boot frequency maybe higher 800Mhz i.e. So
+ * in ldo-bypass mode watchdog reset will only triger POR reset, not
+ * WDOG reset. But below code depends on hardware design, if HW didn't
+ * connect WDOG_B pin to external pmic such as i.mx6slevk, we can skip
+ * these code since it assumed boot from 400Mhz always.
+ */
+ reg = readw(&wdog->wcr);
+ reg |= 1 << 3;
+ /*
+ * WDZST bit is write-once only bit. Align this bit in kernel,
+ * otherwise kernel code will have no chance to set this bit.
+ */
+ reg |= 1 << 0;
+ writew(reg, &wdog->wcr);
+}
+
void reset_misc(void)
{
#ifdef CONFIG_VIDEO_MXS
@@ -854,3 +875,122 @@ int arch_auxiliary_core_check_up(u32 core_id)
return 1;
}
#endif
+
+#ifdef CONFIG_LDO_BYPASS_CHECK
+DECLARE_GLOBAL_DATA_PTR;
+static int ldo_bypass;
+
+int check_ldo_bypass(void)
+{
+ const int *ldo_mode;
+ int node;
+
+ /* get the right fdt_blob from the global working_fdt */
+ gd->fdt_blob = working_fdt;
+ /* Get the node from FDT for anatop ldo-bypass */
+ node = fdt_node_offset_by_compatible(gd->fdt_blob, -1,
+ "fsl,imx6q-gpc");
+ if (node < 0) {
+ printf("No gpc device node %d, force to ldo-enable.\n", node);
+ return 0;
+ }
+ ldo_mode = fdt_getprop(gd->fdt_blob, node, "fsl,ldo-bypass", NULL);
+ /*
+ * return 1 if "fsl,ldo-bypass = <1>", else return 0 if
+ * "fsl,ldo-bypass = <0>" or no "fsl,ldo-bypass" property
+ */
+ ldo_bypass = fdt32_to_cpu(*ldo_mode) == 1 ? 1 : 0;
+
+ return ldo_bypass;
+}
+
+int check_1_2G(void)
+{
+ u32 reg;
+ int result = 0;
+ struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+ struct fuse_bank *bank = &ocotp->bank[0];
+ struct fuse_bank0_regs *fuse_bank0 =
+ (struct fuse_bank0_regs *)bank->fuse_regs;
+
+ reg = readl(&fuse_bank0->cfg3);
+ if (((reg >> 16) & 0x3) == 0x3) {
+ if (ldo_bypass) {
+ printf("Wrong dtb file used! i.MX6Q@1.2Ghz only "
+ "works with ldo-enable mode!\n");
+ /*
+ * Currently, only imx6q-sabresd board might be here,
+ * since only i.MX6Q support 1.2G and only Sabresd board
+ * support ldo-bypass mode. So hardcode here.
+ * You can also modify your board(i.MX6Q) dtb name if it
+ * supports both ldo-bypass and ldo-enable mode.
+ */
+ printf("Please use imx6q-sabresd-ldo.dtb!\n");
+ hang();
+ }
+ result = 1;
+ }
+
+ return result;
+}
+
+static int arm_orig_podf;
+void set_arm_freq_400M(bool is_400M)
+{
+ struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+
+ if (is_400M)
+ writel(0x1, &mxc_ccm->cacrr);
+ else
+ writel(arm_orig_podf, &mxc_ccm->cacrr);
+}
+
+void prep_anatop_bypass(void)
+{
+ struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+
+ arm_orig_podf = readl(&mxc_ccm->cacrr);
+ /*
+ * Downgrade ARM speed to 400Mhz as half of boot 800Mhz before ldo
+ * bypassed, also downgrade internal vddarm ldo to 0.975V.
+ * VDDARM_IN 0.975V + 125mV = 1.1V < Max(1.3V)
+ * otherwise at 800Mhz(i.mx6dl):
+ * VDDARM_IN 1.175V + 125mV = 1.3V = Max(1.3V)
+ * We need provide enough gap in this case.
+ * skip if boot from 400M.
+ */
+ if (!arm_orig_podf)
+ set_arm_freq_400M(true);
+
+ if (!is_mx6dl() && !is_mx6sx())
+ set_ldo_voltage(LDO_ARM, 975);
+ else
+ set_ldo_voltage(LDO_ARM, 1150);
+}
+
+int set_anatop_bypass(int wdog_reset_pin)
+{
+ struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
+ struct wdog_regs *wdog;
+ u32 reg = readl(&anatop->reg_core);
+
+ /* bypass VDDARM/VDDSOC */
+ reg = reg | (0x1F << 18) | 0x1F;
+ writel(reg, &anatop->reg_core);
+
+ if (wdog_reset_pin == 2)
+ wdog = (struct wdog_regs *) WDOG2_BASE_ADDR;
+ else if (wdog_reset_pin == 1)
+ wdog = (struct wdog_regs *) WDOG1_BASE_ADDR;
+ else
+ return arm_orig_podf;
+ set_wdog_reset(wdog);
+ return arm_orig_podf;
+}
+
+void finish_anatop_bypass(void)
+{
+ if (!arm_orig_podf)
+ set_arm_freq_400M(false);
+}
+#endif
diff --git a/arch/arm/imx-common/cpu.c b/arch/arm/imx-common/cpu.c
index b857e5e..d494e9b 100644
--- a/arch/arm/imx-common/cpu.c
+++ b/arch/arm/imx-common/cpu.c
@@ -297,6 +297,9 @@ void arch_preboot_os(void)
disable_sata_clock();
#endif
#endif
+#if defined(CONFIG_LDO_BYPASS_CHECK)
+ ldo_mode_set(check_ldo_bypass());
+#endif
#if defined(CONFIG_VIDEO_IPUV3)
/* disable video before launching O/S */
ipuv3_fb_shutdown();
diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h
index 8c3c956..79dc207 100644
--- a/arch/arm/include/asm/arch-mx6/sys_proto.h
+++ b/arch/arm/include/asm/arch-mx6/sys_proto.h
@@ -9,3 +9,13 @@
#include <asm/imx-common/sys_proto.h>
#include <asm/arch/module_fuse.h>
+
+void set_wdog_reset(struct wdog_regs *wdog);
+#ifdef CONFIG_LDO_BYPASS_CHECK
+int check_ldo_bypass(void);
+int check_1_2G(void);
+int set_anatop_bypass(int wdog_reset_pin);
+void ldo_mode_set(int ldo_bypass);
+void prep_anatop_bypass(void);
+void finish_anatop_bypass(void);
+#endif
diff --git a/board/freescale/mx6qarm2/mx6qarm2.c b/board/freescale/mx6qarm2/mx6qarm2.c
index db605c7..15471c2 100644
--- a/board/freescale/mx6qarm2/mx6qarm2.c
+++ b/board/freescale/mx6qarm2/mx6qarm2.c
@@ -306,3 +306,11 @@ int checkboard(void)
return 0;
}
+
+#ifdef CONFIG_LDO_BYPASS_CHECK
+/* no external pmic, always ldo_enable */
+void ldo_mode_set(int ldo_bypass)
+{
+ return;
+}
+#endif
diff --git a/board/freescale/mx6qsabreauto/mx6qsabreauto.c b/board/freescale/mx6qsabreauto/mx6qsabreauto.c
index e0ff4fc..de68caf 100644
--- a/board/freescale/mx6qsabreauto/mx6qsabreauto.c
+++ b/board/freescale/mx6qsabreauto/mx6qsabreauto.c
@@ -785,6 +785,44 @@ int power_init_board(void)
return 0;
}
+#ifdef CONFIG_LDO_BYPASS_CHECK
+void ldo_mode_set(int ldo_bypass)
+{
+ unsigned int value;
+ struct pmic *p = pmic_get("PFUZE100");
+
+ if (!p) {
+ printf("No PMIC found!\n");
+ return;
+ }
+
+ /* increase VDDARM/VDDSOC to support 1.2G chip */
+ if (check_1_2G()) {
+ ldo_bypass = 0; /* ldo_enable on 1.2G chip */
+ printf("1.2G chip, increase VDDARM_IN/VDDSOC_IN\n");
+
+ if (is_mx6dqp()) {
+ /* increase VDDARM to 1.425V */
+ pmic_reg_read(p, PFUZE100_SW2VOL, &value);
+ value &= ~0x3f;
+ value |= 0x29;
+ pmic_reg_write(p, PFUZE100_SW2VOL, value);
+ } else {
+ /* increase VDDARM to 1.425V */
+ pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
+ value &= ~0x3f;
+ value |= 0x2d;
+ pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
+ }
+ /* increase VDDSOC to 1.425V */
+ pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
+ value &= ~0x3f;
+ value |= 0x2d;
+ pmic_reg_write(p, PFUZE100_SW1CVOL, value);
+ }
+}
+#endif
+
#ifdef CONFIG_CMD_BMODE
static const struct boot_mode board_boot_modes[] = {
/* 4 bit bus width */
diff --git a/board/freescale/mx6sabresd/mx6sabresd.c b/board/freescale/mx6sabresd/mx6sabresd.c
index d0db0c6..c09c9d2 100644
--- a/board/freescale/mx6sabresd/mx6sabresd.c
+++ b/board/freescale/mx6sabresd/mx6sabresd.c
@@ -1076,6 +1076,197 @@ int power_init_board(void)
}
#endif
+#ifdef CONFIG_LDO_BYPASS_CHECK
+#ifdef CONFIG_POWER
+void ldo_mode_set(int ldo_bypass)
+{
+ unsigned int value;
+ int is_400M;
+ unsigned char vddarm;
+ struct pmic *p = pmic_get("PFUZE100");
+
+ if (!p) {
+ printf("No PMIC found!\n");
+ return;
+ }
+
+ /* increase VDDARM/VDDSOC to support 1.2G chip */
+ if (check_1_2G()) {
+ ldo_bypass = 0; /* ldo_enable on 1.2G chip */
+ printf("1.2G chip, increase VDDARM_IN/VDDSOC_IN\n");
+ if (is_mx6dqp()) {
+ /* increase VDDARM to 1.425V */
+ pmic_reg_read(p, PFUZE100_SW2VOL, &value);
+ value &= ~0x3f;
+ value |= 0x29;
+ pmic_reg_write(p, PFUZE100_SW2VOL, value);
+ } else {
+ /* increase VDDARM to 1.425V */
+ pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
+ value &= ~0x3f;
+ value |= 0x2d;
+ pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
+ }
+ /* increase VDDSOC to 1.425V */
+ pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
+ value &= ~0x3f;
+ value |= 0x2d;
+ pmic_reg_write(p, PFUZE100_SW1CVOL, value);
+ }
+ /* switch to ldo_bypass mode , boot on 800Mhz */
+ if (ldo_bypass) {
+ prep_anatop_bypass();
+ if (is_mx6dqp()) {
+ /* decrease VDDARM for 400Mhz DQP:1.1V*/
+ pmic_reg_read(p, PFUZE100_SW2VOL, &value);
+ value &= ~0x3f;
+ value |= 0x1c;
+ pmic_reg_write(p, PFUZE100_SW2VOL, value);
+ } else {
+ /* decrease VDDARM for 400Mhz DQ:1.1V, DL:1.275V */
+ pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
+ value &= ~0x3f;
+ if (is_mx6dl())
+ value |= 0x27;
+ else
+ value |= 0x20;
+
+ pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
+ }
+ /* increase VDDSOC to 1.3V */
+ pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
+ value &= ~0x3f;
+ value |= 0x28;
+ pmic_reg_write(p, PFUZE100_SW1CVOL, value);
+
+ /*
+ * MX6Q/DQP:
+ * VDDARM:1.15V@800M; VDDSOC:1.175V@800M
+ * VDDARM:0.975V@400M; VDDSOC:1.175V@400M
+ * MX6DL:
+ * VDDARM:1.175V@800M; VDDSOC:1.175V@800M
+ * VDDARM:1.075V@400M; VDDSOC:1.175V@400M
+ */
+ is_400M = set_anatop_bypass(2);
+ if (is_mx6dqp()) {
+ pmic_reg_read(p, PFUZE100_SW2VOL, &value);
+ value &= ~0x3f;
+ if (is_400M)
+ value |= 0x17;
+ else
+ value |= 0x1e;
+ pmic_reg_write(p, PFUZE100_SW2VOL, value);
+ }
+
+ if (is_400M) {
+ if (is_mx6dl())
+ vddarm = 0x1f;
+ else
+ vddarm = 0x1b;
+ } else {
+ if (is_mx6dl())
+ vddarm = 0x23;
+ else
+ vddarm = 0x22;
+ }
+ pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
+ value &= ~0x3f;
+ value |= vddarm;
+ pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
+
+ /* decrease VDDSOC to 1.175V */
+ pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
+ value &= ~0x3f;
+ value |= 0x23;
+ pmic_reg_write(p, PFUZE100_SW1CVOL, value);
+
+ finish_anatop_bypass();
+ printf("switch to ldo_bypass mode!\n");
+ }
+}
+#elif defined(CONFIG_DM_PMIC_PFUZE100)
+void ldo_mode_set(int ldo_bypass)
+{
+ int is_400M;
+ unsigned char vddarm;
+ struct udevice *dev;
+ int ret;
+
+ ret = pmic_get("pfuze100", &dev);
+ if (ret == -ENODEV) {
+ printf("No PMIC found!\n");
+ return;
+ }
+
+ /* increase VDDARM/VDDSOC to support 1.2G chip */
+ if (check_1_2G()) {
+ ldo_bypass = 0; /* ldo_enable on 1.2G chip */
+ printf("1.2G chip, increase VDDARM_IN/VDDSOC_IN\n");
+ if (is_mx6dqp()) {
+ /* increase VDDARM to 1.425V */
+ pmic_clrsetbits(dev, PFUZE100_SW2VOL, 0x3f, 0x29);
+ } else {
+ /* increase VDDARM to 1.425V */
+ pmic_clrsetbits(dev, PFUZE100_SW1ABVOL, 0x3f, 0x2d);
+ }
+ /* increase VDDSOC to 1.425V */
+ pmic_clrsetbits(dev, PFUZE100_SW1CVOL, 0x3f, 0x2d);
+ }
+ /* switch to ldo_bypass mode , boot on 800Mhz */
+ if (ldo_bypass) {
+ prep_anatop_bypass();
+ if (is_mx6dqp()) {
+ /* decrease VDDARM for 400Mhz DQP:1.1V*/
+ pmic_clrsetbits(dev, PFUZE100_SW2VOL, 0x3f, 0x1c);
+ } else {
+ /* decrease VDDARM for 400Mhz DQ:1.1V, DL:1.275V */
+ if (is_mx6dl())
+ pmic_clrsetbits(dev, PFUZE100_SW1ABVOL, 0x3f, 0x27);
+ else
+ pmic_clrsetbits(dev, PFUZE100_SW1ABVOL, 0x3f, 0x20);
+ }
+ /* increase VDDSOC to 1.3V */
+ pmic_clrsetbits(dev, PFUZE100_SW1CVOL, 0x3f, 0x28);
+
+ /*
+ * MX6Q/DQP:
+ * VDDARM:1.15V@800M; VDDSOC:1.175V@800M
+ * VDDARM:0.975V@400M; VDDSOC:1.175V@400M
+ * MX6DL:
+ * VDDARM:1.175V@800M; VDDSOC:1.175V@800M
+ * VDDARM:1.075V@400M; VDDSOC:1.175V@400M
+ */
+ is_400M = set_anatop_bypass(2);
+ if (is_mx6dqp()) {
+ if (is_400M)
+ pmic_clrsetbits(dev, PFUZE100_SW2VOL, 0x3f, 0x17);
+ else
+ pmic_clrsetbits(dev, PFUZE100_SW2VOL, 0x3f, 0x1e);
+ }
+
+ if (is_400M) {
+ if (is_mx6dl())
+ vddarm = 0x1f;
+ else
+ vddarm = 0x1b;
+ } else {
+ if (is_mx6dl())
+ vddarm = 0x23;
+ else
+ vddarm = 0x22;
+ }
+ pmic_clrsetbits(dev, PFUZE100_SW1ABVOL, 0x3f, vddarm);
+
+ /* decrease VDDSOC to 1.175V */
+ pmic_clrsetbits(dev, PFUZE100_SW1CVOL, 0x3f, 0x23);
+
+ finish_anatop_bypass();
+ printf("switch to ldo_bypass mode!\n");
+ }
+}
+#endif
+#endif
+
#ifdef CONFIG_CMD_BMODE
static const struct boot_mode board_boot_modes[] = {
/* 4 bit bus width */
diff --git a/board/freescale/mx6slevk/mx6slevk.c b/board/freescale/mx6slevk/mx6slevk.c
index 1e2f67b..76fc24e 100644
--- a/board/freescale/mx6slevk/mx6slevk.c
+++ b/board/freescale/mx6slevk/mx6slevk.c
@@ -400,6 +400,60 @@ int power_init_board(void)
return 0;
}
+#ifdef CONFIG_LDO_BYPASS_CHECK
+void ldo_mode_set(int ldo_bypass)
+{
+ u32 value;
+ int is_400M;
+ struct pmic *p = pmic_get("PFUZE100");
+
+ if (!p) {
+ printf("No pmic!\n");
+ return;
+ }
+
+ /* swith to ldo_bypass mode */
+ if (ldo_bypass) {
+ prep_anatop_bypass();
+
+ /* decrease VDDARM to 1.1V */
+ pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
+ value &= ~0x3f;
+ value |= 0x20;
+ pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
+
+ /* increase VDDSOC to 1.3V */
+ pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
+ value &= ~0x3f;
+ value |= 0x28;
+ pmic_reg_write(p, PFUZE100_SW1CVOL, value);
+
+ is_400M = set_anatop_bypass(0);
+
+ /*
+ * MX6SL: VDDARM:1.175V@800M; VDDSOC:1.175V@800M
+ * VDDARM:0.975V@400M; VDDSOC:1.175V@400M
+ */
+ pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
+ value &= ~0x3f;
+ if (is_400M)
+ value |= 0x1b;
+ else
+ value |= 0x23;
+ pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
+
+ /* decrease VDDSOC to 1.175V */
+ pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
+ value &= ~0x3f;
+ value |= 0x23;
+ pmic_reg_write(p, PFUZE100_SW1CVOL, value);
+
+ finish_anatop_bypass();
+ printf("switch to ldo_bypass mode!\n");
+ }
+}
+#endif
+
#endif
#ifdef CONFIG_FEC_MXC
diff --git a/board/freescale/mx6sxsabreauto/mx6sxsabreauto.c b/board/freescale/mx6sxsabreauto/mx6sxsabreauto.c
index 36c4c12..7fd74d9 100644
--- a/board/freescale/mx6sxsabreauto/mx6sxsabreauto.c
+++ b/board/freescale/mx6sxsabreauto/mx6sxsabreauto.c
@@ -181,6 +181,33 @@ int power_init_board(void)
return 0;
}
+#ifdef CONFIG_LDO_BYPASS_CHECK
+void ldo_mode_set(int ldo_bypass)
+{
+ struct udevice *dev;
+ int ret;
+
+ ret = pmic_get("pfuze100", &dev);
+ if (ret == -ENODEV) {
+ printf("No PMIC found!\n");
+ return;
+ }
+
+ /* switch to ldo_bypass mode */
+ if (ldo_bypass) {
+ /* decrease VDDARM to 1.15V */
+ pmic_clrsetbits(dev, PFUZE100_SW1ABVOL, 0x3f, SW1x_1_150V);
+
+ /* decrease VDDSOC to 1.15V */
+ pmic_clrsetbits(dev, PFUZE100_SW1CVOL, 0x3f, SW1x_1_150V);
+
+ set_anatop_bypass(1);
+
+ printf("switch to ldo_bypass mode!\n");
+ }
+}
+#endif
+
#ifdef CONFIG_USB_EHCI_MX6
#define USB_OTHERREGS_OFFSET 0x800
#define UCTRL_PWR_POL (1 << 9)
diff --git a/board/freescale/mx6sxsabresd/mx6sxsabresd.c b/board/freescale/mx6sxsabresd/mx6sxsabresd.c
index d242072..ebb837b 100644
--- a/board/freescale/mx6sxsabresd/mx6sxsabresd.c
+++ b/board/freescale/mx6sxsabresd/mx6sxsabresd.c
@@ -329,6 +329,57 @@ int power_init_board(void)
return 0;
}
+#ifdef CONFIG_LDO_BYPASS_CHECK
+void ldo_mode_set(int ldo_bypass)
+{
+ unsigned int value;
+ int is_400M;
+ u32 vddarm;
+ struct pmic *p = pmic_get("PFUZE100");
+
+ if (!p) {
+ printf("No PMIC found!\n");
+ return;
+ }
+
+ /* switch to ldo_bypass mode */
+ if (ldo_bypass) {
+ prep_anatop_bypass();
+ /* decrease VDDARM to 1.275V */
+ pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
+ value &= ~0x3f;
+ value |= PFUZE100_SW1ABC_SETP(12750);
+ pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
+
+ /* decrease VDDSOC to 1.3V */
+ pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
+ value &= ~0x3f;
+ value |= PFUZE100_SW1ABC_SETP(13000);
+ pmic_reg_write(p, PFUZE100_SW1CVOL, value);
+
+ is_400M = set_anatop_bypass(1);
+ if (is_400M)
+ vddarm = PFUZE100_SW1ABC_SETP(10750);
+ else
+ vddarm = PFUZE100_SW1ABC_SETP(11750);
+
+ pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
+ value &= ~0x3f;
+ value |= vddarm;
+ pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
+
+ pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
+ value &= ~0x3f;
+ value |= PFUZE100_SW1ABC_SETP(11750);
+ pmic_reg_write(p, PFUZE100_SW1CVOL, value);
+
+ finish_anatop_bypass();
+ printf("switch to ldo_bypass mode!\n");
+ }
+
+}
+#endif
+
#ifdef CONFIG_USB_EHCI_MX6
#define USB_OTHERREGS_OFFSET 0x800
#define UCTRL_PWR_POL (1 << 9)
diff --git a/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c b/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c
index 826d2c9..b34f818 100644
--- a/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c
+++ b/board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c
@@ -217,6 +217,43 @@ int power_init_board(void)
return 0;
}
+
+#ifdef CONFIG_LDO_BYPASS_CHECK
+void ldo_mode_set(int ldo_bypass)
+{
+ unsigned int value;
+ u32 vddarm;
+
+ struct pmic *p = pmic_get("PFUZE3000");
+
+ if (!p) {
+ printf("No PMIC found!\n");
+ return;
+ }
+
+ /* switch to ldo_bypass mode */
+ if (ldo_bypass) {
+ prep_anatop_bypass();
+ /* decrease VDDARM to 1.275V */
+ pmic_reg_read(p, PFUZE3000_SW1BVOLT, &value);
+ value &= ~0x1f;
+ value |= PFUZE3000_SW1AB_SETP(1275);
+ pmic_reg_write(p, PFUZE3000_SW1BVOLT, value);
+
+ set_anatop_bypass(1);
+ vddarm = PFUZE3000_SW1AB_SETP(1175);
+
+ pmic_reg_read(p, PFUZE3000_SW1BVOLT, &value);
+ value &= ~0x1f;
+ value |= vddarm;
+ pmic_reg_write(p, PFUZE3000_SW1BVOLT, value);
+
+ finish_anatop_bypass();
+
+ printf("switch to ldo_bypass mode!\n");
+ }
+}
+#endif
#endif
#endif
diff --git a/include/configs/mx6_common.h b/include/configs/mx6_common.h
index 138dd62..f62a7df 100644
--- a/include/configs/mx6_common.h
+++ b/include/configs/mx6_common.h
@@ -109,4 +109,8 @@ defined(CONFIG_MX6DL)) && !defined(CONFIG_MX6S)
#endif
#endif
+/* LDO Bypass */
+#ifndef CONFIG_MX6SLL
+#define CONFIG_LDO_BYPASS_CHECK
+#endif
#endif
diff --git a/include/configs/mx6ul_14x14_evk.h b/include/configs/mx6ul_14x14_evk.h
index f56783e..cb78e18 100644
--- a/include/configs/mx6ul_14x14_evk.h
+++ b/include/configs/mx6ul_14x14_evk.h
@@ -24,6 +24,8 @@
#else
#define PHYS_SDRAM_SIZE SZ_512M
#define BOOTARGS_CMA_SIZE ""
+/* DCDC used on 14x14 EVK, no PMIC */
+#undef CONFIG_LDO_BYPASS_CHECK
#endif
/* SPL options */