MLK-12495 mx6: Add LDO bypass support
authorYe Li <ye.li@nxp.com>
Mon, 7 Mar 2016 07:37:34 +0000 (15:37 +0800)
committerYe Li <ye.li@nxp.com>
Wed, 5 Apr 2017 06:04:41 +0000 (14:04 +0800)
Port LDO bypass support from v2015 to support the features:

1. Add check for 1.2GHz core speed. If Speed grading fuse is for 1.2GHz,
   enable LDO bypass and setup PMIC voltages. LDO bypass is dependent
   on the flatten device tree file.

2. We set WDOG_B in set_anatop_bypass() before, because it is the only case, but now
   on i.mx6sabreauto board, we didn't use ldo-bypass mode, but have to use WDOG_B to
   reboot whole board, so split these code to independent function so that board file
   can call it freely.

Signed-off-by: Ye Li <ye.li@nxp.com>
(cherry picked from commit 5b87d04dba66fa45375d59648838ef89f559f75d)

13 files changed:
arch/arm/cpu/armv7/mx6/Kconfig
arch/arm/cpu/armv7/mx6/soc.c
arch/arm/imx-common/cpu.c
arch/arm/include/asm/arch-mx6/sys_proto.h
board/freescale/mx6qarm2/mx6qarm2.c
board/freescale/mx6qsabreauto/mx6qsabreauto.c
board/freescale/mx6sabresd/mx6sabresd.c
board/freescale/mx6slevk/mx6slevk.c
board/freescale/mx6sxsabreauto/mx6sxsabreauto.c
board/freescale/mx6sxsabresd/mx6sxsabresd.c
board/freescale/mx6ul_14x14_evk/mx6ul_14x14_evk.c
include/configs/mx6_common.h
include/configs/mx6ul_14x14_evk.h

index d34a7cd..801a929 100644 (file)
@@ -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
index 61b7498..6d46713 100644 (file)
@@ -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
index b857e5e..d494e9b 100644 (file)
@@ -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();
index 8c3c956..79dc207 100644 (file)
@@ -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
index db605c7..15471c2 100644 (file)
@@ -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
index e0ff4fc..de68caf 100644 (file)
@@ -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 */
index d0db0c6..c09c9d2 100644 (file)
@@ -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 */
index 1e2f67b..76fc24e 100644 (file)
@@ -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
index 36c4c12..7fd74d9 100644 (file)
@@ -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)
index d242072..ebb837b 100644 (file)
@@ -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)
index 826d2c9..b34f818 100644 (file)
@@ -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
 
index 138dd62..f62a7df 100644 (file)
@@ -109,4 +109,8 @@ defined(CONFIG_MX6DL)) && !defined(CONFIG_MX6S)
 #endif
 #endif
 
+/* LDO Bypass */
+#ifndef CONFIG_MX6SLL
+#define CONFIG_LDO_BYPASS_CHECK
+#endif
 #endif
index f56783e..cb78e18 100644 (file)
@@ -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 */