[U-Boot] [PATCH 04/14] imx: ventana: add support for GW5905

Tim Harvey
2019-02-04T21:10:50Z

The GW5905 is single-board tablet computer based on the i.MX6 SoC with the
following peripheral set:
- eMMC flash (boot device)
- microSD expansion
- LVDS display connector for off-board 3D+1C with PWM backlight
and I2C based touch controller
- MIPI camera connector supporting the TRULY CM8487-B500SA-E (OV5640)
- ublox EMMY-W1 WiFi/Bluetooth/NFC module (SDIO/UART)
- ublox ZOE-M8Q GPS
- LSM9DS1 9-DOF IMU
- 1x 1-lane miniPCIe socket with USB 2.0
- Gateworks System Controller
- Audio jack with TLV320AIC Audio Codec, Speaker AMP
and TSA227E Headphone detect
- MAX8607 3-mode LED camera flash
- DECT ULE module
- FUSB302 USB-C PD and ISL9238 Battery charger

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
board/gateworks/gw_ventana/common.c | 97 ++++++++++++++++++++-
board/gateworks/gw_ventana/eeprom.c | 4 +-
board/gateworks/gw_ventana/gsc.c | 6 +-
board/gateworks/gw_ventana/gsc.h | 3 +-
board/gateworks/gw_ventana/gw_ventana.c | 2 +-
board/gateworks/gw_ventana/gw_ventana_spl.c | 48 ++++++++--
board/gateworks/gw_ventana/ventana_eeprom.h | 1 +
7 files changed, 149 insertions(+), 12 deletions(-)

diff --git a/board/gateworks/gw_ventana/common.c b/board/gateworks/gw_ventana/common.c
index 676a1a8f42..b962b4b29d 100644
--- a/board/gateworks/gw_ventana/common.c
+++ b/board/gateworks/gw_ventana/common.c
@@ -457,6 +457,47 @@ static iomux_v3_cfg_t const gw5904_gpio_pads[] = {
IOMUX_PADS(PAD_SD2_DAT2__GPIO1_IO13 | DIO_PAD_CFG),
};

+static iomux_v3_cfg_t const gw5905_gpio_pads[] = {
+ /* EMMY_PDN# */
+ IOMUX_PADS(PAD_NANDF_D3__GPIO2_IO03 | DIO_PAD_CFG),
+ /* MX6_LOCLED# */
+ IOMUX_PADS(PAD_NANDF_CS1__GPIO6_IO14 | DIO_PAD_CFG),
+ /* MIPI_RST */
+ IOMUX_PADS(PAD_SD2_DAT0__GPIO1_IO15 | DIO_PAD_CFG),
+ /* MIPI_PWDN */
+ IOMUX_PADS(PAD_SD2_DAT1__GPIO1_IO14 | DIO_PAD_CFG),
+ /* USBEHCI_SEL */
+ IOMUX_PADS(PAD_GPIO_7__GPIO1_IO07 | DIO_PAD_CFG),
+ /* PCI_RST# */
+ IOMUX_PADS(PAD_GPIO_16__GPIO7_IO11 | DIO_PAD_CFG),
+ /* LVDS_BKLEN # */
+ IOMUX_PADS(PAD_GPIO_17__GPIO7_IO12 | DIO_PAD_CFG),
+ /* PCIESKT_WDIS# */
+ IOMUX_PADS(PAD_GPIO_18__GPIO7_IO13 | DIO_PAD_CFG),
+ /* SPK_SHDN# */
+ IOMUX_PADS(PAD_GPIO_19__GPIO4_IO05 | DIO_PAD_CFG),
+ /* LOCLED# */
+ IOMUX_PADS(PAD_NANDF_CS1__GPIO6_IO14 | DIO_PAD_CFG),
+ /* FLASH LED1 */
+ IOMUX_PADS(PAD_DISP0_DAT11__GPIO5_IO05 | DIO_PAD_CFG),
+ /* FLASH LED2 */
+ IOMUX_PADS(PAD_DISP0_DAT12__GPIO5_IO06 | DIO_PAD_CFG),
+ /* DECT_RST# */
+ IOMUX_PADS(PAD_DISP0_DAT20__GPIO5_IO14 | DIO_PAD_CFG),
+ /* USBH1_PEN (EHCI) */
+ IOMUX_PADS(PAD_EIM_D31__GPIO3_IO31 | DIO_PAD_CFG),
+ /* LVDS_PWM */
+ IOMUX_PADS(PAD_GPIO_9__GPIO1_IO09 | DIO_PAD_CFG),
+ /* CODEC_RST */
+ IOMUX_PADS(PAD_DISP0_DAT23__GPIO5_IO17 | DIO_PAD_CFG),
+ /* GYRO_CONTROL/DATA_EN */
+ IOMUX_PADS(PAD_CSI0_DAT8__GPIO5_IO26 | DIO_PAD_CFG),
+ /* TOUCH_RST */
+ IOMUX_PADS(PAD_KEY_COL1__GPIO4_IO08 | DIO_PAD_CFG),
+ /* TOUCH_IRQ */
+ IOMUX_PADS(PAD_KEY_COL0__GPIO4_IO06 | DIO_PAD_CFG),
+};
+
/* Digital I/O */
struct dio_cfg gw51xx_dio[] = {
{
@@ -993,8 +1034,25 @@ struct ventana gpio_cfg[GW_UNKNOWN] = {
.mezz_irq = IMX_GPIO_NR(2, 18),
.otgpwr_en = IMX_GPIO_NR(3, 22),
},
+
+ /* GW5905 */
+ {
+ .gpio_pads = gw5905_gpio_pads,
+ .num_pads = ARRAY_SIZE(gw5905_gpio_pads)/2,
+ .leds = {
+ IMX_GPIO_NR(6, 14),
+ },
+ .pcie_rst = IMX_GPIO_NR(7, 11),
+ .wdis = IMX_GPIO_NR(7, 13),
+ },
};

+#define SETUP_GPIO_OUTPUT(gpio, name, level) \
+ gpio_request(gpio, name); \
+ gpio_direction_output(gpio, level);
+#define SETUP_GPIO_INPUT(gpio, name) \
+ gpio_request(gpio, name); \
+ gpio_direction_input(gpio);
void setup_iomux_gpio(int board, struct ventana_board_info *info)
{
int i;
@@ -1143,6 +1201,28 @@ void setup_iomux_gpio(int board, struct ventana_board_info *info)
gpio_request(IMX_GPIO_NR(1, 13), "m2_rst#");
gpio_direction_output(IMX_GPIO_NR(1, 13), 1);
break;
+ case GW5905:
+ SETUP_GPIO_OUTPUT(IMX_GPIO_NR(1, 7), "usb_pcisel", 0);
+ SETUP_GPIO_OUTPUT(IMX_GPIO_NR(1, 9), "lvds_cabc", 1);
+ SETUP_GPIO_OUTPUT(IMX_GPIO_NR(1, 14), "mipi_pdwn", 1);
+ SETUP_GPIO_OUTPUT(IMX_GPIO_NR(1, 15), "mipi_rst#", 0);
+ SETUP_GPIO_OUTPUT(IMX_GPIO_NR(2, 3), "emmy_pdwn#", 1);
+ SETUP_GPIO_OUTPUT(IMX_GPIO_NR(4, 5), "spk_shdn#", 0);
+ SETUP_GPIO_OUTPUT(IMX_GPIO_NR(4, 8), "touch_rst", 0);
+ SETUP_GPIO_OUTPUT(IMX_GPIO_NR(4, 6), "touch_irq", 0);
+ SETUP_GPIO_OUTPUT(IMX_GPIO_NR(5, 5), "flash_en1", 0);
+ SETUP_GPIO_OUTPUT(IMX_GPIO_NR(5, 6), "flash_en2", 0);
+ SETUP_GPIO_OUTPUT(IMX_GPIO_NR(5, 14), "dect_rst#", 1);
+ SETUP_GPIO_OUTPUT(IMX_GPIO_NR(5, 17), "codec_rst#", 0);
+ SETUP_GPIO_OUTPUT(IMX_GPIO_NR(5, 26), "imu_den", 1);
+ SETUP_GPIO_OUTPUT(IMX_GPIO_NR(7, 12), "lvds_cabc", 0);
+ mdelay(100);
+ /*
+ * gauruntee touch controller comes out of reset with INT
+ * low for address
+ */
+ SETUP_GPIO_OUTPUT(IMX_GPIO_NR(4, 8), "touch_rst", 1);
+ break;
}
}

@@ -1292,7 +1372,7 @@ void setup_pmic(void)
pmic_reg_write(p, LTC3676_DVB3A, 0x1f);
break;
case GW5903:
- /* mask PGOOD during SW1 transition */
+ /* mask PGOOD during SW3 transition */
pmic_reg_write(p, LTC3676_DVB3B,
0x1f | LTC3676_PGOOD_MASK);
/* set SW3 (VDD_ARM) */
@@ -1304,6 +1384,19 @@ void setup_pmic(void)
/* 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,
@@ -1371,6 +1464,7 @@ int board_mmc_init(bd_t *bis)
usdhc_cfg[1].max_bus_width = 4;
return fsl_esdhc_initialize(bis, &usdhc_cfg[1]);
case GW5904:
+ case GW5905:
/* usdhc3: 8bit eMMC */
SETUP_IOMUX_PADS(gw5904_emmc_pads);
usdhc_cfg[0].esdhc_base = USDHC3_BASE_ADDR;
@@ -1399,6 +1493,7 @@ int board_mmc_getcd(struct mmc *mmc)
break;
case GW5903:
case GW5904:
+ case GW5905:
/* emmc is always present */
if (cfg->esdhc_base == USDHC3_BASE_ADDR)
return 1;
diff --git a/board/gateworks/gw_ventana/eeprom.c b/board/gateworks/gw_ventana/eeprom.c
index f0ae820988..13ccf2b059 100644
--- a/board/gateworks/gw_ventana/eeprom.c
+++ b/board/gateworks/gw_ventana/eeprom.c
@@ -99,8 +99,10 @@ read_eeprom(int bus, struct ventana_board_info *info)
case '9':
if (info->model[4] == '0' && info->model[5] == '3')
type = GW5903;
- if (info->model[4] == '0' && info->model[5] == '4')
+ else if (info->model[4] == '0' && info->model[5] == '4')
type = GW5904;
+ else if (info->model[4] == '0' && info->model[5] == '5')
+ type = GW5905;
break;
}
return type;
diff --git a/board/gateworks/gw_ventana/gsc.c b/board/gateworks/gw_ventana/gsc.c
index c31ef117b2..068f8cd9e7 100644
--- a/board/gateworks/gw_ventana/gsc.c
+++ b/board/gateworks/gw_ventana/gsc.c
@@ -70,7 +70,7 @@ static void read_hwmon(const char *name, uint reg, uint size)
puts("fRD\n");
} else {
ui = buf[0] | (buf[1]<<8) | (buf[2]<<16);
- if (reg == GSC_HWMON_TEMP && ui > 0x8000)
+ if (size == 2 && ui > 0x8000)
ui -= 0xffff;
if (ui == 0xffffff)
puts("invalid\n");
@@ -140,6 +140,10 @@ int gsc_info(int verbose)
read_hwmon("VDD_IO4", GSC_HWMON_VDD_IO4, 3);
read_hwmon("VDD_GPS", GSC_HWMON_VDD_IO3, 3);
break;
+ case '9': /* GW590x */
+ read_hwmon("AMONBMON", GSC_HWMON_VDD_IO3, 3);
+ read_hwmon("BAT_VOLT", GSC_HWMON_VDD_EXT, 3);
+ read_hwmon("BAT_TEMP", GSC_HWMON_VDD_IO4, 2);
}
return 0;
}
diff --git a/board/gateworks/gw_ventana/gsc.h b/board/gateworks/gw_ventana/gsc.h
index 0cce9b1b3a..6dcaafadf3 100644
--- a/board/gateworks/gw_ventana/gsc.h
+++ b/board/gateworks/gw_ventana/gsc.h
@@ -48,9 +48,10 @@ enum {
GSC_HWMON_VBATT = 0x08,
GSC_HWMON_VDD_5P0 = 0x0b,
GSC_HWMON_VDD_CORE = 0x0e,
+ GSC_HWMON_VDD_SOC = 0x11,
GSC_HWMON_VDD_HIGH = 0x14,
GSC_HWMON_VDD_DDR = 0x17,
- GSC_HWMON_VDD_SOC = 0x11,
+ GSC_HWMON_VDD_EXT = 0x1a,
GSC_HWMON_VDD_1P8 = 0x1d,
GSC_HWMON_VDD_IO2 = 0x20,
GSC_HWMON_VDD_2P5 = 0x23,
diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c
index c0b0cc9bb9..e1ad0fc9a0 100644
--- a/board/gateworks/gw_ventana/gw_ventana.c
+++ b/board/gateworks/gw_ventana/gw_ventana.c
@@ -709,7 +709,7 @@ static const struct boot_mode board_boot_modes[] = {
/* NAND: 64pages per block, 3 row addr cycles, 2 copies of FCB/DBBT */
{ "nand", MAKE_CFGVAL(0x80, 0x02, 0x00, 0x00) },
{ "emmc2", MAKE_CFGVAL(0x60, 0x48, 0x00, 0x00) }, /* GW5600 */
- { "emmc3", MAKE_CFGVAL(0x60, 0x50, 0x00, 0x00) }, /* GW5903/GW5904 */
+ { "emmc3", MAKE_CFGVAL(0x60, 0x50, 0x00, 0x00) }, /* GW5903/4/5 */
{ NULL, 0 },
};
#endif
diff --git a/board/gateworks/gw_ventana/gw_ventana_spl.c b/board/gateworks/gw_ventana/gw_ventana_spl.c
index 80ade9f437..280493dd46 100644
--- a/board/gateworks/gw_ventana/gw_ventana_spl.c
+++ b/board/gateworks/gw_ventana/gw_ventana_spl.c
@@ -390,6 +390,25 @@ static struct mx6_mmdc_calibration mx6sdl_256x64x2_mmdc_calib = {
.p1_mpwrdlctl = 0x3F36363F,
};

+static struct mx6_mmdc_calibration mx6sdl_128x64x2_mmdc_calib = {
+ /* write leveling calibration determine */
+ .p0_mpwldectrl0 = 0x001F003F,
+ .p0_mpwldectrl1 = 0x001F001F,
+ .p1_mpwldectrl0 = 0x001F004E,
+ .p1_mpwldectrl1 = 0x0059001F,
+ /* Read DQS Gating calibration */
+ .p0_mpdgctrl0 = 0x42220225,
+ .p0_mpdgctrl1 = 0x0213021F,
+ .p1_mpdgctrl0 = 0x022C0242,
+ .p1_mpdgctrl1 = 0x022C0244,
+ /* Read Calibration: DQS delay relative to DQ read access */
+ .p0_mprddlctl = 0x474A4C4A,
+ .p1_mprddlctl = 0x48494C45,
+ /* Write Calibration: DQ/DM delay relative to DQS write access */
+ .p0_mpwrdlctl = 0x3F3F3F36,
+ .p1_mpwrdlctl = 0x3F36363F,
+};
+
static struct mx6_mmdc_calibration mx6dq_512x32_mmdc_calib = {
/* write leveling calibration determine */
.p0_mpwldectrl0 = 0x002A0025,
@@ -519,18 +538,33 @@ static void spl_dram_init(int width, int size_mb, int board_model)
calib = &mx6sdl_128x64_mmdc_calib;
debug("2gB density\n");
} else if (width == 64 && size_mb == 2048) {
- mem = &mt41k256m16ha_125;
- if (is_cpu_type(MXC_CPU_MX6Q))
- calib = &mx6dq_256x64_mmdc_calib;
- else
- calib = &mx6sdl_256x64_mmdc_calib;
- debug("4gB density\n");
+ switch(board_model) {
+ case GW5905:
+ /* 8xMT41K128M16 (2GiB) fly-by mirrored 2-chipsels */
+ mem = &mt41k128m16jt_125;
+ debug("2gB density - 2 chipsel\n");
+ if (!is_cpu_type(MXC_CPU_MX6Q)) {
+ calib = &mx6sdl_128x64x2_mmdc_calib;
+ sysinfo.ncs = 2;
+ sysinfo.cs_density = 10; /* CS0_END=39 */
+ sysinfo.cs1_mirror = 1; /* mirror enabled */
+ }
+ break;
+ default:
+ mem = &mt41k256m16ha_125;
+ if (is_cpu_type(MXC_CPU_MX6Q))
+ calib = &mx6dq_256x64_mmdc_calib;
+ else
+ calib = &mx6sdl_256x64_mmdc_calib;
+ debug("4gB density\n");
+ break;
+ }
} else if (width == 64 && size_mb == 4096) {
switch(board_model) {
case GW5903:
/* 8xMT41K256M16 (4GiB) fly-by mirrored 2-chipsels */
mem = &mt41k256m16ha_125;
- debug("4gB density\n");
+ debug("4gB density - 2 chipsel\n");
if (!is_cpu_type(MXC_CPU_MX6Q)) {
calib = &mx6sdl_256x64x2_mmdc_calib;
sysinfo.ncs = 2;
diff --git a/board/gateworks/gw_ventana/ventana_eeprom.h b/board/gateworks/gw_ventana/ventana_eeprom.h
index d2a16f1a00..f2d87373ec 100644
--- a/board/gateworks/gw_ventana/ventana_eeprom.h
+++ b/board/gateworks/gw_ventana/ventana_eeprom.h
@@ -114,6 +114,7 @@ enum {
GW560x,
GW5903,
GW5904,
+ GW5905,
GW_UNKNOWN,
GW_BADCRC,
};
--
2.17.1