]> git.ipfire.org Git - thirdparty/u-boot.git/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot-mips
authorTom Rini <trini@konsulko.com>
Sat, 21 May 2016 00:43:27 +0000 (20:43 -0400)
committerTom Rini <trini@konsulko.com>
Mon, 23 May 2016 15:51:37 +0000 (11:51 -0400)
28 files changed:
README
arch/arm/cpu/armv8/start.S
board/compulab/common/eeprom.c
cmd/eeprom.c
common/Makefile
common/dlmalloc.c
common/eeprom/eeprom_field.c [new file with mode: 0644]
common/eeprom/eeprom_layout.c [new file with mode: 0644]
common/image-fit.c
common/spl/spl_fat.c
common/spl/spl_fit.c
configs/pico-imx6ul_defconfig
drivers/ddr/marvell/a38x/ddr3_init.c
drivers/spi/omap3_spi.c
dts/Kconfig
include/configs/cm_fx6.h
include/configs/cm_t335.h
include/configs/cm_t35.h
include/configs/cm_t3517.h
include/configs/cm_t43.h
include/configs/cm_t54.h
include/configs/theadorable.h
include/eeprom_field.h [new file with mode: 0644]
include/eeprom_layout.h [new file with mode: 0644]
scripts/basic/fixdep.c
tools/imagetool.c
tools/imagetool.h
tools/mkimage.c

diff --git a/README b/README
index 94e9943b0460f5a41fab1994e745864e4ff92836..6f4c09a3a1fc13b47a6510b01c5c96a260c503ff 100644 (file)
--- a/README
+++ b/README
@@ -1003,6 +1003,7 @@ The following options need to be configured:
                CONFIG_CMD_ECHO           echo arguments
                CONFIG_CMD_EDITENV        edit env variable
                CONFIG_CMD_EEPROM       * EEPROM read/write support
+               CONFIG_CMD_EEPROM_LAYOUT* EEPROM layout aware commands
                CONFIG_CMD_ELF          * bootelf, bootvx
                CONFIG_CMD_ENV_CALLBACK * display details about env callbacks
                CONFIG_CMD_ENV_FLAGS    * display details about env flags
index c3cc8199caf94f87f869c30d720ed09a6d6b7fb1..e933021a17ebe78de0a7a6150e248fe414d8bbdf 100644 (file)
@@ -216,7 +216,7 @@ WEAK(lowlevel_init)
 #endif
 #endif
 
-#ifndef CONFIG_ARMV8_MULTIENTRY
+#ifdef CONFIG_ARMV8_MULTIENTRY
        branch_if_master x0, x1, 2f
 
        /*
index 630446820cc5fc3bbff02f1194f0c5eb671da5ec..b5f1aa61cb8dd135ee10165c847fa555f9908a9e 100644 (file)
@@ -9,6 +9,9 @@
 
 #include <common.h>
 #include <i2c.h>
+#include <eeprom_layout.h>
+#include <eeprom_field.h>
+#include <linux/kernel.h>
 #include "eeprom.h"
 
 #ifndef CONFIG_SYS_I2C_EEPROM_ADDR
@@ -181,3 +184,344 @@ int cl_eeprom_get_product_name(uchar *buf, uint eeprom_bus)
 
        return err;
 }
+
+#ifdef CONFIG_CMD_EEPROM_LAYOUT
+/**
+ * eeprom_field_print_bin_ver() - print a "version field" which contains binary
+ *                               data
+ *
+ * Treat the field data as simple binary data, and print it formatted as a
+ * version number (2 digits after decimal point).
+ * The field size must be exactly 2 bytes.
+ *
+ * Sample output:
+ *      Field Name      123.45
+ *
+ * @field:     an initialized field to print
+ */
+void eeprom_field_print_bin_ver(const struct eeprom_field *field)
+{
+       if ((field->buf[0] == 0xff) && (field->buf[1] == 0xff)) {
+               field->buf[0] = 0;
+               field->buf[1] = 0;
+       }
+
+       printf(PRINT_FIELD_SEGMENT, field->name);
+       int major = (field->buf[1] << 8 | field->buf[0]) / 100;
+       int minor = (field->buf[1] << 8 | field->buf[0]) - major * 100;
+       printf("%d.%02d\n", major, minor);
+}
+
+/**
+ * eeprom_field_update_bin_ver() - update a "version field" which contains
+ *                                binary data
+ *
+ * This function takes a version string in the form of x.y (x and y are both
+ * decimal values, y is limited to two digits), translates it to the binary
+ * form, then writes it to the field. The field size must be exactly 2 bytes.
+ *
+ * This function strictly enforces the data syntax, and will not update the
+ * field if there's any deviation from it. It also protects from overflow.
+ *
+ * @field:     an initialized field
+ * @value:     a version string
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+int eeprom_field_update_bin_ver(struct eeprom_field *field, char *value)
+{
+       char *endptr;
+       char *tok = strtok(value, ".");
+       if (tok == NULL)
+               return -1;
+
+       int num = simple_strtol(tok, &endptr, 0);
+       if (*endptr != '\0')
+               return -1;
+
+       tok = strtok(NULL, "");
+       if (tok == NULL)
+               return -1;
+
+       int remainder = simple_strtol(tok, &endptr, 0);
+       if (*endptr != '\0')
+               return -1;
+
+       num = num * 100 + remainder;
+       if (num >> 16)
+               return -1;
+
+       field->buf[0] = (unsigned char)num;
+       field->buf[1] = num >> 8;
+
+       return 0;
+}
+
+char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+                   "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+/**
+ * eeprom_field_print_date() - print a field which contains date data
+ *
+ * Treat the field data as simple binary data, and print it formatted as a date.
+ * Sample output:
+ *      Field Name      07/Feb/2014
+ *      Field Name      56/BAD/9999
+ *
+ * @field:     an initialized field to print
+ */
+void eeprom_field_print_date(const struct eeprom_field *field)
+{
+       printf(PRINT_FIELD_SEGMENT, field->name);
+       printf("%02d/", field->buf[0]);
+       if (field->buf[1] >= 1 && field->buf[1] <= 12)
+               printf("%s", months[field->buf[1] - 1]);
+       else
+               printf("BAD");
+
+       printf("/%d\n", field->buf[3] << 8 | field->buf[2]);
+}
+
+static int validate_date(unsigned char day, unsigned char month,
+                       unsigned int year)
+{
+       int days_in_february;
+
+       switch (month) {
+       case 0:
+       case 2:
+       case 4:
+       case 6:
+       case 7:
+       case 9:
+       case 11:
+               if (day > 31)
+                       return -1;
+               break;
+       case 3:
+       case 5:
+       case 8:
+       case 10:
+               if (day > 30)
+                       return -1;
+               break;
+       case 1:
+               days_in_february = 28;
+               if (year % 4 == 0) {
+                       if (year % 100 != 0)
+                               days_in_february = 29;
+                       else if (year % 400 == 0)
+                               days_in_february = 29;
+               }
+
+               if (day > days_in_february)
+                       return -1;
+
+               break;
+       default:
+               return -1;
+       }
+
+       return 0;
+}
+
+/**
+ * eeprom_field_update_date() - update a date field which contains binary data
+ *
+ * This function takes a date string in the form of x/Mon/y (x and y are both
+ * decimal values), translates it to the binary representation, then writes it
+ * to the field.
+ *
+ * This function strictly enforces the data syntax, and will not update the
+ * field if there's any deviation from it. It also protects from overflow in the
+ * year value, and checks the validity of the date.
+ *
+ * @field:     an initialized field
+ * @value:     a date string
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+int eeprom_field_update_date(struct eeprom_field *field, char *value)
+{
+       char *endptr;
+       char *tok1 = strtok(value, "/");
+       char *tok2 = strtok(NULL, "/");
+       char *tok3 = strtok(NULL, "/");
+
+       if (tok1 == NULL || tok2 == NULL || tok3 == NULL) {
+               printf("%s: syntax error\n", field->name);
+               return -1;
+       }
+
+       unsigned char day = (unsigned char)simple_strtol(tok1, &endptr, 0);
+       if (*endptr != '\0' || day == 0) {
+               printf("%s: invalid day\n", field->name);
+               return -1;
+       }
+
+       unsigned char month;
+       for (month = 1; month <= 12; month++)
+               if (!strcmp(tok2, months[month - 1]))
+                       break;
+
+       unsigned int year = simple_strtol(tok3, &endptr, 0);
+       if (*endptr != '\0') {
+               printf("%s: invalid year\n", field->name);
+               return -1;
+       }
+
+       if (validate_date(day, month - 1, year)) {
+               printf("%s: invalid date\n", field->name);
+               return -1;
+       }
+
+       if (year >> 16) {
+               printf("%s: year overflow\n", field->name);
+               return -1;
+       }
+
+       field->buf[0] = day;
+       field->buf[1] = month;
+       field->buf[2] = (unsigned char)year;
+       field->buf[3] = (unsigned char)(year >> 8);
+
+       return 0;
+}
+
+#define        LAYOUT_VERSION_LEGACY 1
+#define        LAYOUT_VERSION_VER1 2
+#define        LAYOUT_VERSION_VER2 3
+#define        LAYOUT_VERSION_VER3 4
+
+extern struct eeprom_field layout_unknown[1];
+
+#define DEFINE_PRINT_UPDATE(x) eeprom_field_print_##x, eeprom_field_update_##x
+
+#ifdef CONFIG_CM_T3X
+struct eeprom_field layout_legacy[5] = {
+       { "MAC address",          6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "Board Revision",       2, NULL, DEFINE_PRINT_UPDATE(bin) },
+       { "Serial Number",        8, NULL, DEFINE_PRINT_UPDATE(bin) },
+       { "Board Configuration", 64, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { RESERVED_FIELDS,      176, NULL, eeprom_field_print_reserved,
+                                          eeprom_field_update_ascii },
+};
+#else
+#define layout_legacy layout_unknown
+#endif
+
+#if defined(CONFIG_CM_T3X) || defined(CONFIG_CM_T3517)
+struct eeprom_field layout_v1[12] = {
+       { "Major Revision",      2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
+       { "Minor Revision",      2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
+       { "1st MAC Address",     6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "2nd MAC Address",     6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "Production Date",     4, NULL, DEFINE_PRINT_UPDATE(date) },
+       { "Serial Number",      12, NULL, DEFINE_PRINT_UPDATE(bin_rev) },
+       { RESERVED_FIELDS,      96, NULL, DEFINE_PRINT_UPDATE(reserved) },
+       { "Product Name",       16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #1", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #2", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #3", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { RESERVED_FIELDS,      64, NULL, eeprom_field_print_reserved,
+                                         eeprom_field_update_ascii },
+};
+#else
+#define layout_v1 layout_unknown
+#endif
+
+struct eeprom_field layout_v2[15] = {
+       { "Major Revision",            2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
+       { "Minor Revision",            2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
+       { "1st MAC Address",           6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "2nd MAC Address",           6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "Production Date",           4, NULL, DEFINE_PRINT_UPDATE(date) },
+       { "Serial Number",            12, NULL, DEFINE_PRINT_UPDATE(bin_rev) },
+       { "3rd MAC Address (WIFI)",    6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "4th MAC Address (Bluetooth)", 6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "Layout Version",            1, NULL, DEFINE_PRINT_UPDATE(bin) },
+       { RESERVED_FIELDS,            83, NULL, DEFINE_PRINT_UPDATE(reserved) },
+       { "Product Name",             16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #1",       16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #2",       16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #3",       16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { RESERVED_FIELDS,            64, NULL, eeprom_field_print_reserved,
+                                               eeprom_field_update_ascii },
+};
+
+struct eeprom_field layout_v3[16] = {
+       { "Major Revision",            2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
+       { "Minor Revision",            2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
+       { "1st MAC Address",           6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "2nd MAC Address",           6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "Production Date",           4, NULL, DEFINE_PRINT_UPDATE(date) },
+       { "Serial Number",            12, NULL, DEFINE_PRINT_UPDATE(bin_rev) },
+       { "3rd MAC Address (WIFI)",    6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "4th MAC Address (Bluetooth)", 6, NULL, DEFINE_PRINT_UPDATE(mac) },
+       { "Layout Version",            1, NULL, DEFINE_PRINT_UPDATE(bin) },
+       { "CompuLab EEPROM ID",        3, NULL, DEFINE_PRINT_UPDATE(bin) },
+       { RESERVED_FIELDS,            80, NULL, DEFINE_PRINT_UPDATE(reserved) },
+       { "Product Name",             16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #1",       16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #2",       16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { "Product Options #3",       16, NULL, DEFINE_PRINT_UPDATE(ascii) },
+       { RESERVED_FIELDS,            64, NULL, eeprom_field_print_reserved,
+                                               eeprom_field_update_ascii },
+};
+
+void eeprom_layout_assign(struct eeprom_layout *layout, int layout_version)
+{
+       switch (layout->layout_version) {
+       case LAYOUT_VERSION_LEGACY:
+               layout->fields = layout_legacy;
+               layout->num_of_fields = ARRAY_SIZE(layout_legacy);
+               break;
+       case LAYOUT_VERSION_VER1:
+               layout->fields = layout_v1;
+               layout->num_of_fields = ARRAY_SIZE(layout_v1);
+               break;
+       case LAYOUT_VERSION_VER2:
+               layout->fields = layout_v2;
+               layout->num_of_fields = ARRAY_SIZE(layout_v2);
+               break;
+       case LAYOUT_VERSION_VER3:
+               layout->fields = layout_v3;
+               layout->num_of_fields = ARRAY_SIZE(layout_v3);
+               break;
+       default:
+               __eeprom_layout_assign(layout, layout_version);
+       }
+}
+
+int eeprom_parse_layout_version(char *str)
+{
+       if (!strcmp(str, "legacy"))
+               return LAYOUT_VERSION_LEGACY;
+       else if (!strcmp(str, "v1"))
+               return LAYOUT_VERSION_VER1;
+       else if (!strcmp(str, "v2"))
+               return LAYOUT_VERSION_VER2;
+       else if (!strcmp(str, "v3"))
+               return LAYOUT_VERSION_VER3;
+       else
+               return LAYOUT_VERSION_UNRECOGNIZED;
+}
+
+int eeprom_layout_detect(unsigned char *data)
+{
+       switch (data[EEPROM_LAYOUT_VER_OFFSET]) {
+       case 0xff:
+       case 0:
+               return LAYOUT_VERSION_VER1;
+       case 2:
+               return LAYOUT_VERSION_VER2;
+       case 3:
+               return LAYOUT_VERSION_VER3;
+       }
+
+       if (data[EEPROM_LAYOUT_VER_OFFSET] >= 0x20)
+               return LAYOUT_VERSION_LEGACY;
+
+       return LAYOUT_VERSION_UNRECOGNIZED;
+}
+#endif
index e5457ba0cf44d82344517a1b9b4fbaa1d1853f96..0a0e4a2c1cc8f365c5f4d9539dd91eeec24d0e9e 100644 (file)
@@ -24,6 +24,7 @@
 #include <config.h>
 #include <command.h>
 #include <i2c.h>
+#include <eeprom_layout.h>
 
 #ifndef        CONFIG_SYS_I2C_SPEED
 #define        CONFIG_SYS_I2C_SPEED    50000
@@ -72,7 +73,7 @@ void eeprom_init(int bus)
 #endif
 
        /* I2C EEPROM */
-#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C_SOFT)
+#if defined(CONFIG_HARD_I2C) || defined(CONFIG_SYS_I2C)
 #if defined(CONFIG_SYS_I2C)
        if (bus >= 0)
                i2c_set_bus_num(bus);
@@ -207,63 +208,243 @@ int eeprom_write(unsigned dev_addr, unsigned offset,
        return ret;
 }
 
-static int do_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+static int parse_numeric_param(char *str)
 {
-       const char *const fmt =
-               "\nEEPROM @0x%lX %s: addr %08lx  off %04lx  count %ld ... ";
-       char * const *args = &argv[2];
-       int rcode;
-       ulong dev_addr, addr, off, cnt;
-       int bus_addr;
+       char *endptr;
+       int value = simple_strtol(str, &endptr, 16);
+
+       return (*endptr != '\0') ? -1 : value;
+}
+
+/**
+ * parse_i2c_bus_addr - parse the i2c bus and i2c devaddr parameters
+ *
+ * @i2c_bus:   address to store the i2c bus
+ * @i2c_addr:  address to store the device i2c address
+ * @argc:      count of command line arguments left to parse
+ * @argv:      command line arguments left to parse
+ * @argc_no_bus_addr:  argc value we expect to see when bus & addr aren't given
+ *
+ * @returns:   number of arguments parsed or CMD_RET_USAGE if error
+ */
+static int parse_i2c_bus_addr(int *i2c_bus, ulong *i2c_addr, int argc,
+                             char * const argv[], int argc_no_bus_addr)
+{
+       int argc_no_bus = argc_no_bus_addr + 1;
+       int argc_bus_addr = argc_no_bus_addr + 2;
 
-       switch (argc) {
 #ifdef CONFIG_SYS_DEF_EEPROM_ADDR
-       case 5:
-               bus_addr = -1;
-               dev_addr = CONFIG_SYS_DEF_EEPROM_ADDR;
-               break;
+       if (argc == argc_no_bus_addr) {
+               *i2c_bus = -1;
+               *i2c_addr = CONFIG_SYS_DEF_EEPROM_ADDR;
+
+               return 0;
+       }
 #endif
-       case 6:
-               bus_addr = -1;
-               dev_addr = simple_strtoul(*args++, NULL, 16);
-               break;
-       case 7:
-               bus_addr = simple_strtoul(*args++, NULL, 16);
-               dev_addr = simple_strtoul(*args++, NULL, 16);
-               break;
-       default:
-               return CMD_RET_USAGE;
+       if (argc == argc_no_bus) {
+               *i2c_bus = -1;
+               *i2c_addr = parse_numeric_param(argv[0]);
+
+               return 1;
        }
 
-       addr = simple_strtoul(*args++, NULL, 16);
-       off = simple_strtoul(*args++, NULL, 16);
-       cnt = simple_strtoul(*args++, NULL, 16);
+       if (argc == argc_bus_addr) {
+               *i2c_bus = parse_numeric_param(argv[0]);
+               *i2c_addr = parse_numeric_param(argv[1]);
+
+               return 2;
+       }
+
+       return CMD_RET_USAGE;
+}
+
+#ifdef CONFIG_CMD_EEPROM_LAYOUT
+
+__weak int eeprom_parse_layout_version(char *str)
+{
+       return LAYOUT_VERSION_UNRECOGNIZED;
+}
 
-       eeprom_init(bus_addr);
+static unsigned char eeprom_buf[CONFIG_SYS_EEPROM_SIZE];
 
-       if (strcmp(argv[1], "read") == 0) {
-               printf(fmt, dev_addr, argv[1], addr, off, cnt);
+#ifndef CONFIG_EEPROM_LAYOUT_HELP_STRING
+#define CONFIG_EEPROM_LAYOUT_HELP_STRING "<not defined>"
+#endif
 
-               rcode = eeprom_read(dev_addr, off, (uchar *)addr, cnt);
+#endif
+
+enum eeprom_action {
+       EEPROM_READ,
+       EEPROM_WRITE,
+       EEPROM_PRINT,
+       EEPROM_UPDATE,
+       EEPROM_ACTION_INVALID,
+};
+
+static enum eeprom_action parse_action(char *cmd)
+{
+       if (!strncmp(cmd, "read", 4))
+               return EEPROM_READ;
+       if (!strncmp(cmd, "write", 5))
+               return EEPROM_WRITE;
+#ifdef CONFIG_CMD_EEPROM_LAYOUT
+       if (!strncmp(cmd, "print", 5))
+               return EEPROM_PRINT;
+       if (!strncmp(cmd, "update", 6))
+               return EEPROM_UPDATE;
+#endif
+
+       return EEPROM_ACTION_INVALID;
+}
+
+static int eeprom_execute_command(enum eeprom_action action, int i2c_bus,
+                                 ulong i2c_addr, int layout_ver, char *key,
+                                 char *value, ulong addr, ulong off, ulong cnt)
+{
+       int rcode = 0;
+       const char *const fmt =
+               "\nEEPROM @0x%lX %s: addr %08lx  off %04lx  count %ld ... ";
+#ifdef CONFIG_CMD_EEPROM_LAYOUT
+       struct eeprom_layout layout;
+#endif
+
+       if (action == EEPROM_ACTION_INVALID)
+               return CMD_RET_USAGE;
+
+       eeprom_init(i2c_bus);
+       if (action == EEPROM_READ) {
+               printf(fmt, i2c_addr, "read", addr, off, cnt);
+
+               rcode = eeprom_read(i2c_addr, off, (uchar *)addr, cnt);
 
                puts("done\n");
                return rcode;
-       } else if (strcmp(argv[1], "write") == 0) {
-               printf(fmt, dev_addr, argv[1], addr, off, cnt);
+       } else if (action == EEPROM_WRITE) {
+               printf(fmt, i2c_addr, "write", addr, off, cnt);
 
-               rcode = eeprom_write(dev_addr, off, (uchar *)addr, cnt);
+               rcode = eeprom_write(i2c_addr, off, (uchar *)addr, cnt);
 
                puts("done\n");
                return rcode;
        }
 
-       return CMD_RET_USAGE;
+#ifdef CONFIG_CMD_EEPROM_LAYOUT
+       rcode = eeprom_read(i2c_addr, 0, eeprom_buf, CONFIG_SYS_EEPROM_SIZE);
+       if (rcode < 0)
+               return rcode;
+
+       eeprom_layout_setup(&layout, eeprom_buf, CONFIG_SYS_EEPROM_SIZE,
+                           layout_ver);
+
+       if (action == EEPROM_PRINT) {
+               layout.print(&layout);
+               return 0;
+       }
+
+       layout.update(&layout, key, value);
+
+       rcode = eeprom_write(i2c_addr, 0, layout.data, CONFIG_SYS_EEPROM_SIZE);
+#endif
+
+       return rcode;
+}
+
+#define NEXT_PARAM(argc, index)        { (argc)--; (index)++; }
+int do_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       int layout_ver = LAYOUT_VERSION_AUTODETECT;
+       enum eeprom_action action = EEPROM_ACTION_INVALID;
+       int i2c_bus = -1, index = 0;
+       ulong i2c_addr = -1, addr = 0, cnt = 0, off = 0;
+       int ret;
+       char *field_name = "";
+       char *field_value = "";
+
+       if (argc <= 1)
+               return CMD_RET_USAGE;
+
+       NEXT_PARAM(argc, index); /* Skip program name */
+
+       action = parse_action(argv[index]);
+       NEXT_PARAM(argc, index);
+
+       if (action == EEPROM_ACTION_INVALID)
+               return CMD_RET_USAGE;
+
+#ifdef CONFIG_CMD_EEPROM_LAYOUT
+       if (action == EEPROM_PRINT || action == EEPROM_UPDATE) {
+               if (!strcmp(argv[index], "-l")) {
+                       NEXT_PARAM(argc, index);
+                       layout_ver = eeprom_parse_layout_version(argv[index]);
+                       NEXT_PARAM(argc, index);
+               }
+       }
+#endif
+
+       switch (action) {
+       case EEPROM_READ:
+       case EEPROM_WRITE:
+               ret = parse_i2c_bus_addr(&i2c_bus, &i2c_addr, argc,
+                                        argv + index, 3);
+               break;
+       case EEPROM_PRINT:
+               ret = parse_i2c_bus_addr(&i2c_bus, &i2c_addr, argc,
+                                        argv + index, 0);
+               break;
+       case EEPROM_UPDATE:
+               ret = parse_i2c_bus_addr(&i2c_bus, &i2c_addr, argc,
+                                        argv + index, 2);
+               break;
+       default:
+               /* Get compiler to stop whining */
+               return CMD_RET_USAGE;
+       }
+
+       if (ret == CMD_RET_USAGE)
+               return ret;
+
+       while (ret--)
+               NEXT_PARAM(argc, index);
+
+       if (action == EEPROM_READ || action == EEPROM_WRITE) {
+               addr = parse_numeric_param(argv[index]);
+               NEXT_PARAM(argc, index);
+               off = parse_numeric_param(argv[index]);
+               NEXT_PARAM(argc, index);
+               cnt = parse_numeric_param(argv[index]);
+       }
+
+#ifdef CONFIG_CMD_EEPROM_LAYOUT
+       if (action == EEPROM_UPDATE) {
+               field_name = argv[index];
+               NEXT_PARAM(argc, index);
+               field_value = argv[index];
+               NEXT_PARAM(argc, index);
+       }
+#endif
+
+       return eeprom_execute_command(action, i2c_bus, i2c_addr, layout_ver,
+                                     field_name, field_value, addr, off, cnt);
 }
 
 U_BOOT_CMD(
-       eeprom, 7,      1,      do_eeprom,
+       eeprom, 8,      1,      do_eeprom,
        "EEPROM sub-system",
        "read  <bus> <devaddr> addr off cnt\n"
        "eeprom write <bus> <devaddr> addr off cnt\n"
        "       - read/write `cnt' bytes from `devaddr` EEPROM at offset `off'"
+#ifdef CONFIG_CMD_EEPROM_LAYOUT
+       "\n"
+       "eeprom print [-l <layout_version>] <bus> <devaddr>\n"
+       "       - Print layout fields and their data in human readable format\n"
+       "eeprom update [-l <layout_version>] <bus> <devaddr> field_name field_value\n"
+       "       - Update a specific eeprom field with new data.\n"
+       "         The new data must be written in the same human readable format as shown by the print command.\n"
+       "\n"
+       "LAYOUT VERSIONS\n"
+       "The -l option can be used to force the command to interpret the EEPROM data using the chosen layout.\n"
+       "If the -l option is omitted, the command will auto detect the layout based on the data in the EEPROM.\n"
+       "The values which can be provided with the -l option are:\n"
+       CONFIG_EEPROM_LAYOUT_HELP_STRING"\n"
+#endif
 )
index f9b26b7bbe49d66f1bb0c7d470fd65c315bfa887..0562d5cea46a5d50b1364451fd8b7701348551bb 100644 (file)
@@ -156,6 +156,9 @@ obj-y += fb_nand.o
 endif
 endif
 
+ifdef CONFIG_CMD_EEPROM_LAYOUT
+obj-y += eeprom/eeprom_field.o eeprom/eeprom_layout.o
+endif
 # We always have this since drivers/ddr/fs/interactive.c needs it
 obj-$(CONFIG_CMDLINE) += cli_simple.o
 
index b09f5249a902c7991986517dc91f0cfd447789f9..adc680e95938b7bb6b213f7c691e7de3cad69d1e 100644 (file)
@@ -1909,6 +1909,7 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
   * fulfill the user's request.
   */
   if (m == NULL) {
+    size_t extra, extra2;
     /*
      * Use bytes not nb, since mALLOc internally calls request2size too, and
      * each call increases the size to allocate, to account for the header.
@@ -1917,9 +1918,27 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
     /* Aligned -> return it */
     if ((((unsigned long)(m)) % alignment) == 0)
       return m;
-    /* Otherwise, fail */
+    /*
+     * Otherwise, try again, requesting enough extra space to be able to
+     * acquire alignment.
+     */
     fREe(m);
-    m = NULL;
+    /* Add in extra bytes to match misalignment of unexpanded allocation */
+    extra = alignment - (((unsigned long)(m)) % alignment);
+    m  = (char*)(mALLOc(bytes + extra));
+    /*
+     * m might not be the same as before. Validate that the previous value of
+     * extra still works for the current value of m.
+     * If (!m), extra2=alignment so 
+     */
+    if (m) {
+      extra2 = alignment - (((unsigned long)(m)) % alignment);
+      if (extra2 > extra) {
+        fREe(m);
+        m = NULL;
+      }
+    }
+    /* Fall through to original NULL check and chunk splitting logic */
   }
 
   if (m == NULL) return NULL; /* propagate failure */
diff --git a/common/eeprom/eeprom_field.c b/common/eeprom/eeprom_field.c
new file mode 100644 (file)
index 0000000..7f095a6
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * (C) Copyright 2009-2016 CompuLab, Ltd.
+ *
+ * Authors: Nikita Kiryanov <nikita@compulab.co.il>
+ *         Igor Grinberg <grinberg@compulab.co.il>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/string.h>
+#include <eeprom_field.h>
+
+static void __eeprom_field_print_bin(const struct eeprom_field *field,
+                                    char *delimiter, bool reverse)
+{
+       int i;
+       int from = reverse ? field->size - 1 : 0;
+       int to = reverse ? 0 : field->size - 1;
+
+       printf(PRINT_FIELD_SEGMENT, field->name);
+       for (i = from; i != to; reverse ? i-- : i++)
+               printf("%02x%s", field->buf[i], delimiter);
+
+       printf("%02x\n", field->buf[i]);
+}
+
+static int __eeprom_field_update_bin(struct eeprom_field *field,
+                                    const char *value, bool reverse)
+{
+       int len = strlen(value);
+       int k, j, i = reverse ? len - 1 : 0;
+       unsigned char byte;
+       char *endptr;
+
+       /* each two characters in the string fit in one byte */
+       if (len > field->size * 2)
+               return -1;
+
+       memset(field->buf, 0, field->size);
+
+       /* i - string iterator, j - buf iterator */
+       for (j = 0; j < field->size; j++) {
+               byte = 0;
+               char tmp[3] = { 0, 0, 0 };
+
+               if ((reverse && i < 0) || (!reverse && i >= len))
+                       break;
+
+               for (k = 0; k < 2; k++) {
+                       if (reverse && i == 0) {
+                               tmp[k] = value[i];
+                               break;
+                       }
+
+                       tmp[k] = value[reverse ? i - 1 + k : i + k];
+               }
+
+               byte = simple_strtoul(tmp, &endptr, 0);
+               if (*endptr != '\0' || byte < 0)
+                       return -1;
+
+               field->buf[j] = byte;
+               i = reverse ? i - 2 : i + 2;
+       }
+
+       return 0;
+}
+
+static int __eeprom_field_update_bin_delim(struct eeprom_field *field,
+                                          char *value, char *delimiter)
+{
+       int count = 0;
+       int i, val;
+       const char *tmp = value;
+       char *tok;
+       char *endptr;
+
+       tmp = strstr(tmp, delimiter);
+       while (tmp != NULL) {
+               count++;
+               tmp++;
+               tmp = strstr(tmp, delimiter);
+       }
+
+       if (count > field->size)
+               return -1;
+
+       tok = strtok(value, delimiter);
+       for (i = 0; tok && i < field->size; i++) {
+               val = simple_strtoul(tok, &endptr, 0);
+               if (*endptr != '\0')
+                       return -1;
+
+               /* here we assume that each tok is no more than byte long */
+               field->buf[i] = (unsigned char)val;
+               tok = strtok(NULL, delimiter);
+       }
+
+       return 0;
+}
+
+/**
+ * eeprom_field_print_bin() - print a field which contains binary data
+ *
+ * Treat the field data as simple binary data, and print it as two digit
+ * hexadecimal values.
+ * Sample output:
+ *      Field Name       0102030405060708090a
+ *
+ * @field:     an initialized field to print
+ */
+void eeprom_field_print_bin(const struct eeprom_field *field)
+{
+       __eeprom_field_print_bin(field, "", false);
+}
+
+/**
+ * eeprom_field_update_bin() - Update field with new data in binary form
+ *
+ * @field:     an initialized field
+ * @value:     a string of values (i.e. "10b234a")
+ */
+int eeprom_field_update_bin(struct eeprom_field *field, char *value)
+{
+       return __eeprom_field_update_bin(field, value, false);
+}
+
+/**
+ * eeprom_field_update_reserved() - Update reserved field with new data in
+ *                                 binary form
+ *
+ * @field:     an initialized field
+ * @value:     a space delimited string of byte values (i.e. "1 02 3 0x4")
+ */
+int eeprom_field_update_reserved(struct eeprom_field *field, char *value)
+{
+       return __eeprom_field_update_bin_delim(field, value, " ");
+}
+
+/**
+ * eeprom_field_print_bin_rev() - print a field which contains binary data in
+ *                               reverse order
+ *
+ * Treat the field data as simple binary data, and print it in reverse order
+ * as two digit hexadecimal values.
+ *
+ * Data in field:
+ *                      0102030405060708090a
+ * Sample output:
+ *      Field Name      0a090807060504030201
+ *
+ * @field:     an initialized field to print
+ */
+void eeprom_field_print_bin_rev(const struct eeprom_field *field)
+{
+       __eeprom_field_print_bin(field, "", true);
+}
+
+/**
+ * eeprom_field_update_bin_rev() - Update field with new data in binary form,
+ *                                storing it in reverse
+ *
+ * This function takes a string of byte values, and stores them
+ * in the field in the reverse order. i.e. if the input string was "1234",
+ * "3412" will be written to the field.
+ *
+ * @field:     an initialized field
+ * @value:     a string of byte values
+ */
+int eeprom_field_update_bin_rev(struct eeprom_field *field, char *value)
+{
+       return __eeprom_field_update_bin(field, value, true);
+}
+
+/**
+ * eeprom_field_print_mac_addr() - print a field which contains a mac address
+ *
+ * Treat the field data as simple binary data, and print it formatted as a MAC
+ * address.
+ * Sample output:
+ *      Field Name     01:02:03:04:05:06
+ *
+ * @field:     an initialized field to print
+ */
+void eeprom_field_print_mac(const struct eeprom_field *field)
+{
+       __eeprom_field_print_bin(field, ":", false);
+}
+
+/**
+ * eeprom_field_update_mac() - Update a mac address field which contains binary
+ *                            data
+ *
+ * @field:     an initialized field
+ * @value:     a colon delimited string of byte values (i.e. "1:02:3:ff")
+ */
+int eeprom_field_update_mac(struct eeprom_field *field, char *value)
+{
+       return __eeprom_field_update_bin_delim(field, value, ":");
+}
+
+/**
+ * eeprom_field_print_ascii() - print a field which contains ASCII data
+ * @field:     an initialized field to print
+ */
+void eeprom_field_print_ascii(const struct eeprom_field *field)
+{
+       char format[8];
+
+       sprintf(format, "%%.%ds\n", field->size);
+       printf(PRINT_FIELD_SEGMENT, field->name);
+       printf(format, field->buf);
+}
+
+/**
+ * eeprom_field_update_ascii() - Update field with new data in ASCII form
+ * @field:     an initialized field
+ * @value:     the new string data
+ *
+ * Returns 0 on success, -1 of failure (new string too long).
+ */
+int eeprom_field_update_ascii(struct eeprom_field *field, char *value)
+{
+       if (strlen(value) >= field->size) {
+               printf("%s: new data too long\n", field->name);
+               return -1;
+       }
+
+       strncpy((char *)field->buf, value, field->size - 1);
+       field->buf[field->size - 1] = '\0';
+
+       return 0;
+}
+
+/**
+ * eeprom_field_print_reserved() - print the "Reserved fields" field
+ *
+ * Print a notice that the following field_size bytes are reserved.
+ *
+ * Sample output:
+ *      Reserved fields              (64 bytes)
+ *
+ * @field:     an initialized field to print
+ */
+void eeprom_field_print_reserved(const struct eeprom_field *field)
+{
+       printf(PRINT_FIELD_SEGMENT, "Reserved fields\t");
+       printf("(%d bytes)\n", field->size);
+}
diff --git a/common/eeprom/eeprom_layout.c b/common/eeprom/eeprom_layout.c
new file mode 100644 (file)
index 0000000..c059233
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * (C) Copyright 2009-2016 CompuLab, Ltd.
+ *
+ * Authors: Nikita Kiryanov <nikita@compulab.co.il>
+ *         Igor Grinberg <grinberg@compulab.co.il>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/kernel.h>
+#include <eeprom_layout.h>
+#include <eeprom_field.h>
+
+#define NO_LAYOUT_FIELDS       "Unknown layout. Dumping raw data\n"
+
+struct eeprom_field layout_unknown[1] = {
+       { NO_LAYOUT_FIELDS, 256, NULL, eeprom_field_print_bin,
+                                      eeprom_field_update_bin },
+};
+
+/*
+ * eeprom_layout_detect() - detect layout based on the contents of the data.
+ * @data: Pointer to the data to be analyzed.
+ *
+ * Returns: the detected layout version.
+ */
+__weak int eeprom_layout_detect(unsigned char *data)
+{
+       return LAYOUT_VERSION_UNRECOGNIZED;
+}
+
+/*
+ * __eeprom_layout_assign() - set the layout fields
+ * @layout:            A pointer to an existing struct layout.
+ * @layout_version:    The version number of the desired layout
+ */
+__weak void __eeprom_layout_assign(struct eeprom_layout *layout,
+                                  int layout_version)
+{
+       layout->fields = layout_unknown;
+       layout->num_of_fields = ARRAY_SIZE(layout_unknown);
+}
+void eeprom_layout_assign(struct eeprom_layout *layout, int layout_version) \
+               __attribute__((weak, alias("__eeprom_layout_assign")));
+
+/*
+ * eeprom_layout_print() - print the layout and the data which is assigned to it
+ * @layout: A pointer to an existing struct layout.
+ */
+static void eeprom_layout_print(const struct eeprom_layout *layout)
+{
+       int i;
+       struct eeprom_field *fields = layout->fields;
+
+       for (i = 0; i < layout->num_of_fields; i++)
+               fields[i].print(&fields[i]);
+}
+
+/*
+ * eeprom_layout_update_field() - update a single field in the layout data.
+ * @layout:    A pointer to an existing struct layout.
+ * @field_name:        The name of the field to update.
+ * @new_data:  The new field data (a string. Format depends on the field)
+ *
+ * Returns: 0 on success, negative error value on failure.
+ */
+static int eeprom_layout_update_field(struct eeprom_layout *layout,
+                                     char *field_name, char *new_data)
+{
+       int i, err;
+       struct eeprom_field *fields = layout->fields;
+
+       if (new_data == NULL)
+               return 0;
+
+       if (field_name == NULL)
+               return -1;
+
+       for (i = 0; i < layout->num_of_fields; i++) {
+               if (fields[i].name == RESERVED_FIELDS ||
+                   strcmp(fields[i].name, field_name))
+                       continue;
+
+               err = fields[i].update(&fields[i], new_data);
+               if (err)
+                       printf("Invalid data for field %s\n", field_name);
+
+               return err;
+       }
+
+       printf("No such field '%s'\n", field_name);
+
+       return -1;
+}
+
+/*
+ * eeprom_layout_setup() - setup layout struct with the layout data and
+ *                        metadata as dictated by layout_version
+ * @layout:    A pointer to an existing struct layout.
+ * @buf:       A buffer initialized with the eeprom data.
+ * @buf_size:  Size of buf in bytes.
+ * @layout version: The version number of the layout.
+ */
+void eeprom_layout_setup(struct eeprom_layout *layout, unsigned char *buf,
+                        unsigned int buf_size, int layout_version)
+{
+       int i;
+
+       if (layout_version == LAYOUT_VERSION_AUTODETECT)
+               layout->layout_version = eeprom_layout_detect(buf);
+       else
+               layout->layout_version = layout_version;
+
+       eeprom_layout_assign(layout, layout_version);
+       layout->data = buf;
+       for (i = 0; i < layout->num_of_fields; i++) {
+               layout->fields[i].buf = buf;
+               buf += layout->fields[i].size;
+       }
+
+       layout->data_size = buf_size;
+       layout->print = eeprom_layout_print;
+       layout->update = eeprom_layout_update_field;
+}
index 25f8a1183d58de323bc4a66af34683db48471263..c86b7c6b1182e42e3febf94caaa3604628f809c6 100644 (file)
@@ -886,9 +886,9 @@ int fit_set_timestamp(void *fit, int noffset, time_t timestamp)
        ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t,
                                sizeof(uint32_t));
        if (ret) {
-               printf("Can't set '%s' property for '%s' node (%s)\n",
-                      FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL),
-                      fdt_strerror(ret));
+               debug("Can't set '%s' property for '%s' node (%s)\n",
+                     FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL),
+                     fdt_strerror(ret));
                return ret == -FDT_ERR_NOSPACE ? -ENOSPC : -1;
        }
 
index 338ea2f092b8dc9b250626efc91d44e68716e199..5b0d96925ed4436a64f171b82f8a56f5e9a778f7 100644 (file)
@@ -58,7 +58,7 @@ int spl_load_image_fat(struct blk_desc *block_dev,
                goto end;
 
        err = spl_parse_image_header(header);
-       if (err <= 0)
+       if (err)
                goto end;
 
        err = file_fat_read(filename, (u8 *)spl_image.load_addr, 0);
index 1a5c0275a70c161257b79554cbc09fe8ed04ec3f..26842ba285cea51eeae81c73fd290300f447d6ab 100644 (file)
@@ -39,8 +39,13 @@ static int spl_fit_select_fdt(const void *fdt, int images, int *fdt_offsetp)
             node >= 0;
             node = fdt_next_subnode(fdt, node)) {
                name = fdt_getprop(fdt, node, "description", &len);
-               if (!name)
+               if (!name) {
+#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
+                       printf("%s: Missing FDT description in DTB\n",
+                              __func__);
+#endif
                        return -EINVAL;
+               }
                if (board_fit_config_name_match(name))
                        continue;
 
index cc49dc976fedca30db1aa43a020df20aac2dc709..d46cd3bfa8b6726c8d399a329c5d6d31ce62ed5c 100644 (file)
@@ -2,6 +2,7 @@ CONFIG_ARM=y
 CONFIG_ARCH_MX6=y
 CONFIG_TARGET_PICO_IMX6UL=y
 CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/technexion/pico-imx6ul/imximage.cfg"
+CONFIG_HUSH_PARSER=y
 CONFIG_CMD_BOOTZ=y
 # CONFIG_CMD_IMLS is not set
 CONFIG_CMD_MEMTEST=y
index ee05f57f43670409297cca0df0f14c9ac1de5a00..55baad498ae52770959c0dbbf888493bec0a6572 100644 (file)
@@ -678,7 +678,7 @@ u32 ddr3_get_device_width(u32 cs)
        return (device_width == 0) ? 8 : 16;
 }
 
-float ddr3_get_device_size(u32 cs)
+static int ddr3_get_device_size(u32 cs)
 {
        u32 device_size_low, device_size_high, device_size;
        u32 data, cs_low_offset, cs_high_offset;
@@ -695,15 +695,15 @@ float ddr3_get_device_size(u32 cs)
 
        switch (device_size) {
        case 0:
-               return 2;
+               return 2048;
        case 2:
-               return 0.5;
+               return 512;
        case 3:
-               return 1;
+               return 1024;
        case 4:
-               return 4;
+               return 4096;
        case 5:
-               return 8;
+               return 8192;
        case 1:
        default:
                DEBUG_INIT_C("Error: Wrong device size of Cs: ", cs, 1);
@@ -711,13 +711,13 @@ float ddr3_get_device_size(u32 cs)
                 * Small value will give wrong emem size in
                 * ddr3_calc_mem_cs_size
                 */
-               return 0.01;
+               return 0;
        }
 }
 
 int ddr3_calc_mem_cs_size(u32 cs, u32 *cs_size)
 {
-       float cs_mem_size;
+       int cs_mem_size;
 
        /* Calculate in GiB */
        cs_mem_size = ((ddr3_get_bus_width() / ddr3_get_device_width(cs)) *
@@ -731,21 +731,12 @@ int ddr3_calc_mem_cs_size(u32 cs, u32 *cs_size)
         */
        cs_mem_size *= DDR_CONTROLLER_BUS_WIDTH_MULTIPLIER;
 
-       if (cs_mem_size == 0.125) {
-               *cs_size = 128 << 20;
-       } else if (cs_mem_size == 0.25) {
-               *cs_size = 256 << 20;
-       } else if (cs_mem_size == 0.5) {
-               *cs_size = 512 << 20;
-       } else if (cs_mem_size == 1) {
-               *cs_size = 1 << 30;
-       } else if (cs_mem_size == 2) {
-               *cs_size = 2 << 30;
-       } else {
+       if (!cs_mem_size || (cs_mem_size == 64) || (cs_mem_size == 4096)) {
                DEBUG_INIT_C("Error: Wrong Memory size of Cs: ", cs, 1);
                return MV_BAD_VALUE;
        }
 
+       *cs_size = cs_mem_size << 20;
        return MV_OK;
 }
 
index 2fe34c9a14a8e569a1989b5f87f5d5adef09f8e0..60e9d6e82552c8d18711a3667508d794545b880b 100644 (file)
@@ -35,6 +35,12 @@ DECLARE_GLOBAL_DATA_PTR;
 #define OMAP3_MCSPI4_BASE      0x480BA000
 #endif
 
+#define OMAP4_MCSPI_REG_OFFSET 0x100
+
+struct omap2_mcspi_platform_config {
+       unsigned int regs_offset;
+};
+
 /* per-register bitmasks */
 #define OMAP3_MCSPI_SYSCONFIG_SMARTIDLE (2 << 3)
 #define OMAP3_MCSPI_SYSCONFIG_ENAWAKEUP BIT(2)
@@ -623,7 +629,10 @@ static int omap3_spi_probe(struct udevice *dev)
        const void *blob = gd->fdt_blob;
        int node = dev->of_offset;
 
-       priv->regs = (struct mcspi *)dev_get_addr(dev);
+       struct omap2_mcspi_platform_config* data =
+               (struct omap2_mcspi_platform_config*)dev_get_driver_data(dev);
+
+       priv->regs = (struct mcspi *)(dev_get_addr(dev) + data->regs_offset);
        priv->pin_dir = fdtdec_get_uint(blob, node, "ti,pindir-d0-out-d1-in",
                                            MCSPI_PINDIR_D0_IN_D1_OUT);
        priv->wordlen = SPI_DEFAULT_WORDLEN;
@@ -662,9 +671,17 @@ static const struct dm_spi_ops omap3_spi_ops = {
         */
 };
 
+static struct omap2_mcspi_platform_config omap2_pdata = {
+       .regs_offset = 0,
+};
+
+static struct omap2_mcspi_platform_config omap4_pdata = {
+       .regs_offset = OMAP4_MCSPI_REG_OFFSET,
+};
+
 static const struct udevice_id omap3_spi_ids[] = {
-       { .compatible = "ti,omap2-mcspi" },
-       { .compatible = "ti,omap4-mcspi" },
+       { .compatible = "ti,omap2-mcspi", .data = (ulong)&omap2_pdata },
+       { .compatible = "ti,omap4-mcspi", .data = (ulong)&omap4_pdata },
        { }
 };
 
index d5850093539d20b076a0c02b0859bdef4d3c12f9..c56c1299c09f65e445e80fe1da6e12516b74834c 100644 (file)
@@ -62,6 +62,7 @@ config DEFAULT_DEVICE_TREE
 config OF_LIST
        string "List of device tree files to include for DT control"
        depends on SPL_LOAD_FIT
+       default DEFAULT_DEVICE_TREE
        help
          This option specifies a list of device tree files to use for DT
          control. These will be packaged into a FIT. At run-time, SPL will
index 9a125529c6de370bd9b9c077c5b849dde9cccae9..1f20ec3c6d2b555e1b748a959585e4d98e0bfb14 100644 (file)
 #define CONFIG_VIDEO_LOGO
 #define CONFIG_VIDEO_BMP_LOGO
 
+/* EEPROM */
+#define CONFIG_CMD_EEPROM
+#define CONFIG_ENV_EEPROM_IS_ON_I2C
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         1
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      4
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  5
+#define CONFIG_SYS_EEPROM_SIZE                 256
+
+#define CONFIG_CMD_EEPROM_LAYOUT
+#define CONFIG_EEPROM_LAYOUT_HELP_STRING "v2, v3"
+
 #endif /* __CONFIG_CM_FX6_H */
index c4f1d4f43889cc83fae6827f42ae5fa36fdc155c..6dbc9e980c9b1e2152561f57581acddc33559ec8 100644 (file)
 #define STATUS_LED_PERIOD              (CONFIG_SYS_HZ / 2)
 #define STATUS_LED_BOOT                        0
 
+/* EEPROM */
+#define CONFIG_CMD_EEPROM
+#define CONFIG_ENV_EEPROM_IS_ON_I2C
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         1
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      4
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  5
+#define CONFIG_SYS_EEPROM_SIZE                 256
+
+#define CONFIG_CMD_EEPROM_LAYOUT
+#define CONFIG_EEPROM_LAYOUT_HELP_STRING "v2, v3"
+
 #ifndef CONFIG_SPL_BUILD
 /*
  * Enable PCA9555 at I2C0-0x26.
index 5d581162cbe70d2553e96b1c046c3b2630fe4b6e..0fb853002c08abe3efd200bc476bde12f9a1441c 100644 (file)
 #define CONFIG_SYS_SPL_MALLOC_START    0x80208000
 #define CONFIG_SYS_SPL_MALLOC_SIZE     0x100000
 
+/* EEPROM */
+#define CONFIG_CMD_EEPROM
+#define CONFIG_ENV_EEPROM_IS_ON_I2C
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         1
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      4
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  5
+#define CONFIG_SYS_EEPROM_SIZE                 256
+
+#define CONFIG_CMD_EEPROM_LAYOUT
+#define CONFIG_EEPROM_LAYOUT_HELP_STRING "legacy, v1, v2, v3"
+
 #endif /* __CONFIG_H */
index 7cedb6736dae610f1454c7852bf6c4c6faa2a7a4..7c087c6f5d1ba46cb9780ec5ef29a0739f4bb41d 100644 (file)
 
 #define CONFIG_OMAP3_SPI
 
+/* EEPROM */
+#define CONFIG_CMD_EEPROM
+#define CONFIG_ENV_EEPROM_IS_ON_I2C
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         1
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      4
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  5
+#define CONFIG_SYS_EEPROM_SIZE                 256
+
+#define CONFIG_CMD_EEPROM_LAYOUT
+#define CONFIG_EEPROM_LAYOUT_HELP_STRING "v1, v2, v3"
+
 #endif /* __CONFIG_H */
index ee818ede267eedab950066c5753a0536ad78fe9d..c2dbd31803a20e427d8b283d2eb17c584f5b4e7a 100644 (file)
 #define CONFIG_SPL_I2C_SUPPORT
 #define CONFIG_SPL_POWER_SUPPORT
 
+/* EEPROM */
+#define CONFIG_CMD_EEPROM
+#define CONFIG_ENV_EEPROM_IS_ON_I2C
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         1
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      4
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  5
+#define CONFIG_SYS_EEPROM_SIZE                 256
+
+#define CONFIG_CMD_EEPROM_LAYOUT
+#define CONFIG_EEPROM_LAYOUT_HELP_STRING "v2, v3"
+
 #endif /* __CONFIG_CM_T43_H */
index ac6103c0665ef60561ef5e64bf29a55f093ee852..ff63d7a7756830fb5695945eda3a13a122630e3f 100644 (file)
 
 /* Enabled commands */
 
+/* EEPROM */
+#define CONFIG_CMD_EEPROM
+#define CONFIG_ENV_EEPROM_IS_ON_I2C
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN         1
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS      4
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS  5
+#define CONFIG_SYS_EEPROM_SIZE                 256
+
+#define CONFIG_CMD_EEPROM_LAYOUT
+#define CONFIG_EEPROM_LAYOUT_HELP_STRING "v2, v3"
+
 /* USB Networking options */
 #define CONFIG_USB_HOST_ETHER
 #define CONFIG_USB_ETHER_SMSC95XX
index 1caa8588560d8d9bb89dbe9889d459d57711594a..dda70c5c818fcf1b83c2f4647baff5c46de285b9 100644 (file)
@@ -64,6 +64,7 @@
 #define PHY_ANEG_TIMEOUT       8000    /* PHY needs a longer aneg time */
 
 #define CONFIG_SYS_CONSOLE_INFO_QUIET  /* don't print console @ startup */
+#define CONFIG_ZERO_BOOTDELAY_CHECK    /* check for keypress on bootdelay==0 */
 #define CONFIG_SYS_ALT_MEMTEST
 #define CONFIG_PREBOOT
 
diff --git a/include/eeprom_field.h b/include/eeprom_field.h
new file mode 100644 (file)
index 0000000..94e259f
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright 2009-2016 CompuLab, Ltd.
+ *
+ * Authors: Nikita Kiryanov <nikita@compulab.co.il>
+ *         Igor Grinberg <grinberg@compulab.co.il>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _FIELD_
+#define _FIELD_
+
+#define PRINT_FIELD_SEGMENT    "%-30s"
+
+struct eeprom_field {
+       char *name;
+       int size;
+       unsigned char *buf;
+
+       void (*print)(const struct eeprom_field *eeprom_field);
+       int (*update)(struct eeprom_field *eeprom_field, char *value);
+};
+
+void eeprom_field_print_bin(const struct eeprom_field *field);
+int eeprom_field_update_bin(struct eeprom_field *field, char *value);
+
+void eeprom_field_print_bin_rev(const struct eeprom_field *field);
+int eeprom_field_update_bin_rev(struct eeprom_field *field, char *value);
+
+void eeprom_field_print_mac(const struct eeprom_field *field);
+int eeprom_field_update_mac(struct eeprom_field *field, char *value);
+
+void eeprom_field_print_ascii(const struct eeprom_field *field);
+int eeprom_field_update_ascii(struct eeprom_field *field, char *value);
+
+void eeprom_field_print_reserved(const struct eeprom_field *field);
+int eeprom_field_update_reserved(struct eeprom_field *field, char *value);
+
+#endif
diff --git a/include/eeprom_layout.h b/include/eeprom_layout.h
new file mode 100644 (file)
index 0000000..459b99d
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * (C) Copyright 2009-2016 CompuLab, Ltd.
+ *
+ * Authors: Nikita Kiryanov <nikita@compulab.co.il>
+ *         Igor Grinberg <grinberg@compulab.co.il>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _LAYOUT_
+#define _LAYOUT_
+
+#define RESERVED_FIELDS                        NULL
+#define LAYOUT_VERSION_UNRECOGNIZED    -1
+#define LAYOUT_VERSION_AUTODETECT      -2
+
+struct eeprom_layout {
+       struct eeprom_field *fields;
+       int num_of_fields;
+       int layout_version;
+       unsigned char *data;
+       int data_size;
+       void (*print)(const struct eeprom_layout *eeprom_layout);
+       int (*update)(struct eeprom_layout *eeprom_layout, char *field_name,
+                     char *new_data);
+};
+
+void eeprom_layout_setup(struct eeprom_layout *layout, unsigned char *buf,
+                        unsigned int buf_size, int layout_version);
+__weak void __eeprom_layout_assign(struct eeprom_layout *layout,
+                                  int layout_version);
+
+#endif
index e8e8c7756deb09e00ec7cb48e3dd0ad628e3c6cc..9bd0de2490748730e750dbf8797a3ae19c431c95 100644 (file)
@@ -296,7 +296,11 @@ static void do_config_file(const char *filename)
                perror(filename);
                exit(2);
        }
-       fstat(fd, &st);
+       if (fstat(fd, &st) < 0) {
+               fprintf(stderr, "fixdep: error fstat'ing config file: ");
+               perror(filename);
+               exit(2);
+       }
        if (st.st_size == 0) {
                close(fd);
                return;
index 916ab964d553e2d214be17a58f1f8f86b7a36ffe..08d191d9f894a6b86afd867de33ec4026c2286f2 100644 (file)
@@ -51,7 +51,8 @@ int imagetool_verify_print_header(
                                 * successful
                                 */
                                if ((*curr)->print_header) {
-                                       (*curr)->print_header(ptr);
+                                       if (!params->quiet)
+                                               (*curr)->print_header(ptr);
                                } else {
                                        fprintf(stderr,
                                                "%s: print_header undefined for %s\n",
index 24f8f4b2f6352fbfb6e86388236be1fb0f501e3c..a3ed0f43d6afa21caa6d8755536b17d8a3f27ba2 100644 (file)
@@ -73,6 +73,7 @@ struct image_tool_params {
        struct content_info *content_head;      /* List of files to include */
        struct content_info *content_tail;
        bool external_data;     /* Store data outside the FIT */
+       bool quiet;             /* Don't output text in normal operation */
 };
 
 /*
index 93d1c16c7ce0e8afa580ccfb84bc8e454b163f54..aefe22f19b219a7d339dbfdc6f92ca1afe8b1831 100644 (file)
@@ -136,7 +136,7 @@ static void process_args(int argc, char **argv)
        int opt;
 
        while ((opt = getopt(argc, argv,
-                            "a:A:b:cC:d:D:e:Ef:Fk:K:ln:O:rR:sT:vVx")) != -1) {
+                            "a:A:b:cC:d:D:e:Ef:Fk:K:ln:O:rR:qsT:vVx")) != -1) {
                switch (opt) {
                case 'a':
                        params.addr = strtoull(optarg, &ptr, 16);
@@ -216,6 +216,9 @@ static void process_args(int argc, char **argv)
                        if (params.os < 0)
                                usage("Invalid operating system");
                        break;
+               case 'q':
+                       params.quiet = 1;
+                       break;
                case 'r':
                        params.require_keys = 1;
                        break;