Home | History | Annotate | Download | only in common
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * Library to support early TI EVM EEPROM handling
      4  *
      5  * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
      6  *	Lokesh Vutla
      7  *	Steve Kipisz
      8  */
      9 
     10 #include <common.h>
     11 #include <asm/omap_common.h>
     12 #include <dm/uclass.h>
     13 #include <i2c.h>
     14 
     15 #include "board_detect.h"
     16 
     17 #if defined(CONFIG_DM_I2C_COMPAT)
     18 /**
     19  * ti_i2c_set_alen - Set chip's i2c address length
     20  * @bus_addr - I2C bus number
     21  * @dev_addr - I2C eeprom id
     22  * @alen     - I2C address length in bytes
     23  *
     24  * DM_I2C by default sets the address length to be used to 1. This
     25  * function allows this address length to be changed to match the
     26  * eeprom used for board detection.
     27  */
     28 int __maybe_unused ti_i2c_set_alen(int bus_addr, int dev_addr, int alen)
     29 {
     30 	struct udevice *dev;
     31 	struct udevice *bus;
     32 	int rc;
     33 
     34 	rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
     35 	if (rc)
     36 		return rc;
     37 	rc = i2c_get_chip(bus, dev_addr, 1, &dev);
     38 	if (rc)
     39 		return rc;
     40 	rc = i2c_set_chip_offset_len(dev, alen);
     41 	if (rc)
     42 		return rc;
     43 
     44 	return 0;
     45 }
     46 #else
     47 int __maybe_unused ti_i2c_set_alen(int bus_addr, int dev_addr, int alen)
     48 {
     49 	return 0;
     50 }
     51 #endif
     52 
     53 /**
     54  * ti_i2c_eeprom_init - Initialize an i2c bus and probe for a device
     55  * @i2c_bus: i2c bus number to initialize
     56  * @dev_addr: Device address to probe for
     57  *
     58  * Return: 0 on success or corresponding error on failure.
     59  */
     60 static int __maybe_unused ti_i2c_eeprom_init(int i2c_bus, int dev_addr)
     61 {
     62 	int rc;
     63 
     64 	if (i2c_bus >= 0) {
     65 		rc = i2c_set_bus_num(i2c_bus);
     66 		if (rc)
     67 			return rc;
     68 	}
     69 
     70 	return i2c_probe(dev_addr);
     71 }
     72 
     73 /**
     74  * ti_i2c_eeprom_read - Read data from an EEPROM
     75  * @dev_addr: The device address of the EEPROM
     76  * @offset: Offset to start reading in the EEPROM
     77  * @ep: Pointer to a buffer to read into
     78  * @epsize: Size of buffer
     79  *
     80  * Return: 0 on success or corresponding result of i2c_read
     81  */
     82 static int __maybe_unused ti_i2c_eeprom_read(int dev_addr, int offset,
     83 					     uchar *ep, int epsize)
     84 {
     85 	int bus_num, rc, alen;
     86 
     87 	bus_num = i2c_get_bus_num();
     88 
     89 	alen = 2;
     90 
     91 	rc = ti_i2c_set_alen(bus_num, dev_addr, alen);
     92 	if (rc)
     93 		return rc;
     94 
     95 	return i2c_read(dev_addr, offset, alen, ep, epsize);
     96 }
     97 
     98 /**
     99  * ti_eeprom_string_cleanup() - Handle eeprom programming errors
    100  * @s:	eeprom string (should be NULL terminated)
    101  *
    102  * Some Board manufacturers do not add a NULL termination at the
    103  * end of string, instead some binary information is kludged in, hence
    104  * convert the string to just printable characters of ASCII chart.
    105  */
    106 static void __maybe_unused ti_eeprom_string_cleanup(char *s)
    107 {
    108 	int i, l;
    109 
    110 	l = strlen(s);
    111 	for (i = 0; i < l; i++, s++)
    112 		if (*s < ' ' || *s > '~') {
    113 			*s = 0;
    114 			break;
    115 		}
    116 }
    117 
    118 __weak void gpi2c_init(void)
    119 {
    120 }
    121 
    122 static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr,
    123 					    u32 header, u32 size, uint8_t *ep)
    124 {
    125 	u32 byte, hdr_read;
    126 	int rc;
    127 
    128 	gpi2c_init();
    129 	rc = ti_i2c_eeprom_init(bus_addr, dev_addr);
    130 	if (rc)
    131 		return rc;
    132 
    133 	/*
    134 	 * Read the header first then only read the other contents.
    135 	 */
    136 	byte = 2;
    137 
    138 	rc = ti_i2c_set_alen(bus_addr, dev_addr, byte);
    139 	if (rc)
    140 		return rc;
    141 
    142 	rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read, 4);
    143 	if (rc)
    144 		return rc;
    145 
    146 	/* Corrupted data??? */
    147 	if (hdr_read != header) {
    148 		rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read, 4);
    149 		/*
    150 		 * read the eeprom header using i2c again, but use only a
    151 		 * 1 byte address (some legacy boards need this..)
    152 		 */
    153 		byte = 1;
    154 		if (rc) {
    155 			rc = ti_i2c_set_alen(bus_addr, dev_addr, byte);
    156 			if (rc)
    157 				return rc;
    158 
    159 			rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read,
    160 				      4);
    161 		}
    162 		if (rc)
    163 			return rc;
    164 	}
    165 	if (hdr_read != header)
    166 		return -1;
    167 
    168 	rc = i2c_read(dev_addr, 0x0, byte, ep, size);
    169 	if (rc)
    170 		return rc;
    171 
    172 	return 0;
    173 }
    174 
    175 int __maybe_unused ti_i2c_eeprom_am_set(const char *name, const char *rev)
    176 {
    177 	struct ti_common_eeprom *ep;
    178 
    179 	if (!name || !rev)
    180 		return -1;
    181 
    182 	ep = TI_EEPROM_DATA;
    183 	if (ep->header == TI_EEPROM_HEADER_MAGIC)
    184 		goto already_set;
    185 
    186 	/* Set to 0 all fields */
    187 	memset(ep, 0, sizeof(*ep));
    188 	strncpy(ep->name, name, TI_EEPROM_HDR_NAME_LEN);
    189 	strncpy(ep->version, rev, TI_EEPROM_HDR_REV_LEN);
    190 	/* Some dummy serial number to identify the platform */
    191 	strncpy(ep->serial, "0000", TI_EEPROM_HDR_SERIAL_LEN);
    192 	/* Mark it with a valid header */
    193 	ep->header = TI_EEPROM_HEADER_MAGIC;
    194 
    195 already_set:
    196 	return 0;
    197 }
    198 
    199 int __maybe_unused ti_i2c_eeprom_am_get(int bus_addr, int dev_addr)
    200 {
    201 	int rc;
    202 	struct ti_am_eeprom am_ep;
    203 	struct ti_common_eeprom *ep;
    204 
    205 	ep = TI_EEPROM_DATA;
    206 #ifndef CONFIG_SPL_BUILD
    207 	if (ep->header == TI_EEPROM_HEADER_MAGIC)
    208 		return 0; /* EEPROM has already been read */
    209 #endif
    210 
    211 	/* Initialize with a known bad marker for i2c fails.. */
    212 	ep->header = TI_DEAD_EEPROM_MAGIC;
    213 	ep->name[0] = 0x0;
    214 	ep->version[0] = 0x0;
    215 	ep->serial[0] = 0x0;
    216 	ep->config[0] = 0x0;
    217 
    218 	rc = ti_i2c_eeprom_get(bus_addr, dev_addr, TI_EEPROM_HEADER_MAGIC,
    219 			       sizeof(am_ep), (uint8_t *)&am_ep);
    220 	if (rc)
    221 		return rc;
    222 
    223 	ep->header = am_ep.header;
    224 	strlcpy(ep->name, am_ep.name, TI_EEPROM_HDR_NAME_LEN + 1);
    225 	ti_eeprom_string_cleanup(ep->name);
    226 
    227 	/* BeagleBone Green '1' eeprom, board_rev: 0x1a 0x00 0x00 0x00 */
    228 	if (am_ep.version[0] == 0x1a && am_ep.version[1] == 0x00 &&
    229 	    am_ep.version[2] == 0x00 && am_ep.version[3] == 0x00)
    230 		strlcpy(ep->version, "BBG1", TI_EEPROM_HDR_REV_LEN + 1);
    231 	else
    232 		strlcpy(ep->version, am_ep.version, TI_EEPROM_HDR_REV_LEN + 1);
    233 	ti_eeprom_string_cleanup(ep->version);
    234 	strlcpy(ep->serial, am_ep.serial, TI_EEPROM_HDR_SERIAL_LEN + 1);
    235 	ti_eeprom_string_cleanup(ep->serial);
    236 	strlcpy(ep->config, am_ep.config, TI_EEPROM_HDR_CONFIG_LEN + 1);
    237 	ti_eeprom_string_cleanup(ep->config);
    238 
    239 	memcpy(ep->mac_addr, am_ep.mac_addr,
    240 	       TI_EEPROM_HDR_NO_OF_MAC_ADDR * TI_EEPROM_HDR_ETH_ALEN);
    241 
    242 	return 0;
    243 }
    244 
    245 int __maybe_unused ti_i2c_eeprom_dra7_get(int bus_addr, int dev_addr)
    246 {
    247 	int rc, offset = 0;
    248 	struct dra7_eeprom dra7_ep;
    249 	struct ti_common_eeprom *ep;
    250 
    251 	ep = TI_EEPROM_DATA;
    252 #ifndef CONFIG_SPL_BUILD
    253 	if (ep->header == DRA7_EEPROM_HEADER_MAGIC)
    254 		return 0; /* EEPROM has already been read */
    255 #endif
    256 
    257 	/* Initialize with a known bad marker for i2c fails.. */
    258 	ep->header = TI_DEAD_EEPROM_MAGIC;
    259 	ep->name[0] = 0x0;
    260 	ep->version[0] = 0x0;
    261 	ep->serial[0] = 0x0;
    262 	ep->config[0] = 0x0;
    263 	ep->emif1_size = 0;
    264 	ep->emif2_size = 0;
    265 
    266 	rc = ti_i2c_eeprom_get(bus_addr, dev_addr, DRA7_EEPROM_HEADER_MAGIC,
    267 			       sizeof(dra7_ep), (uint8_t *)&dra7_ep);
    268 	if (rc)
    269 		return rc;
    270 
    271 	ep->header = dra7_ep.header;
    272 	strlcpy(ep->name, dra7_ep.name, TI_EEPROM_HDR_NAME_LEN + 1);
    273 	ti_eeprom_string_cleanup(ep->name);
    274 
    275 	offset = dra7_ep.version_major - 1;
    276 
    277 	/* Rev F is skipped */
    278 	if (offset >= 5)
    279 		offset = offset + 1;
    280 	snprintf(ep->version, TI_EEPROM_HDR_REV_LEN + 1, "%c.%d",
    281 		 'A' + offset, dra7_ep.version_minor);
    282 	ti_eeprom_string_cleanup(ep->version);
    283 	ep->emif1_size = (u64)dra7_ep.emif1_size;
    284 	ep->emif2_size = (u64)dra7_ep.emif2_size;
    285 	strlcpy(ep->config, dra7_ep.config, TI_EEPROM_HDR_CONFIG_LEN + 1);
    286 	ti_eeprom_string_cleanup(ep->config);
    287 
    288 	return 0;
    289 }
    290 
    291 bool __maybe_unused board_ti_is(char *name_tag)
    292 {
    293 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
    294 
    295 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
    296 		return false;
    297 	return !strncmp(ep->name, name_tag, TI_EEPROM_HDR_NAME_LEN);
    298 }
    299 
    300 bool __maybe_unused board_ti_rev_is(char *rev_tag, int cmp_len)
    301 {
    302 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
    303 	int l;
    304 
    305 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
    306 		return false;
    307 
    308 	l = cmp_len > TI_EEPROM_HDR_REV_LEN ? TI_EEPROM_HDR_REV_LEN : cmp_len;
    309 	return !strncmp(ep->version, rev_tag, l);
    310 }
    311 
    312 char * __maybe_unused board_ti_get_rev(void)
    313 {
    314 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
    315 
    316 	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
    317 	return ep->version;
    318 }
    319 
    320 char * __maybe_unused board_ti_get_config(void)
    321 {
    322 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
    323 
    324 	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
    325 	return ep->config;
    326 }
    327 
    328 char * __maybe_unused board_ti_get_name(void)
    329 {
    330 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
    331 
    332 	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
    333 	return ep->name;
    334 }
    335 
    336 void __maybe_unused
    337 board_ti_get_eth_mac_addr(int index,
    338 			  u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])
    339 {
    340 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
    341 
    342 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
    343 		goto fail;
    344 
    345 	if (index < 0 || index >= TI_EEPROM_HDR_NO_OF_MAC_ADDR)
    346 		goto fail;
    347 
    348 	memcpy(mac_addr, ep->mac_addr[index], TI_EEPROM_HDR_ETH_ALEN);
    349 	return;
    350 
    351 fail:
    352 	memset(mac_addr, 0, TI_EEPROM_HDR_ETH_ALEN);
    353 }
    354 
    355 u64 __maybe_unused board_ti_get_emif1_size(void)
    356 {
    357 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
    358 
    359 	if (ep->header != DRA7_EEPROM_HEADER_MAGIC)
    360 		return 0;
    361 
    362 	return ep->emif1_size;
    363 }
    364 
    365 u64 __maybe_unused board_ti_get_emif2_size(void)
    366 {
    367 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
    368 
    369 	if (ep->header != DRA7_EEPROM_HEADER_MAGIC)
    370 		return 0;
    371 
    372 	return ep->emif2_size;
    373 }
    374 
    375 void __maybe_unused set_board_info_env(char *name)
    376 {
    377 	char *unknown = "unknown";
    378 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
    379 
    380 	if (name)
    381 		env_set("board_name", name);
    382 	else if (ep->name)
    383 		env_set("board_name", ep->name);
    384 	else
    385 		env_set("board_name", unknown);
    386 
    387 	if (ep->version)
    388 		env_set("board_rev", ep->version);
    389 	else
    390 		env_set("board_rev", unknown);
    391 
    392 	if (ep->serial)
    393 		env_set("board_serial", ep->serial);
    394 	else
    395 		env_set("board_serial", unknown);
    396 }
    397 
    398 static u64 mac_to_u64(u8 mac[6])
    399 {
    400 	int i;
    401 	u64 addr = 0;
    402 
    403 	for (i = 0; i < 6; i++) {
    404 		addr <<= 8;
    405 		addr |= mac[i];
    406 	}
    407 
    408 	return addr;
    409 }
    410 
    411 static void u64_to_mac(u64 addr, u8 mac[6])
    412 {
    413 	mac[5] = addr;
    414 	mac[4] = addr >> 8;
    415 	mac[3] = addr >> 16;
    416 	mac[2] = addr >> 24;
    417 	mac[1] = addr >> 32;
    418 	mac[0] = addr >> 40;
    419 }
    420 
    421 void board_ti_set_ethaddr(int index)
    422 {
    423 	uint8_t mac_addr[6];
    424 	int i;
    425 	u64 mac1, mac2;
    426 	u8 mac_addr1[6], mac_addr2[6];
    427 	int num_macs;
    428 	/*
    429 	 * Export any Ethernet MAC addresses from EEPROM.
    430 	 * The 2 MAC addresses in EEPROM define the address range.
    431 	 */
    432 	board_ti_get_eth_mac_addr(0, mac_addr1);
    433 	board_ti_get_eth_mac_addr(1, mac_addr2);
    434 
    435 	if (is_valid_ethaddr(mac_addr1) && is_valid_ethaddr(mac_addr2)) {
    436 		mac1 = mac_to_u64(mac_addr1);
    437 		mac2 = mac_to_u64(mac_addr2);
    438 
    439 		/* must contain an address range */
    440 		num_macs = mac2 - mac1 + 1;
    441 		if (num_macs <= 0)
    442 			return;
    443 
    444 		if (num_macs > 50) {
    445 			printf("%s: Too many MAC addresses: %d. Limiting to 50\n",
    446 			       __func__, num_macs);
    447 			num_macs = 50;
    448 		}
    449 
    450 		for (i = 0; i < num_macs; i++) {
    451 			u64_to_mac(mac1 + i, mac_addr);
    452 			if (is_valid_ethaddr(mac_addr)) {
    453 				eth_env_set_enetaddr_by_index("eth", i + index,
    454 							      mac_addr);
    455 			}
    456 		}
    457 	}
    458 }
    459 
    460 bool __maybe_unused board_ti_was_eeprom_read(void)
    461 {
    462 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
    463 
    464 	if (ep->header == TI_EEPROM_HEADER_MAGIC)
    465 		return true;
    466 	else
    467 		return false;
    468 }
    469