[PATCH 2/2] arm64: imx8mp: Read item and serial number from EEPROM ID page on DH i.MX8MP DHCOM
Christoph Niedermaier
cniedermaier at dh-electronics.com
Thu Oct 10 15:23:37 CEST 2024
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 <cniedermaier at dh-electronics.com>
---
Cc: "NXP i.MX U-Boot Team" <uboot-imx at nxp.com>
Cc: Marek Vasut <marex at denx.de>
Cc: Fabio Estevam <festevam at gmail.com>
Cc: Stefano Babic <sbabic at denx.de>
Cc: Tom Rini <trini at konsulko.com>
Cc: u-boot at 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
More information about the U-Boot
mailing list