[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