All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 00/12] imx:mx6 add ldo bypass
@ 2015-01-09  8:59 Peng Fan
  2015-01-09  8:59 ` [U-Boot] [PATCH 01/12] imx:mx6slevk add pmic and i2c configuration Peng Fan
                   ` (11 more replies)
  0 siblings, 12 replies; 31+ messages in thread
From: Peng Fan @ 2015-01-09  8:59 UTC (permalink / raw)
  To: u-boot

This patch set is based on these three patches:
https://patchwork.ozlabs.org/patch/426621/
https://patchwork.ozlabs.org/patch/426623/
https://patchwork.ozlabs.org/patch/426622/

If want to test this patch set, please first apply the up 3 patches.

This patch set is mainly to add ldo bypass support.

Since pmic related function is not readly in previous patch,
patch 1/12, patch 2/12, patch 3/12 is first to add pmic related support,
such as power_init_board, related iomux/pad settings and configuration in
header file. Then ldo bypass function can be implemented.

patch 4/12 is to update mxc_ccm_regs with more registers, since ldo setting
will use them.

patch 5/12 is to update fuse_bank0_regs, since ldo setting will check it.

patch 6/12 is to add a macro for setting voltage easily.

patch 7/12 is to add ldo bypass related common function.

patch 8/12, patch 9/12, patch 10/12, patch 11/12 is to implement ldo_mode_set
in different boards' file.

patch 12/12 is to invoke ldo_mode_set in arch_preboot_os. Future work
will integrate Device tree for i.MX6 U-Boot. Then we can move it to
power_init_board.

More detailed info can see each patch's commit log. 

Peng Fan (12):
  imx:mx6slevk add pmic and i2c configuration
  imx:mx6sl add I2c pad settings
  imx:mx6slevk implement power init board
  imx:mx6 update mxc_ccm_reg
  imx:mx6 update fuse_bank0_regs
  pmic:pfuze add macro for setting voltage
  imx:mx6 Support LDO bypass
  imx:mx6slevk add ldo mode set function
  imx:mx6sabresd Add ldo_mode_set function
  imx:mx6sxsabresd add ldo mode set function
  imx:mx6qsabreauto add ldo mode init
  ARM:imx call ldo_mode_set in arch_preboot_os

 arch/arm/cpu/armv7/mx6/soc.c                  | 141 ++++++++++++++++++++++++++
 arch/arm/imx-common/cpu.c                     |   4 +
 arch/arm/include/asm/arch-mx6/crm_regs.h      |  87 ++++++++++++++++
 arch/arm/include/asm/arch-mx6/imx-regs.h      |  12 ++-
 arch/arm/include/asm/arch-mx6/mx6sl_pins.h    |   5 +
 arch/arm/include/asm/arch-mx6/sys_proto.h     |   9 ++
 board/freescale/mx6qsabreauto/mx6qsabreauto.c |  31 ++++++
 board/freescale/mx6sabresd/mx6sabresd.c       |  85 ++++++++++++++++
 board/freescale/mx6slevk/mx6slevk.c           | 100 ++++++++++++++++++
 board/freescale/mx6sxsabresd/mx6sxsabresd.c   |  50 +++++++++
 include/configs/mx6qsabreauto.h               |   2 +
 include/configs/mx6sabresd.h                  |   2 +
 include/configs/mx6slevk.h                    |  14 +++
 include/configs/mx6sxsabresd.h                |   2 +
 include/power/pfuze100_pmic.h                 |   2 +
 15 files changed, 542 insertions(+), 4 deletions(-)

-- 
1.8.4

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 01/12] imx:mx6slevk add pmic and i2c configuration
  2015-01-09  8:59 [U-Boot] [PATCH 00/12] imx:mx6 add ldo bypass Peng Fan
@ 2015-01-09  8:59 ` Peng Fan
  2015-01-09  8:59 ` [U-Boot] [PATCH 02/12] imx:mx6sl add I2c pad settings Peng Fan
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 31+ messages in thread
From: Peng Fan @ 2015-01-09  8:59 UTC (permalink / raw)
  To: u-boot

Add pmic and i2c configuration in board header file.

Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
---
 include/configs/mx6slevk.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/configs/mx6slevk.h b/include/configs/mx6slevk.h
index e6c4130..9fd7619 100644
--- a/include/configs/mx6slevk.h
+++ b/include/configs/mx6slevk.h
@@ -48,6 +48,18 @@
 #define CONFIG_CMD_FAT
 #define CONFIG_DOS_PARTITION
 
+/* I2C Configs */
+#define CONFIG_CMD_I2C
+#define CONFIG_SYS_I2C
+#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_SPEED		  100000
+
+/* PMIC */
+#define CONFIG_POWER
+#define CONFIG_POWER_I2C
+#define CONFIG_POWER_PFUZE100
+#define CONFIG_POWER_PFUZE100_I2C_ADDR	0x08
+
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_DHCP
 #define CONFIG_CMD_MII
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 02/12] imx:mx6sl add I2c pad settings
  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 ` Peng Fan
  2015-01-09  8:59 ` [U-Boot] [PATCH 03/12] imx:mx6slevk implement power init board Peng Fan
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 31+ messages in thread
From: Peng Fan @ 2015-01-09  8:59 UTC (permalink / raw)
  To: u-boot

This few pad settings are for pmic i2c.

Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
---
 arch/arm/include/asm/arch-mx6/mx6sl_pins.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/include/asm/arch-mx6/mx6sl_pins.h b/arch/arm/include/asm/arch-mx6/mx6sl_pins.h
index 9ded3d8..0475203 100644
--- a/arch/arm/include/asm/arch-mx6/mx6sl_pins.h
+++ b/arch/arm/include/asm/arch-mx6/mx6sl_pins.h
@@ -58,5 +58,10 @@ enum {
 
 	MX6_PAD_KEY_COL4__USB_USBOTG1_PWR			= IOMUX_PAD(0x0484, 0x017C, 6, 0x0000, 0, 0),
 	MX6_PAD_KEY_COL5__USB_USBOTG2_PWR			= IOMUX_PAD(0x0488, 0x0180, 6, 0x0000, 0, 0),
+
+	MX6_PAD_I2C1_SDA__I2C1_SDA				= IOMUX_PAD(0x0450, 0x0160, 0x10, 0x0720, 2, 0),
+	MX6_PAD_I2C1_SDA__GPIO_3_13				= IOMUX_PAD(0x0450, 0x0160, 5, 0x0000, 0, 0),
+	MX6_PAD_I2C1_SCL__I2C1_SCL				= IOMUX_PAD(0x044C, 0x015C, 0x10, 0x071C, 2, 0),
+	MX6_PAD_I2C1_SCL__GPIO_3_12				= IOMUX_PAD(0x044C, 0x015C, 5, 0x0000, 0, 0),
 };
 #endif	/* __ASM_ARCH_MX6_MX6SL_PINS_H__ */
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 03/12] imx:mx6slevk implement power init board
  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 ` 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
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 31+ messages in thread
From: Peng Fan @ 2015-01-09  8:59 UTC (permalink / raw)
  To: u-boot

Implement power_init_board and related I2C interface configuration.

After adding this, uboot can successfully detect and configure pmic.

"
U-Boot 2015.01-rc4-00110-g5697113-dirty (Jan 08 2015 - 21:06:44)

CPU:   Freescale i.MX6SL rev1.0 at 396 MHz
Reset cause: POR
Board: MX6SLEVK
I2C:   ready
DRAM:  1 GiB
PMIC:  PFUZE100 ID=0x10
MMC:   FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2
"

Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
---
 board/freescale/mx6slevk/mx6slevk.c | 47 +++++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/board/freescale/mx6slevk/mx6slevk.c b/board/freescale/mx6slevk/mx6slevk.c
index 838ea6c..f74b237 100644
--- a/board/freescale/mx6slevk/mx6slevk.c
+++ b/board/freescale/mx6slevk/mx6slevk.c
@@ -13,13 +13,18 @@
 #include <asm/arch/sys_proto.h>
 #include <asm/gpio.h>
 #include <asm/imx-common/iomux-v3.h>
+#include <asm/imx-common/mxc_i2c.h>
 #include <asm/imx-common/spi.h>
 #include <asm/io.h>
 #include <linux/sizes.h>
 #include <common.h>
 #include <fsl_esdhc.h>
+#include <i2c.h>
 #include <mmc.h>
 #include <netdev.h>
+#include <power/pmic.h>
+#include <power/pfuze100_pmic.h>
+#include "../common/pfuze.h"
 #include <usb.h>
 #include <usb/ehci-fsl.h>
 
@@ -40,6 +45,11 @@ DECLARE_GLOBAL_DATA_PTR;
 #define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \
 		      PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
 
+#define I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |		\
+		      PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |	\
+		      PAD_CTL_DSE_40ohm | PAD_CTL_HYS |		\
+		      PAD_CTL_ODE | PAD_CTL_SRE_FAST)
+
 #define ETH_PHY_RESET	IMX_GPIO_NR(4, 21)
 
 int dram_init(void)
@@ -221,6 +231,39 @@ int board_mmc_init(bd_t *bis)
 	return 0;
 }
 
+#ifdef CONFIG_SYS_I2C_MXC
+#define PC	MUX_PAD_CTRL(I2C_PAD_CTRL)
+/* I2C1 for PMIC */
+struct i2c_pads_info i2c_pad_info1 = {
+	.sda = {
+		.i2c_mode = MX6_PAD_I2C1_SDA__I2C1_SDA | PC,
+		.gpio_mode = MX6_PAD_I2C1_SDA__GPIO_3_13 | PC,
+		.gp = IMX_GPIO_NR(3, 13),
+	},
+	.scl = {
+		.i2c_mode = MX6_PAD_I2C1_SCL__I2C1_SCL | PC,
+		.gpio_mode = MX6_PAD_I2C1_SCL__GPIO_3_12 | PC,
+		.gp = IMX_GPIO_NR(3, 12),
+	},
+};
+
+int power_init_board(void)
+{
+	struct pmic *p;
+	unsigned int ret;
+
+	p = pfuze_common_init(I2C_PMIC);
+	if (!p)
+		return -ENODEV;
+
+	ret = pfuze_mode_init(p, APS_PFM);
+	if (ret < 0)
+		return -EIO;
+
+	return 0;
+}
+#endif
+
 #ifdef CONFIG_FEC_MXC
 int board_eth_init(bd_t *bis)
 {
@@ -297,6 +340,10 @@ int board_init(void)
 	/* address of boot parameters */
 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 
+#ifdef CONFIG_SYS_I2C_MXC
+	setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
+#endif
+
 #ifdef	CONFIG_FEC_MXC
 	setup_fec();
 #endif
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 04/12] imx:mx6 update mxc_ccm_reg
  2015-01-09  8:59 [U-Boot] [PATCH 00/12] imx:mx6 add ldo bypass Peng Fan
                   ` (2 preceding siblings ...)
  2015-01-09  8:59 ` [U-Boot] [PATCH 03/12] imx:mx6slevk implement power init board Peng Fan
@ 2015-01-09  8:59 ` Peng Fan
  2015-02-10 11:03   ` Stefano Babic
  2015-01-09  8:59 ` [U-Boot] [PATCH 05/12] imx:mx6 update fuse_bank0_regs Peng Fan
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 31+ messages in thread
From: Peng Fan @ 2015-01-09  8:59 UTC (permalink / raw)
  To: u-boot

Add more register for structure mxc_ccm_reg.

Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
---
 arch/arm/include/asm/arch-mx6/crm_regs.h | 87 ++++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)

diff --git a/arch/arm/include/asm/arch-mx6/crm_regs.h b/arch/arm/include/asm/arch-mx6/crm_regs.h
index 39f3c07..55e1287 100644
--- a/arch/arm/include/asm/arch-mx6/crm_regs.h
+++ b/arch/arm/include/asm/arch-mx6/crm_regs.h
@@ -103,6 +103,93 @@ struct mxc_ccm_reg {
 	u32 analog_pfd_528_set;
 	u32 analog_pfd_528_clr;
 	u32 analog_pfd_528_tog;
+	u32 reg_1p1;				/* 0x4110 */
+	u32 reg_1p1_set;			/* 0x4114 */
+	u32 reg_1p1_clr;			/* 0x4118 */
+	u32 reg_1p1_tog;			/* 0x411c */
+	u32 reg_3p0;				/* 0x4120 */
+	u32 reg_3p0_set;			/* 0x4124 */
+	u32 reg_3p0_clr;			/* 0x4128 */
+	u32 reg_3p0_tog;			/* 0x412c */
+	u32 reg_2p5;				/* 0x4130 */
+	u32 reg_2p5_set;			/* 0x4134 */
+	u32 reg_2p5_clr;			/* 0x4138 */
+	u32 reg_2p5_tog;			/* 0x413c */
+	u32 reg_core;				/* 0x4140 */
+	u32 reg_core_set;			/* 0x4144 */
+	u32 reg_core_clr;			/* 0x4148 */
+	u32 reg_core_tog;			/* 0x414c */
+	u32 ana_misc0;				/* 0x4150 */
+	u32 ana_misc0_set;			/* 0x4154 */
+	u32 ana_misc0_clr;			/* 0x4158 */
+	u32 ana_misc0_tog;			/* 0x415c */
+	u32 ana_misc1;				/* 0x4160 */
+	u32 ana_misc1_set;			/* 0x4164 */
+	u32 ana_misc1_clr;			/* 0x4168 */
+	u32 ana_misc1_tog;			/* 0x416c */
+	u32 ana_misc2;				/* 0x4170 */
+	u32 ana_misc2_set;			/* 0x4174 */
+	u32 ana_misc2_clr;			/* 0x4178 */
+	u32 ana_misc2_tog;			/* 0x417c */
+	u32 tempsense0;				/* 0x4180 */
+	u32 tempsense0_set;			/* 0x4184 */
+	u32 tempsense0_clr;			/* 0x4188 */
+	u32 tempsense0_tog;			/* 0x418c */
+	u32 tempsense1;				/* 0x4190 */
+	u32 tempsense1_set;			/* 0x4194 */
+	u32 tempsense1_clr;			/* 0x4198 */
+	u32 tempsense1_tog;			/* 0x419c */
+	u32 usb1_vbus_detect;			/* 0x41a0 */
+	u32 usb1_vbus_detect_set;		/* 0x41a4 */
+	u32 usb1_vbus_detect_clr;		/* 0x41a8 */
+	u32 usb1_vbus_detect_tog;		/* 0x41ac */
+	u32 usb1_chrg_detect;			/* 0x41b0 */
+	u32 usb1_chrg_detect_set;		/* 0x41b4 */
+	u32 usb1_chrg_detect_clr;		/* 0x41b8 */
+	u32 usb1_chrg_detect_tog;		/* 0x41bc */
+	u32 usb1_vbus_det_stat;			/* 0x41c0 */
+	u32 usb1_vbus_det_stat_set;		/* 0x41c4 */
+	u32 usb1_vbus_det_stat_clr;		/* 0x41c8 */
+	u32 usb1_vbus_det_stat_tog;		/* 0x41cc */
+	u32 usb1_chrg_det_stat;			/* 0x41d0 */
+	u32 usb1_chrg_det_stat_set;		/* 0x41d4 */
+	u32 usb1_chrg_det_stat_clr;		/* 0x41d8 */
+	u32 usb1_chrg_det_stat_tog;		/* 0x41dc */
+	u32 usb1_loopback;			/* 0x41e0 */
+	u32 usb1_loopback_set;			/* 0x41e4 */
+	u32 usb1_loopback_clr;			/* 0x41e8 */
+	u32 usb1_loopback_tog;			/* 0x41ec */
+	u32 usb1_misc;				/* 0x41f0 */
+	u32 usb1_misc_set;			/* 0x41f4 */
+	u32 usb1_misc_clr;			/* 0x41f8 */
+	u32 usb1_misc_tog;			/* 0x41fc */
+	u32 usb2_vbus_detect;			/* 0x4200 */
+	u32 usb2_vbus_detect_set;		/* 0x4204 */
+	u32 usb2_vbus_detect_clr;		/* 0x4208 */
+	u32 usb2_vbus_detect_tog;		/* 0x420c */
+	u32 usb2_chrg_detect;			/* 0x4210 */
+	u32 usb2_chrg_detect_set;		/* 0x4214 */
+	u32 usb2_chrg_detect_clr;		/* 0x4218 */
+	u32 usb2_chrg_detect_tog;		/* 0x421c */
+	u32 usb2_vbus_det_stat;			/* 0x4220 */
+	u32 usb2_vbus_det_stat_set;		/* 0x4224 */
+	u32 usb2_vbus_det_stat_clr;		/* 0x4228 */
+	u32 usb2_vbus_det_stat_tog;		/* 0x422c */
+	u32 usb2_chrg_det_stat;			/* 0x4230 */
+	u32 usb2_chrg_det_stat_set;		/* 0x4234 */
+	u32 usb2_chrg_det_stat_clr;		/* 0x4238 */
+	u32 usb2_chrg_det_stat_tog;		/* 0x423c */
+	u32 usb2_loopback;			/* 0x4240 */
+	u32 usb2_loopback_set;			/* 0x4244 */
+	u32 usb2_loopback_clr;			/* 0x4248 */
+	u32 usb2_loopback_tog;			/* 0x424c */
+	u32 usb2_misc;				/* 0x4250 */
+	u32 usb2_misc_set;			/* 0x4254 */
+	u32 usb2_misc_clr;			/* 0x4258 */
+	u32 usb2_misc_tog;			/* 0x425c */
+	u32 digprog;				/* 0x4260 */
+	u32 reserved1[7];
+	u32 digprog_sololite;			/* 0x4280 */
 };
 #endif
 
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 05/12] imx:mx6 update fuse_bank0_regs
  2015-01-09  8:59 [U-Boot] [PATCH 00/12] imx:mx6 add ldo bypass Peng Fan
                   ` (3 preceding siblings ...)
  2015-01-09  8:59 ` [U-Boot] [PATCH 04/12] imx:mx6 update mxc_ccm_reg Peng Fan
@ 2015-01-09  8:59 ` 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
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 31+ messages in thread
From: Peng Fan @ 2015-01-09  8:59 UTC (permalink / raw)
  To: u-boot

Update fuse_bank0_regs structure according reference mannual.

Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
---
 arch/arm/include/asm/arch-mx6/imx-regs.h | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h
index c968600..22f371d 100644
--- a/arch/arm/include/asm/arch-mx6/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx6/imx-regs.h
@@ -624,12 +624,16 @@ struct fuse_bank0_regs {
 	u32	rsvd1[3];
 	u32	uid_high;
 	u32	rsvd2[3];
-	u32	rsvd3[4];
-	u32	rsvd4[4];
-	u32	rsvd5[4];
+	u32	cfg2;
+	u32	rsvd3[3];
+	u32	cfg3;
+	u32	rsvd4[3];
+	u32	cfg4;
+	u32	rsvd5[3];
 	u32	cfg5;
 	u32	rsvd6[3];
-	u32	rsvd7[4];
+	u32	cfg6;
+	u32	rsvd7[3];
 };
 
 #ifdef CONFIG_MX6SX
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 06/12] pmic:pfuze add macro for setting voltage
  2015-01-09  8:59 [U-Boot] [PATCH 00/12] imx:mx6 add ldo bypass Peng Fan
                   ` (4 preceding siblings ...)
  2015-01-09  8:59 ` [U-Boot] [PATCH 05/12] imx:mx6 update fuse_bank0_regs Peng Fan
@ 2015-01-09  8:59 ` Peng Fan
  2015-02-10 11:54   ` Stefano Babic
  2015-01-09  8:59 ` [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass Peng Fan
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 31+ messages in thread
From: Peng Fan @ 2015-01-09  8:59 UTC (permalink / raw)
  To: u-boot

"#define PFUZE100_SW1ABC_SETP(x) ((x - 3000) / 250)"
This macro is for configuring SW1A/B/C Output Voltage easily.

Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
---
 include/power/pfuze100_pmic.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/power/pfuze100_pmic.h b/include/power/pfuze100_pmic.h
index 7474afb..d304658 100644
--- a/include/power/pfuze100_pmic.h
+++ b/include/power/pfuze100_pmic.h
@@ -61,6 +61,8 @@ enum {
  * Buck Regulators
  */
 
+#define PFUZE100_SW1ABC_SETP(x)	((x - 3000) / 250)
+
 /* SW1A/B/C Output Voltage Configuration */
 #define SW1x_0_300V 0
 #define SW1x_0_325V 1
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass
  2015-01-09  8:59 [U-Boot] [PATCH 00/12] imx:mx6 add ldo bypass Peng Fan
                   ` (5 preceding siblings ...)
  2015-01-09  8:59 ` [U-Boot] [PATCH 06/12] pmic:pfuze add macro for setting voltage Peng Fan
@ 2015-01-09  8:59 ` Peng Fan
  2015-02-10 11:23   ` Stefano Babic
  2015-02-10 14:33   ` Tim Harvey
  2015-01-09  8:59 ` [U-Boot] [PATCH 08/12] imx:mx6slevk add ldo mode set function Peng Fan
                   ` (4 subsequent siblings)
  11 siblings, 2 replies; 31+ messages in thread
From: Peng Fan @ 2015-01-09  8:59 UTC (permalink / raw)
  To: u-boot

The basic graph for voltage input is:
   VDDARM_IN ---> LDO_DIG(ARM) ---> VDD_ARM_CAP
   VDDSOC_IN ---> LDO_DIG(SOC) ---> VDD_SOC_CAP

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.

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.

Also add related function prototype in sys_proto.h

Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
Signed-off-by: Robin Gong <b38343@freescale.com>
Signed-off-by: Nitin Garg <nitin.garg@freescale.com>
---
 arch/arm/cpu/armv7/mx6/soc.c              | 141 ++++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-mx6/sys_proto.h |   9 ++
 2 files changed, 150 insertions(+)

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;
+}
+
+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;
+}
+
+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);
+}
+
+void prep_anatop_bypass(void)
+{
+	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+
+	arm_orig_podf = readl(&mxc_ccm->cacrr);
+	/*
+	 * Downgrade ARM speed to 400Mhz as half of boot 800Mhz before ldo
+	 * bypassed, also downgrade internal vddarm ldo to 0.975V.
+	 * VDDARM_IN 0.975V + 125mV = 1.1V < Max(1.3V)
+	 * otherwise@800Mhz(i.mx6dl):
+	 * VDDARM_IN 1.175V + 125mV = 1.3V = Max(1.3V)
+	 * We need provide enough gap in this case.
+	 * skip if boot from 400M.
+	 */
+	if (!arm_orig_podf)
+		set_arm_freq_400M(true);
+#if !defined(CONFIG_MX6DL) && !defined(CONFIG_MX6SX)
+	set_ldo_voltage(LDO_ARM, 975);
+#else
+	set_ldo_voltage(LDO_ARM, 1150);
+#endif
+}
+
+void set_wdog_reset(struct wdog_regs *wdog)
+{
+	u32 reg = readw(&wdog->wcr);
+	/*
+	 * use WDOG_B mode to reset external pmic because it's risky for the
+	 * following watchdog reboot in case of cpu freq at lowest 400Mhz with
+	 * ldo-bypass mode. Because boot frequency maybe higher 800Mhz i.e. So
+	 * in ldo-bypass mode watchdog reset will only triger POR reset, not
+	 * WDOG reset. But below code depends on hardware design, if HW didn't
+	 * connect WDOG_B pin to external pmic such as i.mx6slevk, we can skip
+	 * these code since it assumed boot from 400Mhz always.
+	 */
+	reg = readw(&wdog->wcr);
+	reg |= 1 << 3;
+	/*
+	 * WDZST bit is write-once only bit. Align this bit in kernel,
+	 * otherwise kernel code will have no chance to set this bit.
+	 */
+	reg |= 1 << 0;
+	writew(reg, &wdog->wcr);
+}
+
+int set_anatop_bypass(int wdog_reset_pin)
+{
+	struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+	struct wdog_regs *wdog;
+	u32 reg = readl(&ccm_regs->reg_core);
+
+	/* bypass VDDARM/VDDSOC */
+	reg = reg | (0x1F << 18) | 0x1F;
+	writel(reg, &ccm_regs->reg_core);
+
+	if (wdog_reset_pin == 2)
+		wdog = (struct wdog_regs *)WDOG2_BASE_ADDR;
+	else if (wdog_reset_pin == 1)
+		wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
+	else
+		return arm_orig_podf;
+	set_wdog_reset(wdog);
+	return arm_orig_podf;
+}
+
+void finish_anatop_bypass(void)
+{
+	if (!arm_orig_podf)
+		set_arm_freq_400M(false);
+}
+#endif
+
 #ifdef CONFIG_IMX_HDMI
 void imx_enable_hdmi_phy(void)
 {
diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h
index 28ba844..e6f2112 100644
--- a/arch/arm/include/asm/arch-mx6/sys_proto.h
+++ b/arch/arm/include/asm/arch-mx6/sys_proto.h
@@ -28,6 +28,15 @@ const char *get_imx_type(u32 imxtype);
 unsigned imx_ddr_size(void);
 void set_chipselect_size(int const);
 
+void set_wdog_reset(struct wdog_regs *wdog);
+#ifdef CONFIG_LDO_BYPASS_CHECK
+int check_ldo_bypass(void);
+int check_1_2G(void);
+void ldo_mode_set(int ldo_bypass);
+int set_anatop_bypass(int wdog_reset_pin);
+void prep_anatop_bypass(void);
+void finish_anatop_bypass(void);
+#endif
 /*
  * Initializes on-chip ethernet controllers.
  * to override, implement board_eth_init()
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 08/12] imx:mx6slevk add ldo mode set function
  2015-01-09  8:59 [U-Boot] [PATCH 00/12] imx:mx6 add ldo bypass Peng Fan
                   ` (6 preceding siblings ...)
  2015-01-09  8:59 ` [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass Peng Fan
@ 2015-01-09  8:59 ` Peng Fan
  2015-01-09  8:59 ` [U-Boot] [PATCH 09/12] imx:mx6sabresd Add ldo_mode_set function Peng Fan
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 31+ messages in thread
From: Peng Fan @ 2015-01-09  8:59 UTC (permalink / raw)
  To: u-boot

Add ldo_mode_set function. If ldo_bypass is true, it will adjust voltage.
If not, do nothing.

This function is board specific, so implement it in board file.

Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
Signed-off-by: Robin Gong <b38343@freescale.com>
---
 board/freescale/mx6slevk/mx6slevk.c | 61 ++++++++++++++++++++++++++++++++++---
 include/configs/mx6slevk.h          |  2 ++
 2 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/board/freescale/mx6slevk/mx6slevk.c b/board/freescale/mx6slevk/mx6slevk.c
index f74b237..fdb6672 100644
--- a/board/freescale/mx6slevk/mx6slevk.c
+++ b/board/freescale/mx6slevk/mx6slevk.c
@@ -247,16 +247,69 @@ struct i2c_pads_info i2c_pad_info1 = {
 	},
 };
 
+static struct pmic *pfuze;
+
+#ifdef CONFIG_LDO_BYPASS_CHECK
+void ldo_mode_set(int ldo_bypass)
+{
+	u32 value;
+	int is_400M;
+	struct pmic *p = pfuze;
+
+	if (!p)
+		return;
+
+	/* swith to ldo_bypass mode */
+	if (ldo_bypass) {
+		prep_anatop_bypass();
+
+		/* decrease VDDARM to 1.1V */
+		pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
+		value &= ~0x3f;
+		value |= PFUZE100_SW1ABC_SETP(11000);
+		pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
+
+		/* increase VDDSOC to 1.3V */
+		pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
+		value &= ~0x3f;
+		value |= PFUZE100_SW1ABC_SETP(13000);
+		pmic_reg_write(p, PFUZE100_SW1CVOL, value);
+
+		is_400M = set_anatop_bypass(0);
+
+		/*
+		 * MX6SL: VDDARM:1.175V at 800M; VDDSOC:1.175V at 800M
+		 *        VDDARM:0.975V at 400M; VDDSOC:1.175V at 400M
+		 */
+		pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
+		value &= ~0x3f;
+		if (is_400M)
+			value |= PFUZE100_SW1ABC_SETP(9750);
+		else
+			value |= PFUZE100_SW1ABC_SETP(11750);
+		pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
+
+		/* decrease VDDSOC to 1.175V */
+		pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
+		value &= ~0x3f;
+		value |= PFUZE100_SW1ABC_SETP(11750);
+		pmic_reg_write(p, PFUZE100_SW1CVOL, value);
+
+		finish_anatop_bypass();
+		printf("switch to ldo_bypass mode!\n");
+	}
+}
+#endif
+
 int power_init_board(void)
 {
-	struct pmic *p;
 	unsigned int ret;
 
-	p = pfuze_common_init(I2C_PMIC);
-	if (!p)
+	pfuze = pfuze_common_init(I2C_PMIC);
+	if (!pfuze)
 		return -ENODEV;
 
-	ret = pfuze_mode_init(p, APS_PFM);
+	ret = pfuze_mode_init(pfuze, APS_PFM);
 	if (ret < 0)
 		return -EIO;
 
diff --git a/include/configs/mx6slevk.h b/include/configs/mx6slevk.h
index 9fd7619..56c2faf 100644
--- a/include/configs/mx6slevk.h
+++ b/include/configs/mx6slevk.h
@@ -60,6 +60,8 @@
 #define CONFIG_POWER_PFUZE100
 #define CONFIG_POWER_PFUZE100_I2C_ADDR	0x08
 
+#define CONFIG_LDO_BYPASS_CHECK
+
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_DHCP
 #define CONFIG_CMD_MII
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 09/12] imx:mx6sabresd Add ldo_mode_set function
  2015-01-09  8:59 [U-Boot] [PATCH 00/12] imx:mx6 add ldo bypass Peng Fan
                   ` (7 preceding siblings ...)
  2015-01-09  8:59 ` [U-Boot] [PATCH 08/12] imx:mx6slevk add ldo mode set function Peng Fan
@ 2015-01-09  8:59 ` Peng Fan
  2015-01-09  8:59 ` [U-Boot] [PATCH 10/12] imx:mx6sxsabresd add ldo mode set function Peng Fan
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 31+ messages in thread
From: Peng Fan @ 2015-01-09  8:59 UTC (permalink / raw)
  To: u-boot

If runs at 1.2GHz, enable ldo, and adjust voltage.

If ldo_bypass is true, it will adjust voltage. If not, do nothing.

This function is board specific, so implement it in board file.

Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
Signed-off-by: Robin Gong <b38343@freescale.com>
Signed-off-by: Nitin Garg <nitin.garg@freescale.com>
---
 board/freescale/mx6sabresd/mx6sabresd.c | 85 +++++++++++++++++++++++++++++++++
 include/configs/mx6sabresd.h            |  2 +
 2 files changed, 87 insertions(+)

diff --git a/board/freescale/mx6sabresd/mx6sabresd.c b/board/freescale/mx6sabresd/mx6sabresd.c
index 59544d9..9e0a8ae 100644
--- a/board/freescale/mx6sabresd/mx6sabresd.c
+++ b/board/freescale/mx6sabresd/mx6sabresd.c
@@ -628,6 +628,7 @@ int board_init(void)
 	return 0;
 }
 
+static struct pmic *pfuze;
 int power_init_board(void)
 {
 	struct pmic *p;
@@ -636,6 +637,7 @@ int power_init_board(void)
 	p = pfuze_common_init(I2C_PMIC);
 	if (!p)
 		return -ENODEV;
+	pfuze = p;
 
 	ret = pfuze_mode_init(p, APS_PFM);
 	if (ret < 0)
@@ -656,6 +658,89 @@ int power_init_board(void)
 	return 0;
 }
 
+#ifdef CONFIG_LDO_BYPASS_CHECK
+void ldo_mode_set(int ldo_bypass)
+{
+	unsigned int value;
+	int is_400M;
+	unsigned char vddarm;
+	struct pmic *p = pfuze;
+
+	/* increase VDDARM/VDDSOC to support 1.2G chip */
+	if (check_1_2G()) {
+		ldo_bypass = 0;	/* ldo_enable on 1.2G chip */
+		printf("1.2G chip, increase VDDARM_IN/VDDSOC_IN\n");
+		/* increase VDDARM to 1.425V */
+		pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
+		value &= ~0x3f;
+		value |= PFUZE100_SW1ABC_SETP(14250);
+		pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
+
+		/* increase VDDSOC to 1.425V */
+		pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
+		value &= ~0x3f;
+		value |= PFUZE100_SW1ABC_SETP(14250);
+		pmic_reg_write(p, PFUZE100_SW1CVOL, value);
+	}
+	/* switch to ldo_bypass mode , boot on 800Mhz */
+	if (ldo_bypass) {
+		prep_anatop_bypass();
+
+		/* decrease VDDARM for 400Mhz DQ:1.1V, DL:1.275V */
+		pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
+		value &= ~0x3f;
+#if defined(CONFIG_MX6DL)
+		value |= PFUZE100_SW1ABC_SETP(12750);
+#else
+		value |= PFUZE100_SW1ABC_SETP(11000);
+#endif
+		pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
+
+		/* increase VDDSOC to 1.3V */
+		pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
+		value &= ~0x3f;
+		value |= PFUZE100_SW1ABC_SETP(13000);
+		pmic_reg_write(p, PFUZE100_SW1CVOL, value);
+
+		/*
+		 * MX6Q:
+		 * VDDARM:1.15V at 800M; VDDSOC:1.175V at 800M
+		 * VDDARM:0.975V at 400M; VDDSOC:1.175V at 400M
+		 * MX6DL:
+		 * VDDARM:1.175V at 800M; VDDSOC:1.175V at 800M
+		 * VDDARM:1.075V at 400M; VDDSOC:1.175V@400M
+		 */
+		is_400M = set_anatop_bypass(2);
+		if (is_400M)
+#if defined(CONFIG_MX6DL)
+			vddarm = PFUZE100_SW1ABC_SETP(10750);
+#else
+			vddarm = PFUZE100_SW1ABC_SETP(9750);
+#endif
+		else
+#if defined(CONFIG_MX6DL)
+			vddarm = PFUZE100_SW1ABC_SETP(11750);
+#else
+			vddarm = PFUZE100_SW1ABC_SETP(11500);
+#endif
+
+		pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
+		value &= ~0x3f;
+		value |= vddarm;
+		pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
+
+		/* decrease VDDSOC to 1.175V */
+		pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
+		value &= ~0x3f;
+		value |= PFUZE100_SW1ABC_SETP(11750);
+		pmic_reg_write(p, PFUZE100_SW1CVOL, value);
+
+		finish_anatop_bypass();
+		printf("switch to ldo_bypass mode!\n");
+	}
+}
+#endif
+
 #ifdef CONFIG_MXC_SPI
 int board_spi_cs_gpio(unsigned bus, unsigned cs)
 {
diff --git a/include/configs/mx6sabresd.h b/include/configs/mx6sabresd.h
index 99d9d4d..70dbf30 100644
--- a/include/configs/mx6sabresd.h
+++ b/include/configs/mx6sabresd.h
@@ -60,6 +60,8 @@
 #define CONFIG_POWER_PFUZE100
 #define CONFIG_POWER_PFUZE100_I2C_ADDR	0x08
 
+#define CONFIG_LDO_BYPASS_CHECK
+
 /* USB Configs */
 #define CONFIG_CMD_USB
 #ifdef CONFIG_CMD_USB
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 10/12] imx:mx6sxsabresd add ldo mode set function
  2015-01-09  8:59 [U-Boot] [PATCH 00/12] imx:mx6 add ldo bypass Peng Fan
                   ` (8 preceding siblings ...)
  2015-01-09  8:59 ` [U-Boot] [PATCH 09/12] imx:mx6sabresd Add ldo_mode_set function Peng Fan
@ 2015-01-09  8:59 ` 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
  11 siblings, 0 replies; 31+ messages in thread
From: Peng Fan @ 2015-01-09  8:59 UTC (permalink / raw)
  To: u-boot

Add ldo_mode_set function. If ldo_bypass is true, it will adjust voltage.
If not, do nothing.

This function is board specific, so implement it in board file.

Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
Signed-off-by: Robin Gong <b38343@freescale.com>
---
 board/freescale/mx6sxsabresd/mx6sxsabresd.c | 50 +++++++++++++++++++++++++++++
 include/configs/mx6sxsabresd.h              |  2 ++
 2 files changed, 52 insertions(+)

diff --git a/board/freescale/mx6sxsabresd/mx6sxsabresd.c b/board/freescale/mx6sxsabresd/mx6sxsabresd.c
index fbf3337..36432c4 100644
--- a/board/freescale/mx6sxsabresd/mx6sxsabresd.c
+++ b/board/freescale/mx6sxsabresd/mx6sxsabresd.c
@@ -196,6 +196,7 @@ static struct i2c_pads_info i2c_pad_info1 = {
 	},
 };
 
+static struct pmic *pfuze;
 int power_init_board(void)
 {
 	struct pmic *p;
@@ -204,6 +205,7 @@ int power_init_board(void)
 	p = pfuze_common_init(I2C_PMIC);
 	if (!p)
 		return -ENODEV;
+	pfuze = p;
 
 	ret = pfuze_mode_init(p, APS_PFM);
 	if (ret < 0)
@@ -218,6 +220,54 @@ int power_init_board(void)
 	return 0;
 }
 
+#ifdef CONFIG_LDO_BYPASS_CHECK
+void ldo_mode_set(int ldo_bypass)
+{
+	unsigned int value;
+	int is_400M;
+	u32 vddarm;
+	struct pmic *p = pfuze;
+
+	if (!p)
+		return;
+
+	/* switch to ldo_bypass mode */
+	if (ldo_bypass) {
+		prep_anatop_bypass();
+		/* decrease VDDARM to 1.275V */
+		pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
+		value &= ~0x3f;
+		value |= PFUZE100_SW1ABC_SETP(12750);
+		pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
+
+		/* decrease VDDSOC to 1.3V */
+		pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
+		value &= ~0x3f;
+		value |= PFUZE100_SW1ABC_SETP(13000);
+		pmic_reg_write(p, PFUZE100_SW1CVOL, value);
+
+		is_400M = set_anatop_bypass(1);
+		if (is_400M)
+			vddarm = PFUZE100_SW1ABC_SETP(10750);
+		else
+			vddarm = PFUZE100_SW1ABC_SETP(11750);
+
+		pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
+		value &= ~0x3f;
+		value |= vddarm;
+		pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
+
+		pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
+		value &= ~0x3f;
+		value |= PFUZE100_SW1ABC_SETP(11750);
+		pmic_reg_write(p, PFUZE100_SW1CVOL, value);
+
+		finish_anatop_bypass();
+		printf("switch to ldo_bypass mode!\n");
+	}
+}
+#endif
+
 #ifdef CONFIG_USB_EHCI_MX6
 #define USB_OTHERREGS_OFFSET	0x800
 #define UCTRL_PWR_POL		(1 << 9)
diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h
index 469d250..d69310e 100644
--- a/include/configs/mx6sxsabresd.h
+++ b/include/configs/mx6sxsabresd.h
@@ -181,6 +181,8 @@
 #define CONFIG_POWER_PFUZE100
 #define CONFIG_POWER_PFUZE100_I2C_ADDR	0x08
 
+#define CONFIG_LDO_BYPASS_CHECK
+
 /* Network */
 #define CONFIG_CMD_PING
 #define CONFIG_CMD_DHCP
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 11/12] imx:mx6qsabreauto add ldo mode init
  2015-01-09  8:59 [U-Boot] [PATCH 00/12] imx:mx6 add ldo bypass Peng Fan
                   ` (9 preceding siblings ...)
  2015-01-09  8:59 ` [U-Boot] [PATCH 10/12] imx:mx6sxsabresd add ldo mode set function Peng Fan
@ 2015-01-09  8:59 ` Peng Fan
  2015-01-09  8:59 ` [U-Boot] [PATCH 12/12] ARM:imx call ldo_mode_set in arch_preboot_os Peng Fan
  11 siblings, 0 replies; 31+ messages in thread
From: Peng Fan @ 2015-01-09  8:59 UTC (permalink / raw)
  To: u-boot

If runs at 1.2GHz, enable ldo, and adjust voltage.
Otherwise, do nothing

Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
Signed-off-by: Robin Gong <b38343@freescale.com>
---
 board/freescale/mx6qsabreauto/mx6qsabreauto.c | 31 +++++++++++++++++++++++++++
 include/configs/mx6qsabreauto.h               |  2 ++
 2 files changed, 33 insertions(+)

diff --git a/board/freescale/mx6qsabreauto/mx6qsabreauto.c b/board/freescale/mx6qsabreauto/mx6qsabreauto.c
index b29ff2b..84ac9b7 100644
--- a/board/freescale/mx6qsabreauto/mx6qsabreauto.c
+++ b/board/freescale/mx6qsabreauto/mx6qsabreauto.c
@@ -29,6 +29,7 @@
 #include <asm/arch/crm_regs.h>
 #include <pca953x.h>
 #include <power/pmic.h>
+#include <power/pfuze100_pmic.h>
 #include "../common/pfuze.h"
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -512,6 +513,7 @@ int board_spi_cs_gpio(unsigned bus, unsigned cs)
 }
 #endif
 
+static struct pmic *pfuze;
 int power_init_board(void)
 {
 	struct pmic *p;
@@ -520,6 +522,7 @@ int power_init_board(void)
 	p = pfuze_common_init(I2C_PMIC);
 	if (!p)
 		return -ENODEV;
+	pfuze = p;
 
 	ret = pfuze_mode_init(p, APS_PFM);
 	if (ret < 0)
@@ -528,6 +531,34 @@ int power_init_board(void)
 	return 0;
 }
 
+#ifdef CONFIG_LDO_BYPASS_CHECK
+void ldo_mode_set(int ldo_bypass)
+{
+	unsigned int value;
+	struct pmic *p = pfuze;
+
+	if (!p)
+		return;
+
+	/* increase VDDARM/VDDSOC to support 1.2G chip */
+	if (check_1_2G()) {
+		ldo_bypass = 0;	/* ldo_enable on 1.2G chip */
+		printf("1.2G chip, increase VDDARM_IN/VDDSOC_IN\n");
+		/* increase VDDARM to 1.425V */
+		pmic_reg_read(p, PFUZE100_SW1ABVOL, &value);
+		value &= ~0x3f;
+		value |= PFUZE100_SW1ABC_SETP(14250);
+		pmic_reg_write(p, PFUZE100_SW1ABVOL, value);
+
+		/* increase VDDSOC to 1.425V */
+		pmic_reg_read(p, PFUZE100_SW1CVOL, &value);
+		value &= ~0x3f;
+		value |= PFUZE100_SW1ABC_SETP(14250);
+		pmic_reg_write(p, PFUZE100_SW1CVOL, value);
+	}
+}
+#endif
+
 #ifdef CONFIG_CMD_BMODE
 static const struct boot_mode board_boot_modes[] = {
 	/* 4 bit bus width */
diff --git a/include/configs/mx6qsabreauto.h b/include/configs/mx6qsabreauto.h
index 51042ca..5b4fb65 100644
--- a/include/configs/mx6qsabreauto.h
+++ b/include/configs/mx6qsabreauto.h
@@ -80,4 +80,6 @@
 #define CONFIG_POWER_PFUZE100
 #define CONFIG_POWER_PFUZE100_I2C_ADDR	0x08
 
+#define CONFIG_LDO_BYPASS_CHECK
+
 #endif                         /* __MX6QSABREAUTO_CONFIG_H */
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 12/12] ARM:imx call ldo_mode_set in arch_preboot_os
  2015-01-09  8:59 [U-Boot] [PATCH 00/12] imx:mx6 add ldo bypass Peng Fan
                   ` (10 preceding siblings ...)
  2015-01-09  8:59 ` [U-Boot] [PATCH 11/12] imx:mx6qsabreauto add ldo mode init Peng Fan
@ 2015-01-09  8:59 ` Peng Fan
  11 siblings, 0 replies; 31+ messages in thread
From: Peng Fan @ 2015-01-09  8:59 UTC (permalink / raw)
  To: u-boot

Current i.MX6 U-Boot does not support device tree. We check
ldo-bypass from dtb file which is loaded when running
`run loadfdt`.

Future work is needed to integrate device tree in uboot. And move
related function invoke in power_init_board.

Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
Signed-off-by: Robin Gong <b38343@freescale.com>
---
 arch/arm/imx-common/cpu.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/imx-common/cpu.c b/arch/arm/imx-common/cpu.c
index 28ccd29..1e518f2 100644
--- a/arch/arm/imx-common/cpu.c
+++ b/arch/arm/imx-common/cpu.c
@@ -204,6 +204,10 @@ u32 get_ahb_clk(void)
 
 void arch_preboot_os(void)
 {
+#if defined(CONFIG_LDO_BYPASS_CHECK)
+	ldo_mode_set(check_ldo_bypass());
+#endif
+
 #if defined(CONFIG_CMD_SATA)
 	sata_stop();
 #if defined(CONFIG_MX6)
-- 
1.8.4

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 03/12] imx:mx6slevk implement power init board
  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
  0 siblings, 0 replies; 31+ messages in thread
From: Stefano Babic @ 2015-02-10 11:01 UTC (permalink / raw)
  To: u-boot

Hi Peng,

On 09/01/2015 09:59, Peng Fan wrote:
> Implement power_init_board and related I2C interface configuration.
> 
> After adding this, uboot can successfully detect and configure pmic.
> 
> "
> U-Boot 2015.01-rc4-00110-g5697113-dirty (Jan 08 2015 - 21:06:44)
> 
> CPU:   Freescale i.MX6SL rev1.0 at 396 MHz
> Reset cause: POR
> Board: MX6SLEVK
> I2C:   ready
> DRAM:  1 GiB
> PMIC:  PFUZE100 ID=0x10
> MMC:   FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2
> "
> 
> Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
> ---
>  board/freescale/mx6slevk/mx6slevk.c | 47 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 47 insertions(+)
> 
> diff --git a/board/freescale/mx6slevk/mx6slevk.c b/board/freescale/mx6slevk/mx6slevk.c
> index 838ea6c..f74b237 100644
> --- a/board/freescale/mx6slevk/mx6slevk.c
> +++ b/board/freescale/mx6slevk/mx6slevk.c
> @@ -13,13 +13,18 @@
>  #include <asm/arch/sys_proto.h>
>  #include <asm/gpio.h>
>  #include <asm/imx-common/iomux-v3.h>
> +#include <asm/imx-common/mxc_i2c.h>
>  #include <asm/imx-common/spi.h>
>  #include <asm/io.h>
>  #include <linux/sizes.h>
>  #include <common.h>
>  #include <fsl_esdhc.h>
> +#include <i2c.h>
>  #include <mmc.h>
>  #include <netdev.h>
> +#include <power/pmic.h>
> +#include <power/pfuze100_pmic.h>
> +#include "../common/pfuze.h"
>  #include <usb.h>
>  #include <usb/ehci-fsl.h>
>  
> @@ -40,6 +45,11 @@ DECLARE_GLOBAL_DATA_PTR;
>  #define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \
>  		      PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
>  
> +#define I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |		\
> +		      PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |	\
> +		      PAD_CTL_DSE_40ohm | PAD_CTL_HYS |		\
> +		      PAD_CTL_ODE | PAD_CTL_SRE_FAST)
> +
>  #define ETH_PHY_RESET	IMX_GPIO_NR(4, 21)
>  
>  int dram_init(void)
> @@ -221,6 +231,39 @@ int board_mmc_init(bd_t *bis)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_SYS_I2C_MXC
> +#define PC	MUX_PAD_CTRL(I2C_PAD_CTRL)
> +/* I2C1 for PMIC */
> +struct i2c_pads_info i2c_pad_info1 = {
> +	.sda = {
> +		.i2c_mode = MX6_PAD_I2C1_SDA__I2C1_SDA | PC,
> +		.gpio_mode = MX6_PAD_I2C1_SDA__GPIO_3_13 | PC,
> +		.gp = IMX_GPIO_NR(3, 13),
> +	},
> +	.scl = {
> +		.i2c_mode = MX6_PAD_I2C1_SCL__I2C1_SCL | PC,
> +		.gpio_mode = MX6_PAD_I2C1_SCL__GPIO_3_12 | PC,
> +		.gp = IMX_GPIO_NR(3, 12),
> +	},
> +};
> +
> +int power_init_board(void)
> +{
> +	struct pmic *p;
> +	unsigned int ret;
> +
> +	p = pfuze_common_init(I2C_PMIC);
> +	if (!p)
> +		return -ENODEV;
> +
> +	ret = pfuze_mode_init(p, APS_PFM);
> +	if (ret < 0)
> +		return -EIO;
> +
> +	return 0;
> +}
> +#endif
> +
>  #ifdef CONFIG_FEC_MXC
>  int board_eth_init(bd_t *bis)
>  {
> @@ -297,6 +340,10 @@ int board_init(void)
>  	/* address of boot parameters */
>  	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
>  
> +#ifdef CONFIG_SYS_I2C_MXC
> +	setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
> +#endif
> +
>  #ifdef	CONFIG_FEC_MXC
>  	setup_fec();
>  #endif
> 

Patches are quite orthogonal: patches 1-3 have nothing to do with the
subject of the patchset (LDO bypass) and can flawlessly be applied.

Best regards,
Stefano Babic

-- 
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 04/12] imx:mx6 update mxc_ccm_reg
  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
  0 siblings, 1 reply; 31+ messages in thread
From: Stefano Babic @ 2015-02-10 11:03 UTC (permalink / raw)
  To: u-boot

Hi Peng,

On 09/01/2015 09:59, Peng Fan wrote:
> Add more register for structure mxc_ccm_reg.
> 
> Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
> ---
>  arch/arm/include/asm/arch-mx6/crm_regs.h | 87 ++++++++++++++++++++++++++++++++
>  1 file changed, 87 insertions(+)
> 
> diff --git a/arch/arm/include/asm/arch-mx6/crm_regs.h b/arch/arm/include/asm/arch-mx6/crm_regs.h
> index 39f3c07..55e1287 100644
> --- a/arch/arm/include/asm/arch-mx6/crm_regs.h
> +++ b/arch/arm/include/asm/arch-mx6/crm_regs.h
> @@ -103,6 +103,93 @@ struct mxc_ccm_reg {
>  	u32 analog_pfd_528_set;
>  	u32 analog_pfd_528_clr;
>  	u32 analog_pfd_528_tog;
> +	u32 reg_1p1;				/* 0x4110 */
> +	u32 reg_1p1_set;			/* 0x4114 */

Even if the offset can be sometimes quite useful, the best reference is
the manual. You see that other fields have no offset in comments, so
please remove them here.

> +	u32 reg_1p1_clr;			/* 0x4118 */
> +	u32 reg_1p1_tog;			/* 0x411c */
> +	u32 reg_3p0;				/* 0x4120 */
> +	u32 reg_3p0_set;			/* 0x4124 */
> +	u32 reg_3p0_clr;			/* 0x4128 */
> +	u32 reg_3p0_tog;			/* 0x412c */
> +	u32 reg_2p5;				/* 0x4130 */
> +	u32 reg_2p5_set;			/* 0x4134 */
> +	u32 reg_2p5_clr;			/* 0x4138 */
> +	u32 reg_2p5_tog;			/* 0x413c */
> +	u32 reg_core;				/* 0x4140 */
> +	u32 reg_core_set;			/* 0x4144 */
> +	u32 reg_core_clr;			/* 0x4148 */
> +	u32 reg_core_tog;			/* 0x414c */
> +	u32 ana_misc0;				/* 0x4150 */
> +	u32 ana_misc0_set;			/* 0x4154 */
> +	u32 ana_misc0_clr;			/* 0x4158 */
> +	u32 ana_misc0_tog;			/* 0x415c */
> +	u32 ana_misc1;				/* 0x4160 */
> +	u32 ana_misc1_set;			/* 0x4164 */
> +	u32 ana_misc1_clr;			/* 0x4168 */
> +	u32 ana_misc1_tog;			/* 0x416c */
> +	u32 ana_misc2;				/* 0x4170 */
> +	u32 ana_misc2_set;			/* 0x4174 */
> +	u32 ana_misc2_clr;			/* 0x4178 */
> +	u32 ana_misc2_tog;			/* 0x417c */
> +	u32 tempsense0;				/* 0x4180 */
> +	u32 tempsense0_set;			/* 0x4184 */
> +	u32 tempsense0_clr;			/* 0x4188 */
> +	u32 tempsense0_tog;			/* 0x418c */
> +	u32 tempsense1;				/* 0x4190 */
> +	u32 tempsense1_set;			/* 0x4194 */
> +	u32 tempsense1_clr;			/* 0x4198 */
> +	u32 tempsense1_tog;			/* 0x419c */
> +	u32 usb1_vbus_detect;			/* 0x41a0 */
> +	u32 usb1_vbus_detect_set;		/* 0x41a4 */
> +	u32 usb1_vbus_detect_clr;		/* 0x41a8 */
> +	u32 usb1_vbus_detect_tog;		/* 0x41ac */
> +	u32 usb1_chrg_detect;			/* 0x41b0 */
> +	u32 usb1_chrg_detect_set;		/* 0x41b4 */
> +	u32 usb1_chrg_detect_clr;		/* 0x41b8 */
> +	u32 usb1_chrg_detect_tog;		/* 0x41bc */
> +	u32 usb1_vbus_det_stat;			/* 0x41c0 */
> +	u32 usb1_vbus_det_stat_set;		/* 0x41c4 */
> +	u32 usb1_vbus_det_stat_clr;		/* 0x41c8 */
> +	u32 usb1_vbus_det_stat_tog;		/* 0x41cc */
> +	u32 usb1_chrg_det_stat;			/* 0x41d0 */
> +	u32 usb1_chrg_det_stat_set;		/* 0x41d4 */
> +	u32 usb1_chrg_det_stat_clr;		/* 0x41d8 */
> +	u32 usb1_chrg_det_stat_tog;		/* 0x41dc */
> +	u32 usb1_loopback;			/* 0x41e0 */
> +	u32 usb1_loopback_set;			/* 0x41e4 */
> +	u32 usb1_loopback_clr;			/* 0x41e8 */
> +	u32 usb1_loopback_tog;			/* 0x41ec */
> +	u32 usb1_misc;				/* 0x41f0 */
> +	u32 usb1_misc_set;			/* 0x41f4 */
> +	u32 usb1_misc_clr;			/* 0x41f8 */
> +	u32 usb1_misc_tog;			/* 0x41fc */
> +	u32 usb2_vbus_detect;			/* 0x4200 */
> +	u32 usb2_vbus_detect_set;		/* 0x4204 */
> +	u32 usb2_vbus_detect_clr;		/* 0x4208 */
> +	u32 usb2_vbus_detect_tog;		/* 0x420c */
> +	u32 usb2_chrg_detect;			/* 0x4210 */
> +	u32 usb2_chrg_detect_set;		/* 0x4214 */
> +	u32 usb2_chrg_detect_clr;		/* 0x4218 */
> +	u32 usb2_chrg_detect_tog;		/* 0x421c */
> +	u32 usb2_vbus_det_stat;			/* 0x4220 */
> +	u32 usb2_vbus_det_stat_set;		/* 0x4224 */
> +	u32 usb2_vbus_det_stat_clr;		/* 0x4228 */
> +	u32 usb2_vbus_det_stat_tog;		/* 0x422c */
> +	u32 usb2_chrg_det_stat;			/* 0x4230 */
> +	u32 usb2_chrg_det_stat_set;		/* 0x4234 */
> +	u32 usb2_chrg_det_stat_clr;		/* 0x4238 */
> +	u32 usb2_chrg_det_stat_tog;		/* 0x423c */
> +	u32 usb2_loopback;			/* 0x4240 */
> +	u32 usb2_loopback_set;			/* 0x4244 */
> +	u32 usb2_loopback_clr;			/* 0x4248 */
> +	u32 usb2_loopback_tog;			/* 0x424c */
> +	u32 usb2_misc;				/* 0x4250 */
> +	u32 usb2_misc_set;			/* 0x4254 */
> +	u32 usb2_misc_clr;			/* 0x4258 */
> +	u32 usb2_misc_tog;			/* 0x425c */
> +	u32 digprog;				/* 0x4260 */
> +	u32 reserved1[7];
> +	u32 digprog_sololite;			/* 0x4280 */
>  };
>  #endif
>  
> 

Best regards,
Stefano Babic


-- 
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass
  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:33   ` Tim Harvey
  1 sibling, 1 reply; 31+ messages in thread
From: Stefano Babic @ 2015-02-10 11:23 UTC (permalink / raw)
  To: u-boot

Hi Peng,

On 09/01/2015 09:59, 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
> 
> 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.
> 
> 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.
> 
> Also add related function prototype in sys_proto.h
> 

Ok - with this explanation, I would try to understand how the changes
can be split. If the feature/change works for several boards, it makes
sense to have it common and general. If it is only for one board, must
flow into the board directory.

It looks like that ldo-bypass is strictly dependent on the board.
Firstly, it must have PMIC, and not all boards have it. Your last sentence:

> 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 looks to me as an item very bound to the board. Could it be
possible to use another pin (I do not know the schematics, I remember
that such as reset pin was fix on previous i.MX) ? If answer is yes, can
these changes be used by other board or are they only for sabresd ?


> Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
> Signed-off-by: Robin Gong <b38343@freescale.com>
> Signed-off-by: Nitin Garg <nitin.garg@freescale.com>
> ---
>  arch/arm/cpu/armv7/mx6/soc.c              | 141 ++++++++++++++++++++++++++++++
>  arch/arm/include/asm/arch-mx6/sys_proto.h |   9 ++
>  2 files changed, 150 insertions(+)
> 
> 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;

mmmhh....global to the module ?

> +
> +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);

I am quite lost. I have searched in kernel (current TOT), and I have not
found such property. Can you help me to understand ?

> +	/*
> +	 * 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;
> +}
> +
> +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.

This enforce my doubts.

> +			 */
> +			printf("Please use imx6q-sabresd-ldo.dtb!\n");

In any case, do not use hard-coded filenames into u-boot. They can change.

> +			hang();
> +		}
> +		result = 1;
> +	}
> +
> +	return result;
> +}
> +
> +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);
> +}
> +
> +void prep_anatop_bypass(void)
> +{
> +	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
> +
> +	arm_orig_podf = readl(&mxc_ccm->cacrr);
> +	/*
> +	 * Downgrade ARM speed to 400Mhz as half of boot 800Mhz before ldo
> +	 * bypassed, also downgrade internal vddarm ldo to 0.975V.
> +	 * VDDARM_IN 0.975V + 125mV = 1.1V < Max(1.3V)
> +	 * otherwise at 800Mhz(i.mx6dl):
> +	 * VDDARM_IN 1.175V + 125mV = 1.3V = Max(1.3V)
> +	 * We need provide enough gap in this case.
> +	 * skip if boot from 400M.
> +	 */
> +	if (!arm_orig_podf)
> +		set_arm_freq_400M(true);
> +#if !defined(CONFIG_MX6DL) && !defined(CONFIG_MX6SX)
> +	set_ldo_voltage(LDO_ARM, 975);
> +#else
> +	set_ldo_voltage(LDO_ARM, 1150);
> +#endif
> +}
> +
> +void set_wdog_reset(struct wdog_regs *wdog)
> +{
> +	u32 reg = readw(&wdog->wcr);
> +	/*
> +	 * use WDOG_B mode to reset external pmic because it's risky for the
> +	 * following watchdog reboot in case of cpu freq at lowest 400Mhz with
> +	 * ldo-bypass mode. Because boot frequency maybe higher 800Mhz i.e. So
> +	 * in ldo-bypass mode watchdog reset will only triger POR reset, not
> +	 * WDOG reset. But below code depends on hardware design, if HW didn't
> +	 * connect WDOG_B pin to external pmic such as i.mx6slevk, we can skip
> +	 * these code since it assumed boot from 400Mhz always.
> +	 */
> +	reg = readw(&wdog->wcr);
> +	reg |= 1 << 3;
> +	/*
> +	 * WDZST bit is write-once only bit. Align this bit in kernel,
> +	 * otherwise kernel code will have no chance to set this bit.
> +	 */
> +	reg |= 1 << 0;
> +	writew(reg, &wdog->wcr);
> +}
> +
> +int set_anatop_bypass(int wdog_reset_pin)
> +{
> +	struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
> +	struct wdog_regs *wdog;
> +	u32 reg = readl(&ccm_regs->reg_core);
> +
> +	/* bypass VDDARM/VDDSOC */
> +	reg = reg | (0x1F << 18) | 0x1F;
> +	writel(reg, &ccm_regs->reg_core);
> +
> +	if (wdog_reset_pin == 2)
> +		wdog = (struct wdog_regs *)WDOG2_BASE_ADDR;
> +	else if (wdog_reset_pin == 1)
> +		wdog = (struct wdog_regs *)WDOG1_BASE_ADDR;
> +	else
> +		return arm_orig_podf;
> +	set_wdog_reset(wdog);
> +	return arm_orig_podf;
> +}
> +
> +void finish_anatop_bypass(void)
> +{
> +	if (!arm_orig_podf)
> +		set_arm_freq_400M(false);
> +}
> +#endif
> +
>  #ifdef CONFIG_IMX_HDMI
>  void imx_enable_hdmi_phy(void)
>  {
> diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h
> index 28ba844..e6f2112 100644
> --- a/arch/arm/include/asm/arch-mx6/sys_proto.h
> +++ b/arch/arm/include/asm/arch-mx6/sys_proto.h
> @@ -28,6 +28,15 @@ const char *get_imx_type(u32 imxtype);
>  unsigned imx_ddr_size(void);
>  void set_chipselect_size(int const);
>  
> +void set_wdog_reset(struct wdog_regs *wdog);
> +#ifdef CONFIG_LDO_BYPASS_CHECK

Why do we need #ifdef ?


> +int check_ldo_bypass(void);
> +int check_1_2G(void);
> +void ldo_mode_set(int ldo_bypass);
> +int set_anatop_bypass(int wdog_reset_pin);
> +void prep_anatop_bypass(void);
> +void finish_anatop_bypass(void);
> +#endif
>  /*
>   * Initializes on-chip ethernet controllers.
>   * to override, implement board_eth_init()
> 

Best regards,
Stefano Babic

-- 
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 05/12] imx:mx6 update fuse_bank0_regs
  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
  0 siblings, 0 replies; 31+ messages in thread
From: Stefano Babic @ 2015-02-10 11:51 UTC (permalink / raw)
  To: u-boot

On 09/01/2015 09:59, Peng Fan wrote:
> Update fuse_bank0_regs structure according reference mannual.
> 
> Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
> ---
>  arch/arm/include/asm/arch-mx6/imx-regs.h | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h
> index c968600..22f371d 100644
> --- a/arch/arm/include/asm/arch-mx6/imx-regs.h
> +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h
> @@ -624,12 +624,16 @@ struct fuse_bank0_regs {
>  	u32	rsvd1[3];
>  	u32	uid_high;
>  	u32	rsvd2[3];
> -	u32	rsvd3[4];
> -	u32	rsvd4[4];
> -	u32	rsvd5[4];
> +	u32	cfg2;
> +	u32	rsvd3[3];
> +	u32	cfg3;
> +	u32	rsvd4[3];
> +	u32	cfg4;
> +	u32	rsvd5[3];
>  	u32	cfg5;
>  	u32	rsvd6[3];
> -	u32	rsvd7[4];
> +	u32	cfg6;
> +	u32	rsvd7[3];
>  };
>  
>  #ifdef CONFIG_MX6SX
> 
Applied to u-boot-imx, thanks !

Best regards,
Stefano Babic

-- 
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 06/12] pmic:pfuze add macro for setting voltage
  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
  0 siblings, 1 reply; 31+ messages in thread
From: Stefano Babic @ 2015-02-10 11:54 UTC (permalink / raw)
  To: u-boot

On 09/01/2015 09:59, Peng Fan wrote:
> "#define PFUZE100_SW1ABC_SETP(x) ((x - 3000) / 250)"
> This macro is for configuring SW1A/B/C Output Voltage easily.
> 
> Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
> ---
>  include/power/pfuze100_pmic.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/include/power/pfuze100_pmic.h b/include/power/pfuze100_pmic.h
> index 7474afb..d304658 100644
> --- a/include/power/pfuze100_pmic.h
> +++ b/include/power/pfuze100_pmic.h
> @@ -61,6 +61,8 @@ enum {
>   * Buck Regulators
>   */
>  
> +#define PFUZE100_SW1ABC_SETP(x)	((x - 3000) / 250)
> +
>  /* SW1A/B/C Output Voltage Configuration */
>  #define SW1x_0_300V 0
>  #define SW1x_0_325V 1
> 

To inform you: patches 1-3 must be rebased and reworked, mainly due to
pmic_mode_init() (you have postpone V2 after discussion about
ldo-bypass). I start applying the 5-6, that contain only new defines.

Applied to u-boot-imx, thanks !

Best regards,
Stefano Babic

-- 
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass
  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:33   ` Tim Harvey
  2015-02-11 10:49     ` Robin Gong
  1 sibling, 1 reply; 31+ messages in thread
From: Tim Harvey @ 2015-02-10 14:33 UTC (permalink / raw)
  To: u-boot

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).

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

>

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

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

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass
  2015-02-10 11:23   ` Stefano Babic
@ 2015-02-10 14:50     ` Tim Harvey
  2015-02-10 14:59       ` Fabio Estevam
  2015-02-11  8:42       ` Stefano Babic
  0 siblings, 2 replies; 31+ messages in thread
From: Tim Harvey @ 2015-02-10 14:50 UTC (permalink / raw)
  To: u-boot

On Tue, Feb 10, 2015 at 3:23 AM, Stefano Babic <sbabic@denx.de> wrote:
>
> Ok - with this explanation, I would try to understand how the changes
> can be split. If the feature/change works for several boards, it makes
> sense to have it common and general. If it is only for one board, must
> flow into the board directory.

It should be common as there are several boards which use PMIC's and can use it.

>
> It looks like that ldo-bypass is strictly dependent on the board.
> Firstly, it must have PMIC, and not all boards have it. Your last sentence:

Any board that has a PMIC capable of regulating VDD_ARM_IN and
VDD_SOC_IN to the setpoints from the IMX6 datasheet can operate in LDO
bypass mode, unless operating at 1.2GHz in which case the datasheet
states that the LDO must be used (not bypassed) 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 looks to me as an item very bound to the board. Could it be
> possible to use another pin (I do not know the schematics, I remember
> that such as reset pin was fix on previous i.MX) ? If answer is yes, can
> these changes be used by other board or are they only for sabresd ?
>

agreed - this is a board-specific pinmux

>
>> Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
>> Signed-off-by: Robin Gong <b38343@freescale.com>
>> Signed-off-by: Nitin Garg <nitin.garg@freescale.com>
>> ---
>>  arch/arm/cpu/armv7/mx6/soc.c              | 141 ++++++++++++++++++++++++++++++
>>  arch/arm/include/asm/arch-mx6/sys_proto.h |   9 ++
>>  2 files changed, 150 insertions(+)
>>
>> 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;
>
> mmmhh....global to the module ?
>
>> +
>> +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);
>
> I am quite lost. I have searched in kernel (current TOT), and I have not
> found such property. Can you help me to understand ?

Right - you won't find it because its a Freescale vendor kernel
implementation only. A hack if you ask me to avoid having to doing
ldo-byapss the right way.

Here are the threads that I know of regarding ldo-bypass in the
kernel, where it needs to be:

https://lkml.org/lkml/2014/12/18/255
https://lkml.org/lkml/2014/10/31/3

Peng,

I think what you are trying to do here is to put the anatop regulators
in bypass mode so that the Freescale vendor kernel leaves them
bypassed (which is what the 3.10.x based vendor kernels supporting
device-tree at http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git
do). This is what the Freescale vendor U-Boot does and so they have
created a horrible dependence between kernel and bootloader.

Instead you may be interested in what I did for our BSP's that use the
Freescale vendor kernel. Instead of touching U-Boot, I look for the
fsl,ldo-bypass node in the kernel and enable it just like their
bootloader would have:
https://github.com/Gateworks/linux-imx6/commit/a1af6ac6f00b4da7c8a5656e8ff093d4ab5cadee

That said, I would love to see some help getting IMX6 ldo-bypass
support upstream. All of our boards have an external PMIC and are
capable of bypass mode. Bypassing the LDO on such boards really helps
reduce overall board power consumption as well as move heat from the
CPU to the PMIC.

Tim

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass
  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
  1 sibling, 1 reply; 31+ messages in thread
From: Fabio Estevam @ 2015-02-10 14:59 UTC (permalink / raw)
  To: u-boot

Hi Tim,

On Tue, Feb 10, 2015 at 12:50 PM, Tim Harvey <tharvey@gateworks.com> wrote:

> I think what you are trying to do here is to put the anatop regulators
> in bypass mode so that the Freescale vendor kernel leaves them
> bypassed (which is what the 3.10.x based vendor kernels supporting
> device-tree at http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git
> do). This is what the Freescale vendor U-Boot does and so they have
> created a horrible dependence between kernel and bootloader.

I agree.

> Instead you may be interested in what I did for our BSP's that use the
> Freescale vendor kernel. Instead of touching U-Boot, I look for the
> fsl,ldo-bypass node in the kernel and enable it just like their
> bootloader would have:
> https://github.com/Gateworks/linux-imx6/commit/a1af6ac6f00b4da7c8a5656e8ff093d4ab5cadee
>
> That said, I would love to see some help getting IMX6 ldo-bypass
> support upstream. All of our boards have an external PMIC and are

I want to help you on upstreaming ldo-bypass support in the kernel, Tim.

Can we do like your approach, but defining
imx_anatop_ldobypass_enable() inside
rivers/regulator/anatop-regulator.c instead?

Regards,

Fabio Estevam

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass
  2015-02-10 14:59       ` Fabio Estevam
@ 2015-02-10 15:29         ` Tim Harvey
  0 siblings, 0 replies; 31+ messages in thread
From: Tim Harvey @ 2015-02-10 15:29 UTC (permalink / raw)
  To: u-boot

On Tue, Feb 10, 2015 at 6:59 AM, Fabio Estevam <festevam@gmail.com> wrote:
> Hi Tim,
>
> On Tue, Feb 10, 2015 at 12:50 PM, Tim Harvey <tharvey@gateworks.com> wrote:
>
>> I think what you are trying to do here is to put the anatop regulators
>> in bypass mode so that the Freescale vendor kernel leaves them
>> bypassed (which is what the 3.10.x based vendor kernels supporting
>> device-tree at http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git
>> do). This is what the Freescale vendor U-Boot does and so they have
>> created a horrible dependence between kernel and bootloader.
>
> I agree.
>
>> Instead you may be interested in what I did for our BSP's that use the
>> Freescale vendor kernel. Instead of touching U-Boot, I look for the
>> fsl,ldo-bypass node in the kernel and enable it just like their
>> bootloader would have:
>> https://github.com/Gateworks/linux-imx6/commit/a1af6ac6f00b4da7c8a5656e8ff093d4ab5cadee
>>
>> That said, I would love to see some help getting IMX6 ldo-bypass
>> support upstream. All of our boards have an external PMIC and are
>
> I want to help you on upstreaming ldo-bypass support in the kernel, Tim.

Great!

>
> Can we do like your approach, but defining
> imx_anatop_ldobypass_enable() inside
> rivers/regulator/anatop-regulator.c instead?

Yes, I think that makes sense. I hope to be able to get back to this
in a couple of weeks after a round of U-Boot updates that are next on
my list.

Thanks,

Tim

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 06/12] pmic:pfuze add macro for setting voltage
  2015-02-10 11:54   ` Stefano Babic
@ 2015-02-11  2:06     ` Peng Fan
  0 siblings, 0 replies; 31+ messages in thread
From: Peng Fan @ 2015-02-11  2:06 UTC (permalink / raw)
  To: u-boot

Hi, Stefano

On 2/10/2015 7:54 PM, Stefano Babic wrote:
> On 09/01/2015 09:59, Peng Fan wrote:
>> "#define PFUZE100_SW1ABC_SETP(x) ((x - 3000) / 250)"
>> This macro is for configuring SW1A/B/C Output Voltage easily.
>>
>> Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
>> ---
>>   include/power/pfuze100_pmic.h | 2 ++
>>   1 file changed, 2 insertions(+)
>>
>> diff --git a/include/power/pfuze100_pmic.h b/include/power/pfuze100_pmic.h
>> index 7474afb..d304658 100644
>> --- a/include/power/pfuze100_pmic.h
>> +++ b/include/power/pfuze100_pmic.h
>> @@ -61,6 +61,8 @@ enum {
>>    * Buck Regulators
>>    */
>>   
>> +#define PFUZE100_SW1ABC_SETP(x)	((x - 3000) / 250)
>> +
>>   /* SW1A/B/C Output Voltage Configuration */
>>   #define SW1x_0_300V 0
>>   #define SW1x_0_325V 1
>>
> To inform you: patches 1-3 must be rebased and reworked, mainly due to
> pmic_mode_init() (you have postpone V2 after discussion about
> ldo-bypass). I start applying the 5-6, that contain only new defines.
I'll rebase patches 1-3 and make the three patches a single v2 patch set.
>
> Applied to u-boot-imx, thanks !
>
> Best regards,
> Stefano Babic
>
Thanks,
Peng.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 04/12] imx:mx6 update mxc_ccm_reg
  2015-02-10 11:03   ` Stefano Babic
@ 2015-02-11  2:19     ` Peng Fan
  0 siblings, 0 replies; 31+ messages in thread
From: Peng Fan @ 2015-02-11  2:19 UTC (permalink / raw)
  To: u-boot

Hi, Stefano

On 2/10/2015 7:03 PM, Stefano Babic wrote:
> Hi Peng,
>
> On 09/01/2015 09:59, Peng Fan wrote:
>> Add more register for structure mxc_ccm_reg.
>>
>> Signed-off-by: Peng Fan <Peng.Fan@freescale.com>
>> ---
>>   arch/arm/include/asm/arch-mx6/crm_regs.h | 87 ++++++++++++++++++++++++++++++++
>>   1 file changed, 87 insertions(+)
>>
>> diff --git a/arch/arm/include/asm/arch-mx6/crm_regs.h b/arch/arm/include/asm/arch-mx6/crm_regs.h
>> index 39f3c07..55e1287 100644
>> --- a/arch/arm/include/asm/arch-mx6/crm_regs.h
>> +++ b/arch/arm/include/asm/arch-mx6/crm_regs.h
>> @@ -103,6 +103,93 @@ struct mxc_ccm_reg {
>>   	u32 analog_pfd_528_set;
>>   	u32 analog_pfd_528_clr;
>>   	u32 analog_pfd_528_tog;
>> +	u32 reg_1p1;				/* 0x4110 */
>> +	u32 reg_1p1_set;			/* 0x4114 */
> Even if the offset can be sometimes quite useful, the best reference is
> the manual. You see that other fields have no offset in comments, so
> please remove them here.
Ok. I'll remove the offset here.
>
>> +	u32 reg_1p1_clr;			/* 0x4118 */
>> +	u32 reg_1p1_tog;			/* 0x411c */
>> +	u32 reg_3p0;				/* 0x4120 */
>> +	u32 reg_3p0_set;			/* 0x4124 */
>> +	u32 reg_3p0_clr;			/* 0x4128 */
>> +	u32 reg_3p0_tog;			/* 0x412c */
>> +	u32 reg_2p5;				/* 0x4130 */
>> +	u32 reg_2p5_set;			/* 0x4134 */
>> +	u32 reg_2p5_clr;			/* 0x4138 */
>> +	u32 reg_2p5_tog;			/* 0x413c */
>> +	u32 reg_core;				/* 0x4140 */
>> +	u32 reg_core_set;			/* 0x4144 */
>> +	u32 reg_core_clr;			/* 0x4148 */
>> +	u32 reg_core_tog;			/* 0x414c */
>> +	u32 ana_misc0;				/* 0x4150 */
>> +	u32 ana_misc0_set;			/* 0x4154 */
>> +	u32 ana_misc0_clr;			/* 0x4158 */
>> +	u32 ana_misc0_tog;			/* 0x415c */
>> +	u32 ana_misc1;				/* 0x4160 */
>> +	u32 ana_misc1_set;			/* 0x4164 */
>> +	u32 ana_misc1_clr;			/* 0x4168 */
>> +	u32 ana_misc1_tog;			/* 0x416c */
>> +	u32 ana_misc2;				/* 0x4170 */
>> +	u32 ana_misc2_set;			/* 0x4174 */
>> +	u32 ana_misc2_clr;			/* 0x4178 */
>> +	u32 ana_misc2_tog;			/* 0x417c */
>> +	u32 tempsense0;				/* 0x4180 */
>> +	u32 tempsense0_set;			/* 0x4184 */
>> +	u32 tempsense0_clr;			/* 0x4188 */
>> +	u32 tempsense0_tog;			/* 0x418c */
>> +	u32 tempsense1;				/* 0x4190 */
>> +	u32 tempsense1_set;			/* 0x4194 */
>> +	u32 tempsense1_clr;			/* 0x4198 */
>> +	u32 tempsense1_tog;			/* 0x419c */
>> +	u32 usb1_vbus_detect;			/* 0x41a0 */
>> +	u32 usb1_vbus_detect_set;		/* 0x41a4 */
>> +	u32 usb1_vbus_detect_clr;		/* 0x41a8 */
>> +	u32 usb1_vbus_detect_tog;		/* 0x41ac */
>> +	u32 usb1_chrg_detect;			/* 0x41b0 */
>> +	u32 usb1_chrg_detect_set;		/* 0x41b4 */
>> +	u32 usb1_chrg_detect_clr;		/* 0x41b8 */
>> +	u32 usb1_chrg_detect_tog;		/* 0x41bc */
>> +	u32 usb1_vbus_det_stat;			/* 0x41c0 */
>> +	u32 usb1_vbus_det_stat_set;		/* 0x41c4 */
>> +	u32 usb1_vbus_det_stat_clr;		/* 0x41c8 */
>> +	u32 usb1_vbus_det_stat_tog;		/* 0x41cc */
>> +	u32 usb1_chrg_det_stat;			/* 0x41d0 */
>> +	u32 usb1_chrg_det_stat_set;		/* 0x41d4 */
>> +	u32 usb1_chrg_det_stat_clr;		/* 0x41d8 */
>> +	u32 usb1_chrg_det_stat_tog;		/* 0x41dc */
>> +	u32 usb1_loopback;			/* 0x41e0 */
>> +	u32 usb1_loopback_set;			/* 0x41e4 */
>> +	u32 usb1_loopback_clr;			/* 0x41e8 */
>> +	u32 usb1_loopback_tog;			/* 0x41ec */
>> +	u32 usb1_misc;				/* 0x41f0 */
>> +	u32 usb1_misc_set;			/* 0x41f4 */
>> +	u32 usb1_misc_clr;			/* 0x41f8 */
>> +	u32 usb1_misc_tog;			/* 0x41fc */
>> +	u32 usb2_vbus_detect;			/* 0x4200 */
>> +	u32 usb2_vbus_detect_set;		/* 0x4204 */
>> +	u32 usb2_vbus_detect_clr;		/* 0x4208 */
>> +	u32 usb2_vbus_detect_tog;		/* 0x420c */
>> +	u32 usb2_chrg_detect;			/* 0x4210 */
>> +	u32 usb2_chrg_detect_set;		/* 0x4214 */
>> +	u32 usb2_chrg_detect_clr;		/* 0x4218 */
>> +	u32 usb2_chrg_detect_tog;		/* 0x421c */
>> +	u32 usb2_vbus_det_stat;			/* 0x4220 */
>> +	u32 usb2_vbus_det_stat_set;		/* 0x4224 */
>> +	u32 usb2_vbus_det_stat_clr;		/* 0x4228 */
>> +	u32 usb2_vbus_det_stat_tog;		/* 0x422c */
>> +	u32 usb2_chrg_det_stat;			/* 0x4230 */
>> +	u32 usb2_chrg_det_stat_set;		/* 0x4234 */
>> +	u32 usb2_chrg_det_stat_clr;		/* 0x4238 */
>> +	u32 usb2_chrg_det_stat_tog;		/* 0x423c */
>> +	u32 usb2_loopback;			/* 0x4240 */
>> +	u32 usb2_loopback_set;			/* 0x4244 */
>> +	u32 usb2_loopback_clr;			/* 0x4248 */
>> +	u32 usb2_loopback_tog;			/* 0x424c */
>> +	u32 usb2_misc;				/* 0x4250 */
>> +	u32 usb2_misc_set;			/* 0x4254 */
>> +	u32 usb2_misc_clr;			/* 0x4258 */
>> +	u32 usb2_misc_tog;			/* 0x425c */
>> +	u32 digprog;				/* 0x4260 */
>> +	u32 reserved1[7];
>> +	u32 digprog_sololite;			/* 0x4280 */
>>   };
>>   #endif
>>   
>>
> Best regards,
> Stefano Babic
>
>
Thanks,
Peng.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass
  2015-02-10 14:50     ` Tim Harvey
  2015-02-10 14:59       ` Fabio Estevam
@ 2015-02-11  8:42       ` Stefano Babic
  1 sibling, 0 replies; 31+ messages in thread
From: Stefano Babic @ 2015-02-11  8:42 UTC (permalink / raw)
  To: u-boot

Hi Tim,

On 10/02/2015 15:50, Tim Harvey wrote:
> On Tue, Feb 10, 2015 at 3:23 AM, Stefano Babic <sbabic@denx.de> wrote:
>>
>> Ok - with this explanation, I would try to understand how the changes
>> can be split. If the feature/change works for several boards, it makes
>> sense to have it common and general. If it is only for one board, must
>> flow into the board directory.
> 
> It should be common as there are several boards which use PMIC's and can use it.
> 

Fully agree.


>> I am quite lost. I have searched in kernel (current TOT), and I have not
>> found such property. Can you help me to understand ?
> 
> Right - you won't find it because its a Freescale vendor kernel
> implementation only. A hack if you ask me to avoid having to doing
> ldo-byapss the right way.

Exactly, this cannot flow into mainline.

> 
> Here are the threads that I know of regarding ldo-bypass in the
> kernel, where it needs to be:
> 
> https://lkml.org/lkml/2014/12/18/255
> https://lkml.org/lkml/2014/10/31/3

Thanks for pointing out !

> 
> Peng,
> 
> I think what you are trying to do here is to put the anatop regulators
> in bypass mode so that the Freescale vendor kernel leaves them
> bypassed (which is what the 3.10.x based vendor kernels supporting
> device-tree at http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git
> do). This is what the Freescale vendor U-Boot does and so they have
> created a horrible dependence between kernel and bootloader.
> 

You are perfectly right.

> Instead you may be interested in what I did for our BSP's that use the
> Freescale vendor kernel. Instead of touching U-Boot, I look for the
> fsl,ldo-bypass node in the kernel and enable it just like their
> bootloader would have:
> https://github.com/Gateworks/linux-imx6/commit/a1af6ac6f00b4da7c8a5656e8ff093d4ab5cadee
> 

Thanks - you are on the right direction ;-)

Best regards,
Stefano

-- 
=====================================================================
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic at denx.de
=====================================================================

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass
  2015-02-10 14:33   ` Tim Harvey
@ 2015-02-11 10:49     ` Robin Gong
  2015-02-11 15:47       ` Tim Harvey
  0 siblings, 1 reply; 31+ messages in thread
From: Robin Gong @ 2015-02-11 10:49 UTC (permalink / raw)
  To: u-boot

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

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass
  2015-02-11 10:49     ` Robin Gong
@ 2015-02-11 15:47       ` Tim Harvey
  2015-02-13  0:08         ` Tim Harvey
  2015-02-13  8:16         ` Robin Gong
  0 siblings, 2 replies; 31+ messages in thread
From: Tim Harvey @ 2015-02-11 15:47 UTC (permalink / raw)
  To: u-boot

On Wed, Feb 11, 2015 at 2:49 AM, Robin Gong <b38343@freescale.com> wrote:
<snip>
>>
>> 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.

Hi Robin,

I understand that configuring WDOG_B external reset must be used when
LDO bypass is used. This should be done in the kernel but you can also
set this pinmux up in uboot in the board-specific init.

If your kernel is providing the PMIC driver and cpufreq driver that
alter the cpu core frequencies it must also be configuring pinmux so
that WDOG_B gets routed to the pin that connects to the PMIC so any
reset based on that wdog (SRS or timeout) issues a hard reset to the
PMIC. Failure to do so is a kernel bug. I believe this is done
properly in the Freescale kernel for the reference boards.

If you are trying to take care of an issue caused by a watchdog reset
(SRS or timeout) not properly resetting a PMIC (ie perhaps a PCB
errata where signal doesn't go to the PMIC) then you should probably
simply set the PMIC rails where they need to be for the 800MHz
operation in the bootloader and not muck with the CPU frequency.
Honestly, if your PMIC rails are too low for 800MHz on powerup your
bootloader may not be stable anyway right? Note that the operating
setpoints have the same SOC voltage for both 792MHz and 396MHz, its
only the ARM voltage that is lower for 396 vs 792 and chances are your
not going to have an issue just in the bootloader at that point.

<snip>
>>
>> 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....

I just don't see the point in having the CPU frequency changed in the
bootloader - leave this up to the OS kernel. I don't think any of this
patch should go into mainline uboot.

I think my kernel patch I referenced provides you with a simple kernel
solution that de-couples ldo-bypass completely from the bootloader.

<snip>
>>
>> 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.

Are you saying there is an IMX6 variant that powers up per eFUSE
settings at 1.2GHz? The IMX6QDLRM efuse settings I'm looking at just
have two power-up frequency options: 392MHz and 792MHz.

In my opinion, your PMIC should be setting VDD_ARM and VDD_SOC at the
necessary voltages for what the CPU is currently running at, in the
bootloader. Its up to your OS to properly control this to its needs
later. Again, if for some reason (hardware errata) you have a
situation where the PMIC maybe didn't get reset and the board powers
up into the bootloader at a frequency higher than the rails are set
to, then simply set its rails to where they need to be for the freq
your running at in the bootloader.

>> > +
>> > +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.

Too much complexity in my opinion for the power reduction benefits
while in the bootloader. Leave ldo-bypass out of the bootloader and
you won't have to bother with this. The IMX6 can handle a max of 1.3V
on VDD_ARM_IN and VDD_SOC_IN (and 1.5V on the output side of the LDO).
So you can simply set your PMIC in the bootloader to something between
that and 1.175v and be done with it right?

>> 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 doesn't belong in uboot. It was wrong for Freescale to create a
dependence between the bootloader and the kernel when it is so easy to
avoid.

I don't think any of this particular patch should go into mainline uboot.

Regards,

Tim

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass
  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
  1 sibling, 1 reply; 31+ messages in thread
From: Tim Harvey @ 2015-02-13  0:08 UTC (permalink / raw)
  To: u-boot

On Wed, Feb 11, 2015 at 7:47 AM, Tim Harvey <tharvey@gateworks.com> wrote:
> On Wed, Feb 11, 2015 at 2:49 AM, Robin Gong <b38343@freescale.com> wrote:
> <snip>
>>>
>>> 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.
>
> Hi Robin,
>
> I understand that configuring WDOG_B external reset must be used when
> LDO bypass is used. This should be done in the kernel but you can also
> set this pinmux up in uboot in the board-specific init.
>
> If your kernel is providing the PMIC driver and cpufreq driver that
> alter the cpu core frequencies it must also be configuring pinmux so
> that WDOG_B gets routed to the pin that connects to the PMIC so any
> reset based on that wdog (SRS or timeout) issues a hard reset to the
> PMIC. Failure to do so is a kernel bug. I believe this is done
> properly in the Freescale kernel for the reference boards.
>
> If you are trying to take care of an issue caused by a watchdog reset
> (SRS or timeout) not properly resetting a PMIC (ie perhaps a PCB
> errata where signal doesn't go to the PMIC) then you should probably
> simply set the PMIC rails where they need to be for the 800MHz
> operation in the bootloader and not muck with the CPU frequency.
> Honestly, if your PMIC rails are too low for 800MHz on powerup your
> bootloader may not be stable anyway right? Note that the operating
> setpoints have the same SOC voltage for both 792MHz and 396MHz, its
> only the ARM voltage that is lower for 396 vs 792 and chances are your
> not going to have an issue just in the bootloader at that point.
>

Robin,

The issue your describing was interesting to me and I ran some tests
and found that on a board with no reset to the PMIC, an IMX6Q CPU,
ldo-bypass enabled, and the CPU freq set to 400MHz (such that VDD_ARM
rail set to 0.960V for 400MHz operation) the chip does not even come
out of reset (ie when SRS is set in the watchdog controller). So I
don't really see any ability to work around this in bootloader
software since you won't get there in this case.

Possible solutions I can think of for boards without a PMIC reset is
to either blow the eFUSE so the chip comes up in 400MHz or in the
kernel never allow the VDD_ARM or VDD_SOC rail to go below where they
need to be for CPU startup (the only one that does is VDD_ARM) or
before soft-reboot make sure the cpufreq is at 800MHz or above (which
must be done at higher levels before single-cpu mode in
machine_restart). This also does not deal with the case of a watchdog
reset and/or a crash handler.

Are you findings different?

Tim

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass
  2015-02-13  0:08         ` Tim Harvey
@ 2015-02-13  7:20           ` Robin Gong
  0 siblings, 0 replies; 31+ messages in thread
From: Robin Gong @ 2015-02-13  7:20 UTC (permalink / raw)
  To: u-boot

On Thu, Feb 12, 2015 at 04:08:51PM -0800, Tim Harvey wrote:
> On Wed, Feb 11, 2015 at 7:47 AM, Tim Harvey <tharvey@gateworks.com> wrote:
> > On Wed, Feb 11, 2015 at 2:49 AM, Robin Gong <b38343@freescale.com> wrote:
> > <snip>
> >>>
> >>> 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.
> >
> > Hi Robin,
> >
> > I understand that configuring WDOG_B external reset must be used when
> > LDO bypass is used. This should be done in the kernel but you can also
> > set this pinmux up in uboot in the board-specific init.
> >
> > If your kernel is providing the PMIC driver and cpufreq driver that
> > alter the cpu core frequencies it must also be configuring pinmux so
> > that WDOG_B gets routed to the pin that connects to the PMIC so any
> > reset based on that wdog (SRS or timeout) issues a hard reset to the
> > PMIC. Failure to do so is a kernel bug. I believe this is done
> > properly in the Freescale kernel for the reference boards.
> >
> > If you are trying to take care of an issue caused by a watchdog reset
> > (SRS or timeout) not properly resetting a PMIC (ie perhaps a PCB
> > errata where signal doesn't go to the PMIC) then you should probably
> > simply set the PMIC rails where they need to be for the 800MHz
> > operation in the bootloader and not muck with the CPU frequency.
> > Honestly, if your PMIC rails are too low for 800MHz on powerup your
> > bootloader may not be stable anyway right? Note that the operating
> > setpoints have the same SOC voltage for both 792MHz and 396MHz, its
> > only the ARM voltage that is lower for 396 vs 792 and chances are your
> > not going to have an issue just in the bootloader at that point.
> >
> 
> Robin,
> 
> The issue your describing was interesting to me and I ran some tests
> and found that on a board with no reset to the PMIC, an IMX6Q CPU,
> ldo-bypass enabled, and the CPU freq set to 400MHz (such that VDD_ARM
> rail set to 0.960V for 400MHz operation) the chip does not even come
> out of reset (ie when SRS is set in the watchdog controller). So I
> don't really see any ability to work around this in bootloader
> software since you won't get there in this case.
Yes, ldo-bypass mode depends on reset PMIC while reboot happen. But even on
this feature supported boards, we'd better provide warm reset in ldo-enable
mode,for example, warm reset can keep printed log in DDR while system crash
in last time and trigger watchdog reset. Someone may use DCDC instead of PMIC,
or some board didn't connect WDOG_B reset with PMIC, have to use ldo-enable
mode.
> 
> Possible solutions I can think of for boards without a PMIC reset is
> to either blow the eFUSE so the chip comes up in 400MHz or in the
> kernel never allow the VDD_ARM or VDD_SOC rail to go below where they
> need to be for CPU startup (the only one that does is VDD_ARM) or
> before soft-reboot make sure the cpufreq is at 800MHz or above (which
> must be done at higher levels before single-cpu mode in
> machine_restart). This also does not deal with the case of a watchdog
> reset and/or a crash handler.
> 
Yes, absolutely. But we suggest connecting PMIC reset pin with WDOG_B or just
use ldo-enable mode if they are not very care of power number.
> Are you findings different?
> 
> Tim

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass
  2015-02-11 15:47       ` Tim Harvey
  2015-02-13  0:08         ` Tim Harvey
@ 2015-02-13  8:16         ` Robin Gong
  2015-02-24 15:56           ` Tim Harvey
  1 sibling, 1 reply; 31+ messages in thread
From: Robin Gong @ 2015-02-13  8:16 UTC (permalink / raw)
  To: u-boot

On Wed, Feb 11, 2015 at 07:47:57AM -0800, Tim Harvey wrote:
> On Wed, Feb 11, 2015 at 2:49 AM, Robin Gong <b38343@freescale.com> wrote:
> <snip>
> >>
> >> 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.
> 
> Hi Robin,
> 
> I understand that configuring WDOG_B external reset must be used when
> LDO bypass is used. This should be done in the kernel but you can also
> set this pinmux up in uboot in the board-specific init.
> 
> If your kernel is providing the PMIC driver and cpufreq driver that
> alter the cpu core frequencies it must also be configuring pinmux so
> that WDOG_B gets routed to the pin that connects to the PMIC so any
> reset based on that wdog (SRS or timeout) issues a hard reset to the
> PMIC. Failure to do so is a kernel bug. I believe this is done
> properly in the Freescale kernel for the reference boards.
>
pinmux is not enough. WDT bit of WDOGx_WCR need to be taken care of if you want
to enable WDOG_B pin reset function. But unfortunately the current wdog driver
of kernel not touch this write-once bit. To limit the impact from kernel, set
this bit in u-boot.
> If you are trying to take care of an issue caused by a watchdog reset
> (SRS or timeout) not properly resetting a PMIC (ie perhaps a PCB
> errata where signal doesn't go to the PMIC) then you should probably
> simply set the PMIC rails where they need to be for the 800MHz
> operation in the bootloader and not muck with the CPU frequency.
> Honestly, if your PMIC rails are too low for 800MHz on powerup your
> bootloader may not be stable anyway right? Note that the operating
> setpoints have the same SOC voltage for both 792MHz and 396MHz, its
> only the ARM voltage that is lower for 396 vs 792 and chances are your
> not going to have an issue just in the bootloader at that point.
> 
As you saw in another mail, bootloader is too late. It'll hang in ROM code.
> <snip>
> >>
> >> 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....
> 
> I just don't see the point in having the CPU frequency changed in the
> bootloader - leave this up to the OS kernel. I don't think any of this
> patch should go into mainline uboot.
> 
> I think my kernel patch I referenced provides you with a simple kernel
> solution that de-couples ldo-bypass completely from the bootloader.
> 
Can you please share me the patch link? Thanks.
> <snip>
> >>
> >> 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.
> 
> Are you saying there is an IMX6 variant that powers up per eFUSE
> settings at 1.2GHz? The IMX6QDLRM efuse settings I'm looking at just
> have two power-up frequency options: 392MHz and 792MHz.
> 
Sorry, I mean max frequency(SPEED_GRADING[1:0]), not power-up frequency. 
> In my opinion, your PMIC should be setting VDD_ARM and VDD_SOC at the
> necessary voltages for what the CPU is currently running at, in the
> bootloader. Its up to your OS to properly control this to its needs
> later. Again, if for some reason (hardware errata) you have a
> situation where the PMIC maybe didn't get reset and the board powers
> up into the bootloader at a frequency higher than the rails are set
> to, then simply set its rails to where they need to be for the freq
> your running at in the bootloader.
> 
> >> > +
> >> > +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.
> 
> Too much complexity in my opinion for the power reduction benefits
> while in the bootloader. Leave ldo-bypass out of the bootloader and
> you won't have to bother with this. The IMX6 can handle a max of 1.3V
> on VDD_ARM_IN and VDD_SOC_IN (and 1.5V on the output side of the LDO).
> So you can simply set your PMIC in the bootloader to something between
> that and 1.175v and be done with it right?
> 
Not for power reduction, just for match with the voltage setting which data
sheet saying in any time or any narrow timing window. Have to set VDDRAM_IN
1.3v for 800Mhz(VDDARM 1.175v) before ldo-bypass mode switched. And set
VDDARM_IN to 1.175v after ldo-bypass mode switched. But in the narrow window
which VDDARM_IN from 1.3v to 1.175v with ldo-bypass mode enabled. The 1.3v
plus power ripple may beyond the max volage.
> >> 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 doesn't belong in uboot. It was wrong for Freescale to create a
> dependence between the bootloader and the kernel when it is so easy to
> avoid.
> 
> I don't think any of this particular patch should go into mainline uboot.
> 
Tim, thanks for your reviewing, understood your concerning. Looks it's better
done in kernel.
> Regards,
> 
> Tim

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 07/12] imx:mx6 Support LDO bypass
  2015-02-13  8:16         ` Robin Gong
@ 2015-02-24 15:56           ` Tim Harvey
  0 siblings, 0 replies; 31+ messages in thread
From: Tim Harvey @ 2015-02-24 15:56 UTC (permalink / raw)
  To: u-boot

On Fri, Feb 13, 2015 at 12:16 AM, Robin Gong <b38343@freescale.com> wrote:
> On Wed, Feb 11, 2015 at 07:47:57AM -0800, Tim Harvey wrote:
>> On Wed, Feb 11, 2015 at 2:49 AM, Robin Gong <b38343@freescale.com> wrote:
>> <snip>
>> >>
>> >> 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.
>>
>> Hi Robin,
>>
>> I understand that configuring WDOG_B external reset must be used when
>> LDO bypass is used. This should be done in the kernel but you can also
>> set this pinmux up in uboot in the board-specific init.
>>
>> If your kernel is providing the PMIC driver and cpufreq driver that
>> alter the cpu core frequencies it must also be configuring pinmux so
>> that WDOG_B gets routed to the pin that connects to the PMIC so any
>> reset based on that wdog (SRS or timeout) issues a hard reset to the
>> PMIC. Failure to do so is a kernel bug. I believe this is done
>> properly in the Freescale kernel for the reference boards.
>>
> pinmux is not enough. WDT bit of WDOGx_WCR need to be taken care of if you want
> to enable WDOG_B pin reset function. But unfortunately the current wdog driver
> of kernel not touch this write-once bit. To limit the impact from kernel, set
> this bit in u-boot.

Hi Robin,

'To limit the impact from kernel, set this bit in u-boot' indicates
that you are trying to create a u-boot and kernel dependence on each
other which is a bad idea. The kernel should take care of everything
it needs without making assumptions on what the bootloader did.

You are correct in that the current imx2_wdt.c does not 'set' the
write-once WCR bit to enable the external reset but it does seem funny
to me that Freescale decided to patch system.c's mxc_restart
(http://git.freescale.com/git/cgit.cgi/imx/linux-2.6-imx.git/commit/arch/arm/mach-imx/system.c?h=imx_3.10.53_1.1.0_ga&id=ee07b144e1adff13d262e7f353f5804e3c2d3e06)
to try to deal with the machine_restart case but did not patch
imx2_wdt.c to deal with the watchdog timeout case.

Wouldn't these boards also hang when reset from a watchdog timeout
when using ldo-enabled and CPU at 397Mhz. It seems to me that you should
also be patching imx2_wdt.c to set WCR for that case.

>> If you are trying to take care of an issue caused by a watchdog reset
>> (SRS or timeout) not properly resetting a PMIC (ie perhaps a PCB
>> errata where signal doesn't go to the PMIC) then you should probably
>> simply set the PMIC rails where they need to be for the 800MHz
>> operation in the bootloader and not muck with the CPU frequency.
>> Honestly, if your PMIC rails are too low for 800MHz on powerup your
>> bootloader may not be stable anyway right? Note that the operating
>> setpoints have the same SOC voltage for both 792MHz and 396MHz, its
>> only the ARM voltage that is lower for 396 vs 792 and chances are your
>> not going to have an issue just in the bootloader at that point.
>>
> As you saw in another mail, bootloader is too late. It'll hang in ROM code.
>>
<snip>
>>
> Can you please share me the patch link? Thanks.

The link was further up in the thread in response to Peng:

Instead of touching U-Boot, in my 'Freescale' kernel I look for the
fsl,ldo-bypass node in the kernel init and enable it just like their
bootloader would have:

https://github.com/Gateworks/linux-imx6/commit/a1af6ac6f00b4da7c8a5656e8ff093d4ab5cadee

It is still not good to rely on the fsl,ldo-bypass property to be set
(which will never make it into mainline) because this does not
garuntee that ldo-bypass is setup and functioning correctly at all (ie
user could have PMIC driver disabled, or not configured in device-tree
properly as source for arm/soc rails) but I haven't figured out the
best solution upstream yet and haven't had time to get back to it. Its
still a much lesser evil than requiring that ldo-bypass be configured
in the bootloader. This patch removes the dependence upon the
bootloader (I will never use Freescales hacked up U-Boot - I think its
still based on a 2009 branch).

I have given up on getting patches into Freescale's kernel - perhaps
being an employee you will have better luck :) I'm still hoping that
someday mainline linux will have all the IPU/VPU/GPU support for IMX6
that is missing (but getting very close!) which is what is forcing me
to use Freescale's kernel for some of our BSP's.

Tim

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2015-02-24 15:56 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
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

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.