uboot/board/freescale/common/sys_eeprom.c
<<
>>
Prefs
   1/*
   2 * Copyright 2006, 2008-2009 Freescale Semiconductor
   3 * York Sun (yorksun@freescale.com)
   4 * Haiying Wang (haiying.wang@freescale.com)
   5 * Timur Tabi (timur@freescale.com)
   6 *
   7 * See file CREDITS for list of people who contributed to this
   8 * project.
   9 *
  10 * This program is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU General Public License as
  12 * published by the Free Software Foundation; either version 2 of
  13 * the License, or (at your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 * GNU General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public License
  21 * along with this program; if not, write to the Free Software
  22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23 * MA 02111-1307 USA
  24 */
  25
  26#include <common.h>
  27#include <command.h>
  28#include <i2c.h>
  29#include <linux/ctype.h>
  30
  31#include "../common/eeprom.h"
  32
  33#if !defined(CONFIG_SYS_I2C_EEPROM_CCID) && !defined(CONFIG_SYS_I2C_EEPROM_NXID)
  34#error "Please define either CONFIG_SYS_I2C_EEPROM_CCID or CONFIG_SYS_I2C_EEPROM_NXID"
  35#endif
  36
  37#define MAX_NUM_PORTS   8       /* This value must be 8 as defined in doc */
  38
  39/**
  40 * static eeprom: EEPROM layout for CCID or NXID formats
  41 *
  42 * See application note AN3638 for details.
  43 */
  44static struct __attribute__ ((__packed__)) eeprom {
  45#ifdef CONFIG_SYS_I2C_EEPROM_CCID
  46        u8 id[4];         /* 0x00 - 0x03 EEPROM Tag 'CCID' */
  47        u8 major;         /* 0x04        Board revision, major */
  48        u8 minor;         /* 0x05        Board revision, minor */
  49        u8 sn[10];        /* 0x06 - 0x0F Serial Number*/
  50        u8 errata[2];     /* 0x10 - 0x11 Errata Level */
  51        u8 date[6];       /* 0x12 - 0x17 Build Date */
  52        u8 res_0[40];     /* 0x18 - 0x3f Reserved */
  53        u8 mac_count;     /* 0x40        Number of MAC addresses */
  54        u8 mac_flag;      /* 0x41        MAC table flags */
  55        u8 mac[MAX_NUM_PORTS][6];     /* 0x42 - 0x71 MAC addresses */
  56        u32 crc;          /* 0x72        CRC32 checksum */
  57#endif
  58#ifdef CONFIG_SYS_I2C_EEPROM_NXID
  59        u8 id[4];         /* 0x00 - 0x03 EEPROM Tag 'NXID' */
  60        u8 sn[12];        /* 0x04 - 0x0F Serial Number */
  61        u8 errata[5];     /* 0x10 - 0x14 Errata Level */
  62        u8 date[6];       /* 0x15 - 0x1a Build Date */
  63        u8 res_0;         /* 0x1b        Reserved */
  64        u32 version;      /* 0x1c - 0x1f NXID Version */
  65        u8 tempcal[8];    /* 0x20 - 0x27 Temperature Calibration Factors */
  66        u8 tempcalsys[2]; /* 0x28 - 0x29 System Temperature Calibration Factors */
  67        u8 tempcalflags;  /* 0x2a        Temperature Calibration Flags */
  68        u8 res_1[21];     /* 0x2b - 0x3f Reserved */
  69        u8 mac_count;     /* 0x40        Number of MAC addresses */
  70        u8 mac_flag;      /* 0x41        MAC table flags */
  71        u8 mac[MAX_NUM_PORTS][6];     /* 0x42 - 0x71 MAC addresses */
  72        u32 crc;          /* 0x72        CRC32 checksum */
  73#endif
  74} e;
  75
  76/* Set to 1 if we've read EEPROM into memory */
  77static int has_been_read = 0;
  78
  79#ifdef CONFIG_SYS_I2C_EEPROM_NXID
  80/* Is this a valid NXID EEPROM? */
  81#define is_valid ((e.id[0] == 'N') || (e.id[1] == 'X') || \
  82                  (e.id[2] == 'I') || (e.id[3] == 'D'))
  83#endif
  84
  85#ifdef CONFIG_SYS_I2C_EEPROM_CCID
  86/* Is this a valid CCID EEPROM? */
  87#define is_valid ((e.id[0] == 'C') || (e.id[1] == 'C') || \
  88                  (e.id[2] == 'I') || (e.id[3] == 'D'))
  89#endif
  90
  91/**
  92 * show_eeprom - display the contents of the EEPROM
  93 */
  94static void show_eeprom(void)
  95{
  96        int i;
  97        unsigned int crc;
  98
  99        /* EEPROM tag ID, either CCID or NXID */
 100#ifdef CONFIG_SYS_I2C_EEPROM_NXID
 101        printf("ID: %c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3],
 102                be32_to_cpu(e.version));
 103#else
 104        printf("ID: %c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]);
 105#endif
 106
 107        /* Serial number */
 108        printf("SN: %s\n", e.sn);
 109
 110        /* Errata level. */
 111#ifdef CONFIG_SYS_I2C_EEPROM_NXID
 112        printf("Errata: %s\n", e.errata);
 113#else
 114        printf("Errata: %c%c\n",
 115                e.errata[0] ? e.errata[0] : '.',
 116                e.errata[1] ? e.errata[1] : '.');
 117#endif
 118
 119        /* Build date, BCD date values, as YYMMDDhhmmss */
 120        printf("Build date: 20%02x/%02x/%02x %02x:%02x:%02x %s\n",
 121                e.date[0], e.date[1], e.date[2],
 122                e.date[3] & 0x7F, e.date[4], e.date[5],
 123                e.date[3] & 0x80 ? "PM" : "");
 124
 125        /* Show MAC addresses  */
 126        for (i = 0; i < min(e.mac_count, MAX_NUM_PORTS); i++) {
 127
 128                u8 *p = e.mac[i];
 129
 130                printf("Eth%u: %02x:%02x:%02x:%02x:%02x:%02x\n", i,
 131                        p[0], p[1], p[2], p[3], p[4], p[5]);
 132        }
 133
 134        crc = crc32(0, (void *)&e, sizeof(e) - 4);
 135
 136        if (crc == be32_to_cpu(e.crc))
 137                printf("CRC: %08x\n", be32_to_cpu(e.crc));
 138        else
 139                printf("CRC: %08x (should be %08x)\n",
 140                        be32_to_cpu(e.crc), crc);
 141
 142#ifdef DEBUG
 143        printf("EEPROM dump: (0x%x bytes)\n", sizeof(e));
 144        for (i = 0; i < sizeof(e); i++) {
 145                if ((i % 16) == 0)
 146                        printf("%02X: ", i);
 147                printf("%02X ", ((u8 *)&e)[i]);
 148                if (((i % 16) == 15) || (i == sizeof(e) - 1))
 149                        printf("\n");
 150        }
 151#endif
 152}
 153
 154/**
 155 * read_eeprom - read the EEPROM into memory
 156 */
 157static int read_eeprom(void)
 158{
 159        int ret;
 160#ifdef CONFIG_SYS_EEPROM_BUS_NUM
 161        unsigned int bus;
 162#endif
 163
 164        if (has_been_read)
 165                return 0;
 166
 167#ifdef CONFIG_SYS_EEPROM_BUS_NUM
 168        bus = i2c_get_bus_num();
 169        i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM);
 170#endif
 171
 172        ret = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
 173                (void *)&e, sizeof(e));
 174
 175#ifdef CONFIG_SYS_EEPROM_BUS_NUM
 176        i2c_set_bus_num(bus);
 177#endif
 178
 179#ifdef DEBUG
 180        show_eeprom();
 181#endif
 182
 183        has_been_read = (ret == 0) ? 1 : 0;
 184
 185        return ret;
 186}
 187
 188/**
 189 *  update_crc - update the CRC
 190 *
 191 *  This function should be called after each update to the EEPROM structure,
 192 *  to make sure the CRC is always correct.
 193 */
 194static void update_crc(void)
 195{
 196        u32 crc;
 197
 198        crc = crc32(0, (void *)&e, sizeof(e) - 4);
 199        e.crc = cpu_to_be32(crc);
 200}
 201
 202/**
 203 * prog_eeprom - write the EEPROM from memory
 204 */
 205static int prog_eeprom(void)
 206{
 207        int ret = 0; /* shut up gcc */
 208        int i;
 209        void *p;
 210#ifdef CONFIG_SYS_EEPROM_BUS_NUM
 211        unsigned int bus;
 212#endif
 213
 214        /* Set the reserved values to 0xFF   */
 215#ifdef CONFIG_SYS_I2C_EEPROM_NXID
 216        e.res_0 = 0xFF;
 217        memset(e.res_1, 0xFF, sizeof(e.res_1));
 218#else
 219        memset(e.res_0, 0xFF, sizeof(e.res_0));
 220#endif
 221        update_crc();
 222
 223#ifdef CONFIG_SYS_EEPROM_BUS_NUM
 224        bus = i2c_get_bus_num();
 225        i2c_set_bus_num(CONFIG_SYS_EEPROM_BUS_NUM);
 226#endif
 227
 228        for (i = 0, p = &e; i < sizeof(e); i += 8, p += 8) {
 229                ret = i2c_write(CONFIG_SYS_I2C_EEPROM_ADDR, i, CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
 230                        p, min((sizeof(e) - i), 8));
 231                if (ret)
 232                        break;
 233                udelay(5000);   /* 5ms write cycle timing */
 234        }
 235
 236#ifdef CONFIG_SYS_EEPROM_BUS_NUM
 237        i2c_set_bus_num(bus);
 238#endif
 239
 240        if (ret) {
 241                printf("Programming failed.\n");
 242                return -1;
 243        }
 244
 245        printf("Programming passed.\n");
 246        return 0;
 247}
 248
 249/**
 250 * h2i - converts hex character into a number
 251 *
 252 * This function takes a hexadecimal character (e.g. '7' or 'C') and returns
 253 * the integer equivalent.
 254 */
 255static inline u8 h2i(char p)
 256{
 257        if ((p >= '0') && (p <= '9'))
 258                return p - '0';
 259
 260        if ((p >= 'A') && (p <= 'F'))
 261                return (p - 'A') + 10;
 262
 263        if ((p >= 'a') && (p <= 'f'))
 264                return (p - 'a') + 10;
 265
 266        return 0;
 267}
 268
 269/**
 270 * set_date - stores the build date into the EEPROM
 271 *
 272 * This function takes a pointer to a string in the format "YYMMDDhhmmss"
 273 * (2-digit year, 2-digit month, etc), converts it to a 6-byte BCD string,
 274 * and stores it in the build date field of the EEPROM local copy.
 275 */
 276static void set_date(const char *string)
 277{
 278        unsigned int i;
 279
 280        if (strlen(string) != 12) {
 281                printf("Usage: mac date YYMMDDhhmmss\n");
 282                return;
 283        }
 284
 285        for (i = 0; i < 6; i++)
 286                e.date[i] = h2i(string[2 * i]) << 4 | h2i(string[2 * i + 1]);
 287
 288        update_crc();
 289}
 290
 291/**
 292 * set_mac_address - stores a MAC address into the EEPROM
 293 *
 294 * This function takes a pointer to MAC address string
 295 * (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number) and
 296 * stores it in one of the MAC address fields of the EEPROM local copy.
 297 */
 298static void set_mac_address(unsigned int index, const char *string)
 299{
 300        char *p = (char *) string;
 301        unsigned int i;
 302
 303        if (!string) {
 304                printf("Usage: mac <n> XX:XX:XX:XX:XX:XX\n");
 305                return;
 306        }
 307
 308        for (i = 0; *p && (i < 6); i++) {
 309                e.mac[index][i] = simple_strtoul(p, &p, 16);
 310                if (*p == ':')
 311                        p++;
 312        }
 313
 314        update_crc();
 315}
 316
 317int do_mac(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 318{
 319        char cmd;
 320
 321        if (argc == 1) {
 322                show_eeprom();
 323                return 0;
 324        }
 325
 326        cmd = argv[1][0];
 327
 328        if (cmd == 'r') {
 329                read_eeprom();
 330                return 0;
 331        }
 332
 333        if (cmd == 'i') {
 334#ifdef CONFIG_SYS_I2C_EEPROM_NXID
 335                memcpy(e.id, "NXID", sizeof(e.id));
 336                e.version = 0;
 337#else
 338                memcpy(e.id, "CCID", sizeof(e.id));
 339#endif
 340                return 0;
 341        }
 342
 343        if (!is_valid) {
 344                printf("Please read the EEPROM ('r') and/or set the ID ('i') first.\n");
 345                return 0;
 346        }
 347
 348        if (argc == 2) {
 349                switch (cmd) {
 350                case 's':       /* save */
 351                        prog_eeprom();
 352                        break;
 353                default:
 354                        cmd_usage(cmdtp);
 355                        break;
 356                }
 357
 358                return 0;
 359        }
 360
 361        /* We know we have at least one parameter  */
 362
 363        switch (cmd) {
 364        case 'n':       /* serial number */
 365                memset(e.sn, 0, sizeof(e.sn));
 366                strncpy((char *)e.sn, argv[2], sizeof(e.sn) - 1);
 367                update_crc();
 368                break;
 369        case 'e':       /* errata */
 370#ifdef CONFIG_SYS_I2C_EEPROM_NXID
 371                memset(e.errata, 0, 5);
 372                strncpy((char *)e.errata, argv[2], 4);
 373#else
 374                e.errata[0] = argv[2][0];
 375                e.errata[1] = argv[2][1];
 376#endif
 377                update_crc();
 378                break;
 379        case 'd':       /* date BCD format YYMMDDhhmmss */
 380                set_date(argv[2]);
 381                break;
 382        case 'p':       /* MAC table size */
 383                e.mac_count = simple_strtoul(argv[2], NULL, 16);
 384                update_crc();
 385                break;
 386        case '0' ... '7':       /* "mac 0" through "mac 7" */
 387                set_mac_address(cmd - '0', argv[2]);
 388                break;
 389        case 'h':       /* help */
 390        default:
 391                cmd_usage(cmdtp);
 392                break;
 393        }
 394
 395        return 0;
 396}
 397
 398/**
 399 * mac_read_from_eeprom - read the MAC addresses from EEPROM
 400 *
 401 * This function reads the MAC addresses from EEPROM and sets the
 402 * appropriate environment variables for each one read.
 403 *
 404 * The environment variables are only set if they haven't been set already.
 405 * This ensures that any user-saved variables are never overwritten.
 406 *
 407 * This function must be called after relocation.
 408 */
 409int mac_read_from_eeprom(void)
 410{
 411        unsigned int i;
 412        u32 crc;
 413
 414        puts("EEPROM: ");
 415
 416        if (read_eeprom()) {
 417                printf("Read failed.\n");
 418                return -1;
 419        }
 420
 421        if (!is_valid) {
 422                printf("Invalid ID (%02x %02x %02x %02x)\n",
 423                       e.id[0], e.id[1], e.id[2], e.id[3]);
 424                return -1;
 425        }
 426
 427        crc = crc32(0, (void *)&e, sizeof(e) - 4);
 428        if (crc != be32_to_cpu(e.crc)) {
 429                printf("CRC mismatch (%08x != %08x)\n", crc, be32_to_cpu(e.crc));
 430                return -1;
 431        }
 432
 433        for (i = 0; i < min(e.mac_count, MAX_NUM_PORTS); i++) {
 434                if (memcmp(&e.mac[i], "\0\0\0\0\0\0", 6) &&
 435                    memcmp(&e.mac[i], "\xFF\xFF\xFF\xFF\xFF\xFF", 6)) {
 436                        char ethaddr[18];
 437                        char enetvar[9];
 438
 439                        sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X",
 440                                e.mac[i][0],
 441                                e.mac[i][1],
 442                                e.mac[i][2],
 443                                e.mac[i][3],
 444                                e.mac[i][4],
 445                                e.mac[i][5]);
 446                        sprintf(enetvar, i ? "eth%daddr" : "ethaddr", i);
 447                        /* Only initialize environment variables that are blank
 448                         * (i.e. have not yet been set)
 449                         */
 450                        if (!getenv(enetvar))
 451                                setenv(enetvar, ethaddr);
 452                }
 453        }
 454
 455#ifdef CONFIG_SYS_I2C_EEPROM_NXID
 456        printf("%c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3],
 457                be32_to_cpu(e.version));
 458#else
 459        printf("%c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]);
 460#endif
 461
 462        return 0;
 463}
 464
 465#ifdef CONFIG_SYS_I2C_EEPROM_CCID
 466
 467/**
 468 * get_cpu_board_revision - get the CPU board revision on 85xx boards
 469 *
 470 * Read the EEPROM to determine the board revision.
 471 *
 472 * This function is called before relocation, so we need to read a private
 473 * copy of the EEPROM into a local variable on the stack.
 474 *
 475 * Also, we assume that CONFIG_SYS_EEPROM_BUS_NUM == CONFIG_SYS_SPD_BUS_NUM.  The global
 476 * variable i2c_bus_num must be compile-time initialized to CONFIG_SYS_SPD_BUS_NUM,
 477 * so that the SPD code will work.  This means that all pre-relocation I2C
 478 * operations can only occur on the CONFIG_SYS_SPD_BUS_NUM bus.  So if
 479 * CONFIG_SYS_EEPROM_BUS_NUM != CONFIG_SYS_SPD_BUS_NUM, then we can't read the EEPROM when
 480 * this function is called.  Oh well.
 481 */
 482unsigned int get_cpu_board_revision(void)
 483{
 484        struct board_eeprom {
 485                u32 id;           /* 0x00 - 0x03 EEPROM Tag 'CCID' */
 486                u8 major;         /* 0x04        Board revision, major */
 487                u8 minor;         /* 0x05        Board revision, minor */
 488        } be;
 489
 490        i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, CONFIG_SYS_I2C_EEPROM_ADDR_LEN,
 491                (void *)&be, sizeof(be));
 492
 493        if (be.id != (('C' << 24) | ('C' << 16) | ('I' << 8) | 'D'))
 494                return MPC85XX_CPU_BOARD_REV(0, 0);
 495
 496        if ((be.major == 0xff) && (be.minor == 0xff))
 497                return MPC85XX_CPU_BOARD_REV(0, 0);
 498
 499        return MPC85XX_CPU_BOARD_REV(be.major, be.minor);
 500}
 501#endif
 502