diff options
author | Michal Simek <michal.simek@xilinx.com> | 2020-08-03 16:14:23 +0200 |
---|---|---|
committer | Michal Simek <michal.simek@xilinx.com> | 2020-10-27 08:13:32 +0100 |
commit | f149b39ca3afbe3645f3e50ebd8a1e8af9a445a3 (patch) | |
tree | 47d215a89ac79634e1255138196cf4241aa04f9a /board | |
parent | 4489e0aa9b5548a2ad1beb2853bbc0db56cf1db5 (diff) | |
download | u-boot-f149b39ca3afbe3645f3e50ebd8a1e8af9a445a3.zip u-boot-f149b39ca3afbe3645f3e50ebd8a1e8af9a445a3.tar.gz u-boot-f149b39ca3afbe3645f3e50ebd8a1e8af9a445a3.tar.bz2 |
xilinx: board: Add FRU decoder support
FMC cards are using FRU format for card identification. That's why add
support for this format.
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Diffstat (limited to 'board')
-rw-r--r-- | board/xilinx/common/board.c | 83 |
1 files changed, 82 insertions, 1 deletions
diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index 410b4cd..821ee83 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -17,6 +17,8 @@ #include <i2c_eeprom.h> #include <net.h> +#include "fru.h" + #if defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET) int zynq_board_read_rom_ethaddr(unsigned char *ethaddr) { @@ -65,7 +67,7 @@ struct xilinx_board_description { static int highest_id = -1; static struct xilinx_board_description **board_info; -#define XILINX_I2C_DETECTION_BITS 8 +#define XILINX_I2C_DETECTION_BITS sizeof(struct fru_common_hdr) /* Variable which stores pointer to array which stores eeprom content */ struct xilinx_legacy_format { @@ -160,6 +162,82 @@ static bool xilinx_detect_legacy(u8 *buffer) return true; } +static int xilinx_read_eeprom_fru(struct udevice *dev, char *name, + struct xilinx_board_description *desc) +{ + int ret, eeprom_size; + u8 *fru_content; + + /* FIXME this is shortcut - if eeprom type is wrong it will fail */ + eeprom_size = i2c_eeprom_size(dev); + + fru_content = calloc(1, eeprom_size); + if (!fru_content) + return -ENOMEM; + + debug("%s: I2C EEPROM read pass data at %p\n", __func__, + fru_content); + + ret = dm_i2c_read(dev, 0, (uchar *)fru_content, + eeprom_size); + if (ret) { + debug("%s: I2C EEPROM read failed\n", __func__); + free(fru_content); + return ret; + } + + printf("Xilinx I2C FRU format at %s:\n", name); + fru_capture((unsigned long)fru_content); + ret = fru_display(0); + if (ret) { + printf("FRU format decoding failed.\n"); + return ret; + } + + if (desc->header == EEPROM_HEADER_MAGIC) { + debug("Information already filled\n"); + return -EINVAL; + } + + /* It is clear that FRU was captured and structures were filled */ + strncpy(desc->manufacturer, (char *)fru_data.brd.manufacturer_name, + sizeof(desc->manufacturer)); + strncpy(desc->name, (char *)fru_data.brd.product_name, + sizeof(desc->name)); + strncpy(desc->revision, (char *)fru_data.brd.rev, + sizeof(desc->revision)); + strncpy(desc->serial, (char *)fru_data.brd.serial_number, + sizeof(desc->serial)); + desc->header = EEPROM_HEADER_MAGIC; + + return 0; +} + +static bool xilinx_detect_fru(u8 *buffer) +{ + u8 checksum = 0; + int i; + + checksum = fru_checksum((u8 *)buffer, sizeof(struct fru_common_hdr)); + if (checksum) { + debug("%s Common header CRC FAIL\n", __func__); + return false; + } + + bool all_zeros = true; + /* Checksum over all zeros is also zero that's why detect this case */ + for (i = 0; i < sizeof(struct fru_common_hdr); i++) { + if (buffer[i] != 0) + all_zeros = false; + } + + if (all_zeros) + return false; + + debug("%s Common header CRC PASS\n", __func__); + return true; +} + static int xilinx_read_eeprom_single(char *name, struct xilinx_board_description *desc) { @@ -184,6 +262,9 @@ static int xilinx_read_eeprom_single(char *name, debug("%s: i2c memory detected: %s\n", __func__, name); + if (CONFIG_IS_ENABLED(CMD_FRU) && xilinx_detect_fru(buffer)) + return xilinx_read_eeprom_fru(dev, name, desc); + if (xilinx_detect_legacy(buffer)) return xilinx_read_eeprom_legacy(dev, name, desc); |