diff mbox

[U-Boot,2/2] ventana: Add Gateworks Ventana family support

Message ID 1391284192-8440-3-git-send-email-tharvey@gateworks.com
State Superseded
Delegated to: Stefano Babic
Headers show

Commit Message

Tim Harvey Feb. 1, 2014, 7:49 p.m. UTC
Gateworks Ventana is a product family based on the i.MX6.  This
patch adds support for all boards in the Ventana family. Where
possible, data from the boards EEPROM is used to determine various
details about the board at runtime.

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
 board/gateworks/gw_ventana/Makefile         |   10 +
 board/gateworks/gw_ventana/README           |   56 ++
 board/gateworks/gw_ventana/clocks.cfg       |   42 +
 board/gateworks/gw_ventana/gsc.c            |  129 +++
 board/gateworks/gw_ventana/gsc.h            |    9 +
 board/gateworks/gw_ventana/gw_ventana.c     | 1200 +++++++++++++++++++++++++++
 board/gateworks/gw_ventana/gw_ventana.cfg   |   42 +
 board/gateworks/gw_ventana/ventana_eeprom.h |  103 +++
 boards.cfg                                  |    5 +
 include/configs/gw_ventana.h                |  418 ++++++++++
 10 files changed, 2014 insertions(+)
 create mode 100644 board/gateworks/gw_ventana/Makefile
 create mode 100644 board/gateworks/gw_ventana/README
 create mode 100644 board/gateworks/gw_ventana/clocks.cfg
 create mode 100644 board/gateworks/gw_ventana/gsc.c
 create mode 100644 board/gateworks/gw_ventana/gsc.h
 create mode 100644 board/gateworks/gw_ventana/gw_ventana.c
 create mode 100644 board/gateworks/gw_ventana/gw_ventana.cfg
 create mode 100644 board/gateworks/gw_ventana/ventana_eeprom.h
 create mode 100644 include/configs/gw_ventana.h

Comments

Stefano Babic Feb. 3, 2014, 5:39 p.m. UTC | #1
Hi Tim,

On 01/02/2014 20:49, Tim Harvey wrote:
> Gateworks Ventana is a product family based on the i.MX6.  This
> patch adds support for all boards in the Ventana family. Where
> possible, data from the boards EEPROM is used to determine various
> details about the board at runtime.
> 
> Signed-off-by: Tim Harvey <tharvey@gateworks.com>
> ---
>  board/gateworks/gw_ventana/Makefile         |   10 +
>  board/gateworks/gw_ventana/README           |   56 ++
>  board/gateworks/gw_ventana/clocks.cfg       |   42 +
>  board/gateworks/gw_ventana/gsc.c            |  129 +++
>  board/gateworks/gw_ventana/gsc.h            |    9 +
>  board/gateworks/gw_ventana/gw_ventana.c     | 1200 +++++++++++++++++++++++++++
>  board/gateworks/gw_ventana/gw_ventana.cfg   |   42 +
>  board/gateworks/gw_ventana/ventana_eeprom.h |  103 +++
>  boards.cfg                                  |    5 +
>  include/configs/gw_ventana.h                |  418 ++++++++++
>  10 files changed, 2014 insertions(+)
>  create mode 100644 board/gateworks/gw_ventana/Makefile
>  create mode 100644 board/gateworks/gw_ventana/README
>  create mode 100644 board/gateworks/gw_ventana/clocks.cfg
>  create mode 100644 board/gateworks/gw_ventana/gsc.c
>  create mode 100644 board/gateworks/gw_ventana/gsc.h
>  create mode 100644 board/gateworks/gw_ventana/gw_ventana.c
>  create mode 100644 board/gateworks/gw_ventana/gw_ventana.cfg
>  create mode 100644 board/gateworks/gw_ventana/ventana_eeprom.h
>  create mode 100644 include/configs/gw_ventana.h
> 
> diff --git a/board/gateworks/gw_ventana/Makefile b/board/gateworks/gw_ventana/Makefile
> new file mode 100644
> index 0000000..e8dab89
> --- /dev/null
> +++ b/board/gateworks/gw_ventana/Makefile
> @@ -0,0 +1,10 @@
> +#
> +# Copyright (C) 2012-2013, Guennadi Liakhovetski <lg@denx.de>
> +# (C) Copyright 2012-2013 Freescale Semiconductor, Inc.
> +# Copyright (C) 2013, Gateworks Corporation
> +#
> +# SPDX-License-Identifier:  GPL-2.0+
> +#
> +
> +obj-y  := gw_ventana.o gsc.o
> +
> diff --git a/board/gateworks/gw_ventana/README b/board/gateworks/gw_ventana/README
> new file mode 100644
> index 0000000..f744a4a
> --- /dev/null
> +++ b/board/gateworks/gw_ventana/README
> @@ -0,0 +1,56 @@
> +U-Boot for the Gateworks Ventana Product Family boards
> +
> +This file contains information for the port of U-Boot to the Gateworks
> +Ventana Product family boards.
> +
> +1. Boot source, boot from NAND
> +------------------------------
> +
> +The i.MX6 BOOT ROM expects some structures that provide details of NAND layout
> +and bad block information (referred to as 'bootstreams') which are replicated
> +multiple times in NAND. The number of replications is configurable through
> +board strapping options and eFUSE settings.  The Freescale 'kobs-ng'
> +application from the Freescale LTIB BSP, which runs under Linux, must be used
> +to program the bootstream in order to setup the replicated headers correctly.
> +
> +The Gateworks Ventana boards with NAND flash have been factory programmed
> +such that their eFUSE settings expect 2 copies of the boostream (this is
> +specified by providing kobs-ng with the --search_exponent=1 argument). Once in
> +Linux with MTD support for the NAND on /dev/mtd0 you can program the boostream
> +with:
> +
> +kobs-ng init -v -x --search_exponent=1 u-boot.imx
> +
> +The kobs-ng application users an imximage (u-boot.imx) which contains the
                            ^-- spelling, uses

> +Image Vector Table (IVT) and Device Configuration Data (DCD) structures that
> +the i.MX6 BOOT ROM requires to boot.  The kobs-ng adds the Firmware
> +Configuration Block (FCB) and Discovered Bad Block Table (DBBT).
> +
> +This information is taken from:
> +  http://trac.gateworks.com/wiki/ventana/bootloader#NANDFLASH
> +
> +More details about the i.MX6 BOOT ROM can be found at:
> +  http://cache.freescale.com/files/32bit/doc/ref_manual/IMX6DQRM.pdf

Why cache.freescale ? I think you can simply write that more information
are in the User Manual. Freescale moves sometimes the location of the
documentation.

> diff --git a/board/gateworks/gw_ventana/gsc.c b/board/gateworks/gw_ventana/gsc.c
> new file mode 100644
> index 0000000..72eec38
> --- /dev/null
> +++ b/board/gateworks/gw_ventana/gsc.c
> @@ -0,0 +1,129 @@
> +/*
> + * Copyright (C) 2013 Gateworks Corporation
> + *
> + * Author: Tim Harvey <tharvey@gateworks.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <asm/errno.h>
> +#include <common.h>
> +#include <i2c.h>
> +#include <linux/ctype.h>
> +
> +/*
> + * 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.
> + * When this does occur, it will never be busy long enough to fail more than
> + * 2 back-to-back transfers.  Thus we wrap i2c_read and i2c_write with
> + * 3 retries.
> + */
> +int gsc_i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
> +{
> +	int retry = 3;
> +	int n = 0;
> +	int ret;
> +
> +	while (n++ < retry) {
> +		ret = i2c_read(chip, addr, alen, buf, len);
> +		if (!ret)
> +			break;
> +		printf("%s: 0x%02x 0x%02x retry%d: %d\n", __func__, chip, addr,
> +		       n, ret);

This is a debug message - you could use debug() instead of printf() to
conditionally compile it.

> +		if (ret != -ENODEV)
> +			break;
> +		mdelay(10);
> +	}
> +	return ret;
> +}

> +
> +int gsc_i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
> +{
> +	int retry = 3;
> +	int n = 0;
> +	int ret;
> +
> +	while (n++ < retry) {
> +		ret = i2c_write(chip, addr, alen, buf, len);
> +		if (!ret)
> +			break;
> +		printf("%s: 0x%02x 0x%02x retry%d: %d\n", __func__, chip, addr,
> +		       n, ret);

Ditto.

> +		if (ret != -ENODEV)
> +			break;
> +		mdelay(10);
> +	}
> +	mdelay(1);
> +	return ret;
> +}
> +
> +#ifdef CONFIG_CMD_GSC
> +static void read_hwmon(const char *name, uint reg, uint size, uint low,
> +		       uint high)
> +{
> +	unsigned char buf[3];
> +	uint ui;
> +
> +	printf("%-8s:", name);
> +	memset(buf, 0, sizeof(buf));
> +	if (gsc_i2c_read(0x29, reg, 1, buf, size)) {
                         ^---- use a #define for the I2c address

> +		puts("fRD\n");
> +	} else {
> +		ui = buf[0] | (buf[1]<<8) | (buf[2]<<16);
> +		if (ui == 0xffffff)
> +			printf("fVL");
> +		else if (ui < low)
> +			printf("%d fLO", ui);

What is fLO ? Low Overflow or what else ? Can you add comments to these ?

> +		else if (ui > high)
> +			printf("%d fHI", ui);
> +		else
> +			printf("%d", ui);
> +	}
> +	puts("\n");
> +}
> +
> +int do_gsc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +	const char *model = getenv("model");
> +
> +	i2c_set_bus_num(0);
> +	read_hwmon("Temp",     0x00, 2, 0, 9000);
> +	read_hwmon("VIN",      0x02, 3, 8000, 60000);
> +	read_hwmon("VDD_3P3",  0x05, 3, 3300*0.9, 3300*1.1);
> +	read_hwmon("VBATT",    0x08, 3, 2000*0.9, 3000*1.1);
> +	read_hwmon("VDD_HIGH", 0x14, 3, 3000*0.9, 3000*1.1);
> +	read_hwmon("VDD_DDR",  0x17, 3, 1500*0.9, 1500*1.1);
> +	read_hwmon("VDD_5P0",  0x0b, 3, 5000*0.9, 5000*1.1);
> +	read_hwmon("VDD_2P5",  0x23, 3, 2500*0.9, 2500*1.1);
> +	read_hwmon("VDD_1P8",  0x1d, 3, 1800*0.9, 1800*1.1);

It will be better to add the register layout to gsc.h and using the
defines here.

> +
> +	switch (model[3]) {
> +	case '1': /* GW51xx */
> +		read_hwmon("VDD_CORE", 0x0e, 3, 1175*0.9, 1175*1.1);
> +		read_hwmon("VDD_SOC",  0x11, 3, 1175*0.9, 1175*1.1);
> +		break;

What about a macro that get the variation in percent as parameter ?

> +	case '2': /* GW52xx */
> +		read_hwmon("VDD_CORE", 0x0e, 3, 1175*0.9, 1175*1.1);
> +		read_hwmon("VDD_SOC",  0x11, 3, 1175*0.9, 1175*1.1);
> +		read_hwmon("VDD_1P0",  0x20, 3, 1000*0.9, 1000*1.1);
> +		break;
> +	case '3': /* GW53xx */
> +		read_hwmon("VDD_CORE", 0x0e, 3, 1175*0.9, 1175*1.1);
> +		read_hwmon("VDD_SOC",  0x11, 3, 1175*0.9, 1175*1.1);
> +		read_hwmon("VDD_1P0",  0x20, 3, 1000*0.9, 1000*1.1);
> +		break;
> +	case '4': /* GW54xx */
> +		read_hwmon("VDD_CORE", 0x0e, 3, 1375*0.9, 1375*1.1);
> +		read_hwmon("VDD_SOC",  0x11, 3, 1375*0.9, 1375*1.1);
> +		read_hwmon("VDD_1P0",  0x20, 3, 1000*0.9, 1000*1.1);
> +		break;
> +	}
> +	return 0;
> +}
> +
> +U_BOOT_CMD(gsc, 1, 1, do_gsc,
> +	   "GSC test",
> +	   ""
> +);
> +
> +#endif /* CONFIG_CMD_GSC */
> diff --git a/board/gateworks/gw_ventana/gsc.h b/board/gateworks/gw_ventana/gsc.h
> new file mode 100644
> index 0000000..6b9cb98
> --- /dev/null
> +++ b/board/gateworks/gw_ventana/gsc.h
> @@ -0,0 +1,9 @@
> +#ifndef __ASSEMBLY__
> +/*
> + * I2C transactions to the GSC are done via these functions which
> + * perform retries in the case of a busy GSC NAK'ing the transaction
> + */
> +extern int gsc_i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len);
> +extern int gsc_i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len);

You do not need to use the "extern" keywords, see all other U-Boot
header files.

> +#endif
> +
> diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c
> new file mode 100644
> index 0000000..d8c9989
> --- /dev/null
> +++ b/board/gateworks/gw_ventana/gw_ventana.c
> @@ -0,0 +1,1200 @@
> +/*
> + * Copyright (C) 2013 Gateworks Corporation
> + *
> + * Author: Tim Harvey <tharvey@gateworks.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/imx-regs.h>
> +#include <asm/arch/iomux.h>
> +#include <asm/arch/mx6-pins.h>
> +#include <asm/arch/crm_regs.h>
> +#include <asm/arch/sys_proto.h>
> +#include <asm/gpio.h>
> +#include <asm/imx-common/iomux-v3.h>
> +#include <asm/imx-common/mxc_i2c.h>
> +#include <asm/imx-common/boot_mode.h>
> +#include <asm/imx-common/sata.h>
> +#include <jffs2/load_kernel.h>
> +#include <hwconfig.h>
> +#include <i2c.h>
> +#include <linux/ctype.h>
> +#include <fdt_support.h>
> +#include <fsl_esdhc.h>
> +#include <miiphy.h>
> +#include <mmc.h>
> +#include <mtd_node.h>
> +#include <netdev.h>
> +#include <power/pmic.h>
> +#include <power/pfuze100_pmic.h>
> +#include <i2c.h>
> +#include <fdt_support.h>
> +#include <jffs2/load_kernel.h>
> +#include <spi_flash.h>
> +
> +#include "gsc.h"
> +#include "ventana_eeprom.h"
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +/* GPIO's common to all baseboards */
> +#define GP_PHY_RST	IMX_GPIO_NR(1, 30)
> +#define GP_USB_OTG_PWR	IMX_GPIO_NR(3, 22)
> +#define GP_SD3_CD	IMX_GPIO_NR(7, 0)
> +#define GP_RS232_EN	IMX_GPIO_NR(2, 11)
> +#define GP_MSATA_SEL	IMX_GPIO_NR(2, 8)
> +
> +#define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |		\
> +	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |		\
> +	PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
> +
> +#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |		\
> +	PAD_CTL_PUS_47K_UP  | PAD_CTL_SPEED_LOW |		\
> +	PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
> +
> +#define ENET_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |		\
> +	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED	  |		\
> +	PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
> +
> +#define SPI_PAD_CTRL (PAD_CTL_HYS |				\
> +	PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED |		\
> +	PAD_CTL_DSE_40ohm     | PAD_CTL_SRE_FAST)
> +
> +#define DIO_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |		\
> +	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |		\
> +	PAD_CTL_DSE_34ohm | PAD_CTL_HYS | PAD_CTL_SRE_FAST)
> +
> +#define I2C_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
> +	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |	\
> +	PAD_CTL_ODE | PAD_CTL_SRE_FAST)
> +
> +/*
> + * EEPROM board info struct populated by read_eeprom so that we only have to
> + * read it once.
> + */
> +static struct ventana_board_info ventana_info;
> +
> +/* UART1: Function varies per baseboard */
> +iomux_v3_cfg_t const uart1_pads[] = {
> +	MX6_PAD_SD3_DAT6__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
> +	MX6_PAD_SD3_DAT7__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
> +};
> +
> +/* UART2: Serial Console */
> +iomux_v3_cfg_t const uart2_pads[] = {
> +	MX6_PAD_SD4_DAT7__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
> +	MX6_PAD_SD4_DAT4__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
> +};
> +
> +#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
> +
> +/* I2C1: GSC */
> +struct i2c_pads_info i2c_pad_info0 = {
> +	.scl = {
> +		.i2c_mode = MX6_PAD_EIM_D21__I2C1_SCL | PC,
> +		.gpio_mode = MX6_PAD_EIM_D21__GPIO3_IO21 | PC,
> +		.gp = IMX_GPIO_NR(3, 21)
> +	},
> +	.sda = {
> +		.i2c_mode = MX6_PAD_EIM_D28__I2C1_SDA | PC,
> +		.gpio_mode = MX6_PAD_EIM_D28__GPIO3_IO28 | PC,
> +		.gp = IMX_GPIO_NR(3, 28)
> +	}
> +};
> +
> +/* I2C2: PMIC/PCIe Switch/PCIe Clock/Mezz */
> +struct i2c_pads_info i2c_pad_info1 = {
> +	.scl = {
> +		.i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | PC,
> +		.gpio_mode = MX6_PAD_KEY_COL3__GPIO4_IO12 | PC,
> +		.gp = IMX_GPIO_NR(4, 12)
> +	},
> +	.sda = {
> +		.i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | PC,
> +		.gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | PC,
> +		.gp = IMX_GPIO_NR(4, 13)
> +	}
> +};
> +
> +/* I2C3: Misc/Expansion */
> +struct i2c_pads_info i2c_pad_info2 = {
> +	.scl = {
> +		.i2c_mode = MX6_PAD_GPIO_3__I2C3_SCL | PC,
> +		.gpio_mode = MX6_PAD_GPIO_3__GPIO1_IO03 | PC,
> +		.gp = IMX_GPIO_NR(1, 3)
> +	},
> +	.sda = {
> +		.i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA | PC,
> +		.gpio_mode = MX6_PAD_GPIO_6__GPIO1_IO06 | PC,
> +		.gp = IMX_GPIO_NR(1, 6)
> +	}
> +};
> +
> +/* MMC */
> +iomux_v3_cfg_t const usdhc3_pads[] = {
> +	MX6_PAD_SD3_CLK__SD3_CLK    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
> +	MX6_PAD_SD3_CMD__SD3_CMD    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
> +	MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
> +	MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
> +	MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
> +	MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
> +	MX6_PAD_SD3_DAT5__GPIO7_IO00  | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
> +};
> +
> +/* ENET */
> +iomux_v3_cfg_t const enet_pads[] = {
> +	MX6_PAD_ENET_MDIO__ENET_MDIO		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> +	MX6_PAD_ENET_MDC__ENET_MDC		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> +	MX6_PAD_RGMII_TXC__RGMII_TXC		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> +	MX6_PAD_RGMII_TD0__RGMII_TD0		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> +	MX6_PAD_RGMII_TD1__RGMII_TD1		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> +	MX6_PAD_RGMII_TD2__RGMII_TD2		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> +	MX6_PAD_RGMII_TD3__RGMII_TD3		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> +	MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL),
> +	MX6_PAD_ENET_REF_CLK__ENET_TX_CLK	| MUX_PAD_CTRL(ENET_PAD_CTRL),
> +	MX6_PAD_RGMII_RXC__RGMII_RXC		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> +	MX6_PAD_RGMII_RD0__RGMII_RD0		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> +	MX6_PAD_RGMII_RD1__RGMII_RD1		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> +	MX6_PAD_RGMII_RD2__RGMII_RD2		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> +	MX6_PAD_RGMII_RD3__RGMII_RD3		| MUX_PAD_CTRL(ENET_PAD_CTRL),
> +	MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL),
> +	/* PHY nRST */
> +	MX6_PAD_ENET_TXD0__GPIO1_IO30		| MUX_PAD_CTRL(NO_PAD_CTRL),
> +};
> +
> +/* NAND */
> +iomux_v3_cfg_t const nfc_pads[] = {
> +	MX6_PAD_NANDF_CLE__NAND_CLE     | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	MX6_PAD_NANDF_ALE__NAND_ALE     | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	MX6_PAD_NANDF_WP_B__NAND_WP_B   | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	MX6_PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	MX6_PAD_NANDF_CS0__NAND_CE0_B   | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	MX6_PAD_SD4_CMD__NAND_RE_B      | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	MX6_PAD_SD4_CLK__NAND_WE_B      | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	MX6_PAD_NANDF_D0__NAND_DATA00   | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	MX6_PAD_NANDF_D1__NAND_DATA01   | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	MX6_PAD_NANDF_D2__NAND_DATA02   | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	MX6_PAD_NANDF_D3__NAND_DATA03   | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	MX6_PAD_NANDF_D4__NAND_DATA04   | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	MX6_PAD_NANDF_D5__NAND_DATA05   | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	MX6_PAD_NANDF_D6__NAND_DATA06   | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	MX6_PAD_NANDF_D7__NAND_DATA07   | MUX_PAD_CTRL(NO_PAD_CTRL),
> +};
> +
> +#ifdef CONFIG_CMD_NAND
> +static void setup_gpmi_nand(void)
> +{
> +	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
> +
> +	/* config gpmi nand iomux */
> +	imx_iomux_v3_setup_multiple_pads(nfc_pads, ARRAY_SIZE(nfc_pads));
> +
> +	/* config gpmi and bch clock to 100 MHz */
> +	clrsetbits_le32(&mxc_ccm->cs2cdr,
> +			MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
> +			MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
> +			MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
> +			MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
> +			MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
> +			MXC_CCM_CS2CDR_ENFC_CLK_SEL(3));
> +
> +	/* enable gpmi and bch clock gating */
> +	setbits_le32(&mxc_ccm->CCGR4,
> +		     MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
> +		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
> +		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
> +		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
> +		     MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET);
> +
> +	/* enable apbh clock gating */
> +	setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
> +}
> +#endif
> +
> +static void setup_iomux_enet(void)
> +{
> +	imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
> +
> +	/* toggle PHY_RST# */
> +	gpio_direction_output(GP_PHY_RST, 0);
> +	mdelay(2);
> +	gpio_set_value(GP_PHY_RST, 1);
> +}
> +
> +static void setup_iomux_uart(void)
> +{
> +	imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
> +	imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
> +}
> +
> +#ifdef CONFIG_USB_EHCI_MX6
> +iomux_v3_cfg_t const usb_pads[] = {
> +	MX6_PAD_GPIO_1__USB_OTG_ID   | MUX_PAD_CTRL(DIO_PAD_CTRL),
> +	MX6_PAD_KEY_COL4__USB_OTG_OC | MUX_PAD_CTRL(DIO_PAD_CTRL),
> +	MX6_PAD_EIM_D22__GPIO3_IO22  | MUX_PAD_CTRL(DIO_PAD_CTRL), /* OTG PWR */
> +};
> +
> +int board_ehci_hcd_init(int port)
> +{
> +	struct ventana_board_info *info = &ventana_info;
> +
> +	imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads));
> +
> +	/* Reset USB HUB (present on GW54xx/GW53xx) */
> +	switch (info->model[3]) {
> +	case '3': /* GW53xx */
> +		imx_iomux_v3_setup_pad(MX6_PAD_GPIO_9__GPIO1_IO09|
> +				       MUX_PAD_CTRL(NO_PAD_CTRL));
> +		gpio_direction_output(IMX_GPIO_NR(1, 9), 0);
> +		mdelay(2);
> +		gpio_set_value(IMX_GPIO_NR(1, 9), 1);
> +		break;
> +	case '4': /* GW54xx */
> +		imx_iomux_v3_setup_pad(MX6_PAD_SD1_DAT0__GPIO1_IO16 |
> +				       MUX_PAD_CTRL(NO_PAD_CTRL));
> +		gpio_direction_output(IMX_GPIO_NR(1, 16), 0);
> +		mdelay(2);
> +		gpio_set_value(IMX_GPIO_NR(1, 16), 1);
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
> +int board_ehci_power(int port, int on)
> +{
> +	if (port)
> +		return 0;
> +	gpio_set_value(GP_USB_OTG_PWR, on);
> +	return 0;
> +}
> +#endif /* CONFIG_USB_EHCI_MX6 */
> +
> +#ifdef CONFIG_FSL_ESDHC
> +struct fsl_esdhc_cfg usdhc_cfg = { USDHC3_BASE_ADDR };
> +
> +int board_mmc_getcd(struct mmc *mmc)
> +{
> +	/* Card Detect */
> +	gpio_direction_input(GP_SD3_CD);
> +	return !gpio_get_value(GP_SD3_CD);
> +}
> +
> +int board_mmc_init(bd_t *bis)
> +{
> +	/* Only one USDHC controller on Ventana */
> +	imx_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
> +	usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
> +	usdhc_cfg.max_bus_width = 4;
> +
> +	return fsl_esdhc_initialize(bis, &usdhc_cfg);
> +}
> +#endif /* CONFIG_FSL_ESDHC */
> +
> +#ifdef CONFIG_MXC_SPI
> +iomux_v3_cfg_t const ecspi1_pads[] = {
> +	/* SS1 */
> +	MX6_PAD_EIM_D19__GPIO3_IO19  | MUX_PAD_CTRL(SPI_PAD_CTRL),
> +	MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
> +	MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
> +	MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
> +};
> +
> +static void setup_spi(void)
> +{
> +	gpio_direction_output(CONFIG_SF_DEFAULT_CS, 1);
> +	imx_iomux_v3_setup_multiple_pads(ecspi1_pads,
> +					 ARRAY_SIZE(ecspi1_pads));
> +}
> +#endif
> +
> +/* configure eth0 PHY board-specific LED behavior */
> +int board_phy_config(struct phy_device *phydev)
> +{
> +	unsigned short val;
> +
> +	/* Marvel 88E1510 */
> +	if (phydev->phy_id == 0x1410dd1) {
> +		/*
> +		 * Page 3, Register 16: LED[2:0] Function Control Register
> +		 * LED[0] (SPD:Amber) R16_3.3:0 to 0111: on-GbE link
> +		 * LED[1] (LNK:Green) R16_3.7:4 to 0001: on-link, blink-activity
> +		 */
> +		phy_write(phydev, MDIO_DEVAD_NONE, 22, 3);
> +		val = phy_read(phydev, MDIO_DEVAD_NONE, 16);
> +		val &= 0xff00;
> +		val |= 0x0017;
> +		phy_write(phydev, MDIO_DEVAD_NONE, 16, val);
> +		phy_write(phydev, MDIO_DEVAD_NONE, 22, 0);
> +	}
> +
> +	if (phydev->drv->config)
> +		phydev->drv->config(phydev);
> +
> +	return 0;
> +}
> +
> +int board_eth_init(bd_t *bis)
> +{
> +	setup_iomux_enet();
> +
> +#ifdef CONFIG_FEC_MXC
> +	cpu_eth_init(bis);
> +#endif
> +
> +#ifdef CONFIG_MV_UDC
> +	/* For otg ethernet*/
> +	usb_eth_initialize(bis);
> +#endif
> +
> +	return 0;
> +}
> +
> +/*
> + * read ventana EEPROM and return structure or NULL on error
> + * should be called once, the first time eeprom data is needed
> + */
> +static void
> +read_eeprom(void)
> +{
> +	int i;
> +	int chksum;
> +	struct ventana_board_info *info = &ventana_info;
> +	unsigned char *buf = (unsigned char *)&ventana_info;
> +
> +	memset(info, 0, sizeof(ventana_info));
> +
> +	/*
> +	 * On a board with a missing/depleted backup battery for GSC, the
> +	 * board may be ready to probe the GSC before its firmware is
> +	 * running.  We will wait here indefinately for the GSC/EEPROM.
> +	 */
> +	while (1) {
> +		if (0 == i2c_set_bus_num(0) && 0 == i2c_probe(0x51))
> +			break;
> +		mdelay(1);
> +	}
> +
> +	/* read eeprom config section */
> +	if (gsc_i2c_read(0x51, 0x00, 1, buf, sizeof(ventana_info))) {

Use define for I2C address. Fix it globally.

> +		puts("EEPROM: Failed to read EEPROM\n");
> +		info->model[0] = 0;
> +		return;
> +	}
> +
> +	/* sanity checks */
> +	if (info->model[0] != 'G' || info->model[1] != 'W') {
> +		puts("EEPROM: Invalid Model in EEPROM\n");
> +		info->model[0] = 0;
> +		return;
> +	}
> +
> +	/* validate checksum */
> +	for (chksum = 0, i = 0; i < sizeof(*info)-2; i++)
> +		chksum += buf[i];
> +	if ((info->chksum[0] != chksum>>8) ||
> +	    (info->chksum[1] != (chksum&0xff))) {
> +		puts("EEPROM: Failed EEPROM checksum\n");
> +		info->model[0] = 0;
> +		return;
> +	}
> +}
> +
> +/*
> + * Baseboard specific GPIO
> + */
> +
> +/* common to add baseboards */
> +static iomux_v3_cfg_t const gw_gpio_pads[] = {
> +	/* MSATA_EN */
> +	MX6_PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* RS232_EN# */
> +	MX6_PAD_SD4_DAT3__GPIO2_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +};
> +
> +/* prototype */
> +static iomux_v3_cfg_t const gwproto_gpio_pads[] = {
> +	/* PANLEDG# */
> +	MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* PANLEDR# */
> +	MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* LOCLED# */
> +	MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* RS485_EN */
> +	MX6_PAD_SD3_DAT4__GPIO7_IO01 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* IOEXP_PWREN# */
> +	MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* IOEXP_IRQ# */
> +	MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* VID_EN */
> +	MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* DIOI2C_DIS# */
> +	MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* PCICK_SSON */
> +	MX6_PAD_SD1_CLK__GPIO1_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* PCI_RST# */
> +	MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +};
> +
> +static iomux_v3_cfg_t const gw51xx_gpio_pads[] = {
> +	/* PANLEDG# */
> +	MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* PANLEDR# */
> +	MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* IOEXP_PWREN# */
> +	MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* IOEXP_IRQ# */
> +	MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +
> +	/* GPS_SHDN */
> +	MX6_PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* VID_PWR */
> +	MX6_PAD_CSI0_DATA_EN__GPIO5_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* PCI_RST# */
> +	MX6_PAD_GPIO_0__GPIO1_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +};
> +
> +static iomux_v3_cfg_t const gw52xx_gpio_pads[] = {
> +	/* PANLEDG# */
> +	MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* PANLEDR# */
> +	MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* IOEXP_PWREN# */
> +	MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* IOEXP_IRQ# */
> +	MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +
> +	/* MX6_LOCLED# */
> +	MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* GPS_SHDN */
> +	MX6_PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* USBOTG_SEL */
> +	MX6_PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* VID_PWR */
> +	MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* PCI_RST# */
> +	MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +};
> +
> +static iomux_v3_cfg_t const gw53xx_gpio_pads[] = {
> +	/* PANLEDG# */
> +	MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* PANLEDR# */
> +	MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* IOEXP_PWREN# */
> +	MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* IOEXP_IRQ# */
> +	MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +
> +	/* MX6_LOCLED# */
> +	MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* GPS_SHDN */
> +	MX6_PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* VID_EN */
> +	MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* PCI_RST# */
> +	MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +};
> +
> +static iomux_v3_cfg_t const gw54xx_gpio_pads[] = {
> +	/* PANLEDG# */
> +	MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* PANLEDR# */
> +	MX6_PAD_KEY_COL2__GPIO4_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* MX6_LOCLED# */
> +	MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* MIPI_DIO */
> +	MX6_PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* RS485_EN */
> +	MX6_PAD_EIM_D24__GPIO3_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* IOEXP_PWREN# */
> +	MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* IOEXP_IRQ# */
> +	MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* DIOI2C_DIS# */
> +	MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* DIOI2C_DIS# */
> +	MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* PCICK_SSON */
> +	MX6_PAD_SD1_CLK__GPIO1_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +	/* PCI_RST# */
> +	MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
> +};
> +
> +/* setup GPIO pinmux and default configuration per baseboard */
> +static void setup_board_gpio(void)
> +{
> +	struct ventana_board_info *info = &ventana_info;
> +	const char *s;
> +	char arg[10];
> +	size_t len;
> +	int i;
> +	char baseboard = info->model[3];
> +	enum {
> +		GW51xx,
> +		GW52xx,
> +		GW53xx,
> +		GW54xx,
> +		GW54proto, /* original GW5400-A prototype */
> +		UNKNOWN,
> +	};
> +	struct dio_cfg {
> +		iomux_v3_cfg_t gpio_padmux;
> +		unsigned gpio_param;
> +		iomux_v3_cfg_t pwm_padmux;
> +		unsigned pwm_param;
> +	};
> +	int board_type = UNKNOWN;
> +	int quiet = simple_strtol(getenv("quiet"), NULL, 10);
> +	struct dio_cfg dio_cfg[] = {
> +		/* GW51xx */
> +		{ MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16),
> +			0, 0 },
> +		{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
> +			MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
> +		{ MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17),
> +			MX6_PAD_SD1_DAT1__PWM3_OUT, 3 },
> +		{ MX6_PAD_SD1_CMD__GPIO1_IO18, IMX_GPIO_NR(1, 18),
> +			MX6_PAD_SD1_CMD__PWM4_OUT, 4 },
> +
> +		/* GW52xx */
> +		{ MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16),
> +			0, 0 },
> +		{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
> +			MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
> +		{ MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17),
> +			MX6_PAD_SD1_DAT1__PWM3_OUT, 3 },
> +		{ MX6_PAD_SD1_CLK__GPIO1_IO20, IMX_GPIO_NR(1, 20),
> +			0, 0 },
> +
> +		/* GW53xx */
> +		{ MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16),
> +			0, 0 },
> +		{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
> +			MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
> +		{ MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17),
> +			MX6_PAD_SD1_DAT1__PWM3_OUT, 3 },
> +		{ MX6_PAD_SD1_CLK__GPIO1_IO20, IMX_GPIO_NR(1, 20),
> +			0, 0 },
> +
> +		/* GW54xx */
> +		{ MX6_PAD_GPIO_9__GPIO1_IO09, IMX_GPIO_NR(1, 9),
> +			MX6_PAD_GPIO_9__PWM1_OUT, 1 },
> +		{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
> +			MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
> +		{ MX6_PAD_SD4_DAT1__GPIO2_IO09, IMX_GPIO_NR(2, 9),
> +			MX6_PAD_SD4_DAT1__PWM3_OUT, 3 },
> +		{ MX6_PAD_SD4_DAT2__GPIO2_IO10, IMX_GPIO_NR(2, 10),
> +			MX6_PAD_SD4_DAT2__PWM4_OUT, 4 },
> +
> +		/* GW54proto */
> +		{ MX6_PAD_GPIO_9__GPIO1_IO09, IMX_GPIO_NR(1, 9),
> +			MX6_PAD_GPIO_9__PWM1_OUT, 1 },
> +		{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
> +			MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
> +		{ MX6_PAD_SD4_DAT1__GPIO2_IO09, IMX_GPIO_NR(2, 9),
> +			MX6_PAD_SD4_DAT1__PWM3_OUT, 3 },
> +		{ MX6_PAD_SD4_DAT2__GPIO2_IO10, IMX_GPIO_NR(2, 10),
> +			MX6_PAD_SD4_DAT2__PWM4_OUT, 4 },
> +	};
> +
> +	/* Common GPIO configuration */
> +	imx_iomux_v3_setup_multiple_pads(gw_gpio_pads,
> +					 ARRAY_SIZE(gw_gpio_pads));
> +	/* RS232_EN# */
> +	gpio_direction_output(GP_RS232_EN, (hwconfig("rs232")) ? 0 : 1);
> +
> +	/* MSATA Enable */
> +	if (is_cpu_type(MXC_CPU_MX6Q) &&
> +	    test_bit(EECONFIG_SATA, info->config)) {
> +		gpio_direction_output(GP_MSATA_SEL,
> +				      (hwconfig("msata")) ?  1 : 0);
> +	} else {
> +		gpio_direction_output(GP_MSATA_SEL, 0);
> +	}
> +
> +	/* original GW5400-A prototype */
> +	if (strncasecmp((const char *)info->model, "GW5400-A", 8) == 0)
> +		baseboard = '0';
> +
> +	switch (baseboard) {
> +	case '0': /* original GW5400-A prototype */
> +		board_type = GW54proto;
> +		imx_iomux_v3_setup_multiple_pads(gwproto_gpio_pads,
> +						 ARRAY_SIZE(gwproto_gpio_pads));
> +		/* PANLEDG# (GRN off) */
> +		gpio_direction_output(IMX_GPIO_NR(4, 6), 1);
> +		/* PANLEDR# (RED off) */
> +		gpio_direction_output(IMX_GPIO_NR(4, 10), 1);
> +		/* MX6_LOCLED# (off) */
> +		gpio_direction_output(IMX_GPIO_NR(4, 15), 1);
> +		/* RS485 Transmit Enable */
> +		gpio_direction_output(IMX_GPIO_NR(3, 24), 0);
> +		/* Expansion IO0 - PWREN# */
> +		gpio_direction_output(IMX_GPIO_NR(4, 7), 0);
> +		/* Expansion IO1 - IRQ# */
> +		gpio_direction_input(IMX_GPIO_NR(4, 9));
> +		/* DIOI2C_DIS# */
> +		gpio_direction_output(IMX_GPIO_NR(4,  5), 0);
> +		/* PCICK_SSON: disable spread-spectrum clock */
> +		gpio_direction_output(IMX_GPIO_NR(1, 20), 0);
> +		/* assert PCI_RST# (released by OS when clock is valid) */
> +		gpio_direction_output(IMX_GPIO_NR(1, 29), 0);
> +		break;
> +
> +	case '1':
> +		board_type = GW51xx;
> +		imx_iomux_v3_setup_multiple_pads(gw51xx_gpio_pads,
> +						 ARRAY_SIZE(gw51xx_gpio_pads));
> +		/* PANLEDG# (GRN off) */
> +		gpio_direction_output(IMX_GPIO_NR(4, 6), 1);
> +		/* PANLEDR# (RED off) */
> +		gpio_direction_output(IMX_GPIO_NR(4, 7), 1);
> +		/* GPS_SHDN */
> +		gpio_direction_output(IMX_GPIO_NR(1, 2), 1);
> +		/* Analog video codec power enable */
> +		gpio_direction_output(IMX_GPIO_NR(5, 20), 1);
> +		/* Expansion IO0 - PWREN# */
> +		gpio_direction_output(IMX_GPIO_NR(2, 19), 0);
> +		/* Expansion IO1 - IRQ# */
> +		gpio_direction_input(IMX_GPIO_NR(2, 18));
> +		/* assert PCI_RST# (released by OS when clock is valid) */
> +		gpio_direction_output(IMX_GPIO_NR(1, 0), 0);
> +		break;
> +
> +	case '2':
> +		board_type = GW52xx;
> +		imx_iomux_v3_setup_multiple_pads(gw52xx_gpio_pads,
> +						 ARRAY_SIZE(gw52xx_gpio_pads));
> +		/* PANLEDG# (GRN off) */
> +		gpio_direction_output(IMX_GPIO_NR(4, 6), 1);
> +		/* PANLEDR# (RED off) */
> +		gpio_direction_output(IMX_GPIO_NR(4, 7), 1);
> +		/* MX6_LOCLED# (off) */
> +		gpio_direction_output(IMX_GPIO_NR(4, 15), 1);
> +		/* GPS_SHDN */
> +		gpio_direction_output(IMX_GPIO_NR(1, 27), 1);
> +		/* Expansion IO0 - PWREN# */
> +		gpio_direction_output(IMX_GPIO_NR(2, 19), 0);
> +		/* Expansion IO1 - IRQ# */
> +		gpio_direction_input(IMX_GPIO_NR(2, 18));
> +		/* USBOTG Select (PCISKT or FrontPanel) */
> +		gpio_direction_output(IMX_GPIO_NR(1, 2), 0);
> +		/* Analog video codec power enable */
> +		gpio_direction_output(IMX_GPIO_NR(3, 31), 1);
> +		/* assert PCI_RST# (released by OS when clock is valid) */
> +		gpio_direction_output(IMX_GPIO_NR(1, 29), 0);
> +		break;
> +
> +	case '3':
> +		board_type = GW53xx;
> +		imx_iomux_v3_setup_multiple_pads(gw53xx_gpio_pads,
> +						 ARRAY_SIZE(gw53xx_gpio_pads));
> +		/* PANLEDG# (GRN off) */
> +		gpio_direction_output(IMX_GPIO_NR(4, 6), 1);
> +		/* PANLEDR# (RED off) */
> +		gpio_direction_output(IMX_GPIO_NR(4, 7), 1);
> +		/* MX6_LOCLED# (off) */
> +		gpio_direction_output(IMX_GPIO_NR(4, 15), 1);
> +		/* GPS_SHDN */
> +		gpio_direction_output(IMX_GPIO_NR(1, 27), 1);
> +		/* Expansion IO0 - PWREN# */
> +		gpio_direction_output(IMX_GPIO_NR(2, 19), 0);
> +		/* Expansion IO1 - IRQ# */
> +		gpio_direction_input(IMX_GPIO_NR(2, 18));
> +		/* Analog video codec power enable */
> +		gpio_direction_output(IMX_GPIO_NR(3, 31), 1);
> +		/* assert PCI_RST# (released by OS when clock is valid) */
> +		gpio_direction_output(IMX_GPIO_NR(1, 29), 0);
> +		break;
> +
> +	case '4':
> +		board_type = GW54xx;
> +		imx_iomux_v3_setup_multiple_pads(gw54xx_gpio_pads,
> +						 ARRAY_SIZE(gw54xx_gpio_pads));
> +		/* PANLEDG# (GRN off) */
> +		gpio_direction_output(IMX_GPIO_NR(4, 6), 1);
> +		/* PANLEDR# (RED off) */
> +		gpio_direction_output(IMX_GPIO_NR(4, 7), 1);
> +		/* MX6_LOCLED# (off) */
> +		gpio_direction_output(IMX_GPIO_NR(4, 15), 1);
> +		/* RS485 Transmit Enable */
> +		gpio_direction_output(IMX_GPIO_NR(7, 1), 0);
> +		/* Expansion IO0 - PWREN# */
> +		gpio_direction_output(IMX_GPIO_NR(2, 19), 0);
> +		/* Expansion IO1 - IRQ# */
> +		gpio_direction_input(IMX_GPIO_NR(2, 18));
> +		/* Analog video codec power enable */
> +		gpio_direction_output(IMX_GPIO_NR(3, 31), 1);
> +		/* DIOI2C_DIS# */
> +		gpio_direction_output(IMX_GPIO_NR(4,  5), 0);
> +		/* PCICK_SSON: disable spread-spectrum clock */
> +		gpio_direction_output(IMX_GPIO_NR(1, 20), 0);
> +		/* assert PCI_RST# (released by OS when clock is valid) */
> +		gpio_direction_output(IMX_GPIO_NR(1, 29), 0);
> +		break;
> +	}

mmhh..I think the code is still nasty and could be improved. Code is
copied from case ti case, but the same operation are done.

You could create a structure with the setup for each board. For GPIOs,
you have the pad setting for the GPIOs and a list of gpios that must be
set. You could rewrite this code with something like

struct gpio_setup {
	int gpio;
	int val;
};

struct ventana {
	 iomux_v3_cfg_t gpio_pads;
	 gpio_setup gpios[..];
};



Then add the tables for each model to get the whole table:
{
	{ gwproto_gpio_pad, ...},
	{ gw51xx_gpio_pads,...},
}

You can reuse baseboard as index in the table. With this assumption, you
can dropü completely the switch, having selected the data before
applying the setup. Code will be smaller, too.


> +
> +	/*
> +	 * Configure DIO pinmux/padctl registers
> +	 * see IMX6DQRM/IMX6SDLRM IOMUXC_SW_PAD_CTL_PAD_* register definitions
> +	 */
> +	if (board_type > UNKNOWN)
> +		return;
> +	for (i = 0; i < 4; i++) {
> +		struct dio_cfg *cfg = &dio_cfg[(4*board_type)+i];
> +		unsigned ctrl = DIO_PAD_CTRL;
> +
> +		sprintf(arg, "dio%d", i);
> +		if (!hwconfig(arg))
> +			continue;
> +		s = hwconfig_subarg(arg, "padctrl", &len);
> +		if (s)
> +			ctrl = simple_strtoul(s, NULL, 16) & 0x3ffff;
> +		if (hwconfig_subarg_cmp(arg, "mode", "gpio")) {
> +			if (!quiet) {
> +				printf("DIO%d:  GPIO%d_IO%02d (gpio-%d)\n", i,
> +				       (cfg->gpio_param/32)+1,
> +				       cfg->gpio_param%32,
> +				       cfg->gpio_param);
> +			}
> +			imx_iomux_v3_setup_pad(cfg->gpio_padmux |
> +					       MUX_PAD_CTRL(ctrl));
> +			gpio_direction_input(cfg->gpio_param);
> +		} else if (hwconfig_subarg_cmp("dio2", "mode", "pwm") &&
> +			   cfg->pwm_padmux) {
> +			if (!quiet)
> +				printf("DIO%d:  pwm%d\n", i, cfg->pwm_param);
> +			imx_iomux_v3_setup_pad(cfg->pwm_padmux |
> +					       MUX_PAD_CTRL(ctrl));
> +		}
> +	}
> +
> +	if (!quiet) {
> +		if (is_cpu_type(MXC_CPU_MX6Q) &&
> +		    (test_bit(EECONFIG_SATA, info->config))) {
> +			printf("MSATA: %s\n", (hwconfig("msata") ?
> +			       "enabled" : "disabled"));
> +		}
> +		printf("RS232: %s\n", (hwconfig("rs232")) ?
> +		       "enabled" : "disabled");
> +	}
> +}
> +
> +#ifdef CONFIG_SERIAL_TAG
> +/*
> + * called when setting up ATAGS before booting kernel
> + * populate serialnum from the following (in order of priority):
> + *   serial# env var
> + *   eeprom
> + */
> +void get_board_serial(struct tag_serialnr *serialnr)
> +{
> +	char *serial = getenv("serial#");
> +
> +	if (serial) {
> +		serialnr->high = 0;
> +		serialnr->low = simple_strtoul(serial, NULL, 10);
> +	} else if (ventana_info.model[0]) {
> +		serialnr->high = 0;
> +		serialnr->low = ventana_info.serial;
> +	} else {
> +		serialnr->high = 0;
> +		serialnr->low = 0;
> +	}
> +}
> +#endif
> +
> +/*
> + * Board Support
> + */
> +
> +int board_early_init_f(void)
> +{
> +	setup_iomux_uart();
> +	gpio_direction_output(GP_USB_OTG_PWR, 0); /* OTG power off */
> +
> +	return 0;
> +}
> +
> +int dram_init(void)
> +{
> +	gd->ram_size = get_ram_size((void *)PHYS_SDRAM,
> +				    CONFIG_DDR_MB*1024*1024);
> +
> +	return 0;
> +}
> +
> +int board_init(void)
> +{
> +	struct iomuxc_base_regs *const iomuxc_regs
> +		= (struct iomuxc_base_regs *)IOMUXC_BASE_ADDR;
> +
> +	clrsetbits_le32(&iomuxc_regs->gpr[1],
> +			IOMUXC_GPR1_OTG_ID_MASK,
> +			IOMUXC_GPR1_OTG_ID_GPIO1);
> +
> +	/* address of linux boot parameters */
> +	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
> +
> +#ifdef CONFIG_CMD_NAND
> +	setup_gpmi_nand();
> +#endif
> +#ifdef CONFIG_MXC_SPI
> +	setup_spi();
> +#endif
> +	setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0);
> +	setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
> +	setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
> +
> +#ifdef CONFIG_CMD_SATA
> +	setup_sata();
> +#endif
> +	/* read Gateworks EEPROM into global struct (used later) */
> +	read_eeprom();
> +
> +	return 0;
> +}
> +
> +#if defined(CONFIG_DISPLAY_BOARDINFO_LATE)
> +/*
> + * called during late init (after relocation and after board_init())
> + * by virtue of CONFIG_DISPLAY_BOARDINFO_LATE as we needed i2c initialized and
> + * EEPROM read.
> + */
> +int checkboard(void)
> +{
> +	struct ventana_board_info *info = &ventana_info;
> +	unsigned char buf[4];
> +	const char *p;
> +	int quiet; /* Quiet or minimal output mode */
> +
> +	quiet = 0;
> +	p = getenv("quiet");
> +	if (p)
> +		quiet = simple_strtol(p, NULL, 10);
> +	else
> +		setenv("quiet", "0");
> +
> +	puts("\nGateworks Corporation Copyright 2014\n");
> +	if (info->model[0]) {
> +		printf("Model: %s\n", info->model);
> +		printf("MFGDate: %02x-%02x-%02x%02x\n",
> +		       info->mfgdate[0], info->mfgdate[1],
> +		       info->mfgdate[2], info->mfgdate[3]);
> +		printf("Serial:%d\n", info->serial);
> +	} else {
> +		puts("Invalid EEPROM - board will not function fully\n");
> +	}
> +
> +	/* Display GSC firmware revision/CRC/status/RTC */
> +	if (!quiet) {
> +		i2c_set_bus_num(0);
> +		if (!gsc_i2c_read(0x20, 14, 1, buf, 1)) {
> +			printf("GSC:   v%d", buf[0]);
> +			if (!gsc_i2c_read(0x20, 10, 1, buf, 4)) {
> +				/* show firmware revision and CRC */
> +				printf(" 0x%04x", buf[2] | buf[3]<<8);
> +				/* show status register */
> +				printf(" 0x%02x", buf[0]);
> +			}
> +			puts("\n");
> +		}
> +		if (!gsc_i2c_read(0x68, 0x00, 1, buf, 4)) {
> +			printf("RTC:   %d\n",
> +			       buf[0] | buf[1]<<8 | buf[2]<<16 | buf[3]<<24);
> +		}
> +	}
> +
> +	return 0;
> +}
> +#endif
> +
> +#ifdef CONFIG_CMD_BMODE
> +/*
> + * BOOT_CFG1, BOOT_CFG2, BOOT_CFG3, BOOT_CFG4
> + * see Table 8-11 and Table 5-9
> + *  BOOT_CFG1[7] = 1 (boot from NAND)
> + *  BOOT_CFG1[5] = 0 - raw NAND
> + *  BOOT_CFG1[4] = 0 - default pad settings
> + *  BOOT_CFG1[3:2] = 00 - devices = 1
> + *  BOOT_CFG1[1:0] = 00 - Row Address Cycles = 3
> + *  BOOT_CFG2[4:3] = 00 - Boot Search Count = 2
> + *  BOOT_CFG2[2:1] = 01 - Pages In Block = 64
> + *  BOOT_CFG2[0] = 0 - Reset time 12ms
> + */
> +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) },
> +	{ NULL, 0 },
> +};
> +#endif
> +
> +/* late init */
> +int misc_init_r(void)
> +{
> +	struct ventana_board_info *info = &ventana_info;
> +	unsigned char reg;
> +
> +	/* set env vars based on EEPROM data */
> +	if (ventana_info.model[0]) {
> +		char str[16], fdt[36];
> +		char *p;
> +		const char *cputype = "";
> +		int i;
> +
> +		/*
> +		 * FDT name will be prefixed with CPU type.  Three versions
> +		 * will be created each increasingly generic and bootloader
> +		 * env scripts will try loading each from most specific to
> +		 * least.
> +		 */
> +		if (is_cpu_type(MXC_CPU_MX6Q))
> +			cputype = "imx6q";
> +		else if (is_cpu_type(MXC_CPU_MX6DL))
> +			cputype = "imx6dl";
> +		memset(str, 0, sizeof(str));
> +		for (i = 0; i < (sizeof(str)-1) && info->model[i]; i++)
> +			str[i] = tolower(info->model[i]);
> +		if (!getenv("model"))
> +			setenv("model", str);
> +		if (!getenv("fdt_file")) {
> +			sprintf(fdt, "%s-%s.dtb", cputype, str);
> +			setenv("fdt_file", fdt);
> +		}
> +		p = strchr(str, '-');
> +		if (p) {
> +			*p++ = 0;
> +
> +			setenv("model_base", str);
> +			if (!getenv("fdt_file1")) {
> +				sprintf(fdt, "%s-%s.dtb", cputype, str);
> +				setenv("fdt_file1", fdt);
> +			}
> +			str[4] = 'x';
> +			str[5] = 'x';
> +			str[6] = 0;
> +			if (!getenv("fdt_file2")) {
> +				sprintf(fdt, "%s-%s.dtb", cputype, str);
> +				setenv("fdt_file2", fdt);
> +			}
> +		}
> +
> +		/* initialize env from EEPROM */
> +		if (test_bit(EECONFIG_ETH0, info->config) &&
> +		    !getenv("ethaddr")) {
> +			eth_setenv_enetaddr("ethaddr", info->mac0);
> +		}
> +		if (test_bit(EECONFIG_ETH1, info->config) &&
> +		    !getenv("eth1addr")) {
> +			eth_setenv_enetaddr("eth1addr", info->mac1);
> +		}
> +
> +		/* board serial-number */
> +		sprintf(str, "%6d", info->serial);
> +		setenv("serial#", str);
> +	}
> +
> +	/* configure PFUZE100 PMIC (not used on Ventana baseboards) */
> +	if (!pmic_init(1)) {
> +		struct pmic *p = pmic_get("PFUZE100_PMIC");
> +		u32 reg;
> +		if (p && !pmic_probe(p)) {
> +			/* 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);
> +			pmic_reg_write(p, PFUZE100_SWBSTCON1, reg);
> +		}
> +	}
> +
> +	/* setup baseboard specific GPIO pinmux and config */
> +	setup_board_gpio();
> +
> +#ifdef CONFIG_CMD_BMODE
> +	add_board_boot_modes(board_boot_modes);
> +#endif
> +
> +	/*
> +	 *  The Gateworks System Controller implements a boot
> +	 *  watchdog (always enabled) as a workaround for IMX6 boot related
> +	 *  errata such as:
> +	 *    ERR007117 - fixed in silicon r1.3
> +	 *    ERR007220 - fixed in silicon r1.3
> +	 *    ERR005768 - no fix
> +	 *    ERR006282 - fixed in silicon r1.3
> +	 *  see http://cache.freescale.com/files/32bit/doc/errata/IMX6DQCE.pdf
> +	 *
> +	 * Disable the boot watchdog and display/clear the timeout flag if set
> +	 */
> +	i2c_set_bus_num(0);
> +	if (!gsc_i2c_read(0x20, 1, 1, &reg, 1)) {
> +		reg |= 0x80;
> +		if (gsc_i2c_write(0x20, 1, 1, &reg, 1))
> +			puts("Error: could not disable GSC Watchdog\n");
> +	} else {
> +		puts("Error: could not disable GSC Watchdog\n");
> +	}
> +	if (!gsc_i2c_read(0x20, 10, 1, &reg, 1)) {
> +		if (reg & 0x40) { /* GSC watchdog timeout */
> +			puts("GSC boot watchdog timeout detected");
> +			reg &= ~0x40; /* clear flag */
> +			gsc_i2c_write(0x20, 10, 1, &reg, 1);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
> +/*
> + * called prior to booting kernel or by 'fdt boardsetup' command
> + *
> + * unless 'fdt_noauto' env var is set we will update the following in the DTB:
> + *  - mtd partitions based on mtdparts/mtdids env
> + *  - system-serial (board serial num from EEPROM)
> + *  - board (full model from EEPROM)
> + *  - peripherals removed from DTB if not loaded on board (per EEPROM config)
> + */
> +void ft_board_setup(void *blob, bd_t *bd)
> +{
> +	struct ventana_board_info *info = &ventana_info;
> +	struct node_info nodes[] = {
> +		{ "sst,w25q256",          MTD_DEV_TYPE_NOR, },  /* SPI flash */
> +		{ "fsl,imx6q-gpmi-nand",  MTD_DEV_TYPE_NAND, }, /* NAND flash */
> +	};
> +	const char *model = getenv("model");
> +
> +	if (getenv("fdt_noauto")) {
> +		puts("   Skiping ft_board_setup (fdt_noauto defined)\n");
> +		return;
> +	}
> +
> +	/* Update partition nodes using info from mtdparts env var */
> +	puts("   Updating MTD partitions...\n");
> +	fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
> +
> +	if (!model) {
> +		puts("invalid board info: Leaving FDT fully enabled\n");
> +		return;
> +	}
> +	printf("   Adjusting FDT per EEPROM for %s...\n", model);
> +
> +	/* board serial number */
> +	fdt_setprop(blob, 0, "system-serial", getenv("serial#"),
> +		    strlen(getenv("serial#") + 1));
> +
> +	/* board (model contains model from device-tree) */
> +	fdt_setprop(blob, 0, "board", info->model,
> +		    strlen((const char *)info->model) + 1);
> +
> +	/*
> +	 * Peripheral Config:
> +	 *  remove nodes by alias path if EEPROM config tells us the
> +	 *  peripheral is not loaded on the board.
> +	 */
> +	if (!test_bit(EECONFIG_ETH0, info->config))
> +		fdt_del_node_and_alias(blob, "ethernet0");
> +	if (!test_bit(EECONFIG_ETH1, info->config))
> +		fdt_del_node_and_alias(blob, "ethernet1");
> +	if (!test_bit(EECONFIG_HDMI_OUT, info->config))
> +		fdt_del_node_and_alias(blob, "hdmi_out");
> +	if (!test_bit(EECONFIG_SATA, info->config))
> +		fdt_del_node_and_alias(blob, "ahci0");
> +	if (!test_bit(EECONFIG_PCIE, info->config))
> +		fdt_del_node_and_alias(blob, "pcie");
> +	if (!test_bit(EECONFIG_SSI0, info->config))
> +		fdt_del_node_and_alias(blob, "ssi0");
> +	if (!test_bit(EECONFIG_SSI1, info->config))
> +		fdt_del_node_and_alias(blob, "ssi1");
> +	if (!test_bit(EECONFIG_LCD, info->config))
> +		fdt_del_node_and_alias(blob, "lcd0");
> +	if (!test_bit(EECONFIG_LVDS0, info->config))
> +		fdt_del_node_and_alias(blob, "lvds0");
> +	if (!test_bit(EECONFIG_LVDS1, info->config))
> +		fdt_del_node_and_alias(blob, "lvds1");
> +	if (!test_bit(EECONFIG_USB0, info->config))
> +		fdt_del_node_and_alias(blob, "usb0");
> +	if (!test_bit(EECONFIG_USB1, info->config))
> +		fdt_del_node_and_alias(blob, "usb1");
> +	if (!test_bit(EECONFIG_SD0, info->config))
> +		fdt_del_node_and_alias(blob, "mmc0");
> +	if (!test_bit(EECONFIG_SD1, info->config))
> +		fdt_del_node_and_alias(blob, "mmc1");
> +	if (!test_bit(EECONFIG_SD2, info->config))
> +		fdt_del_node_and_alias(blob, "mmc2");
> +	if (!test_bit(EECONFIG_SD3, info->config))
> +		fdt_del_node_and_alias(blob, "mmc3");
> +	if (!test_bit(EECONFIG_UART0, info->config))
> +		fdt_del_node_and_alias(blob, "serial0");
> +	if (!test_bit(EECONFIG_UART1, info->config))
> +		fdt_del_node_and_alias(blob, "serial1");
> +	if (!test_bit(EECONFIG_UART2, info->config))
> +		fdt_del_node_and_alias(blob, "serial2");
> +	if (!test_bit(EECONFIG_UART3, info->config))
> +		fdt_del_node_and_alias(blob, "serial3");
> +	if (!test_bit(EECONFIG_UART4, info->config))
> +		fdt_del_node_and_alias(blob, "serial4");
> +	if (!test_bit(EECONFIG_IPU0, info->config))
> +		fdt_del_node_and_alias(blob, "ipu0");
> +	if (!test_bit(EECONFIG_IPU1, info->config))
> +		fdt_del_node_and_alias(blob, "ipu1");
> +	if (!test_bit(EECONFIG_FLEXCAN, info->config))
> +		fdt_del_node_and_alias(blob, "can0");
> +	if (!test_bit(EECONFIG_MIPI_DSI, info->config))
> +		fdt_del_node_and_alias(blob, "mipi_dsi");
> +	if (!test_bit(EECONFIG_MIPI_CSI, info->config))
> +		fdt_del_node_and_alias(blob, "mipi_csi");
> +	if (!test_bit(EECONFIG_TZASC0, info->config))
> +		fdt_del_node_and_alias(blob, "tzasc0");
> +	if (!test_bit(EECONFIG_TZASC1, info->config))
> +		fdt_del_node_and_alias(blob, "tzasc1");
> +	if (!test_bit(EECONFIG_I2C0, info->config))
> +		fdt_del_node_and_alias(blob, "i2c0");
> +	if (!test_bit(EECONFIG_I2C1, info->config))
> +		fdt_del_node_and_alias(blob, "i2c1");
> +	if (!test_bit(EECONFIG_I2C2, info->config))
> +		fdt_del_node_and_alias(blob, "i2c2");
> +	if (!test_bit(EECONFIG_VPU, info->config))
> +		fdt_del_node_and_alias(blob, "vpu");
> +	if (!test_bit(EECONFIG_CSI0, info->config))
> +		fdt_del_node_and_alias(blob, "csi0");
> +	if (!test_bit(EECONFIG_CSI1, info->config))
> +		fdt_del_node_and_alias(blob, "csi1");
> +	if (!test_bit(EECONFIG_CAAM, info->config))
> +		fdt_del_node_and_alias(blob, "caam");
> +	if (!test_bit(EECONFIG_ESPCI0, info->config))
> +		fdt_del_node_and_alias(blob, "spi0");
> +	if (!test_bit(EECONFIG_ESPCI1, info->config))
> +		fdt_del_node_and_alias(blob, "spi1");
> +	if (!test_bit(EECONFIG_ESPCI2, info->config))
> +		fdt_del_node_and_alias(blob, "spi2");
> +	if (!test_bit(EECONFIG_ESPCI3, info->config))
> +		fdt_del_node_and_alias(blob, "spi3");
> +	if (!test_bit(EECONFIG_ESPCI4, info->config))
> +		fdt_del_node_and_alias(blob, "spi4");
> +	if (!test_bit(EECONFIG_ESPCI5, info->config))
> +		fdt_del_node_and_alias(blob, "spi5");
> +	if (!test_bit(EECONFIG_HDMI_IN, info->config))
> +		fdt_del_node_and_alias(blob, "hdmi_in");
> +	if (!test_bit(EECONFIG_VID_OUT, info->config))
> +		fdt_del_node_and_alias(blob, "cvbs_out");
> +	if (!test_bit(EECONFIG_VID_IN, info->config))
> +		fdt_del_node_and_alias(blob, "cvbs_in");
> +	if (!test_bit(EECONFIG_NAND, info->config))
> +		fdt_del_node_and_alias(blob, "nand");
> +	if (!test_bit(EECONFIG_GPS, info->config))
> +		fdt_del_node_and_alias(blob, "pps");

I read your post on devicetree ML - I do not see thare is a preferred
way to do this. Anyway, this code is nasty: it is a big cut&paste.

Please use enum for the bit definitions, and use a table to iterate your
eprom setup. I would see this long list of peripheral config translated
in a few lines, such as:

	for (bit=first_bit_toiterate; bit < last_bit_to_iterate; bit++)
	{
            if(!test_bit(bit,info->config))
                fdt_del_node_and_alias(blob, properties[bit]);
	}

> --- /dev/null
> +++ b/board/gateworks/gw_ventana/ventana_eeprom.h
> @@ -0,0 +1,103 @@
> +/*
> + * Copyright (C) 2013 Gateworks Corporation
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#ifndef _VENTANA_EEPROM_
> +#define _VENTANA_EEPROM_
> +
> +struct ventana_board_info {
> +	u8 mac0[6];          /* 0x00: MAC1 */
> +	u8 mac1[6];          /* 0x06: MAC2 */
> +	u8 res0[12];         /* 0x0C: reserved */
> +	u32 serial;          /* 0x18: Serial Number (read only) */
> +	u8 res1[4];          /* 0x1C: reserved */
> +	u8 mfgdate[4];       /* 0x20: MFG date (read only) */
> +	u8 res2[7];          /* 0x24 */
> +	/* sdram config */
> +	u8 sdram_size;       /* 0x2B: enum (512,1024,2048) MB */
> +	u8 sdram_speed;      /* 0x2C: enum (100,133,166,200,267,333,400) MHz */
> +	u8 sdram_width;      /* 0x2D: enum (32,64) bit */
> +	/* cpu config */
> +	u8 cpu_speed;        /* 0x2E: enum (800,1000,1200) MHz */
> +	u8 cpu_type;         /* 0x2F: enum (imx6q,imx6d,imx6dl,imx6s) */
> +	u8 model[16];        /* 0x30: model string */
> +	/* FLASH config */
> +	u8 nand_flash_size;  /* 0x40: enum (4,8,16,32,64,128) MB */
> +	u8 spi_flash_size;   /* 0x41: enum (4,8,16,32,64,128) MB */
> +
> +	/* Config1: SoC Peripherals */
> +	u8 config[8];        /* 0x42: loading options */
> +
> +#define EECONFIG_ETH0     0
> +#define EECONFIG_ETH1     1
> +#define EECONFIG_HDMI_OUT 2
> +#define EECONFIG_SATA     3
> +#define EECONFIG_PCIE     4
> +#define EECONFIG_SSI0     5
> +#define EECONFIG_SSI1     6
> +#define EECONFIG_LCD      7
> +#define EECONFIG_LVDS0    8
> +#define EECONFIG_LVDS1    9
> +#define EECONFIG_USB0     10
> +#define EECONFIG_USB1     11
> +#define EECONFIG_SD0      12
> +#define EECONFIG_SD1      13
> +#define EECONFIG_SD2      14
> +#define EECONFIG_SD3      15
> +#define EECONFIG_UART0    16
> +#define EECONFIG_UART1    17
> +#define EECONFIG_UART2    18
> +#define EECONFIG_UART3    19
> +#define EECONFIG_UART4    20
> +#define EECONFIG_IPU0     21
> +#define EECONFIG_IPU1     22
> +#define EECONFIG_FLEXCAN  23
> +#define EECONFIG_MIPI_DSI 24
> +#define EECONFIG_MIPI_CSI 25
> +#define EECONFIG_TZASC0   26
> +#define EECONFIG_TZASC1   27
> +#define EECONFIG_I2C0     28
> +#define EECONFIG_I2C1     29
> +#define EECONFIG_I2C2     30
> +#define EECONFIG_VPU      31
> +#define EECONFIG_CSI0     32
> +#define EECONFIG_CSI1     33
> +#define EECONFIG_CAAM     34
> +#define EECONFIG_MEZZ     35
> +#define EECONFIG_RES1     36
> +#define EECONFIG_RES2     37
> +#define EECONFIG_RES3     38
> +#define EECONFIG_RES4     39
> +#define EECONFIG_ESPCI0   40
> +#define EECONFIG_ESPCI1   41
> +#define EECONFIG_ESPCI2   42
> +#define EECONFIG_ESPCI3   43
> +#define EECONFIG_ESPCI4   44
> +#define EECONFIG_ESPCI5   45
> +#define EECONFIG_RES5     46
> +#define EECONFIG_RES6     47
> +#define EECONFIG_GPS      48
> +#define EECONFIG_SPIFL0   49
> +#define EECONFIG_SPIFL1   50
> +#define EECONFIG_GSPBATT  51
> +#define EECONFIG_HDMI_IN  52
> +#define EECONFIG_VID_OUT  53
> +#define EECONFIG_VID_IN   54
> +#define EECONFIG_NAND     55
> +#define EECONFIG_RES8     56
> +#define EECONFIG_RES9     57
> +#define EECONFIG_RES10    58
> +#define EECONFIG_RES11    59
> +#define EECONFIG_RES12    60
> +#define EECONFIG_RES13    61
> +#define EECONFIG_RES14    62
> +#define EECONFIG_RES15    63

Use enum for these

> +
> +	u8 res3[4];          /* 0x4A */
> +
> +	u8 chksum[2];        /* 0x4E */
> +};
> +
> +#endif
> diff --git a/boards.cfg b/boards.cfg
> index a8336cc..5f94558 100644
> --- a/boards.cfg
> +++ b/boards.cfg
> @@ -308,6 +308,11 @@ Active  arm         armv7          mx6         freescale       mx6qsabreauto
>  Active  arm         armv7          mx6         freescale       mx6sabresd          mx6dlsabresd                         mx6sabresd:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL                                                             Fabio Estevam <fabio.estevam@freescale.com>
>  Active  arm         armv7          mx6         freescale       mx6sabresd          mx6qsabresd                          mx6sabresd:IMX_CONFIG=board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg,MX6Q                                                           Fabio Estevam <fabio.estevam@freescale.com>
>  Active  arm         armv7          mx6         freescale       mx6slevk            mx6slevk                             mx6slevk:IMX_CONFIG=board/freescale/mx6slevk/imximage.cfg,MX6SL                                                                   Fabio Estevam <fabio.estevam@freescale.com>
> +Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanadl                          gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6DL,DDR_MB=512                                                  Tim Harvey <tharvey@gateworks.com>
> +Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanadl1g                        gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6DL,DDR_MB=1024                                                 Tim Harvey <tharvey@gateworks.com>
> +Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanaq                           gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=512                                                   Tim Harvey <tharvey@gateworks.com>
> +Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanaq1g                         gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=1024                                                  Tim Harvey <tharvey@gateworks.com>
> +Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanaq1gspi                      gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=1024,SPI_FLASH                                        Tim Harvey <tharvey@gateworks.com>
>  Active  arm         armv7          mx6         barco           titanium            titanium                             titanium:IMX_CONFIG=board/barco/titanium/imximage.cfg                                                                         Stefan Roese <sr@denx.de>
>  Active  arm         armv7          mx6         solidrun        hummingboard        hummingboard_solo                           hummingboard:IMX_CONFIG=board/solidrun/hummingboard/solo.cfg,MX6S,DDR_MB=512        Jon Nettleton <jon.nettleton@gmail.com>
>  Active  arm         armv7          omap3       -               overo               omap3_overo                          -                                                                                                                                 Steve Sakoman <sakoman@gmail.com>
> diff --git a/include/configs/gw_ventana.h b/include/configs/gw_ventana.h
> new file mode 100644
> index 0000000..05f4771
> --- /dev/null
> +++ b/include/configs/gw_ventana.h
> @@ -0,0 +1,418 @@
> +/*
> + * Copyright (C) 2013 Gateworks Corporation
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#ifndef __CONFIG_H
> +#define __CONFIG_H
> +
> +#include "mx6_common.h"
> +#define CONFIG_MX6
> +#define CONFIG_DISPLAY_CPUINFO         /* display cpu info */
> +#define CONFIG_DISPLAY_BOARDINFO_LATE  /* display board info (after reloc) */
> +
> +#define CONFIG_MACH_TYPE	4520   /* Gateworks Ventana Platform */
> +
> +#include <asm/arch/imx-regs.h>
> +#include <asm/imx-common/gpio.h>
> +
> +/* ATAGs */
> +#define CONFIG_CMDLINE_TAG
> +#define CONFIG_SETUP_MEMORY_TAGS
> +#define CONFIG_INITRD_TAG
> +#define CONFIG_SERIAL_TAG
> +#define CONFIG_REVISION_TAG
> +
> +/* Size of malloc() pool */
> +#define CONFIG_SYS_MALLOC_LEN		(10 * 1024 * 1024)
> +
> +/* Init Functions */
> +#define CONFIG_BOARD_EARLY_INIT_F
> +#define CONFIG_MISC_INIT_R
> +
> +/* GPIO */
> +#define CONFIG_MXC_GPIO
> +
> +/* Serial */
> +#define CONFIG_MXC_UART
> +#define CONFIG_MXC_UART_BASE	       UART2_BASE
> +
> +#ifdef CONFIG_SPI_FLASH
> +
> +/* SPI */
> +#define CONFIG_CMD_SF
> +#ifdef CONFIG_CMD_SF
> +  #define CONFIG_MXC_SPI
> +  #define CONFIG_SPI_FLASH_MTD
> +  #define CONFIG_SPI_FLASH_BAR
> +  #define CONFIG_SPI_FLASH_WINBOND
> +  #define CONFIG_SPI_FLASH_WINBOND_ERASESIZE 64*1024  /* 4,32,64K for W26Q256 */
> +  #define CONFIG_SF_DEFAULT_BUS              0
> +  #define CONFIG_SF_DEFAULT_CS               (0|(IMX_GPIO_NR(3, 19)<<8))
> +					     /* GPIO 3-19 (21248) */
> +  #define CONFIG_SF_DEFAULT_SPEED            30000000
> +  #define CONFIG_SF_DEFAULT_MODE             (SPI_MODE_0)
> +#endif
> +
> +/* Flattened Image Tree Suport */
> +#define CONFIG_FIT
> +#define CONFIG_FIT_VERBOSE

I do not understand what CONFIG_FIT has to do with SPI. Why is it in the
#ifdef CONFIG_SPI_FLASH case ?

> +
> +#else
> +/* Enable NAND support */
> +#define CONFIG_CMD_TIME
> +#define CONFIG_CMD_NAND
> +#define CONFIG_CMD_NAND_TRIMFFS
> +#ifdef CONFIG_CMD_NAND
> +  #define CONFIG_NAND_MXS
> +  #define CONFIG_SYS_MAX_NAND_DEVICE	1
> +  #define CONFIG_SYS_NAND_BASE		0x40000000
> +  #define CONFIG_SYS_NAND_5_ADDR_CYCLE
> +  #define CONFIG_SYS_NAND_ONFI_DETECTION
> +
> +  /* DMA stuff, needed for GPMI/MXS NAND support */
> +  #define CONFIG_APBH_DMA
> +  #define CONFIG_APBH_DMA_BURST
> +  #define CONFIG_APBH_DMA_BURST8
> +#endif
> +
> +#endif /* CONFIG_SPI_FLASH */
> +
> +/* I2C Configs */
> +#define CONFIG_CMD_I2C
> +#define CONFIG_SYS_I2C
> +#define CONFIG_SYS_I2C_MXC
> +#define CONFIG_SYS_I2C_SPEED		  100000
> +
> +/* MMC Configs */
> +#define CONFIG_FSL_ESDHC
> +#define CONFIG_FSL_USDHC
> +#define CONFIG_SYS_FSL_ESDHC_ADDR      0
> +#define CONFIG_SYS_FSL_USDHC_NUM       1
> +#define CONFIG_MMC
> +#define CONFIG_CMD_MMC
> +#define CONFIG_GENERIC_MMC
> +#define CONFIG_BOUNCE_BUFFER
> +
> +/* Filesystem support */
> +#define CONFIG_CMD_EXT2
> +#define CONFIG_CMD_FAT
> +#define CONFIG_CMD_UBIFS
> +#define CONFIG_DOS_PARTITION
> +
> +/* Network config - Allow larger/faster download for TFTP/NFS */
> +#define CONFIG_IP_DEFRAG
> +#define CONFIG_TFTP_BLOCKSIZE 4096
> +#define CONFIG_NFS_READ_SIZE  4096
> +
> +#ifdef CONFIG_MX6Q
> +#define CONFIG_CMD_SATA

CONFIG_CMD_SATA is not strict bound to the processor type. You are using
CONFIG_MX6Q for multiple purposes.

> +#endif
> +
> +/*
> + * SATA Configs
> + */
> +#ifdef CONFIG_CMD_SATA
> +  #define CONFIG_DWC_AHSATA
> +  #define CONFIG_SYS_SATA_MAX_DEVICE	1
> +  #define CONFIG_DWC_AHSATA_PORT_ID	0
> +  #define CONFIG_DWC_AHSATA_BASE_ADDR	SATA_ARB_BASE_ADDR
> +  #define CONFIG_LBA48
> +  #define CONFIG_LIBATA
> +#endif
> +
> +/*
> + * PMIC
> + */
> +#define CONFIG_POWER
> +#define CONFIG_POWER_I2C
> +#define CONFIG_POWER_PFUZE100
> +#define CONFIG_POWER_PFUZE100_I2C_ADDR	0x08
> +
> +/* Various command support */
> +#include <config_cmd_default.h>
> +#undef CONFIG_CMD_IMLS
> +#define CONFIG_CMD_PING
> +#define CONFIG_CMD_DHCP
> +#define CONFIG_CMD_MII
> +#define CONFIG_CMD_NET
> +#define CONFIG_CMD_BMODE         /* set eFUSE shadow for a boot dev and reset */
> +#define CONFIG_CMD_HDMIDETECT    /* detect HDMI output device */
> +#define CONFIG_CMD_SETEXPR
> +#define CONFIG_CMD_BOOTZ
> +#define CONFIG_CMD_GSC
> +#define CONFIG_CMD_UBI
> +#define CONFIG_RBTREE
> +#define CONFIG_LZO
> +#define CONFIG_CMD_FUSE          /* eFUSE read/write support */
> +#ifdef CONFIG_CMD_FUSE
> +#define CONFIG_MXC_OCOTP
> +#endif
> +
> +
> +/* Ethernet support */
> +#define CONFIG_FEC_MXC
> +#define CONFIG_MII
> +#define IMX_FEC_BASE             ENET_BASE_ADDR
> +#define CONFIG_FEC_XCV_TYPE      RGMII
> +#define CONFIG_ETHPRIME          "FEC"
> +#define CONFIG_FEC_MXC_PHYADDR   0
> +#define CONFIG_PHYLIB
> +#define CONFIG_ARP_TIMEOUT       200UL
> +
> +/* USB Configs */
> +#define CONFIG_CMD_USB
> +#define CONFIG_USB_EHCI
> +#define CONFIG_USB_EHCI_MX6
> +#define CONFIG_USB_STORAGE
> +#define CONFIG_USB_HOST_ETHER
> +#define CONFIG_USB_ETHER_ASIX
> +#define CONFIG_USB_ETHER_SMSC95XX
> +#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
> +#define CONFIG_EHCI_HCD_INIT_AFTER_RESET  /* For OTG port */
> +#define CONFIG_MXC_USB_PORTSC     (PORT_PTS_UTMI | PORT_PTS_PTW)
> +#define CONFIG_MXC_USB_FLAGS      0
> +#define CONFIG_USB_KEYBOARD
> +#define CONFIG_MV_UDC
> +#define CONFIG_USBD_HS
> +#define CONFIG_USB_GADGET_DUALSPEED
> +#define CONFIG_USB_ETHER
> +#define CONFIG_USB_ETH_CDC
> +#define CONFIG_NETCONSOLE
> +#define CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP
> +#define CONFIG_USB_HUB_MIN_POWER_ON_DELAY 1200
> +
> +/* serial console (ttymxc1,115200) */
> +#define CONFIG_CONS_INDEX              1
> +#define CONFIG_BAUDRATE                115200
> +
> +/* Miscellaneous configurable options */
> +#define CONFIG_SYS_LONGHELP
> +#define CONFIG_SYS_HUSH_PARSER
> +#define CONFIG_SYS_PROMPT	             "Ventana > "
> +#define CONFIG_SYS_CBSIZE	             1024
> +#define CONFIG_AUTO_COMPLETE
> +#define CONFIG_CMDLINE_EDITING
> +#define CONFIG_HWCONFIG
> +
> +/* Print Buffer Size */
> +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
> +#define CONFIG_SYS_MAXARGS	           16
> +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
> +
> +/* Memory configuration */
> +#define CONFIG_SYS_MEMTEST_START       0x10000000
> +#define CONFIG_SYS_MEMTEST_END	       0x10010000
> +#define CONFIG_SYS_MEMTEST_SCRATCH     0x10800000
> +#define CONFIG_SYS_TEXT_BASE	         0x17800000
> +#define CONFIG_SYS_LOAD_ADDR           0x12000000
> +
> +/* Physical Memory Map */
> +#define CONFIG_NR_DRAM_BANKS           1
> +#define PHYS_SDRAM                     MMDC0_ARB_BASE_ADDR
> +#define CONFIG_SYS_SDRAM_BASE          PHYS_SDRAM
> +#define CONFIG_SYS_INIT_RAM_ADDR       IRAM_BASE_ADDR
> +#define CONFIG_SYS_INIT_RAM_SIZE       IRAM_SIZE
> +
> +#define CONFIG_SYS_INIT_SP_OFFSET \
> +	(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
> +#define CONFIG_SYS_INIT_SP_ADDR \
> +	(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
> +
> +/* FLASH and environment organization */
> +#define CONFIG_SYS_NO_FLASH  /* no NOR flash */
> +
> +/*
> + * MTD Command for mtdparts
> + */
> +#define CONFIG_CMD_MTDPARTS
> +#define CONFIG_MTD_DEVICE
> +#define CONFIG_MTD_PARTITIONS
> +#ifdef CONFIG_SPI_FLASH
> +#define MTDIDS_DEFAULT    "nor0=nor"
> +#define MTDPARTS_DEFAULT  \
> +	"mtdparts=nor:512k(uboot),64k(env),2m(kernel),-(rootfs)"
> +#else
> +#define MTDIDS_DEFAULT    "nand0=nand"
> +#define MTDPARTS_DEFAULT  "mtdparts=nand:16m(uboot),1m(env),-(rootfs)"
> +#endif
> +
> +/* Persistent Environment Config */
> +#define CONFIG_ENV_OVERWRITE    /* allow to overwrite serial and ethaddr */
> +#ifdef CONFIG_SPI_FLASH
> +#define CONFIG_ENV_IS_IN_SPI_FLASH
> +#else
> +#define CONFIG_ENV_IS_IN_NAND
> +#endif
> +#if defined(CONFIG_ENV_IS_IN_MMC)

Is it a case ? You have CONFIG_ENV_IS_IN_SPI_FLASH or
CONFIG_ENV_IS_IN_NAND. This seems to me a dead case.

> +  #define CONFIG_ENV_OFFSET              (6 * 64 * 1024)
> +  #define CONFIG_ENV_SIZE                (8 * 1024)
> +  #define CONFIG_SYS_MMC_ENV_DEV         0
> +#elif defined(CONFIG_ENV_IS_IN_NAND)
> +  #define CONFIG_ENV_OFFSET              (16 << 20)
> +  #define CONFIG_ENV_SECT_SIZE           (128 << 10)
> +  #define CONFIG_ENV_SIZE                CONFIG_ENV_SECT_SIZE
> +  #define CONFIG_ENV_OFFSET_REDUND       (CONFIG_ENV_OFFSET + (512 << 10))
> +  #define CONFIG_ENV_SIZE_REDUND         CONFIG_ENV_SIZE
> +#elif defined(CONFIG_ENV_IS_IN_SPI_FLASH)
> +  #define CONFIG_ENV_OFFSET              (512 * 1024)
> +  #define CONFIG_ENV_SECT_SIZE           (64 * 1024)
> +  #define CONFIG_ENV_SIZE                (8 * 1024)
> +  #define CONFIG_ENV_SPI_BUS             CONFIG_SF_DEFAULT_BUS
> +  #define CONFIG_ENV_SPI_CS              CONFIG_SF_DEFAULT_CS
> +  #define CONFIG_ENV_SPI_MODE            CONFIG_SF_DEFAULT_MODE
> +  #define CONFIG_ENV_SPI_MAX_HZ          CONFIG_SF_DEFAULT_SPEED
> +#endif
> +
> +/* Environment */
> +#define CONFIG_BOOTDELAY          3
> +#define CONFIG_LOADADDR           CONFIG_SYS_LOAD_ADDR
> +#define CONFIG_IPADDR             192.168.1.1
> +#define CONFIG_SERVERIP           192.168.1.146
> +#define HWCONFIG_DEFAULT \
> +	"hwconfig=rs232;" \
> +	"dio0:mode=gpio;dio1:mode=gpio;dio2:mode=gpio;dio3:mode=gpio\0" \
> +
> +#define CONFIG_EXTRA_ENV_SETTINGS_COMMON \
> +	"console=ttymxc1\0" \
> +	"bootdevs=usb mmc sata flash\0" \
> +	HWCONFIG_DEFAULT \
> +	"video=\0" \
> +	\
> +	"mtdparts=" MTDPARTS_DEFAULT "\0" \
> +	"mtdids=" MTDIDS_DEFAULT "\0" \
> +	\
> +	"fdt_high=0xffffffff\0" \
> +	"fdt_addr=0x18000000\0" \
> +	"loadfdt=" \
> +		"if ${fsload} ${fdt_addr} boot/${fdt_file}; then " \
> +			"echo Loaded DTB from boot/${fdt_file}; " \
> +		"elif ${fsload} ${fdt_addr} boot/${fdt_file1}; then " \
> +			"echo Loaded DTB from boot/${fdt_file1}; " \
> +		"elif ${fsload} ${fdt_addr} boot/${fdt_file2}; then " \
> +				"echo Loaded DTB from boot/${fdt_file2}; " \
> +		"fi\0" \
> +	\
> +	"script=boot/6x_bootscript-ventana\0" \
> +	"loadscript=" \
> +		"if ${fsload} ${loadaddr} ${script}; then " \
> +			"source; " \
> +		"fi\0" \
> +	\
> +	"uimage=boot/uImage\0" \
> +	"mmc_root=/dev/mmcblk0p1 rootfstype=ext4 rootwait rw\0" \
> +	"mmc_boot=" \
> +		"setenv fsload 'ext2load mmc 0:1'; " \
> +		"mmc dev 0 && mmc rescan && " \
> +		"run loadscript; " \
> +		"if ${fsload} ${loadaddr} ${uimage}; then " \
> +			"setenv bootargs console=${console},${baudrate} " \
> +				"root=/dev/mmcblk0p1 rootfstype=ext4 " \
> +				"rootwait rw ${video} ${extra}; " \
> +			"if run loadfdt && fdt addr ${fdt_addr}; then " \
> +				"bootm ${loadaddr} - ${fdt_addr}; " \
> +			"else " \
> +				"bootm; " \
> +			"fi; " \
> +		"fi\0" \
> +	\
> +	"sata_boot=" \
> +		"setenv fsload 'ext2load sata 0:1'; sata init && " \
> +		"run loadscript; " \
> +		"if ${fsload} ${loadaddr} ${uimage}; then " \
> +			"setenv bootargs console=${console},${baudrate} " \
> +				"root=/dev/sda1 rootfstype=ext4 " \
> +				"rootwait rw ${video} ${extra}; " \
> +			"if run loadfdt && fdt addr ${fdt_addr}; then " \
> +				"bootm ${loadaddr} - ${fdt_addr}; " \
> +			"else " \
> +				"bootm; " \
> +			"fi; " \
> +		"fi\0" \
> +	"usb_boot=" \
> +		"setenv fsload 'ext2load usb 0:1'; usb start && usb dev 0 && " \
> +		"run loadscript; " \
> +		"if ${fsload} ${loadaddr} ${uimage}; then " \
> +			"setenv bootargs console=${console},${baudrate} " \
> +				"root=/dev/sda1 rootfstype=ext4 " \
> +				"rootwait rw ${video} ${extra}; " \
> +			"if run loadfdt && fdt addr ${fdt_addr}; then " \
> +				"bootm ${loadaddr} - ${fdt_addr}; " \
> +			"else " \
> +				"bootm; " \
> +			"fi; " \
> +		"fi\0"
> +
> +#ifdef CONFIG_SPI_FLASH
> +	#define CONFIG_EXTRA_ENV_SETTINGS \
> +	CONFIG_EXTRA_ENV_SETTINGS_COMMON \
> +	"image_os=ventana/openwrt-imx6-imx6q-gw5400-a-squashfs.bin\0" \
> +	"image_uboot=ventana/u-boot_spi.imx\0" \
> +	\
> +	"spi_koffset=0x90000\0" \
> +	"spi_klen=0x200000\0" \
> +	\
> +	"spi_updateuboot=echo Updating uboot from " \
> +		"${serverip}:${image_uboot}...; " \
> +		"tftpboot ${loadaddr} ${image_uboot} && " \
> +		"sf probe && sf erase 0 80000 && " \
> +			"sf write ${loadaddr} 400 ${filesize}\0" \
> +	"spi_update=echo Updating OS from ${serverip}:${image_os} " \
> +		"to ${spi_koffset} ...; " \
> +		"tftp ${loadaddr} ${image_os} && " \
> +		"sf probe && " \
> +		"sf update ${loadaddr} ${spi_koffset} ${filesize}\0" \
> +	\
> +	"flash_boot=" \
> +		"if sf probe && " \
> +		"sf read ${loadaddr} ${spi_koffset} ${spi_klen}; then " \
> +			"setenv bootargs console=${console},${baudrate} " \
> +				"root=/dev/mtdblock3 " \
> +				"rootfstype=squashfs,jffs2 " \
> +				"${video} ${extra}; " \
> +			"bootm; " \
> +		"fi\0"
> +#else
> +	#define CONFIG_EXTRA_ENV_SETTINGS \
> +	CONFIG_EXTRA_ENV_SETTINGS_COMMON \
> +	"image_rootfs=openwrt-imx6-ventana-rootfs.ubi\0" \
> +	\
> +	"nand_update=echo Updating NAND from ${serverip}:${image_rootfs}...; " \
> +		"tftp ${loadaddr} ${image_rootfs} && " \
> +		"nand erase.part rootfs && " \
> +		"nand write ${loadaddr} rootfs ${filesize}\0" \
> +	\
> +	"flash_boot=" \
> +		"setenv fsload 'ubifsload'; " \
> +		"ubi part rootfs && ubifsmount ubi0:rootfs; " \
> +		"run loadscript; " \
> +		"if ${fsload} ${loadaddr} ${uimage}; then " \
> +			"setenv bootargs console=${console},${baudrate} " \
> +				"root=ubi0:rootfs ubi.mtd=2 " \
> +				"rootfstype=ubifs ${video} ${extra}; " \
> +			"if run loadfdt && fdt addr ${fdt_addr}; then " \
> +				"ubifsumount; " \
> +				"bootm ${loadaddr} - ${fdt_addr}; " \
> +			"else " \
> +				"ubifsumount; bootm; " \
> +			"fi; " \
> +		"fi\0"
> +#endif
> +
> +#define CONFIG_BOOTCOMMAND \
> +	"for btype in ${bootdevs}; do " \
> +		"echo; echo Attempting ${btype} boot...; " \
> +		"if run ${btype}_boot; then; fi; " \
> +	"done"
> +
> +/* Device Tree Support */
> +#define CONFIG_OF_BOARD_SETUP
> +#define CONFIG_OF_LIBFDT
> +#define CONFIG_FDT_FIXUP_PARTITIONS
> +
> +#ifndef CONFIG_SYS_DCACHE_OFF
> +  #define CONFIG_CMD_CACHE
> +#endif
> +
> +#endif			       /* __CONFIG_H */
> 


Best regards,
Stefano Babic
Tim Harvey Feb. 5, 2014, 8:17 a.m. UTC | #2
On Mon, Feb 3, 2014 at 9:39 AM, Stefano Babic <sbabic@denx.de> wrote:
> Hi Tim,
>
> On 01/02/2014 20:49, Tim Harvey wrote:
>> Gateworks Ventana is a product family based on the i.MX6.  This
>> patch adds support for all boards in the Ventana family. Where
>> possible, data from the boards EEPROM is used to determine various
>> details about the board at runtime.
>>
>> Signed-off-by: Tim Harvey <tharvey@gateworks.com>
>> ---
>>  board/gateworks/gw_ventana/Makefile         |   10 +
>>  board/gateworks/gw_ventana/README           |   56 ++
>>  board/gateworks/gw_ventana/clocks.cfg       |   42 +
>>  board/gateworks/gw_ventana/gsc.c            |  129 +++
>>  board/gateworks/gw_ventana/gsc.h            |    9 +
>>  board/gateworks/gw_ventana/gw_ventana.c     | 1200 +++++++++++++++++++++++++++
>>  board/gateworks/gw_ventana/gw_ventana.cfg   |   42 +
>>  board/gateworks/gw_ventana/ventana_eeprom.h |  103 +++
>>  boards.cfg                                  |    5 +
>>  include/configs/gw_ventana.h                |  418 ++++++++++
>>  10 files changed, 2014 insertions(+)
>>  create mode 100644 board/gateworks/gw_ventana/Makefile
>>  create mode 100644 board/gateworks/gw_ventana/README
>>  create mode 100644 board/gateworks/gw_ventana/clocks.cfg
>>  create mode 100644 board/gateworks/gw_ventana/gsc.c
>>  create mode 100644 board/gateworks/gw_ventana/gsc.h
>>  create mode 100644 board/gateworks/gw_ventana/gw_ventana.c
>>  create mode 100644 board/gateworks/gw_ventana/gw_ventana.cfg
>>  create mode 100644 board/gateworks/gw_ventana/ventana_eeprom.h
>>  create mode 100644 include/configs/gw_ventana.h
>>
>> diff --git a/board/gateworks/gw_ventana/Makefile b/board/gateworks/gw_ventana/Makefile
>> new file mode 100644
>> index 0000000..e8dab89
>> --- /dev/null
>> +++ b/board/gateworks/gw_ventana/Makefile
>> @@ -0,0 +1,10 @@
>> +#
>> +# Copyright (C) 2012-2013, Guennadi Liakhovetski <lg@denx.de>
>> +# (C) Copyright 2012-2013 Freescale Semiconductor, Inc.
>> +# Copyright (C) 2013, Gateworks Corporation
>> +#
>> +# SPDX-License-Identifier:  GPL-2.0+
>> +#
>> +
>> +obj-y  := gw_ventana.o gsc.o
>> +
>> diff --git a/board/gateworks/gw_ventana/README b/board/gateworks/gw_ventana/README
>> new file mode 100644
>> index 0000000..f744a4a
>> --- /dev/null
>> +++ b/board/gateworks/gw_ventana/README
>> @@ -0,0 +1,56 @@
>> +U-Boot for the Gateworks Ventana Product Family boards
>> +
>> +This file contains information for the port of U-Boot to the Gateworks
>> +Ventana Product family boards.
>> +
>> +1. Boot source, boot from NAND
>> +------------------------------
>> +
>> +The i.MX6 BOOT ROM expects some structures that provide details of NAND layout
>> +and bad block information (referred to as 'bootstreams') which are replicated
>> +multiple times in NAND. The number of replications is configurable through
>> +board strapping options and eFUSE settings.  The Freescale 'kobs-ng'
>> +application from the Freescale LTIB BSP, which runs under Linux, must be used
>> +to program the bootstream in order to setup the replicated headers correctly.
>> +
>> +The Gateworks Ventana boards with NAND flash have been factory programmed
>> +such that their eFUSE settings expect 2 copies of the boostream (this is
>> +specified by providing kobs-ng with the --search_exponent=1 argument). Once in
>> +Linux with MTD support for the NAND on /dev/mtd0 you can program the boostream
>> +with:
>> +
>> +kobs-ng init -v -x --search_exponent=1 u-boot.imx
>> +
>> +The kobs-ng application users an imximage (u-boot.imx) which contains the
>                             ^-- spelling, uses

will fix

>
>> +Image Vector Table (IVT) and Device Configuration Data (DCD) structures that
>> +the i.MX6 BOOT ROM requires to boot.  The kobs-ng adds the Firmware
>> +Configuration Block (FCB) and Discovered Bad Block Table (DBBT).
>> +
>> +This information is taken from:
>> +  http://trac.gateworks.com/wiki/ventana/bootloader#NANDFLASH
>> +
>> +More details about the i.MX6 BOOT ROM can be found at:
>> +  http://cache.freescale.com/files/32bit/doc/ref_manual/IMX6DQRM.pdf
>
> Why cache.freescale ? I think you can simply write that more information
> are in the User Manual. Freescale moves sometimes the location of the
> documentation.

will replace with:

More details about the i.MX6 BOOT ROM can be found in the IMX6
reference manuals.

>
>> diff --git a/board/gateworks/gw_ventana/gsc.c b/board/gateworks/gw_ventana/gsc.c
>> new file mode 100644
>> index 0000000..72eec38
>> --- /dev/null
>> +++ b/board/gateworks/gw_ventana/gsc.c
>> @@ -0,0 +1,129 @@
>> +/*
>> + * Copyright (C) 2013 Gateworks Corporation
>> + *
>> + * Author: Tim Harvey <tharvey@gateworks.com>
>> + *
>> + * SPDX-License-Identifier: GPL-2.0+
>> + */
>> +
>> +#include <asm/errno.h>
>> +#include <common.h>
>> +#include <i2c.h>
>> +#include <linux/ctype.h>
>> +
>> +/*
>> + * 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.
>> + * When this does occur, it will never be busy long enough to fail more than
>> + * 2 back-to-back transfers.  Thus we wrap i2c_read and i2c_write with
>> + * 3 retries.
>> + */
>> +int gsc_i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
>> +{
>> +     int retry = 3;
>> +     int n = 0;
>> +     int ret;
>> +
>> +     while (n++ < retry) {
>> +             ret = i2c_read(chip, addr, alen, buf, len);
>> +             if (!ret)
>> +                     break;
>> +             printf("%s: 0x%02x 0x%02x retry%d: %d\n", __func__, chip, addr,
>> +                    n, ret);
>
> This is a debug message - you could use debug() instead of printf() to
> conditionally compile it.

will do

>
>> +             if (ret != -ENODEV)
>> +                     break;
>> +             mdelay(10);
>> +     }
>> +     return ret;
>> +}
>
>> +
>> +int gsc_i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
>> +{
>> +     int retry = 3;
>> +     int n = 0;
>> +     int ret;
>> +
>> +     while (n++ < retry) {
>> +             ret = i2c_write(chip, addr, alen, buf, len);
>> +             if (!ret)
>> +                     break;
>> +             printf("%s: 0x%02x 0x%02x retry%d: %d\n", __func__, chip, addr,
>> +                    n, ret);
>
> Ditto.
>
>> +             if (ret != -ENODEV)
>> +                     break;
>> +             mdelay(10);
>> +     }
>> +     mdelay(1);
>> +     return ret;
>> +}
>> +
>> +#ifdef CONFIG_CMD_GSC
>> +static void read_hwmon(const char *name, uint reg, uint size, uint low,
>> +                    uint high)
>> +{
>> +     unsigned char buf[3];
>> +     uint ui;
>> +
>> +     printf("%-8s:", name);
>> +     memset(buf, 0, sizeof(buf));
>> +     if (gsc_i2c_read(0x29, reg, 1, buf, size)) {
>                          ^---- use a #define for the I2c address

will do

>
>> +             puts("fRD\n");
>> +     } else {
>> +             ui = buf[0] | (buf[1]<<8) | (buf[2]<<16);
>> +             if (ui == 0xffffff)
>> +                     printf("fVL");
>> +             else if (ui < low)
>> +                     printf("%d fLO", ui);
>
> What is fLO ? Low Overflow or what else ? Can you add comments to these ?

agreed this is cryptic.  I will replace with 'invalid', 'failed -
low', 'failed -high'.

>
>> +             else if (ui > high)
>> +                     printf("%d fHI", ui);
>> +             else
>> +                     printf("%d", ui);
>> +     }
>> +     puts("\n");
>> +}
>> +
>> +int do_gsc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>> +{
>> +     const char *model = getenv("model");
>> +
>> +     i2c_set_bus_num(0);
>> +     read_hwmon("Temp",     0x00, 2, 0, 9000);
>> +     read_hwmon("VIN",      0x02, 3, 8000, 60000);
>> +     read_hwmon("VDD_3P3",  0x05, 3, 3300*0.9, 3300*1.1);
>> +     read_hwmon("VBATT",    0x08, 3, 2000*0.9, 3000*1.1);
>> +     read_hwmon("VDD_HIGH", 0x14, 3, 3000*0.9, 3000*1.1);
>> +     read_hwmon("VDD_DDR",  0x17, 3, 1500*0.9, 1500*1.1);
>> +     read_hwmon("VDD_5P0",  0x0b, 3, 5000*0.9, 5000*1.1);
>> +     read_hwmon("VDD_2P5",  0x23, 3, 2500*0.9, 2500*1.1);
>> +     read_hwmon("VDD_1P8",  0x1d, 3, 1800*0.9, 1800*1.1);
>
> It will be better to add the register layout to gsc.h and using the
> defines here.

will do

>
>> +
>> +     switch (model[3]) {
>> +     case '1': /* GW51xx */
>> +             read_hwmon("VDD_CORE", 0x0e, 3, 1175*0.9, 1175*1.1);
>> +             read_hwmon("VDD_SOC",  0x11, 3, 1175*0.9, 1175*1.1);
>> +             break;
>
> What about a macro that get the variation in percent as parameter ?

how about:

#define MINMAX(n, percent)  n*(1.0-percent/100), n*(1.0+percent/100)

read_hwmon("VDD_CORE", GSC_HWMON_VDD_CORE, 3, MINMAX(1175, 10));
...

>
>> +     case '2': /* GW52xx */
>> +             read_hwmon("VDD_CORE", 0x0e, 3, 1175*0.9, 1175*1.1);
>> +             read_hwmon("VDD_SOC",  0x11, 3, 1175*0.9, 1175*1.1);
>> +             read_hwmon("VDD_1P0",  0x20, 3, 1000*0.9, 1000*1.1);
>> +             break;
>> +     case '3': /* GW53xx */
>> +             read_hwmon("VDD_CORE", 0x0e, 3, 1175*0.9, 1175*1.1);
>> +             read_hwmon("VDD_SOC",  0x11, 3, 1175*0.9, 1175*1.1);
>> +             read_hwmon("VDD_1P0",  0x20, 3, 1000*0.9, 1000*1.1);
>> +             break;
>> +     case '4': /* GW54xx */
>> +             read_hwmon("VDD_CORE", 0x0e, 3, 1375*0.9, 1375*1.1);
>> +             read_hwmon("VDD_SOC",  0x11, 3, 1375*0.9, 1375*1.1);
>> +             read_hwmon("VDD_1P0",  0x20, 3, 1000*0.9, 1000*1.1);
>> +             break;
>> +     }
>> +     return 0;
>> +}
>> +
>> +U_BOOT_CMD(gsc, 1, 1, do_gsc,
>> +        "GSC test",
>> +        ""
>> +);
>> +
>> +#endif /* CONFIG_CMD_GSC */
>> diff --git a/board/gateworks/gw_ventana/gsc.h b/board/gateworks/gw_ventana/gsc.h
>> new file mode 100644
>> index 0000000..6b9cb98
>> --- /dev/null
>> +++ b/board/gateworks/gw_ventana/gsc.h
>> @@ -0,0 +1,9 @@
>> +#ifndef __ASSEMBLY__
>> +/*
>> + * I2C transactions to the GSC are done via these functions which
>> + * perform retries in the case of a busy GSC NAK'ing the transaction
>> + */
>> +extern int gsc_i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len);
>> +extern int gsc_i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len);
>
> You do not need to use the "extern" keywords, see all other U-Boot
> header files.

ok

>
>> +#endif
>> +
>> diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c
>> new file mode 100644
>> index 0000000..d8c9989
>> --- /dev/null
>> +++ b/board/gateworks/gw_ventana/gw_ventana.c
<snip>
>> +
>> +/*
>> + * read ventana EEPROM and return structure or NULL on error
>> + * should be called once, the first time eeprom data is needed
>> + */
>> +static void
>> +read_eeprom(void)
>> +{
>> +     int i;
>> +     int chksum;
>> +     struct ventana_board_info *info = &ventana_info;
>> +     unsigned char *buf = (unsigned char *)&ventana_info;
>> +
>> +     memset(info, 0, sizeof(ventana_info));
>> +
>> +     /*
>> +      * On a board with a missing/depleted backup battery for GSC, the
>> +      * board may be ready to probe the GSC before its firmware is
>> +      * running.  We will wait here indefinately for the GSC/EEPROM.
>> +      */
>> +     while (1) {
>> +             if (0 == i2c_set_bus_num(0) && 0 == i2c_probe(0x51))
>> +                     break;
>> +             mdelay(1);
>> +     }
>> +
>> +     /* read eeprom config section */
>> +     if (gsc_i2c_read(0x51, 0x00, 1, buf, sizeof(ventana_info))) {
>
> Use define for I2C address. Fix it globally.

ok

>
>> +             puts("EEPROM: Failed to read EEPROM\n");
>> +             info->model[0] = 0;
>> +             return;
>> +     }
>> +
>> +     /* sanity checks */
>> +     if (info->model[0] != 'G' || info->model[1] != 'W') {
>> +             puts("EEPROM: Invalid Model in EEPROM\n");
>> +             info->model[0] = 0;
>> +             return;
>> +     }
>> +
>> +     /* validate checksum */
>> +     for (chksum = 0, i = 0; i < sizeof(*info)-2; i++)
>> +             chksum += buf[i];
>> +     if ((info->chksum[0] != chksum>>8) ||
>> +         (info->chksum[1] != (chksum&0xff))) {
>> +             puts("EEPROM: Failed EEPROM checksum\n");
>> +             info->model[0] = 0;
>> +             return;
>> +     }
>> +}
>> +
>> +/*
>> + * Baseboard specific GPIO
>> + */
>> +
>> +/* common to add baseboards */
>> +static iomux_v3_cfg_t const gw_gpio_pads[] = {
>> +     /* MSATA_EN */
>> +     MX6_PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* RS232_EN# */
>> +     MX6_PAD_SD4_DAT3__GPIO2_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +};
>> +
>> +/* prototype */
>> +static iomux_v3_cfg_t const gwproto_gpio_pads[] = {
>> +     /* PANLEDG# */
>> +     MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* PANLEDR# */
>> +     MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* LOCLED# */
>> +     MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* RS485_EN */
>> +     MX6_PAD_SD3_DAT4__GPIO7_IO01 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* IOEXP_PWREN# */
>> +     MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* IOEXP_IRQ# */
>> +     MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* VID_EN */
>> +     MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* DIOI2C_DIS# */
>> +     MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* PCICK_SSON */
>> +     MX6_PAD_SD1_CLK__GPIO1_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* PCI_RST# */
>> +     MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +};
>> +
>> +static iomux_v3_cfg_t const gw51xx_gpio_pads[] = {
>> +     /* PANLEDG# */
>> +     MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* PANLEDR# */
>> +     MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* IOEXP_PWREN# */
>> +     MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* IOEXP_IRQ# */
>> +     MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +
>> +     /* GPS_SHDN */
>> +     MX6_PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* VID_PWR */
>> +     MX6_PAD_CSI0_DATA_EN__GPIO5_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* PCI_RST# */
>> +     MX6_PAD_GPIO_0__GPIO1_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +};
>> +
>> +static iomux_v3_cfg_t const gw52xx_gpio_pads[] = {
>> +     /* PANLEDG# */
>> +     MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* PANLEDR# */
>> +     MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* IOEXP_PWREN# */
>> +     MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* IOEXP_IRQ# */
>> +     MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +
>> +     /* MX6_LOCLED# */
>> +     MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* GPS_SHDN */
>> +     MX6_PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* USBOTG_SEL */
>> +     MX6_PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* VID_PWR */
>> +     MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* PCI_RST# */
>> +     MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +};
>> +
>> +static iomux_v3_cfg_t const gw53xx_gpio_pads[] = {
>> +     /* PANLEDG# */
>> +     MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* PANLEDR# */
>> +     MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* IOEXP_PWREN# */
>> +     MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* IOEXP_IRQ# */
>> +     MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +
>> +     /* MX6_LOCLED# */
>> +     MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* GPS_SHDN */
>> +     MX6_PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* VID_EN */
>> +     MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* PCI_RST# */
>> +     MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +};
>> +
>> +static iomux_v3_cfg_t const gw54xx_gpio_pads[] = {
>> +     /* PANLEDG# */
>> +     MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* PANLEDR# */
>> +     MX6_PAD_KEY_COL2__GPIO4_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* MX6_LOCLED# */
>> +     MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* MIPI_DIO */
>> +     MX6_PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* RS485_EN */
>> +     MX6_PAD_EIM_D24__GPIO3_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* IOEXP_PWREN# */
>> +     MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* IOEXP_IRQ# */
>> +     MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* DIOI2C_DIS# */
>> +     MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* DIOI2C_DIS# */
>> +     MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* PCICK_SSON */
>> +     MX6_PAD_SD1_CLK__GPIO1_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +     /* PCI_RST# */
>> +     MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
>> +};
>> +
>> +/* setup GPIO pinmux and default configuration per baseboard */
>> +static void setup_board_gpio(void)
>> +{
>> +     struct ventana_board_info *info = &ventana_info;
>> +     const char *s;
>> +     char arg[10];
>> +     size_t len;
>> +     int i;
>> +     char baseboard = info->model[3];
>> +     enum {
>> +             GW51xx,
>> +             GW52xx,
>> +             GW53xx,
>> +             GW54xx,
>> +             GW54proto, /* original GW5400-A prototype */
>> +             UNKNOWN,
>> +     };
>> +     struct dio_cfg {
>> +             iomux_v3_cfg_t gpio_padmux;
>> +             unsigned gpio_param;
>> +             iomux_v3_cfg_t pwm_padmux;
>> +             unsigned pwm_param;
>> +     };
>> +     int board_type = UNKNOWN;
>> +     int quiet = simple_strtol(getenv("quiet"), NULL, 10);
>> +     struct dio_cfg dio_cfg[] = {
>> +             /* GW51xx */
>> +             { MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16),
>> +                     0, 0 },
>> +             { MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
>> +                     MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
>> +             { MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17),
>> +                     MX6_PAD_SD1_DAT1__PWM3_OUT, 3 },
>> +             { MX6_PAD_SD1_CMD__GPIO1_IO18, IMX_GPIO_NR(1, 18),
>> +                     MX6_PAD_SD1_CMD__PWM4_OUT, 4 },
>> +
>> +             /* GW52xx */
>> +             { MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16),
>> +                     0, 0 },
>> +             { MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
>> +                     MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
>> +             { MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17),
>> +                     MX6_PAD_SD1_DAT1__PWM3_OUT, 3 },
>> +             { MX6_PAD_SD1_CLK__GPIO1_IO20, IMX_GPIO_NR(1, 20),
>> +                     0, 0 },
>> +
>> +             /* GW53xx */
>> +             { MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16),
>> +                     0, 0 },
>> +             { MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
>> +                     MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
>> +             { MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17),
>> +                     MX6_PAD_SD1_DAT1__PWM3_OUT, 3 },
>> +             { MX6_PAD_SD1_CLK__GPIO1_IO20, IMX_GPIO_NR(1, 20),
>> +                     0, 0 },
>> +
>> +             /* GW54xx */
>> +             { MX6_PAD_GPIO_9__GPIO1_IO09, IMX_GPIO_NR(1, 9),
>> +                     MX6_PAD_GPIO_9__PWM1_OUT, 1 },
>> +             { MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
>> +                     MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
>> +             { MX6_PAD_SD4_DAT1__GPIO2_IO09, IMX_GPIO_NR(2, 9),
>> +                     MX6_PAD_SD4_DAT1__PWM3_OUT, 3 },
>> +             { MX6_PAD_SD4_DAT2__GPIO2_IO10, IMX_GPIO_NR(2, 10),
>> +                     MX6_PAD_SD4_DAT2__PWM4_OUT, 4 },
>> +
>> +             /* GW54proto */
>> +             { MX6_PAD_GPIO_9__GPIO1_IO09, IMX_GPIO_NR(1, 9),
>> +                     MX6_PAD_GPIO_9__PWM1_OUT, 1 },
>> +             { MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
>> +                     MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
>> +             { MX6_PAD_SD4_DAT1__GPIO2_IO09, IMX_GPIO_NR(2, 9),
>> +                     MX6_PAD_SD4_DAT1__PWM3_OUT, 3 },
>> +             { MX6_PAD_SD4_DAT2__GPIO2_IO10, IMX_GPIO_NR(2, 10),
>> +                     MX6_PAD_SD4_DAT2__PWM4_OUT, 4 },
>> +     };
>> +
>> +     /* Common GPIO configuration */
>> +     imx_iomux_v3_setup_multiple_pads(gw_gpio_pads,
>> +                                      ARRAY_SIZE(gw_gpio_pads));
>> +     /* RS232_EN# */
>> +     gpio_direction_output(GP_RS232_EN, (hwconfig("rs232")) ? 0 : 1);
>> +
>> +     /* MSATA Enable */
>> +     if (is_cpu_type(MXC_CPU_MX6Q) &&
>> +         test_bit(EECONFIG_SATA, info->config)) {
>> +             gpio_direction_output(GP_MSATA_SEL,
>> +                                   (hwconfig("msata")) ?  1 : 0);
>> +     } else {
>> +             gpio_direction_output(GP_MSATA_SEL, 0);
>> +     }
>> +
>> +     /* original GW5400-A prototype */
>> +     if (strncasecmp((const char *)info->model, "GW5400-A", 8) == 0)
>> +             baseboard = '0';
>> +
>> +     switch (baseboard) {
>> +     case '0': /* original GW5400-A prototype */
>> +             board_type = GW54proto;
>> +             imx_iomux_v3_setup_multiple_pads(gwproto_gpio_pads,
>> +                                              ARRAY_SIZE(gwproto_gpio_pads));
>> +             /* PANLEDG# (GRN off) */
>> +             gpio_direction_output(IMX_GPIO_NR(4, 6), 1);
>> +             /* PANLEDR# (RED off) */
>> +             gpio_direction_output(IMX_GPIO_NR(4, 10), 1);
>> +             /* MX6_LOCLED# (off) */
>> +             gpio_direction_output(IMX_GPIO_NR(4, 15), 1);
>> +             /* RS485 Transmit Enable */
>> +             gpio_direction_output(IMX_GPIO_NR(3, 24), 0);
>> +             /* Expansion IO0 - PWREN# */
>> +             gpio_direction_output(IMX_GPIO_NR(4, 7), 0);
>> +             /* Expansion IO1 - IRQ# */
>> +             gpio_direction_input(IMX_GPIO_NR(4, 9));
>> +             /* DIOI2C_DIS# */
>> +             gpio_direction_output(IMX_GPIO_NR(4,  5), 0);
>> +             /* PCICK_SSON: disable spread-spectrum clock */
>> +             gpio_direction_output(IMX_GPIO_NR(1, 20), 0);
>> +             /* assert PCI_RST# (released by OS when clock is valid) */
>> +             gpio_direction_output(IMX_GPIO_NR(1, 29), 0);
>> +             break;
>> +
>> +     case '1':
>> +             board_type = GW51xx;
>> +             imx_iomux_v3_setup_multiple_pads(gw51xx_gpio_pads,
>> +                                              ARRAY_SIZE(gw51xx_gpio_pads));
>> +             /* PANLEDG# (GRN off) */
>> +             gpio_direction_output(IMX_GPIO_NR(4, 6), 1);
>> +             /* PANLEDR# (RED off) */
>> +             gpio_direction_output(IMX_GPIO_NR(4, 7), 1);
>> +             /* GPS_SHDN */
>> +             gpio_direction_output(IMX_GPIO_NR(1, 2), 1);
>> +             /* Analog video codec power enable */
>> +             gpio_direction_output(IMX_GPIO_NR(5, 20), 1);
>> +             /* Expansion IO0 - PWREN# */
>> +             gpio_direction_output(IMX_GPIO_NR(2, 19), 0);
>> +             /* Expansion IO1 - IRQ# */
>> +             gpio_direction_input(IMX_GPIO_NR(2, 18));
>> +             /* assert PCI_RST# (released by OS when clock is valid) */
>> +             gpio_direction_output(IMX_GPIO_NR(1, 0), 0);
>> +             break;
>> +
>> +     case '2':
>> +             board_type = GW52xx;
>> +             imx_iomux_v3_setup_multiple_pads(gw52xx_gpio_pads,
>> +                                              ARRAY_SIZE(gw52xx_gpio_pads));
>> +             /* PANLEDG# (GRN off) */
>> +             gpio_direction_output(IMX_GPIO_NR(4, 6), 1);
>> +             /* PANLEDR# (RED off) */
>> +             gpio_direction_output(IMX_GPIO_NR(4, 7), 1);
>> +             /* MX6_LOCLED# (off) */
>> +             gpio_direction_output(IMX_GPIO_NR(4, 15), 1);
>> +             /* GPS_SHDN */
>> +             gpio_direction_output(IMX_GPIO_NR(1, 27), 1);
>> +             /* Expansion IO0 - PWREN# */
>> +             gpio_direction_output(IMX_GPIO_NR(2, 19), 0);
>> +             /* Expansion IO1 - IRQ# */
>> +             gpio_direction_input(IMX_GPIO_NR(2, 18));
>> +             /* USBOTG Select (PCISKT or FrontPanel) */
>> +             gpio_direction_output(IMX_GPIO_NR(1, 2), 0);
>> +             /* Analog video codec power enable */
>> +             gpio_direction_output(IMX_GPIO_NR(3, 31), 1);
>> +             /* assert PCI_RST# (released by OS when clock is valid) */
>> +             gpio_direction_output(IMX_GPIO_NR(1, 29), 0);
>> +             break;
>> +
>> +     case '3':
>> +             board_type = GW53xx;
>> +             imx_iomux_v3_setup_multiple_pads(gw53xx_gpio_pads,
>> +                                              ARRAY_SIZE(gw53xx_gpio_pads));
>> +             /* PANLEDG# (GRN off) */
>> +             gpio_direction_output(IMX_GPIO_NR(4, 6), 1);
>> +             /* PANLEDR# (RED off) */
>> +             gpio_direction_output(IMX_GPIO_NR(4, 7), 1);
>> +             /* MX6_LOCLED# (off) */
>> +             gpio_direction_output(IMX_GPIO_NR(4, 15), 1);
>> +             /* GPS_SHDN */
>> +             gpio_direction_output(IMX_GPIO_NR(1, 27), 1);
>> +             /* Expansion IO0 - PWREN# */
>> +             gpio_direction_output(IMX_GPIO_NR(2, 19), 0);
>> +             /* Expansion IO1 - IRQ# */
>> +             gpio_direction_input(IMX_GPIO_NR(2, 18));
>> +             /* Analog video codec power enable */
>> +             gpio_direction_output(IMX_GPIO_NR(3, 31), 1);
>> +             /* assert PCI_RST# (released by OS when clock is valid) */
>> +             gpio_direction_output(IMX_GPIO_NR(1, 29), 0);
>> +             break;
>> +
>> +     case '4':
>> +             board_type = GW54xx;
>> +             imx_iomux_v3_setup_multiple_pads(gw54xx_gpio_pads,
>> +                                              ARRAY_SIZE(gw54xx_gpio_pads));
>> +             /* PANLEDG# (GRN off) */
>> +             gpio_direction_output(IMX_GPIO_NR(4, 6), 1);
>> +             /* PANLEDR# (RED off) */
>> +             gpio_direction_output(IMX_GPIO_NR(4, 7), 1);
>> +             /* MX6_LOCLED# (off) */
>> +             gpio_direction_output(IMX_GPIO_NR(4, 15), 1);
>> +             /* RS485 Transmit Enable */
>> +             gpio_direction_output(IMX_GPIO_NR(7, 1), 0);
>> +             /* Expansion IO0 - PWREN# */
>> +             gpio_direction_output(IMX_GPIO_NR(2, 19), 0);
>> +             /* Expansion IO1 - IRQ# */
>> +             gpio_direction_input(IMX_GPIO_NR(2, 18));
>> +             /* Analog video codec power enable */
>> +             gpio_direction_output(IMX_GPIO_NR(3, 31), 1);
>> +             /* DIOI2C_DIS# */
>> +             gpio_direction_output(IMX_GPIO_NR(4,  5), 0);
>> +             /* PCICK_SSON: disable spread-spectrum clock */
>> +             gpio_direction_output(IMX_GPIO_NR(1, 20), 0);
>> +             /* assert PCI_RST# (released by OS when clock is valid) */
>> +             gpio_direction_output(IMX_GPIO_NR(1, 29), 0);
>> +             break;
>> +     }
>
> mmhh..I think the code is still nasty and could be improved. Code is
> copied from case ti case, but the same operation are done.
>
> You could create a structure with the setup for each board. For GPIOs,
> you have the pad setting for the GPIOs and a list of gpios that must be
> set. You could rewrite this code with something like
>
> struct gpio_setup {
>         int gpio;
>         int val;
> };
>
> struct ventana {
>          iomux_v3_cfg_t gpio_pads;
>          gpio_setup gpios[..];
> };
>
>
>
> Then add the tables for each model to get the whole table:
> {
>         { gwproto_gpio_pad, ...},
>         { gw51xx_gpio_pads,...},
> }
>
> You can reuse baseboard as index in the table. With this assumption, you
> can dropü completely the switch, having selected the data before
> applying the setup. Code will be smaller, too.

I'll take this approach for v3
>
>
<snip>
>> +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
>> +/*
>> + * called prior to booting kernel or by 'fdt boardsetup' command
>> + *
>> + * unless 'fdt_noauto' env var is set we will update the following in the DTB:
>> + *  - mtd partitions based on mtdparts/mtdids env
>> + *  - system-serial (board serial num from EEPROM)
>> + *  - board (full model from EEPROM)
>> + *  - peripherals removed from DTB if not loaded on board (per EEPROM config)
>> + */
>> +void ft_board_setup(void *blob, bd_t *bd)
>> +{
>> +     struct ventana_board_info *info = &ventana_info;
>> +     struct node_info nodes[] = {
>> +             { "sst,w25q256",          MTD_DEV_TYPE_NOR, },  /* SPI flash */
>> +             { "fsl,imx6q-gpmi-nand",  MTD_DEV_TYPE_NAND, }, /* NAND flash */
>> +     };
>> +     const char *model = getenv("model");
>> +
>> +     if (getenv("fdt_noauto")) {
>> +             puts("   Skiping ft_board_setup (fdt_noauto defined)\n");
>> +             return;
>> +     }
>> +
>> +     /* Update partition nodes using info from mtdparts env var */
>> +     puts("   Updating MTD partitions...\n");
>> +     fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
>> +
>> +     if (!model) {
>> +             puts("invalid board info: Leaving FDT fully enabled\n");
>> +             return;
>> +     }
>> +     printf("   Adjusting FDT per EEPROM for %s...\n", model);
>> +
>> +     /* board serial number */
>> +     fdt_setprop(blob, 0, "system-serial", getenv("serial#"),
>> +                 strlen(getenv("serial#") + 1));
>> +
>> +     /* board (model contains model from device-tree) */
>> +     fdt_setprop(blob, 0, "board", info->model,
>> +                 strlen((const char *)info->model) + 1);
>> +
>> +     /*
>> +      * Peripheral Config:
>> +      *  remove nodes by alias path if EEPROM config tells us the
>> +      *  peripheral is not loaded on the board.
>> +      */
>> +     if (!test_bit(EECONFIG_ETH0, info->config))
>> +             fdt_del_node_and_alias(blob, "ethernet0");
>> +     if (!test_bit(EECONFIG_ETH1, info->config))
>> +             fdt_del_node_and_alias(blob, "ethernet1");
>> +     if (!test_bit(EECONFIG_HDMI_OUT, info->config))
>> +             fdt_del_node_and_alias(blob, "hdmi_out");
>> +     if (!test_bit(EECONFIG_SATA, info->config))
>> +             fdt_del_node_and_alias(blob, "ahci0");
>> +     if (!test_bit(EECONFIG_PCIE, info->config))
>> +             fdt_del_node_and_alias(blob, "pcie");
>> +     if (!test_bit(EECONFIG_SSI0, info->config))
>> +             fdt_del_node_and_alias(blob, "ssi0");
>> +     if (!test_bit(EECONFIG_SSI1, info->config))
>> +             fdt_del_node_and_alias(blob, "ssi1");
>> +     if (!test_bit(EECONFIG_LCD, info->config))
>> +             fdt_del_node_and_alias(blob, "lcd0");
>> +     if (!test_bit(EECONFIG_LVDS0, info->config))
>> +             fdt_del_node_and_alias(blob, "lvds0");
>> +     if (!test_bit(EECONFIG_LVDS1, info->config))
>> +             fdt_del_node_and_alias(blob, "lvds1");
>> +     if (!test_bit(EECONFIG_USB0, info->config))
>> +             fdt_del_node_and_alias(blob, "usb0");
>> +     if (!test_bit(EECONFIG_USB1, info->config))
>> +             fdt_del_node_and_alias(blob, "usb1");
>> +     if (!test_bit(EECONFIG_SD0, info->config))
>> +             fdt_del_node_and_alias(blob, "mmc0");
>> +     if (!test_bit(EECONFIG_SD1, info->config))
>> +             fdt_del_node_and_alias(blob, "mmc1");
>> +     if (!test_bit(EECONFIG_SD2, info->config))
>> +             fdt_del_node_and_alias(blob, "mmc2");
>> +     if (!test_bit(EECONFIG_SD3, info->config))
>> +             fdt_del_node_and_alias(blob, "mmc3");
>> +     if (!test_bit(EECONFIG_UART0, info->config))
>> +             fdt_del_node_and_alias(blob, "serial0");
>> +     if (!test_bit(EECONFIG_UART1, info->config))
>> +             fdt_del_node_and_alias(blob, "serial1");
>> +     if (!test_bit(EECONFIG_UART2, info->config))
>> +             fdt_del_node_and_alias(blob, "serial2");
>> +     if (!test_bit(EECONFIG_UART3, info->config))
>> +             fdt_del_node_and_alias(blob, "serial3");
>> +     if (!test_bit(EECONFIG_UART4, info->config))
>> +             fdt_del_node_and_alias(blob, "serial4");
>> +     if (!test_bit(EECONFIG_IPU0, info->config))
>> +             fdt_del_node_and_alias(blob, "ipu0");
>> +     if (!test_bit(EECONFIG_IPU1, info->config))
>> +             fdt_del_node_and_alias(blob, "ipu1");
>> +     if (!test_bit(EECONFIG_FLEXCAN, info->config))
>> +             fdt_del_node_and_alias(blob, "can0");
>> +     if (!test_bit(EECONFIG_MIPI_DSI, info->config))
>> +             fdt_del_node_and_alias(blob, "mipi_dsi");
>> +     if (!test_bit(EECONFIG_MIPI_CSI, info->config))
>> +             fdt_del_node_and_alias(blob, "mipi_csi");
>> +     if (!test_bit(EECONFIG_TZASC0, info->config))
>> +             fdt_del_node_and_alias(blob, "tzasc0");
>> +     if (!test_bit(EECONFIG_TZASC1, info->config))
>> +             fdt_del_node_and_alias(blob, "tzasc1");
>> +     if (!test_bit(EECONFIG_I2C0, info->config))
>> +             fdt_del_node_and_alias(blob, "i2c0");
>> +     if (!test_bit(EECONFIG_I2C1, info->config))
>> +             fdt_del_node_and_alias(blob, "i2c1");
>> +     if (!test_bit(EECONFIG_I2C2, info->config))
>> +             fdt_del_node_and_alias(blob, "i2c2");
>> +     if (!test_bit(EECONFIG_VPU, info->config))
>> +             fdt_del_node_and_alias(blob, "vpu");
>> +     if (!test_bit(EECONFIG_CSI0, info->config))
>> +             fdt_del_node_and_alias(blob, "csi0");
>> +     if (!test_bit(EECONFIG_CSI1, info->config))
>> +             fdt_del_node_and_alias(blob, "csi1");
>> +     if (!test_bit(EECONFIG_CAAM, info->config))
>> +             fdt_del_node_and_alias(blob, "caam");
>> +     if (!test_bit(EECONFIG_ESPCI0, info->config))
>> +             fdt_del_node_and_alias(blob, "spi0");
>> +     if (!test_bit(EECONFIG_ESPCI1, info->config))
>> +             fdt_del_node_and_alias(blob, "spi1");
>> +     if (!test_bit(EECONFIG_ESPCI2, info->config))
>> +             fdt_del_node_and_alias(blob, "spi2");
>> +     if (!test_bit(EECONFIG_ESPCI3, info->config))
>> +             fdt_del_node_and_alias(blob, "spi3");
>> +     if (!test_bit(EECONFIG_ESPCI4, info->config))
>> +             fdt_del_node_and_alias(blob, "spi4");
>> +     if (!test_bit(EECONFIG_ESPCI5, info->config))
>> +             fdt_del_node_and_alias(blob, "spi5");
>> +     if (!test_bit(EECONFIG_HDMI_IN, info->config))
>> +             fdt_del_node_and_alias(blob, "hdmi_in");
>> +     if (!test_bit(EECONFIG_VID_OUT, info->config))
>> +             fdt_del_node_and_alias(blob, "cvbs_out");
>> +     if (!test_bit(EECONFIG_VID_IN, info->config))
>> +             fdt_del_node_and_alias(blob, "cvbs_in");
>> +     if (!test_bit(EECONFIG_NAND, info->config))
>> +             fdt_del_node_and_alias(blob, "nand");
>> +     if (!test_bit(EECONFIG_GPS, info->config))
>> +             fdt_del_node_and_alias(blob, "pps");
>
> I read your post on devicetree ML - I do not see thare is a preferred
> way to do this. Anyway, this code is nasty: it is a big cut&paste.

agreed - there seems to be no preferred method.  The code for removing
node+alias is roughly the same for disabling node vis status=disabled
so I could go either way if needed.

>
> Please use enum for the bit definitions, and use a table to iterate your
> eprom setup. I would see this long list of peripheral config translated
> in a few lines, such as:
>
>         for (bit=first_bit_toiterate; bit < last_bit_to_iterate; bit++)
>         {
>             if(!test_bit(bit,info->config))
>                 fdt_del_node_and_alias(blob, properties[bit]);
>         }

I like this idea but it does assume that there is a one-to-one
relationship between a config bit and a device-tree alias/node.  This
assumption is currently true and if it changes in the future I can add
special cases for those nodes.

I will use your idea for v3

>
<snip>
>> diff --git a/include/configs/gw_ventana.h b/include/configs/gw_ventana.h
>> new file mode 100644
>> index 0000000..05f4771
>> --- /dev/null
>> +++ b/include/configs/gw_ventana.h
>> @@ -0,0 +1,418 @@
>> +/*
>> + * Copyright (C) 2013 Gateworks Corporation
>> + *
>> + * SPDX-License-Identifier: GPL-2.0+
>> + */
>> +
>> +#ifndef __CONFIG_H
>> +#define __CONFIG_H
>> +
>> +#include "mx6_common.h"
>> +#define CONFIG_MX6
>> +#define CONFIG_DISPLAY_CPUINFO         /* display cpu info */
>> +#define CONFIG_DISPLAY_BOARDINFO_LATE  /* display board info (after reloc) */
>> +
>> +#define CONFIG_MACH_TYPE     4520   /* Gateworks Ventana Platform */
>> +
>> +#include <asm/arch/imx-regs.h>
>> +#include <asm/imx-common/gpio.h>
>> +
>> +/* ATAGs */
>> +#define CONFIG_CMDLINE_TAG
>> +#define CONFIG_SETUP_MEMORY_TAGS
>> +#define CONFIG_INITRD_TAG
>> +#define CONFIG_SERIAL_TAG
>> +#define CONFIG_REVISION_TAG
>> +
>> +/* Size of malloc() pool */
>> +#define CONFIG_SYS_MALLOC_LEN                (10 * 1024 * 1024)
>> +
>> +/* Init Functions */
>> +#define CONFIG_BOARD_EARLY_INIT_F
>> +#define CONFIG_MISC_INIT_R
>> +
>> +/* GPIO */
>> +#define CONFIG_MXC_GPIO
>> +
>> +/* Serial */
>> +#define CONFIG_MXC_UART
>> +#define CONFIG_MXC_UART_BASE        UART2_BASE
>> +
>> +#ifdef CONFIG_SPI_FLASH
>> +
>> +/* SPI */
>> +#define CONFIG_CMD_SF
>> +#ifdef CONFIG_CMD_SF
>> +  #define CONFIG_MXC_SPI
>> +  #define CONFIG_SPI_FLASH_MTD
>> +  #define CONFIG_SPI_FLASH_BAR
>> +  #define CONFIG_SPI_FLASH_WINBOND
>> +  #define CONFIG_SPI_FLASH_WINBOND_ERASESIZE 64*1024  /* 4,32,64K for W26Q256 */
>> +  #define CONFIG_SF_DEFAULT_BUS              0
>> +  #define CONFIG_SF_DEFAULT_CS               (0|(IMX_GPIO_NR(3, 19)<<8))
>> +                                          /* GPIO 3-19 (21248) */
>> +  #define CONFIG_SF_DEFAULT_SPEED            30000000
>> +  #define CONFIG_SF_DEFAULT_MODE             (SPI_MODE_0)
>> +#endif
>> +
>> +/* Flattened Image Tree Suport */
>> +#define CONFIG_FIT
>> +#define CONFIG_FIT_VERBOSE
>
> I do not understand what CONFIG_FIT has to do with SPI. Why is it in the
> #ifdef CONFIG_SPI_FLASH case ?

I'll move it outside the #ifdef CONFIG_SPI_FLASH. I suppose there is
just as much value in using FIT for NAND... I just haven't been.

>
>> +
>> +#else
>> +/* Enable NAND support */
>> +#define CONFIG_CMD_TIME
>> +#define CONFIG_CMD_NAND
>> +#define CONFIG_CMD_NAND_TRIMFFS
>> +#ifdef CONFIG_CMD_NAND
>> +  #define CONFIG_NAND_MXS
>> +  #define CONFIG_SYS_MAX_NAND_DEVICE 1
>> +  #define CONFIG_SYS_NAND_BASE               0x40000000
>> +  #define CONFIG_SYS_NAND_5_ADDR_CYCLE
>> +  #define CONFIG_SYS_NAND_ONFI_DETECTION
>> +
>> +  /* DMA stuff, needed for GPMI/MXS NAND support */
>> +  #define CONFIG_APBH_DMA
>> +  #define CONFIG_APBH_DMA_BURST
>> +  #define CONFIG_APBH_DMA_BURST8
>> +#endif
>> +
>> +#endif /* CONFIG_SPI_FLASH */
>> +
>> +/* I2C Configs */
>> +#define CONFIG_CMD_I2C
>> +#define CONFIG_SYS_I2C
>> +#define CONFIG_SYS_I2C_MXC
>> +#define CONFIG_SYS_I2C_SPEED           100000
>> +
>> +/* MMC Configs */
>> +#define CONFIG_FSL_ESDHC
>> +#define CONFIG_FSL_USDHC
>> +#define CONFIG_SYS_FSL_ESDHC_ADDR      0
>> +#define CONFIG_SYS_FSL_USDHC_NUM       1
>> +#define CONFIG_MMC
>> +#define CONFIG_CMD_MMC
>> +#define CONFIG_GENERIC_MMC
>> +#define CONFIG_BOUNCE_BUFFER
>> +
>> +/* Filesystem support */
>> +#define CONFIG_CMD_EXT2
>> +#define CONFIG_CMD_FAT
>> +#define CONFIG_CMD_UBIFS
>> +#define CONFIG_DOS_PARTITION
>> +
>> +/* Network config - Allow larger/faster download for TFTP/NFS */
>> +#define CONFIG_IP_DEFRAG
>> +#define CONFIG_TFTP_BLOCKSIZE 4096
>> +#define CONFIG_NFS_READ_SIZE  4096
>> +
>> +#ifdef CONFIG_MX6Q
>> +#define CONFIG_CMD_SATA
>
> CONFIG_CMD_SATA is not strict bound to the processor type. You are using
> CONFIG_MX6Q for multiple purposes.

IMX6DL doesn't have SATA where as IMX6Q does, but I hope to move to
SPL soon anyway and won't be able to do compile time checking so I'll
remove the ifdef.

>
>> +#endif
>> +
>> +/*
>> + * SATA Configs
>> + */
>> +#ifdef CONFIG_CMD_SATA
>> +  #define CONFIG_DWC_AHSATA
>> +  #define CONFIG_SYS_SATA_MAX_DEVICE 1
>> +  #define CONFIG_DWC_AHSATA_PORT_ID  0
>> +  #define CONFIG_DWC_AHSATA_BASE_ADDR        SATA_ARB_BASE_ADDR
>> +  #define CONFIG_LBA48
>> +  #define CONFIG_LIBATA
>> +#endif
>> +
>> +/*
>> + * PMIC
>> + */
>> +#define CONFIG_POWER
>> +#define CONFIG_POWER_I2C
>> +#define CONFIG_POWER_PFUZE100
>> +#define CONFIG_POWER_PFUZE100_I2C_ADDR       0x08
>> +
>> +/* Various command support */
>> +#include <config_cmd_default.h>
>> +#undef CONFIG_CMD_IMLS
>> +#define CONFIG_CMD_PING
>> +#define CONFIG_CMD_DHCP
>> +#define CONFIG_CMD_MII
>> +#define CONFIG_CMD_NET
>> +#define CONFIG_CMD_BMODE         /* set eFUSE shadow for a boot dev and reset */
>> +#define CONFIG_CMD_HDMIDETECT    /* detect HDMI output device */
>> +#define CONFIG_CMD_SETEXPR
>> +#define CONFIG_CMD_BOOTZ
>> +#define CONFIG_CMD_GSC
>> +#define CONFIG_CMD_UBI
>> +#define CONFIG_RBTREE
>> +#define CONFIG_LZO
>> +#define CONFIG_CMD_FUSE          /* eFUSE read/write support */
>> +#ifdef CONFIG_CMD_FUSE
>> +#define CONFIG_MXC_OCOTP
>> +#endif
>> +
>> +
>> +/* Ethernet support */
>> +#define CONFIG_FEC_MXC
>> +#define CONFIG_MII
>> +#define IMX_FEC_BASE             ENET_BASE_ADDR
>> +#define CONFIG_FEC_XCV_TYPE      RGMII
>> +#define CONFIG_ETHPRIME          "FEC"
>> +#define CONFIG_FEC_MXC_PHYADDR   0
>> +#define CONFIG_PHYLIB
>> +#define CONFIG_ARP_TIMEOUT       200UL
>> +
>> +/* USB Configs */
>> +#define CONFIG_CMD_USB
>> +#define CONFIG_USB_EHCI
>> +#define CONFIG_USB_EHCI_MX6
>> +#define CONFIG_USB_STORAGE
>> +#define CONFIG_USB_HOST_ETHER
>> +#define CONFIG_USB_ETHER_ASIX
>> +#define CONFIG_USB_ETHER_SMSC95XX
>> +#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
>> +#define CONFIG_EHCI_HCD_INIT_AFTER_RESET  /* For OTG port */
>> +#define CONFIG_MXC_USB_PORTSC     (PORT_PTS_UTMI | PORT_PTS_PTW)
>> +#define CONFIG_MXC_USB_FLAGS      0
>> +#define CONFIG_USB_KEYBOARD
>> +#define CONFIG_MV_UDC
>> +#define CONFIG_USBD_HS
>> +#define CONFIG_USB_GADGET_DUALSPEED
>> +#define CONFIG_USB_ETHER
>> +#define CONFIG_USB_ETH_CDC
>> +#define CONFIG_NETCONSOLE
>> +#define CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP
>> +#define CONFIG_USB_HUB_MIN_POWER_ON_DELAY 1200
>> +
>> +/* serial console (ttymxc1,115200) */
>> +#define CONFIG_CONS_INDEX              1
>> +#define CONFIG_BAUDRATE                115200
>> +
>> +/* Miscellaneous configurable options */
>> +#define CONFIG_SYS_LONGHELP
>> +#define CONFIG_SYS_HUSH_PARSER
>> +#define CONFIG_SYS_PROMPT                 "Ventana > "
>> +#define CONFIG_SYS_CBSIZE                 1024
>> +#define CONFIG_AUTO_COMPLETE
>> +#define CONFIG_CMDLINE_EDITING
>> +#define CONFIG_HWCONFIG
>> +
>> +/* Print Buffer Size */
>> +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
>> +#define CONFIG_SYS_MAXARGS              16
>> +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
>> +
>> +/* Memory configuration */
>> +#define CONFIG_SYS_MEMTEST_START       0x10000000
>> +#define CONFIG_SYS_MEMTEST_END              0x10010000
>> +#define CONFIG_SYS_MEMTEST_SCRATCH     0x10800000
>> +#define CONFIG_SYS_TEXT_BASE          0x17800000
>> +#define CONFIG_SYS_LOAD_ADDR           0x12000000
>> +
>> +/* Physical Memory Map */
>> +#define CONFIG_NR_DRAM_BANKS           1
>> +#define PHYS_SDRAM                     MMDC0_ARB_BASE_ADDR
>> +#define CONFIG_SYS_SDRAM_BASE          PHYS_SDRAM
>> +#define CONFIG_SYS_INIT_RAM_ADDR       IRAM_BASE_ADDR
>> +#define CONFIG_SYS_INIT_RAM_SIZE       IRAM_SIZE
>> +
>> +#define CONFIG_SYS_INIT_SP_OFFSET \
>> +     (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
>> +#define CONFIG_SYS_INIT_SP_ADDR \
>> +     (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
>> +
>> +/* FLASH and environment organization */
>> +#define CONFIG_SYS_NO_FLASH  /* no NOR flash */
>> +
>> +/*
>> + * MTD Command for mtdparts
>> + */
>> +#define CONFIG_CMD_MTDPARTS
>> +#define CONFIG_MTD_DEVICE
>> +#define CONFIG_MTD_PARTITIONS
>> +#ifdef CONFIG_SPI_FLASH
>> +#define MTDIDS_DEFAULT    "nor0=nor"
>> +#define MTDPARTS_DEFAULT  \
>> +     "mtdparts=nor:512k(uboot),64k(env),2m(kernel),-(rootfs)"
>> +#else
>> +#define MTDIDS_DEFAULT    "nand0=nand"
>> +#define MTDPARTS_DEFAULT  "mtdparts=nand:16m(uboot),1m(env),-(rootfs)"
>> +#endif
>> +
>> +/* Persistent Environment Config */
>> +#define CONFIG_ENV_OVERWRITE    /* allow to overwrite serial and ethaddr */
>> +#ifdef CONFIG_SPI_FLASH
>> +#define CONFIG_ENV_IS_IN_SPI_FLASH
>> +#else
>> +#define CONFIG_ENV_IS_IN_NAND
>> +#endif
>> +#if defined(CONFIG_ENV_IS_IN_MMC)
>
> Is it a case ? You have CONFIG_ENV_IS_IN_SPI_FLASH or
> CONFIG_ENV_IS_IN_NAND. This seems to me a dead case.

One of the baseboards supported has only SPI flash and the boards.cfg
config for it (gwventanaq1gspi)
defines SPI_FLASH.  All other boards have 'only' NAND flash.

So for the Ventana family it really is a case.  I could repeat the
above in a comment if it helps avoids confusion.

>
>> +  #define CONFIG_ENV_OFFSET              (6 * 64 * 1024)
>> +  #define CONFIG_ENV_SIZE                (8 * 1024)
>> +  #define CONFIG_SYS_MMC_ENV_DEV         0
>> +#elif defined(CONFIG_ENV_IS_IN_NAND)
>> +  #define CONFIG_ENV_OFFSET              (16 << 20)
>> +  #define CONFIG_ENV_SECT_SIZE           (128 << 10)
>> +  #define CONFIG_ENV_SIZE                CONFIG_ENV_SECT_SIZE
>> +  #define CONFIG_ENV_OFFSET_REDUND       (CONFIG_ENV_OFFSET + (512 << 10))
>> +  #define CONFIG_ENV_SIZE_REDUND         CONFIG_ENV_SIZE
>> +#elif defined(CONFIG_ENV_IS_IN_SPI_FLASH)
>> +  #define CONFIG_ENV_OFFSET              (512 * 1024)
>> +  #define CONFIG_ENV_SECT_SIZE           (64 * 1024)
>> +  #define CONFIG_ENV_SIZE                (8 * 1024)
>> +  #define CONFIG_ENV_SPI_BUS             CONFIG_SF_DEFAULT_BUS
>> +  #define CONFIG_ENV_SPI_CS              CONFIG_SF_DEFAULT_CS
>> +  #define CONFIG_ENV_SPI_MODE            CONFIG_SF_DEFAULT_MODE
>> +  #define CONFIG_ENV_SPI_MAX_HZ          CONFIG_SF_DEFAULT_SPEED
>> +#endif
>> +
>> +/* Environment */
>> +#define CONFIG_BOOTDELAY          3
>> +#define CONFIG_LOADADDR           CONFIG_SYS_LOAD_ADDR
>> +#define CONFIG_IPADDR             192.168.1.1
>> +#define CONFIG_SERVERIP           192.168.1.146
>> +#define HWCONFIG_DEFAULT \
>> +     "hwconfig=rs232;" \
>> +     "dio0:mode=gpio;dio1:mode=gpio;dio2:mode=gpio;dio3:mode=gpio\0" \
>> +
>> +#define CONFIG_EXTRA_ENV_SETTINGS_COMMON \
>> +     "console=ttymxc1\0" \
>> +     "bootdevs=usb mmc sata flash\0" \
>> +     HWCONFIG_DEFAULT \
>> +     "video=\0" \
>> +     \
>> +     "mtdparts=" MTDPARTS_DEFAULT "\0" \
>> +     "mtdids=" MTDIDS_DEFAULT "\0" \
>> +     \
>> +     "fdt_high=0xffffffff\0" \
>> +     "fdt_addr=0x18000000\0" \
>> +     "loadfdt=" \
>> +             "if ${fsload} ${fdt_addr} boot/${fdt_file}; then " \
>> +                     "echo Loaded DTB from boot/${fdt_file}; " \
>> +             "elif ${fsload} ${fdt_addr} boot/${fdt_file1}; then " \
>> +                     "echo Loaded DTB from boot/${fdt_file1}; " \
>> +             "elif ${fsload} ${fdt_addr} boot/${fdt_file2}; then " \
>> +                             "echo Loaded DTB from boot/${fdt_file2}; " \
>> +             "fi\0" \
>> +     \
>> +     "script=boot/6x_bootscript-ventana\0" \
>> +     "loadscript=" \
>> +             "if ${fsload} ${loadaddr} ${script}; then " \
>> +                     "source; " \
>> +             "fi\0" \
>> +     \
>> +     "uimage=boot/uImage\0" \
>> +     "mmc_root=/dev/mmcblk0p1 rootfstype=ext4 rootwait rw\0" \
>> +     "mmc_boot=" \
>> +             "setenv fsload 'ext2load mmc 0:1'; " \
>> +             "mmc dev 0 && mmc rescan && " \
>> +             "run loadscript; " \
>> +             "if ${fsload} ${loadaddr} ${uimage}; then " \
>> +                     "setenv bootargs console=${console},${baudrate} " \
>> +                             "root=/dev/mmcblk0p1 rootfstype=ext4 " \
>> +                             "rootwait rw ${video} ${extra}; " \
>> +                     "if run loadfdt && fdt addr ${fdt_addr}; then " \
>> +                             "bootm ${loadaddr} - ${fdt_addr}; " \
>> +                     "else " \
>> +                             "bootm; " \
>> +                     "fi; " \
>> +             "fi\0" \
>> +     \
>> +     "sata_boot=" \
>> +             "setenv fsload 'ext2load sata 0:1'; sata init && " \
>> +             "run loadscript; " \
>> +             "if ${fsload} ${loadaddr} ${uimage}; then " \
>> +                     "setenv bootargs console=${console},${baudrate} " \
>> +                             "root=/dev/sda1 rootfstype=ext4 " \
>> +                             "rootwait rw ${video} ${extra}; " \
>> +                     "if run loadfdt && fdt addr ${fdt_addr}; then " \
>> +                             "bootm ${loadaddr} - ${fdt_addr}; " \
>> +                     "else " \
>> +                             "bootm; " \
>> +                     "fi; " \
>> +             "fi\0" \
>> +     "usb_boot=" \
>> +             "setenv fsload 'ext2load usb 0:1'; usb start && usb dev 0 && " \
>> +             "run loadscript; " \
>> +             "if ${fsload} ${loadaddr} ${uimage}; then " \
>> +                     "setenv bootargs console=${console},${baudrate} " \
>> +                             "root=/dev/sda1 rootfstype=ext4 " \
>> +                             "rootwait rw ${video} ${extra}; " \
>> +                     "if run loadfdt && fdt addr ${fdt_addr}; then " \
>> +                             "bootm ${loadaddr} - ${fdt_addr}; " \
>> +                     "else " \
>> +                             "bootm; " \
>> +                     "fi; " \
>> +             "fi\0"
>> +
>> +#ifdef CONFIG_SPI_FLASH
>> +     #define CONFIG_EXTRA_ENV_SETTINGS \
>> +     CONFIG_EXTRA_ENV_SETTINGS_COMMON \
>> +     "image_os=ventana/openwrt-imx6-imx6q-gw5400-a-squashfs.bin\0" \
>> +     "image_uboot=ventana/u-boot_spi.imx\0" \
>> +     \
>> +     "spi_koffset=0x90000\0" \
>> +     "spi_klen=0x200000\0" \
>> +     \
>> +     "spi_updateuboot=echo Updating uboot from " \
>> +             "${serverip}:${image_uboot}...; " \
>> +             "tftpboot ${loadaddr} ${image_uboot} && " \
>> +             "sf probe && sf erase 0 80000 && " \
>> +                     "sf write ${loadaddr} 400 ${filesize}\0" \
>> +     "spi_update=echo Updating OS from ${serverip}:${image_os} " \
>> +             "to ${spi_koffset} ...; " \
>> +             "tftp ${loadaddr} ${image_os} && " \
>> +             "sf probe && " \
>> +             "sf update ${loadaddr} ${spi_koffset} ${filesize}\0" \
>> +     \
>> +     "flash_boot=" \
>> +             "if sf probe && " \
>> +             "sf read ${loadaddr} ${spi_koffset} ${spi_klen}; then " \
>> +                     "setenv bootargs console=${console},${baudrate} " \
>> +                             "root=/dev/mtdblock3 " \
>> +                             "rootfstype=squashfs,jffs2 " \
>> +                             "${video} ${extra}; " \
>> +                     "bootm; " \
>> +             "fi\0"
>> +#else
>> +     #define CONFIG_EXTRA_ENV_SETTINGS \
>> +     CONFIG_EXTRA_ENV_SETTINGS_COMMON \
>> +     "image_rootfs=openwrt-imx6-ventana-rootfs.ubi\0" \
>> +     \
>> +     "nand_update=echo Updating NAND from ${serverip}:${image_rootfs}...; " \
>> +             "tftp ${loadaddr} ${image_rootfs} && " \
>> +             "nand erase.part rootfs && " \
>> +             "nand write ${loadaddr} rootfs ${filesize}\0" \
>> +     \
>> +     "flash_boot=" \
>> +             "setenv fsload 'ubifsload'; " \
>> +             "ubi part rootfs && ubifsmount ubi0:rootfs; " \
>> +             "run loadscript; " \
>> +             "if ${fsload} ${loadaddr} ${uimage}; then " \
>> +                     "setenv bootargs console=${console},${baudrate} " \
>> +                             "root=ubi0:rootfs ubi.mtd=2 " \
>> +                             "rootfstype=ubifs ${video} ${extra}; " \
>> +                     "if run loadfdt && fdt addr ${fdt_addr}; then " \
>> +                             "ubifsumount; " \
>> +                             "bootm ${loadaddr} - ${fdt_addr}; " \
>> +                     "else " \
>> +                             "ubifsumount; bootm; " \
>> +                     "fi; " \
>> +             "fi\0"
>> +#endif
>> +
>> +#define CONFIG_BOOTCOMMAND \
>> +     "for btype in ${bootdevs}; do " \
>> +             "echo; echo Attempting ${btype} boot...; " \
>> +             "if run ${btype}_boot; then; fi; " \
>> +     "done"
>> +
>> +/* Device Tree Support */
>> +#define CONFIG_OF_BOARD_SETUP
>> +#define CONFIG_OF_LIBFDT
>> +#define CONFIG_FDT_FIXUP_PARTITIONS
>> +
>> +#ifndef CONFIG_SYS_DCACHE_OFF
>> +  #define CONFIG_CMD_CACHE
>> +#endif
>> +
>> +#endif                              /* __CONFIG_H */
>>
>

Thanks for the review and the great ideas for simplification.   I'll
start working on a v3.

Tim

>
> Best regards,
> Stefano Babic
>
> --
> =====================================================================
> DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
> HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
> Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic@denx.de
> =====================================================================
diff mbox

Patch

diff --git a/board/gateworks/gw_ventana/Makefile b/board/gateworks/gw_ventana/Makefile
new file mode 100644
index 0000000..e8dab89
--- /dev/null
+++ b/board/gateworks/gw_ventana/Makefile
@@ -0,0 +1,10 @@ 
+#
+# Copyright (C) 2012-2013, Guennadi Liakhovetski <lg@denx.de>
+# (C) Copyright 2012-2013 Freescale Semiconductor, Inc.
+# Copyright (C) 2013, Gateworks Corporation
+#
+# SPDX-License-Identifier:  GPL-2.0+
+#
+
+obj-y  := gw_ventana.o gsc.o
+
diff --git a/board/gateworks/gw_ventana/README b/board/gateworks/gw_ventana/README
new file mode 100644
index 0000000..f744a4a
--- /dev/null
+++ b/board/gateworks/gw_ventana/README
@@ -0,0 +1,56 @@ 
+U-Boot for the Gateworks Ventana Product Family boards
+
+This file contains information for the port of U-Boot to the Gateworks
+Ventana Product family boards.
+
+1. Boot source, boot from NAND
+------------------------------
+
+The i.MX6 BOOT ROM expects some structures that provide details of NAND layout
+and bad block information (referred to as 'bootstreams') which are replicated
+multiple times in NAND. The number of replications is configurable through
+board strapping options and eFUSE settings.  The Freescale 'kobs-ng'
+application from the Freescale LTIB BSP, which runs under Linux, must be used
+to program the bootstream in order to setup the replicated headers correctly.
+
+The Gateworks Ventana boards with NAND flash have been factory programmed
+such that their eFUSE settings expect 2 copies of the boostream (this is
+specified by providing kobs-ng with the --search_exponent=1 argument). Once in
+Linux with MTD support for the NAND on /dev/mtd0 you can program the boostream
+with:
+
+kobs-ng init -v -x --search_exponent=1 u-boot.imx
+
+The kobs-ng application users an imximage (u-boot.imx) which contains the
+Image Vector Table (IVT) and Device Configuration Data (DCD) structures that
+the i.MX6 BOOT ROM requires to boot.  The kobs-ng adds the Firmware
+Configuration Block (FCB) and Discovered Bad Block Table (DBBT).
+
+This information is taken from:
+  http://trac.gateworks.com/wiki/ventana/bootloader#NANDFLASH
+
+More details about the i.MX6 BOOT ROM can be found at:
+  http://cache.freescale.com/files/32bit/doc/ref_manual/IMX6DQRM.pdf
+
+2. Build
+--------
+
+There are several Gateworks Ventana boards that share a simliar design but
+vary based on CPU, Memory configuration, and subloaded devices.  Although
+the subloaded devices are handled dynamically in the bootloader using
+factory configured EEPROM data to modify the device-tree, the CPU choice
+(IMX6Q vs IMX6DL) and memory configurations are currently compile-time
+options.
+
+The following Gateworks Ventana configurations exist:
+ gwventanaq1gspi: MX6Q,1GB,SPI FLASH
+ gwventanaq     : MX6Q,512MB,NAND FLASH
+ gwventanaq1g   : MX6Q,1GB,NAND FLASH
+ gwventanadl    : MX6DL,512MB,NAND FLASH
+ gwventanadl1g  : MX6DL,1GB,NAND FLASH
+
+To build U-Boot for the MX6Q,1GB,NAND FLASH for example:
+
+ make gwventanaq1g_config
+ make
+
diff --git a/board/gateworks/gw_ventana/clocks.cfg b/board/gateworks/gw_ventana/clocks.cfg
new file mode 100644
index 0000000..a8118a2
--- /dev/null
+++ b/board/gateworks/gw_ventana/clocks.cfg
@@ -0,0 +1,42 @@ 
+/*
+ * Copyright (C) 2013 Boundary Devices
+ * Copyright (C) 2013 Gateworks Corporation
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Device Configuration Data (DCD)
+ *
+ * Each entry must have the format:
+ * Addr-type           Address        Value
+ *
+ * where:
+ *      Addr-type register length (1,2 or 4 bytes)
+ *      Address   absolute address of the register
+ *      value     value to be stored in the register
+ */
+
+/* set the default clock gate to save power */
+DATA 4, CCM_CCGR0, 0x00C03F3F
+DATA 4, CCM_CCGR1, 0x0030FC03
+DATA 4, CCM_CCGR2, 0x0FFFC000
+DATA 4, CCM_CCGR3, 0x3FF00000
+DATA 4, CCM_CCGR4, 0xFFFFF300 /* enable NAND/GPMI/BCH clocks */
+DATA 4, CCM_CCGR5, 0x0F0000C3
+DATA 4, CCM_CCGR6, 0x000003FF
+
+/* enable AXI cache for VDOA/VPU/IPU */
+DATA 4, MX6_IOMUXC_GPR4, 0xF00000CF
+/* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
+DATA 4, MX6_IOMUXC_GPR6, 0x007F007F
+DATA 4, MX6_IOMUXC_GPR7, 0x007F007F
+
+/*
+ * Setup CCM_CCOSR register as follows:
+ *
+ * cko1_en  = 1    --> CKO1 enabled
+ * cko1_div = 111  --> divide by 8
+ * cko1_sel = 1011 --> ahb_clk_root
+ *
+ * This sets CKO1 at ahb_clk_root/8 = 132/8 = 16.5 MHz
+ */
+DATA 4, CCM_CCOSR, 0x000000fb
diff --git a/board/gateworks/gw_ventana/gsc.c b/board/gateworks/gw_ventana/gsc.c
new file mode 100644
index 0000000..72eec38
--- /dev/null
+++ b/board/gateworks/gw_ventana/gsc.c
@@ -0,0 +1,129 @@ 
+/*
+ * Copyright (C) 2013 Gateworks Corporation
+ *
+ * Author: Tim Harvey <tharvey@gateworks.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <asm/errno.h>
+#include <common.h>
+#include <i2c.h>
+#include <linux/ctype.h>
+
+/*
+ * 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.
+ * When this does occur, it will never be busy long enough to fail more than
+ * 2 back-to-back transfers.  Thus we wrap i2c_read and i2c_write with
+ * 3 retries.
+ */
+int gsc_i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
+{
+	int retry = 3;
+	int n = 0;
+	int ret;
+
+	while (n++ < retry) {
+		ret = i2c_read(chip, addr, alen, buf, len);
+		if (!ret)
+			break;
+		printf("%s: 0x%02x 0x%02x retry%d: %d\n", __func__, chip, addr,
+		       n, ret);
+		if (ret != -ENODEV)
+			break;
+		mdelay(10);
+	}
+	return ret;
+}
+
+int gsc_i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
+{
+	int retry = 3;
+	int n = 0;
+	int ret;
+
+	while (n++ < retry) {
+		ret = i2c_write(chip, addr, alen, buf, len);
+		if (!ret)
+			break;
+		printf("%s: 0x%02x 0x%02x retry%d: %d\n", __func__, chip, addr,
+		       n, ret);
+		if (ret != -ENODEV)
+			break;
+		mdelay(10);
+	}
+	mdelay(1);
+	return ret;
+}
+
+#ifdef CONFIG_CMD_GSC
+static void read_hwmon(const char *name, uint reg, uint size, uint low,
+		       uint high)
+{
+	unsigned char buf[3];
+	uint ui;
+
+	printf("%-8s:", name);
+	memset(buf, 0, sizeof(buf));
+	if (gsc_i2c_read(0x29, reg, 1, buf, size)) {
+		puts("fRD\n");
+	} else {
+		ui = buf[0] | (buf[1]<<8) | (buf[2]<<16);
+		if (ui == 0xffffff)
+			printf("fVL");
+		else if (ui < low)
+			printf("%d fLO", ui);
+		else if (ui > high)
+			printf("%d fHI", ui);
+		else
+			printf("%d", ui);
+	}
+	puts("\n");
+}
+
+int do_gsc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	const char *model = getenv("model");
+
+	i2c_set_bus_num(0);
+	read_hwmon("Temp",     0x00, 2, 0, 9000);
+	read_hwmon("VIN",      0x02, 3, 8000, 60000);
+	read_hwmon("VDD_3P3",  0x05, 3, 3300*0.9, 3300*1.1);
+	read_hwmon("VBATT",    0x08, 3, 2000*0.9, 3000*1.1);
+	read_hwmon("VDD_HIGH", 0x14, 3, 3000*0.9, 3000*1.1);
+	read_hwmon("VDD_DDR",  0x17, 3, 1500*0.9, 1500*1.1);
+	read_hwmon("VDD_5P0",  0x0b, 3, 5000*0.9, 5000*1.1);
+	read_hwmon("VDD_2P5",  0x23, 3, 2500*0.9, 2500*1.1);
+	read_hwmon("VDD_1P8",  0x1d, 3, 1800*0.9, 1800*1.1);
+
+	switch (model[3]) {
+	case '1': /* GW51xx */
+		read_hwmon("VDD_CORE", 0x0e, 3, 1175*0.9, 1175*1.1);
+		read_hwmon("VDD_SOC",  0x11, 3, 1175*0.9, 1175*1.1);
+		break;
+	case '2': /* GW52xx */
+		read_hwmon("VDD_CORE", 0x0e, 3, 1175*0.9, 1175*1.1);
+		read_hwmon("VDD_SOC",  0x11, 3, 1175*0.9, 1175*1.1);
+		read_hwmon("VDD_1P0",  0x20, 3, 1000*0.9, 1000*1.1);
+		break;
+	case '3': /* GW53xx */
+		read_hwmon("VDD_CORE", 0x0e, 3, 1175*0.9, 1175*1.1);
+		read_hwmon("VDD_SOC",  0x11, 3, 1175*0.9, 1175*1.1);
+		read_hwmon("VDD_1P0",  0x20, 3, 1000*0.9, 1000*1.1);
+		break;
+	case '4': /* GW54xx */
+		read_hwmon("VDD_CORE", 0x0e, 3, 1375*0.9, 1375*1.1);
+		read_hwmon("VDD_SOC",  0x11, 3, 1375*0.9, 1375*1.1);
+		read_hwmon("VDD_1P0",  0x20, 3, 1000*0.9, 1000*1.1);
+		break;
+	}
+	return 0;
+}
+
+U_BOOT_CMD(gsc, 1, 1, do_gsc,
+	   "GSC test",
+	   ""
+);
+
+#endif /* CONFIG_CMD_GSC */
diff --git a/board/gateworks/gw_ventana/gsc.h b/board/gateworks/gw_ventana/gsc.h
new file mode 100644
index 0000000..6b9cb98
--- /dev/null
+++ b/board/gateworks/gw_ventana/gsc.h
@@ -0,0 +1,9 @@ 
+#ifndef __ASSEMBLY__
+/*
+ * I2C transactions to the GSC are done via these functions which
+ * perform retries in the case of a busy GSC NAK'ing the transaction
+ */
+extern int gsc_i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len);
+extern int gsc_i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len);
+#endif
+
diff --git a/board/gateworks/gw_ventana/gw_ventana.c b/board/gateworks/gw_ventana/gw_ventana.c
new file mode 100644
index 0000000..d8c9989
--- /dev/null
+++ b/board/gateworks/gw_ventana/gw_ventana.c
@@ -0,0 +1,1200 @@ 
+/*
+ * Copyright (C) 2013 Gateworks Corporation
+ *
+ * Author: Tim Harvey <tharvey@gateworks.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/iomux.h>
+#include <asm/arch/mx6-pins.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/gpio.h>
+#include <asm/imx-common/iomux-v3.h>
+#include <asm/imx-common/mxc_i2c.h>
+#include <asm/imx-common/boot_mode.h>
+#include <asm/imx-common/sata.h>
+#include <jffs2/load_kernel.h>
+#include <hwconfig.h>
+#include <i2c.h>
+#include <linux/ctype.h>
+#include <fdt_support.h>
+#include <fsl_esdhc.h>
+#include <miiphy.h>
+#include <mmc.h>
+#include <mtd_node.h>
+#include <netdev.h>
+#include <power/pmic.h>
+#include <power/pfuze100_pmic.h>
+#include <i2c.h>
+#include <fdt_support.h>
+#include <jffs2/load_kernel.h>
+#include <spi_flash.h>
+
+#include "gsc.h"
+#include "ventana_eeprom.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* GPIO's common to all baseboards */
+#define GP_PHY_RST	IMX_GPIO_NR(1, 30)
+#define GP_USB_OTG_PWR	IMX_GPIO_NR(3, 22)
+#define GP_SD3_CD	IMX_GPIO_NR(7, 0)
+#define GP_RS232_EN	IMX_GPIO_NR(2, 11)
+#define GP_MSATA_SEL	IMX_GPIO_NR(2, 8)
+
+#define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |		\
+	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |		\
+	PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |		\
+	PAD_CTL_PUS_47K_UP  | PAD_CTL_SPEED_LOW |		\
+	PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
+
+#define ENET_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |		\
+	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED	  |		\
+	PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
+
+#define SPI_PAD_CTRL (PAD_CTL_HYS |				\
+	PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED |		\
+	PAD_CTL_DSE_40ohm     | PAD_CTL_SRE_FAST)
+
+#define DIO_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |		\
+	PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |		\
+	PAD_CTL_DSE_34ohm | PAD_CTL_HYS | PAD_CTL_SRE_FAST)
+
+#define I2C_PAD_CTRL  (PAD_CTL_PUS_100K_UP |			\
+	PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS |	\
+	PAD_CTL_ODE | PAD_CTL_SRE_FAST)
+
+/*
+ * EEPROM board info struct populated by read_eeprom so that we only have to
+ * read it once.
+ */
+static struct ventana_board_info ventana_info;
+
+/* UART1: Function varies per baseboard */
+iomux_v3_cfg_t const uart1_pads[] = {
+	MX6_PAD_SD3_DAT6__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
+	MX6_PAD_SD3_DAT7__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
+};
+
+/* UART2: Serial Console */
+iomux_v3_cfg_t const uart2_pads[] = {
+	MX6_PAD_SD4_DAT7__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
+	MX6_PAD_SD4_DAT4__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
+};
+
+#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
+
+/* I2C1: GSC */
+struct i2c_pads_info i2c_pad_info0 = {
+	.scl = {
+		.i2c_mode = MX6_PAD_EIM_D21__I2C1_SCL | PC,
+		.gpio_mode = MX6_PAD_EIM_D21__GPIO3_IO21 | PC,
+		.gp = IMX_GPIO_NR(3, 21)
+	},
+	.sda = {
+		.i2c_mode = MX6_PAD_EIM_D28__I2C1_SDA | PC,
+		.gpio_mode = MX6_PAD_EIM_D28__GPIO3_IO28 | PC,
+		.gp = IMX_GPIO_NR(3, 28)
+	}
+};
+
+/* I2C2: PMIC/PCIe Switch/PCIe Clock/Mezz */
+struct i2c_pads_info i2c_pad_info1 = {
+	.scl = {
+		.i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | PC,
+		.gpio_mode = MX6_PAD_KEY_COL3__GPIO4_IO12 | PC,
+		.gp = IMX_GPIO_NR(4, 12)
+	},
+	.sda = {
+		.i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | PC,
+		.gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | PC,
+		.gp = IMX_GPIO_NR(4, 13)
+	}
+};
+
+/* I2C3: Misc/Expansion */
+struct i2c_pads_info i2c_pad_info2 = {
+	.scl = {
+		.i2c_mode = MX6_PAD_GPIO_3__I2C3_SCL | PC,
+		.gpio_mode = MX6_PAD_GPIO_3__GPIO1_IO03 | PC,
+		.gp = IMX_GPIO_NR(1, 3)
+	},
+	.sda = {
+		.i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA | PC,
+		.gpio_mode = MX6_PAD_GPIO_6__GPIO1_IO06 | PC,
+		.gp = IMX_GPIO_NR(1, 6)
+	}
+};
+
+/* MMC */
+iomux_v3_cfg_t const usdhc3_pads[] = {
+	MX6_PAD_SD3_CLK__SD3_CLK    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD3_CMD__SD3_CMD    | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+	MX6_PAD_SD3_DAT5__GPIO7_IO00  | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+};
+
+/* ENET */
+iomux_v3_cfg_t const enet_pads[] = {
+	MX6_PAD_ENET_MDIO__ENET_MDIO		| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_ENET_MDC__ENET_MDC		| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_TXC__RGMII_TXC		| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_TD0__RGMII_TD0		| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_TD1__RGMII_TD1		| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_TD2__RGMII_TD2		| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_TD3__RGMII_TD3		| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_ENET_REF_CLK__ENET_TX_CLK	| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_RXC__RGMII_RXC		| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_RD0__RGMII_RD0		| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_RD1__RGMII_RD1		| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_RD2__RGMII_RD2		| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_RD3__RGMII_RD3		| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL	| MUX_PAD_CTRL(ENET_PAD_CTRL),
+	/* PHY nRST */
+	MX6_PAD_ENET_TXD0__GPIO1_IO30		| MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+/* NAND */
+iomux_v3_cfg_t const nfc_pads[] = {
+	MX6_PAD_NANDF_CLE__NAND_CLE     | MUX_PAD_CTRL(NO_PAD_CTRL),
+	MX6_PAD_NANDF_ALE__NAND_ALE     | MUX_PAD_CTRL(NO_PAD_CTRL),
+	MX6_PAD_NANDF_WP_B__NAND_WP_B   | MUX_PAD_CTRL(NO_PAD_CTRL),
+	MX6_PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL),
+	MX6_PAD_NANDF_CS0__NAND_CE0_B   | MUX_PAD_CTRL(NO_PAD_CTRL),
+	MX6_PAD_SD4_CMD__NAND_RE_B      | MUX_PAD_CTRL(NO_PAD_CTRL),
+	MX6_PAD_SD4_CLK__NAND_WE_B      | MUX_PAD_CTRL(NO_PAD_CTRL),
+	MX6_PAD_NANDF_D0__NAND_DATA00   | MUX_PAD_CTRL(NO_PAD_CTRL),
+	MX6_PAD_NANDF_D1__NAND_DATA01   | MUX_PAD_CTRL(NO_PAD_CTRL),
+	MX6_PAD_NANDF_D2__NAND_DATA02   | MUX_PAD_CTRL(NO_PAD_CTRL),
+	MX6_PAD_NANDF_D3__NAND_DATA03   | MUX_PAD_CTRL(NO_PAD_CTRL),
+	MX6_PAD_NANDF_D4__NAND_DATA04   | MUX_PAD_CTRL(NO_PAD_CTRL),
+	MX6_PAD_NANDF_D5__NAND_DATA05   | MUX_PAD_CTRL(NO_PAD_CTRL),
+	MX6_PAD_NANDF_D6__NAND_DATA06   | MUX_PAD_CTRL(NO_PAD_CTRL),
+	MX6_PAD_NANDF_D7__NAND_DATA07   | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+#ifdef CONFIG_CMD_NAND
+static void setup_gpmi_nand(void)
+{
+	struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+
+	/* config gpmi nand iomux */
+	imx_iomux_v3_setup_multiple_pads(nfc_pads, ARRAY_SIZE(nfc_pads));
+
+	/* config gpmi and bch clock to 100 MHz */
+	clrsetbits_le32(&mxc_ccm->cs2cdr,
+			MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
+			MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
+			MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
+			MXC_CCM_CS2CDR_ENFC_CLK_PODF(0) |
+			MXC_CCM_CS2CDR_ENFC_CLK_PRED(3) |
+			MXC_CCM_CS2CDR_ENFC_CLK_SEL(3));
+
+	/* enable gpmi and bch clock gating */
+	setbits_le32(&mxc_ccm->CCGR4,
+		     MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
+		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
+		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
+		     MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
+		     MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_OFFSET);
+
+	/* enable apbh clock gating */
+	setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
+}
+#endif
+
+static void setup_iomux_enet(void)
+{
+	imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
+
+	/* toggle PHY_RST# */
+	gpio_direction_output(GP_PHY_RST, 0);
+	mdelay(2);
+	gpio_set_value(GP_PHY_RST, 1);
+}
+
+static void setup_iomux_uart(void)
+{
+	imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
+	imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
+}
+
+#ifdef CONFIG_USB_EHCI_MX6
+iomux_v3_cfg_t const usb_pads[] = {
+	MX6_PAD_GPIO_1__USB_OTG_ID   | MUX_PAD_CTRL(DIO_PAD_CTRL),
+	MX6_PAD_KEY_COL4__USB_OTG_OC | MUX_PAD_CTRL(DIO_PAD_CTRL),
+	MX6_PAD_EIM_D22__GPIO3_IO22  | MUX_PAD_CTRL(DIO_PAD_CTRL), /* OTG PWR */
+};
+
+int board_ehci_hcd_init(int port)
+{
+	struct ventana_board_info *info = &ventana_info;
+
+	imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads));
+
+	/* Reset USB HUB (present on GW54xx/GW53xx) */
+	switch (info->model[3]) {
+	case '3': /* GW53xx */
+		imx_iomux_v3_setup_pad(MX6_PAD_GPIO_9__GPIO1_IO09|
+				       MUX_PAD_CTRL(NO_PAD_CTRL));
+		gpio_direction_output(IMX_GPIO_NR(1, 9), 0);
+		mdelay(2);
+		gpio_set_value(IMX_GPIO_NR(1, 9), 1);
+		break;
+	case '4': /* GW54xx */
+		imx_iomux_v3_setup_pad(MX6_PAD_SD1_DAT0__GPIO1_IO16 |
+				       MUX_PAD_CTRL(NO_PAD_CTRL));
+		gpio_direction_output(IMX_GPIO_NR(1, 16), 0);
+		mdelay(2);
+		gpio_set_value(IMX_GPIO_NR(1, 16), 1);
+		break;
+	}
+
+	return 0;
+}
+
+int board_ehci_power(int port, int on)
+{
+	if (port)
+		return 0;
+	gpio_set_value(GP_USB_OTG_PWR, on);
+	return 0;
+}
+#endif /* CONFIG_USB_EHCI_MX6 */
+
+#ifdef CONFIG_FSL_ESDHC
+struct fsl_esdhc_cfg usdhc_cfg = { USDHC3_BASE_ADDR };
+
+int board_mmc_getcd(struct mmc *mmc)
+{
+	/* Card Detect */
+	gpio_direction_input(GP_SD3_CD);
+	return !gpio_get_value(GP_SD3_CD);
+}
+
+int board_mmc_init(bd_t *bis)
+{
+	/* Only one USDHC controller on Ventana */
+	imx_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
+	usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+	usdhc_cfg.max_bus_width = 4;
+
+	return fsl_esdhc_initialize(bis, &usdhc_cfg);
+}
+#endif /* CONFIG_FSL_ESDHC */
+
+#ifdef CONFIG_MXC_SPI
+iomux_v3_cfg_t const ecspi1_pads[] = {
+	/* SS1 */
+	MX6_PAD_EIM_D19__GPIO3_IO19  | MUX_PAD_CTRL(SPI_PAD_CTRL),
+	MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
+	MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
+	MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
+};
+
+static void setup_spi(void)
+{
+	gpio_direction_output(CONFIG_SF_DEFAULT_CS, 1);
+	imx_iomux_v3_setup_multiple_pads(ecspi1_pads,
+					 ARRAY_SIZE(ecspi1_pads));
+}
+#endif
+
+/* configure eth0 PHY board-specific LED behavior */
+int board_phy_config(struct phy_device *phydev)
+{
+	unsigned short val;
+
+	/* Marvel 88E1510 */
+	if (phydev->phy_id == 0x1410dd1) {
+		/*
+		 * Page 3, Register 16: LED[2:0] Function Control Register
+		 * LED[0] (SPD:Amber) R16_3.3:0 to 0111: on-GbE link
+		 * LED[1] (LNK:Green) R16_3.7:4 to 0001: on-link, blink-activity
+		 */
+		phy_write(phydev, MDIO_DEVAD_NONE, 22, 3);
+		val = phy_read(phydev, MDIO_DEVAD_NONE, 16);
+		val &= 0xff00;
+		val |= 0x0017;
+		phy_write(phydev, MDIO_DEVAD_NONE, 16, val);
+		phy_write(phydev, MDIO_DEVAD_NONE, 22, 0);
+	}
+
+	if (phydev->drv->config)
+		phydev->drv->config(phydev);
+
+	return 0;
+}
+
+int board_eth_init(bd_t *bis)
+{
+	setup_iomux_enet();
+
+#ifdef CONFIG_FEC_MXC
+	cpu_eth_init(bis);
+#endif
+
+#ifdef CONFIG_MV_UDC
+	/* For otg ethernet*/
+	usb_eth_initialize(bis);
+#endif
+
+	return 0;
+}
+
+/*
+ * read ventana EEPROM and return structure or NULL on error
+ * should be called once, the first time eeprom data is needed
+ */
+static void
+read_eeprom(void)
+{
+	int i;
+	int chksum;
+	struct ventana_board_info *info = &ventana_info;
+	unsigned char *buf = (unsigned char *)&ventana_info;
+
+	memset(info, 0, sizeof(ventana_info));
+
+	/*
+	 * On a board with a missing/depleted backup battery for GSC, the
+	 * board may be ready to probe the GSC before its firmware is
+	 * running.  We will wait here indefinately for the GSC/EEPROM.
+	 */
+	while (1) {
+		if (0 == i2c_set_bus_num(0) && 0 == i2c_probe(0x51))
+			break;
+		mdelay(1);
+	}
+
+	/* read eeprom config section */
+	if (gsc_i2c_read(0x51, 0x00, 1, buf, sizeof(ventana_info))) {
+		puts("EEPROM: Failed to read EEPROM\n");
+		info->model[0] = 0;
+		return;
+	}
+
+	/* sanity checks */
+	if (info->model[0] != 'G' || info->model[1] != 'W') {
+		puts("EEPROM: Invalid Model in EEPROM\n");
+		info->model[0] = 0;
+		return;
+	}
+
+	/* validate checksum */
+	for (chksum = 0, i = 0; i < sizeof(*info)-2; i++)
+		chksum += buf[i];
+	if ((info->chksum[0] != chksum>>8) ||
+	    (info->chksum[1] != (chksum&0xff))) {
+		puts("EEPROM: Failed EEPROM checksum\n");
+		info->model[0] = 0;
+		return;
+	}
+}
+
+/*
+ * Baseboard specific GPIO
+ */
+
+/* common to add baseboards */
+static iomux_v3_cfg_t const gw_gpio_pads[] = {
+	/* MSATA_EN */
+	MX6_PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* RS232_EN# */
+	MX6_PAD_SD4_DAT3__GPIO2_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+/* prototype */
+static iomux_v3_cfg_t const gwproto_gpio_pads[] = {
+	/* PANLEDG# */
+	MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* PANLEDR# */
+	MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* LOCLED# */
+	MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* RS485_EN */
+	MX6_PAD_SD3_DAT4__GPIO7_IO01 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* IOEXP_PWREN# */
+	MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* IOEXP_IRQ# */
+	MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* VID_EN */
+	MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* DIOI2C_DIS# */
+	MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* PCICK_SSON */
+	MX6_PAD_SD1_CLK__GPIO1_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* PCI_RST# */
+	MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const gw51xx_gpio_pads[] = {
+	/* PANLEDG# */
+	MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* PANLEDR# */
+	MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* IOEXP_PWREN# */
+	MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* IOEXP_IRQ# */
+	MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
+
+	/* GPS_SHDN */
+	MX6_PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* VID_PWR */
+	MX6_PAD_CSI0_DATA_EN__GPIO5_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* PCI_RST# */
+	MX6_PAD_GPIO_0__GPIO1_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const gw52xx_gpio_pads[] = {
+	/* PANLEDG# */
+	MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* PANLEDR# */
+	MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* IOEXP_PWREN# */
+	MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* IOEXP_IRQ# */
+	MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
+
+	/* MX6_LOCLED# */
+	MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* GPS_SHDN */
+	MX6_PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* USBOTG_SEL */
+	MX6_PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* VID_PWR */
+	MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* PCI_RST# */
+	MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const gw53xx_gpio_pads[] = {
+	/* PANLEDG# */
+	MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* PANLEDR# */
+	MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* IOEXP_PWREN# */
+	MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* IOEXP_IRQ# */
+	MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
+
+	/* MX6_LOCLED# */
+	MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* GPS_SHDN */
+	MX6_PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* VID_EN */
+	MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* PCI_RST# */
+	MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const gw54xx_gpio_pads[] = {
+	/* PANLEDG# */
+	MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* PANLEDR# */
+	MX6_PAD_KEY_COL2__GPIO4_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* MX6_LOCLED# */
+	MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* MIPI_DIO */
+	MX6_PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* RS485_EN */
+	MX6_PAD_EIM_D24__GPIO3_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* IOEXP_PWREN# */
+	MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* IOEXP_IRQ# */
+	MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* DIOI2C_DIS# */
+	MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* DIOI2C_DIS# */
+	MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* PCICK_SSON */
+	MX6_PAD_SD1_CLK__GPIO1_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
+	/* PCI_RST# */
+	MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+/* setup GPIO pinmux and default configuration per baseboard */
+static void setup_board_gpio(void)
+{
+	struct ventana_board_info *info = &ventana_info;
+	const char *s;
+	char arg[10];
+	size_t len;
+	int i;
+	char baseboard = info->model[3];
+	enum {
+		GW51xx,
+		GW52xx,
+		GW53xx,
+		GW54xx,
+		GW54proto, /* original GW5400-A prototype */
+		UNKNOWN,
+	};
+	struct dio_cfg {
+		iomux_v3_cfg_t gpio_padmux;
+		unsigned gpio_param;
+		iomux_v3_cfg_t pwm_padmux;
+		unsigned pwm_param;
+	};
+	int board_type = UNKNOWN;
+	int quiet = simple_strtol(getenv("quiet"), NULL, 10);
+	struct dio_cfg dio_cfg[] = {
+		/* GW51xx */
+		{ MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16),
+			0, 0 },
+		{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
+			MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
+		{ MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17),
+			MX6_PAD_SD1_DAT1__PWM3_OUT, 3 },
+		{ MX6_PAD_SD1_CMD__GPIO1_IO18, IMX_GPIO_NR(1, 18),
+			MX6_PAD_SD1_CMD__PWM4_OUT, 4 },
+
+		/* GW52xx */
+		{ MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16),
+			0, 0 },
+		{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
+			MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
+		{ MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17),
+			MX6_PAD_SD1_DAT1__PWM3_OUT, 3 },
+		{ MX6_PAD_SD1_CLK__GPIO1_IO20, IMX_GPIO_NR(1, 20),
+			0, 0 },
+
+		/* GW53xx */
+		{ MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16),
+			0, 0 },
+		{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
+			MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
+		{ MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17),
+			MX6_PAD_SD1_DAT1__PWM3_OUT, 3 },
+		{ MX6_PAD_SD1_CLK__GPIO1_IO20, IMX_GPIO_NR(1, 20),
+			0, 0 },
+
+		/* GW54xx */
+		{ MX6_PAD_GPIO_9__GPIO1_IO09, IMX_GPIO_NR(1, 9),
+			MX6_PAD_GPIO_9__PWM1_OUT, 1 },
+		{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
+			MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
+		{ MX6_PAD_SD4_DAT1__GPIO2_IO09, IMX_GPIO_NR(2, 9),
+			MX6_PAD_SD4_DAT1__PWM3_OUT, 3 },
+		{ MX6_PAD_SD4_DAT2__GPIO2_IO10, IMX_GPIO_NR(2, 10),
+			MX6_PAD_SD4_DAT2__PWM4_OUT, 4 },
+
+		/* GW54proto */
+		{ MX6_PAD_GPIO_9__GPIO1_IO09, IMX_GPIO_NR(1, 9),
+			MX6_PAD_GPIO_9__PWM1_OUT, 1 },
+		{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
+			MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
+		{ MX6_PAD_SD4_DAT1__GPIO2_IO09, IMX_GPIO_NR(2, 9),
+			MX6_PAD_SD4_DAT1__PWM3_OUT, 3 },
+		{ MX6_PAD_SD4_DAT2__GPIO2_IO10, IMX_GPIO_NR(2, 10),
+			MX6_PAD_SD4_DAT2__PWM4_OUT, 4 },
+	};
+
+	/* Common GPIO configuration */
+	imx_iomux_v3_setup_multiple_pads(gw_gpio_pads,
+					 ARRAY_SIZE(gw_gpio_pads));
+	/* RS232_EN# */
+	gpio_direction_output(GP_RS232_EN, (hwconfig("rs232")) ? 0 : 1);
+
+	/* MSATA Enable */
+	if (is_cpu_type(MXC_CPU_MX6Q) &&
+	    test_bit(EECONFIG_SATA, info->config)) {
+		gpio_direction_output(GP_MSATA_SEL,
+				      (hwconfig("msata")) ?  1 : 0);
+	} else {
+		gpio_direction_output(GP_MSATA_SEL, 0);
+	}
+
+	/* original GW5400-A prototype */
+	if (strncasecmp((const char *)info->model, "GW5400-A", 8) == 0)
+		baseboard = '0';
+
+	switch (baseboard) {
+	case '0': /* original GW5400-A prototype */
+		board_type = GW54proto;
+		imx_iomux_v3_setup_multiple_pads(gwproto_gpio_pads,
+						 ARRAY_SIZE(gwproto_gpio_pads));
+		/* PANLEDG# (GRN off) */
+		gpio_direction_output(IMX_GPIO_NR(4, 6), 1);
+		/* PANLEDR# (RED off) */
+		gpio_direction_output(IMX_GPIO_NR(4, 10), 1);
+		/* MX6_LOCLED# (off) */
+		gpio_direction_output(IMX_GPIO_NR(4, 15), 1);
+		/* RS485 Transmit Enable */
+		gpio_direction_output(IMX_GPIO_NR(3, 24), 0);
+		/* Expansion IO0 - PWREN# */
+		gpio_direction_output(IMX_GPIO_NR(4, 7), 0);
+		/* Expansion IO1 - IRQ# */
+		gpio_direction_input(IMX_GPIO_NR(4, 9));
+		/* DIOI2C_DIS# */
+		gpio_direction_output(IMX_GPIO_NR(4,  5), 0);
+		/* PCICK_SSON: disable spread-spectrum clock */
+		gpio_direction_output(IMX_GPIO_NR(1, 20), 0);
+		/* assert PCI_RST# (released by OS when clock is valid) */
+		gpio_direction_output(IMX_GPIO_NR(1, 29), 0);
+		break;
+
+	case '1':
+		board_type = GW51xx;
+		imx_iomux_v3_setup_multiple_pads(gw51xx_gpio_pads,
+						 ARRAY_SIZE(gw51xx_gpio_pads));
+		/* PANLEDG# (GRN off) */
+		gpio_direction_output(IMX_GPIO_NR(4, 6), 1);
+		/* PANLEDR# (RED off) */
+		gpio_direction_output(IMX_GPIO_NR(4, 7), 1);
+		/* GPS_SHDN */
+		gpio_direction_output(IMX_GPIO_NR(1, 2), 1);
+		/* Analog video codec power enable */
+		gpio_direction_output(IMX_GPIO_NR(5, 20), 1);
+		/* Expansion IO0 - PWREN# */
+		gpio_direction_output(IMX_GPIO_NR(2, 19), 0);
+		/* Expansion IO1 - IRQ# */
+		gpio_direction_input(IMX_GPIO_NR(2, 18));
+		/* assert PCI_RST# (released by OS when clock is valid) */
+		gpio_direction_output(IMX_GPIO_NR(1, 0), 0);
+		break;
+
+	case '2':
+		board_type = GW52xx;
+		imx_iomux_v3_setup_multiple_pads(gw52xx_gpio_pads,
+						 ARRAY_SIZE(gw52xx_gpio_pads));
+		/* PANLEDG# (GRN off) */
+		gpio_direction_output(IMX_GPIO_NR(4, 6), 1);
+		/* PANLEDR# (RED off) */
+		gpio_direction_output(IMX_GPIO_NR(4, 7), 1);
+		/* MX6_LOCLED# (off) */
+		gpio_direction_output(IMX_GPIO_NR(4, 15), 1);
+		/* GPS_SHDN */
+		gpio_direction_output(IMX_GPIO_NR(1, 27), 1);
+		/* Expansion IO0 - PWREN# */
+		gpio_direction_output(IMX_GPIO_NR(2, 19), 0);
+		/* Expansion IO1 - IRQ# */
+		gpio_direction_input(IMX_GPIO_NR(2, 18));
+		/* USBOTG Select (PCISKT or FrontPanel) */
+		gpio_direction_output(IMX_GPIO_NR(1, 2), 0);
+		/* Analog video codec power enable */
+		gpio_direction_output(IMX_GPIO_NR(3, 31), 1);
+		/* assert PCI_RST# (released by OS when clock is valid) */
+		gpio_direction_output(IMX_GPIO_NR(1, 29), 0);
+		break;
+
+	case '3':
+		board_type = GW53xx;
+		imx_iomux_v3_setup_multiple_pads(gw53xx_gpio_pads,
+						 ARRAY_SIZE(gw53xx_gpio_pads));
+		/* PANLEDG# (GRN off) */
+		gpio_direction_output(IMX_GPIO_NR(4, 6), 1);
+		/* PANLEDR# (RED off) */
+		gpio_direction_output(IMX_GPIO_NR(4, 7), 1);
+		/* MX6_LOCLED# (off) */
+		gpio_direction_output(IMX_GPIO_NR(4, 15), 1);
+		/* GPS_SHDN */
+		gpio_direction_output(IMX_GPIO_NR(1, 27), 1);
+		/* Expansion IO0 - PWREN# */
+		gpio_direction_output(IMX_GPIO_NR(2, 19), 0);
+		/* Expansion IO1 - IRQ# */
+		gpio_direction_input(IMX_GPIO_NR(2, 18));
+		/* Analog video codec power enable */
+		gpio_direction_output(IMX_GPIO_NR(3, 31), 1);
+		/* assert PCI_RST# (released by OS when clock is valid) */
+		gpio_direction_output(IMX_GPIO_NR(1, 29), 0);
+		break;
+
+	case '4':
+		board_type = GW54xx;
+		imx_iomux_v3_setup_multiple_pads(gw54xx_gpio_pads,
+						 ARRAY_SIZE(gw54xx_gpio_pads));
+		/* PANLEDG# (GRN off) */
+		gpio_direction_output(IMX_GPIO_NR(4, 6), 1);
+		/* PANLEDR# (RED off) */
+		gpio_direction_output(IMX_GPIO_NR(4, 7), 1);
+		/* MX6_LOCLED# (off) */
+		gpio_direction_output(IMX_GPIO_NR(4, 15), 1);
+		/* RS485 Transmit Enable */
+		gpio_direction_output(IMX_GPIO_NR(7, 1), 0);
+		/* Expansion IO0 - PWREN# */
+		gpio_direction_output(IMX_GPIO_NR(2, 19), 0);
+		/* Expansion IO1 - IRQ# */
+		gpio_direction_input(IMX_GPIO_NR(2, 18));
+		/* Analog video codec power enable */
+		gpio_direction_output(IMX_GPIO_NR(3, 31), 1);
+		/* DIOI2C_DIS# */
+		gpio_direction_output(IMX_GPIO_NR(4,  5), 0);
+		/* PCICK_SSON: disable spread-spectrum clock */
+		gpio_direction_output(IMX_GPIO_NR(1, 20), 0);
+		/* assert PCI_RST# (released by OS when clock is valid) */
+		gpio_direction_output(IMX_GPIO_NR(1, 29), 0);
+		break;
+	}
+
+	/*
+	 * Configure DIO pinmux/padctl registers
+	 * see IMX6DQRM/IMX6SDLRM IOMUXC_SW_PAD_CTL_PAD_* register definitions
+	 */
+	if (board_type > UNKNOWN)
+		return;
+	for (i = 0; i < 4; i++) {
+		struct dio_cfg *cfg = &dio_cfg[(4*board_type)+i];
+		unsigned ctrl = DIO_PAD_CTRL;
+
+		sprintf(arg, "dio%d", i);
+		if (!hwconfig(arg))
+			continue;
+		s = hwconfig_subarg(arg, "padctrl", &len);
+		if (s)
+			ctrl = simple_strtoul(s, NULL, 16) & 0x3ffff;
+		if (hwconfig_subarg_cmp(arg, "mode", "gpio")) {
+			if (!quiet) {
+				printf("DIO%d:  GPIO%d_IO%02d (gpio-%d)\n", i,
+				       (cfg->gpio_param/32)+1,
+				       cfg->gpio_param%32,
+				       cfg->gpio_param);
+			}
+			imx_iomux_v3_setup_pad(cfg->gpio_padmux |
+					       MUX_PAD_CTRL(ctrl));
+			gpio_direction_input(cfg->gpio_param);
+		} else if (hwconfig_subarg_cmp("dio2", "mode", "pwm") &&
+			   cfg->pwm_padmux) {
+			if (!quiet)
+				printf("DIO%d:  pwm%d\n", i, cfg->pwm_param);
+			imx_iomux_v3_setup_pad(cfg->pwm_padmux |
+					       MUX_PAD_CTRL(ctrl));
+		}
+	}
+
+	if (!quiet) {
+		if (is_cpu_type(MXC_CPU_MX6Q) &&
+		    (test_bit(EECONFIG_SATA, info->config))) {
+			printf("MSATA: %s\n", (hwconfig("msata") ?
+			       "enabled" : "disabled"));
+		}
+		printf("RS232: %s\n", (hwconfig("rs232")) ?
+		       "enabled" : "disabled");
+	}
+}
+
+#ifdef CONFIG_SERIAL_TAG
+/*
+ * called when setting up ATAGS before booting kernel
+ * populate serialnum from the following (in order of priority):
+ *   serial# env var
+ *   eeprom
+ */
+void get_board_serial(struct tag_serialnr *serialnr)
+{
+	char *serial = getenv("serial#");
+
+	if (serial) {
+		serialnr->high = 0;
+		serialnr->low = simple_strtoul(serial, NULL, 10);
+	} else if (ventana_info.model[0]) {
+		serialnr->high = 0;
+		serialnr->low = ventana_info.serial;
+	} else {
+		serialnr->high = 0;
+		serialnr->low = 0;
+	}
+}
+#endif
+
+/*
+ * Board Support
+ */
+
+int board_early_init_f(void)
+{
+	setup_iomux_uart();
+	gpio_direction_output(GP_USB_OTG_PWR, 0); /* OTG power off */
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = get_ram_size((void *)PHYS_SDRAM,
+				    CONFIG_DDR_MB*1024*1024);
+
+	return 0;
+}
+
+int board_init(void)
+{
+	struct iomuxc_base_regs *const iomuxc_regs
+		= (struct iomuxc_base_regs *)IOMUXC_BASE_ADDR;
+
+	clrsetbits_le32(&iomuxc_regs->gpr[1],
+			IOMUXC_GPR1_OTG_ID_MASK,
+			IOMUXC_GPR1_OTG_ID_GPIO1);
+
+	/* address of linux boot parameters */
+	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
+
+#ifdef CONFIG_CMD_NAND
+	setup_gpmi_nand();
+#endif
+#ifdef CONFIG_MXC_SPI
+	setup_spi();
+#endif
+	setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0);
+	setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
+	setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
+
+#ifdef CONFIG_CMD_SATA
+	setup_sata();
+#endif
+	/* read Gateworks EEPROM into global struct (used later) */
+	read_eeprom();
+
+	return 0;
+}
+
+#if defined(CONFIG_DISPLAY_BOARDINFO_LATE)
+/*
+ * called during late init (after relocation and after board_init())
+ * by virtue of CONFIG_DISPLAY_BOARDINFO_LATE as we needed i2c initialized and
+ * EEPROM read.
+ */
+int checkboard(void)
+{
+	struct ventana_board_info *info = &ventana_info;
+	unsigned char buf[4];
+	const char *p;
+	int quiet; /* Quiet or minimal output mode */
+
+	quiet = 0;
+	p = getenv("quiet");
+	if (p)
+		quiet = simple_strtol(p, NULL, 10);
+	else
+		setenv("quiet", "0");
+
+	puts("\nGateworks Corporation Copyright 2014\n");
+	if (info->model[0]) {
+		printf("Model: %s\n", info->model);
+		printf("MFGDate: %02x-%02x-%02x%02x\n",
+		       info->mfgdate[0], info->mfgdate[1],
+		       info->mfgdate[2], info->mfgdate[3]);
+		printf("Serial:%d\n", info->serial);
+	} else {
+		puts("Invalid EEPROM - board will not function fully\n");
+	}
+
+	/* Display GSC firmware revision/CRC/status/RTC */
+	if (!quiet) {
+		i2c_set_bus_num(0);
+		if (!gsc_i2c_read(0x20, 14, 1, buf, 1)) {
+			printf("GSC:   v%d", buf[0]);
+			if (!gsc_i2c_read(0x20, 10, 1, buf, 4)) {
+				/* show firmware revision and CRC */
+				printf(" 0x%04x", buf[2] | buf[3]<<8);
+				/* show status register */
+				printf(" 0x%02x", buf[0]);
+			}
+			puts("\n");
+		}
+		if (!gsc_i2c_read(0x68, 0x00, 1, buf, 4)) {
+			printf("RTC:   %d\n",
+			       buf[0] | buf[1]<<8 | buf[2]<<16 | buf[3]<<24);
+		}
+	}
+
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_CMD_BMODE
+/*
+ * BOOT_CFG1, BOOT_CFG2, BOOT_CFG3, BOOT_CFG4
+ * see Table 8-11 and Table 5-9
+ *  BOOT_CFG1[7] = 1 (boot from NAND)
+ *  BOOT_CFG1[5] = 0 - raw NAND
+ *  BOOT_CFG1[4] = 0 - default pad settings
+ *  BOOT_CFG1[3:2] = 00 - devices = 1
+ *  BOOT_CFG1[1:0] = 00 - Row Address Cycles = 3
+ *  BOOT_CFG2[4:3] = 00 - Boot Search Count = 2
+ *  BOOT_CFG2[2:1] = 01 - Pages In Block = 64
+ *  BOOT_CFG2[0] = 0 - Reset time 12ms
+ */
+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) },
+	{ NULL, 0 },
+};
+#endif
+
+/* late init */
+int misc_init_r(void)
+{
+	struct ventana_board_info *info = &ventana_info;
+	unsigned char reg;
+
+	/* set env vars based on EEPROM data */
+	if (ventana_info.model[0]) {
+		char str[16], fdt[36];
+		char *p;
+		const char *cputype = "";
+		int i;
+
+		/*
+		 * FDT name will be prefixed with CPU type.  Three versions
+		 * will be created each increasingly generic and bootloader
+		 * env scripts will try loading each from most specific to
+		 * least.
+		 */
+		if (is_cpu_type(MXC_CPU_MX6Q))
+			cputype = "imx6q";
+		else if (is_cpu_type(MXC_CPU_MX6DL))
+			cputype = "imx6dl";
+		memset(str, 0, sizeof(str));
+		for (i = 0; i < (sizeof(str)-1) && info->model[i]; i++)
+			str[i] = tolower(info->model[i]);
+		if (!getenv("model"))
+			setenv("model", str);
+		if (!getenv("fdt_file")) {
+			sprintf(fdt, "%s-%s.dtb", cputype, str);
+			setenv("fdt_file", fdt);
+		}
+		p = strchr(str, '-');
+		if (p) {
+			*p++ = 0;
+
+			setenv("model_base", str);
+			if (!getenv("fdt_file1")) {
+				sprintf(fdt, "%s-%s.dtb", cputype, str);
+				setenv("fdt_file1", fdt);
+			}
+			str[4] = 'x';
+			str[5] = 'x';
+			str[6] = 0;
+			if (!getenv("fdt_file2")) {
+				sprintf(fdt, "%s-%s.dtb", cputype, str);
+				setenv("fdt_file2", fdt);
+			}
+		}
+
+		/* initialize env from EEPROM */
+		if (test_bit(EECONFIG_ETH0, info->config) &&
+		    !getenv("ethaddr")) {
+			eth_setenv_enetaddr("ethaddr", info->mac0);
+		}
+		if (test_bit(EECONFIG_ETH1, info->config) &&
+		    !getenv("eth1addr")) {
+			eth_setenv_enetaddr("eth1addr", info->mac1);
+		}
+
+		/* board serial-number */
+		sprintf(str, "%6d", info->serial);
+		setenv("serial#", str);
+	}
+
+	/* configure PFUZE100 PMIC (not used on Ventana baseboards) */
+	if (!pmic_init(1)) {
+		struct pmic *p = pmic_get("PFUZE100_PMIC");
+		u32 reg;
+		if (p && !pmic_probe(p)) {
+			/* 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);
+			pmic_reg_write(p, PFUZE100_SWBSTCON1, reg);
+		}
+	}
+
+	/* setup baseboard specific GPIO pinmux and config */
+	setup_board_gpio();
+
+#ifdef CONFIG_CMD_BMODE
+	add_board_boot_modes(board_boot_modes);
+#endif
+
+	/*
+	 *  The Gateworks System Controller implements a boot
+	 *  watchdog (always enabled) as a workaround for IMX6 boot related
+	 *  errata such as:
+	 *    ERR007117 - fixed in silicon r1.3
+	 *    ERR007220 - fixed in silicon r1.3
+	 *    ERR005768 - no fix
+	 *    ERR006282 - fixed in silicon r1.3
+	 *  see http://cache.freescale.com/files/32bit/doc/errata/IMX6DQCE.pdf
+	 *
+	 * Disable the boot watchdog and display/clear the timeout flag if set
+	 */
+	i2c_set_bus_num(0);
+	if (!gsc_i2c_read(0x20, 1, 1, &reg, 1)) {
+		reg |= 0x80;
+		if (gsc_i2c_write(0x20, 1, 1, &reg, 1))
+			puts("Error: could not disable GSC Watchdog\n");
+	} else {
+		puts("Error: could not disable GSC Watchdog\n");
+	}
+	if (!gsc_i2c_read(0x20, 10, 1, &reg, 1)) {
+		if (reg & 0x40) { /* GSC watchdog timeout */
+			puts("GSC boot watchdog timeout detected");
+			reg &= ~0x40; /* clear flag */
+			gsc_i2c_write(0x20, 10, 1, &reg, 1);
+		}
+	}
+
+	return 0;
+}
+
+#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
+/*
+ * called prior to booting kernel or by 'fdt boardsetup' command
+ *
+ * unless 'fdt_noauto' env var is set we will update the following in the DTB:
+ *  - mtd partitions based on mtdparts/mtdids env
+ *  - system-serial (board serial num from EEPROM)
+ *  - board (full model from EEPROM)
+ *  - peripherals removed from DTB if not loaded on board (per EEPROM config)
+ */
+void ft_board_setup(void *blob, bd_t *bd)
+{
+	struct ventana_board_info *info = &ventana_info;
+	struct node_info nodes[] = {
+		{ "sst,w25q256",          MTD_DEV_TYPE_NOR, },  /* SPI flash */
+		{ "fsl,imx6q-gpmi-nand",  MTD_DEV_TYPE_NAND, }, /* NAND flash */
+	};
+	const char *model = getenv("model");
+
+	if (getenv("fdt_noauto")) {
+		puts("   Skiping ft_board_setup (fdt_noauto defined)\n");
+		return;
+	}
+
+	/* Update partition nodes using info from mtdparts env var */
+	puts("   Updating MTD partitions...\n");
+	fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
+
+	if (!model) {
+		puts("invalid board info: Leaving FDT fully enabled\n");
+		return;
+	}
+	printf("   Adjusting FDT per EEPROM for %s...\n", model);
+
+	/* board serial number */
+	fdt_setprop(blob, 0, "system-serial", getenv("serial#"),
+		    strlen(getenv("serial#") + 1));
+
+	/* board (model contains model from device-tree) */
+	fdt_setprop(blob, 0, "board", info->model,
+		    strlen((const char *)info->model) + 1);
+
+	/*
+	 * Peripheral Config:
+	 *  remove nodes by alias path if EEPROM config tells us the
+	 *  peripheral is not loaded on the board.
+	 */
+	if (!test_bit(EECONFIG_ETH0, info->config))
+		fdt_del_node_and_alias(blob, "ethernet0");
+	if (!test_bit(EECONFIG_ETH1, info->config))
+		fdt_del_node_and_alias(blob, "ethernet1");
+	if (!test_bit(EECONFIG_HDMI_OUT, info->config))
+		fdt_del_node_and_alias(blob, "hdmi_out");
+	if (!test_bit(EECONFIG_SATA, info->config))
+		fdt_del_node_and_alias(blob, "ahci0");
+	if (!test_bit(EECONFIG_PCIE, info->config))
+		fdt_del_node_and_alias(blob, "pcie");
+	if (!test_bit(EECONFIG_SSI0, info->config))
+		fdt_del_node_and_alias(blob, "ssi0");
+	if (!test_bit(EECONFIG_SSI1, info->config))
+		fdt_del_node_and_alias(blob, "ssi1");
+	if (!test_bit(EECONFIG_LCD, info->config))
+		fdt_del_node_and_alias(blob, "lcd0");
+	if (!test_bit(EECONFIG_LVDS0, info->config))
+		fdt_del_node_and_alias(blob, "lvds0");
+	if (!test_bit(EECONFIG_LVDS1, info->config))
+		fdt_del_node_and_alias(blob, "lvds1");
+	if (!test_bit(EECONFIG_USB0, info->config))
+		fdt_del_node_and_alias(blob, "usb0");
+	if (!test_bit(EECONFIG_USB1, info->config))
+		fdt_del_node_and_alias(blob, "usb1");
+	if (!test_bit(EECONFIG_SD0, info->config))
+		fdt_del_node_and_alias(blob, "mmc0");
+	if (!test_bit(EECONFIG_SD1, info->config))
+		fdt_del_node_and_alias(blob, "mmc1");
+	if (!test_bit(EECONFIG_SD2, info->config))
+		fdt_del_node_and_alias(blob, "mmc2");
+	if (!test_bit(EECONFIG_SD3, info->config))
+		fdt_del_node_and_alias(blob, "mmc3");
+	if (!test_bit(EECONFIG_UART0, info->config))
+		fdt_del_node_and_alias(blob, "serial0");
+	if (!test_bit(EECONFIG_UART1, info->config))
+		fdt_del_node_and_alias(blob, "serial1");
+	if (!test_bit(EECONFIG_UART2, info->config))
+		fdt_del_node_and_alias(blob, "serial2");
+	if (!test_bit(EECONFIG_UART3, info->config))
+		fdt_del_node_and_alias(blob, "serial3");
+	if (!test_bit(EECONFIG_UART4, info->config))
+		fdt_del_node_and_alias(blob, "serial4");
+	if (!test_bit(EECONFIG_IPU0, info->config))
+		fdt_del_node_and_alias(blob, "ipu0");
+	if (!test_bit(EECONFIG_IPU1, info->config))
+		fdt_del_node_and_alias(blob, "ipu1");
+	if (!test_bit(EECONFIG_FLEXCAN, info->config))
+		fdt_del_node_and_alias(blob, "can0");
+	if (!test_bit(EECONFIG_MIPI_DSI, info->config))
+		fdt_del_node_and_alias(blob, "mipi_dsi");
+	if (!test_bit(EECONFIG_MIPI_CSI, info->config))
+		fdt_del_node_and_alias(blob, "mipi_csi");
+	if (!test_bit(EECONFIG_TZASC0, info->config))
+		fdt_del_node_and_alias(blob, "tzasc0");
+	if (!test_bit(EECONFIG_TZASC1, info->config))
+		fdt_del_node_and_alias(blob, "tzasc1");
+	if (!test_bit(EECONFIG_I2C0, info->config))
+		fdt_del_node_and_alias(blob, "i2c0");
+	if (!test_bit(EECONFIG_I2C1, info->config))
+		fdt_del_node_and_alias(blob, "i2c1");
+	if (!test_bit(EECONFIG_I2C2, info->config))
+		fdt_del_node_and_alias(blob, "i2c2");
+	if (!test_bit(EECONFIG_VPU, info->config))
+		fdt_del_node_and_alias(blob, "vpu");
+	if (!test_bit(EECONFIG_CSI0, info->config))
+		fdt_del_node_and_alias(blob, "csi0");
+	if (!test_bit(EECONFIG_CSI1, info->config))
+		fdt_del_node_and_alias(blob, "csi1");
+	if (!test_bit(EECONFIG_CAAM, info->config))
+		fdt_del_node_and_alias(blob, "caam");
+	if (!test_bit(EECONFIG_ESPCI0, info->config))
+		fdt_del_node_and_alias(blob, "spi0");
+	if (!test_bit(EECONFIG_ESPCI1, info->config))
+		fdt_del_node_and_alias(blob, "spi1");
+	if (!test_bit(EECONFIG_ESPCI2, info->config))
+		fdt_del_node_and_alias(blob, "spi2");
+	if (!test_bit(EECONFIG_ESPCI3, info->config))
+		fdt_del_node_and_alias(blob, "spi3");
+	if (!test_bit(EECONFIG_ESPCI4, info->config))
+		fdt_del_node_and_alias(blob, "spi4");
+	if (!test_bit(EECONFIG_ESPCI5, info->config))
+		fdt_del_node_and_alias(blob, "spi5");
+	if (!test_bit(EECONFIG_HDMI_IN, info->config))
+		fdt_del_node_and_alias(blob, "hdmi_in");
+	if (!test_bit(EECONFIG_VID_OUT, info->config))
+		fdt_del_node_and_alias(blob, "cvbs_out");
+	if (!test_bit(EECONFIG_VID_IN, info->config))
+		fdt_del_node_and_alias(blob, "cvbs_in");
+	if (!test_bit(EECONFIG_NAND, info->config))
+		fdt_del_node_and_alias(blob, "nand");
+	if (!test_bit(EECONFIG_GPS, info->config))
+		fdt_del_node_and_alias(blob, "pps");
+}
+#endif /* defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP) */
+
diff --git a/board/gateworks/gw_ventana/gw_ventana.cfg b/board/gateworks/gw_ventana/gw_ventana.cfg
new file mode 100644
index 0000000..6618fb9
--- /dev/null
+++ b/board/gateworks/gw_ventana/gw_ventana.cfg
@@ -0,0 +1,42 @@ 
+/*
+ * Copyright (C) 2013 Gateworks Corporation
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Refer doc/README.imximage for more details about how-to configure
+ * and create imximage boot image
+ *
+ * The syntax is taken as close as possible with the kwbimage
+ */
+
+/* image version */
+IMAGE_VERSION 2
+
+/*
+ * Boot Device : one of
+ * spi, sd, nand, sata
+ */
+#ifdef CONFIG_SPI_FLASH
+BOOT_FROM      spi
+#else
+BOOT_FROM      nand
+#endif
+
+#define __ASSEMBLY__
+#include <config.h>
+#include "asm/arch/mx6-ddr.h"
+#include "asm/arch/iomux.h"
+#include "asm/arch/crm_regs.h"
+
+/* Memory configuration (size is overridden via eeprom config) */
+#include "../../boundary/nitrogen6x/ddr-setup.cfg"
+#if defined(CONFIG_MX6Q) && CONFIG_DDR_MB == 1024
+  #include "../../boundary/nitrogen6x/1066mhz_4x128mx16.cfg"
+#elif defined(CONFIG_MX6DL) && CONFIG_DDR_MB == 1024
+  #include "../../boundary/nitrogen6x/800mhz_4x128mx16.cfg"
+#elif defined(CONFIG_MX6DL) && CONFIG_DDR_MB == 512
+  #include "../../boundary/nitrogen6x/800mhz_2x128mx16.cfg"
+#else
+  #error "Unsupported CPU/Memory configuration"
+#endif
+#include "clocks.cfg"
diff --git a/board/gateworks/gw_ventana/ventana_eeprom.h b/board/gateworks/gw_ventana/ventana_eeprom.h
new file mode 100644
index 0000000..6388f7e
--- /dev/null
+++ b/board/gateworks/gw_ventana/ventana_eeprom.h
@@ -0,0 +1,103 @@ 
+/*
+ * Copyright (C) 2013 Gateworks Corporation
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _VENTANA_EEPROM_
+#define _VENTANA_EEPROM_
+
+struct ventana_board_info {
+	u8 mac0[6];          /* 0x00: MAC1 */
+	u8 mac1[6];          /* 0x06: MAC2 */
+	u8 res0[12];         /* 0x0C: reserved */
+	u32 serial;          /* 0x18: Serial Number (read only) */
+	u8 res1[4];          /* 0x1C: reserved */
+	u8 mfgdate[4];       /* 0x20: MFG date (read only) */
+	u8 res2[7];          /* 0x24 */
+	/* sdram config */
+	u8 sdram_size;       /* 0x2B: enum (512,1024,2048) MB */
+	u8 sdram_speed;      /* 0x2C: enum (100,133,166,200,267,333,400) MHz */
+	u8 sdram_width;      /* 0x2D: enum (32,64) bit */
+	/* cpu config */
+	u8 cpu_speed;        /* 0x2E: enum (800,1000,1200) MHz */
+	u8 cpu_type;         /* 0x2F: enum (imx6q,imx6d,imx6dl,imx6s) */
+	u8 model[16];        /* 0x30: model string */
+	/* FLASH config */
+	u8 nand_flash_size;  /* 0x40: enum (4,8,16,32,64,128) MB */
+	u8 spi_flash_size;   /* 0x41: enum (4,8,16,32,64,128) MB */
+
+	/* Config1: SoC Peripherals */
+	u8 config[8];        /* 0x42: loading options */
+
+#define EECONFIG_ETH0     0
+#define EECONFIG_ETH1     1
+#define EECONFIG_HDMI_OUT 2
+#define EECONFIG_SATA     3
+#define EECONFIG_PCIE     4
+#define EECONFIG_SSI0     5
+#define EECONFIG_SSI1     6
+#define EECONFIG_LCD      7
+#define EECONFIG_LVDS0    8
+#define EECONFIG_LVDS1    9
+#define EECONFIG_USB0     10
+#define EECONFIG_USB1     11
+#define EECONFIG_SD0      12
+#define EECONFIG_SD1      13
+#define EECONFIG_SD2      14
+#define EECONFIG_SD3      15
+#define EECONFIG_UART0    16
+#define EECONFIG_UART1    17
+#define EECONFIG_UART2    18
+#define EECONFIG_UART3    19
+#define EECONFIG_UART4    20
+#define EECONFIG_IPU0     21
+#define EECONFIG_IPU1     22
+#define EECONFIG_FLEXCAN  23
+#define EECONFIG_MIPI_DSI 24
+#define EECONFIG_MIPI_CSI 25
+#define EECONFIG_TZASC0   26
+#define EECONFIG_TZASC1   27
+#define EECONFIG_I2C0     28
+#define EECONFIG_I2C1     29
+#define EECONFIG_I2C2     30
+#define EECONFIG_VPU      31
+#define EECONFIG_CSI0     32
+#define EECONFIG_CSI1     33
+#define EECONFIG_CAAM     34
+#define EECONFIG_MEZZ     35
+#define EECONFIG_RES1     36
+#define EECONFIG_RES2     37
+#define EECONFIG_RES3     38
+#define EECONFIG_RES4     39
+#define EECONFIG_ESPCI0   40
+#define EECONFIG_ESPCI1   41
+#define EECONFIG_ESPCI2   42
+#define EECONFIG_ESPCI3   43
+#define EECONFIG_ESPCI4   44
+#define EECONFIG_ESPCI5   45
+#define EECONFIG_RES5     46
+#define EECONFIG_RES6     47
+#define EECONFIG_GPS      48
+#define EECONFIG_SPIFL0   49
+#define EECONFIG_SPIFL1   50
+#define EECONFIG_GSPBATT  51
+#define EECONFIG_HDMI_IN  52
+#define EECONFIG_VID_OUT  53
+#define EECONFIG_VID_IN   54
+#define EECONFIG_NAND     55
+#define EECONFIG_RES8     56
+#define EECONFIG_RES9     57
+#define EECONFIG_RES10    58
+#define EECONFIG_RES11    59
+#define EECONFIG_RES12    60
+#define EECONFIG_RES13    61
+#define EECONFIG_RES14    62
+#define EECONFIG_RES15    63
+
+	u8 res3[4];          /* 0x4A */
+
+	u8 chksum[2];        /* 0x4E */
+};
+
+#endif
diff --git a/boards.cfg b/boards.cfg
index a8336cc..5f94558 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -308,6 +308,11 @@  Active  arm         armv7          mx6         freescale       mx6qsabreauto
 Active  arm         armv7          mx6         freescale       mx6sabresd          mx6dlsabresd                         mx6sabresd:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL                                                             Fabio Estevam <fabio.estevam@freescale.com>
 Active  arm         armv7          mx6         freescale       mx6sabresd          mx6qsabresd                          mx6sabresd:IMX_CONFIG=board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg,MX6Q                                                           Fabio Estevam <fabio.estevam@freescale.com>
 Active  arm         armv7          mx6         freescale       mx6slevk            mx6slevk                             mx6slevk:IMX_CONFIG=board/freescale/mx6slevk/imximage.cfg,MX6SL                                                                   Fabio Estevam <fabio.estevam@freescale.com>
+Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanadl                          gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6DL,DDR_MB=512                                                  Tim Harvey <tharvey@gateworks.com>
+Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanadl1g                        gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6DL,DDR_MB=1024                                                 Tim Harvey <tharvey@gateworks.com>
+Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanaq                           gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=512                                                   Tim Harvey <tharvey@gateworks.com>
+Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanaq1g                         gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=1024                                                  Tim Harvey <tharvey@gateworks.com>
+Active  arm         armv7          mx6         gateworks       gw_ventana          gwventanaq1gspi                      gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=1024,SPI_FLASH                                        Tim Harvey <tharvey@gateworks.com>
 Active  arm         armv7          mx6         barco           titanium            titanium                             titanium:IMX_CONFIG=board/barco/titanium/imximage.cfg                                                                         Stefan Roese <sr@denx.de>
 Active  arm         armv7          mx6         solidrun        hummingboard        hummingboard_solo                           hummingboard:IMX_CONFIG=board/solidrun/hummingboard/solo.cfg,MX6S,DDR_MB=512        Jon Nettleton <jon.nettleton@gmail.com>
 Active  arm         armv7          omap3       -               overo               omap3_overo                          -                                                                                                                                 Steve Sakoman <sakoman@gmail.com>
diff --git a/include/configs/gw_ventana.h b/include/configs/gw_ventana.h
new file mode 100644
index 0000000..05f4771
--- /dev/null
+++ b/include/configs/gw_ventana.h
@@ -0,0 +1,418 @@ 
+/*
+ * Copyright (C) 2013 Gateworks Corporation
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include "mx6_common.h"
+#define CONFIG_MX6
+#define CONFIG_DISPLAY_CPUINFO         /* display cpu info */
+#define CONFIG_DISPLAY_BOARDINFO_LATE  /* display board info (after reloc) */
+
+#define CONFIG_MACH_TYPE	4520   /* Gateworks Ventana Platform */
+
+#include <asm/arch/imx-regs.h>
+#include <asm/imx-common/gpio.h>
+
+/* ATAGs */
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+#define CONFIG_SERIAL_TAG
+#define CONFIG_REVISION_TAG
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN		(10 * 1024 * 1024)
+
+/* Init Functions */
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_MISC_INIT_R
+
+/* GPIO */
+#define CONFIG_MXC_GPIO
+
+/* Serial */
+#define CONFIG_MXC_UART
+#define CONFIG_MXC_UART_BASE	       UART2_BASE
+
+#ifdef CONFIG_SPI_FLASH
+
+/* SPI */
+#define CONFIG_CMD_SF
+#ifdef CONFIG_CMD_SF
+  #define CONFIG_MXC_SPI
+  #define CONFIG_SPI_FLASH_MTD
+  #define CONFIG_SPI_FLASH_BAR
+  #define CONFIG_SPI_FLASH_WINBOND
+  #define CONFIG_SPI_FLASH_WINBOND_ERASESIZE 64*1024  /* 4,32,64K for W26Q256 */
+  #define CONFIG_SF_DEFAULT_BUS              0
+  #define CONFIG_SF_DEFAULT_CS               (0|(IMX_GPIO_NR(3, 19)<<8))
+					     /* GPIO 3-19 (21248) */
+  #define CONFIG_SF_DEFAULT_SPEED            30000000
+  #define CONFIG_SF_DEFAULT_MODE             (SPI_MODE_0)
+#endif
+
+/* Flattened Image Tree Suport */
+#define CONFIG_FIT
+#define CONFIG_FIT_VERBOSE
+
+#else
+/* Enable NAND support */
+#define CONFIG_CMD_TIME
+#define CONFIG_CMD_NAND
+#define CONFIG_CMD_NAND_TRIMFFS
+#ifdef CONFIG_CMD_NAND
+  #define CONFIG_NAND_MXS
+  #define CONFIG_SYS_MAX_NAND_DEVICE	1
+  #define CONFIG_SYS_NAND_BASE		0x40000000
+  #define CONFIG_SYS_NAND_5_ADDR_CYCLE
+  #define CONFIG_SYS_NAND_ONFI_DETECTION
+
+  /* DMA stuff, needed for GPMI/MXS NAND support */
+  #define CONFIG_APBH_DMA
+  #define CONFIG_APBH_DMA_BURST
+  #define CONFIG_APBH_DMA_BURST8
+#endif
+
+#endif /* CONFIG_SPI_FLASH */
+
+/* I2C Configs */
+#define CONFIG_CMD_I2C
+#define CONFIG_SYS_I2C
+#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_SPEED		  100000
+
+/* MMC Configs */
+#define CONFIG_FSL_ESDHC
+#define CONFIG_FSL_USDHC
+#define CONFIG_SYS_FSL_ESDHC_ADDR      0
+#define CONFIG_SYS_FSL_USDHC_NUM       1
+#define CONFIG_MMC
+#define CONFIG_CMD_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_BOUNCE_BUFFER
+
+/* Filesystem support */
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_UBIFS
+#define CONFIG_DOS_PARTITION
+
+/* Network config - Allow larger/faster download for TFTP/NFS */
+#define CONFIG_IP_DEFRAG
+#define CONFIG_TFTP_BLOCKSIZE 4096
+#define CONFIG_NFS_READ_SIZE  4096
+
+#ifdef CONFIG_MX6Q
+#define CONFIG_CMD_SATA
+#endif
+
+/*
+ * SATA Configs
+ */
+#ifdef CONFIG_CMD_SATA
+  #define CONFIG_DWC_AHSATA
+  #define CONFIG_SYS_SATA_MAX_DEVICE	1
+  #define CONFIG_DWC_AHSATA_PORT_ID	0
+  #define CONFIG_DWC_AHSATA_BASE_ADDR	SATA_ARB_BASE_ADDR
+  #define CONFIG_LBA48
+  #define CONFIG_LIBATA
+#endif
+
+/*
+ * PMIC
+ */
+#define CONFIG_POWER
+#define CONFIG_POWER_I2C
+#define CONFIG_POWER_PFUZE100
+#define CONFIG_POWER_PFUZE100_I2C_ADDR	0x08
+
+/* Various command support */
+#include <config_cmd_default.h>
+#undef CONFIG_CMD_IMLS
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_BMODE         /* set eFUSE shadow for a boot dev and reset */
+#define CONFIG_CMD_HDMIDETECT    /* detect HDMI output device */
+#define CONFIG_CMD_SETEXPR
+#define CONFIG_CMD_BOOTZ
+#define CONFIG_CMD_GSC
+#define CONFIG_CMD_UBI
+#define CONFIG_RBTREE
+#define CONFIG_LZO
+#define CONFIG_CMD_FUSE          /* eFUSE read/write support */
+#ifdef CONFIG_CMD_FUSE
+#define CONFIG_MXC_OCOTP
+#endif
+
+
+/* Ethernet support */
+#define CONFIG_FEC_MXC
+#define CONFIG_MII
+#define IMX_FEC_BASE             ENET_BASE_ADDR
+#define CONFIG_FEC_XCV_TYPE      RGMII
+#define CONFIG_ETHPRIME          "FEC"
+#define CONFIG_FEC_MXC_PHYADDR   0
+#define CONFIG_PHYLIB
+#define CONFIG_ARP_TIMEOUT       200UL
+
+/* USB Configs */
+#define CONFIG_CMD_USB
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_MX6
+#define CONFIG_USB_STORAGE
+#define CONFIG_USB_HOST_ETHER
+#define CONFIG_USB_ETHER_ASIX
+#define CONFIG_USB_ETHER_SMSC95XX
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
+#define CONFIG_EHCI_HCD_INIT_AFTER_RESET  /* For OTG port */
+#define CONFIG_MXC_USB_PORTSC     (PORT_PTS_UTMI | PORT_PTS_PTW)
+#define CONFIG_MXC_USB_FLAGS      0
+#define CONFIG_USB_KEYBOARD
+#define CONFIG_MV_UDC
+#define CONFIG_USBD_HS
+#define CONFIG_USB_GADGET_DUALSPEED
+#define CONFIG_USB_ETHER
+#define CONFIG_USB_ETH_CDC
+#define CONFIG_NETCONSOLE
+#define CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP
+#define CONFIG_USB_HUB_MIN_POWER_ON_DELAY 1200
+
+/* serial console (ttymxc1,115200) */
+#define CONFIG_CONS_INDEX              1
+#define CONFIG_BAUDRATE                115200
+
+/* Miscellaneous configurable options */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT	             "Ventana > "
+#define CONFIG_SYS_CBSIZE	             1024
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_HWCONFIG
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS	           16
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+
+/* Memory configuration */
+#define CONFIG_SYS_MEMTEST_START       0x10000000
+#define CONFIG_SYS_MEMTEST_END	       0x10010000
+#define CONFIG_SYS_MEMTEST_SCRATCH     0x10800000
+#define CONFIG_SYS_TEXT_BASE	         0x17800000
+#define CONFIG_SYS_LOAD_ADDR           0x12000000
+
+/* Physical Memory Map */
+#define CONFIG_NR_DRAM_BANKS           1
+#define PHYS_SDRAM                     MMDC0_ARB_BASE_ADDR
+#define CONFIG_SYS_SDRAM_BASE          PHYS_SDRAM
+#define CONFIG_SYS_INIT_RAM_ADDR       IRAM_BASE_ADDR
+#define CONFIG_SYS_INIT_RAM_SIZE       IRAM_SIZE
+
+#define CONFIG_SYS_INIT_SP_OFFSET \
+	(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR \
+	(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
+
+/* FLASH and environment organization */
+#define CONFIG_SYS_NO_FLASH  /* no NOR flash */
+
+/*
+ * MTD Command for mtdparts
+ */
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_MTD_DEVICE
+#define CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_SPI_FLASH
+#define MTDIDS_DEFAULT    "nor0=nor"
+#define MTDPARTS_DEFAULT  \
+	"mtdparts=nor:512k(uboot),64k(env),2m(kernel),-(rootfs)"
+#else
+#define MTDIDS_DEFAULT    "nand0=nand"
+#define MTDPARTS_DEFAULT  "mtdparts=nand:16m(uboot),1m(env),-(rootfs)"
+#endif
+
+/* Persistent Environment Config */
+#define CONFIG_ENV_OVERWRITE    /* allow to overwrite serial and ethaddr */
+#ifdef CONFIG_SPI_FLASH
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#else
+#define CONFIG_ENV_IS_IN_NAND
+#endif
+#if defined(CONFIG_ENV_IS_IN_MMC)
+  #define CONFIG_ENV_OFFSET              (6 * 64 * 1024)
+  #define CONFIG_ENV_SIZE                (8 * 1024)
+  #define CONFIG_SYS_MMC_ENV_DEV         0
+#elif defined(CONFIG_ENV_IS_IN_NAND)
+  #define CONFIG_ENV_OFFSET              (16 << 20)
+  #define CONFIG_ENV_SECT_SIZE           (128 << 10)
+  #define CONFIG_ENV_SIZE                CONFIG_ENV_SECT_SIZE
+  #define CONFIG_ENV_OFFSET_REDUND       (CONFIG_ENV_OFFSET + (512 << 10))
+  #define CONFIG_ENV_SIZE_REDUND         CONFIG_ENV_SIZE
+#elif defined(CONFIG_ENV_IS_IN_SPI_FLASH)
+  #define CONFIG_ENV_OFFSET              (512 * 1024)
+  #define CONFIG_ENV_SECT_SIZE           (64 * 1024)
+  #define CONFIG_ENV_SIZE                (8 * 1024)
+  #define CONFIG_ENV_SPI_BUS             CONFIG_SF_DEFAULT_BUS
+  #define CONFIG_ENV_SPI_CS              CONFIG_SF_DEFAULT_CS
+  #define CONFIG_ENV_SPI_MODE            CONFIG_SF_DEFAULT_MODE
+  #define CONFIG_ENV_SPI_MAX_HZ          CONFIG_SF_DEFAULT_SPEED
+#endif
+
+/* Environment */
+#define CONFIG_BOOTDELAY          3
+#define CONFIG_LOADADDR           CONFIG_SYS_LOAD_ADDR
+#define CONFIG_IPADDR             192.168.1.1
+#define CONFIG_SERVERIP           192.168.1.146
+#define HWCONFIG_DEFAULT \
+	"hwconfig=rs232;" \
+	"dio0:mode=gpio;dio1:mode=gpio;dio2:mode=gpio;dio3:mode=gpio\0" \
+
+#define CONFIG_EXTRA_ENV_SETTINGS_COMMON \
+	"console=ttymxc1\0" \
+	"bootdevs=usb mmc sata flash\0" \
+	HWCONFIG_DEFAULT \
+	"video=\0" \
+	\
+	"mtdparts=" MTDPARTS_DEFAULT "\0" \
+	"mtdids=" MTDIDS_DEFAULT "\0" \
+	\
+	"fdt_high=0xffffffff\0" \
+	"fdt_addr=0x18000000\0" \
+	"loadfdt=" \
+		"if ${fsload} ${fdt_addr} boot/${fdt_file}; then " \
+			"echo Loaded DTB from boot/${fdt_file}; " \
+		"elif ${fsload} ${fdt_addr} boot/${fdt_file1}; then " \
+			"echo Loaded DTB from boot/${fdt_file1}; " \
+		"elif ${fsload} ${fdt_addr} boot/${fdt_file2}; then " \
+				"echo Loaded DTB from boot/${fdt_file2}; " \
+		"fi\0" \
+	\
+	"script=boot/6x_bootscript-ventana\0" \
+	"loadscript=" \
+		"if ${fsload} ${loadaddr} ${script}; then " \
+			"source; " \
+		"fi\0" \
+	\
+	"uimage=boot/uImage\0" \
+	"mmc_root=/dev/mmcblk0p1 rootfstype=ext4 rootwait rw\0" \
+	"mmc_boot=" \
+		"setenv fsload 'ext2load mmc 0:1'; " \
+		"mmc dev 0 && mmc rescan && " \
+		"run loadscript; " \
+		"if ${fsload} ${loadaddr} ${uimage}; then " \
+			"setenv bootargs console=${console},${baudrate} " \
+				"root=/dev/mmcblk0p1 rootfstype=ext4 " \
+				"rootwait rw ${video} ${extra}; " \
+			"if run loadfdt && fdt addr ${fdt_addr}; then " \
+				"bootm ${loadaddr} - ${fdt_addr}; " \
+			"else " \
+				"bootm; " \
+			"fi; " \
+		"fi\0" \
+	\
+	"sata_boot=" \
+		"setenv fsload 'ext2load sata 0:1'; sata init && " \
+		"run loadscript; " \
+		"if ${fsload} ${loadaddr} ${uimage}; then " \
+			"setenv bootargs console=${console},${baudrate} " \
+				"root=/dev/sda1 rootfstype=ext4 " \
+				"rootwait rw ${video} ${extra}; " \
+			"if run loadfdt && fdt addr ${fdt_addr}; then " \
+				"bootm ${loadaddr} - ${fdt_addr}; " \
+			"else " \
+				"bootm; " \
+			"fi; " \
+		"fi\0" \
+	"usb_boot=" \
+		"setenv fsload 'ext2load usb 0:1'; usb start && usb dev 0 && " \
+		"run loadscript; " \
+		"if ${fsload} ${loadaddr} ${uimage}; then " \
+			"setenv bootargs console=${console},${baudrate} " \
+				"root=/dev/sda1 rootfstype=ext4 " \
+				"rootwait rw ${video} ${extra}; " \
+			"if run loadfdt && fdt addr ${fdt_addr}; then " \
+				"bootm ${loadaddr} - ${fdt_addr}; " \
+			"else " \
+				"bootm; " \
+			"fi; " \
+		"fi\0"
+
+#ifdef CONFIG_SPI_FLASH
+	#define CONFIG_EXTRA_ENV_SETTINGS \
+	CONFIG_EXTRA_ENV_SETTINGS_COMMON \
+	"image_os=ventana/openwrt-imx6-imx6q-gw5400-a-squashfs.bin\0" \
+	"image_uboot=ventana/u-boot_spi.imx\0" \
+	\
+	"spi_koffset=0x90000\0" \
+	"spi_klen=0x200000\0" \
+	\
+	"spi_updateuboot=echo Updating uboot from " \
+		"${serverip}:${image_uboot}...; " \
+		"tftpboot ${loadaddr} ${image_uboot} && " \
+		"sf probe && sf erase 0 80000 && " \
+			"sf write ${loadaddr} 400 ${filesize}\0" \
+	"spi_update=echo Updating OS from ${serverip}:${image_os} " \
+		"to ${spi_koffset} ...; " \
+		"tftp ${loadaddr} ${image_os} && " \
+		"sf probe && " \
+		"sf update ${loadaddr} ${spi_koffset} ${filesize}\0" \
+	\
+	"flash_boot=" \
+		"if sf probe && " \
+		"sf read ${loadaddr} ${spi_koffset} ${spi_klen}; then " \
+			"setenv bootargs console=${console},${baudrate} " \
+				"root=/dev/mtdblock3 " \
+				"rootfstype=squashfs,jffs2 " \
+				"${video} ${extra}; " \
+			"bootm; " \
+		"fi\0"
+#else
+	#define CONFIG_EXTRA_ENV_SETTINGS \
+	CONFIG_EXTRA_ENV_SETTINGS_COMMON \
+	"image_rootfs=openwrt-imx6-ventana-rootfs.ubi\0" \
+	\
+	"nand_update=echo Updating NAND from ${serverip}:${image_rootfs}...; " \
+		"tftp ${loadaddr} ${image_rootfs} && " \
+		"nand erase.part rootfs && " \
+		"nand write ${loadaddr} rootfs ${filesize}\0" \
+	\
+	"flash_boot=" \
+		"setenv fsload 'ubifsload'; " \
+		"ubi part rootfs && ubifsmount ubi0:rootfs; " \
+		"run loadscript; " \
+		"if ${fsload} ${loadaddr} ${uimage}; then " \
+			"setenv bootargs console=${console},${baudrate} " \
+				"root=ubi0:rootfs ubi.mtd=2 " \
+				"rootfstype=ubifs ${video} ${extra}; " \
+			"if run loadfdt && fdt addr ${fdt_addr}; then " \
+				"ubifsumount; " \
+				"bootm ${loadaddr} - ${fdt_addr}; " \
+			"else " \
+				"ubifsumount; bootm; " \
+			"fi; " \
+		"fi\0"
+#endif
+
+#define CONFIG_BOOTCOMMAND \
+	"for btype in ${bootdevs}; do " \
+		"echo; echo Attempting ${btype} boot...; " \
+		"if run ${btype}_boot; then; fi; " \
+	"done"
+
+/* Device Tree Support */
+#define CONFIG_OF_BOARD_SETUP
+#define CONFIG_OF_LIBFDT
+#define CONFIG_FDT_FIXUP_PARTITIONS
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+  #define CONFIG_CMD_CACHE
+#endif
+
+#endif			       /* __CONFIG_H */