xref: /rk3399_rockchip-uboot/board/ti/common/board_detect.c (revision fd1e959e91d2b0b2e853d09dd9167dfff18a616c)
10bea813dSLokesh Vutla /*
20bea813dSLokesh Vutla  * Library to support early TI EVM EEPROM handling
30bea813dSLokesh Vutla  *
40bea813dSLokesh Vutla  * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
50bea813dSLokesh Vutla  *	Lokesh Vutla
60bea813dSLokesh Vutla  *	Steve Kipisz
70bea813dSLokesh Vutla  *
80bea813dSLokesh Vutla  * SPDX-License-Identifier:    GPL-2.0+
90bea813dSLokesh Vutla  */
100bea813dSLokesh Vutla 
110bea813dSLokesh Vutla #include <common.h>
120bea813dSLokesh Vutla #include <asm/omap_common.h>
13c6b80b13SCooper Jr., Franklin #include <dm/uclass.h>
140bea813dSLokesh Vutla #include <i2c.h>
150bea813dSLokesh Vutla 
160bea813dSLokesh Vutla #include "board_detect.h"
170bea813dSLokesh Vutla 
18c6b80b13SCooper Jr., Franklin #if defined(CONFIG_DM_I2C_COMPAT)
19c6b80b13SCooper Jr., Franklin /**
20c6b80b13SCooper Jr., Franklin  * ti_i2c_set_alen - Set chip's i2c address length
21c6b80b13SCooper Jr., Franklin  * @bus_addr - I2C bus number
22c6b80b13SCooper Jr., Franklin  * @dev_addr - I2C eeprom id
23c6b80b13SCooper Jr., Franklin  * @alen     - I2C address length in bytes
24c6b80b13SCooper Jr., Franklin  *
25c6b80b13SCooper Jr., Franklin  * DM_I2C by default sets the address length to be used to 1. This
26c6b80b13SCooper Jr., Franklin  * function allows this address length to be changed to match the
27c6b80b13SCooper Jr., Franklin  * eeprom used for board detection.
28c6b80b13SCooper Jr., Franklin  */
ti_i2c_set_alen(int bus_addr,int dev_addr,int alen)29c6b80b13SCooper Jr., Franklin int __maybe_unused ti_i2c_set_alen(int bus_addr, int dev_addr, int alen)
30c6b80b13SCooper Jr., Franklin {
31c6b80b13SCooper Jr., Franklin 	struct udevice *dev;
32c6b80b13SCooper Jr., Franklin 	struct udevice *bus;
33c6b80b13SCooper Jr., Franklin 	int rc;
34c6b80b13SCooper Jr., Franklin 
35c6b80b13SCooper Jr., Franklin 	rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
36c6b80b13SCooper Jr., Franklin 	if (rc)
37c6b80b13SCooper Jr., Franklin 		return rc;
38c6b80b13SCooper Jr., Franklin 	rc = i2c_get_chip(bus, dev_addr, 1, &dev);
39c6b80b13SCooper Jr., Franklin 	if (rc)
40c6b80b13SCooper Jr., Franklin 		return rc;
41c6b80b13SCooper Jr., Franklin 	rc = i2c_set_chip_offset_len(dev, alen);
42c6b80b13SCooper Jr., Franklin 	if (rc)
43c6b80b13SCooper Jr., Franklin 		return rc;
44c6b80b13SCooper Jr., Franklin 
45c6b80b13SCooper Jr., Franklin 	return 0;
46c6b80b13SCooper Jr., Franklin }
47c6b80b13SCooper Jr., Franklin #else
ti_i2c_set_alen(int bus_addr,int dev_addr,int alen)48c6b80b13SCooper Jr., Franklin int __maybe_unused ti_i2c_set_alen(int bus_addr, int dev_addr, int alen)
49c6b80b13SCooper Jr., Franklin {
50c6b80b13SCooper Jr., Franklin 	return 0;
51c6b80b13SCooper Jr., Franklin }
52c6b80b13SCooper Jr., Franklin #endif
53c6b80b13SCooper Jr., Franklin 
540bea813dSLokesh Vutla /**
550bea813dSLokesh Vutla  * ti_i2c_eeprom_init - Initialize an i2c bus and probe for a device
560bea813dSLokesh Vutla  * @i2c_bus: i2c bus number to initialize
570bea813dSLokesh Vutla  * @dev_addr: Device address to probe for
580bea813dSLokesh Vutla  *
590bea813dSLokesh Vutla  * Return: 0 on success or corresponding error on failure.
600bea813dSLokesh Vutla  */
ti_i2c_eeprom_init(int i2c_bus,int dev_addr)610bea813dSLokesh Vutla static int __maybe_unused ti_i2c_eeprom_init(int i2c_bus, int dev_addr)
620bea813dSLokesh Vutla {
630bea813dSLokesh Vutla 	int rc;
640bea813dSLokesh Vutla 
650bea813dSLokesh Vutla 	if (i2c_bus >= 0) {
660bea813dSLokesh Vutla 		rc = i2c_set_bus_num(i2c_bus);
670bea813dSLokesh Vutla 		if (rc)
680bea813dSLokesh Vutla 			return rc;
690bea813dSLokesh Vutla 	}
700bea813dSLokesh Vutla 
710bea813dSLokesh Vutla 	return i2c_probe(dev_addr);
720bea813dSLokesh Vutla }
730bea813dSLokesh Vutla 
740bea813dSLokesh Vutla /**
750bea813dSLokesh Vutla  * ti_i2c_eeprom_read - Read data from an EEPROM
760bea813dSLokesh Vutla  * @dev_addr: The device address of the EEPROM
770bea813dSLokesh Vutla  * @offset: Offset to start reading in the EEPROM
780bea813dSLokesh Vutla  * @ep: Pointer to a buffer to read into
790bea813dSLokesh Vutla  * @epsize: Size of buffer
800bea813dSLokesh Vutla  *
810bea813dSLokesh Vutla  * Return: 0 on success or corresponding result of i2c_read
820bea813dSLokesh Vutla  */
ti_i2c_eeprom_read(int dev_addr,int offset,uchar * ep,int epsize)830bea813dSLokesh Vutla static int __maybe_unused ti_i2c_eeprom_read(int dev_addr, int offset,
840bea813dSLokesh Vutla 					     uchar *ep, int epsize)
850bea813dSLokesh Vutla {
86e25ae322SCooper Jr., Franklin 	int bus_num, rc, alen;
87e25ae322SCooper Jr., Franklin 
88e25ae322SCooper Jr., Franklin 	bus_num = i2c_get_bus_num();
89e25ae322SCooper Jr., Franklin 
90e25ae322SCooper Jr., Franklin 	alen = 2;
91e25ae322SCooper Jr., Franklin 
92e25ae322SCooper Jr., Franklin 	rc = ti_i2c_set_alen(bus_num, dev_addr, alen);
93e25ae322SCooper Jr., Franklin 	if (rc)
94e25ae322SCooper Jr., Franklin 		return rc;
95e25ae322SCooper Jr., Franklin 
96e25ae322SCooper Jr., Franklin 	return i2c_read(dev_addr, offset, alen, ep, epsize);
970bea813dSLokesh Vutla }
980bea813dSLokesh Vutla 
990bea813dSLokesh Vutla /**
1000bea813dSLokesh Vutla  * ti_eeprom_string_cleanup() - Handle eeprom programming errors
1010bea813dSLokesh Vutla  * @s:	eeprom string (should be NULL terminated)
1020bea813dSLokesh Vutla  *
1030bea813dSLokesh Vutla  * Some Board manufacturers do not add a NULL termination at the
1040bea813dSLokesh Vutla  * end of string, instead some binary information is kludged in, hence
1050bea813dSLokesh Vutla  * convert the string to just printable characters of ASCII chart.
1060bea813dSLokesh Vutla  */
ti_eeprom_string_cleanup(char * s)1070bea813dSLokesh Vutla static void __maybe_unused ti_eeprom_string_cleanup(char *s)
1080bea813dSLokesh Vutla {
1090bea813dSLokesh Vutla 	int i, l;
1100bea813dSLokesh Vutla 
1110bea813dSLokesh Vutla 	l = strlen(s);
1120bea813dSLokesh Vutla 	for (i = 0; i < l; i++, s++)
1130bea813dSLokesh Vutla 		if (*s < ' ' || *s > '~') {
1140bea813dSLokesh Vutla 			*s = 0;
1150bea813dSLokesh Vutla 			break;
1160bea813dSLokesh Vutla 		}
1170bea813dSLokesh Vutla }
1180bea813dSLokesh Vutla 
gpi2c_init(void)1190bea813dSLokesh Vutla __weak void gpi2c_init(void)
1200bea813dSLokesh Vutla {
1210bea813dSLokesh Vutla }
1220bea813dSLokesh Vutla 
ti_i2c_eeprom_get(int bus_addr,int dev_addr,u32 header,u32 size,uint8_t * ep)1230bea813dSLokesh Vutla static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr,
1240bea813dSLokesh Vutla 					    u32 header, u32 size, uint8_t *ep)
1250bea813dSLokesh Vutla {
1260bea813dSLokesh Vutla 	u32 byte, hdr_read;
1270bea813dSLokesh Vutla 	int rc;
1280bea813dSLokesh Vutla 
1290bea813dSLokesh Vutla 	gpi2c_init();
1300bea813dSLokesh Vutla 	rc = ti_i2c_eeprom_init(bus_addr, dev_addr);
1310bea813dSLokesh Vutla 	if (rc)
1320bea813dSLokesh Vutla 		return rc;
1330bea813dSLokesh Vutla 
1340bea813dSLokesh Vutla 	/*
1350bea813dSLokesh Vutla 	 * Read the header first then only read the other contents.
1360bea813dSLokesh Vutla 	 */
1370bea813dSLokesh Vutla 	byte = 2;
138e25ae322SCooper Jr., Franklin 
139e25ae322SCooper Jr., Franklin 	rc = ti_i2c_set_alen(bus_addr, dev_addr, byte);
140e25ae322SCooper Jr., Franklin 	if (rc)
141e25ae322SCooper Jr., Franklin 		return rc;
142e25ae322SCooper Jr., Franklin 
1430bea813dSLokesh Vutla 	rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read, 4);
1440bea813dSLokesh Vutla 	if (rc)
1450bea813dSLokesh Vutla 		return rc;
1460bea813dSLokesh Vutla 
1470bea813dSLokesh Vutla 	/* Corrupted data??? */
1480bea813dSLokesh Vutla 	if (hdr_read != header) {
1490bea813dSLokesh Vutla 		rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read, 4);
1500bea813dSLokesh Vutla 		/*
1510bea813dSLokesh Vutla 		 * read the eeprom header using i2c again, but use only a
1520bea813dSLokesh Vutla 		 * 1 byte address (some legacy boards need this..)
1530bea813dSLokesh Vutla 		 */
1540bea813dSLokesh Vutla 		byte = 1;
155e25ae322SCooper Jr., Franklin 		if (rc) {
156e25ae322SCooper Jr., Franklin 			rc = ti_i2c_set_alen(bus_addr, dev_addr, byte);
1570bea813dSLokesh Vutla 			if (rc)
158e25ae322SCooper Jr., Franklin 				return rc;
159e25ae322SCooper Jr., Franklin 
1600bea813dSLokesh Vutla 			rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read,
1610bea813dSLokesh Vutla 				      4);
162e25ae322SCooper Jr., Franklin 		}
1630bea813dSLokesh Vutla 		if (rc)
1640bea813dSLokesh Vutla 			return rc;
1650bea813dSLokesh Vutla 	}
1660bea813dSLokesh Vutla 	if (hdr_read != header)
1670bea813dSLokesh Vutla 		return -1;
1680bea813dSLokesh Vutla 
1690bea813dSLokesh Vutla 	rc = i2c_read(dev_addr, 0x0, byte, ep, size);
1700bea813dSLokesh Vutla 	if (rc)
1710bea813dSLokesh Vutla 		return rc;
1720bea813dSLokesh Vutla 
1730bea813dSLokesh Vutla 	return 0;
1740bea813dSLokesh Vutla }
1750bea813dSLokesh Vutla 
ti_i2c_eeprom_am_set(const char * name,const char * rev)176e936f997SNishanth Menon int __maybe_unused ti_i2c_eeprom_am_set(const char *name, const char *rev)
177e936f997SNishanth Menon {
178e936f997SNishanth Menon 	struct ti_common_eeprom *ep;
179e936f997SNishanth Menon 
180e936f997SNishanth Menon 	if (!name || !rev)
181e936f997SNishanth Menon 		return -1;
182e936f997SNishanth Menon 
183e936f997SNishanth Menon 	ep = TI_EEPROM_DATA;
184e936f997SNishanth Menon 	if (ep->header == TI_EEPROM_HEADER_MAGIC)
185e936f997SNishanth Menon 		goto already_set;
186e936f997SNishanth Menon 
187e936f997SNishanth Menon 	/* Set to 0 all fields */
188e936f997SNishanth Menon 	memset(ep, 0, sizeof(*ep));
189e936f997SNishanth Menon 	strncpy(ep->name, name, TI_EEPROM_HDR_NAME_LEN);
190e936f997SNishanth Menon 	strncpy(ep->version, rev, TI_EEPROM_HDR_REV_LEN);
191e936f997SNishanth Menon 	/* Some dummy serial number to identify the platform */
192e936f997SNishanth Menon 	strncpy(ep->serial, "0000", TI_EEPROM_HDR_SERIAL_LEN);
193e936f997SNishanth Menon 	/* Mark it with a valid header */
194e936f997SNishanth Menon 	ep->header = TI_EEPROM_HEADER_MAGIC;
195e936f997SNishanth Menon 
196e936f997SNishanth Menon already_set:
197e936f997SNishanth Menon 	return 0;
198e936f997SNishanth Menon }
199e936f997SNishanth Menon 
ti_i2c_eeprom_am_get(int bus_addr,int dev_addr)2000bea813dSLokesh Vutla int __maybe_unused ti_i2c_eeprom_am_get(int bus_addr, int dev_addr)
2010bea813dSLokesh Vutla {
2020bea813dSLokesh Vutla 	int rc;
2030bea813dSLokesh Vutla 	struct ti_am_eeprom am_ep;
2040bea813dSLokesh Vutla 	struct ti_common_eeprom *ep;
2050bea813dSLokesh Vutla 
2060bea813dSLokesh Vutla 	ep = TI_EEPROM_DATA;
207a3a23c97SJean-Jacques Hiblot #ifndef CONFIG_SPL_BUILD
2080bea813dSLokesh Vutla 	if (ep->header == TI_EEPROM_HEADER_MAGIC)
209a3a23c97SJean-Jacques Hiblot 		return 0; /* EEPROM has already been read */
210a3a23c97SJean-Jacques Hiblot #endif
2110bea813dSLokesh Vutla 
2120bea813dSLokesh Vutla 	/* Initialize with a known bad marker for i2c fails.. */
2130bea813dSLokesh Vutla 	ep->header = TI_DEAD_EEPROM_MAGIC;
2140bea813dSLokesh Vutla 	ep->name[0] = 0x0;
2150bea813dSLokesh Vutla 	ep->version[0] = 0x0;
2160bea813dSLokesh Vutla 	ep->serial[0] = 0x0;
2172a78c9e7SNishanth Menon 	ep->config[0] = 0x0;
2180bea813dSLokesh Vutla 
2190bea813dSLokesh Vutla 	rc = ti_i2c_eeprom_get(bus_addr, dev_addr, TI_EEPROM_HEADER_MAGIC,
2200bea813dSLokesh Vutla 			       sizeof(am_ep), (uint8_t *)&am_ep);
2210bea813dSLokesh Vutla 	if (rc)
2220bea813dSLokesh Vutla 		return rc;
2230bea813dSLokesh Vutla 
2240bea813dSLokesh Vutla 	ep->header = am_ep.header;
2250bea813dSLokesh Vutla 	strlcpy(ep->name, am_ep.name, TI_EEPROM_HDR_NAME_LEN + 1);
2260bea813dSLokesh Vutla 	ti_eeprom_string_cleanup(ep->name);
2270bea813dSLokesh Vutla 
2280bea813dSLokesh Vutla 	/* BeagleBone Green '1' eeprom, board_rev: 0x1a 0x00 0x00 0x00 */
2290bea813dSLokesh Vutla 	if (am_ep.version[0] == 0x1a && am_ep.version[1] == 0x00 &&
2300bea813dSLokesh Vutla 	    am_ep.version[2] == 0x00 && am_ep.version[3] == 0x00)
2310bea813dSLokesh Vutla 		strlcpy(ep->version, "BBG1", TI_EEPROM_HDR_REV_LEN + 1);
2320bea813dSLokesh Vutla 	else
2330bea813dSLokesh Vutla 		strlcpy(ep->version, am_ep.version, TI_EEPROM_HDR_REV_LEN + 1);
2340bea813dSLokesh Vutla 	ti_eeprom_string_cleanup(ep->version);
2350bea813dSLokesh Vutla 	strlcpy(ep->serial, am_ep.serial, TI_EEPROM_HDR_SERIAL_LEN + 1);
2360bea813dSLokesh Vutla 	ti_eeprom_string_cleanup(ep->serial);
2370bea813dSLokesh Vutla 	strlcpy(ep->config, am_ep.config, TI_EEPROM_HDR_CONFIG_LEN + 1);
2380bea813dSLokesh Vutla 	ti_eeprom_string_cleanup(ep->config);
2390bea813dSLokesh Vutla 
2400bea813dSLokesh Vutla 	memcpy(ep->mac_addr, am_ep.mac_addr,
2410bea813dSLokesh Vutla 	       TI_EEPROM_HDR_NO_OF_MAC_ADDR * TI_EEPROM_HDR_ETH_ALEN);
2420bea813dSLokesh Vutla 
2430bea813dSLokesh Vutla 	return 0;
2440bea813dSLokesh Vutla }
2450bea813dSLokesh Vutla 
ti_i2c_eeprom_dra7_get(int bus_addr,int dev_addr)246d3b98a9eSLokesh Vutla int __maybe_unused ti_i2c_eeprom_dra7_get(int bus_addr, int dev_addr)
247d3b98a9eSLokesh Vutla {
248d3b98a9eSLokesh Vutla 	int rc, offset = 0;
249d3b98a9eSLokesh Vutla 	struct dra7_eeprom dra7_ep;
250d3b98a9eSLokesh Vutla 	struct ti_common_eeprom *ep;
251d3b98a9eSLokesh Vutla 
252d3b98a9eSLokesh Vutla 	ep = TI_EEPROM_DATA;
253a3a23c97SJean-Jacques Hiblot #ifndef CONFIG_SPL_BUILD
254d3b98a9eSLokesh Vutla 	if (ep->header == DRA7_EEPROM_HEADER_MAGIC)
255a3a23c97SJean-Jacques Hiblot 		return 0; /* EEPROM has already been read */
256a3a23c97SJean-Jacques Hiblot #endif
257d3b98a9eSLokesh Vutla 
258d3b98a9eSLokesh Vutla 	/* Initialize with a known bad marker for i2c fails.. */
25928d624beSNishanth Menon 	ep->header = TI_DEAD_EEPROM_MAGIC;
260d3b98a9eSLokesh Vutla 	ep->name[0] = 0x0;
261d3b98a9eSLokesh Vutla 	ep->version[0] = 0x0;
262d3b98a9eSLokesh Vutla 	ep->serial[0] = 0x0;
2632a78c9e7SNishanth Menon 	ep->config[0] = 0x0;
264d3b98a9eSLokesh Vutla 	ep->emif1_size = 0;
265d3b98a9eSLokesh Vutla 	ep->emif2_size = 0;
266d3b98a9eSLokesh Vutla 
267d3b98a9eSLokesh Vutla 	rc = ti_i2c_eeprom_get(bus_addr, dev_addr, DRA7_EEPROM_HEADER_MAGIC,
268d3b98a9eSLokesh Vutla 			       sizeof(dra7_ep), (uint8_t *)&dra7_ep);
269d3b98a9eSLokesh Vutla 	if (rc)
270d3b98a9eSLokesh Vutla 		return rc;
271d3b98a9eSLokesh Vutla 
272d3b98a9eSLokesh Vutla 	ep->header = dra7_ep.header;
273d3b98a9eSLokesh Vutla 	strlcpy(ep->name, dra7_ep.name, TI_EEPROM_HDR_NAME_LEN + 1);
274d3b98a9eSLokesh Vutla 	ti_eeprom_string_cleanup(ep->name);
275d3b98a9eSLokesh Vutla 
276d3b98a9eSLokesh Vutla 	offset = dra7_ep.version_major - 1;
277d3b98a9eSLokesh Vutla 
278d3b98a9eSLokesh Vutla 	/* Rev F is skipped */
279d3b98a9eSLokesh Vutla 	if (offset >= 5)
280d3b98a9eSLokesh Vutla 		offset = offset + 1;
281d3b98a9eSLokesh Vutla 	snprintf(ep->version, TI_EEPROM_HDR_REV_LEN + 1, "%c.%d",
282d3b98a9eSLokesh Vutla 		 'A' + offset, dra7_ep.version_minor);
283d3b98a9eSLokesh Vutla 	ti_eeprom_string_cleanup(ep->version);
284d3b98a9eSLokesh Vutla 	ep->emif1_size = (u64)dra7_ep.emif1_size;
285d3b98a9eSLokesh Vutla 	ep->emif2_size = (u64)dra7_ep.emif2_size;
286d3b98a9eSLokesh Vutla 	strlcpy(ep->config, dra7_ep.config, TI_EEPROM_HDR_CONFIG_LEN + 1);
287d3b98a9eSLokesh Vutla 	ti_eeprom_string_cleanup(ep->config);
288d3b98a9eSLokesh Vutla 
289d3b98a9eSLokesh Vutla 	return 0;
290d3b98a9eSLokesh Vutla }
291d3b98a9eSLokesh Vutla 
board_ti_is(char * name_tag)2920bea813dSLokesh Vutla bool __maybe_unused board_ti_is(char *name_tag)
2930bea813dSLokesh Vutla {
2940bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
2950bea813dSLokesh Vutla 
2960bea813dSLokesh Vutla 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
2970bea813dSLokesh Vutla 		return false;
2980bea813dSLokesh Vutla 	return !strncmp(ep->name, name_tag, TI_EEPROM_HDR_NAME_LEN);
2990bea813dSLokesh Vutla }
3000bea813dSLokesh Vutla 
board_ti_rev_is(char * rev_tag,int cmp_len)3010bea813dSLokesh Vutla bool __maybe_unused board_ti_rev_is(char *rev_tag, int cmp_len)
3020bea813dSLokesh Vutla {
3030bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
3040bea813dSLokesh Vutla 	int l;
3050bea813dSLokesh Vutla 
3060bea813dSLokesh Vutla 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
3070bea813dSLokesh Vutla 		return false;
3080bea813dSLokesh Vutla 
3090bea813dSLokesh Vutla 	l = cmp_len > TI_EEPROM_HDR_REV_LEN ? TI_EEPROM_HDR_REV_LEN : cmp_len;
3100bea813dSLokesh Vutla 	return !strncmp(ep->version, rev_tag, l);
3110bea813dSLokesh Vutla }
3120bea813dSLokesh Vutla 
board_ti_get_rev(void)3130bea813dSLokesh Vutla char * __maybe_unused board_ti_get_rev(void)
3140bea813dSLokesh Vutla {
3150bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
3160bea813dSLokesh Vutla 
3177774e97aSNishanth Menon 	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
3180bea813dSLokesh Vutla 	return ep->version;
3190bea813dSLokesh Vutla }
3200bea813dSLokesh Vutla 
board_ti_get_config(void)3210bea813dSLokesh Vutla char * __maybe_unused board_ti_get_config(void)
3220bea813dSLokesh Vutla {
3230bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
3240bea813dSLokesh Vutla 
3257774e97aSNishanth Menon 	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
3260bea813dSLokesh Vutla 	return ep->config;
3270bea813dSLokesh Vutla }
3280bea813dSLokesh Vutla 
board_ti_get_name(void)3290bea813dSLokesh Vutla char * __maybe_unused board_ti_get_name(void)
3300bea813dSLokesh Vutla {
3310bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
3320bea813dSLokesh Vutla 
3337774e97aSNishanth Menon 	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
3340bea813dSLokesh Vutla 	return ep->name;
3350bea813dSLokesh Vutla }
3360bea813dSLokesh Vutla 
3370bea813dSLokesh Vutla void __maybe_unused
board_ti_get_eth_mac_addr(int index,u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])3380bea813dSLokesh Vutla board_ti_get_eth_mac_addr(int index,
3390bea813dSLokesh Vutla 			  u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])
3400bea813dSLokesh Vutla {
3410bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
3420bea813dSLokesh Vutla 
3430bea813dSLokesh Vutla 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
3440bea813dSLokesh Vutla 		goto fail;
3450bea813dSLokesh Vutla 
3460bea813dSLokesh Vutla 	if (index < 0 || index >= TI_EEPROM_HDR_NO_OF_MAC_ADDR)
3470bea813dSLokesh Vutla 		goto fail;
3480bea813dSLokesh Vutla 
3490bea813dSLokesh Vutla 	memcpy(mac_addr, ep->mac_addr[index], TI_EEPROM_HDR_ETH_ALEN);
3500bea813dSLokesh Vutla 	return;
3510bea813dSLokesh Vutla 
3520bea813dSLokesh Vutla fail:
3530bea813dSLokesh Vutla 	memset(mac_addr, 0, TI_EEPROM_HDR_ETH_ALEN);
3540bea813dSLokesh Vutla }
3550bea813dSLokesh Vutla 
board_ti_get_emif1_size(void)356d3b98a9eSLokesh Vutla u64 __maybe_unused board_ti_get_emif1_size(void)
357d3b98a9eSLokesh Vutla {
358d3b98a9eSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
359d3b98a9eSLokesh Vutla 
360d3b98a9eSLokesh Vutla 	if (ep->header != DRA7_EEPROM_HEADER_MAGIC)
361d3b98a9eSLokesh Vutla 		return 0;
362d3b98a9eSLokesh Vutla 
363d3b98a9eSLokesh Vutla 	return ep->emif1_size;
364d3b98a9eSLokesh Vutla }
365d3b98a9eSLokesh Vutla 
board_ti_get_emif2_size(void)366d3b98a9eSLokesh Vutla u64 __maybe_unused board_ti_get_emif2_size(void)
367d3b98a9eSLokesh Vutla {
368d3b98a9eSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
369d3b98a9eSLokesh Vutla 
370d3b98a9eSLokesh Vutla 	if (ep->header != DRA7_EEPROM_HEADER_MAGIC)
371d3b98a9eSLokesh Vutla 		return 0;
372d3b98a9eSLokesh Vutla 
373d3b98a9eSLokesh Vutla 	return ep->emif2_size;
374d3b98a9eSLokesh Vutla }
375d3b98a9eSLokesh Vutla 
set_board_info_env(char * name)3760bea813dSLokesh Vutla void __maybe_unused set_board_info_env(char *name)
3770bea813dSLokesh Vutla {
3780bea813dSLokesh Vutla 	char *unknown = "unknown";
3790bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
3800bea813dSLokesh Vutla 
3810bea813dSLokesh Vutla 	if (name)
382382bee57SSimon Glass 		env_set("board_name", name);
3830bea813dSLokesh Vutla 	else if (ep->name)
384382bee57SSimon Glass 		env_set("board_name", ep->name);
3850bea813dSLokesh Vutla 	else
386382bee57SSimon Glass 		env_set("board_name", unknown);
3870bea813dSLokesh Vutla 
3880bea813dSLokesh Vutla 	if (ep->version)
389382bee57SSimon Glass 		env_set("board_rev", ep->version);
3900bea813dSLokesh Vutla 	else
391382bee57SSimon Glass 		env_set("board_rev", unknown);
3920bea813dSLokesh Vutla 
3930bea813dSLokesh Vutla 	if (ep->serial)
394382bee57SSimon Glass 		env_set("board_serial", ep->serial);
3950bea813dSLokesh Vutla 	else
396382bee57SSimon Glass 		env_set("board_serial", unknown);
3970bea813dSLokesh Vutla }
39838f719eaSRoger Quadros 
mac_to_u64(u8 mac[6])39938f719eaSRoger Quadros static u64 mac_to_u64(u8 mac[6])
40038f719eaSRoger Quadros {
40138f719eaSRoger Quadros 	int i;
40238f719eaSRoger Quadros 	u64 addr = 0;
40338f719eaSRoger Quadros 
40438f719eaSRoger Quadros 	for (i = 0; i < 6; i++) {
40538f719eaSRoger Quadros 		addr <<= 8;
40638f719eaSRoger Quadros 		addr |= mac[i];
40738f719eaSRoger Quadros 	}
40838f719eaSRoger Quadros 
40938f719eaSRoger Quadros 	return addr;
41038f719eaSRoger Quadros }
41138f719eaSRoger Quadros 
u64_to_mac(u64 addr,u8 mac[6])41238f719eaSRoger Quadros static void u64_to_mac(u64 addr, u8 mac[6])
41338f719eaSRoger Quadros {
41438f719eaSRoger Quadros 	mac[5] = addr;
41538f719eaSRoger Quadros 	mac[4] = addr >> 8;
41638f719eaSRoger Quadros 	mac[3] = addr >> 16;
41738f719eaSRoger Quadros 	mac[2] = addr >> 24;
41838f719eaSRoger Quadros 	mac[1] = addr >> 32;
41938f719eaSRoger Quadros 	mac[0] = addr >> 40;
42038f719eaSRoger Quadros }
42138f719eaSRoger Quadros 
board_ti_set_ethaddr(int index)42238f719eaSRoger Quadros void board_ti_set_ethaddr(int index)
42338f719eaSRoger Quadros {
42438f719eaSRoger Quadros 	uint8_t mac_addr[6];
42538f719eaSRoger Quadros 	int i;
42638f719eaSRoger Quadros 	u64 mac1, mac2;
42738f719eaSRoger Quadros 	u8 mac_addr1[6], mac_addr2[6];
42838f719eaSRoger Quadros 	int num_macs;
42938f719eaSRoger Quadros 	/*
43038f719eaSRoger Quadros 	 * Export any Ethernet MAC addresses from EEPROM.
43138f719eaSRoger Quadros 	 * The 2 MAC addresses in EEPROM define the address range.
43238f719eaSRoger Quadros 	 */
43338f719eaSRoger Quadros 	board_ti_get_eth_mac_addr(0, mac_addr1);
43438f719eaSRoger Quadros 	board_ti_get_eth_mac_addr(1, mac_addr2);
43538f719eaSRoger Quadros 
43638f719eaSRoger Quadros 	if (is_valid_ethaddr(mac_addr1) && is_valid_ethaddr(mac_addr2)) {
43738f719eaSRoger Quadros 		mac1 = mac_to_u64(mac_addr1);
43838f719eaSRoger Quadros 		mac2 = mac_to_u64(mac_addr2);
43938f719eaSRoger Quadros 
44038f719eaSRoger Quadros 		/* must contain an address range */
44138f719eaSRoger Quadros 		num_macs = mac2 - mac1 + 1;
44238f719eaSRoger Quadros 		if (num_macs <= 0)
44338f719eaSRoger Quadros 			return;
44438f719eaSRoger Quadros 
44538f719eaSRoger Quadros 		if (num_macs > 50) {
44638f719eaSRoger Quadros 			printf("%s: Too many MAC addresses: %d. Limiting to 50\n",
44738f719eaSRoger Quadros 			       __func__, num_macs);
44838f719eaSRoger Quadros 			num_macs = 50;
44938f719eaSRoger Quadros 		}
45038f719eaSRoger Quadros 
45138f719eaSRoger Quadros 		for (i = 0; i < num_macs; i++) {
45238f719eaSRoger Quadros 			u64_to_mac(mac1 + i, mac_addr);
45338f719eaSRoger Quadros 			if (is_valid_ethaddr(mac_addr)) {
454*fd1e959eSSimon Glass 				eth_env_set_enetaddr_by_index("eth", i + index,
45538f719eaSRoger Quadros 							      mac_addr);
45638f719eaSRoger Quadros 			}
45738f719eaSRoger Quadros 		}
45838f719eaSRoger Quadros 	}
45938f719eaSRoger Quadros }
46069e8d4baSCooper Jr., Franklin 
board_ti_was_eeprom_read(void)46169e8d4baSCooper Jr., Franklin bool __maybe_unused board_ti_was_eeprom_read(void)
46269e8d4baSCooper Jr., Franklin {
46369e8d4baSCooper Jr., Franklin 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
46469e8d4baSCooper Jr., Franklin 
46569e8d4baSCooper Jr., Franklin 	if (ep->header == TI_EEPROM_HEADER_MAGIC)
46669e8d4baSCooper Jr., Franklin 		return true;
46769e8d4baSCooper Jr., Franklin 	else
46869e8d4baSCooper Jr., Franklin 		return false;
46969e8d4baSCooper Jr., Franklin }
470