uboot/board/pm520/flash.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2001
   3 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
   4 *
   5 * (C) Copyright 2001-2004
   6 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   7 *
   8 * See file CREDITS for list of people who contributed to this
   9 * project.
  10 *
  11 * This program is free software; you can redistribute it and/or
  12 * modify it under the terms of the GNU General Public License as
  13 * published by the Free Software Foundation; either version 2 of
  14 * the License, or (at your option) any later version.
  15 *
  16 * This program is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 * GNU General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24 * MA 02111-1307 USA
  25 */
  26
  27#include <common.h>
  28#include <linux/byteorder/swab.h>
  29
  30
  31flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];    /* info for FLASH chips    */
  32
  33/* Board support for 1 or 2 flash devices */
  34#define FLASH_PORT_WIDTH32
  35#undef FLASH_PORT_WIDTH16
  36
  37#ifdef FLASH_PORT_WIDTH16
  38#define FLASH_PORT_WIDTH        ushort
  39#define FLASH_PORT_WIDTHV       vu_short
  40#define SWAP(x)                 (x)
  41#else
  42#define FLASH_PORT_WIDTH        ulong
  43#define FLASH_PORT_WIDTHV       vu_long
  44#define SWAP(x)                 (x)
  45#endif
  46
  47/* Intel-compatible flash ID */
  48#define INTEL_COMPAT            0x00890089
  49#define INTEL_ALT               0x00B000B0
  50
  51/* Intel-compatible flash commands */
  52#define INTEL_PROGRAM           0x00100010
  53#define INTEL_ERASE             0x00200020
  54#define INTEL_CLEAR             0x00500050
  55#define INTEL_LOCKBIT           0x00600060
  56#define INTEL_PROTECT           0x00010001
  57#define INTEL_STATUS            0x00700070
  58#define INTEL_READID            0x00900090
  59#define INTEL_CONFIRM           0x00D000D0
  60#define INTEL_RESET             0xFFFFFFFF
  61
  62/* Intel-compatible flash status bits */
  63#define INTEL_FINISHED          0x00800080
  64#define INTEL_OK                0x00800080
  65
  66#define FPW     FLASH_PORT_WIDTH
  67#define FPWV    FLASH_PORT_WIDTHV
  68
  69#define mb() __asm__ __volatile__ ("" : : : "memory")
  70
  71/*-----------------------------------------------------------------------
  72 * Functions
  73 */
  74static ulong flash_get_size (FPW *addr, flash_info_t *info);
  75static int write_data (flash_info_t *info, ulong dest, FPW data);
  76static void flash_get_offsets (ulong base, flash_info_t *info);
  77void inline spin_wheel (void);
  78static void flash_sync_real_protect (flash_info_t * info);
  79static unsigned char intel_sector_protected (flash_info_t *info, ushort sector);
  80
  81/*-----------------------------------------------------------------------
  82 */
  83
  84unsigned long flash_init (void)
  85{
  86        int i;
  87        ulong size = 0;
  88        extern void flash_preinit(void);
  89        extern void flash_afterinit(ulong, ulong);
  90        ulong flashbase = CONFIG_SYS_FLASH_BASE;
  91
  92        flash_preinit();
  93
  94        for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
  95                switch (i) {
  96                case 0:
  97                        memset(&flash_info[i], 0, sizeof(flash_info_t));
  98                        flash_get_size ((FPW *) flashbase, &flash_info[i]);
  99                        flash_get_offsets (flash_info[i].start[0], &flash_info[i]);
 100                        break;
 101                default:
 102                        panic ("configured to many flash banks!\n");
 103                        break;
 104                }
 105                size += flash_info[i].size;
 106
 107                /* get the h/w and s/w protection status in sync */
 108                flash_sync_real_protect(&flash_info[i]);
 109        }
 110
 111        /* Protect monitor and environment sectors
 112         */
 113#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
 114#ifndef CONFIG_BOOT_ROM
 115        flash_protect ( FLAG_PROTECT_SET,
 116                        CONFIG_SYS_MONITOR_BASE,
 117                        CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
 118                        &flash_info[0] );
 119#endif
 120#endif
 121
 122#ifdef  CONFIG_ENV_IS_IN_FLASH
 123        flash_protect ( FLAG_PROTECT_SET,
 124                        CONFIG_ENV_ADDR,
 125                        CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0] );
 126#endif
 127
 128        flash_afterinit(flash_info[0].start[0], flash_info[0].size);
 129
 130        return size;
 131}
 132
 133/*-----------------------------------------------------------------------
 134 */
 135static void flash_get_offsets (ulong base, flash_info_t *info)
 136{
 137        int i;
 138
 139        if (info->flash_id == FLASH_UNKNOWN) {
 140                return;
 141        }
 142
 143        if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
 144                for (i = 0; i < info->sector_count; i++) {
 145                        info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE);
 146                }
 147        }
 148}
 149
 150/*-----------------------------------------------------------------------
 151 */
 152void flash_print_info (flash_info_t *info)
 153{
 154        int i;
 155
 156        if (info->flash_id == FLASH_UNKNOWN) {
 157                printf ("missing or unknown FLASH type\n");
 158                return;
 159        }
 160
 161        switch (info->flash_id & FLASH_VENDMASK) {
 162        case FLASH_MAN_INTEL:
 163                printf ("INTEL ");
 164                break;
 165        default:
 166                printf ("Unknown Vendor ");
 167                break;
 168        }
 169
 170        switch (info->flash_id & FLASH_TYPEMASK) {
 171        case FLASH_28F256J3A:
 172                printf ("28F256J3A\n");
 173                break;
 174
 175        case FLASH_28F128J3A:
 176                printf ("28F128J3A\n");
 177                break;
 178
 179        case FLASH_28F640J3A:
 180                printf ("28F640J3A\n");
 181                break;
 182
 183        case FLASH_28F320J3A:
 184                printf ("28F320J3A\n");
 185                break;
 186
 187        default:
 188                printf ("Unknown Chip Type\n");
 189                break;
 190        }
 191
 192        printf ("  Size: %ld MB in %d Sectors\n",
 193                        info->size >> 20, info->sector_count);
 194
 195        printf ("  Sector Start Addresses:");
 196        for (i = 0; i < info->sector_count; ++i) {
 197                if ((i % 5) == 0)
 198                        printf ("\n   ");
 199                printf (" %08lX%s",
 200                        info->start[i],
 201                        info->protect[i] ? " (RO)" : "     ");
 202        }
 203        printf ("\n");
 204        return;
 205}
 206
 207/*
 208 * The following code cannot be run from FLASH!
 209 */
 210static ulong flash_get_size (FPW *addr, flash_info_t *info)
 211{
 212        volatile FPW value;
 213
 214        /* Write auto select command: read Manufacturer ID */
 215        addr[0x5555] = (FPW) 0x00AA00AA;
 216        addr[0x2AAA] = (FPW) 0x00550055;
 217        addr[0x5555] = (FPW) 0x00900090;
 218
 219        mb ();
 220        udelay(100);
 221
 222        value = addr[0];
 223
 224        switch (value) {
 225
 226        case (FPW) INTEL_MANUFACT:
 227                info->flash_id = FLASH_MAN_INTEL;
 228                break;
 229
 230        default:
 231                info->flash_id = FLASH_UNKNOWN;
 232                info->sector_count = 0;
 233                info->size = 0;
 234                addr[0] = (FPW) 0x00FF00FF;     /* restore read mode */
 235                return (0);                     /* no or unknown flash  */
 236        }
 237
 238        mb ();
 239        value = addr[1];                        /* device ID        */
 240
 241        switch (value) {
 242
 243        case (FPW) INTEL_ID_28F256J3A:
 244                info->flash_id += FLASH_28F256J3A;
 245                /* In U-Boot we support only 32 MB (no bank-switching) */
 246                info->sector_count = 256 / 2;
 247                info->size =  0x04000000 / 2;
 248                info->start[0] = CONFIG_SYS_FLASH_BASE + 0x02000000;
 249                break;                          /* => 32 MB     */
 250
 251        case (FPW) INTEL_ID_28F128J3A:
 252                info->flash_id += FLASH_28F128J3A;
 253                info->sector_count = 128;
 254                info->size = 0x02000000;
 255                info->start[0] = CONFIG_SYS_FLASH_BASE + 0x02000000;
 256                break;                          /* => 32 MB     */
 257
 258        case (FPW) INTEL_ID_28F640J3A:
 259                info->flash_id += FLASH_28F640J3A;
 260                info->sector_count = 64;
 261                info->size = 0x01000000;
 262                info->start[0] = CONFIG_SYS_FLASH_BASE + 0x03000000;
 263                break;                          /* => 16 MB     */
 264
 265        case (FPW) INTEL_ID_28F320J3A:
 266                info->flash_id += FLASH_28F320J3A;
 267                info->sector_count = 32;
 268                info->size = 0x800000;
 269                info->start[0] = CONFIG_SYS_FLASH_BASE + 0x03800000;
 270                break;                          /* => 8 MB     */
 271
 272        default:
 273                info->flash_id = FLASH_UNKNOWN;
 274                break;
 275        }
 276
 277        if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) {
 278                printf ("** ERROR: sector count %d > max (%d) **\n",
 279                        info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
 280                info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
 281        }
 282
 283        addr[0] = (FPW) 0x00FF00FF;             /* restore read mode */
 284
 285        return (info->size);
 286}
 287
 288
 289/*
 290 * This function gets the u-boot flash sector protection status
 291 * (flash_info_t.protect[]) in sync with the sector protection
 292 * status stored in hardware.
 293 */
 294static void flash_sync_real_protect (flash_info_t * info)
 295{
 296        int i;
 297
 298        switch (info->flash_id & FLASH_TYPEMASK) {
 299
 300        case FLASH_28F256J3A:
 301        case FLASH_28F128J3A:
 302        case FLASH_28F640J3A:
 303        case FLASH_28F320J3A:
 304                for (i = 0; i < info->sector_count; ++i) {
 305                        info->protect[i] = intel_sector_protected(info, i);
 306                }
 307                break;
 308        default:
 309                /* no h/w protect support */
 310                break;
 311        }
 312}
 313
 314
 315/*
 316 * checks if "sector" in bank "info" is protected. Should work on intel
 317 * strata flash chips 28FxxxJ3x in 8-bit mode.
 318 * Returns 1 if sector is protected (or timed-out while trying to read
 319 * protection status), 0 if it is not.
 320 */
 321static unsigned char intel_sector_protected (flash_info_t *info, ushort sector)
 322{
 323        FPWV *addr;
 324        FPWV *lock_conf_addr;
 325        ulong start;
 326        unsigned char ret;
 327
 328        /*
 329         * first, wait for the WSM to be finished. The rationale for
 330         * waiting for the WSM to become idle for at most
 331         * CONFIG_SYS_FLASH_ERASE_TOUT is as follows. The WSM can be busy
 332         * because of: (1) erase, (2) program or (3) lock bit
 333         * configuration. So we just wait for the longest timeout of
 334         * the (1)-(3), i.e. the erase timeout.
 335         */
 336
 337        /* wait at least 35ns (W12) before issuing Read Status Register */
 338        udelay(1);
 339        addr = (FPWV *) info->start[sector];
 340        *addr = (FPW) INTEL_STATUS;
 341
 342        start = get_timer (0);
 343        while ((*addr & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) {
 344                if (get_timer (start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 345                        *addr = (FPW) INTEL_RESET; /* restore read mode */
 346                        printf("WSM busy too long, can't get prot status\n");
 347                        return 1;
 348                }
 349        }
 350
 351        /* issue the Read Identifier Codes command */
 352        *addr = (FPW) INTEL_READID;
 353
 354        /* wait at least 35ns (W12) before reading */
 355        udelay(1);
 356
 357        /* Intel example code uses offset of 2 for 16 bit flash */
 358        lock_conf_addr = (FPWV *) info->start[sector] + 2;
 359        ret = (*lock_conf_addr & (FPW) INTEL_PROTECT) ? 1 : 0;
 360
 361        /* put flash back in read mode */
 362        *addr = (FPW) INTEL_RESET;
 363
 364        return ret;
 365}
 366
 367/*-----------------------------------------------------------------------
 368 */
 369
 370int flash_erase (flash_info_t *info, int s_first, int s_last)
 371{
 372        int flag, prot, sect;
 373        ulong type, start;
 374        int rcode = 0;
 375
 376        if ((s_first < 0) || (s_first > s_last)) {
 377                if (info->flash_id == FLASH_UNKNOWN) {
 378                        printf ("- missing\n");
 379                } else {
 380                        printf ("- no sectors to erase\n");
 381                }
 382                return 1;
 383        }
 384
 385        type = (info->flash_id & FLASH_VENDMASK);
 386        if ((type != FLASH_MAN_INTEL)) {
 387                printf ("Can't erase unknown flash type %08lx - aborted\n",
 388                        info->flash_id);
 389                return 1;
 390        }
 391
 392        prot = 0;
 393        for (sect = s_first; sect <= s_last; ++sect) {
 394                if (info->protect[sect]) {
 395                        prot++;
 396                }
 397        }
 398
 399        if (prot) {
 400                printf ("- Warning: %d protected sectors will not be erased!\n",
 401                        prot);
 402        } else {
 403                printf ("\n");
 404        }
 405
 406        start = get_timer (0);
 407
 408        /* Disable interrupts which might cause a timeout here */
 409        flag = disable_interrupts ();
 410
 411        /* Start erase on unprotected sectors */
 412        for (sect = s_first; sect <= s_last; sect++) {
 413                if (info->protect[sect] == 0) { /* not protected */
 414                        FPWV *addr = (FPWV *) (info->start[sect]);
 415                        FPW status;
 416
 417                        printf ("Erasing sector %2d ... ", sect);
 418
 419                        /* arm simple, non interrupt dependent timer */
 420                        start = get_timer(0);
 421
 422                        *addr = (FPW) 0x00500050;       /* clear status register */
 423                        *addr = (FPW) 0x00200020;       /* erase setup */
 424                        *addr = (FPW) 0x00D000D0;       /* erase confirm */
 425
 426                        while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
 427                                if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 428                                        printf ("Timeout\n");
 429                                        *addr = (FPW) 0x00B000B0;       /* suspend erase     */
 430                                        *addr = (FPW) 0x00FF00FF;       /* reset to read mode */
 431                                        rcode = 1;
 432                                        break;
 433                                }
 434                        }
 435
 436                        *addr = 0x00500050;     /* clear status register cmd.   */
 437                        *addr = 0x00FF00FF;     /* resest to read mode          */
 438
 439                        printf (" done\n");
 440                }
 441        }
 442
 443        if (flag)
 444                enable_interrupts();
 445
 446        return rcode;
 447}
 448
 449/*-----------------------------------------------------------------------
 450 * Copy memory to flash, returns:
 451 * 0 - OK
 452 * 1 - write timeout
 453 * 2 - Flash not erased
 454 * 4 - Flash not identified
 455 */
 456
 457int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
 458{
 459        ulong cp, wp;
 460        FPW data;
 461        int count, i, l, rc, port_width;
 462
 463        if (info->flash_id == FLASH_UNKNOWN) {
 464                return 4;
 465        }
 466/* get lower word aligned address */
 467#ifdef FLASH_PORT_WIDTH16
 468        wp = (addr & ~1);
 469        port_width = 2;
 470#else
 471        wp = (addr & ~3);
 472        port_width = 4;
 473#endif
 474
 475        /*
 476         * handle unaligned start bytes
 477         */
 478        if ((l = addr - wp) != 0) {
 479                data = 0;
 480                for (i = 0, cp = wp; i < l; ++i, ++cp) {
 481                        data = (data << 8) | (*(uchar *) cp);
 482                }
 483                for (; i < port_width && cnt > 0; ++i) {
 484                        data = (data << 8) | *src++;
 485                        --cnt;
 486                        ++cp;
 487                }
 488                for (; cnt == 0 && i < port_width; ++i, ++cp) {
 489                        data = (data << 8) | (*(uchar *) cp);
 490                }
 491
 492                if ((rc = write_data (info, wp, SWAP (data))) != 0) {
 493                        return (rc);
 494                }
 495                wp += port_width;
 496        }
 497
 498        /*
 499         * handle word aligned part
 500         */
 501        count = 0;
 502        while (cnt >= port_width) {
 503                data = 0;
 504                for (i = 0; i < port_width; ++i) {
 505                        data = (data << 8) | *src++;
 506                }
 507                if ((rc = write_data (info, wp, SWAP (data))) != 0) {
 508                        return (rc);
 509                }
 510                wp += port_width;
 511                cnt -= port_width;
 512                if (count++ > 0x800) {
 513                        spin_wheel ();
 514                        count = 0;
 515                }
 516        }
 517
 518        if (cnt == 0) {
 519                return (0);
 520        }
 521
 522        /*
 523         * handle unaligned tail bytes
 524         */
 525        data = 0;
 526        for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
 527                data = (data << 8) | *src++;
 528                --cnt;
 529        }
 530        for (; i < port_width; ++i, ++cp) {
 531                data = (data << 8) | (*(uchar *) cp);
 532        }
 533
 534        return (write_data (info, wp, SWAP (data)));
 535}
 536
 537/*-----------------------------------------------------------------------
 538 * Write a word or halfword to Flash, returns:
 539 * 0 - OK
 540 * 1 - write timeout
 541 * 2 - Flash not erased
 542 */
 543static int write_data (flash_info_t *info, ulong dest, FPW data)
 544{
 545        FPWV *addr = (FPWV *) dest;
 546        ulong status;
 547        ulong start;
 548        int flag;
 549        int rcode = 0;
 550
 551        /* Check if Flash is (sufficiently) erased */
 552        if ((*addr & data) != data) {
 553                printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr);
 554                return (2);
 555        }
 556        /* Disable interrupts which might cause a timeout here */
 557        flag = disable_interrupts ();
 558
 559        *addr = (FPW) 0x00400040;       /* write setup */
 560        *addr = data;
 561
 562        /* arm simple, non interrupt dependent timer */
 563        start = get_timer(0);
 564
 565        /* wait while polling the status register */
 566        while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
 567                if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 568                        rcode = 1;
 569                        break;
 570                }
 571        }
 572
 573        *addr = (FPW) 0x00FF00FF;       /* restore read mode */
 574
 575        if (flag)
 576                enable_interrupts();
 577
 578        return rcode;
 579}
 580
 581void inline spin_wheel (void)
 582{
 583        static int p = 0;
 584        static char w[] = "\\/-";
 585
 586        printf ("\010%c", w[p]);
 587        (++p == 3) ? (p = 0) : 0;
 588}
 589
 590/*-----------------------------------------------------------------------
 591 * Set/Clear sector's lock bit, returns:
 592 * 0 - OK
 593 * 1 - Error (timeout, voltage problems, etc.)
 594 */
 595int flash_real_protect (flash_info_t *info, long sector, int prot)
 596{
 597        ulong start;
 598        int i;
 599        int rc = 0;
 600        vu_long *addr = (vu_long *)(info->start[sector]);
 601        int flag = disable_interrupts();
 602
 603        *addr = INTEL_CLEAR;    /* Clear status register */
 604        if (prot) {                     /* Set sector lock bit */
 605                *addr = INTEL_LOCKBIT;  /* Sector lock bit */
 606                *addr = INTEL_PROTECT;  /* set */
 607        }
 608        else {                          /* Clear sector lock bit */
 609                *addr = INTEL_LOCKBIT;  /* All sectors lock bits */
 610                *addr = INTEL_CONFIRM;  /* clear */
 611        }
 612
 613        start = get_timer(0);
 614
 615        while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
 616                if (get_timer(start) > CONFIG_SYS_FLASH_UNLOCK_TOUT) {
 617                        printf("Flash lock bit operation timed out\n");
 618                        rc = 1;
 619                        break;
 620                }
 621        }
 622
 623        if (*addr != INTEL_OK) {
 624                printf("Flash lock bit operation failed at %08X, CSR=%08X\n",
 625                       (uint)addr, (uint)*addr);
 626                rc = 1;
 627        }
 628
 629        if (!rc)
 630                info->protect[sector] = prot;
 631
 632        /*
 633         * Clear lock bit command clears all sectors lock bits, so
 634         * we have to restore lock bits of protected sectors.
 635         * WARNING: code below re-locks sectors only for one bank (info).
 636         * This causes problems on boards where several banks share
 637         * the same chip, as sectors in othere banks will be unlocked
 638         * but not re-locked. It works fine on pm520 though, as there
 639         * is only one chip and one bank.
 640         */
 641        if (!prot)
 642        {
 643                for (i = 0; i < info->sector_count; i++)
 644                {
 645                        if (info->protect[i])
 646                        {
 647                                start = get_timer(0);
 648                                addr = (vu_long *)(info->start[i]);
 649                                *addr = INTEL_LOCKBIT;  /* Sector lock bit */
 650                                *addr = INTEL_PROTECT;  /* set */
 651                                while ((*addr & INTEL_FINISHED) != INTEL_FINISHED)
 652                                {
 653                                        if (get_timer(start) > CONFIG_SYS_FLASH_UNLOCK_TOUT)
 654                                        {
 655                                                printf("Flash lock bit operation timed out\n");
 656                                                rc = 1;
 657                                                break;
 658                                        }
 659                                }
 660                        }
 661                }
 662                /*
 663                 * get the s/w sector protection status in sync with the h/w,
 664                 * in case something went wrong during the re-locking.
 665                 */
 666                flash_sync_real_protect(info); /* resets flash to read  mode */
 667        }
 668
 669        if (flag)
 670                enable_interrupts();
 671
 672        *addr = INTEL_RESET;            /* Reset to read array mode */
 673
 674        return rc;
 675}
 676