[PATCH 1/5] imx8mn-var-som: read and print SoM infos from eeprom on startup

Hugo Villeneuve hugo at hugovil.com
Mon May 1 22:01:17 CEST 2023


From: Hugo Villeneuve <hvilleneuve at dimonoff.com>

Enable support to read and display configuration/manufacturing infos
from 4Kbit EEPROM located on SOM board.

Note: CONFIG_DISPLAY_BOARDINFO is automatically selected for ARM arch.

Signed-off-by: Hugo Villeneuve <hvilleneuve at dimonoff.com>
---
 .../dts/imx8mn-var-som-symphony-u-boot.dtsi   |   4 +
 arch/arm/dts/imx8mn-var-som.dtsi              |  10 ++
 arch/arm/mach-imx/imx8m/Kconfig               |   2 +
 .../variscite/imx8mn_var_som/imx8mn_var_som.c | 134 ++++++++++++++++++
 configs/imx8mn_var_som_defconfig              |   1 +
 5 files changed, 151 insertions(+)

diff --git a/arch/arm/dts/imx8mn-var-som-symphony-u-boot.dtsi b/arch/arm/dts/imx8mn-var-som-symphony-u-boot.dtsi
index af80aaea0b..7272fc2b4c 100644
--- a/arch/arm/dts/imx8mn-var-som-symphony-u-boot.dtsi
+++ b/arch/arm/dts/imx8mn-var-som-symphony-u-boot.dtsi
@@ -68,3 +68,7 @@
 &usdhc3 {
 	bootph-pre-ram;
 };
+
+&eeprom_som {
+	bootph-pre-ram;
+};
diff --git a/arch/arm/dts/imx8mn-var-som.dtsi b/arch/arm/dts/imx8mn-var-som.dtsi
index 87b5e23c76..dea9eff3f0 100644
--- a/arch/arm/dts/imx8mn-var-som.dtsi
+++ b/arch/arm/dts/imx8mn-var-som.dtsi
@@ -11,6 +11,10 @@
 	model = "Variscite VAR-SOM-MX8MN module";
 	compatible = "variscite,var-som-mx8mn", "fsl,imx8mn";
 
+	aliases {
+		eeprom-som = &eeprom_som;
+	};
+
 	chosen {
 		stdout-path = &uart4;
 	};
@@ -222,6 +226,12 @@
 			};
 		};
 	};
+
+	eeprom_som: eeprom at 52 {
+		compatible = "atmel,24c04";
+		reg = <0x52>;
+		pagesize = <16>;
+	};
 };
 
 &i2c3 {
diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig
index dc51f971d4..ec0abb92b8 100644
--- a/arch/arm/mach-imx/imx8m/Kconfig
+++ b/arch/arm/mach-imx/imx8m/Kconfig
@@ -239,6 +239,8 @@ config TARGET_IMX8MN_VAR_SOM
 	select IMX8MN
 	select SUPPORT_SPL
 	select IMX8M_DDR4
+	select MISC
+	select I2C_EEPROM
 
 config TARGET_KONTRON_PITX_IMX8M
 	bool "Support Kontron pITX-imx8m"
diff --git a/board/variscite/imx8mn_var_som/imx8mn_var_som.c b/board/variscite/imx8mn_var_som/imx8mn_var_som.c
index d40f4d0176..a89457e8f5 100644
--- a/board/variscite/imx8mn_var_som/imx8mn_var_som.c
+++ b/board/variscite/imx8mn_var_som/imx8mn_var_som.c
@@ -1,11 +1,49 @@
 // SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright 2021 Collabora Ltd.
+ * Copyright 2018-2020 Variscite Ltd.
+ * Copyright 2023 DimOnOff Inc.
  */
 
 #include <common.h>
+#include <dm.h>
 #include <env.h>
+#include <fdtdec.h>
+#include <fdt_support.h>
+#include <i2c_eeprom.h>
+#include <malloc.h>
 #include <asm/io.h>
+#include <asm/global_data.h>
+#include <linux/libfdt.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Optional SOM features flags. */
+#define VAR_EEPROM_F_WIFI		BIT(0)
+#define VAR_EEPROM_F_ETH		BIT(1) /* Ethernet PHY on SOM. */
+#define VAR_EEPROM_F_AUDIO		BIT(2)
+#define VAR_EEPROM_F_MX8M_LVDS		BIT(3) /* i.MX8MM, i.MX8MN, i.MX8MQ only */
+#define VAR_EEPROM_F_MX8Q_SOC_ID	BIT(3) /* 0 = i.MX8QM, 1 = i.MX8QP */
+#define VAR_EEPROM_F_NAND		BIT(4)
+
+#define VAR_IMX8_EEPROM_MAGIC	0x384D /* "8M" */
+
+/* Number of DRAM adjustment tables. */
+#define DRAM_TABLES_NUM 7
+
+struct var_imx8_eeprom_info {
+	u16 magic;
+	u8 partnumber[3];         /* Part number */
+	u8 assembly[10];          /* Assembly number */
+	u8 date[9];               /* Build date */
+	u8 mac[6];                /* MAC address */
+	u8 somrev;
+	u8 eeprom_version;
+	u8 features;              /* SOM features */
+	u8 dramsize;              /* DRAM size */
+	u8 off[DRAM_TABLES_NUM + 1]; /* DRAM table offsets */
+	u8 partnumber2[5];        /* Part number 2 */
+} __packed;
 
 static void setup_fec(void)
 {
@@ -28,3 +66,99 @@ int board_mmc_get_env_dev(int devno)
 {
 	return devno;
 }
+
+#if !defined(CONFIG_SPL_BUILD)
+
+#if defined(CONFIG_DISPLAY_BOARDINFO)
+
+static void display_som_infos(struct var_imx8_eeprom_info *info)
+{
+	char partnumber[sizeof(info->partnumber) +
+			sizeof(info->partnumber2) + 1];
+	char assembly[sizeof(info->assembly) + 1];
+	char date[sizeof(info->date) + 1];
+
+	/* Read first part of P/N. */
+	memcpy(partnumber, info->partnumber, sizeof(info->partnumber));
+
+	/* Read second part of P/N. */
+	if (info->eeprom_version >= 3)
+		memcpy(partnumber + sizeof(info->partnumber), info->partnumber2,
+		       sizeof(info->partnumber2));
+
+	memcpy(assembly, info->assembly, sizeof(info->assembly));
+	memcpy(date, info->date, sizeof(info->date));
+
+	/* Make sure strings are null terminated. */
+	partnumber[sizeof(partnumber) - 1] = '\0';
+	assembly[sizeof(assembly) - 1] = '\0';
+	date[sizeof(date) - 1] = '\0';
+
+	printf("SOM board: P/N: %s, Assy: %s, Date: %s\n"
+	       "           Wifi: %s, EthPhy: %s, Rev: %d\n",
+	       partnumber, assembly, date,
+	       info->features & VAR_EEPROM_F_WIFI ? "yes" : "no",
+	       info->features & VAR_EEPROM_F_ETH ? "yes" : "no",
+	       info->somrev);
+}
+
+static int var_read_som_eeprom(struct var_imx8_eeprom_info *info)
+{
+	const char *path = "eeprom-som";
+	struct udevice *dev;
+	int ret, off;
+
+	off = fdt_path_offset(gd->fdt_blob, path);
+	if (off < 0) {
+		pr_err("%s: fdt_path_offset() failed: %d\n", __func__, off);
+		return off;
+	}
+
+	ret = uclass_get_device_by_of_offset(UCLASS_I2C_EEPROM, off, &dev);
+	if (ret) {
+		pr_err("%s: uclass_get_device_by_of_offset() failed: %d\n",
+		       __func__, ret);
+		return ret;
+	}
+
+	ret = i2c_eeprom_read(dev, 0, (uint8_t *)info,
+			      sizeof(struct var_imx8_eeprom_info));
+	if (ret) {
+		pr_err("%s: i2c_eeprom_read() failed: %d\n", __func__, ret);
+		return ret;
+	}
+
+	if (htons(info->magic) != VAR_IMX8_EEPROM_MAGIC) {
+		/* Do not fail if the content is invalid */
+		pr_err("Board: Invalid board info magic: 0x%08x, expected 0x%08x\n",
+		       htons(info->magic), VAR_IMX8_EEPROM_MAGIC);
+	}
+
+	return 0;
+}
+
+int checkboard(void)
+{
+	int rc;
+	struct var_imx8_eeprom_info *info;
+
+	info = malloc(sizeof(struct var_imx8_eeprom_info));
+	if (!info)
+		return -ENOMEM;
+
+	rc = var_read_som_eeprom(info);
+	if (rc)
+		return rc;
+
+	display_som_infos(info);
+
+#if defined(CONFIG_BOARD_TYPES)
+	gd->board_type = info->features;
+#endif /* CONFIG_BOARD_TYPES */
+
+	return 0;
+}
+
+#endif /* CONFIG_DISPLAY_BOARDINFO */
+
+#endif /* CONFIG_SPL_BUILD */
diff --git a/configs/imx8mn_var_som_defconfig b/configs/imx8mn_var_som_defconfig
index f02cbab839..bb1245bd35 100644
--- a/configs/imx8mn_var_som_defconfig
+++ b/configs/imx8mn_var_som_defconfig
@@ -34,6 +34,7 @@ CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
 CONFIG_SPL_BSS_START_ADDR=0x950000
 CONFIG_SPL_BSS_MAX_SIZE=0x2000
 CONFIG_SPL_BOARD_INIT=y
+CONFIG_BOARD_TYPES=y
 CONFIG_SPL_BOOTROM_SUPPORT=y
 # CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
 CONFIG_SYS_SPL_MALLOC=y
-- 
2.30.2



More information about the U-Boot mailing list