1 // SPDX-License-Identifier: GPL-2.0+
3 * Library to support early TI EVM EEPROM handling
5 * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
12 #include <asm/arch/hardware.h>
13 #include <asm/omap_common.h>
14 #include <dm/uclass.h>
21 #include "board_detect.h"
23 #if !defined(CONFIG_DM_I2C)
25 * ti_i2c_eeprom_init - Initialize an i2c bus and probe for a device
26 * @i2c_bus: i2c bus number to initialize
27 * @dev_addr: Device address to probe for
29 * Return: 0 on success or corresponding error on failure.
31 static int __maybe_unused ti_i2c_eeprom_init(int i2c_bus, int dev_addr)
36 rc = i2c_set_bus_num(i2c_bus);
41 return i2c_probe(dev_addr);
45 * ti_i2c_eeprom_read - Read data from an EEPROM
46 * @dev_addr: The device address of the EEPROM
47 * @offset: Offset to start reading in the EEPROM
48 * @ep: Pointer to a buffer to read into
49 * @epsize: Size of buffer
51 * Return: 0 on success or corresponding result of i2c_read
53 static int __maybe_unused ti_i2c_eeprom_read(int dev_addr, int offset,
54 uchar *ep, int epsize)
56 return i2c_read(dev_addr, offset, 2, ep, epsize);
61 * ti_eeprom_string_cleanup() - Handle eeprom programming errors
62 * @s: eeprom string (should be NULL terminated)
64 * Some Board manufacturers do not add a NULL termination at the
65 * end of string, instead some binary information is kludged in, hence
66 * convert the string to just printable characters of ASCII chart.
68 static void __maybe_unused ti_eeprom_string_cleanup(char *s)
73 for (i = 0; i < l; i++, s++)
74 if (*s < ' ' || *s > '~') {
80 __weak void gpi2c_init(void)
84 static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr,
85 u32 header, u32 size, uint8_t *ep)
90 #if defined(CONFIG_DM_I2C)
94 rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
97 rc = dm_i2c_probe(bus, dev_addr, 0, &dev);
102 * Read the header first then only read the other contents.
104 rc = i2c_set_chip_offset_len(dev, 2);
108 rc = dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4);
112 /* Corrupted data??? */
113 if (hdr_read != header) {
114 rc = dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4);
116 * read the eeprom header using i2c again, but use only a
117 * 1 byte address (some legacy boards need this..)
120 rc = i2c_set_chip_offset_len(dev, 1);
124 rc = dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4);
129 if (hdr_read != header)
132 rc = dm_i2c_read(dev, 0, ep, size);
139 rc = ti_i2c_eeprom_init(bus_addr, dev_addr);
144 * Read the header first then only read the other contents.
148 rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read, 4);
152 /* Corrupted data??? */
153 if (hdr_read != header) {
154 rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read, 4);
156 * read the eeprom header using i2c again, but use only a
157 * 1 byte address (some legacy boards need this..)
161 rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read,
167 if (hdr_read != header)
170 rc = i2c_read(dev_addr, 0x0, byte, ep, size);
177 int __maybe_unused ti_emmc_boardid_get(void)
182 struct ti_common_eeprom *ep;
183 struct ti_am_eeprom brdid;
184 struct blk_desc *bdesc;
188 if (ep->header == TI_EEPROM_HEADER_MAGIC)
189 return 0; /* EEPROM has already been read */
191 /* Initialize with a known bad marker for emmc fails.. */
192 ep->header = TI_DEAD_EEPROM_MAGIC;
194 ep->version[0] = 0x0;
198 /* uclass object initialization */
199 rc = mmc_initialize(NULL);
203 /* Set device to /dev/mmcblk1 */
204 rc = uclass_get_device(UCLASS_MMC, 1, &dev);
208 /* Grab the mmc device */
209 mmc = mmc_get_mmc_dev(dev);
213 /* mmc hardware initialization routine */
216 /* Set partition to /dev/mmcblk1boot1 */
217 rc = mmc_switch_part(mmc, 2);
221 buffer = malloc(mmc->read_bl_len);
225 bdesc = mmc_get_blk_desc(mmc);
227 /* blk_dread returns the number of blocks read*/
228 if (blk_dread(bdesc, 0L, 1, buffer) != 1) {
233 memcpy(&brdid, buffer, sizeof(brdid));
235 /* Write out the ep struct values */
236 ep->header = brdid.header;
237 strlcpy(ep->name, brdid.name, TI_EEPROM_HDR_NAME_LEN + 1);
238 ti_eeprom_string_cleanup(ep->name);
239 strlcpy(ep->version, brdid.version, TI_EEPROM_HDR_REV_LEN + 1);
240 ti_eeprom_string_cleanup(ep->version);
241 strlcpy(ep->serial, brdid.serial, TI_EEPROM_HDR_SERIAL_LEN + 1);
242 ti_eeprom_string_cleanup(ep->serial);
250 int __maybe_unused ti_i2c_eeprom_am_set(const char *name, const char *rev)
252 struct ti_common_eeprom *ep;
258 if (ep->header == TI_EEPROM_HEADER_MAGIC)
261 /* Set to 0 all fields */
262 memset(ep, 0, sizeof(*ep));
263 strncpy(ep->name, name, TI_EEPROM_HDR_NAME_LEN);
264 strncpy(ep->version, rev, TI_EEPROM_HDR_REV_LEN);
265 /* Some dummy serial number to identify the platform */
266 strncpy(ep->serial, "0000", TI_EEPROM_HDR_SERIAL_LEN);
267 /* Mark it with a valid header */
268 ep->header = TI_EEPROM_HEADER_MAGIC;
274 int __maybe_unused ti_i2c_eeprom_am_get(int bus_addr, int dev_addr)
277 struct ti_am_eeprom am_ep;
278 struct ti_common_eeprom *ep;
281 #ifndef CONFIG_SPL_BUILD
282 if (ep->header == TI_EEPROM_HEADER_MAGIC)
283 return 0; /* EEPROM has already been read */
286 /* Initialize with a known bad marker for i2c fails.. */
287 ep->header = TI_DEAD_EEPROM_MAGIC;
289 ep->version[0] = 0x0;
293 rc = ti_i2c_eeprom_get(bus_addr, dev_addr, TI_EEPROM_HEADER_MAGIC,
294 sizeof(am_ep), (uint8_t *)&am_ep);
298 ep->header = am_ep.header;
299 strlcpy(ep->name, am_ep.name, TI_EEPROM_HDR_NAME_LEN + 1);
300 ti_eeprom_string_cleanup(ep->name);
302 /* BeagleBone Green '1' eeprom, board_rev: 0x1a 0x00 0x00 0x00 */
303 if (am_ep.version[0] == 0x1a && am_ep.version[1] == 0x00 &&
304 am_ep.version[2] == 0x00 && am_ep.version[3] == 0x00)
305 strlcpy(ep->version, "BBG1", TI_EEPROM_HDR_REV_LEN + 1);
307 strlcpy(ep->version, am_ep.version, TI_EEPROM_HDR_REV_LEN + 1);
308 ti_eeprom_string_cleanup(ep->version);
309 strlcpy(ep->serial, am_ep.serial, TI_EEPROM_HDR_SERIAL_LEN + 1);
310 ti_eeprom_string_cleanup(ep->serial);
311 strlcpy(ep->config, am_ep.config, TI_EEPROM_HDR_CONFIG_LEN + 1);
312 ti_eeprom_string_cleanup(ep->config);
314 memcpy(ep->mac_addr, am_ep.mac_addr,
315 TI_EEPROM_HDR_NO_OF_MAC_ADDR * TI_EEPROM_HDR_ETH_ALEN);
320 int __maybe_unused ti_i2c_eeprom_dra7_get(int bus_addr, int dev_addr)
323 struct dra7_eeprom dra7_ep;
324 struct ti_common_eeprom *ep;
327 #ifndef CONFIG_SPL_BUILD
328 if (ep->header == DRA7_EEPROM_HEADER_MAGIC)
329 return 0; /* EEPROM has already been read */
332 /* Initialize with a known bad marker for i2c fails.. */
333 ep->header = TI_DEAD_EEPROM_MAGIC;
335 ep->version[0] = 0x0;
341 rc = ti_i2c_eeprom_get(bus_addr, dev_addr, DRA7_EEPROM_HEADER_MAGIC,
342 sizeof(dra7_ep), (uint8_t *)&dra7_ep);
346 ep->header = dra7_ep.header;
347 strlcpy(ep->name, dra7_ep.name, TI_EEPROM_HDR_NAME_LEN + 1);
348 ti_eeprom_string_cleanup(ep->name);
350 offset = dra7_ep.version_major - 1;
352 /* Rev F is skipped */
355 snprintf(ep->version, TI_EEPROM_HDR_REV_LEN + 1, "%c.%d",
356 'A' + offset, dra7_ep.version_minor);
357 ti_eeprom_string_cleanup(ep->version);
358 ep->emif1_size = (u64)dra7_ep.emif1_size;
359 ep->emif2_size = (u64)dra7_ep.emif2_size;
360 strlcpy(ep->config, dra7_ep.config, TI_EEPROM_HDR_CONFIG_LEN + 1);
361 ti_eeprom_string_cleanup(ep->config);
366 static int ti_i2c_eeprom_am6_parse_record(struct ti_am6_eeprom_record *record,
367 struct ti_am6_eeprom *ep,
372 switch (record->header.id) {
373 case TI_AM6_EEPROM_RECORD_BOARD_INFO:
374 if (record->header.len != sizeof(record->data.board_info))
380 /* Populate (and clean, if needed) the board name */
381 strlcpy(ep->name, record->data.board_info.name,
383 ti_eeprom_string_cleanup(ep->name);
385 /* Populate selected other fields from the board info record */
386 strlcpy(ep->version, record->data.board_info.version,
387 sizeof(ep->version));
388 strlcpy(ep->software_revision,
389 record->data.board_info.software_revision,
390 sizeof(ep->software_revision));
391 strlcpy(ep->serial, record->data.board_info.serial,
394 case TI_AM6_EEPROM_RECORD_MAC_INFO:
395 if (record->header.len != sizeof(record->data.mac_info))
398 if (!mac_addr || !mac_addr_max_cnt)
401 *mac_addr_cnt = ((record->data.mac_info.mac_control &
402 TI_AM6_EEPROM_MAC_ADDR_COUNT_MASK) >>
403 TI_AM6_EEPROM_MAC_ADDR_COUNT_SHIFT) + 1;
406 * The EEPROM can (but may not) hold a very large amount
407 * of MAC addresses, by far exceeding what we want/can store
408 * in the common memory array, so only grab what we can fit.
409 * Note that a value of 0 means 1 MAC address, and so on.
411 *mac_addr_cnt = min(*mac_addr_cnt, mac_addr_max_cnt);
413 memcpy(mac_addr, record->data.mac_info.mac_addr,
414 *mac_addr_cnt * TI_EEPROM_HDR_ETH_ALEN);
417 /* Illegal value... Fall through... */
419 /* Illegal value... Something went horribly wrong... */
422 pr_warn("%s: Ignoring record id %u\n", __func__,
429 int __maybe_unused ti_i2c_eeprom_am6_get(int bus_addr, int dev_addr,
430 struct ti_am6_eeprom *ep,
437 unsigned int eeprom_addr;
438 struct ti_am6_eeprom_record_board_id board_id;
439 struct ti_am6_eeprom_record record;
442 /* Initialize with a known bad marker for i2c fails.. */
443 memset(ep, 0, sizeof(*ep));
444 ep->header = TI_DEAD_EEPROM_MAGIC;
446 /* Read the board ID record which is always the first EEPROM record */
447 rc = ti_i2c_eeprom_get(bus_addr, dev_addr, TI_EEPROM_HEADER_MAGIC,
448 sizeof(board_id), (uint8_t *)&board_id);
452 if (board_id.header.id != TI_AM6_EEPROM_RECORD_BOARD_ID) {
453 pr_err("%s: Invalid board ID record!\n", __func__);
457 /* Establish DM handle to board config EEPROM */
458 rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
461 rc = i2c_get_chip(bus, dev_addr, 1, &dev);
465 ep->header = TI_EEPROM_HEADER_MAGIC;
467 /* Ready to parse TLV structure. Initialize variables... */
471 * After the all-encompassing board ID record all other records follow
472 * a TLV-type scheme. Point to the first such record and then start
473 * parsing those one by one.
475 eeprom_addr = sizeof(board_id);
478 rc = dm_i2c_read(dev, eeprom_addr, (uint8_t *)&record.header,
479 sizeof(record.header));
484 * Check for end of list marker. If we reached it don't go
485 * any further and stop parsing right here.
487 if (record.header.id == TI_AM6_EEPROM_RECORD_END_LIST)
490 eeprom_addr += sizeof(record.header);
492 debug("%s: dev_addr=0x%02x header.id=%u header.len=%u\n",
493 __func__, dev_addr, record.header.id,
496 /* Read record into memory if it fits */
497 if (record.header.len <= sizeof(record.data)) {
498 rc = dm_i2c_read(dev, eeprom_addr,
499 (uint8_t *)&record.data,
505 rc = ti_i2c_eeprom_am6_parse_record(&record, ep,
510 pr_err("%s: EEPROM parsing error!\n", __func__);
515 * We may get here in case of larger records which
516 * are not yet understood.
518 pr_err("%s: Ignoring record id %u\n", __func__,
522 eeprom_addr += record.header.len;
528 int __maybe_unused ti_i2c_eeprom_am6_get_base(int bus_addr, int dev_addr)
530 struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
534 * Always execute EEPROM read by not allowing to bypass it during the
535 * first invocation of SPL which happens on the R5 core.
537 #if !(defined(CONFIG_SPL_BUILD) && defined(CONFIG_CPU_V7R))
538 if (ep->header == TI_EEPROM_HEADER_MAGIC) {
539 debug("%s: EEPROM has already been read\n", __func__);
544 ret = ti_i2c_eeprom_am6_get(bus_addr, dev_addr, ep,
545 (char **)ep->mac_addr,
546 AM6_EEPROM_HDR_NO_OF_MAC_ADDR,
551 bool __maybe_unused board_ti_k3_is(char *name_tag)
553 struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
555 if (ep->header == TI_DEAD_EEPROM_MAGIC)
557 return !strncmp(ep->name, name_tag, AM6_EEPROM_HDR_NAME_LEN);
560 bool __maybe_unused board_ti_is(char *name_tag)
562 struct ti_common_eeprom *ep = TI_EEPROM_DATA;
564 if (ep->header == TI_DEAD_EEPROM_MAGIC)
566 return !strncmp(ep->name, name_tag, TI_EEPROM_HDR_NAME_LEN);
569 bool __maybe_unused board_ti_rev_is(char *rev_tag, int cmp_len)
571 struct ti_common_eeprom *ep = TI_EEPROM_DATA;
574 if (ep->header == TI_DEAD_EEPROM_MAGIC)
577 l = cmp_len > TI_EEPROM_HDR_REV_LEN ? TI_EEPROM_HDR_REV_LEN : cmp_len;
578 return !strncmp(ep->version, rev_tag, l);
581 char * __maybe_unused board_ti_get_rev(void)
583 struct ti_common_eeprom *ep = TI_EEPROM_DATA;
585 /* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
589 char * __maybe_unused board_ti_get_config(void)
591 struct ti_common_eeprom *ep = TI_EEPROM_DATA;
593 /* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
597 char * __maybe_unused board_ti_get_name(void)
599 struct ti_common_eeprom *ep = TI_EEPROM_DATA;
601 /* if ep->header == TI_DEAD_EEPROM_MAGIC, this is empty already */
606 board_ti_get_eth_mac_addr(int index,
607 u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])
609 struct ti_common_eeprom *ep = TI_EEPROM_DATA;
611 if (ep->header == TI_DEAD_EEPROM_MAGIC)
614 if (index < 0 || index >= TI_EEPROM_HDR_NO_OF_MAC_ADDR)
617 memcpy(mac_addr, ep->mac_addr[index], TI_EEPROM_HDR_ETH_ALEN);
621 memset(mac_addr, 0, TI_EEPROM_HDR_ETH_ALEN);
625 board_ti_am6_get_eth_mac_addr(int index,
626 u8 mac_addr[TI_EEPROM_HDR_ETH_ALEN])
628 struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
630 if (ep->header == TI_DEAD_EEPROM_MAGIC)
633 if (index < 0 || index >= ep->mac_addr_cnt)
636 memcpy(mac_addr, ep->mac_addr[index], TI_EEPROM_HDR_ETH_ALEN);
640 memset(mac_addr, 0, TI_EEPROM_HDR_ETH_ALEN);
643 u64 __maybe_unused board_ti_get_emif1_size(void)
645 struct ti_common_eeprom *ep = TI_EEPROM_DATA;
647 if (ep->header != DRA7_EEPROM_HEADER_MAGIC)
650 return ep->emif1_size;
653 u64 __maybe_unused board_ti_get_emif2_size(void)
655 struct ti_common_eeprom *ep = TI_EEPROM_DATA;
657 if (ep->header != DRA7_EEPROM_HEADER_MAGIC)
660 return ep->emif2_size;
663 void __maybe_unused set_board_info_env(char *name)
665 char *unknown = "unknown";
666 struct ti_common_eeprom *ep = TI_EEPROM_DATA;
669 env_set("board_name", name);
671 env_set("board_name", ep->name);
673 env_set("board_name", unknown);
676 env_set("board_rev", ep->version);
678 env_set("board_rev", unknown);
681 env_set("board_serial", ep->serial);
683 env_set("board_serial", unknown);
686 void __maybe_unused set_board_info_env_am6(char *name)
688 char *unknown = "unknown";
689 struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA;
692 env_set("board_name", name);
694 env_set("board_name", ep->name);
696 env_set("board_name", unknown);
699 env_set("board_rev", ep->version);
701 env_set("board_rev", unknown);
703 if (ep->software_revision)
704 env_set("board_software_revision", ep->software_revision);
706 env_set("board_software_revision", unknown);
709 env_set("board_serial", ep->serial);
711 env_set("board_serial", unknown);
714 static u64 mac_to_u64(u8 mac[6])
719 for (i = 0; i < 6; i++) {
727 static void u64_to_mac(u64 addr, u8 mac[6])
737 void board_ti_set_ethaddr(int index)
742 u8 mac_addr1[6], mac_addr2[6];
745 * Export any Ethernet MAC addresses from EEPROM.
746 * The 2 MAC addresses in EEPROM define the address range.
748 board_ti_get_eth_mac_addr(0, mac_addr1);
749 board_ti_get_eth_mac_addr(1, mac_addr2);
751 if (is_valid_ethaddr(mac_addr1) && is_valid_ethaddr(mac_addr2)) {
752 mac1 = mac_to_u64(mac_addr1);
753 mac2 = mac_to_u64(mac_addr2);
755 /* must contain an address range */
756 num_macs = mac2 - mac1 + 1;
761 printf("%s: Too many MAC addresses: %d. Limiting to 50\n",
766 for (i = 0; i < num_macs; i++) {
767 u64_to_mac(mac1 + i, mac_addr);
768 if (is_valid_ethaddr(mac_addr)) {
769 eth_env_set_enetaddr_by_index("eth", i + index,
776 void board_ti_am6_set_ethaddr(int index, int count)
781 for (i = 0; i < count; i++) {
782 board_ti_am6_get_eth_mac_addr(i, mac_addr);
783 if (is_valid_ethaddr(mac_addr))
784 eth_env_set_enetaddr_by_index("eth", i + index,
789 bool __maybe_unused board_ti_was_eeprom_read(void)
791 struct ti_common_eeprom *ep = TI_EEPROM_DATA;
793 if (ep->header == TI_EEPROM_HEADER_MAGIC)