On Thursday 05 November 2015 03:30 AM, Steve Kipisz wrote: > From: Lokesh Vutla <[email protected]> > > Several TI EVMs have EEPROM that can contain board description information > such as revision, DDR definition, serial number, etc. In just about all > cases, these EEPROM are on the I2C bus and provides us the opportunity > to centralize the generic operations involved. > > The on-board EEPROM on the BeagleBone Black, BeagleBone, AM335x EVM, > AM43x GP EVM, AM57xx-evm, BeagleBoard-X15 share the same format. > However, DRA-7* EVMs, OMAP4SDP use a modified format. > > We hence introduce logic which is generic between these platforms > without enforcing any specific format. This allows the boards to use the > relevant format for operations that they might choose. > > This module will compile for all TI SoC based boards when I2C is enabled, > even non-TI boards that do not have the EEPROM. If the functions are not > used, they will not be linked in. > > It is important to note that this logic is fundamental to the board > configuration process such as DDR configuration which is needed in > SPL, hence cannot be part of the standard u-boot driver model (which > is available later in the process). Hence, to aid efficiency, the > eeprom contents are copied over to SRAM scratchpad memory area at the > first invocation to retrieve data. > > The follow on patches introduce the use of this library for AM57x > platform support. AM335x/AM43xx cleanups need to first ensure usage of > omap_common prior to switch over to this generic solution. > > Signed-off-by: Lokesh Vutla <[email protected]> > Signed-off-by: Steve Kipisz <[email protected]> > --- > v3 Based on: > master 83bf0057 arm: at91: reworked meesc board support > > Changes in v3 (since v2): > - Create a new directory board/ti/common for code common to TI board > - Move the EEPROM code to the new directory > - Move the inline code that access the EEPROM data from omap_common.h > to new files in the common directory > > v2: http://marc.info/?t=144655344800001&r=1&w=2 > (mailing list squashed original submission) > > Changes in v2: > - New Patch > > arch/arm/include/asm/omap_common.h | 5 +- > board/ti/am57xx/Makefile | 2 + > board/ti/common/board.c | 54 ++++++++++++++ > board/ti/common/board.h | 117 +++++++++++++++++++++++++++++ > board/ti/common/ti-i2c-eeprom.c | 148 > +++++++++++++++++++++++++++++++++++++ > 5 files changed, 325 insertions(+), 1 deletion(-) > create mode 100644 board/ti/common/board.c > create mode 100644 board/ti/common/board.h > create mode 100644 board/ti/common/ti-i2c-eeprom.c > > diff --git a/arch/arm/include/asm/omap_common.h > b/arch/arm/include/asm/omap_common.h > index d773b0430ad4..f6d929b15e82 100644 > --- a/arch/arm/include/asm/omap_common.h > +++ b/arch/arm/include/asm/omap_common.h > @@ -713,7 +713,9 @@ static inline u8 is_dra72x(void) > #define OMAP_SRAM_SCRATCH_VCORES_PTR (SRAM_SCRATCH_SPACE_ADDR + 0x1C) > #define OMAP_SRAM_SCRATCH_SYS_CTRL (SRAM_SCRATCH_SPACE_ADDR + 0x20) > #define OMAP_SRAM_SCRATCH_BOOT_PARAMS (SRAM_SCRATCH_SPACE_ADDR + 0x24) > -#define OMAP5_SRAM_SCRATCH_SPACE_END (SRAM_SCRATCH_SPACE_ADDR + 0x28) > +#define OMAP_SRAM_SCRATCH_BOARD_EEPROM_START (SRAM_SCRATCH_SPACE_ADDR + 0x28) > +#define OMAP_SRAM_SCRATCH_BOARD_EEPROM_END (SRAM_SCRATCH_SPACE_ADDR + 0x200) > +#define OMAP_SRAM_SCRATCH_SPACE_END (OMAP_SRAM_SCRATCH_BOARD_EEPROM_END) > > /* Boot parameters */ > #define DEVICE_DATA_OFFSET 0x18 > @@ -728,4 +730,5 @@ static inline u8 is_dra72x(void) > u32 omap_sys_boot_device(void); > #endif > > + > #endif /* _OMAP_COMMON_H_ */ > diff --git a/board/ti/am57xx/Makefile b/board/ti/am57xx/Makefile > index 5cd6873f5e97..9d85d31b2cf1 100644 > --- a/board/ti/am57xx/Makefile > +++ b/board/ti/am57xx/Makefile > @@ -6,3 +6,5 @@ > # > > obj-y := board.o > +obj-y += ../common/board.o > +obj-${CONFIG_I2C} += ../common/ti-i2c-eeprom.o > diff --git a/board/ti/common/board.c b/board/ti/common/board.c > new file mode 100644 > index 000000000000..1c02e44916f0 > --- /dev/null > +++ b/board/ti/common/board.c > @@ -0,0 +1,54 @@ > +/* > + * board.c > + * > + * Common board functions for TI AMxxxx based boards. > + * > + * Copyright (C) 2015, Texas Instruments Incorporated - http://www.ti.com > + * > + * Author: Steven Kipisz <[email protected]> > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include <common.h> > +#include <asm/omap_common.h> > + > +#include "board.h" > + > +/** > + * board_am_is() - Generic Board detection logic > + * @name_tag: Tag used in eeprom for the board > + * > + * Return: false if board information does not match OR eeprom was'nt read. > + * true otherwise > + */ > +bool board_am_is(char *name_tag) > +{ > + struct ti_am_eeprom *ep = TI_AM_EEPROM_DATA; > + > + if (ep->header != TI_EEPROM_HEADER_MAGIC) > + return false; > + return !strncmp(ep->name, name_tag, TI_EEPROM_HDR_NAME_LEN); > +} > + > +/** > + * board_am_rev_is() - Compare board revision > + * @rev_tag: Revision tag to check in eeprom > + * @cmp_len: How many chars to compare? > + * > + * NOTE: revision information is often messed up (hence the str len match) :( > + * > + * Return: false if board information does not match OR eeprom was'nt read. > + * true otherwise > + */ > +bool board_am_rev_is(char *rev_tag, int cmp_len) > +{ > + struct ti_am_eeprom *ep = TI_AM_EEPROM_DATA; > + int l; > + > + if (ep->header != TI_EEPROM_HEADER_MAGIC) > + return false; > + > + l = cmp_len > TI_EEPROM_HDR_REV_LEN ? TI_EEPROM_HDR_NAME_LEN : cmp_len; > + return !strncmp(ep->version, rev_tag, l); > +} > diff --git a/board/ti/common/board.h b/board/ti/common/board.h > new file mode 100644 > index 000000000000..19d63cad82f9 > --- /dev/null > +++ b/board/ti/common/board.h
May be keep this header file under arch/arm/include/asm/ so that it can be included properly. Thanks and regards, Lokesh > @@ -0,0 +1,117 @@ > +/* > + * board.h > + * TI AMxxxx common board information header > + * > + * Copyright (C) 2015, Texas Instruments, Incorporated - http://www.ti.com > + * > + * SPDX-L icense-Identifier: GPL-2.0+ > + */ > + > +/* Common I2C eeprom definitions */ > +#ifndef __ASSEMBLY__ > + > +/* TI EEPROM MAGIC Header identifier */ > +#define TI_EEPROM_HEADER_MAGIC 0xEE3355AA > + > +#define TI_EEPROM_HDR_NAME_LEN 8 > +#define TI_EEPROM_HDR_REV_LEN 12 > +#define TI_EEPROM_HDR_SERIAL_LEN 4 > +#define TI_EEPROM_HDR_CONFIG_LEN 32 > +#define TI_EEPROM_HDR_NO_OF_MAC_ADDR 3 > +#define TI_EEPROM_HDR_ETH_ALEN 6 > + > +/** > + * struct ti_am_eeprom - This structure holds data read in from the > + * AM335x, AM437x, AM57xx TI EVM EEPROMs. > + * @header: This holds the magic number > + * @name: The name of the board > + * @version: Board revision > + * @serial: Board serial number > + * @config: Reserved > + * @mac_addr: Any MAC addresses written in the EEPROM > + * > + * The data is this structure is read from the EEPROM on the board. > + * It is used for board detection which is based on name. It is used > + * to configure specific TI boards. This allows booting of multiple > + * TI boards with a single MLO and u-boot. > + */ > +struct ti_am_eeprom { > + unsigned int header; > + char name[TI_EEPROM_HDR_NAME_LEN]; > + char version[TI_EEPROM_HDR_REV_LEN]; > + char serial[TI_EEPROM_HDR_SERIAL_LEN]; > + char config[TI_EEPROM_HDR_CONFIG_LEN]; > + char mac_addr[TI_EEPROM_HDR_NO_OF_MAC_ADDR][TI_EEPROM_HDR_ETH_ALEN]; > +} __attribute__ ((__packed__)); > + > +/** > + * struct ti_am_eeprom_printable - Null terminated, printable EEPROM contents > + * @name: NULL terminated name > + * @version: NULL terminated version > + * @serial: NULL terminated serial number > + */ > +struct ti_am_eeprom_printable { > + char name[TI_EEPROM_HDR_NAME_LEN + 1]; > + char version[TI_EEPROM_HDR_REV_LEN + 1]; > + char serial[TI_EEPROM_HDR_SERIAL_LEN + 1]; > +}; > +#define TI_AM_EEPROM_DATA ((struct ti_am_eeprom *)\ > + OMAP_SRAM_SCRATCH_BOARD_EEPROM_START) > + > +/** > + * ti_i2c_eeprom_am_get() - Consolidated eeprom data collection for AM* TI > EVMs > + * @bus_addr: I2C bus address > + * @dev_addr: I2C slave address > + * @ep: Pointer to eeprom structure > + * > + * *ep is populated by the this AM generic function that consolidates > + * the basic initialization logic common accross all AM* platforms. > + */ > +int ti_i2c_eeprom_am_get(int bus_addr, int dev_addr, struct ti_am_eeprom > **epp); > + > +/** > + * ti_i2c_eeprom_am_get_print() - Get a printable representation of eeprom > data > + * @bus_addr: I2C bus address > + * @dev_addr: I2C slave address > + * @p: Pointer to eeprom structure > + * > + * This reads the eeprom and converts the data into a printable string for > + * further processing. > + */ > +int ti_i2c_eeprom_am_get_print(int bus_addr, int dev_addr, > + struct ti_am_eeprom_printable *p); > + > +/** > + * set_board_info_env() - Setup commonly used board information environment > vars > + * @name: Name of the board > + * @revision: Revision of the board > + * @serial: Serial Number of the board > + * > + * In case of NULL revision or serial information "unknown" is setup. > + * If name is NULL, default_name is used. > + */ > +void set_board_info_env(char *name, char *revision, > + char *serial); > + > +/** > + * board_am_is() - Generic Board detection logic > + * @name_tag: Tag used in eeprom for the board > + * > + * Return: false if board information does not match OR eeprom was'nt read. > + * true otherwise > + */ > +bool board_am_is(char *name_tag); > + > +/** > + * board_am_rev_is() - Compare board revision > + * @rev_tag: Revision tag to check in eeprom > + * @cmp_len: How many chars to compare? > + * > + * NOTE: revision information is often messed up (hence the str len match) :( > + * > + * Return: false if board information does not match OR eeprom was'nt read. > + * true otherwise > + */ > +bool board_am_rev_is(char *rev_tag, int cmp_len); > + > +#endif /* __ASSEMBLY__ */ > diff --git a/board/ti/common/ti-i2c-eeprom.c b/board/ti/common/ti-i2c-eeprom.c > new file mode 100644 > index 000000000000..5ec499b51a5d > --- /dev/null > +++ b/board/ti/common/ti-i2c-eeprom.c > @@ -0,0 +1,148 @@ > +/* > + * Library to support early TI EVM EEPROM handling > + * > + * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ > + * Lokesh Vutla > + * Steve Kipisz > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include <common.h> > +#include <asm/omap_common.h> > +#include <i2c.h> > + > +#include "board.h" > + > +/** > + * ti_i2c_eeprom_init - Initialize an i2c bus and probe for a device > + * @i2c_bus: i2c bus number to initialize > + * @dev_addr: Device address to probe for > + * > + * Return: 0 on success or corresponding error on failure. > + */ > +int __maybe_unused ti_i2c_eeprom_init(int i2c_bus, int dev_addr) > +{ > + int rc; > + > + rc = i2c_set_bus_num(i2c_bus); > + if (rc) > + return rc; > + > + return i2c_probe(dev_addr); > +} > + > +/** > + * ti_i2c_eeprom_read - Read data from an EEPROM > + * @dev_addr: The device address of the EEPROM > + * @offset: Offset to start reading in the EEPROM > + * @ep: Pointer to a buffer to read into > + * @epsize: Size of buffer > + * > + * Return: 0 on success or corresponding result of i2c_read > + */ > +int __maybe_unused ti_i2c_eeprom_read(int dev_addr, int offset, uchar *ep, > + int epsize) > +{ > + return i2c_read(dev_addr, offset, 2, ep, epsize); > +} > + > +/** > + * ti_eeprom_string_cleanup() - Handle eeprom programming errors > + * @s: eeprom string (should be NULL terminated) > + * > + * Some Board manufacturers do not add a NULL termination at the > + * end of string, instead some binary information is kludged in, hence > + * convert the string to just printable characters of ASCII chart. > + */ > +void __maybe_unused ti_eeprom_string_cleanup(char *s) > +{ > + int i, l; > + > + l = strlen(s); > + for (i = 0; i < l; i++, s++) > + if (*s < ' ' || *s > '~') { > + *s = 0; > + break; > + } > +} > + > +int __maybe_unused ti_i2c_eeprom_am_get(int bus_addr, int dev_addr, > + struct ti_am_eeprom **epp) > +{ > + int rc; > + struct ti_am_eeprom *ep; > + > + if (!epp) > + return -1; > + > + ep = TI_AM_EEPROM_DATA; > + if (ep->header == TI_EEPROM_HEADER_MAGIC) > + goto already_read; > + > + /* Initialize with a known bad marker for i2c fails.. */ > + ep->header = 0xADEAD12C; > + > + gpi2c_init(); > + rc = ti_i2c_eeprom_init(bus_addr, dev_addr); > + if (rc) > + return rc; > + rc = i2c_read(dev_addr, 0x0, 2, (uint8_t *)ep, sizeof(*ep)); > + if (rc) > + return rc; > + > + /* Corrupted data??? */ > + if (ep->header != TI_EEPROM_HEADER_MAGIC) > + return -1; > + > +already_read: > + *epp = ep; > + > + return 0; > +} > + > +int __maybe_unused ti_i2c_eeprom_am_get_print(int bus_addr, int dev_addr, > + struct ti_am_eeprom_printable *p) > +{ > + struct ti_am_eeprom *ep; > + int rc; > + > + /* Incase of invalid eeprom contents */ > + p->name[0] = 0x00; > + p->version[0] = 0x00; > + p->serial[0] = 0x00; > + > + rc = ti_i2c_eeprom_am_get(bus_addr, dev_addr, &ep); > + if (rc) > + return rc; > + > + /* > + * Alas! we have to null terminate and cleanup the strings! > + */ > + strlcpy(p->name, ep->name, TI_EEPROM_HDR_NAME_LEN); > + ti_eeprom_string_cleanup(p->name); > + strlcpy(p->version, ep->version, TI_EEPROM_HDR_NAME_LEN); > + ti_eeprom_string_cleanup(p->version); > + strlcpy(p->serial, ep->serial, TI_EEPROM_HDR_NAME_LEN); > + ti_eeprom_string_cleanup(p->serial); > + return 0; > +} > + > +void __maybe_unused set_board_info_env(char *name, char *revision, > + char *serial) > +{ > + char *unknown = "unknown"; > + > + if (name) > + setenv("board_name", name); > + > + if (revision) > + setenv("board_revision", revision); > + else > + setenv("board_revision", unknown); > + > + if (serial) > + setenv("board_serial", serial); > + else > + setenv("board_serial", unknown); > +} > _______________________________________________ U-Boot mailing list [email protected] http://lists.denx.de/mailman/listinfo/u-boot

