[U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass

Robin Gong b38343 at freescale.com
Wed Feb 11 11:49:40 CET 2015


On Tue, Feb 10, 2015 at 06:33:38AM -0800, Tim Harvey wrote:
> On Fri, Jan 9, 2015 at 12:59 AM, Peng Fan <Peng.Fan at freescale.com> wrote:
> > The basic graph for voltage input is:
> >    VDDARM_IN ---> LDO_DIG(ARM) ---> VDD_ARM_CAP
> >    VDDSOC_IN ---> LDO_DIG(SOC) ---> VDD_SOC_CAP
> >
> 
> Hi Peng,
> 
> Glad to see someone else interested in IMX6 LDO bypass mode. I've made
> a couple of stabs at getting it supported in mainline but I haven't
> had the time to follow-through yet there.
> 
> > We can bypass the LDO to save power, if the board already has pmic.
> >
> > set_anatop_bypass is the function to do the bypass VDDARM and VDDSOC
> > work.
> >
> > Current only set VDDARM_IN at 1.175V/VDDSOC_IN at 1.175V before ldo
> > bypass switch. So until ldo bypass switch happened, these voltage
> > setting is set in ldo-enable mode. But in datasheet, we need
> > 1.15V + 125mV = 1.275V for VDDARM_IN. We need to downgrade cpufreq
> > to 400Mhz and restore after ldo bypass mode switch. So add
> > prep_anatop_bypass/finish_anatop_bypass/set_arm_freq_400M to do
> > this work.
> >
> > LDO bypass is dependent on the flatten device tree file. If speed
> > grading fuse is for 1.2GHz, enable LDO bypass and setup PMIC voltages.
> > So add check for 1.2GHz core speed. So add check_1_2G function.
> 
> This isn't quite how it works. If you are 'operating at 1.2GHz'
> (supposing you had a processor cabable of it) you must use the LDO (to
> avoid ripple sensitivity issues).
>
Hi Peng, the limitation is "must use ldo-enable mode in 1.2Ghz", NOT ldo-bypass
> >
> > In ldo-bypass mode, we need trigger WDOG_B pin to reset pmic in
> > ldo-bypass mode. So add set_wdog_reset to do this work.
> 
> This is very board dependent. Here you are referring to a board that
> has a reset input to the PMIC's from the IMX6's watchdog output. In
> this case, this reset routing/pinmux would be needed regardless of
> using ldo-bypass mode or not and that should just be a pinmux of the
> pin your using for WDOG_B.
>
There are two types of reboot in our chip by watchdog : SRS/warm reset
(Software Reset Signal) and WDOG_B(reset signal output to external pmic
to trigger next power cycle). In fact, warm reset can work most cases except
ldo-bypass mode and this is why we connect WDOG_B reset and ldo-bypass here:
kernel may trigger warm reset at the lowest cpu freq setpoint, for example
VDDARM 0.975v at 396Mhz ldo-bypass mode. i.mx6q will reboot with ldo-enable mode
@792Mhz and the VDDARM_IN 0.975v can't support system boot.Thus, we need use
WDOG_B pin to reset external pmic if using ldo-byapss mode.
> >
> 
> <snip>
> 
> > diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
> > index 5f5f497..5d02755 100644
> > --- a/arch/arm/cpu/armv7/mx6/soc.c
> > +++ b/arch/arm/cpu/armv7/mx6/soc.c
> > @@ -18,6 +18,7 @@
> >  #include <asm/arch/sys_proto.h>
> >  #include <asm/imx-common/boot_mode.h>
> >  #include <asm/imx-common/dma.h>
> > +#include <libfdt.h>
> >  #include <stdbool.h>
> >  #include <asm/arch/mxc_hdmi.h>
> >  #include <asm/arch/crm_regs.h>
> > @@ -429,6 +430,146 @@ void s_init(void)
> >         writel(mask528, &anatop->pfd_528_clr);
> >  }
> >
> > +#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;
> > +}
> 
> What you are doing here is relying on a device-tree binding from the
> Freescale 'vendor' kernel, which will NEVER make it upstream and this
> is one of the issues I was running into getting ldo-bypass capability
> upstream in the kernel.
> 
> The issue here is that LDO bypass is dependent on the following things:
>   1. your voltage rail requirements - which are dependent on the CPU
> frequency (there is a nice table in the IMX6 datasheets of voltage on
> each rail at each frequency operating point validated by Freescale).
> The exception of always using the LDO for 1.2GHz is specified here as
> well.
>   2. you have a PMIC in your design on VDD_ARM_IN and VDD_SOC_IN rails
> - this should be specified in the device-tree as well
>   3. you have valid PMIC drivers configured
> 
> In the kernel, its not desired to have a single device-tree node
> called 'fsl,ldo-bypass' for an enable. Instead you need to make sure
> that you PMIC regulators that are 'not' the internal IMX6 anatop
> regulators. This property is not a mainline linux device-tree binding.
> 
Yes, understood. But we have no better solution, because we need touch both
internal anatop regulator and external pmic regulator in ldo-bypass mode, that
bring kernel cpufreq driver code too messy....
> > +
> > +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 at 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;
> > +}
> 
> While it is correct that you must not use LDO bypass when operating at
> 1.2GHz, that does not mean that a CPU capable of 1.2GHz can't use LDO
> bypass at the lower operating points.
>
I see, but to simply things, we regard as 1.2GHz chip(fused) may running at
1.2GHz and force it work in ldo-enable mode although it has chance to running
at 1Ghz. In other words, ldo-bypass mode only set once not dynamically.
> > +
> > +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);
> > +}
> 
> I have no idea what is going on here. Are we now running at different
> CPU frequencies in U-boot? The IMX6 comes up in either 800MHz or
> 400MHz per BOOT_CFG3 e-fuse and from the U-Boot I'm working with
> (still on 2010.04 but pretty sure its the same in 2014.10) the CPU
> frequency is never changed in the bootloader.
> 
Let's try to explain why we downgrade cpufreq to 400Mhz before ldo-bypass mode
switch(i.mx6q):
  cpufreq    VDDSOC    VDDARM
  400Mhz     0.975v     1.175v
  800Mhz     1.175v     1.175v
If system boot from 800Mhz, considering VDDARM setting with 1.175v after
ldo-bypass mode switch, and the voltage drop which bring by internal regulator
125mv, we have to set VDDARM 1.175v+125mv = 1.3v before ldo-bypass mode switch,
but the 1.3v beyond our max voltage for VDDARM. So we have to downgrade the cpufreq
to 400Mhz.
> This brings me to the question of why does LDO bypass have anything at
> all do to with the bootloader?
> 
We only need do once ldo-bypass switch, so we hope it can be implemented in
u-boot
> It is true that the Freescale vendor kernel will keep the LDO in
> bypass mode if its registers are set that way from the bootloader, so
> that is probably what your after here. But again, that is a poor
> kernel implementation that likely won't make it upstream and a
> solution that doesn't handle the dynamic situation of a 1.2GHz cpu
> stepping down and not needing the LDO. It is also true that there are
> alternate device-tree's for the Freescale vendor kernel for some
> boards that have a PMIC such that one device-tree is setup to always
> use the LDO, and one is setup to never use the LDO. I think that is a
> result of taking the easy way out instead of giving the kernel the
> smarts to use the LDO only when needed on these boards.
> 
> Tim


More information about the U-Boot mailing list