The new i.MX8M Plus DHCOM rev.200 is populated with M24C32-D EEPROM which contains additional write-lockable page called ID page, which is populated with a structure containing the item and serial number.
Extend the support for parsing the item and serial number of the EEPROM ID page. Write the item and serial number to the U-Boot environment if the aren't there. If the environment is already there compare it with the one from the EEPROM ID page and output a warning if it differs. Signed-off-by: Christoph Niedermaier <cniederma...@dh-electronics.com> --- Cc: "NXP i.MX U-Boot Team" <uboot-...@nxp.com> Cc: Marek Vasut <ma...@denx.de> Cc: Fabio Estevam <feste...@gmail.com> Cc: Stefano Babic <sba...@denx.de> Cc: Tom Rini <tr...@konsulko.com> Cc: u-b...@dh-electronics.com --- board/dhelectronics/common/dh_common.c | 51 ++++++++++++++++++ board/dhelectronics/common/dh_common.h | 2 + .../dh_imx8mp/imx8mp_dhcom_pdk2.c | 53 +++++++++++++++++++ 3 files changed, 106 insertions(+) diff --git a/board/dhelectronics/common/dh_common.c b/board/dhelectronics/common/dh_common.c index 8ea70fc984..4c31b32e0c 100644 --- a/board/dhelectronics/common/dh_common.c +++ b/board/dhelectronics/common/dh_common.c @@ -11,6 +11,23 @@ #include "dh_common.h" +/* DH item: Vendor coding */ +#define ITEM_PREFIX_NXP 0x01 +#define ITEM_PREFIX_NXP_CHR 'I' +#define ITEM_PREFIX_ST 0x02 +#define ITEM_PREFIX_ST_CHR 'S' + +/* + * DH item: Finished state coding + * Bit = 0 means half finished + * Prefix is 'H' + * Bit = 1 means finished with a customer image flashed + * Prefix is 'F' + */ +#define ITEM_PREFIX_FIN_BIT BIT(7) +#define ITEM_PREFIX_FIN_HALF_CHR 'H' +#define ITEM_PREFIX_FIN_FLASHED_CHR 'F' + struct eeprom_id_page { u8 id[3]; /* Identifier 'D', 'H', 'E' - 'D' is at index 0 */ u8 version; /* 0x10 -- Version 1.0 */ @@ -54,6 +71,7 @@ int dh_get_value_from_eeprom_id_page(enum eip_request_values request, u8 *data, ofnode node; u16 c16; u8 c8; + char soc; eipp = (struct eeprom_id_page *)eipa; @@ -136,6 +154,39 @@ int dh_get_value_from_eeprom_id_page(enum eip_request_values request, u8 *data, else return -EINVAL; break; + case ITEM_NUMBER: + if (data_len >= 8) { /* String with 7 characters + string termination */ + switch (eipp->item_prefix & 0xf) { + case ITEM_PREFIX_NXP: + soc = ITEM_PREFIX_NXP_CHR; + break; + case ITEM_PREFIX_ST: + soc = ITEM_PREFIX_ST_CHR; + break; + default: + return -EINVAL; + } + snprintf(data, data_len, "%c%c%05d", + (eipp->item_prefix & ITEM_PREFIX_FIN_BIT) ? + ITEM_PREFIX_FIN_FLASHED_CHR : ITEM_PREFIX_FIN_HALF_CHR, + soc, (eipp->item_num[0] << 16) | (eipp->item_num[1] << 8) + | eipp->item_num[2]); + } else { + return -EINVAL; + } + break; + case SN: + /* + * data_len must be greater than the size of eipp->serial, + * because there is a string termination needed. + */ + if (data_len > sizeof(eipp->serial)) { + data[sizeof(eipp->serial)] = 0; + memcpy(data, eipp->serial, sizeof(eipp->serial)); + } else { + return -EINVAL; + } + break; default: return -EINVAL; } diff --git a/board/dhelectronics/common/dh_common.h b/board/dhelectronics/common/dh_common.h index 4c22ece435..1baa45e340 100644 --- a/board/dhelectronics/common/dh_common.h +++ b/board/dhelectronics/common/dh_common.h @@ -6,6 +6,8 @@ enum eip_request_values { MAC0, MAC1, + ITEM_NUMBER, + SN, }; /* diff --git a/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c b/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c index 9a8f09fcd4..8970c8fc2d 100644 --- a/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c +++ b/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c @@ -116,6 +116,56 @@ int dh_setup_mac_address(void) return ret; } +void dh_add_item_number_and_serial_to_env(void) +{ + char item_number[8]; /* String with 7 characters + string termination */ + char *item_number_env; + char serial[10]; /* String with 9 characters + string termination */ + char *serial_env; + int ret; + + ret = dh_get_value_from_eeprom_id_page(ITEM_NUMBER, item_number, sizeof(item_number), + "eeprom0"); + if (ret) { + /* + * The function only returns the value -ENOENT for SoM rev.100, because + * the EEPROM ID page isn't available there. Therefore the output makes + * no sense and will be suppressed here. + */ + if (ret != -ENOENT) + printf("%s: Unable to get item number form EEPROM ID page! ret = %d\n", + __func__, ret); + } else { + item_number_env = env_get("vendor_item_number"); + if (!item_number_env) + env_set("vendor_item_number", item_number); + else + if (strcmp(item_number_env, item_number) != 0) + printf("Warning: Environment vendor_item_number differs from EEPROM ID page value (%s != %s)\n", + item_number_env, item_number); + } + + ret = dh_get_value_from_eeprom_id_page(SN, serial, sizeof(serial), "eeprom0"); + if (ret) { + /* + * The function only returns the value -ENOENT for SoM rev.100, because + * the EEPROM ID page isn't available there. Therefore the output makes + * no sense and will be suppressed here. + */ + if (ret != -ENOENT) + printf("%s: Unable to get serial form EEPROM ID page! ret = %d\n", + __func__, ret); + } else { + serial_env = env_get("SN"); + if (!serial_env) + env_set("SN", serial); + else + if (strcmp(serial_env, serial) != 0) + printf("Warning: Environment SN differs from EEPROM ID page value (%s != %s)\n", + serial_env, serial); + } +} + int board_init(void) { return 0; @@ -124,6 +174,9 @@ int board_init(void) int board_late_init(void) { dh_setup_mac_address(); + + dh_add_item_number_and_serial_to_env(); + return 0; } -- 2.30.2