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 <eeprom.h>
12 #include <log.h>
13 #include <net.h>
14 #include <asm/arch/hardware.h>
15 #include <asm/omap_common.h>
16 #include <dm/uclass.h>
17 #include <env.h>
18 #include <i2c.h>
19 #include <mmc.h>
20 #include <errno.h>
21 #include <malloc.h>
22 
23 #include "board_detect.h"
24 
25 #if !CONFIG_IS_ENABLED(DM_I2C)
26 /**
27  * ti_i2c_eeprom_init - Initialize an i2c bus and probe for a device
28  * @i2c_bus: i2c bus number to initialize
29  * @dev_addr: Device address to probe for
30  *
31  * Return: 0 on success or corresponding error on failure.
32  */
ti_i2c_eeprom_init(int i2c_bus,int dev_addr)33 static int __maybe_unused ti_i2c_eeprom_init(int i2c_bus, int dev_addr)
34 {
35 	int rc;
36 
37 	if (i2c_bus >= 0) {
38 		rc = i2c_set_bus_num(i2c_bus);
39 		if (rc)
40 			return rc;
41 	}
42 
43 	return i2c_probe(dev_addr);
44 }
45 
46 /**
47  * ti_i2c_eeprom_read - Read data from an EEPROM
48  * @dev_addr: The device address of the EEPROM
49  * @offset: Offset to start reading in the EEPROM
50  * @ep: Pointer to a buffer to read into
51  * @epsize: Size of buffer
52  *
53  * Return: 0 on success or corresponding result of i2c_read
54  */
ti_i2c_eeprom_read(int dev_addr,int offset,uchar * ep,int epsize)55 static int __maybe_unused ti_i2c_eeprom_read(int dev_addr, int offset,
56 					     uchar *ep, int epsize)
57 {
58 	return i2c_read(dev_addr, offset, 2, ep, epsize);
59 }
60 #endif
61 
62 /**
63  * ti_eeprom_string_cleanup() - Handle eeprom programming errors
64  * @s:	eeprom string (should be NULL terminated)
65  *
66  * Some Board manufacturers do not add a NULL termination at the
67  * end of string, instead some binary information is kludged in, hence
68  * convert the string to just printable characters of ASCII chart.
69  */
ti_eeprom_string_cleanup(char * s)70 static void __maybe_unused ti_eeprom_string_cleanup(char *s)
71 {
72 	int i, l;
73 
74 	l = strlen(s);
75 	for (i = 0; i < l; i++, s++)
76 		if (*s < ' ' || *s > '~') {
77 			*s = 0;
78 			break;
79 		}
80 }
81 
gpi2c_init(void)82 __weak void gpi2c_init(void)
83 {
84 }
85 
ti_i2c_eeprom_get(int bus_addr,int dev_addr,u32 header,u32 size,uint8_t * ep)86 static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr,
87 					    u32 header, u32 size, uint8_t *ep)
88 {
89 	int rc;
90 	uint8_t offset_test;
91 	bool one_byte_addressing = true;
92 
93 #if CONFIG_IS_ENABLED(DM_I2C)
94 	struct udevice *dev;
95 	struct udevice *bus;
96 
97 	rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
98 	if (rc)
99 		return rc;
100 	rc = dm_i2c_probe(bus, dev_addr, 0, &dev);
101 	if (rc)
102 		return rc;
103 
104 	/*
105 	 * Read the header first then only read the other contents.
106 	 */
107 	rc = i2c_set_chip_offset_len(dev, 1);
108 	if (rc)
109 		return rc;
110 
111 	/*
112 	 * Skip checking result here since this could be a valid i2c read fail
113 	 * on some boards that use 2 byte addressing.
114 	 * We must allow for fall through to check the data if 2 byte
115 	 * addressing works
116 	 */
117 	(void)dm_i2c_read(dev, 0, ep, size);
118 
119 	if (*((u32 *)ep) != header)
120 		one_byte_addressing = false;
121 
122 	/*
123 	 * Handle case of bad 2 byte eeproms that responds to 1 byte addressing
124 	 * but gets stuck in const addressing when read requests are performed
125 	 * on offsets. We perform an offset test to make sure it is not a 2 byte
126 	 * eeprom that works with 1 byte addressing but just without an offset
127 	 */
128 
129 	rc = dm_i2c_read(dev, 0x1, &offset_test, sizeof(offset_test));
130 
131 	if (*((u32 *)ep) != (header & 0xFF))
132 		one_byte_addressing = false;
133 
134 	/* Corrupted data??? */
135 	if (!one_byte_addressing) {
136 		/*
137 		 * read the eeprom header using i2c again, but use only a
138 		 * 2 byte address (some newer boards need this..)
139 		 */
140 		rc = i2c_set_chip_offset_len(dev, 2);
141 		if (rc)
142 			return rc;
143 
144 		rc = dm_i2c_read(dev, 0, ep, size);
145 		if (rc)
146 			return rc;
147 	}
148 	if (*((u32 *)ep) != header)
149 		return -1;
150 #else
151 	u32 byte;
152 
153 	gpi2c_init();
154 	rc = ti_i2c_eeprom_init(bus_addr, dev_addr);
155 	if (rc)
156 		return rc;
157 
158 	/*
159 	 * Read the header first then only read the other contents.
160 	 */
161 	byte = 1;
162 
163 	/*
164 	 * Skip checking result here since this could be a valid i2c read fail
165 	 * on some boards that use 2 byte addressing.
166 	 * We must allow for fall through to check the data if 2 byte
167 	 * addressing works
168 	 */
169 	(void)i2c_read(dev_addr, 0x0, byte, ep, size);
170 
171 	if (*((u32 *)ep) != header)
172 		one_byte_addressing = false;
173 
174 	/*
175 	 * Handle case of bad 2 byte eeproms that responds to 1 byte addressing
176 	 * but gets stuck in const addressing when read requests are performed
177 	 * on offsets. We perform an offset test to make sure it is not a 2 byte
178 	 * eeprom that works with 1 byte addressing but just without an offset
179 	 */
180 
181 	rc = i2c_read(dev_addr, 0x1, byte, &offset_test, sizeof(offset_test));
182 
183 	if (*((u32 *)ep) != (header & 0xFF))
184 		one_byte_addressing = false;
185 
186 	/* Corrupted data??? */
187 	if (!one_byte_addressing) {
188 		/*
189 		 * read the eeprom header using i2c again, but use only a
190 		 * 2 byte address (some newer boards need this..)
191 		 */
192 		byte = 2;
193 		rc = i2c_read(dev_addr, 0x0, byte, ep, size);
194 		if (rc)
195 			return rc;
196 	}
197 	if (*((u32 *)ep) != header)
198 		return -1;
199 #endif
200 	return 0;
201 }
202 
ti_emmc_boardid_get(void)203 int __maybe_unused ti_emmc_boardid_get(void)
204 {
205 	int rc;
206 	struct udevice *dev;
207 	struct mmc *mmc;
208 	struct ti_common_eeprom *ep;
209 	struct ti_am_eeprom brdid;
210 	struct blk_desc *bdesc;
211 	uchar *buffer;
212 
213 	ep = TI_EEPROM_DATA;
214 	if (ep->header == TI_EEPROM_HEADER_MAGIC)
215 		return 0;       /* EEPROM has already been read */
216 
217 	/* Initialize with a known bad marker for emmc fails.. */
218 	ep->header = TI_DEAD_EEPROM_MAGIC;
219 	ep->name[0] = 0x0;
220 	ep->version[0] = 0x0;
221 	ep->serial[0] = 0x0;
222 	ep->config[0] = 0x0;
223 
224 	/* uclass object initialization */
225 	rc = mmc_initialize(NULL);
226 	if (rc)
227 		return rc;
228 
229 	/* Set device to /dev/mmcblk1 */
230 	rc = uclass_get_device(UCLASS_MMC, 1, &dev);
231 	if (rc)
232 		return rc;
233 
234 	/* Grab the mmc device */
235 	mmc = mmc_get_mmc_dev(dev);
236 	if (!mmc)
237 		return -ENODEV;
238 
239 	/* mmc hardware initialization routine */
240 	mmc_init(mmc);
241 
242 	/* Set partition to /dev/mmcblk1boot1 */
243 	rc = mmc_switch_part(mmc, 2);
244 	if (rc)
245 		return rc;
246 
247 	buffer = malloc(mmc->read_bl_len);
248 	if (!buffer)
249 		return -ENOMEM;
250 
251 	bdesc = mmc_get_blk_desc(mmc);
252 
253 	/* blk_dread returns the number of blocks read*/
254 	if (blk_dread(bdesc, 0L, 1, buffer) != 1) {
255 		rc = -EIO;
256 		goto cleanup;
257 	}
258 
259 	memcpy(&brdid, buffer, sizeof(brdid));
260 
261 	/* Write out the ep struct values */
262 	ep->header = brdid.header;
263 	strlcpy(ep->name, brdid.name, TI_EEPROM_HDR_NAME_LEN + 1);
264 	ti_eeprom_string_cleanup(ep->name);
265 	strlcpy(ep->version, brdid.version, TI_EEPROM_HDR_REV_LEN + 1);
266 	ti_eeprom_string_cleanup(ep->version);
267 	strlcpy(ep->serial, brdid.serial, TI_EEPROM_HDR_SERIAL_LEN + 1);
268 	ti_eeprom_string_cleanup(ep->serial);
269 
270 cleanup:
271 	free(buffer);
272 
273 	return rc;
274 }
275 
ti_i2c_eeprom_am_set(const char * name,const char * rev)276 int __maybe_unused ti_i2c_eeprom_am_set(const char *name, const char *rev)
277 {
278 	struct ti_common_eeprom *ep;
279 
280 	if (!name || !rev)
281 		return -1;
282 
283 	ep = TI_EEPROM_DATA;
284 	if (ep->header == TI_EEPROM_HEADER_MAGIC)
285 		goto already_set;
286 
287 	/* Set to 0 all fields */
288 	memset(ep, 0, sizeof(*ep));
289 	strncpy(ep->name, name, TI_EEPROM_HDR_NAME_LEN);
290 	strncpy(ep->version, rev, TI_EEPROM_HDR_REV_LEN);
291 	/* Some dummy serial number to identify the platform */
292 	strncpy(ep->serial, "0000", TI_EEPROM_HDR_SERIAL_LEN);
293 	/* Mark it with a valid header */
294 	ep->header = TI_EEPROM_HEADER_MAGIC;
295 
296 already_set:
297 	return 0;
298 }
299 
ti_i2c_eeprom_am_get(int bus_addr,int dev_addr)300 int __maybe_unused ti_i2c_eeprom_am_get(int bus_addr, int dev_addr)
301 {
302 	int rc;
303 	struct ti_am_eeprom am_ep;
304 	struct ti_common_eeprom *ep;
305 
306 	ep = TI_EEPROM_DATA;
307 #ifndef CONFIG_SPL_BUILD
308 	if (ep->header == TI_EEPROM_HEADER_MAGIC)
309 		return 0; /* EEPROM has already been read */
310 #endif
311 
312 	/* Initialize with a known bad marker for i2c fails.. */
313 	ep->header = TI_DEAD_EEPROM_MAGIC;
314 	ep->name[0] = 0x0;
315 	ep->version[0] = 0x0;
316 	ep->serial[0] = 0x0;
317 	ep->config[0] = 0x0;
318 
319 	rc = ti_i2c_eeprom_get(bus_addr, dev_addr, TI_EEPROM_HEADER_MAGIC,
320 			       sizeof(am_ep), (uint8_t *)&am_ep);
321 	if (rc)
322 		return rc;
323 
324 	ep->header = am_ep.header;
325 	strlcpy(ep->name, am_ep.name, TI_EEPROM_HDR_NAME_LEN + 1);
326 	ti_eeprom_string_cleanup(ep->name);
327 
328 	/* BeagleBone Green '1' eeprom, board_rev: 0x1a 0x00 0x00 0x00 */
329 	if (am_ep.version[0] == 0x1a && am_ep.version[1] == 0x00 &&
330 	    am_ep.version[2] == 0x00 && am_ep.version[3] == 0x00)
331 		strlcpy(ep->version, "BBG1", TI_EEPROM_HDR_REV_LEN + 1);
332 	else
333 		strlcpy(ep->version, am_ep.version, TI_EEPROM_HDR_REV_LEN + 1);
334 	ti_eeprom_string_cleanup(ep->version);
335 	strlcpy(ep->serial, am_ep.serial, TI_EEPROM_HDR_SERIAL_LEN + 1);
336 	ti_eeprom_string_cleanup(ep->serial);
337 	strlcpy(ep->config, am_ep.config, TI_EEPROM_HDR_CONFIG_LEN + 1);
338 	ti_eeprom_string_cleanup(ep->config);
339 
340 	memcpy(ep->mac_addr, am_ep.mac_addr,
341 	       TI_EEPROM_HDR_NO_OF_MAC_ADDR * TI_EEPROM_HDR_ETH_ALEN);
342 
343 	return 0;
344 }
345 
ti_i2c_eeprom_dra7_get(int bus_addr,int dev_addr)346 int __maybe_unused ti_i2c_eeprom_dra7_get(int bus_addr, int dev_addr)
347 {
348 	int rc, offset = 0;
349 	struct dra7_eeprom dra7_ep;
350 	struct ti_common_eeprom *ep;
351 
352 	ep = TI_EEPROM_DATA;
353 #ifndef CONFIG_SPL_BUILD
354 	if (ep->header == DRA7_EEPROM_HEADER_MAGIC)
355 		return 0; /* EEPROM has already been read */
356 #endif
357 
358 	/* Initialize with a known bad marker for i2c fails.. */
359 	ep->header = TI_DEAD_EEPROM_MAGIC;
360 	ep->name[0] = 0x0;
361 	ep->version[0] = 0x0;
362 	ep->serial[0] = 0x0;
363 	ep->config[0] = 0x0;
364 	ep->emif1_size = 0;
365 	ep->emif2_size = 0;
366 
367 	rc = ti_i2c_eeprom_get(bus_addr, dev_addr, DRA7_EEPROM_HEADER_MAGIC,
368 			       sizeof(dra7_ep), (uint8_t *)&dra7_ep);
369 	if (rc)
370 		return rc;
371 
372 	ep->header = dra7_ep.header;
373 	strlcpy(ep->name, dra7_ep.name, TI_EEPROM_HDR_NAME_LEN + 1);
374 	ti_eeprom_string_cleanup(ep->name);
375 
376 	offset = dra7_ep.version_major - 1;
377 
378 	/* Rev F is skipped */
379 	if (offset >= 5)
380 		offset = offset + 1;
381 	snprintf(ep->version, TI_EEPROM_HDR_REV_LEN + 1, "%c.%d",
382 		 'A' + offset, dra7_ep.version_minor);
383 	ti_eeprom_string_cleanup(ep->version);
384 	ep->emif1_size = (u64)dra7_ep.emif1_size;
385 	ep->emif2_size = (u64)dra7_ep.emif2_size;
386 	strlcpy(ep->config, dra7_ep.config, TI_EEPROM_HDR_CONFIG_LEN + 1);
387 	ti_eeprom_string_cleanup(ep->config);
388 
389 	return 0;
390 }
391 
ti_i2c_eeprom_am6_parse_record(struct ti_am6_eeprom_record * record,struct ti_am6_eeprom * ep,char ** mac_addr,u8 mac_addr_max_cnt,u8 * mac_addr_cnt)392 static int ti_i2c_eeprom_am6_parse_record(struct ti_am6_eeprom_record *record,
393 					  struct ti_am6_eeprom *ep,
394 					  char **mac_addr,
395 					  u8 mac_addr_max_cnt,
396 					  u8 *mac_addr_cnt)
397 {
398 	switch (record->header.id) {
399 	case TI_AM6_EEPROM_RECORD_BOARD_INFO:
400 		if (record->header.len != sizeof(record->data.board_info))
401 			return -EINVAL;
402 
403 		if (!ep)
404 			break;
405 
406 		/* Populate (and clean, if needed) the board name */
407 		strlcpy(ep->name, record->data.board_info.name,
408 			sizeof(ep->name));
409 		ti_eeprom_string_cleanup(ep->name);
410 
411 		/* Populate selected other fields from the board info record */
412 		strlcpy(ep->version, record->data.board_info.version,
413 			sizeof(ep->version));
414 		strlcpy(ep->software_revision,
415 			record->data.board_info.software_revision,
416 			sizeof(ep->software_revision));
417 		strlcpy(ep->serial, record->data.board_info.serial,
418 			sizeof(ep->serial));
419 		break;
420 	case TI_AM6_EEPROM_RECORD_MAC_INFO:
421 		if (record->header.len != sizeof(record->data.mac_info))
422 			return -EINVAL;
423 
424 		if (!mac_addr || !mac_addr_max_cnt)
425 			break;
426 
427 		*mac_addr_cnt = ((record->data.mac_info.mac_control &
428 				 TI_AM6_EEPROM_MAC_ADDR_COUNT_MASK) >>
429 				 TI_AM6_EEPROM_MAC_ADDR_COUNT_SHIFT) + 1;
430 
431 		/*
432 		 * The EEPROM can (but may not) hold a very large amount
433 		 * of MAC addresses, by far exceeding what we want/can store
434 		 * in the common memory array, so only grab what we can fit.
435 		 * Note that a value of 0 means 1 MAC address, and so on.
436 		 */
437 		*mac_addr_cnt = min(*mac_addr_cnt, mac_addr_max_cnt);
438 
439 		memcpy(mac_addr, record->data.mac_info.mac_addr,
440 		       *mac_addr_cnt * TI_EEPROM_HDR_ETH_ALEN);
441 		break;
442 	case 0x00:
443 		/* Illegal value... Fall through... */
444 	case 0xFF:
445 		/* Illegal value... Something went horribly wrong... */
446 		return -EINVAL;
447 	default:
448 		pr_warn("%s: Ignoring record id %u\n", __func__,
449 			record->header.id);
450 	}
451 
452 	return 0;
453 }
454 
ti_i2c_eeprom_am6_get(int bus_addr,int dev_addr,struct ti_am6_eeprom * ep,char ** mac_addr,u8 mac_addr_max_cnt,u8 * mac_addr_cnt)455 int __maybe_unused ti_i2c_eeprom_am6_get(int bus_addr, int dev_addr,
456 					 struct ti_am6_eeprom *ep,
457 					 char **mac_addr,
458 					 u8 mac_addr_max_cnt,
459 					 u8 *mac_addr_cnt)
460 {
461 	struct udevice *dev;
462 	struct udevice *bus;
463 	unsigned int eeprom_addr;
464 	struct ti_am6_eeprom_record_board_id board_id;
465 	struct ti_am6_eeprom_record record;
466 	int rc;
467 	int consecutive_bad_records = 0;
468 
469 	/* Initialize with a known bad marker for i2c fails.. */
470 	memset(ep, 0, sizeof(*ep));
471 	ep->header = TI_DEAD_EEPROM_MAGIC;
472 
473 	/* Read the board ID record which is always the first EEPROM record */
474 	rc = ti_i2c_eeprom_get(bus_addr, dev_addr, TI_EEPROM_HEADER_MAGIC,
475 			       sizeof(board_id), (uint8_t *)&board_id);
476 	if (rc)
477 		return rc;
478 
479 	if (board_id.header.id != TI_AM6_EEPROM_RECORD_BOARD_ID) {
480 		pr_err("%s: Invalid board ID record!\n", __func__);
481 		return -EINVAL;
482 	}
483 
484 	/* Establish DM handle to board config EEPROM */
485 	rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
486 	if (rc)
487 		return rc;
488 	rc = i2c_get_chip(bus, dev_addr, 1, &dev);
489 	if (rc)
490 		return rc;
491 
492 	ep->header = TI_EEPROM_HEADER_MAGIC;
493 
494 	/* Ready to parse TLV structure. Initialize variables... */
495 	*mac_addr_cnt = 0;
496 
497 	/*
498 	 * After the all-encompassing board ID record all other records follow
499 	 * a TLV-type scheme. Point to the first such record and then start
500 	 * parsing those one by one.
501 	 */
502 	eeprom_addr = sizeof(board_id);
503 
504 	while (consecutive_bad_records < 10) {
505 		rc = dm_i2c_read(dev, eeprom_addr, (uint8_t *)&record.header,
506 				 sizeof(record.header));
507 		if (rc)
508 			return rc;
509 
510 		/*
511 		 * Check for end of list marker. If we reached it don't go
512 		 * any further and stop parsing right here.
513 		 */
514 		if (record.header.id == TI_AM6_EEPROM_RECORD_END_LIST)
515 			break;
516 
517 		eeprom_addr += sizeof(record.header);
518 
519 		debug("%s: dev_addr=0x%02x header.id=%u header.len=%u\n",
520 		      __func__, dev_addr, record.header.id,
521 		      record.header.len);
522 
523 		/* Read record into memory if it fits */
524 		if (record.header.len <= sizeof(record.data)) {
525 			rc = dm_i2c_read(dev, eeprom_addr,
526 					 (uint8_t *)&record.data,
527 					 record.header.len);
528 			if (rc)
529 				return rc;
530 
531 			/* Process record */
532 			rc = ti_i2c_eeprom_am6_parse_record(&record, ep,
533 							    mac_addr,
534 							    mac_addr_max_cnt,
535 							    mac_addr_cnt);
536 			if (rc) {
537 				pr_err("%s: EEPROM parsing error!\n", __func__);
538 				return rc;
539 			}
540 			consecutive_bad_records = 0;
541 		} else {
542 			/*
543 			 * We may get here in case of larger records which
544 			 * are not yet understood.
545 			 */
546 			pr_err("%s: Ignoring record id %u\n", __func__,
547 			       record.header.id);
548 			consecutive_bad_records++;
549 		}
550 
551 		eeprom_addr += record.header.len;
552 	}
553 
554 	return 0;
555 }
556 
ti_i2c_eeprom_am6_get_base(int bus_addr,int dev_addr)557 int __maybe_unused ti_i2c_eeprom_am6_get_base(int bus_addr, int dev_addr)
558 {
559 	struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
560 	int ret;
561 
562 	/*
563 	 * Always execute EEPROM read by not allowing to bypass it during the
564 	 * first invocation of SPL which happens on the R5 core.
565 	 */
566 #if !(defined(CONFIG_SPL_BUILD) && defined(CONFIG_CPU_V7R))
567 	if (ep->header == TI_EEPROM_HEADER_MAGIC) {
568 		debug("%s: EEPROM has already been read\n", __func__);
569 		return 0;
570 	}
571 #endif
572 
573 	ret = ti_i2c_eeprom_am6_get(bus_addr, dev_addr, ep,
574 				    (char **)ep->mac_addr,
575 				    AM6_EEPROM_HDR_NO_OF_MAC_ADDR,
576 				    &ep->mac_addr_cnt);
577 	return ret;
578 }
579 
board_ti_k3_is(char * name_tag)580 bool __maybe_unused board_ti_k3_is(char *name_tag)
581 {
582 	struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
583 
584 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
585 		return false;
586 	return !strncmp(ep->name, name_tag, AM6_EEPROM_HDR_NAME_LEN);
587 }
588 
board_ti_is(char * name_tag)589 bool __maybe_unused board_ti_is(char *name_tag)
590 {
591 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
592 
593 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
594 		return false;
595 	return !strncmp(ep->name, name_tag, TI_EEPROM_HDR_NAME_LEN);
596 }
597 
board_ti_rev_is(char * rev_tag,int cmp_len)598 bool __maybe_unused board_ti_rev_is(char *rev_tag, int cmp_len)
599 {
600 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
601 	int l;
602 
603 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
604 		return false;
605 
606 	l = cmp_len > TI_EEPROM_HDR_REV_LEN ? TI_EEPROM_HDR_REV_LEN : cmp_len;
607 	return !strncmp(ep->version, rev_tag, l);
608 }
609 
board_ti_get_rev(void)610 char * __maybe_unused board_ti_get_rev(void)
611 {
612 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
613 
614 	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
615 	return ep->version;
616 }
617 
board_ti_get_config(void)618 char * __maybe_unused board_ti_get_config(void)
619 {
620 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
621 
622 	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
623 	return ep->config;
624 }
625 
board_ti_get_name(void)626 char * __maybe_unused board_ti_get_name(void)
627 {
628 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
629 
630 	/* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
631 	return ep->name;
632 }
633 
634 void __maybe_unused
board_ti_get_eth_mac_addr(int index,u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])635 board_ti_get_eth_mac_addr(int index,
636 			  u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])
637 {
638 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
639 
640 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
641 		goto fail;
642 
643 	if (index < 0 || index >= TI_EEPROM_HDR_NO_OF_MAC_ADDR)
644 		goto fail;
645 
646 	memcpy(mac_addr, ep->mac_addr[index], TI_EEPROM_HDR_ETH_ALEN);
647 	return;
648 
649 fail:
650 	memset(mac_addr, 0, TI_EEPROM_HDR_ETH_ALEN);
651 }
652 
653 void __maybe_unused
board_ti_am6_get_eth_mac_addr(int index,u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])654 board_ti_am6_get_eth_mac_addr(int index,
655 			      u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])
656 {
657 	struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
658 
659 	if (ep->header == TI_DEAD_EEPROM_MAGIC)
660 		goto fail;
661 
662 	if (index < 0 || index >= ep->mac_addr_cnt)
663 		goto fail;
664 
665 	memcpy(mac_addr, ep->mac_addr[index], TI_EEPROM_HDR_ETH_ALEN);
666 	return;
667 
668 fail:
669 	memset(mac_addr, 0, TI_EEPROM_HDR_ETH_ALEN);
670 }
671 
board_ti_get_emif1_size(void)672 u64 __maybe_unused board_ti_get_emif1_size(void)
673 {
674 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
675 
676 	if (ep->header != DRA7_EEPROM_HEADER_MAGIC)
677 		return 0;
678 
679 	return ep->emif1_size;
680 }
681 
board_ti_get_emif2_size(void)682 u64 __maybe_unused board_ti_get_emif2_size(void)
683 {
684 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
685 
686 	if (ep->header != DRA7_EEPROM_HEADER_MAGIC)
687 		return 0;
688 
689 	return ep->emif2_size;
690 }
691 
set_board_info_env(char * name)692 void __maybe_unused set_board_info_env(char *name)
693 {
694 	char *unknown = "unknown";
695 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
696 
697 	if (name)
698 		env_set("board_name", name);
699 	else if (strlen(ep->name) != 0)
700 		env_set("board_name", ep->name);
701 	else
702 		env_set("board_name", unknown);
703 
704 	if (strlen(ep->version) != 0)
705 		env_set("board_rev", ep->version);
706 	else
707 		env_set("board_rev", unknown);
708 
709 	if (strlen(ep->serial) != 0)
710 		env_set("board_serial", ep->serial);
711 	else
712 		env_set("board_serial", unknown);
713 }
714 
set_board_info_env_am6(char * name)715 void __maybe_unused set_board_info_env_am6(char *name)
716 {
717 	char *unknown = "unknown";
718 	struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
719 
720 	if (name)
721 		env_set("board_name", name);
722 	else if (strlen(ep->name) != 0)
723 		env_set("board_name", ep->name);
724 	else
725 		env_set("board_name", unknown);
726 
727 	if (strlen(ep->version) != 0)
728 		env_set("board_rev", ep->version);
729 	else
730 		env_set("board_rev", unknown);
731 
732 	if (strlen(ep->software_revision) != 0)
733 		env_set("board_software_revision", ep->software_revision);
734 	else
735 		env_set("board_software_revision", unknown);
736 
737 	if (strlen(ep->serial) != 0)
738 		env_set("board_serial", ep->serial);
739 	else
740 		env_set("board_serial", unknown);
741 }
742 
mac_to_u64(u8 mac[6])743 static u64 mac_to_u64(u8 mac[6])
744 {
745 	int i;
746 	u64 addr = 0;
747 
748 	for (i = 0; i < 6; i++) {
749 		addr <<= 8;
750 		addr |= mac[i];
751 	}
752 
753 	return addr;
754 }
755 
u64_to_mac(u64 addr,u8 mac[6])756 static void u64_to_mac(u64 addr, u8 mac[6])
757 {
758 	mac[5] = addr;
759 	mac[4] = addr >> 8;
760 	mac[3] = addr >> 16;
761 	mac[2] = addr >> 24;
762 	mac[1] = addr >> 32;
763 	mac[0] = addr >> 40;
764 }
765 
board_ti_set_ethaddr(int index)766 void board_ti_set_ethaddr(int index)
767 {
768 	uint8_t mac_addr[6];
769 	int i;
770 	u64 mac1, mac2;
771 	u8 mac_addr1[6], mac_addr2[6];
772 	int num_macs;
773 	/*
774 	 * Export any Ethernet MAC addresses from EEPROM.
775 	 * The 2 MAC addresses in EEPROM define the address range.
776 	 */
777 	board_ti_get_eth_mac_addr(0, mac_addr1);
778 	board_ti_get_eth_mac_addr(1, mac_addr2);
779 
780 	if (is_valid_ethaddr(mac_addr1) && is_valid_ethaddr(mac_addr2)) {
781 		mac1 = mac_to_u64(mac_addr1);
782 		mac2 = mac_to_u64(mac_addr2);
783 
784 		/* must contain an address range */
785 		num_macs = mac2 - mac1 + 1;
786 		if (num_macs <= 0)
787 			return;
788 
789 		if (num_macs > 50) {
790 			printf("%s: Too many MAC addresses: %d. Limiting to 50\n",
791 			       __func__, num_macs);
792 			num_macs = 50;
793 		}
794 
795 		for (i = 0; i < num_macs; i++) {
796 			u64_to_mac(mac1 + i, mac_addr);
797 			if (is_valid_ethaddr(mac_addr)) {
798 				eth_env_set_enetaddr_by_index("eth", i + index,
799 							      mac_addr);
800 			}
801 		}
802 	}
803 }
804 
board_ti_am6_set_ethaddr(int index,int count)805 void board_ti_am6_set_ethaddr(int index, int count)
806 {
807 	u8 mac_addr[6];
808 	int i;
809 
810 	for (i = 0; i < count; i++) {
811 		board_ti_am6_get_eth_mac_addr(i, mac_addr);
812 		if (is_valid_ethaddr(mac_addr))
813 			eth_env_set_enetaddr_by_index("eth", i + index,
814 						      mac_addr);
815 	}
816 }
817 
board_ti_was_eeprom_read(void)818 bool __maybe_unused board_ti_was_eeprom_read(void)
819 {
820 	struct ti_common_eeprom *ep = TI_EEPROM_DATA;
821 
822 	if (ep->header == TI_EEPROM_HEADER_MAGIC)
823 		return true;
824 	else
825 		return false;
826 }
827