[PATCH 3/3] xilinx: board: Add support for additional card detection

Michal Simek michal.simek at xilinx.com
Wed Oct 14 15:55:50 CEST 2020


The most of Xilinx evaluation boards have FMC connectors which contain
small eeprom for card identification. That's why read content of eeprom and
record it.
Also generate cardX_ variables for easier script handling.

Signed-off-by: Michal Simek <michal.simek at xilinx.com>
---

 board/xilinx/common/board.c | 85 ++++++++++++++++++++++++++-----------
 1 file changed, 61 insertions(+), 24 deletions(-)

diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c
index 0aed84546d41..0d0c21ca3d40 100644
--- a/board/xilinx/common/board.c
+++ b/board/xilinx/common/board.c
@@ -62,7 +62,8 @@ struct xilinx_board_description {
 	u8 mac_addr[EEPROM_HDR_NO_OF_MAC_ADDR][EEPROM_HDR_ETH_ALEN + 1];
 };
 
-static struct xilinx_board_description *board_info;
+static int highest_id = -1;
+static struct xilinx_board_description **board_info;
 
 #define XILINX_I2C_DETECTION_BITS	8
 
@@ -191,15 +192,16 @@ static int xilinx_read_eeprom_single(char *name,
 
 __maybe_unused int xilinx_read_eeprom(void)
 {
-	int id, highest_id;
+	int id, ret;
 	char name_buf[8]; /* 8 bytes should be enough for nvmem+number */
+	struct xilinx_board_description *desc;
 
 	highest_id = dev_read_alias_highest_id("nvmem");
 	/* No nvmem aliases present */
 	if (highest_id < 0)
 		return -EINVAL;
 
-	board_info = calloc(1, sizeof(*board_info));
+	board_info = calloc(1, sizeof(desc) * highest_id);
 	if (!board_info)
 		return -ENOMEM;
 
@@ -209,12 +211,28 @@ __maybe_unused int xilinx_read_eeprom(void)
 	for (id = 0; id <= highest_id; id++) {
 		snprintf(name_buf, sizeof(name_buf), "nvmem%d", id);
 
+		/* Alloc structure */
+		desc = board_info[id];
+		if (!desc) {
+			desc = calloc(1, sizeof(*desc));
+			if (!desc)
+				return -ENOMEM;
+
+			board_info[id] = desc;
+		}
+
 		/* Ignoring return value for supporting multiple chips */
-		xilinx_read_eeprom_single(name_buf, board_info);
+		ret = xilinx_read_eeprom_single(name_buf, desc);
+		if (ret) {
+			free(desc);
+			board_info[id] = NULL;
+		}
 	}
 
-	if (board_info->header != EEPROM_HEADER_MAGIC)
-		free(board_info);
+	/*
+	 * Consider to clean board_info structure when board/cards are not
+	 * detected.
+	 */
 
 	return 0;
 }
@@ -253,10 +271,23 @@ void *board_fdt_blob_setup(void)
 }
 #endif
 
+static int env_set_by_index(const char *name, int index, char *data)
+{
+	char var[32];
+
+	if (!index)
+		sprintf(var, "board_%s", name);
+	else
+		sprintf(var, "card%d_%s", index, name);
+
+	return env_set(var, data);
+}
+
 int board_late_init_xilinx(void)
 {
 	u32 ret = 0;
-	int i;
+	int i, id, macid = 0;
+	struct xilinx_board_description *desc;
 	phys_size_t bootm_size = gd->ram_size;
 
 	if (CONFIG_IS_ENABLED(ARCH_ZYNQ))
@@ -267,27 +298,33 @@ int board_late_init_xilinx(void)
 	ret |= env_set_addr("bootm_low", (void *)gd->ram_base);
 	ret |= env_set_addr("bootm_size", (void *)bootm_size);
 
-	if (board_info) {
-		if (board_info->manufacturer)
-			ret |= env_set("manufacturer",
-				       board_info->manufacturer);
-		if (board_info->name)
-			ret |= env_set("board_name", board_info->name);
-		if (board_info->revision)
-			ret |= env_set("board_rev", board_info->revision);
-		if (board_info->serial)
-			ret |= env_set("board_serial", board_info->serial);
-
-		for (i = 0; i < EEPROM_HDR_NO_OF_MAC_ADDR; i++) {
-			if (!board_info->mac_addr[i])
-				continue;
+	for (id = 0; id <= highest_id; id++) {
+		desc = board_info[id];
+		if (desc && desc->header == EEPROM_HEADER_MAGIC) {
+			if (desc->manufacturer[0])
+				ret |= env_set_by_index("manufacturer", id,
+							desc->manufacturer);
+			if (desc->name[0])
+				ret |= env_set_by_index("name", id,
+							desc->name);
+			if (desc->revision[0])
+				ret |= env_set_by_index("rev", id,
+							desc->revision);
+			if (desc->serial[0])
+				ret |= env_set_by_index("serial", id,
+							desc->serial);
 
 			if (!CONFIG_IS_ENABLED(NET))
 				continue;
 
-			if (is_valid_ethaddr((const u8 *)board_info->mac_addr[i]))
-				ret |= eth_env_set_enetaddr_by_index("eth", i,
-						board_info->mac_addr[i]);
+			for (i = 0; i < EEPROM_HDR_NO_OF_MAC_ADDR; i++) {
+				if (!desc->mac_addr[i])
+					continue;
+
+				if (is_valid_ethaddr((const u8 *)desc->mac_addr[i]))
+					ret |= eth_env_set_enetaddr_by_index("eth",
+							macid++, desc->mac_addr[i]);
+			}
 		}
 	}
 
-- 
2.28.0



More information about the U-Boot mailing list