From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tim Harvey Date: Tue, 10 Feb 2015 06:33:38 -0800 Subject: [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass In-Reply-To: <1420793987-7621-8-git-send-email-Peng.Fan@freescale.com> References: <1420793987-7621-1-git-send-email-Peng.Fan@freescale.com> <1420793987-7621-8-git-send-email-Peng.Fan@freescale.com> Message-ID: List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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). > > 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. > > 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. > + > +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. > + > +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. This brings me to the question of why does LDO bypass have anything at all do to with the bootloader? 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