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