mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 15:41:40 +00:00
board: gateworks: gw_ventana: convert to DM_I2C
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@gateworks.com>
This commit is contained in:
parent
0c67906248
commit
cb339a0021
10 changed files with 334 additions and 295 deletions
|
@ -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@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, ®);
|
||||
printf("PMIC: PFUZE100 ID=0x%02x\n", reg);
|
||||
|
||||
/* Set VGEN1 to 1.5V and enable */
|
||||
pmic_reg_read(p, PFUZE100_VGEN1VOL, ®);
|
||||
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 &= ~(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 &= ~(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 &= ~(SW_MODE_MASK);
|
||||
reg |= PWM_PWM;
|
||||
pmic_reg_write(p, PFUZE100_SW1ABMODE, reg);
|
||||
|
||||
pmic_reg_read(p, PFUZE100_SW2MODE, ®);
|
||||
reg &= ~(SW_MODE_MASK);
|
||||
reg |= PWM_PWM;
|
||||
pmic_reg_write(p, PFUZE100_SW2MODE, reg);
|
||||
|
||||
pmic_reg_read(p, PFUZE100_SW3AMODE, ®);
|
||||
reg &= ~(SW_MODE_MASK);
|
||||
reg |= PWM_PWM;
|
||||
pmic_reg_write(p, PFUZE100_SW3AMODE, reg);
|
||||
|
||||
pmic_reg_read(p, PFUZE100_SW3BMODE, ®);
|
||||
reg &= ~(SW_MODE_MASK);
|
||||
reg |= PWM_PWM;
|
||||
pmic_reg_write(p, PFUZE100_SW3BMODE, reg);
|
||||
|
||||
pmic_reg_read(p, PFUZE100_SW4MODE, ®);
|
||||
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@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 *)®, 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 *)®, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include <fdt_support.h>
|
||||
#define WDOG1_ADDR 0x20bc000
|
||||
#define WDOG2_ADDR 0x20c0000
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, ®, 1)) {
|
||||
reg |= (1 << GSC_SC_CTRL1_WDDIS);
|
||||
if (!gsc_i2c_write(GSC_SC_ADDR, GSC_SC_CTRL1, 1, ®, 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, ®, 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, ®, 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, ®, 1))
|
||||
return CMD_RET_FAILURE;
|
||||
reg &= ~((1 << GSC_SC_CTRL1_WDEN) | (1 << GSC_SC_CTRL1_WDTIME));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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@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, ®);
|
||||
printf("PMIC: PFUZE100 ID=0x%02x\n", reg);
|
||||
|
||||
/* Set VGEN1 to 1.5V and enable */
|
||||
pmic_reg_read(p, PFUZE100_VGEN1VOL, ®);
|
||||
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 &= ~(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 &= ~(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 &= ~(SW_MODE_MASK);
|
||||
reg |= PWM_PWM;
|
||||
pmic_reg_write(p, PFUZE100_SW1ABMODE, reg);
|
||||
|
||||
pmic_reg_read(p, PFUZE100_SW2MODE, ®);
|
||||
reg &= ~(SW_MODE_MASK);
|
||||
reg |= PWM_PWM;
|
||||
pmic_reg_write(p, PFUZE100_SW2MODE, reg);
|
||||
|
||||
pmic_reg_read(p, PFUZE100_SW3AMODE, ®);
|
||||
reg &= ~(SW_MODE_MASK);
|
||||
reg |= PWM_PWM;
|
||||
pmic_reg_write(p, PFUZE100_SW3AMODE, reg);
|
||||
|
||||
pmic_reg_read(p, PFUZE100_SW3BMODE, ®);
|
||||
reg &= ~(SW_MODE_MASK);
|
||||
reg |= PWM_PWM;
|
||||
pmic_reg_write(p, PFUZE100_SW3BMODE, reg);
|
||||
|
||||
pmic_reg_read(p, PFUZE100_SW4MODE, ®);
|
||||
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@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 *)®, 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 *)®, 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
|
||||
|
|
|
@ -90,7 +90,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
|
||||
|
|
|
@ -90,7 +90,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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue