[PATCH 1/7] board: gateworks: gw_ventana: convert to DM_I2C

Tim Harvey tharvey at gateworks.com
Tue Mar 8 01:24:00 CET 2022


convert to DM_I2C for U-Boot while leaving SPL legacy I2C:
 - Move I2C config from common to SPL
 - Move PMIC config from common to SPL (no need to re-configure pmic)
 - add DM_I2C support to eeprom/gsc functions shared by SPL and U-Boot

Signed-off-by: Tim Harvey <tharvey at gateworks.com>
---
 board/gateworks/gw_ventana/common.c         | 266 --------------------
 board/gateworks/gw_ventana/common.h         |   4 -
 board/gateworks/gw_ventana/eeprom.c         |   9 +
 board/gateworks/gw_ventana/gsc.c            |  60 ++++-
 board/gateworks/gw_ventana/gsc.h            |   1 +
 board/gateworks/gw_ventana/gw_ventana.c     |  17 +-
 board/gateworks/gw_ventana/gw_ventana_spl.c | 266 ++++++++++++++++++++
 configs/gwventana_emmc_defconfig            |   2 +-
 configs/gwventana_gw5904_defconfig          |   2 +-
 configs/gwventana_nand_defconfig            |   2 +-
 10 files changed, 334 insertions(+), 295 deletions(-)

diff --git a/board/gateworks/gw_ventana/common.c b/board/gateworks/gw_ventana/common.c
index 7ec931c8a831..2be6518b63e0 100644
--- a/board/gateworks/gw_ventana/common.c
+++ b/board/gateworks/gw_ventana/common.c
@@ -16,10 +16,6 @@
 #include <fsl_esdhc_imx.h>
 #include <hwconfig.h>
 #include <linux/delay.h>
-#include <power/pmic.h>
-#include <power/ltc3676_pmic.h>
-#include <power/pfuze100_pmic.h>
-#include <power/mp5416.h>
 
 #include "common.h"
 
@@ -83,98 +79,6 @@ static iomux_v3_cfg_t const usdhc3_pads[] = {
 	IOMUX_PADS(PAD_SD3_DAT5__GPIO7_IO00  | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
 };
 
-/*
- * I2C pad configs:
- * I2C1: GSC
- * I2C2: PMIC,PCIe Switch,Clock,Mezz
- * I2C3: Multimedia/Expansion
- */
-static struct i2c_pads_info mx6q_i2c_pad_info[] = {
-	{
-		.scl = {
-			.i2c_mode = MX6Q_PAD_EIM_D21__I2C1_SCL | PC,
-			.gpio_mode = MX6Q_PAD_EIM_D21__GPIO3_IO21 | PC,
-			.gp = IMX_GPIO_NR(3, 21)
-		},
-		.sda = {
-			.i2c_mode = MX6Q_PAD_EIM_D28__I2C1_SDA | PC,
-			.gpio_mode = MX6Q_PAD_EIM_D28__GPIO3_IO28 | PC,
-			.gp = IMX_GPIO_NR(3, 28)
-		}
-	}, {
-		.scl = {
-			.i2c_mode = MX6Q_PAD_KEY_COL3__I2C2_SCL | PC,
-			.gpio_mode = MX6Q_PAD_KEY_COL3__GPIO4_IO12 | PC,
-			.gp = IMX_GPIO_NR(4, 12)
-		},
-		.sda = {
-			.i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | PC,
-			.gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO4_IO13 | PC,
-			.gp = IMX_GPIO_NR(4, 13)
-		}
-	}, {
-		.scl = {
-			.i2c_mode = MX6Q_PAD_GPIO_3__I2C3_SCL | PC,
-			.gpio_mode = MX6Q_PAD_GPIO_3__GPIO1_IO03 | PC,
-			.gp = IMX_GPIO_NR(1, 3)
-		},
-		.sda = {
-			.i2c_mode = MX6Q_PAD_GPIO_6__I2C3_SDA | PC,
-			.gpio_mode = MX6Q_PAD_GPIO_6__GPIO1_IO06 | PC,
-			.gp = IMX_GPIO_NR(1, 6)
-		}
-	}
-};
-
-static struct i2c_pads_info mx6dl_i2c_pad_info[] = {
-	{
-		.scl = {
-			.i2c_mode = MX6DL_PAD_EIM_D21__I2C1_SCL | PC,
-			.gpio_mode = MX6DL_PAD_EIM_D21__GPIO3_IO21 | PC,
-			.gp = IMX_GPIO_NR(3, 21)
-		},
-		.sda = {
-			.i2c_mode = MX6DL_PAD_EIM_D28__I2C1_SDA | PC,
-			.gpio_mode = MX6DL_PAD_EIM_D28__GPIO3_IO28 | PC,
-			.gp = IMX_GPIO_NR(3, 28)
-		}
-	}, {
-		.scl = {
-			.i2c_mode = MX6DL_PAD_KEY_COL3__I2C2_SCL | PC,
-			.gpio_mode = MX6DL_PAD_KEY_COL3__GPIO4_IO12 | PC,
-			.gp = IMX_GPIO_NR(4, 12)
-		},
-		.sda = {
-			.i2c_mode = MX6DL_PAD_KEY_ROW3__I2C2_SDA | PC,
-			.gpio_mode = MX6DL_PAD_KEY_ROW3__GPIO4_IO13 | PC,
-			.gp = IMX_GPIO_NR(4, 13)
-		}
-	}, {
-		.scl = {
-			.i2c_mode = MX6DL_PAD_GPIO_3__I2C3_SCL | PC,
-			.gpio_mode = MX6DL_PAD_GPIO_3__GPIO1_IO03 | PC,
-			.gp = IMX_GPIO_NR(1, 3)
-		},
-		.sda = {
-			.i2c_mode = MX6DL_PAD_GPIO_6__I2C3_SDA | PC,
-			.gpio_mode = MX6DL_PAD_GPIO_6__GPIO1_IO06 | PC,
-			.gp = IMX_GPIO_NR(1, 6)
-		}
-	}
-};
-
-void setup_ventana_i2c(int i2c)
-{
-	struct i2c_pads_info *p;
-
-	if (is_cpu_type(MXC_CPU_MX6Q))
-		p = &mx6q_i2c_pad_info[i2c];
-	else
-		p = &mx6dl_i2c_pad_info[i2c];
-
-	setup_i2c(i2c, CONFIG_SYS_I2C_SPEED, 0x7f, p);
-}
-
 /*
  * Baseboard specific GPIO
  */
@@ -1402,176 +1306,6 @@ void setup_board_gpio(int board, struct ventana_board_info *info)
 	}
 }
 
-/* setup board specific PMIC */
-void setup_pmic(void)
-{
-	struct pmic *p;
-	struct ventana_board_info ventana_info;
-	int board = read_eeprom(CONFIG_I2C_GSC, &ventana_info);
-	const int i2c_pmic = 1;
-	u32 reg;
-	char rev;
-	int i;
-
-	/* determine board revision */
-	rev = 'A';
-	for (i = sizeof(ventana_info.model) - 1; i > 0; i--) {
-		if (ventana_info.model[i] >= 'A') {
-			rev = ventana_info.model[i];
-			break;
-		}
-	}
-
-	i2c_set_bus_num(i2c_pmic);
-
-	/* configure PFUZE100 PMIC */
-	if (!i2c_probe(CONFIG_POWER_PFUZE100_I2C_ADDR)) {
-		debug("probed PFUZE100 at 0x%x\n", CONFIG_POWER_PFUZE100_I2C_ADDR);
-		power_pfuze100_init(i2c_pmic);
-		p = pmic_get("PFUZE100");
-		if (p && !pmic_probe(p)) {
-			pmic_reg_read(p, PFUZE100_DEVICEID, &reg);
-			printf("PMIC:  PFUZE100 ID=0x%02x\n", reg);
-
-			/* Set VGEN1 to 1.5V and enable */
-			pmic_reg_read(p, PFUZE100_VGEN1VOL, &reg);
-			reg &= ~(LDO_VOL_MASK);
-			reg |= (LDOA_1_50V | LDO_EN);
-			pmic_reg_write(p, PFUZE100_VGEN1VOL, reg);
-
-			/* Set SWBST to 5.0V and enable */
-			pmic_reg_read(p, PFUZE100_SWBSTCON1, &reg);
-			reg &= ~(SWBST_MODE_MASK | SWBST_VOL_MASK);
-			reg |= (SWBST_5_00V | (SWBST_MODE_AUTO << SWBST_MODE_SHIFT));
-			pmic_reg_write(p, PFUZE100_SWBSTCON1, reg);
-
-			if (board == GW54xx && (rev == 'G')) {
-				/* Disable VGEN5 */
-				pmic_reg_write(p, PFUZE100_VGEN5VOL, 0);
-
-				/* Set VGEN6 to 2.5V and enable */
-				pmic_reg_read(p, PFUZE100_VGEN6VOL, &reg);
-				reg &= ~(LDO_VOL_MASK);
-				reg |= (LDOB_2_50V | LDO_EN);
-				pmic_reg_write(p, PFUZE100_VGEN6VOL, reg);
-			}
-		}
-
-		/* put all switchers in continuous mode */
-		pmic_reg_read(p, PFUZE100_SW1ABMODE, &reg);
-		reg &= ~(SW_MODE_MASK);
-		reg |= PWM_PWM;
-		pmic_reg_write(p, PFUZE100_SW1ABMODE, reg);
-
-		pmic_reg_read(p, PFUZE100_SW2MODE, &reg);
-		reg &= ~(SW_MODE_MASK);
-		reg |= PWM_PWM;
-		pmic_reg_write(p, PFUZE100_SW2MODE, reg);
-
-		pmic_reg_read(p, PFUZE100_SW3AMODE, &reg);
-		reg &= ~(SW_MODE_MASK);
-		reg |= PWM_PWM;
-		pmic_reg_write(p, PFUZE100_SW3AMODE, reg);
-
-		pmic_reg_read(p, PFUZE100_SW3BMODE, &reg);
-		reg &= ~(SW_MODE_MASK);
-		reg |= PWM_PWM;
-		pmic_reg_write(p, PFUZE100_SW3BMODE, reg);
-
-		pmic_reg_read(p, PFUZE100_SW4MODE, &reg);
-		reg &= ~(SW_MODE_MASK);
-		reg |= PWM_PWM;
-		pmic_reg_write(p, PFUZE100_SW4MODE, reg);
-	}
-
-	/* configure LTC3676 PMIC */
-	else if (!i2c_probe(CONFIG_POWER_LTC3676_I2C_ADDR)) {
-		debug("probed LTC3676 at 0x%x\n", CONFIG_POWER_LTC3676_I2C_ADDR);
-		power_ltc3676_init(i2c_pmic);
-		p = pmic_get("LTC3676_PMIC");
-		if (!p || pmic_probe(p))
-			return;
-		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.
-		 */
-		switch (board) {
-		case GW560x:
-			/* 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);
-			break;
-		case GW5903:
-			/* 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 SW4 transition */
-			pmic_reg_write(p, LTC3676_DVB4B,
-				       0x1f | LTC3676_PGOOD_MASK);
-			/* set SW4 (VDD_SOC) */
-			pmic_reg_write(p, LTC3676_DVB4A, 0x1f);
-			break;
-		case GW5905:
-			/* mask PGOOD during SW1 transition */
-			pmic_reg_write(p, LTC3676_DVB1B,
-				       0x1f | LTC3676_PGOOD_MASK);
-			/* set SW1 (VDD_ARM) */
-			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_SOC) */
-			pmic_reg_write(p, LTC3676_DVB3A, 0x1f);
-			break;
-		default:
-			/* 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);
-		}
-
-		/* put all switchers in continuous mode */
-		pmic_reg_write(p, LTC3676_BUCK1, 0xc0);
-		pmic_reg_write(p, LTC3676_BUCK2, 0xc0);
-		pmic_reg_write(p, LTC3676_BUCK3, 0xc0);
-		pmic_reg_write(p, LTC3676_BUCK4, 0xc0);
-	}
-
-	/* configure MP5416 PMIC */
-	else if (!i2c_probe(0x69)) {
-		puts("PMIC:  MP5416\n");
-		switch (board) {
-		case GW5910:
-			/* SW1: VDD_ARM 1.2V -> (1.275 to 1.475) */
-			reg = MP5416_VSET_EN | MP5416_VSET_SW1_SVAL(1475000);
-			i2c_write(0x69, MP5416_VSET_SW1, 1, (uint8_t *)&reg, 1);
-			/* SW4: VDD_SOC 1.2V -> (1.350 to 1.475) */
-			reg = MP5416_VSET_EN | MP5416_VSET_SW4_SVAL(1475000);
-			i2c_write(0x69, MP5416_VSET_SW4, 1, (uint8_t *)&reg, 1);
-			break;
-		}
-	}
-}
-
 #include <fdt_support.h>
 #define WDOG1_ADDR      0x20bc000
 #define WDOG2_ADDR      0x20c0000
diff --git a/board/gateworks/gw_ventana/common.h b/board/gateworks/gw_ventana/common.h
index edfb065f6a70..526ff066b629 100644
--- a/board/gateworks/gw_ventana/common.h
+++ b/board/gateworks/gw_ventana/common.h
@@ -79,12 +79,8 @@ struct ventana {
 
 extern struct ventana gpio_cfg[GW_UNKNOWN];
 
-/* configure i2c iomux */
-void setup_ventana_i2c(int);
 /* configure uart iomux */
 void setup_iomux_uart(void);
-/* conifgure PMIC */
-void setup_pmic(void);
 /* 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/eeprom.c b/board/gateworks/gw_ventana/eeprom.c
index d21aa3c38ff2..c3a2bbe9ca48 100644
--- a/board/gateworks/gw_ventana/eeprom.c
+++ b/board/gateworks/gw_ventana/eeprom.c
@@ -13,6 +13,7 @@
 #include <malloc.h>
 #include <asm/bitops.h>
 #include <linux/delay.h>
+#include <dm/uclass.h>
 
 #include "gsc.h"
 #include "ventana_eeprom.h"
@@ -34,12 +35,20 @@ read_eeprom(int bus, struct ventana_board_info *info)
 	 * board may be ready to probe the GSC before its firmware is
 	 * running.  We will wait here indefinately for the GSC/EEPROM.
 	 */
+#if CONFIG_IS_ENABLED(DM_I2C)
+	while (1) {
+		if (i2c_get_dev(bus, GSC_EEPROM_ADDR))
+			break;
+		mdelay(1);
+	}
+#else
 	while (1) {
 		if (0 == i2c_set_bus_num(bus) &&
 		    0 == i2c_probe(GSC_EEPROM_ADDR))
 			break;
 		mdelay(1);
 	}
+#endif
 
 	/* read eeprom config section */
 	mdelay(10);
diff --git a/board/gateworks/gw_ventana/gsc.c b/board/gateworks/gw_ventana/gsc.c
index 324e5dbed2c8..3c8707578c2f 100644
--- a/board/gateworks/gw_ventana/gsc.c
+++ b/board/gateworks/gw_ventana/gsc.c
@@ -16,12 +16,31 @@
 
 #include <asm/arch/sys_proto.h>
 #include <asm/global_data.h>
+#include <dm/device.h>
+#include <dm/uclass.h>
 
 #include "ventana_eeprom.h"
 #include "gsc.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#if CONFIG_IS_ENABLED(DM_I2C)
+struct udevice *i2c_get_dev(int busno, int slave)
+{
+	struct udevice *dev, *bus;
+	int ret;
+
+	ret = uclass_get_device_by_seq(UCLASS_I2C, busno, &bus);
+	if (ret)
+		return NULL;
+	ret = dm_i2c_probe(bus, slave, 0, &dev);
+	if (ret)
+		return NULL;
+
+	return dev;
+}
+#endif
+
 /*
  * The Gateworks System Controller will fail to ACK a master transaction if
  * it is busy, which can occur during its 1HZ timer tick while reading ADC's.
@@ -34,9 +53,27 @@ int gsc_i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
 	int retry = 3;
 	int n = 0;
 	int ret;
+#if CONFIG_IS_ENABLED(DM_I2C)
+	struct udevice *dev;
+
+	dev = i2c_get_dev(CONFIG_I2C_GSC, chip);
+	if (!dev)
+		return -ENODEV;
+	ret = i2c_set_chip_offset_len(dev, alen);
+	if (ret) {
+		puts("EEPROM: Failed to set alen\n");
+		return ret;
+	}
+#else
+	i2c_set_bus_num(CONFIG_I2C_GSC);
+#endif
 
 	while (n++ < retry) {
+#if CONFIG_IS_ENABLED(DM_I2C)
+		ret = dm_i2c_read(dev, addr, buf, len);
+#else
 		ret = i2c_read(chip, addr, alen, buf, len);
+#endif
 		if (!ret)
 			break;
 		debug("%s: 0x%02x 0x%02x retry%d: %d\n", __func__, chip, addr,
@@ -53,9 +90,25 @@ int gsc_i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
 	int retry = 3;
 	int n = 0;
 	int ret;
+#if CONFIG_IS_ENABLED(DM_I2C)
+	struct udevice *dev;
+
+	dev = i2c_get_dev(CONFIG_I2C_GSC, chip);
+	if (!dev)
+		return -ENODEV;
+	ret = i2c_set_chip_offset_len(dev, alen);
+	if (ret) {
+		puts("EEPROM: Failed to set alen\n");
+		return ret;
+	}
+#endif
 
 	while (n++ < retry) {
+#if CONFIG_IS_ENABLED(DM_I2C)
+		ret = dm_i2c_write(dev, addr, buf, len);
+#else
 		ret = i2c_write(chip, addr, alen, buf, len);
+#endif
 		if (!ret)
 			break;
 		debug("%s: 0x%02x 0x%02x retry%d: %d\n", __func__, chip, addr,
@@ -79,7 +132,6 @@ int gsc_get_board_temp(void)
 	node = fdt_node_offset_by_compatible(fdt, -1, "gw,gsc-adc");
 	if (node <= 0)
 		return node;
-	i2c_set_bus_num(0);
 
 	/* iterate over hwmon nodes */
 	node = fdt_first_subnode(fdt, node);
@@ -122,7 +174,6 @@ int gsc_hwmon(void)
 	node = fdt_node_offset_by_compatible(fdt, -1, "gw,gsc-adc");
 	if (node <= 0)
 		return node;
-	i2c_set_bus_num(0);
 
 	/* iterate over hwmon nodes */
 	node = fdt_first_subnode(fdt, node);
@@ -184,7 +235,6 @@ int gsc_info(int verbose)
 {
 	unsigned char buf[16];
 
-	i2c_set_bus_num(0);
 	if (gsc_i2c_read(GSC_SC_ADDR, 0, 1, buf, 16))
 		return CMD_RET_FAILURE;
 
@@ -225,7 +275,6 @@ int gsc_boot_wd_disable(void)
 {
 	u8 reg;
 
-	i2c_set_bus_num(CONFIG_I2C_GSC);
 	if (!gsc_i2c_read(GSC_SC_ADDR, GSC_SC_CTRL1, 1, &reg, 1)) {
 		reg |= (1 << GSC_SC_CTRL1_WDDIS);
 		if (!gsc_i2c_write(GSC_SC_ADDR, GSC_SC_CTRL1, 1, &reg, 1))
@@ -334,7 +383,6 @@ static int do_gsc_sleep(struct cmd_tbl *cmdtp, int flag, int argc,
 	secs = dectoul(argv[1], NULL);
 	printf("GSC Sleeping for %ld seconds\n", secs);
 
-	i2c_set_bus_num(0);
 	reg = (secs >> 24) & 0xff;
 	if (gsc_i2c_write(GSC_SC_ADDR, 9, 1, &reg, 1))
 		goto error;
@@ -377,7 +425,6 @@ static int do_gsc_wd(struct cmd_tbl *cmdtp, int flag, int argc,
 
 		if (argc > 2)
 			timeout = dectoul(argv[2], NULL);
-		i2c_set_bus_num(0);
 		if (gsc_i2c_read(GSC_SC_ADDR, GSC_SC_CTRL1, 1, &reg, 1))
 			return CMD_RET_FAILURE;
 		reg &= ~((1 << GSC_SC_CTRL1_WDEN) | (1 << GSC_SC_CTRL1_WDTIME));
@@ -391,7 +438,6 @@ static int do_gsc_wd(struct cmd_tbl *cmdtp, int flag, int argc,
 		printf("GSC Watchdog enabled with timeout=%d seconds\n",
 		       timeout);
 	} else if (strcasecmp(argv[1], "disable") == 0) {
-		i2c_set_bus_num(0);
 		if (gsc_i2c_read(GSC_SC_ADDR, GSC_SC_CTRL1, 1, &reg, 1))
 			return CMD_RET_FAILURE;
 		reg &= ~((1 << GSC_SC_CTRL1_WDEN) | (1 << GSC_SC_CTRL1_WDTIME));
diff --git a/board/gateworks/gw_ventana/gsc.h b/board/gateworks/gw_ventana/gsc.h
index 5c349888280e..2e1d25bc6f04 100644
--- a/board/gateworks/gw_ventana/gsc.h
+++ b/board/gateworks/gw_ventana/gsc.h
@@ -68,4 +68,5 @@ int gsc_i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len);
 int gsc_info(int verbose);
 int gsc_boot_wd_disable(void);
 const char *gsc_get_dtb_name(int level, char *buf, int sz);
+struct udevice *i2c_get_dev(int busno, int slave);
 #endif
diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c
index 8cf791467024..a76f0ea62f9d 100644
--- a/board/gateworks/gw_ventana/gw_ventana.c
+++ b/board/gateworks/gw_ventana/gw_ventana.c
@@ -138,8 +138,7 @@ static int detect_lvds(struct display_info_t const *dev)
 		return 0;
 	}
 
-	return i2c_set_bus_num(dev->bus) == 0 &&
-		i2c_probe(dev->addr) == 0;
+	return (i2c_get_dev(dev->bus, dev->addr) ? 1 : 0);
 }
 
 static void enable_lvds(struct display_info_t const *dev)
@@ -355,13 +354,6 @@ static void setup_display(void)
 }
 #endif /* CONFIG_VIDEO_IPUV3 */
 
-/* setup board specific PMIC */
-int power_init_board(void)
-{
-	setup_pmic();
-	return 0;
-}
-
 /*
  * Most Ventana boards have a PLX PEX860x PCIe switch onboard and use its
  * GPIO's as PERST# signals for its downstream ports - configure the GPIO's
@@ -490,12 +482,8 @@ int board_init(void)
 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 
 	/* read Gateworks EEPROM into global struct (used later) */
-	setup_ventana_i2c(0);
 	board_type = read_eeprom(CONFIG_I2C_GSC, &ventana_info);
 
-	setup_ventana_i2c(1);
-	setup_ventana_i2c(2);
-
 	setup_iomux_gpio(board_type, &ventana_info);
 
 	return 0;
@@ -925,8 +913,7 @@ void ft_board_pci_fixup(void *blob, struct bd_info *bd)
 		 */
 		if ((dev->vendor == PCI_VENDOR_ID_TI) &&
 		    (dev->device == 0x8240) &&
-		    (i2c_set_bus_num(1) == 0) &&
-		    (i2c_probe(0x50) == 0))
+		    i2c_get_dev(1, 0x50))
 		{
 			np = fdt_add_pci_path(blob, dev);
 			if (np > 0)
diff --git a/board/gateworks/gw_ventana/gw_ventana_spl.c b/board/gateworks/gw_ventana/gw_ventana_spl.c
index 5a69aff67172..60e2768d2eba 100644
--- a/board/gateworks/gw_ventana/gw_ventana_spl.c
+++ b/board/gateworks/gw_ventana/gw_ventana_spl.c
@@ -20,6 +20,10 @@
 #include <env.h>
 #include <i2c.h>
 #include <spl.h>
+#include <power/pmic.h>
+#include <power/ltc3676_pmic.h>
+#include <power/pfuze100_pmic.h>
+#include <power/mp5416.h>
 
 #include "gsc.h"
 #include "common.h"
@@ -667,6 +671,268 @@ static void ccgr_init(void)
 	writel(0x000003FF, &ccm->CCGR6);
 }
 
+/*
+ * I2C pad configs:
+ * I2C1: GSC
+ * I2C2: PMIC,PCIe Switch,Clock,Mezz
+ * I2C3: Multimedia/Expansion
+ */
+static struct i2c_pads_info mx6q_i2c_pad_info[] = {
+	{
+		.scl = {
+			.i2c_mode = MX6Q_PAD_EIM_D21__I2C1_SCL | PC,
+			.gpio_mode = MX6Q_PAD_EIM_D21__GPIO3_IO21 | PC,
+			.gp = IMX_GPIO_NR(3, 21)
+		},
+		.sda = {
+			.i2c_mode = MX6Q_PAD_EIM_D28__I2C1_SDA | PC,
+			.gpio_mode = MX6Q_PAD_EIM_D28__GPIO3_IO28 | PC,
+			.gp = IMX_GPIO_NR(3, 28)
+		}
+	}, {
+		.scl = {
+			.i2c_mode = MX6Q_PAD_KEY_COL3__I2C2_SCL | PC,
+			.gpio_mode = MX6Q_PAD_KEY_COL3__GPIO4_IO12 | PC,
+			.gp = IMX_GPIO_NR(4, 12)
+		},
+		.sda = {
+			.i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | PC,
+			.gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO4_IO13 | PC,
+			.gp = IMX_GPIO_NR(4, 13)
+		}
+	}, {
+		.scl = {
+			.i2c_mode = MX6Q_PAD_GPIO_3__I2C3_SCL | PC,
+			.gpio_mode = MX6Q_PAD_GPIO_3__GPIO1_IO03 | PC,
+			.gp = IMX_GPIO_NR(1, 3)
+		},
+		.sda = {
+			.i2c_mode = MX6Q_PAD_GPIO_6__I2C3_SDA | PC,
+			.gpio_mode = MX6Q_PAD_GPIO_6__GPIO1_IO06 | PC,
+			.gp = IMX_GPIO_NR(1, 6)
+		}
+	}
+};
+
+static struct i2c_pads_info mx6dl_i2c_pad_info[] = {
+	{
+		.scl = {
+			.i2c_mode = MX6DL_PAD_EIM_D21__I2C1_SCL | PC,
+			.gpio_mode = MX6DL_PAD_EIM_D21__GPIO3_IO21 | PC,
+			.gp = IMX_GPIO_NR(3, 21)
+		},
+		.sda = {
+			.i2c_mode = MX6DL_PAD_EIM_D28__I2C1_SDA | PC,
+			.gpio_mode = MX6DL_PAD_EIM_D28__GPIO3_IO28 | PC,
+			.gp = IMX_GPIO_NR(3, 28)
+		}
+	}, {
+		.scl = {
+			.i2c_mode = MX6DL_PAD_KEY_COL3__I2C2_SCL | PC,
+			.gpio_mode = MX6DL_PAD_KEY_COL3__GPIO4_IO12 | PC,
+			.gp = IMX_GPIO_NR(4, 12)
+		},
+		.sda = {
+			.i2c_mode = MX6DL_PAD_KEY_ROW3__I2C2_SDA | PC,
+			.gpio_mode = MX6DL_PAD_KEY_ROW3__GPIO4_IO13 | PC,
+			.gp = IMX_GPIO_NR(4, 13)
+		}
+	}, {
+		.scl = {
+			.i2c_mode = MX6DL_PAD_GPIO_3__I2C3_SCL | PC,
+			.gpio_mode = MX6DL_PAD_GPIO_3__GPIO1_IO03 | PC,
+			.gp = IMX_GPIO_NR(1, 3)
+		},
+		.sda = {
+			.i2c_mode = MX6DL_PAD_GPIO_6__I2C3_SDA | PC,
+			.gpio_mode = MX6DL_PAD_GPIO_6__GPIO1_IO06 | PC,
+			.gp = IMX_GPIO_NR(1, 6)
+		}
+	}
+};
+
+static void setup_ventana_i2c(int i2c)
+{
+	struct i2c_pads_info *p;
+
+	if (is_cpu_type(MXC_CPU_MX6Q))
+		p = &mx6q_i2c_pad_info[i2c];
+	else
+		p = &mx6dl_i2c_pad_info[i2c];
+
+	setup_i2c(i2c, CONFIG_SYS_I2C_SPEED, 0x7f, p);
+}
+
+/* setup board specific PMIC */
+void setup_pmic(void)
+{
+	struct pmic *p;
+	struct ventana_board_info ventana_info;
+	int board = read_eeprom(CONFIG_I2C_GSC, &ventana_info);
+	const int i2c_pmic = 1;
+	u32 reg;
+	char rev;
+	int i;
+
+	/* determine board revision */
+	rev = 'A';
+	for (i = sizeof(ventana_info.model) - 1; i > 0; i--) {
+		if (ventana_info.model[i] >= 'A') {
+			rev = ventana_info.model[i];
+			break;
+		}
+	}
+
+	i2c_set_bus_num(i2c_pmic);
+
+	/* configure PFUZE100 PMIC */
+	if (!i2c_probe(CONFIG_POWER_PFUZE100_I2C_ADDR)) {
+		debug("probed PFUZE100 at 0x%x\n", CONFIG_POWER_PFUZE100_I2C_ADDR);
+		power_pfuze100_init(i2c_pmic);
+		p = pmic_get("PFUZE100");
+		if (p && !pmic_probe(p)) {
+			pmic_reg_read(p, PFUZE100_DEVICEID, &reg);
+			printf("PMIC:  PFUZE100 ID=0x%02x\n", reg);
+
+			/* Set VGEN1 to 1.5V and enable */
+			pmic_reg_read(p, PFUZE100_VGEN1VOL, &reg);
+			reg &= ~(LDO_VOL_MASK);
+			reg |= (LDOA_1_50V | LDO_EN);
+			pmic_reg_write(p, PFUZE100_VGEN1VOL, reg);
+
+			/* Set SWBST to 5.0V and enable */
+			pmic_reg_read(p, PFUZE100_SWBSTCON1, &reg);
+			reg &= ~(SWBST_MODE_MASK | SWBST_VOL_MASK);
+			reg |= (SWBST_5_00V | (SWBST_MODE_AUTO << SWBST_MODE_SHIFT));
+			pmic_reg_write(p, PFUZE100_SWBSTCON1, reg);
+
+			if (board == GW54xx && (rev == 'G')) {
+				/* Disable VGEN5 */
+				pmic_reg_write(p, PFUZE100_VGEN5VOL, 0);
+
+				/* Set VGEN6 to 2.5V and enable */
+				pmic_reg_read(p, PFUZE100_VGEN6VOL, &reg);
+				reg &= ~(LDO_VOL_MASK);
+				reg |= (LDOB_2_50V | LDO_EN);
+				pmic_reg_write(p, PFUZE100_VGEN6VOL, reg);
+			}
+		}
+
+		/* put all switchers in continuous mode */
+		pmic_reg_read(p, PFUZE100_SW1ABMODE, &reg);
+		reg &= ~(SW_MODE_MASK);
+		reg |= PWM_PWM;
+		pmic_reg_write(p, PFUZE100_SW1ABMODE, reg);
+
+		pmic_reg_read(p, PFUZE100_SW2MODE, &reg);
+		reg &= ~(SW_MODE_MASK);
+		reg |= PWM_PWM;
+		pmic_reg_write(p, PFUZE100_SW2MODE, reg);
+
+		pmic_reg_read(p, PFUZE100_SW3AMODE, &reg);
+		reg &= ~(SW_MODE_MASK);
+		reg |= PWM_PWM;
+		pmic_reg_write(p, PFUZE100_SW3AMODE, reg);
+
+		pmic_reg_read(p, PFUZE100_SW3BMODE, &reg);
+		reg &= ~(SW_MODE_MASK);
+		reg |= PWM_PWM;
+		pmic_reg_write(p, PFUZE100_SW3BMODE, reg);
+
+		pmic_reg_read(p, PFUZE100_SW4MODE, &reg);
+		reg &= ~(SW_MODE_MASK);
+		reg |= PWM_PWM;
+		pmic_reg_write(p, PFUZE100_SW4MODE, reg);
+	}
+
+	/* configure LTC3676 PMIC */
+	else if (!i2c_probe(CONFIG_POWER_LTC3676_I2C_ADDR)) {
+		debug("probed LTC3676 at 0x%x\n", CONFIG_POWER_LTC3676_I2C_ADDR);
+		power_ltc3676_init(i2c_pmic);
+		p = pmic_get("LTC3676_PMIC");
+		if (!p || pmic_probe(p))
+			return;
+		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.
+		 */
+		switch (board) {
+		case GW560x:
+			/* 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);
+			break;
+		case GW5903:
+			/* 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 SW4 transition */
+			pmic_reg_write(p, LTC3676_DVB4B,
+				       0x1f | LTC3676_PGOOD_MASK);
+			/* set SW4 (VDD_SOC) */
+			pmic_reg_write(p, LTC3676_DVB4A, 0x1f);
+			break;
+		case GW5905:
+			/* mask PGOOD during SW1 transition */
+			pmic_reg_write(p, LTC3676_DVB1B,
+				       0x1f | LTC3676_PGOOD_MASK);
+			/* set SW1 (VDD_ARM) */
+			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_SOC) */
+			pmic_reg_write(p, LTC3676_DVB3A, 0x1f);
+			break;
+		default:
+			/* 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);
+		}
+
+		/* put all switchers in continuous mode */
+		pmic_reg_write(p, LTC3676_BUCK1, 0xc0);
+		pmic_reg_write(p, LTC3676_BUCK2, 0xc0);
+		pmic_reg_write(p, LTC3676_BUCK3, 0xc0);
+		pmic_reg_write(p, LTC3676_BUCK4, 0xc0);
+	}
+
+	/* configure MP5416 PMIC */
+	else if (!i2c_probe(0x69)) {
+		puts("PMIC:  MP5416\n");
+		switch (board) {
+		case GW5910:
+			/* SW1: VDD_ARM 1.2V -> (1.275 to 1.475) */
+			reg = MP5416_VSET_EN | MP5416_VSET_SW1_SVAL(1475000);
+			i2c_write(0x69, MP5416_VSET_SW1, 1, (uint8_t *)&reg, 1);
+			/* SW4: VDD_SOC 1.2V -> (1.350 to 1.475) */
+			reg = MP5416_VSET_EN | MP5416_VSET_SW4_SVAL(1475000);
+			i2c_write(0x69, MP5416_VSET_SW4, 1, (uint8_t *)&reg, 1);
+			break;
+		}
+	}
+}
+
 /*
  * called from C runtime startup code (arch/arm/lib/crt0.S:_main)
  * - we have a stack and a place to store GD, both in SRAM
diff --git a/configs/gwventana_emmc_defconfig b/configs/gwventana_emmc_defconfig
index fc33dd26ae52..8f73f102c119 100644
--- a/configs/gwventana_emmc_defconfig
+++ b/configs/gwventana_emmc_defconfig
@@ -92,7 +92,7 @@ CONFIG_NETCONSOLE=y
 CONFIG_DM=y
 CONFIG_BOUNCE_BUFFER=y
 CONFIG_DWC_AHSATA=y
-CONFIG_SYS_I2C_LEGACY=y
+CONFIG_DM_I2C=y
 CONFIG_SPL_SYS_I2C_LEGACY=y
 CONFIG_SYS_I2C_MXC=y
 CONFIG_LED=y
diff --git a/configs/gwventana_gw5904_defconfig b/configs/gwventana_gw5904_defconfig
index 93fd748eabac..0d128872317d 100644
--- a/configs/gwventana_gw5904_defconfig
+++ b/configs/gwventana_gw5904_defconfig
@@ -92,7 +92,7 @@ CONFIG_NETCONSOLE=y
 CONFIG_DM=y
 CONFIG_BOUNCE_BUFFER=y
 CONFIG_DWC_AHSATA=y
-CONFIG_SYS_I2C_LEGACY=y
+CONFIG_DM_I2C=y
 CONFIG_SPL_SYS_I2C_LEGACY=y
 CONFIG_SYS_I2C_MXC=y
 CONFIG_LED=y
diff --git a/configs/gwventana_nand_defconfig b/configs/gwventana_nand_defconfig
index 7d23ea32cdf5..07a2b8c95725 100644
--- a/configs/gwventana_nand_defconfig
+++ b/configs/gwventana_nand_defconfig
@@ -94,7 +94,7 @@ CONFIG_NETCONSOLE=y
 CONFIG_DM=y
 CONFIG_BOUNCE_BUFFER=y
 CONFIG_DWC_AHSATA=y
-CONFIG_SYS_I2C_LEGACY=y
+CONFIG_DM_I2C=y
 CONFIG_SPL_SYS_I2C_LEGACY=y
 CONFIG_SYS_I2C_MXC=y
 CONFIG_LED=y
-- 
2.17.1



More information about the U-Boot mailing list