xref: /openbmc/u-boot/board/ti/common/board_detect.c (revision d94604d5)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
20bea813dSLokesh Vutla /*
30bea813dSLokesh Vutla  * Library to support early TI EVM EEPROM handling
40bea813dSLokesh Vutla  *
50bea813dSLokesh Vutla  * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
60bea813dSLokesh Vutla  *	Lokesh Vutla
70bea813dSLokesh Vutla  *	Steve Kipisz
80bea813dSLokesh Vutla  */
90bea813dSLokesh Vutla 
100bea813dSLokesh Vutla #include <common.h>
110bea813dSLokesh Vutla #include <asm/omap_common.h>
12c6b80b13SCooper Jr., Franklin #include <dm/uclass.h>
130bea813dSLokesh Vutla #include <i2c.h>
140bea813dSLokesh Vutla 
150bea813dSLokesh Vutla #include "board_detect.h"
160bea813dSLokesh Vutla 
17*1514244cSJean-Jacques Hiblot #if !defined(CONFIG_DM_I2C)
180bea813dSLokesh Vutla /**
190bea813dSLokesh Vutla  * ti_i2c_eeprom_init - Initialize an i2c bus and probe for a device
200bea813dSLokesh Vutla  * @i2c_bus: i2c bus number to initialize
210bea813dSLokesh Vutla  * @dev_addr: Device address to probe for
220bea813dSLokesh Vutla  *
230bea813dSLokesh Vutla  * Return: 0 on success or corresponding error on failure.
240bea813dSLokesh Vutla  */
ti_i2c_eeprom_init(int i2c_bus,int dev_addr)250bea813dSLokesh Vutla static int __maybe_unused ti_i2c_eeprom_init(int i2c_bus, int dev_addr)
260bea813dSLokesh Vutla {
270bea813dSLokesh Vutla 	int rc;
280bea813dSLokesh Vutla 
290bea813dSLokesh Vutla 	if (i2c_bus >= 0) {
300bea813dSLokesh Vutla 		rc = i2c_set_bus_num(i2c_bus);
310bea813dSLokesh Vutla 		if (rc)
320bea813dSLokesh Vutla 			return rc;
330bea813dSLokesh Vutla 	}
340bea813dSLokesh Vutla 
350bea813dSLokesh Vutla 	return i2c_probe(dev_addr);
360bea813dSLokesh Vutla }
370bea813dSLokesh Vutla 
380bea813dSLokesh Vutla /**
390bea813dSLokesh Vutla  * ti_i2c_eeprom_read - Read data from an EEPROM
400bea813dSLokesh Vutla  * @dev_addr: The device address of the EEPROM
410bea813dSLokesh Vutla  * @offset: Offset to start reading in the EEPROM
420bea813dSLokesh Vutla  * @ep: Pointer to a buffer to read into
430bea813dSLokesh Vutla  * @epsize: Size of buffer
440bea813dSLokesh Vutla  *
450bea813dSLokesh Vutla  * Return: 0 on success or corresponding result of i2c_read
460bea813dSLokesh Vutla  */
ti_i2c_eeprom_read(int dev_addr,int offset,uchar * ep,int epsize)470bea813dSLokesh Vutla static int __maybe_unused ti_i2c_eeprom_read(int dev_addr, int offset,
480bea813dSLokesh Vutla 					     uchar *ep, int epsize)
490bea813dSLokesh Vutla {
50*1514244cSJean-Jacques Hiblot 	return i2c_read(dev_addr, offset, 2, ep, epsize);
510bea813dSLokesh Vutla }
522463f672SAndreas Dannenberg #endif
530bea813dSLokesh Vutla 
540bea813dSLokesh Vutla /**
550bea813dSLokesh Vutla  * ti_eeprom_string_cleanup() - Handle eeprom programming errors
560bea813dSLokesh Vutla  * @s:	eeprom string (should be NULL terminated)
570bea813dSLokesh Vutla  *
580bea813dSLokesh Vutla  * Some Board manufacturers do not add a NULL termination at the
590bea813dSLokesh Vutla  * end of string, instead some binary information is kludged in, hence
600bea813dSLokesh Vutla  * convert the string to just printable characters of ASCII chart.
610bea813dSLokesh Vutla  */
ti_eeprom_string_cleanup(char * s)620bea813dSLokesh Vutla static void __maybe_unused ti_eeprom_string_cleanup(char *s)
630bea813dSLokesh Vutla {
640bea813dSLokesh Vutla 	int i, l;
650bea813dSLokesh Vutla 
660bea813dSLokesh Vutla 	l = strlen(s);
670bea813dSLokesh Vutla 	for (i = 0; i < l; i++, s++)
680bea813dSLokesh Vutla 		if (*s < ' ' || *s > '~') {
690bea813dSLokesh Vutla 			*s = 0;
700bea813dSLokesh Vutla 			break;
710bea813dSLokesh Vutla 		}
720bea813dSLokesh Vutla }
730bea813dSLokesh Vutla 
gpi2c_init(void)740bea813dSLokesh Vutla __weak void gpi2c_init(void)
750bea813dSLokesh Vutla {
760bea813dSLokesh Vutla }
770bea813dSLokesh Vutla 
ti_i2c_eeprom_get(int bus_addr,int dev_addr,u32 header,u32 size,uint8_t * ep)780bea813dSLokesh Vutla static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr,
790bea813dSLokesh Vutla 					    u32 header, u32 size, uint8_t *ep)
800bea813dSLokesh Vutla {
812463f672SAndreas Dannenberg 	u32 hdr_read;
820bea813dSLokesh Vutla 	int rc;
830bea813dSLokesh Vutla 
84*1514244cSJean-Jacques Hiblot #if defined(CONFIG_DM_I2C)
852463f672SAndreas Dannenberg 	struct udevice *dev;
862463f672SAndreas Dannenberg 	struct udevice *bus;
872463f672SAndreas Dannenberg 
882463f672SAndreas Dannenberg 	rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
892463f672SAndreas Dannenberg 	if (rc)
902463f672SAndreas Dannenberg 		return rc;
912463f672SAndreas Dannenberg 	rc = i2c_get_chip(bus, dev_addr, 1, &dev);
922463f672SAndreas Dannenberg 	if (rc)
932463f672SAndreas Dannenberg 		return rc;
942463f672SAndreas Dannenberg 
952463f672SAndreas Dannenberg 	/*
962463f672SAndreas Dannenberg 	 * Read the header first then only read the other contents.
972463f672SAndreas Dannenberg 	 */
982463f672SAndreas Dannenberg 	rc = i2c_set_chip_offset_len(dev, 2);
992463f672SAndreas Dannenberg 	if (rc)
1002463f672SAndreas Dannenberg 		return rc;
1012463f672SAndreas Dannenberg 
1022463f672SAndreas Dannenberg 	rc = dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4);
1032463f672SAndreas Dannenberg 	if (rc)
1042463f672SAndreas Dannenberg 		return rc;
1052463f672SAndreas Dannenberg 
1062463f672SAndreas Dannenberg 	/* Corrupted data??? */
1072463f672SAndreas Dannenberg 	if (hdr_read != header) {
1082463f672SAndreas Dannenberg 		rc = dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4);
1092463f672SAndreas Dannenberg 		/*
1102463f672SAndreas Dannenberg 		 * read the eeprom header using i2c again, but use only a
1112463f672SAndreas Dannenberg 		 * 1 byte address (some legacy boards need this..)
1122463f672SAndreas Dannenberg 		 */
1132463f672SAndreas Dannenberg 		if (rc) {
1142463f672SAndreas Dannenberg 			rc =  i2c_set_chip_offset_len(dev, 1);
1152463f672SAndreas Dannenberg 			if (rc)
1162463f672SAndreas Dannenberg 				return rc;
1172463f672SAndreas Dannenberg 
1182463f672SAndreas Dannenberg 			rc = dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4);
1192463f672SAndreas Dannenberg 		}
1202463f672SAndreas Dannenberg 		if (rc)
1212463f672SAndreas Dannenberg 			return rc;
1222463f672SAndreas Dannenberg 	}
1232463f672SAndreas Dannenberg 	if (hdr_read != header)
1242463f672SAndreas Dannenberg 		return -1;
1252463f672SAndreas Dannenberg 
1262463f672SAndreas Dannenberg 	rc = dm_i2c_read(dev, 0, ep, size);
1272463f672SAndreas Dannenberg 	if (rc)
1282463f672SAndreas Dannenberg 		return rc;
1292463f672SAndreas Dannenberg #else
1302463f672SAndreas Dannenberg 	u32 byte;
1312463f672SAndreas Dannenberg 
1320bea813dSLokesh Vutla 	gpi2c_init();
1330bea813dSLokesh Vutla 	rc = ti_i2c_eeprom_init(bus_addr, dev_addr);
1340bea813dSLokesh Vutla 	if (rc)
1350bea813dSLokesh Vutla 		return rc;
1360bea813dSLokesh Vutla 
1370bea813dSLokesh Vutla 	/*
1380bea813dSLokesh Vutla 	 * Read the header first then only read the other contents.
1390bea813dSLokesh Vutla 	 */
1400bea813dSLokesh Vutla 	byte = 2;
141e25ae322SCooper Jr., Franklin 
1420bea813dSLokesh Vutla 	rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read, 4);
1430bea813dSLokesh Vutla 	if (rc)
1440bea813dSLokesh Vutla 		return rc;
1450bea813dSLokesh Vutla 
1460bea813dSLokesh Vutla 	/* Corrupted data??? */
1470bea813dSLokesh Vutla 	if (hdr_read != header) {
1480bea813dSLokesh Vutla 		rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read, 4);
1490bea813dSLokesh Vutla 		/*
1500bea813dSLokesh Vutla 		 * read the eeprom header using i2c again, but use only a
1510bea813dSLokesh Vutla 		 * 1 byte address (some legacy boards need this..)
1520bea813dSLokesh Vutla 		 */
1530bea813dSLokesh Vutla 		byte = 1;
154e25ae322SCooper Jr., Franklin 		if (rc) {
1550bea813dSLokesh Vutla 			rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read,
1560bea813dSLokesh Vutla 				      4);
157e25ae322SCooper Jr., Franklin 		}
1580bea813dSLokesh Vutla 		if (rc)
1590bea813dSLokesh Vutla 			return rc;
1600bea813dSLokesh Vutla 	}
1610bea813dSLokesh Vutla 	if (hdr_read != header)
1620bea813dSLokesh Vutla 		return -1;
1630bea813dSLokesh Vutla 
1640bea813dSLokesh Vutla 	rc = i2c_read(dev_addr, 0x0, byte, ep, size);
1650bea813dSLokesh Vutla 	if (rc)
1660bea813dSLokesh Vutla 		return rc;
1672463f672SAndreas Dannenberg #endif
1680bea813dSLokesh Vutla 	return 0;
1690bea813dSLokesh Vutla }
1700bea813dSLokesh Vutla 
ti_i2c_eeprom_am_set(const char * name,const char * rev)171e936f997SNishanth Menon int __maybe_unused ti_i2c_eeprom_am_set(const char *name, const char *rev)
172e936f997SNishanth Menon {
173e936f997SNishanth Menon 	struct ti_common_eeprom *ep;
174e936f997SNishanth Menon 
175e936f997SNishanth Menon 	if (!name || !rev)
176e936f997SNishanth Menon 		return -1;
177e936f997SNishanth Menon 
178e936f997SNishanth Menon 	ep = TI_EEPROM_DATA;
179e936f997SNishanth Menon 	if (ep->header == TI_EEPROM_HEADER_MAGIC)
180e936f997SNishanth Menon 		goto already_set;
181e936f997SNishanth Menon 
182e936f997SNishanth Menon 	/* Set to 0 all fields */
183e936f997SNishanth Menon 	memset(ep, 0, sizeof(*ep));
184e936f997SNishanth Menon 	strncpy(ep->name, name, TI_EEPROM_HDR_NAME_LEN);
185e936f997SNishanth Menon 	strncpy(ep->version, rev, TI_EEPROM_HDR_REV_LEN);
186e936f997SNishanth Menon 	/* Some dummy serial number to identify the platform */
187e936f997SNishanth Menon 	strncpy(ep->serial, "0000", TI_EEPROM_HDR_SERIAL_LEN);
188e936f997SNishanth Menon 	/* Mark it with a valid header */
189e936f997SNishanth Menon 	ep->header = TI_EEPROM_HEADER_MAGIC;
190e936f997SNishanth Menon 
191e936f997SNishanth Menon already_set:
192e936f997SNishanth Menon 	return 0;
193e936f997SNishanth Menon }
194e936f997SNishanth Menon 
ti_i2c_eeprom_am_get(int bus_addr,int dev_addr)1950bea813dSLokesh Vutla int __maybe_unused ti_i2c_eeprom_am_get(int bus_addr, int dev_addr)
1960bea813dSLokesh Vutla {
1970bea813dSLokesh Vutla 	int rc;
1980bea813dSLokesh Vutla 	struct ti_am_eeprom am_ep;
1990bea813dSLokesh Vutla 	struct ti_common_eeprom *ep;
2000bea813dSLokesh Vutla 
2010bea813dSLokesh Vutla 	ep = TI_EEPROM_DATA;
202a3a23c97SJean-Jacques Hiblot #ifndef CONFIG_SPL_BUILD
2030bea813dSLokesh Vutla 	if (ep->header == TI_EEPROM_HEADER_MAGIC)
204a3a23c97SJean-Jacques Hiblot 		return 0; /* EEPROM has already been read */
205a3a23c97SJean-Jacques Hiblot #endif
2060bea813dSLokesh Vutla 
2070bea813dSLokesh Vutla 	/* Initialize with a known bad marker for i2c fails.. */
2080bea813dSLokesh Vutla 	ep->header = TI_DEAD_EEPROM_MAGIC;
2090bea813dSLokesh Vutla 	ep->name[0] = 0x0;
2100bea813dSLokesh Vutla 	ep->version[0] = 0x0;
2110bea813dSLokesh Vutla 	ep->serial[0] = 0x0;
2122a78c9e7SNishanth Menon 	ep->config[0] = 0x0;
2130bea813dSLokesh Vutla 
2140bea813dSLokesh Vutla 	rc = ti_i2c_eeprom_get(bus_addr, dev_addr, TI_EEPROM_HEADER_MAGIC,
2150bea813dSLokesh Vutla 			       sizeof(am_ep), (uint8_t *)&am_ep);
2160bea813dSLokesh Vutla 	if (rc)
2170bea813dSLokesh Vutla 		return rc;
2180bea813dSLokesh Vutla 
2190bea813dSLokesh Vutla 	ep->header = am_ep.header;
2200bea813dSLokesh Vutla 	strlcpy(ep->name, am_ep.name, TI_EEPROM_HDR_NAME_LEN + 1);
2210bea813dSLokesh Vutla 	ti_eeprom_string_cleanup(ep->name);
2220bea813dSLokesh Vutla 
2230bea813dSLokesh Vutla 	/* BeagleBone Green '1' eeprom, board_rev: 0x1a 0x00 0x00 0x00 */
2240bea813dSLokesh Vutla 	if (am_ep.version[0] == 0x1a && am_ep.version[1] == 0x00 &&
2250bea813dSLokesh Vutla 	    am_ep.version[2] == 0x00 && am_ep.version[3] == 0x00)
2260bea813dSLokesh Vutla 		strlcpy(ep->version, "BBG1", TI_EEPROM_HDR_REV_LEN + 1);
2270bea813dSLokesh Vutla 	else
2280bea813dSLokesh Vutla 		strlcpy(ep->version, am_ep.version, TI_EEPROM_HDR_REV_LEN + 1);
2290bea813dSLokesh Vutla 	ti_eeprom_string_cleanup(ep->version);
2300bea813dSLokesh Vutla 	strlcpy(ep->serial, am_ep.serial, TI_EEPROM_HDR_SERIAL_LEN + 1);
2310bea813dSLokesh Vutla 	ti_eeprom_string_cleanup(ep->serial);
2320bea813dSLokesh Vutla 	strlcpy(ep->config, am_ep.config, TI_EEPROM_HDR_CONFIG_LEN + 1);
2330bea813dSLokesh Vutla 	ti_eeprom_string_cleanup(ep->config);
2340bea813dSLokesh Vutla 
2350bea813dSLokesh Vutla 	memcpy(ep->mac_addr, am_ep.mac_addr,
2360bea813dSLokesh Vutla 	       TI_EEPROM_HDR_NO_OF_MAC_ADDR * TI_EEPROM_HDR_ETH_ALEN);
2370bea813dSLokesh Vutla 
2380bea813dSLokesh Vutla 	return 0;
2390bea813dSLokesh Vutla }
2400bea813dSLokesh Vutla 
ti_i2c_eeprom_dra7_get(int bus_addr,int dev_addr)241d3b98a9eSLokesh Vutla int __maybe_unused ti_i2c_eeprom_dra7_get(int bus_addr, int dev_addr)
242d3b98a9eSLokesh Vutla {
243d3b98a9eSLokesh Vutla 	int rc, offset = 0;
244d3b98a9eSLokesh Vutla 	struct dra7_eeprom dra7_ep;
245d3b98a9eSLokesh Vutla 	struct ti_common_eeprom *ep;
246d3b98a9eSLokesh Vutla 
247d3b98a9eSLokesh Vutla 	ep = TI_EEPROM_DATA;
248a3a23c97SJean-Jacques Hiblot #ifndef CONFIG_SPL_BUILD
249d3b98a9eSLokesh Vutla 	if (ep->header == DRA7_EEPROM_HEADER_MAGIC)
250a3a23c97SJean-Jacques Hiblot 		return 0; /* EEPROM has already been read */
251a3a23c97SJean-Jacques Hiblot #endif
252d3b98a9eSLokesh Vutla 
253d3b98a9eSLokesh Vutla 	/* Initialize with a known bad marker for i2c fails.. */
25428d624beSNishanth Menon 	ep->header = TI_DEAD_EEPROM_MAGIC;
255d3b98a9eSLokesh Vutla 	ep->name[0] = 0x0;
256d3b98a9eSLokesh Vutla 	ep->version[0] = 0x0;
257d3b98a9eSLokesh Vutla 	ep->serial[0] = 0x0;
2582a78c9e7SNishanth Menon 	ep->config[0] = 0x0;
259d3b98a9eSLokesh Vutla 	ep->emif1_size = 0;
260d3b98a9eSLokesh Vutla 	ep->emif2_size = 0;
261d3b98a9eSLokesh Vutla 
262d3b98a9eSLokesh Vutla 	rc = ti_i2c_eeprom_get(bus_addr, dev_addr, DRA7_EEPROM_HEADER_MAGIC,
263d3b98a9eSLokesh Vutla 			       sizeof(dra7_ep), (uint8_t *)&dra7_ep);
264d3b98a9eSLokesh Vutla 	if (rc)
265d3b98a9eSLokesh Vutla 		return rc;
266d3b98a9eSLokesh Vutla 
267d3b98a9eSLokesh Vutla 	ep->header = dra7_ep.header;
268d3b98a9eSLokesh Vutla 	strlcpy(ep->name, dra7_ep.name, TI_EEPROM_HDR_NAME_LEN + 1);
269d3b98a9eSLokesh Vutla 	ti_eeprom_string_cleanup(ep->name);
270d3b98a9eSLokesh Vutla 
271d3b98a9eSLokesh Vutla 	offset = dra7_ep.version_major - 1;
272d3b98a9eSLokesh Vutla 
273d3b98a9eSLokesh Vutla 	/* Rev F is skipped */
274d3b98a9eSLokesh Vutla 	if (offset >= 5)
275d3b98a9eSLokesh Vutla 		offset = offset + 1;
276d3b98a9eSLokesh Vutla 	snprintf(ep->version, TI_EEPROM_HDR_REV_LEN + 1, "%c.%d",
277d3b98a9eSLokesh Vutla 		 'A' + offset, dra7_ep.version_minor);
278d3b98a9eSLokesh Vutla 	ti_eeprom_string_cleanup(ep->version);
279d3b98a9eSLokesh Vutla 	ep->emif1_size = (u64)dra7_ep.emif1_size;
280d3b98a9eSLokesh Vutla 	ep->emif2_size = (u64)dra7_ep.emif2_size;
281d3b98a9eSLokesh Vutla 	strlcpy(ep->config, dra7_ep.config, TI_EEPROM_HDR_CONFIG_LEN + 1);
282d3b98a9eSLokesh Vutla 	ti_eeprom_string_cleanup(ep->config);
283d3b98a9eSLokesh Vutla 
284d3b98a9eSLokesh Vutla 	return 0;
285d3b98a9eSLokesh Vutla }
286d3b98a9eSLokesh Vutla 
board_ti_is(char * name_tag)2870bea813dSLokesh Vutla bool __maybe_unused board_ti_is(char *name_tag)
2880bea813dSLokesh Vutla {
2890bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
2900bea813dSLokesh Vutla 
2910bea813dSLokesh Vutla 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
2920bea813dSLokesh Vutla 		return false;
2930bea813dSLokesh Vutla 	return !strncmp(ep->name, name_tag, TI_EEPROM_HDR_NAME_LEN);
2940bea813dSLokesh Vutla }
2950bea813dSLokesh Vutla 
board_ti_rev_is(char * rev_tag,int cmp_len)2960bea813dSLokesh Vutla bool __maybe_unused board_ti_rev_is(char *rev_tag, int cmp_len)
2970bea813dSLokesh Vutla {
2980bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
2990bea813dSLokesh Vutla 	int l;
3000bea813dSLokesh Vutla 
3010bea813dSLokesh Vutla 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
3020bea813dSLokesh Vutla 		return false;
3030bea813dSLokesh Vutla 
3040bea813dSLokesh Vutla 	l = cmp_len > TI_EEPROM_HDR_REV_LEN ? TI_EEPROM_HDR_REV_LEN : cmp_len;
3050bea813dSLokesh Vutla 	return !strncmp(ep->version, rev_tag, l);
3060bea813dSLokesh Vutla }
3070bea813dSLokesh Vutla 
board_ti_get_rev(void)3080bea813dSLokesh Vutla char * __maybe_unused board_ti_get_rev(void)
3090bea813dSLokesh Vutla {
3100bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
3110bea813dSLokesh Vutla 
3127774e97aSNishanth Menon 	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
3130bea813dSLokesh Vutla 	return ep->version;
3140bea813dSLokesh Vutla }
3150bea813dSLokesh Vutla 
board_ti_get_config(void)3160bea813dSLokesh Vutla char * __maybe_unused board_ti_get_config(void)
3170bea813dSLokesh Vutla {
3180bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
3190bea813dSLokesh Vutla 
3207774e97aSNishanth Menon 	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
3210bea813dSLokesh Vutla 	return ep->config;
3220bea813dSLokesh Vutla }
3230bea813dSLokesh Vutla 
board_ti_get_name(void)3240bea813dSLokesh Vutla char * __maybe_unused board_ti_get_name(void)
3250bea813dSLokesh Vutla {
3260bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
3270bea813dSLokesh Vutla 
3287774e97aSNishanth Menon 	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
3290bea813dSLokesh Vutla 	return ep->name;
3300bea813dSLokesh Vutla }
3310bea813dSLokesh Vutla 
3320bea813dSLokesh Vutla void __maybe_unused
board_ti_get_eth_mac_addr(int index,u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])3330bea813dSLokesh Vutla board_ti_get_eth_mac_addr(int index,
3340bea813dSLokesh Vutla 			  u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])
3350bea813dSLokesh Vutla {
3360bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
3370bea813dSLokesh Vutla 
3380bea813dSLokesh Vutla 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
3390bea813dSLokesh Vutla 		goto fail;
3400bea813dSLokesh Vutla 
3410bea813dSLokesh Vutla 	if (index < 0 || index >= TI_EEPROM_HDR_NO_OF_MAC_ADDR)
3420bea813dSLokesh Vutla 		goto fail;
3430bea813dSLokesh Vutla 
3440bea813dSLokesh Vutla 	memcpy(mac_addr, ep->mac_addr[index], TI_EEPROM_HDR_ETH_ALEN);
3450bea813dSLokesh Vutla 	return;
3460bea813dSLokesh Vutla 
3470bea813dSLokesh Vutla fail:
3480bea813dSLokesh Vutla 	memset(mac_addr, 0, TI_EEPROM_HDR_ETH_ALEN);
3490bea813dSLokesh Vutla }
3500bea813dSLokesh Vutla 
board_ti_get_emif1_size(void)351d3b98a9eSLokesh Vutla u64 __maybe_unused board_ti_get_emif1_size(void)
352d3b98a9eSLokesh Vutla {
353d3b98a9eSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
354d3b98a9eSLokesh Vutla 
355d3b98a9eSLokesh Vutla 	if (ep->header != DRA7_EEPROM_HEADER_MAGIC)
356d3b98a9eSLokesh Vutla 		return 0;
357d3b98a9eSLokesh Vutla 
358d3b98a9eSLokesh Vutla 	return ep->emif1_size;
359d3b98a9eSLokesh Vutla }
360d3b98a9eSLokesh Vutla 
board_ti_get_emif2_size(void)361d3b98a9eSLokesh Vutla u64 __maybe_unused board_ti_get_emif2_size(void)
362d3b98a9eSLokesh Vutla {
363d3b98a9eSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
364d3b98a9eSLokesh Vutla 
365d3b98a9eSLokesh Vutla 	if (ep->header != DRA7_EEPROM_HEADER_MAGIC)
366d3b98a9eSLokesh Vutla 		return 0;
367d3b98a9eSLokesh Vutla 
368d3b98a9eSLokesh Vutla 	return ep->emif2_size;
369d3b98a9eSLokesh Vutla }
370d3b98a9eSLokesh Vutla 
set_board_info_env(char * name)3710bea813dSLokesh Vutla void __maybe_unused set_board_info_env(char *name)
3720bea813dSLokesh Vutla {
3730bea813dSLokesh Vutla 	char *unknown = "unknown";
3740bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
3750bea813dSLokesh Vutla 
3760bea813dSLokesh Vutla 	if (name)
377382bee57SSimon Glass 		env_set("board_name", name);
3780bea813dSLokesh Vutla 	else if (ep->name)
379382bee57SSimon Glass 		env_set("board_name", ep->name);
3800bea813dSLokesh Vutla 	else
381382bee57SSimon Glass 		env_set("board_name", unknown);
3820bea813dSLokesh Vutla 
3830bea813dSLokesh Vutla 	if (ep->version)
384382bee57SSimon Glass 		env_set("board_rev", ep->version);
3850bea813dSLokesh Vutla 	else
386382bee57SSimon Glass 		env_set("board_rev", unknown);
3870bea813dSLokesh Vutla 
3880bea813dSLokesh Vutla 	if (ep->serial)
389382bee57SSimon Glass 		env_set("board_serial", ep->serial);
3900bea813dSLokesh Vutla 	else
391382bee57SSimon Glass 		env_set("board_serial", unknown);
3920bea813dSLokesh Vutla }
39338f719eaSRoger Quadros 
mac_to_u64(u8 mac[6])39438f719eaSRoger Quadros static u64 mac_to_u64(u8 mac[6])
39538f719eaSRoger Quadros {
39638f719eaSRoger Quadros 	int i;
39738f719eaSRoger Quadros 	u64 addr = 0;
39838f719eaSRoger Quadros 
39938f719eaSRoger Quadros 	for (i = 0; i < 6; i++) {
40038f719eaSRoger Quadros 		addr <<= 8;
40138f719eaSRoger Quadros 		addr |= mac[i];
40238f719eaSRoger Quadros 	}
40338f719eaSRoger Quadros 
40438f719eaSRoger Quadros 	return addr;
40538f719eaSRoger Quadros }
40638f719eaSRoger Quadros 
u64_to_mac(u64 addr,u8 mac[6])40738f719eaSRoger Quadros static void u64_to_mac(u64 addr, u8 mac[6])
40838f719eaSRoger Quadros {
40938f719eaSRoger Quadros 	mac[5] = addr;
41038f719eaSRoger Quadros 	mac[4] = addr >> 8;
41138f719eaSRoger Quadros 	mac[3] = addr >> 16;
41238f719eaSRoger Quadros 	mac[2] = addr >> 24;
41338f719eaSRoger Quadros 	mac[1] = addr >> 32;
41438f719eaSRoger Quadros 	mac[0] = addr >> 40;
41538f719eaSRoger Quadros }
41638f719eaSRoger Quadros 
board_ti_set_ethaddr(int index)41738f719eaSRoger Quadros void board_ti_set_ethaddr(int index)
41838f719eaSRoger Quadros {
41938f719eaSRoger Quadros 	uint8_t mac_addr[6];
42038f719eaSRoger Quadros 	int i;
42138f719eaSRoger Quadros 	u64 mac1, mac2;
42238f719eaSRoger Quadros 	u8 mac_addr1[6], mac_addr2[6];
42338f719eaSRoger Quadros 	int num_macs;
42438f719eaSRoger Quadros 	/*
42538f719eaSRoger Quadros 	 * Export any Ethernet MAC addresses from EEPROM.
42638f719eaSRoger Quadros 	 * The 2 MAC addresses in EEPROM define the address range.
42738f719eaSRoger Quadros 	 */
42838f719eaSRoger Quadros 	board_ti_get_eth_mac_addr(0, mac_addr1);
42938f719eaSRoger Quadros 	board_ti_get_eth_mac_addr(1, mac_addr2);
43038f719eaSRoger Quadros 
43138f719eaSRoger Quadros 	if (is_valid_ethaddr(mac_addr1) && is_valid_ethaddr(mac_addr2)) {
43238f719eaSRoger Quadros 		mac1 = mac_to_u64(mac_addr1);
43338f719eaSRoger Quadros 		mac2 = mac_to_u64(mac_addr2);
43438f719eaSRoger Quadros 
43538f719eaSRoger Quadros 		/* must contain an address range */
43638f719eaSRoger Quadros 		num_macs = mac2 - mac1 + 1;
43738f719eaSRoger Quadros 		if (num_macs <= 0)
43838f719eaSRoger Quadros 			return;
43938f719eaSRoger Quadros 
44038f719eaSRoger Quadros 		if (num_macs > 50) {
44138f719eaSRoger Quadros 			printf("%s: Too many MAC addresses: %d. Limiting to 50\n",
44238f719eaSRoger Quadros 			       __func__, num_macs);
44338f719eaSRoger Quadros 			num_macs = 50;
44438f719eaSRoger Quadros 		}
44538f719eaSRoger Quadros 
44638f719eaSRoger Quadros 		for (i = 0; i < num_macs; i++) {
44738f719eaSRoger Quadros 			u64_to_mac(mac1 + i, mac_addr);
44838f719eaSRoger Quadros 			if (is_valid_ethaddr(mac_addr)) {
449fd1e959eSSimon Glass 				eth_env_set_enetaddr_by_index("eth", i + index,
45038f719eaSRoger Quadros 							      mac_addr);
45138f719eaSRoger Quadros 			}
45238f719eaSRoger Quadros 		}
45338f719eaSRoger Quadros 	}
45438f719eaSRoger Quadros }
45569e8d4baSCooper Jr., Franklin 
board_ti_was_eeprom_read(void)45669e8d4baSCooper Jr., Franklin bool __maybe_unused board_ti_was_eeprom_read(void)
45769e8d4baSCooper Jr., Franklin {
45869e8d4baSCooper Jr., Franklin 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
45969e8d4baSCooper Jr., Franklin 
46069e8d4baSCooper Jr., Franklin 	if (ep->header == TI_EEPROM_HEADER_MAGIC)
46169e8d4baSCooper Jr., Franklin 		return true;
46269e8d4baSCooper Jr., Franklin 	else
46369e8d4baSCooper Jr., Franklin 		return false;
46469e8d4baSCooper Jr., Franklin }
465