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, last;
 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        last = start;
 408
 409        /* Disable interrupts which might cause a timeout here */
 410        flag = disable_interrupts ();
 411
 412        /* Start erase on unprotected sectors */
 413        for (sect = s_first; sect <= s_last; sect++) {
 414                if (info->protect[sect] == 0) { /* not protected */
 415                        FPWV *addr = (FPWV *) (info->start[sect]);
 416                        FPW status;
 417
 418                        printf ("Erasing sector %2d ... ", sect);
 419
 420                        /* arm simple, non interrupt dependent timer */
 421                        start = get_timer(0);
 422
 423                        *addr = (FPW) 0x00500050;       /* clear status register */
 424                        *addr = (FPW) 0x00200020;       /* erase setup */
 425                        *addr = (FPW) 0x00D000D0;       /* erase confirm */
 426
 427                        while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
 428                                if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 429                                        printf ("Timeout\n");
 430                                        *addr = (FPW) 0x00B000B0;       /* suspend erase     */
 431                                        *addr = (FPW) 0x00FF00FF;       /* reset to read mode */
 432                                        rcode = 1;
 433                                        break;
 434                                }
 435                        }
 436
 437                        *addr = 0x00500050;     /* clear status register cmd.   */
 438                        *addr = 0x00FF00FF;     /* resest to read mode          */
 439
 440                        printf (" done\n");
 441                }
 442        }
 443        return rcode;
 444}
 445
 446/*-----------------------------------------------------------------------
 447 * Copy memory to flash, returns:
 448 * 0 - OK
 449 * 1 - write timeout
 450 * 2 - Flash not erased
 451 * 4 - Flash not identified
 452 */
 453
 454int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
 455{
 456        ulong cp, wp;
 457        FPW data;
 458        int count, i, l, rc, port_width;
 459
 460        if (info->flash_id == FLASH_UNKNOWN) {
 461                return 4;
 462        }
 463/* get lower word aligned address */
 464#ifdef FLASH_PORT_WIDTH16
 465        wp = (addr & ~1);
 466        port_width = 2;
 467#else
 468        wp = (addr & ~3);
 469        port_width = 4;
 470#endif
 471
 472        /*
 473         * handle unaligned start bytes
 474         */
 475        if ((l = addr - wp) != 0) {
 476                data = 0;
 477                for (i = 0, cp = wp; i < l; ++i, ++cp) {
 478                        data = (data << 8) | (*(uchar *) cp);
 479                }
 480                for (; i < port_width && cnt > 0; ++i) {
 481                        data = (data << 8) | *src++;
 482                        --cnt;
 483                        ++cp;
 484                }
 485                for (; cnt == 0 && i < port_width; ++i, ++cp) {
 486                        data = (data << 8) | (*(uchar *) cp);
 487                }
 488
 489                if ((rc = write_data (info, wp, SWAP (data))) != 0) {
 490                        return (rc);
 491                }
 492                wp += port_width;
 493        }
 494
 495        /*
 496         * handle word aligned part
 497         */
 498        count = 0;
 499        while (cnt >= port_width) {
 500                data = 0;
 501                for (i = 0; i < port_width; ++i) {
 502                        data = (data << 8) | *src++;
 503                }
 504                if ((rc = write_data (info, wp, SWAP (data))) != 0) {
 505                        return (rc);
 506                }
 507                wp += port_width;
 508                cnt -= port_width;
 509                if (count++ > 0x800) {
 510                        spin_wheel ();
 511                        count = 0;
 512                }
 513        }
 514
 515        if (cnt == 0) {
 516                return (0);
 517        }
 518
 519        /*
 520         * handle unaligned tail bytes
 521         */
 522        data = 0;
 523        for (i = 0, cp = wp; i < port_width && cnt > 0; ++i, ++cp) {
 524                data = (data << 8) | *src++;
 525                --cnt;
 526        }
 527        for (; i < port_width; ++i, ++cp) {
 528                data = (data << 8) | (*(uchar *) cp);
 529        }
 530
 531        return (write_data (info, wp, SWAP (data)));
 532}
 533
 534/*-----------------------------------------------------------------------
 535 * Write a word or halfword to Flash, returns:
 536 * 0 - OK
 537 * 1 - write timeout
 538 * 2 - Flash not erased
 539 */
 540static int write_data (flash_info_t *info, ulong dest, FPW data)
 541{
 542        FPWV *addr = (FPWV *) dest;
 543        ulong status;
 544        ulong start;
 545        int flag;
 546
 547        /* Check if Flash is (sufficiently) erased */
 548        if ((*addr & data) != data) {
 549                printf ("not erased at %08lx (%lx)\n", (ulong) addr, *addr);
 550                return (2);
 551        }
 552        /* Disable interrupts which might cause a timeout here */
 553        flag = disable_interrupts ();
 554
 555        *addr = (FPW) 0x00400040;       /* write setup */
 556        *addr = data;
 557
 558        /* arm simple, non interrupt dependent timer */
 559        start = get_timer(0);
 560
 561        /* wait while polling the status register */
 562        while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
 563                if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 564                        *addr = (FPW) 0x00FF00FF;       /* restore read mode */
 565                        return (1);
 566                }
 567        }
 568
 569        *addr = (FPW) 0x00FF00FF;       /* restore read mode */
 570
 571        return (0);
 572}
 573
 574void inline spin_wheel (void)
 575{
 576        static int p = 0;
 577        static char w[] = "\\/-";
 578
 579        printf ("\010%c", w[p]);
 580        (++p == 3) ? (p = 0) : 0;
 581}
 582
 583/*-----------------------------------------------------------------------
 584 * Set/Clear sector's lock bit, returns:
 585 * 0 - OK
 586 * 1 - Error (timeout, voltage problems, etc.)
 587 */
 588int flash_real_protect (flash_info_t *info, long sector, int prot)
 589{
 590        ulong start;
 591        int i;
 592        int rc = 0;
 593        vu_long *addr = (vu_long *)(info->start[sector]);
 594        int flag = disable_interrupts();
 595
 596        *addr = INTEL_CLEAR;    /* Clear status register */
 597        if (prot) {                     /* Set sector lock bit */
 598                *addr = INTEL_LOCKBIT;  /* Sector lock bit */
 599                *addr = INTEL_PROTECT;  /* set */
 600        }
 601        else {                          /* Clear sector lock bit */
 602                *addr = INTEL_LOCKBIT;  /* All sectors lock bits */
 603                *addr = INTEL_CONFIRM;  /* clear */
 604        }
 605
 606        start = get_timer(0);
 607
 608        while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
 609                if (get_timer(start) > CONFIG_SYS_FLASH_UNLOCK_TOUT) {
 610                        printf("Flash lock bit operation timed out\n");
 611                        rc = 1;
 612                        break;
 613                }
 614        }
 615
 616        if (*addr != INTEL_OK) {
 617                printf("Flash lock bit operation failed at %08X, CSR=%08X\n",
 618                       (uint)addr, (uint)*addr);
 619                rc = 1;
 620        }
 621
 622        if (!rc)
 623                info->protect[sector] = prot;
 624
 625        /*
 626         * Clear lock bit command clears all sectors lock bits, so
 627         * we have to restore lock bits of protected sectors.
 628         * WARNING: code below re-locks sectors only for one bank (info).
 629         * This causes problems on boards where several banks share
 630         * the same chip, as sectors in othere banks will be unlocked
 631         * but not re-locked. It works fine on pm520 though, as there
 632         * is only one chip and one bank.
 633         */
 634        if (!prot)
 635        {
 636                for (i = 0; i < info->sector_count; i++)
 637                {
 638                        if (info->protect[i])
 639                        {
 640                                start = get_timer(0);
 641                                addr = (vu_long *)(info->start[i]);
 642                                *addr = INTEL_LOCKBIT;  /* Sector lock bit */
 643                                *addr = INTEL_PROTECT;  /* set */
 644                                while ((*addr & INTEL_FINISHED) != INTEL_FINISHED)
 645                                {
 646                                        if (get_timer(start) > CONFIG_SYS_FLASH_UNLOCK_TOUT)
 647                                        {
 648                                                printf("Flash lock bit operation timed out\n");
 649                                                rc = 1;
 650                                                break;
 651                                        }
 652                                }
 653                        }
 654                }
 655                /*
 656                 * get the s/w sector protection status in sync with the h/w,
 657                 * in case something went wrong during the re-locking.
 658                 */
 659                flash_sync_real_protect(info); /* resets flash to read  mode */
 660        }
 661
 662        if (flag)
 663                enable_interrupts();
 664
 665        *addr = INTEL_RESET;            /* Reset to read array mode */
 666
 667        return rc;
 668}
 669