xref: /rk3399_rockchip-uboot/board/ti/common/board_detect.c (revision e25ae3224f0119bf65eac8bf4e15e887e29940e8)
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  */
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
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  */
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  */
830bea813dSLokesh Vutla static int __maybe_unused ti_i2c_eeprom_read(int dev_addr, int offset,
840bea813dSLokesh Vutla 					     uchar *ep, int epsize)
850bea813dSLokesh Vutla {
86*e25ae322SCooper Jr., Franklin 	int bus_num, rc, alen;
87*e25ae322SCooper Jr., Franklin 
88*e25ae322SCooper Jr., Franklin 	bus_num = i2c_get_bus_num();
89*e25ae322SCooper Jr., Franklin 
90*e25ae322SCooper Jr., Franklin 	alen = 2;
91*e25ae322SCooper Jr., Franklin 
92*e25ae322SCooper Jr., Franklin 	rc = ti_i2c_set_alen(bus_num, dev_addr, alen);
93*e25ae322SCooper Jr., Franklin 	if (rc)
94*e25ae322SCooper Jr., Franklin 		return rc;
95*e25ae322SCooper Jr., Franklin 
96*e25ae322SCooper 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  */
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 
1190bea813dSLokesh Vutla __weak void gpi2c_init(void)
1200bea813dSLokesh Vutla {
1210bea813dSLokesh Vutla }
1220bea813dSLokesh Vutla 
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;
138*e25ae322SCooper Jr., Franklin 
139*e25ae322SCooper Jr., Franklin 	rc = ti_i2c_set_alen(bus_addr, dev_addr, byte);
140*e25ae322SCooper Jr., Franklin 	if (rc)
141*e25ae322SCooper Jr., Franklin 		return rc;
142*e25ae322SCooper 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;
155*e25ae322SCooper Jr., Franklin 		if (rc) {
156*e25ae322SCooper Jr., Franklin 			rc = ti_i2c_set_alen(bus_addr, dev_addr, byte);
1570bea813dSLokesh Vutla 			if (rc)
158*e25ae322SCooper Jr., Franklin 				return rc;
159*e25ae322SCooper Jr., Franklin 
1600bea813dSLokesh Vutla 			rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read,
1610bea813dSLokesh Vutla 				      4);
162*e25ae322SCooper 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 
1760bea813dSLokesh Vutla int __maybe_unused ti_i2c_eeprom_am_get(int bus_addr, int dev_addr)
1770bea813dSLokesh Vutla {
1780bea813dSLokesh Vutla 	int rc;
1790bea813dSLokesh Vutla 	struct ti_am_eeprom am_ep;
1800bea813dSLokesh Vutla 	struct ti_common_eeprom *ep;
1810bea813dSLokesh Vutla 
1820bea813dSLokesh Vutla 	ep = TI_EEPROM_DATA;
183a3a23c97SJean-Jacques Hiblot #ifndef CONFIG_SPL_BUILD
1840bea813dSLokesh Vutla 	if (ep->header == TI_EEPROM_HEADER_MAGIC)
185a3a23c97SJean-Jacques Hiblot 		return 0; /* EEPROM has already been read */
186a3a23c97SJean-Jacques Hiblot #endif
1870bea813dSLokesh Vutla 
1880bea813dSLokesh Vutla 	/* Initialize with a known bad marker for i2c fails.. */
1890bea813dSLokesh Vutla 	ep->header = TI_DEAD_EEPROM_MAGIC;
1900bea813dSLokesh Vutla 	ep->name[0] = 0x0;
1910bea813dSLokesh Vutla 	ep->version[0] = 0x0;
1920bea813dSLokesh Vutla 	ep->serial[0] = 0x0;
1932a78c9e7SNishanth Menon 	ep->config[0] = 0x0;
1940bea813dSLokesh Vutla 
1950bea813dSLokesh Vutla 	rc = ti_i2c_eeprom_get(bus_addr, dev_addr, TI_EEPROM_HEADER_MAGIC,
1960bea813dSLokesh Vutla 			       sizeof(am_ep), (uint8_t *)&am_ep);
1970bea813dSLokesh Vutla 	if (rc)
1980bea813dSLokesh Vutla 		return rc;
1990bea813dSLokesh Vutla 
2000bea813dSLokesh Vutla 	ep->header = am_ep.header;
2010bea813dSLokesh Vutla 	strlcpy(ep->name, am_ep.name, TI_EEPROM_HDR_NAME_LEN + 1);
2020bea813dSLokesh Vutla 	ti_eeprom_string_cleanup(ep->name);
2030bea813dSLokesh Vutla 
2040bea813dSLokesh Vutla 	/* BeagleBone Green '1' eeprom, board_rev: 0x1a 0x00 0x00 0x00 */
2050bea813dSLokesh Vutla 	if (am_ep.version[0] == 0x1a && am_ep.version[1] == 0x00 &&
2060bea813dSLokesh Vutla 	    am_ep.version[2] == 0x00 && am_ep.version[3] == 0x00)
2070bea813dSLokesh Vutla 		strlcpy(ep->version, "BBG1", TI_EEPROM_HDR_REV_LEN + 1);
2080bea813dSLokesh Vutla 	else
2090bea813dSLokesh Vutla 		strlcpy(ep->version, am_ep.version, TI_EEPROM_HDR_REV_LEN + 1);
2100bea813dSLokesh Vutla 	ti_eeprom_string_cleanup(ep->version);
2110bea813dSLokesh Vutla 	strlcpy(ep->serial, am_ep.serial, TI_EEPROM_HDR_SERIAL_LEN + 1);
2120bea813dSLokesh Vutla 	ti_eeprom_string_cleanup(ep->serial);
2130bea813dSLokesh Vutla 	strlcpy(ep->config, am_ep.config, TI_EEPROM_HDR_CONFIG_LEN + 1);
2140bea813dSLokesh Vutla 	ti_eeprom_string_cleanup(ep->config);
2150bea813dSLokesh Vutla 
2160bea813dSLokesh Vutla 	memcpy(ep->mac_addr, am_ep.mac_addr,
2170bea813dSLokesh Vutla 	       TI_EEPROM_HDR_NO_OF_MAC_ADDR * TI_EEPROM_HDR_ETH_ALEN);
2180bea813dSLokesh Vutla 
2190bea813dSLokesh Vutla 	return 0;
2200bea813dSLokesh Vutla }
2210bea813dSLokesh Vutla 
222d3b98a9eSLokesh Vutla int __maybe_unused ti_i2c_eeprom_dra7_get(int bus_addr, int dev_addr)
223d3b98a9eSLokesh Vutla {
224d3b98a9eSLokesh Vutla 	int rc, offset = 0;
225d3b98a9eSLokesh Vutla 	struct dra7_eeprom dra7_ep;
226d3b98a9eSLokesh Vutla 	struct ti_common_eeprom *ep;
227d3b98a9eSLokesh Vutla 
228d3b98a9eSLokesh Vutla 	ep = TI_EEPROM_DATA;
229a3a23c97SJean-Jacques Hiblot #ifndef CONFIG_SPL_BUILD
230d3b98a9eSLokesh Vutla 	if (ep->header == DRA7_EEPROM_HEADER_MAGIC)
231a3a23c97SJean-Jacques Hiblot 		return 0; /* EEPROM has already been read */
232a3a23c97SJean-Jacques Hiblot #endif
233d3b98a9eSLokesh Vutla 
234d3b98a9eSLokesh Vutla 	/* Initialize with a known bad marker for i2c fails.. */
23528d624beSNishanth Menon 	ep->header = TI_DEAD_EEPROM_MAGIC;
236d3b98a9eSLokesh Vutla 	ep->name[0] = 0x0;
237d3b98a9eSLokesh Vutla 	ep->version[0] = 0x0;
238d3b98a9eSLokesh Vutla 	ep->serial[0] = 0x0;
2392a78c9e7SNishanth Menon 	ep->config[0] = 0x0;
240d3b98a9eSLokesh Vutla 	ep->emif1_size = 0;
241d3b98a9eSLokesh Vutla 	ep->emif2_size = 0;
242d3b98a9eSLokesh Vutla 
243d3b98a9eSLokesh Vutla 	rc = ti_i2c_eeprom_get(bus_addr, dev_addr, DRA7_EEPROM_HEADER_MAGIC,
244d3b98a9eSLokesh Vutla 			       sizeof(dra7_ep), (uint8_t *)&dra7_ep);
245d3b98a9eSLokesh Vutla 	if (rc)
246d3b98a9eSLokesh Vutla 		return rc;
247d3b98a9eSLokesh Vutla 
248d3b98a9eSLokesh Vutla 	ep->header = dra7_ep.header;
249d3b98a9eSLokesh Vutla 	strlcpy(ep->name, dra7_ep.name, TI_EEPROM_HDR_NAME_LEN + 1);
250d3b98a9eSLokesh Vutla 	ti_eeprom_string_cleanup(ep->name);
251d3b98a9eSLokesh Vutla 
252d3b98a9eSLokesh Vutla 	offset = dra7_ep.version_major - 1;
253d3b98a9eSLokesh Vutla 
254d3b98a9eSLokesh Vutla 	/* Rev F is skipped */
255d3b98a9eSLokesh Vutla 	if (offset >= 5)
256d3b98a9eSLokesh Vutla 		offset = offset + 1;
257d3b98a9eSLokesh Vutla 	snprintf(ep->version, TI_EEPROM_HDR_REV_LEN + 1, "%c.%d",
258d3b98a9eSLokesh Vutla 		 'A' + offset, dra7_ep.version_minor);
259d3b98a9eSLokesh Vutla 	ti_eeprom_string_cleanup(ep->version);
260d3b98a9eSLokesh Vutla 	ep->emif1_size = (u64)dra7_ep.emif1_size;
261d3b98a9eSLokesh Vutla 	ep->emif2_size = (u64)dra7_ep.emif2_size;
262d3b98a9eSLokesh Vutla 	strlcpy(ep->config, dra7_ep.config, TI_EEPROM_HDR_CONFIG_LEN + 1);
263d3b98a9eSLokesh Vutla 	ti_eeprom_string_cleanup(ep->config);
264d3b98a9eSLokesh Vutla 
265d3b98a9eSLokesh Vutla 	return 0;
266d3b98a9eSLokesh Vutla }
267d3b98a9eSLokesh Vutla 
2680bea813dSLokesh Vutla bool __maybe_unused board_ti_is(char *name_tag)
2690bea813dSLokesh Vutla {
2700bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
2710bea813dSLokesh Vutla 
2720bea813dSLokesh Vutla 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
2730bea813dSLokesh Vutla 		return false;
2740bea813dSLokesh Vutla 	return !strncmp(ep->name, name_tag, TI_EEPROM_HDR_NAME_LEN);
2750bea813dSLokesh Vutla }
2760bea813dSLokesh Vutla 
2770bea813dSLokesh Vutla bool __maybe_unused board_ti_rev_is(char *rev_tag, int cmp_len)
2780bea813dSLokesh Vutla {
2790bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
2800bea813dSLokesh Vutla 	int l;
2810bea813dSLokesh Vutla 
2820bea813dSLokesh Vutla 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
2830bea813dSLokesh Vutla 		return false;
2840bea813dSLokesh Vutla 
2850bea813dSLokesh Vutla 	l = cmp_len > TI_EEPROM_HDR_REV_LEN ? TI_EEPROM_HDR_REV_LEN : cmp_len;
2860bea813dSLokesh Vutla 	return !strncmp(ep->version, rev_tag, l);
2870bea813dSLokesh Vutla }
2880bea813dSLokesh Vutla 
2890bea813dSLokesh Vutla char * __maybe_unused board_ti_get_rev(void)
2900bea813dSLokesh Vutla {
2910bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
2920bea813dSLokesh Vutla 
2937774e97aSNishanth Menon 	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
2940bea813dSLokesh Vutla 	return ep->version;
2950bea813dSLokesh Vutla }
2960bea813dSLokesh Vutla 
2970bea813dSLokesh Vutla char * __maybe_unused board_ti_get_config(void)
2980bea813dSLokesh Vutla {
2990bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
3000bea813dSLokesh Vutla 
3017774e97aSNishanth Menon 	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
3020bea813dSLokesh Vutla 	return ep->config;
3030bea813dSLokesh Vutla }
3040bea813dSLokesh Vutla 
3050bea813dSLokesh Vutla char * __maybe_unused board_ti_get_name(void)
3060bea813dSLokesh Vutla {
3070bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
3080bea813dSLokesh Vutla 
3097774e97aSNishanth Menon 	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
3100bea813dSLokesh Vutla 	return ep->name;
3110bea813dSLokesh Vutla }
3120bea813dSLokesh Vutla 
3130bea813dSLokesh Vutla void __maybe_unused
3140bea813dSLokesh Vutla board_ti_get_eth_mac_addr(int index,
3150bea813dSLokesh Vutla 			  u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])
3160bea813dSLokesh Vutla {
3170bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
3180bea813dSLokesh Vutla 
3190bea813dSLokesh Vutla 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
3200bea813dSLokesh Vutla 		goto fail;
3210bea813dSLokesh Vutla 
3220bea813dSLokesh Vutla 	if (index < 0 || index >= TI_EEPROM_HDR_NO_OF_MAC_ADDR)
3230bea813dSLokesh Vutla 		goto fail;
3240bea813dSLokesh Vutla 
3250bea813dSLokesh Vutla 	memcpy(mac_addr, ep->mac_addr[index], TI_EEPROM_HDR_ETH_ALEN);
3260bea813dSLokesh Vutla 	return;
3270bea813dSLokesh Vutla 
3280bea813dSLokesh Vutla fail:
3290bea813dSLokesh Vutla 	memset(mac_addr, 0, TI_EEPROM_HDR_ETH_ALEN);
3300bea813dSLokesh Vutla }
3310bea813dSLokesh Vutla 
332d3b98a9eSLokesh Vutla u64 __maybe_unused board_ti_get_emif1_size(void)
333d3b98a9eSLokesh Vutla {
334d3b98a9eSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
335d3b98a9eSLokesh Vutla 
336d3b98a9eSLokesh Vutla 	if (ep->header != DRA7_EEPROM_HEADER_MAGIC)
337d3b98a9eSLokesh Vutla 		return 0;
338d3b98a9eSLokesh Vutla 
339d3b98a9eSLokesh Vutla 	return ep->emif1_size;
340d3b98a9eSLokesh Vutla }
341d3b98a9eSLokesh Vutla 
342d3b98a9eSLokesh Vutla u64 __maybe_unused board_ti_get_emif2_size(void)
343d3b98a9eSLokesh Vutla {
344d3b98a9eSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
345d3b98a9eSLokesh Vutla 
346d3b98a9eSLokesh Vutla 	if (ep->header != DRA7_EEPROM_HEADER_MAGIC)
347d3b98a9eSLokesh Vutla 		return 0;
348d3b98a9eSLokesh Vutla 
349d3b98a9eSLokesh Vutla 	return ep->emif2_size;
350d3b98a9eSLokesh Vutla }
351d3b98a9eSLokesh Vutla 
3520bea813dSLokesh Vutla void __maybe_unused set_board_info_env(char *name)
3530bea813dSLokesh Vutla {
3540bea813dSLokesh Vutla 	char *unknown = "unknown";
3550bea813dSLokesh Vutla 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
3560bea813dSLokesh Vutla 
3570bea813dSLokesh Vutla 	if (name)
3580bea813dSLokesh Vutla 		setenv("board_name", name);
3590bea813dSLokesh Vutla 	else if (ep->name)
3600bea813dSLokesh Vutla 		setenv("board_name", ep->name);
3610bea813dSLokesh Vutla 	else
3620bea813dSLokesh Vutla 		setenv("board_name", unknown);
3630bea813dSLokesh Vutla 
3640bea813dSLokesh Vutla 	if (ep->version)
3650bea813dSLokesh Vutla 		setenv("board_rev", ep->version);
3660bea813dSLokesh Vutla 	else
3670bea813dSLokesh Vutla 		setenv("board_rev", unknown);
3680bea813dSLokesh Vutla 
3690bea813dSLokesh Vutla 	if (ep->serial)
3700bea813dSLokesh Vutla 		setenv("board_serial", ep->serial);
3710bea813dSLokesh Vutla 	else
3720bea813dSLokesh Vutla 		setenv("board_serial", unknown);
3730bea813dSLokesh Vutla }
37438f719eaSRoger Quadros 
37538f719eaSRoger Quadros static u64 mac_to_u64(u8 mac[6])
37638f719eaSRoger Quadros {
37738f719eaSRoger Quadros 	int i;
37838f719eaSRoger Quadros 	u64 addr = 0;
37938f719eaSRoger Quadros 
38038f719eaSRoger Quadros 	for (i = 0; i < 6; i++) {
38138f719eaSRoger Quadros 		addr <<= 8;
38238f719eaSRoger Quadros 		addr |= mac[i];
38338f719eaSRoger Quadros 	}
38438f719eaSRoger Quadros 
38538f719eaSRoger Quadros 	return addr;
38638f719eaSRoger Quadros }
38738f719eaSRoger Quadros 
38838f719eaSRoger Quadros static void u64_to_mac(u64 addr, u8 mac[6])
38938f719eaSRoger Quadros {
39038f719eaSRoger Quadros 	mac[5] = addr;
39138f719eaSRoger Quadros 	mac[4] = addr >> 8;
39238f719eaSRoger Quadros 	mac[3] = addr >> 16;
39338f719eaSRoger Quadros 	mac[2] = addr >> 24;
39438f719eaSRoger Quadros 	mac[1] = addr >> 32;
39538f719eaSRoger Quadros 	mac[0] = addr >> 40;
39638f719eaSRoger Quadros }
39738f719eaSRoger Quadros 
39838f719eaSRoger Quadros void board_ti_set_ethaddr(int index)
39938f719eaSRoger Quadros {
40038f719eaSRoger Quadros 	uint8_t mac_addr[6];
40138f719eaSRoger Quadros 	int i;
40238f719eaSRoger Quadros 	u64 mac1, mac2;
40338f719eaSRoger Quadros 	u8 mac_addr1[6], mac_addr2[6];
40438f719eaSRoger Quadros 	int num_macs;
40538f719eaSRoger Quadros 	/*
40638f719eaSRoger Quadros 	 * Export any Ethernet MAC addresses from EEPROM.
40738f719eaSRoger Quadros 	 * The 2 MAC addresses in EEPROM define the address range.
40838f719eaSRoger Quadros 	 */
40938f719eaSRoger Quadros 	board_ti_get_eth_mac_addr(0, mac_addr1);
41038f719eaSRoger Quadros 	board_ti_get_eth_mac_addr(1, mac_addr2);
41138f719eaSRoger Quadros 
41238f719eaSRoger Quadros 	if (is_valid_ethaddr(mac_addr1) && is_valid_ethaddr(mac_addr2)) {
41338f719eaSRoger Quadros 		mac1 = mac_to_u64(mac_addr1);
41438f719eaSRoger Quadros 		mac2 = mac_to_u64(mac_addr2);
41538f719eaSRoger Quadros 
41638f719eaSRoger Quadros 		/* must contain an address range */
41738f719eaSRoger Quadros 		num_macs = mac2 - mac1 + 1;
41838f719eaSRoger Quadros 		if (num_macs <= 0)
41938f719eaSRoger Quadros 			return;
42038f719eaSRoger Quadros 
42138f719eaSRoger Quadros 		if (num_macs > 50) {
42238f719eaSRoger Quadros 			printf("%s: Too many MAC addresses: %d. Limiting to 50\n",
42338f719eaSRoger Quadros 			       __func__, num_macs);
42438f719eaSRoger Quadros 			num_macs = 50;
42538f719eaSRoger Quadros 		}
42638f719eaSRoger Quadros 
42738f719eaSRoger Quadros 		for (i = 0; i < num_macs; i++) {
42838f719eaSRoger Quadros 			u64_to_mac(mac1 + i, mac_addr);
42938f719eaSRoger Quadros 			if (is_valid_ethaddr(mac_addr)) {
43038f719eaSRoger Quadros 				eth_setenv_enetaddr_by_index("eth", i + index,
43138f719eaSRoger Quadros 							     mac_addr);
43238f719eaSRoger Quadros 			}
43338f719eaSRoger Quadros 		}
43438f719eaSRoger Quadros 	}
43538f719eaSRoger Quadros }
436