From mboxrd@z Thu Jan 1 00:00:00 1970 From: Robin Gong Date: Wed, 11 Feb 2015 18:49:40 +0800 Subject: [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass In-Reply-To: References: <1420793987-7621-1-git-send-email-Peng.Fan@freescale.com> <1420793987-7621-8-git-send-email-Peng.Fan@freescale.com> Message-ID: <20150211104923.GA880@Robin-OptiPlex-780> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de On Tue, Feb 10, 2015 at 06:33:38AM -0800, Tim Harvey wrote: > On Fri, Jan 9, 2015 at 12:59 AM, Peng Fan 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. > > > > > > > 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 > > #include > > #include > > +#include > > #include > > #include > > #include > > @@ -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