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