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

Tim Harvey tharvey at gateworks.com
Wed Feb 5 09:17:29 CET 2014


On Mon, Feb 3, 2014 at 9:39 AM, Stefano Babic <sbabic at 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 at 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 at 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 at 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 at denx.de
> =====================================================================


More information about the U-Boot mailing list