All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 0/5] imx: ventana: stability fixes
@ 2016-06-17 13:01 Tim Harvey
  2016-06-17 13:01 ` [U-Boot] [PATCH 1/5] imx: mx6: export the set_ldo_voltage function Tim Harvey
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Tim Harvey @ 2016-06-17 13:01 UTC (permalink / raw)
  To: u-boot

This series addresses some stability issues related to voltage rails on
the IMX6 based Gateworks Ventana product family.

Tim Harvey (5):
  imx: mx6: export the set_ldo_voltage function
  imx: ventana: fix PMIC rail adjustments for IMX6SDL in ldo-bypass mode
  pmic: ltc3676: add regulator config function
  imx: ventana: use continuous PWM mode and 1MHz for LTC3676 PMIC
    regulators
  imx: ventana: enable ldo-bypass mode on compatible kernels if
    ldobypass env set

 arch/arm/cpu/armv7/mx6/soc.c              |   8 +-
 arch/arm/include/asm/arch-mx6/sys_proto.h |   9 ++
 board/gateworks/gw_ventana/common.c       | 109 +++++++++++++++------
 board/gateworks/gw_ventana/common.h       |   3 +-
 board/gateworks/gw_ventana/gw_ventana.c   | 152 +++++++++++++++++++++++++++++-
 drivers/power/pmic/pmic_ltc3676.c         |  16 ++++
 include/power/ltc3676_pmic.h              |  40 ++++++++
 7 files changed, 301 insertions(+), 36 deletions(-)

-- 
1.9.1

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

* [U-Boot] [PATCH 1/5] imx: mx6: export the set_ldo_voltage function
  2016-06-17 13:01 [U-Boot] [PATCH 0/5] imx: ventana: stability fixes Tim Harvey
@ 2016-06-17 13:01 ` Tim Harvey
  2016-06-17 13:01 ` [U-Boot] [PATCH 2/5] imx: ventana: fix PMIC rails for IMX6SDL in ldobypass mode Tim Harvey
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Tim Harvey @ 2016-06-17 13:01 UTC (permalink / raw)
  To: u-boot

Allow the set_ldo_voltage function to be called by board support files
to configure the IMX6 internal LDO's.

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
 arch/arm/cpu/armv7/mx6/soc.c              | 8 +-------
 arch/arm/include/asm/arch-mx6/sys_proto.h | 9 +++++++++
 2 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
index 88fcfdc..2b6cc47 100644
--- a/arch/arm/cpu/armv7/mx6/soc.c
+++ b/arch/arm/cpu/armv7/mx6/soc.c
@@ -23,12 +23,6 @@
 #include <imx_thermal.h>
 #include <mmc.h>
 
-enum ldo_reg {
-	LDO_ARM,
-	LDO_SOC,
-	LDO_PU,
-};
-
 struct scu_regs {
 	u32	ctrl;
 	u32	config;
@@ -228,7 +222,7 @@ static void clear_ldo_ramp(void)
  * Possible values are from 0.725V to 1.450V in steps of
  * 0.025V (25mV).
  */
-static int set_ldo_voltage(enum ldo_reg ldo, u32 mv)
+int set_ldo_voltage(enum ldo_reg ldo, u32 mv)
 {
 	struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
 	u32 val, step, old, reg = readl(&anatop->reg_core);
diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h
index 16c9b76..a94c3a1 100644
--- a/arch/arm/include/asm/arch-mx6/sys_proto.h
+++ b/arch/arm/include/asm/arch-mx6/sys_proto.h
@@ -6,3 +6,12 @@
  */
 
 #include <asm/imx-common/sys_proto.h>
+
+/* internal anatop LDO regulators */
+enum ldo_reg {
+	LDO_ARM,
+	LDO_SOC,
+	LDO_PU,
+};
+/* set internal anatop LDO regulator */
+int set_ldo_voltage(enum ldo_reg ldo, u32 mv);
-- 
1.9.1

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

* [U-Boot] [PATCH 2/5] imx: ventana: fix PMIC rails for IMX6SDL in ldobypass mode
  2016-06-17 13:01 [U-Boot] [PATCH 0/5] imx: ventana: stability fixes Tim Harvey
  2016-06-17 13:01 ` [U-Boot] [PATCH 1/5] imx: mx6: export the set_ldo_voltage function Tim Harvey
@ 2016-06-17 13:01 ` Tim Harvey
  2016-06-17 13:01 ` [U-Boot] [PATCH 3/5] pmic: ltc3676: add regulator config function Tim Harvey
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Tim Harvey @ 2016-06-17 13:01 UTC (permalink / raw)
  To: u-boot

The IMX6SDL has a VDD_SOC max of 1.21v when operating in ldo-bypass mode.
While the kernel technically should be in charge of setting the rails and
bypassing the internal LDO regulators if implementing ldo-bypass mode, it
is impossible to meet the VDD_SOC_IN min and max requirements while switching.

It has been found that exceeding the max of 1.21v in ldo-bypass mode
causes PCIe aborts hanging the system and not meeting the min of 1.275v
in ldo-enabled mode can produce other issues.

As a work-around we will examine the device-tree bindings during ft_board_setup
to determine if we are booting a configured for ldo-bypass and will
adjust the PMIC rails, and bypass the LDO's before booting the kernel.

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
 board/gateworks/gw_ventana/common.c     | 103 +++++++++++++++++++++++---------
 board/gateworks/gw_ventana/common.h     |   3 +-
 board/gateworks/gw_ventana/gw_ventana.c |  29 ++++++++-
 3 files changed, 106 insertions(+), 29 deletions(-)

diff --git a/board/gateworks/gw_ventana/common.c b/board/gateworks/gw_ventana/common.c
index 929dde9..366ea93 100644
--- a/board/gateworks/gw_ventana/common.c
+++ b/board/gateworks/gw_ventana/common.c
@@ -856,7 +856,7 @@ void setup_board_gpio(int board, struct ventana_board_info *info)
 	}
 }
 
-/* setup board specific PMIC */
+/* setup initial board specific PMIC */
 void setup_pmic(void)
 {
 	struct pmic *p;
@@ -894,32 +894,81 @@ void setup_pmic(void)
 		p = pmic_get("LTC3676_PMIC");
 		if (p && !pmic_probe(p)) {
 			puts("PMIC:  LTC3676\n");
-			/*
-			 * set board-specific scalar for max CPU frequency
-			 * per CPU based on the LDO enabled Operating Ranges
-			 * defined in the respective IMX6DQ and IMX6SDL
-			 * datasheets. The voltage resulting from the R1/R2
-			 * feedback inputs on Ventana is 1308mV. Note that this
-			 * is a bit shy of the Vmin of 1350mV in the datasheet
-			 * for LDO enabled mode but is as high as we can go.
-			 *
-			 * We will rely on an OS kernel driver to properly
-			 * regulate these per CPU operating point and use LDO
-			 * bypass mode when using the higher frequency
-			 * operating points to compensate as LDO bypass mode
-			 * allows the rails be 125mV lower.
-			 */
-			/* mask PGOOD during SW1 transition */
-			pmic_reg_write(p, LTC3676_DVB1B,
-				       0x1f | LTC3676_PGOOD_MASK);
-			/* set SW1 (VDD_SOC) */
-			pmic_reg_write(p, LTC3676_DVB1A, 0x1f);
-
-			/* mask PGOOD during SW3 transition */
-			pmic_reg_write(p, LTC3676_DVB3B,
-				       0x1f | LTC3676_PGOOD_MASK);
-			/* set SW3 (VDD_ARM) */
-			pmic_reg_write(p, LTC3676_DVB3A, 0x1f);
+
+			/* Mask PGOOD during voltage transitions */
+			pmic_reg_read(p, LTC3676_DVB1B, &reg);
+			reg |= LTC3676_PGOOD_MASK;
+			pmic_reg_write(p, LTC3676_DVB1B, reg);
+			pmic_reg_read(p, LTC3676_DVB3B, &reg);
+			reg |= LTC3676_PGOOD_MASK;
+			pmic_reg_write(p, LTC3676_DVB3B, reg);
+		}
+	}
+}
+
+/*
+ * adjust PMIC rails depending on ldo-bypass or ldo-enabled mode:
+ *
+ * Because the IMX6 VDD_ARM and VDD_SOC rails have minimum values in
+ * ldo-enabled mode which can exceed the maximum values when in
+ * ldo-bypass mode we must alter the rails depending on which mode is desired.
+ *
+ * Because ldo mode is very dependent on kernel support we can examine
+ * the device-tree to decide if the kernel uses ldo-bypass mode.
+ *
+ * ldo-bypass mode min/max values at 800MHz:
+ *  IMX6DQ:  VDDARM: 1.150v - 1.30v
+ *  IMX6DQ:  VDDSOC: 1.150v - 1.30v
+ *  IMX6SDL: VDDARM: 1.150v - 1.30v
+ *  IMX6SDL: VDDSOC: 1.150v - 1.21v <--- exceeding this causes PCIe aborts
+ *
+ * ldo-enabled mode min/max values@800Mhz are 125mV above the ldo-bypass
+ * values.
+ */
+int adjust_pmic(char ldo_enabled)
+{
+	struct pmic *p;
+	u32 reg;
+
+	debug("%s ldo_%s\n", __func__, ldo_enabled ? "enabled" : "bypass");
+	i2c_set_bus_num(CONFIG_I2C_PMIC);
+
+	/* configure LTC3676 PMIC */
+	if (!i2c_probe(CONFIG_POWER_LTC3676_I2C_ADDR)) {
+		p = pmic_get("LTC3676_PMIC");
+		if (!p)
+			return 0;
+
+		debug("Adjusting %s for ldo-%sabled\n", p->name,
+		      ldo_enabled ? "en" : "dis");
+
+		/*
+		 * if ldo_enabled mode bump the default 1.185v rails
+		 * to 1.308v max
+		 */
+		if (ldo_enabled) {
+			/* SW1: VDD_SOC */
+			pmic_reg_read(p, LTC3676_DVB1A, &reg);
+			reg |= 0x1f;
+			pmic_reg_write(p, LTC3676_DVB1A, reg);
+			pmic_reg_read(p, LTC3676_DVB1B, &reg);
+			reg |= 0x1f;
+			pmic_reg_write(p, LTC3676_DVB1B, reg);
+			/* SW3: VDD_ARM */
+			pmic_reg_read(p, LTC3676_DVB3A, &reg);
+			reg |= 0x1f;
+			pmic_reg_write(p, LTC3676_DVB3A, reg);
+			pmic_reg_read(p, LTC3676_DVB3B, &reg);
+			reg |= 0x1f;
+			pmic_reg_write(p, LTC3676_DVB3B, reg);
+		} else {
+			/* set max value to bypass FET's */
+			debug("bypassing LDO's\n");
+			set_ldo_voltage(LDO_ARM, 1500);
+			set_ldo_voltage(LDO_PU, 1500);
+			set_ldo_voltage(LDO_SOC, 1500);
 		}
 	}
+
+	return 1;
 }
diff --git a/board/gateworks/gw_ventana/common.h b/board/gateworks/gw_ventana/common.h
index d037767..3bea94b 100644
--- a/board/gateworks/gw_ventana/common.h
+++ b/board/gateworks/gw_ventana/common.h
@@ -87,8 +87,9 @@ extern struct ventana gpio_cfg[GW_UNKNOWN];
 void setup_ventana_i2c(void);
 /* configure uart iomux */
 void setup_iomux_uart(void);
-/* conifgure PMIC */
+/* configure PMIC */
 void setup_pmic(void);
+int adjust_pmic(char ldo_enabled);
 /* configure gpio iomux/defaults */
 void setup_iomux_gpio(int board, struct ventana_board_info *);
 /* late setup of GPIO (configuration per baseboard and env) */
diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c
index 82313e8..a69549b 100644
--- a/board/gateworks/gw_ventana/gw_ventana.c
+++ b/board/gateworks/gw_ventana/gw_ventana.c
@@ -802,6 +802,24 @@ static inline void ft_delprop_path(void *blob, const char *path,
 	}
 }
 
+/* return the 'compatible' property of a cpu regulator */
+static inline const char *get_cpureg(void *blob, const char *name)
+{
+	const u32 *handle = NULL;
+	int i, len = 0;
+	const char *s = NULL;
+
+	i = fdt_path_offset(blob, "/cpus/cpu at 0");
+	if (i)
+		handle = fdt_getprop(blob, i, name, NULL);
+	if (handle)
+		i = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*handle));
+	if (i)
+		s = (char *)fdt_getprop(blob, i, "compatible", &len);
+	debug("%s:%s\n", name, s);
+	return s;
+}
+
 /*
  * called prior to booting kernel or by 'fdt boardsetup' command
  *
@@ -822,7 +840,7 @@ int ft_board_setup(void *blob, bd_t *bd)
 	const char *model = getenv("model");
 	const char *display = getenv("display");
 	int i;
-	char rev = 0;
+	char rev = 0, ldo_enabled = 0;
 
 	/* determine board revision */
 	for (i = sizeof(ventana_info.model) - 1; i > 0; i--) {
@@ -976,6 +994,15 @@ int ft_board_setup(void *blob, bd_t *bd)
 				"no-1-8-v");
 	}
 
+	/* Determine if we have a kernel using the internal IMX LDO */
+	if (!strcmp("fsl,anatop-regulator", get_cpureg(blob, "arm-supply")) &&
+	    !strcmp("fsl,anatop-regulator", get_cpureg(blob, "pu-supply")) &&
+	    !strcmp("fsl,anatop-regulator", get_cpureg(blob, "soc-supply")))
+		ldo_enabled = 1;
+	printf("   Config LDO-%s mode\n", ldo_enabled ? "enabled" : "bypass");
+	/* Adjust pmic rails depending on LDO enabled vs bypass */
+	adjust_pmic(ldo_enabled);
+
 	/*
 	 * Peripheral Config:
 	 *  remove nodes by alias path if EEPROM config tells us the
-- 
1.9.1

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

* [U-Boot] [PATCH 3/5] pmic: ltc3676: add regulator config function
  2016-06-17 13:01 [U-Boot] [PATCH 0/5] imx: ventana: stability fixes Tim Harvey
  2016-06-17 13:01 ` [U-Boot] [PATCH 1/5] imx: mx6: export the set_ldo_voltage function Tim Harvey
  2016-06-17 13:01 ` [U-Boot] [PATCH 2/5] imx: ventana: fix PMIC rails for IMX6SDL in ldobypass mode Tim Harvey
@ 2016-06-17 13:01 ` Tim Harvey
  2016-06-17 13:01 ` [U-Boot] [PATCH 4/5] imx: ventana: use continuous PWM mode and 1MHz for LTC3676 PMIC regulators Tim Harvey
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Tim Harvey @ 2016-06-17 13:01 UTC (permalink / raw)
  To: u-boot

Add a convenience function for configuring the most common characteristics
of an LTC3676 buck regulator.

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
 drivers/power/pmic/pmic_ltc3676.c | 16 ++++++++++++++++
 include/power/ltc3676_pmic.h      | 40 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+)

diff --git a/drivers/power/pmic/pmic_ltc3676.c b/drivers/power/pmic/pmic_ltc3676.c
index 9b874cb..af795ea 100644
--- a/drivers/power/pmic/pmic_ltc3676.c
+++ b/drivers/power/pmic/pmic_ltc3676.c
@@ -30,3 +30,19 @@ int power_ltc3676_init(unsigned char bus)
 
 	return 0;
 }
+
+void power_ltc3676_swconfig(struct pmic *p, enum ltc3676_sw sw,
+			    enum ltc3676_mode mode, enum ltc3676_phase phase,
+			    enum ltc3676_freq freq)
+{
+	u32 reg;
+
+	pmic_reg_read(p, LTC3676_BUCK1 + sw, &reg);
+	reg &= ~LTC3676_MODE_MASK;
+	reg |= (mode << LTC3676_MODE);
+	reg &= ~(1 << LTC3676_PHASE);
+	reg |= (phase << LTC3676_PHASE);
+	reg &= ~(1 << LTC3676_FREQ);
+	reg |= (freq << LTC3676_FREQ);
+	pmic_reg_write(p, LTC3676_BUCK1 + sw, reg);
+}
diff --git a/include/power/ltc3676_pmic.h b/include/power/ltc3676_pmic.h
index dcaa985..f5b0f3c 100644
--- a/include/power/ltc3676_pmic.h
+++ b/include/power/ltc3676_pmic.h
@@ -42,10 +42,50 @@ enum {
  * SW Configuration
  */
 
+/* DVB<x> registers */
 #define LTC3676_DVB_MASK	0x1f
 #define LTC3676_PGOOD_MASK	(1<<5)
 #define LTC3676_REF_SELA	(0<<5)
 #define LTC3676_REF_SELB	(1<<5)
 
+/* BUCK<x> registers */
+#define LTC3676_MODE_MASK	0x60
+#define LTC3676_MODE		5
+#define LTC3676_STARTUP		4
+#define LTC3676_PHASE		3
+#define LTC3676_FREQ		2
+#define LTC3676_KEEPALIVE	1
+#define LTC3676_RATE		0
+
+enum ltc3676_sw {
+	SW1 = 0,
+	SW2 = 1,
+	SW3 = 2,
+	SW4 = 3
+};
+
+enum ltc3676_mode {
+	PFM = 0, /* pulse-skipping */
+	APF = 1, /* burst - auto switches */
+	PWM = 2, /* forced continuous */
+};
+
+enum ltc3676_phase {
+	PHASE1 = 0,
+	PHASE2 = 1,
+};
+
+enum ltc3676_freq {
+	F2250KHZ = 0,
+	F1125KHZ = 1,
+};
+
+enum ltc3676_rate {
+	SLOW = 0,
+	FAST = 1,
+};
+
 int power_ltc3676_init(unsigned char bus);
+void power_ltc3676_swconfig(struct pmic *, enum ltc3676_sw, enum ltc3676_mode,
+			    enum ltc3676_phase, enum ltc3676_freq);
 #endif
-- 
1.9.1

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

* [U-Boot] [PATCH 4/5] imx: ventana: use continuous PWM mode and 1MHz for LTC3676 PMIC regulators
  2016-06-17 13:01 [U-Boot] [PATCH 0/5] imx: ventana: stability fixes Tim Harvey
                   ` (2 preceding siblings ...)
  2016-06-17 13:01 ` [U-Boot] [PATCH 3/5] pmic: ltc3676: add regulator config function Tim Harvey
@ 2016-06-17 13:01 ` Tim Harvey
  2016-06-17 13:01 ` [U-Boot] [PATCH 5/5] imx: ventana: enable ldo-bypass mode on compatible kernels if ldobypass env set Tim Harvey
  2016-07-13 10:48 ` [U-Boot] [PATCH 0/5] imx: ventana: stability fixes Stefano Babic
  5 siblings, 0 replies; 8+ messages in thread
From: Tim Harvey @ 2016-06-17 13:01 UTC (permalink / raw)
  To: u-boot

It has been found that the default pulse-skipping mode of the LTC3676
regulators produces noise that the IMX6 is especially susceptible to when
run in ldo-bypass mode.

Switch to continuous PWM mode to provide a cleaner rail, as well as 1MHz
switching frequency for EMI reduction. There is no noticeable drop in
efficiency between pulse-skipping mode and PWM mode in the Ventana IMX6
use case.

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
 board/gateworks/gw_ventana/common.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/board/gateworks/gw_ventana/common.c b/board/gateworks/gw_ventana/common.c
index 366ea93..02e27c7 100644
--- a/board/gateworks/gw_ventana/common.c
+++ b/board/gateworks/gw_ventana/common.c
@@ -902,6 +902,12 @@ void setup_pmic(void)
 			pmic_reg_read(p, LTC3676_DVB3B, &reg);
 			reg |= LTC3676_PGOOD_MASK;
 			pmic_reg_write(p, LTC3676_DVB3B, reg);
+
+			/* Use continuous PWM mode, 1Mhz on all regulators */
+			power_ltc3676_swconfig(p, SW1, PWM, PHASE1, F1125KHZ);
+			power_ltc3676_swconfig(p, SW2, PWM, PHASE1, F1125KHZ);
+			power_ltc3676_swconfig(p, SW3, PWM, PHASE1, F1125KHZ);
+			power_ltc3676_swconfig(p, SW4, PWM, PHASE1, F1125KHZ);
 		}
 	}
 }
-- 
1.9.1

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

* [U-Boot] [PATCH 5/5] imx: ventana: enable ldo-bypass mode on compatible kernels if ldobypass env set
  2016-06-17 13:01 [U-Boot] [PATCH 0/5] imx: ventana: stability fixes Tim Harvey
                   ` (3 preceding siblings ...)
  2016-06-17 13:01 ` [U-Boot] [PATCH 4/5] imx: ventana: use continuous PWM mode and 1MHz for LTC3676 PMIC regulators Tim Harvey
@ 2016-06-17 13:01 ` Tim Harvey
  2016-07-13 10:48 ` [U-Boot] [PATCH 0/5] imx: ventana: stability fixes Stefano Babic
  5 siblings, 0 replies; 8+ messages in thread
From: Tim Harvey @ 2016-06-17 13:01 UTC (permalink / raw)
  To: u-boot

The IMX6 has internal LDO's for VDD_ARM and VDD_SOC which can be used with a
fixed voltage PMIC. However, if you have a PMIC capable of varying its output
voltages, you can bypass the IMX6 LDO's in what is known as 'ldo-bypass' mode
in which case the IMX6 internal LDO's are bypassed (their FET's are set to
their maximum voltage effectively opening them completely) and the PMIC
adjusts the voltage rails per the imx6-cpufreq driver which implements
Dynamic Voltage and Frequency Scaling (DVFS).

The advantage of ldo-bypass mode is that it improves CPU power efficiency
by using the more efficient switching regulators in the PMIC which reduces
overall power consumption as well as the CPU thermal output power. The
downside of ldo-bypass mode is that switching regulators are inherently
more noisy that LDO's and in certain cases according to Freescale such as
when running at 1.2GHz for processor grades that support this frequency
ldo-enabled mode is required.

Gateworks Ventana downstream vendor kernels support ldo-bypass mode as they
have a PMIC driver capable of regulating VDD_ARM and VDD_SOC however recent
kernels have defaulted to ldo-enabled mode for greater stability.

This patch allows the bootloader to switch to ldo-bypass mode on kernels
and boards that support it by setting the ldobypass env var to 1.

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
 board/gateworks/gw_ventana/gw_ventana.c | 125 +++++++++++++++++++++++++++++++-
 1 file changed, 124 insertions(+), 1 deletion(-)

diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c
index a69549b..c02ded7 100644
--- a/board/gateworks/gw_ventana/gw_ventana.c
+++ b/board/gateworks/gw_ventana/gw_ventana.c
@@ -814,12 +814,129 @@ static inline const char *get_cpureg(void *blob, const char *name)
 		handle = fdt_getprop(blob, i, name, NULL);
 	if (handle)
 		i = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*handle));
-	if (i)
+	if (i) {
 		s = (char *)fdt_getprop(blob, i, "compatible", &len);
+		if (!s) {
+			i = fdt_parent_offset(blob, i);
+			i = fdt_parent_offset(blob, i);
+			s = (char *)fdt_getprop(blob, i, "compatible", &len);
+		}
+	}
 	debug("%s:%s\n", name, s);
 	return s;
 }
 
+static int dt_find_regulator(void *blob, int offset, const char *name)
+{
+	int i, len;
+	const char *n;
+
+	offset = fdt_first_subnode(blob, offset);
+	if (offset) {
+		fdt_for_each_subnode(blob, i, offset) {
+			n = fdt_getprop(blob, i, "regulator-name", &len);
+			if (strcmp(name, n) == 0)
+				return i;
+		}
+	}
+
+	return -FDT_ERR_NOTFOUND;
+}
+
+/* Enable LDO-bypass mode by manipulating device-tree cpu0 reguatlors
+ *
+ * This requires the following
+ * (which the Gateworks downstream vendor kernel have):
+ * - gpc: ldo-bypass property
+ * - ltc3676/pfuze100 driver with vddarm and vddsoc named regulators
+ *
+ * Returns: 0 on success, -EINVAL if dt does not support ldo-bypass
+ */
+static int disable_dt_ldo(void *blob)
+{
+	int i, cpu, gpc, gpu, vpu, pmic;
+	const u32 *bypass = 0;
+	int len;
+	u32 reg_arm = 0, reg_soc = 0, reg_pu = 0;
+
+	debug("%s\n", __func__);
+
+	/* get necessary dt nodes */
+	gpc = fdt_node_offset_by_compatible(blob, -1, "fsl,imx6q-gpc");
+	if (gpc < 0)
+		debug("%s: can't find gpc\n", __func__);
+	cpu = fdt_node_offset_by_compatible(blob, -1, "arm,cortex-a9");
+	if (cpu < 0)
+		debug("%s: can't find cpu\n", __func__);
+	vpu = fdt_node_offset_by_compatible(blob, -1, "fsl,imx6-vpu");
+	if (vpu < 0)
+		debug("%s: can't find vpu\n", __func__);
+	gpu = fdt_node_offset_by_compatible(blob, -1, "fsl,imx6q-gpu");
+	if (gpu < 0)
+		debug("%s: can't find gpu\n", __func__);
+	pmic = fdt_node_offset_by_compatible(blob, -1, "lltc,ltc3676");
+	if (pmic < 0)
+		pmic = fdt_node_offset_by_compatible(blob, -1, "fsl,pfuze100");
+	if (pmic < 0)
+		debug("%s: can't find LTC3676/PFUZE100 pmic\n", __func__);
+	if (gpc >= 0)
+		bypass = fdt_getprop(blob, gpc, "fsl,ldo-bypass", &len);
+
+	/*
+	 * Get PMIC VDD_ARM/VDD_SOC regulators
+	 * Note: this requires the PMIC regulators to be named
+	 */
+	i = dt_find_regulator(blob, pmic, "vddarm");
+	if (i > 0)
+		reg_arm = fdt_get_phandle(blob, i);
+	i = dt_find_regulator(blob, pmic, "vddsoc");
+	if (i > 0)
+		reg_soc = fdt_get_phandle(blob, i);
+	/* pu_dummy only exists on fsl 3.10.x kernels */
+	i = fdt_node_offset_by_compatible(blob, -1, "fsl,imx6-dummy-pureg");
+	if (i > 0) {
+		reg_pu = fdt_get_phandle(blob, i);
+		/* if pu_dummy exists, we need a handle to it */
+		if (!reg_pu) {
+			debug("%s failed - missing reg_pu handle\n", __func__);
+			return -EINVAL;
+		}
+	}
+
+	/* make sure we have a dt that supports ldo-bypass */
+	if (!gpc || !cpu || !vpu || !gpu || !pmic) {
+		debug("%s failed - missing gpc|cpu|vpu|gpu|pmic nodes\n",
+		      __func__);
+		return -EINVAL;
+	}
+	/* make sure we can switch to ldo-bypass: have pmic reg handles */
+	if (!reg_arm || !reg_soc || !bypass) {
+		debug("%s failed - missing reg_arm|reg_soc|bypass\n", __func__);
+		return -EINVAL;
+	}
+
+	if (fdt32_to_cpu(*bypass)) {
+		debug("%s LDO already bypassed\n", __func__);
+		return -EINVAL;
+	}
+
+	/* set cpu arm-supply and soc-supply to PMIC regulators */
+	fdt_setprop_inplace_u32(blob, cpu, "arm-supply", reg_arm);
+	fdt_setprop_inplace_u32(blob, cpu, "soc-supply", reg_soc);
+	/* set vpu/gpu/gpc pu supplies to dummy regulator (3.10.x only) */
+	if (reg_pu) {
+		fdt_setprop_inplace_u32(blob, cpu, "pu-supply", reg_pu);
+		fdt_setprop_inplace_u32(blob, gpu, "pu-supply", reg_pu);
+		fdt_setprop_inplace_u32(blob, vpu, "pu-supply", reg_pu);
+		fdt_setprop_inplace_u32(blob, gpc, "pu-supply", reg_pu);
+	}
+
+	/* set fsl,ldo-bypass property of gcp to 1 */
+	fdt_setprop_inplace_u32(blob, gpc, "fsl,ldo-bypass", 1);
+
+	return 0;
+}
+
 /*
  * called prior to booting kernel or by 'fdt boardsetup' command
  *
@@ -881,6 +998,12 @@ int ft_board_setup(void *blob, bd_t *bd)
 	/* set desired digital video capture format */
 	ft_sethdmiinfmt(blob, getenv("hdmiinfmt"));
 
+	/* enable LDO-bypass mode */
+	if (getenv("ldobypass")) {
+		if (!disable_dt_ldo(blob))
+			printf("   Set LDO-bypass mode\n");
+	}
+
 	/*
 	 * disable serial2 node for GW54xx for compatibility with older
 	 * 3.10.x kernel that improperly had this node enabled in the DT
-- 
1.9.1

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

* [U-Boot] [PATCH 0/5] imx: ventana: stability fixes
  2016-06-17 13:01 [U-Boot] [PATCH 0/5] imx: ventana: stability fixes Tim Harvey
                   ` (4 preceding siblings ...)
  2016-06-17 13:01 ` [U-Boot] [PATCH 5/5] imx: ventana: enable ldo-bypass mode on compatible kernels if ldobypass env set Tim Harvey
@ 2016-07-13 10:48 ` Stefano Babic
  2016-07-15 13:36   ` Tim Harvey
  5 siblings, 1 reply; 8+ messages in thread
From: Stefano Babic @ 2016-07-13 10:48 UTC (permalink / raw)
  To: u-boot

Hi Tim,

On 17/06/2016 15:01, Tim Harvey wrote:
> This series addresses some stability issues related to voltage rails on
> the IMX6 based Gateworks Ventana product family.
> 
> Tim Harvey (5):
>   imx: mx6: export the set_ldo_voltage function
>   imx: ventana: fix PMIC rail adjustments for IMX6SDL in ldo-bypass mode
>   pmic: ltc3676: add regulator config function
>   imx: ventana: use continuous PWM mode and 1MHz for LTC3676 PMIC
>     regulators
>   imx: ventana: enable ldo-bypass mode on compatible kernels if
>     ldobypass env set
> 
>  arch/arm/cpu/armv7/mx6/soc.c              |   8 +-
>  arch/arm/include/asm/arch-mx6/sys_proto.h |   9 ++
>  board/gateworks/gw_ventana/common.c       | 109 +++++++++++++++------
>  board/gateworks/gw_ventana/common.h       |   3 +-
>  board/gateworks/gw_ventana/gw_ventana.c   | 152 +++++++++++++++++++++++++++++-
>  drivers/power/pmic/pmic_ltc3676.c         |  16 ++++
>  include/power/ltc3676_pmic.h              |  40 ++++++++
>  7 files changed, 301 insertions(+), 36 deletions(-)
> 

I do not find in my emailer 5/5 - I grab 0/5 for the answer.

Patch 4/5 is like a trick, but I am asking if the same solution can be
used on other boards. The issue looks to me quite general, and if
ldo-bypass must be set depends on if there is a capable PMIC.

What about to let this code become more general moving into imx-common ?
Do you see any issue why we shouldn't ?

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] 8+ messages in thread

* [U-Boot] [PATCH 0/5] imx: ventana: stability fixes
  2016-07-13 10:48 ` [U-Boot] [PATCH 0/5] imx: ventana: stability fixes Stefano Babic
@ 2016-07-15 13:36   ` Tim Harvey
  0 siblings, 0 replies; 8+ messages in thread
From: Tim Harvey @ 2016-07-15 13:36 UTC (permalink / raw)
  To: u-boot

On Wed, Jul 13, 2016 at 3:48 AM, Stefano Babic <sbabic@denx.de> wrote:
> Hi Tim,
>
> On 17/06/2016 15:01, Tim Harvey wrote:
>> This series addresses some stability issues related to voltage rails on
>> the IMX6 based Gateworks Ventana product family.
>>
>> Tim Harvey (5):
>>   imx: mx6: export the set_ldo_voltage function
>>   imx: ventana: fix PMIC rail adjustments for IMX6SDL in ldo-bypass mode
>>   pmic: ltc3676: add regulator config function
>>   imx: ventana: use continuous PWM mode and 1MHz for LTC3676 PMIC
>>     regulators
>>   imx: ventana: enable ldo-bypass mode on compatible kernels if
>>     ldobypass env set
>>
>>  arch/arm/cpu/armv7/mx6/soc.c              |   8 +-
>>  arch/arm/include/asm/arch-mx6/sys_proto.h |   9 ++
>>  board/gateworks/gw_ventana/common.c       | 109 +++++++++++++++------
>>  board/gateworks/gw_ventana/common.h       |   3 +-
>>  board/gateworks/gw_ventana/gw_ventana.c   | 152 +++++++++++++++++++++++++++++-
>>  drivers/power/pmic/pmic_ltc3676.c         |  16 ++++
>>  include/power/ltc3676_pmic.h              |  40 ++++++++
>>  7 files changed, 301 insertions(+), 36 deletions(-)
>>
>
> I do not find in my emailer 5/5 - I grab 0/5 for the answer.
>

Stefano,

If your missing 5/5 you can find it in my patches here:
https://patchwork.ozlabs.org/project/uboot/list/?submitter=41730

> Patch 4/5 is like a trick, but I am asking if the same solution can be
> used on other boards. The issue looks to me quite general, and if
> ldo-bypass must be set depends on if there is a capable PMIC.

4/5 'ventana: use continuous PWM mode and 1MHz for LTC3676 PMIC
regulators' was really about configuring the LTC3676 PMIC to use
'continuous PWM' instead of its power-on default of 'pulse skipping'
mode which was just noisy enough to cause issues with the IMX6 when it
was in ldo-bypass mode.

Is this the patch you were thinking of and what was it you felt could
be made more common?

There definitely is a 'trick' to determine if the kernel uses
ldo-bypass by examining its device-tree vddarm/vddsoc regulators in
'imx: ventana: fix PMIC rail adjustments for IMX6SDL in ldo-bypass
mode' and there is another 'trick' perhaps in 'imx: ventana: enable
ldo-bypass mode on compatible kernels if ldobypass env set' which
involves changing a device-tree that is found to 'support' LDO-bypass
mode but does not have it enabled but I'm not sure that is what you
meant.

>
> What about to let this code become more general moving into imx-common ?
> Do you see any issue why we shouldn't ?
>

I maybe should have split of this series into 3 sets but I figured I
would lump them all together as they were all 'power/PMIC' related:

1/5: imx: mx6: export the set_ldo_voltage function
2/5: imx: ventana: fix PMIC rail adjustments for IMX6SDL in ldo-bypass mode
  - these resolved a 1 to 5% board hang for ldo-bypass mode

3/5: pmic: ltc3676: add regulator config function
4/5: imx: ventana: use continuous PWM mode and 1MHz for LTC3676 PMIC regulators
  - these resolved a general board stability issue due to noise
sensitivity of the IMX6 when using ldo-bypass mode

5/5: imx: ventana: enable ldo-bypass mode on compatible kernels if
ldobypass env set
  - this will re-assign regulators in the device-tree to enable
ldo-bypass mode for device-tree's that are capable of running
ldo-bypass mode but have it disabled

As you likely know, IMX6 LDO-bypass requires board and kernel support
such that the kernel must have a PMIC driver capable of adjusting
vddarm and vddsoc within the range specified by the operation points
in the device-tree. Additionally, the device-tree must reference the
PMIC regulators and something in the kernel must put the IMX6 LDO's in
'bypass' mode by fully opening the FET's. Note that there is not yet
support for LDO-bypass in the mainline kernel, so this is strictly
used currently for Freescales downstream kernel currently.

I found that the recommended voltage ranges when in ldo-bypass mode vs
ldo-enabled mode don't overlap, specifically the maximum vddsoc for
imx6sdl in LDO-bypass mode exceeds the minimum for LDO-enabled mode. I
was able to prove that exceeding 1.21v for vddsoc when using
ldo-bypass mode does indeed cause an issue with the PCIe core (hangs
occasionally on init in the kernel). Therefore my only solution was to
determine which mode was going to be used by the booting kernel and
make adjustments while we could in the bootloader before booting the
kernel.

Now, after reviewing all of these to answer your questions I realize that:
 a) IMX6 ldo-bypass is not yet in the mainline Linux kernel
 b) IMX6 ldo-bypass may not be all that desirable anyway: the voltage
tolerances are much tighter which could cause stability issues, it
lowers the processor lifespan, and the power savings are not that
great in general use cases
 c) the two tricks mentioned above only resolve issues that occur on
boards with ldo-bypass enabled
 d) we switched our downstream Freescale vendor kernel a while back to
use ldo-enabled mode because we felt it was more stable and improved
part longevity. This was when I wrote '5/5: imx: ventana: enable
ldo-bypass mode on compatible kernels if ldobypass env set' to allow
users to still use it if their application was very power sensitive

So, I think I'll drop this series as it doesn't pertain to mainline
Linux kernels. I may re-write 4/5 and re-submit as I do feel that
continuous PWM mode for the LTC3676 PMIC may be more suitable for
sensitive rails in general.

Regards,

Tim

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

end of thread, other threads:[~2016-07-15 13:36 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-17 13:01 [U-Boot] [PATCH 0/5] imx: ventana: stability fixes Tim Harvey
2016-06-17 13:01 ` [U-Boot] [PATCH 1/5] imx: mx6: export the set_ldo_voltage function Tim Harvey
2016-06-17 13:01 ` [U-Boot] [PATCH 2/5] imx: ventana: fix PMIC rails for IMX6SDL in ldobypass mode Tim Harvey
2016-06-17 13:01 ` [U-Boot] [PATCH 3/5] pmic: ltc3676: add regulator config function Tim Harvey
2016-06-17 13:01 ` [U-Boot] [PATCH 4/5] imx: ventana: use continuous PWM mode and 1MHz for LTC3676 PMIC regulators Tim Harvey
2016-06-17 13:01 ` [U-Boot] [PATCH 5/5] imx: ventana: enable ldo-bypass mode on compatible kernels if ldobypass env set Tim Harvey
2016-07-13 10:48 ` [U-Boot] [PATCH 0/5] imx: ventana: stability fixes Stefano Babic
2016-07-15 13:36   ` Tim Harvey

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.