Prepare v2023.10
[platform/kernel/u-boot.git] / board / ti / common / board_detect.c
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  */
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  */
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  */
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
82 __weak void gpi2c_init(void)
83 {
84 }
85
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }