All of lore.kernel.org
 help / color / mirror / Atom feed
From: Robin Gong <b38343@freescale.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass
Date: Wed, 11 Feb 2015 18:49:40 +0800	[thread overview]
Message-ID: <20150211104923.GA880@Robin-OptiPlex-780> (raw)
In-Reply-To: <CAJ+vNU2szDUV6ut+4cr-G2tRGOrQH65a6p2xmdM8J+CcWQXSYg@mail.gmail.com>

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@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

  reply	other threads:[~2015-02-11 10:49 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-09  8:59 [U-Boot] [PATCH 00/12] imx:mx6 add ldo bypass Peng Fan
2015-01-09  8:59 ` [U-Boot] [PATCH 01/12] imx:mx6slevk add pmic and i2c configuration Peng Fan
2015-01-09  8:59 ` [U-Boot] [PATCH 02/12] imx:mx6sl add I2c pad settings Peng Fan
2015-01-09  8:59 ` [U-Boot] [PATCH 03/12] imx:mx6slevk implement power init board Peng Fan
2015-02-10 11:01   ` Stefano Babic
2015-01-09  8:59 ` [U-Boot] [PATCH 04/12] imx:mx6 update mxc_ccm_reg Peng Fan
2015-02-10 11:03   ` Stefano Babic
2015-02-11  2:19     ` Peng Fan
2015-01-09  8:59 ` [U-Boot] [PATCH 05/12] imx:mx6 update fuse_bank0_regs Peng Fan
2015-02-10 11:51   ` Stefano Babic
2015-01-09  8:59 ` [U-Boot] [PATCH 06/12] pmic:pfuze add macro for setting voltage Peng Fan
2015-02-10 11:54   ` Stefano Babic
2015-02-11  2:06     ` Peng Fan
2015-01-09  8:59 ` [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass Peng Fan
2015-02-10 11:23   ` Stefano Babic
2015-02-10 14:50     ` Tim Harvey
2015-02-10 14:59       ` Fabio Estevam
2015-02-10 15:29         ` Tim Harvey
2015-02-11  8:42       ` Stefano Babic
2015-02-10 14:33   ` Tim Harvey
2015-02-11 10:49     ` Robin Gong [this message]
2015-02-11 15:47       ` Tim Harvey
2015-02-13  0:08         ` Tim Harvey
2015-02-13  7:20           ` Robin Gong
2015-02-13  8:16         ` Robin Gong
2015-02-24 15:56           ` Tim Harvey
2015-01-09  8:59 ` [U-Boot] [PATCH 08/12] imx:mx6slevk add ldo mode set function Peng Fan
2015-01-09  8:59 ` [U-Boot] [PATCH 09/12] imx:mx6sabresd Add ldo_mode_set function Peng Fan
2015-01-09  8:59 ` [U-Boot] [PATCH 10/12] imx:mx6sxsabresd add ldo mode set function Peng Fan
2015-01-09  8:59 ` [U-Boot] [PATCH 11/12] imx:mx6qsabreauto add ldo mode init Peng Fan
2015-01-09  8:59 ` [U-Boot] [PATCH 12/12] ARM:imx call ldo_mode_set in arch_preboot_os Peng Fan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150211104923.GA880@Robin-OptiPlex-780 \
    --to=b38343@freescale.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.