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