uboot/board/w7o/flash.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2001
   3 * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
   4 *  Based on code by:
   5 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   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 <asm/ppc4xx.h>
  28#include <asm/processor.h>
  29
  30#include <watchdog.h>
  31
  32/* info for FLASH chips    */
  33flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
  34
  35/*
  36 * Functions
  37 */
  38static ulong flash_get_size(vu_long *addr, flash_info_t *info);
  39static int write_word8(flash_info_t *info, ulong dest, ulong data);
  40static int write_word32(flash_info_t *info, ulong dest, ulong data);
  41static void flash_get_offsets(ulong base, flash_info_t *info);
  42
  43unsigned long flash_init(void)
  44{
  45        int i;
  46        unsigned long size_b0, base_b0;
  47        unsigned long size_b1;
  48
  49        /* Init: no FLASHes known */
  50        for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i)
  51                flash_info[i].flash_id = FLASH_UNKNOWN;
  52
  53        /* Get Size of Boot and Main Flashes */
  54        size_b0 = flash_get_size((vu_long *) FLASH_BASE0_PRELIM,
  55                               &flash_info[0]);
  56        if (flash_info[0].flash_id == FLASH_UNKNOWN) {
  57                printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
  58                        size_b0, size_b0 << 20);
  59                return 0;
  60        }
  61        size_b1 =
  62                flash_get_size((vu_long *) FLASH_BASE1_PRELIM,
  63                               &flash_info[1]);
  64        if (flash_info[1].flash_id == FLASH_UNKNOWN) {
  65                printf("## Unknown FLASH on Bank 1 - Size = 0x%08lx = %ld MB\n",
  66                        size_b1, size_b1 << 20);
  67                return 0;
  68        }
  69
  70        /* Calculate base addresses */
  71        base_b0 = -size_b0;
  72
  73        /* Setup offsets for Boot Flash */
  74        flash_get_offsets(base_b0, &flash_info[0]);
  75
  76        /* Protect board level data */
  77        (void) flash_protect(FLAG_PROTECT_SET,
  78                             base_b0,
  79                             flash_info[0].start[1] - 1, &flash_info[0]);
  80
  81        /* Monitor protection ON by default */
  82        (void) flash_protect(FLAG_PROTECT_SET,
  83                             base_b0 + size_b0 - monitor_flash_len,
  84                             base_b0 + size_b0 - 1, &flash_info[0]);
  85
  86        /* Protect the FPGA image */
  87        (void) flash_protect(FLAG_PROTECT_SET,
  88                             FLASH_BASE1_PRELIM,
  89                             FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN -
  90                             1, &flash_info[1]);
  91
  92        /* Protect the default boot image */
  93        (void) flash_protect(FLAG_PROTECT_SET,
  94                             FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN,
  95                             FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN +
  96                             0x600000 - 1, &flash_info[1]);
  97
  98        /* Setup offsets for Main Flash */
  99        flash_get_offsets(FLASH_BASE1_PRELIM, &flash_info[1]);
 100
 101        return size_b0 + size_b1;
 102}
 103
 104static void flash_get_offsets(ulong base, flash_info_t *info)
 105{
 106        int i;
 107
 108        /* set up sector start address table - FOR BOOT ROM ONLY!!! */
 109        if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) {
 110                for (i = 0; i < info->sector_count; i++)
 111                        info->start[i] = base + (i * 0x00010000);
 112        }
 113}                               /* end flash_get_offsets() */
 114
 115void flash_print_info(flash_info_t *info)
 116{
 117        int i;
 118        int k;
 119        int size;
 120        int erased;
 121        volatile unsigned long *flash;
 122
 123        if (info->flash_id == FLASH_UNKNOWN) {
 124                printf("missing or unknown FLASH type\n");
 125                return;
 126        }
 127
 128        switch (info->flash_id & FLASH_VENDMASK) {
 129        case FLASH_MAN_AMD:
 130                printf("1 x AMD ");
 131                break;
 132        case FLASH_MAN_STM:
 133                printf("1 x STM ");
 134                break;
 135        case FLASH_MAN_INTEL:
 136                printf("2 x Intel ");
 137                break;
 138        default:
 139                printf("Unknown Vendor ");
 140        }
 141
 142        switch (info->flash_id & FLASH_TYPEMASK) {
 143        case FLASH_AM040:
 144                if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
 145                        printf("AM29LV040 (4096 Kbit, uniform sector size)\n");
 146                else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM)
 147                        printf("M29W040B (4096 Kbit, uniform block size)\n");
 148                else
 149                        printf("UNKNOWN 29x040x (4096 Kbit, uniform sector size)\n");
 150                break;
 151        case FLASH_28F320J3A:
 152                printf("28F320J3A (32 Mbit = 128K x 32)\n");
 153                break;
 154        case FLASH_28F640J3A:
 155                printf("28F640J3A (64 Mbit = 128K x 64)\n");
 156                break;
 157        case FLASH_28F128J3A:
 158                printf("28F128J3A (128 Mbit = 128K x 128)\n");
 159                break;
 160        default:
 161                printf("Unknown Chip Type\n");
 162        }
 163
 164        if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM) {
 165                printf("  Size: %ld KB in %d Blocks\n",
 166                       info->size >> 10, info->sector_count);
 167        } else {
 168                printf("  Size: %ld KB in %d Sectors\n",
 169                       info->size >> 10, info->sector_count);
 170        }
 171
 172        printf("  Sector Start Addresses:");
 173        for (i = 0; i < info->sector_count; ++i) {
 174                /*
 175                 * Check if whole sector is erased
 176                 */
 177                if (i != (info->sector_count - 1))
 178                        size = info->start[i + 1] - info->start[i];
 179                else
 180                        size = info->start[0] + info->size - info->start[i];
 181                erased = 1;
 182                flash = (volatile unsigned long *) info->start[i];
 183                size = size >> 2;       /* divide by 4 for longword access */
 184                for (k = 0; k < size; k++) {
 185                        if (*flash++ != 0xffffffff) {
 186                                erased = 0;
 187                                break;
 188                        }
 189                }
 190
 191                if ((i % 5) == 0)
 192                        printf("\n   ");
 193                printf(" %08lX%s%s",
 194                       info->start[i],
 195                       erased ? " E" : "  ",
 196                       info->protect[i] ? "RO " : "   ");
 197        }
 198        printf("\n");
 199}                               /* end flash_print_info() */
 200
 201/*
 202 * The following code cannot be run from FLASH!
 203 */
 204static ulong flash_get_size(vu_long *addr, flash_info_t *info)
 205{
 206        short i;
 207        ulong base = (ulong) addr;
 208
 209        /* Setup default type */
 210        info->flash_id = FLASH_UNKNOWN;
 211        info->sector_count = 0;
 212        info->size = 0;
 213
 214        /* Test for Boot Flash */
 215        if (base == FLASH_BASE0_PRELIM) {
 216                unsigned char value;
 217                volatile unsigned char *addr2 = (unsigned char *) addr;
 218
 219                /* Write auto select command: read Manufacturer ID */
 220                *(addr2 + 0x555) = 0xaa;
 221                *(addr2 + 0x2aa) = 0x55;
 222                *(addr2 + 0x555) = 0x90;
 223
 224                /* Manufacture ID */
 225                value = *addr2;
 226                switch (value) {
 227                case (unsigned char) AMD_MANUFACT:
 228                        info->flash_id = FLASH_MAN_AMD;
 229                        break;
 230                case (unsigned char) STM_MANUFACT:
 231                        info->flash_id = FLASH_MAN_STM;
 232                        break;
 233                default:
 234                        *addr2 = 0xf0;  /* no or unknown flash  */
 235                        return 0;
 236                }
 237
 238                /* Device ID */
 239                value = *(addr2 + 1);
 240                switch (value) {
 241                case (unsigned char) AMD_ID_LV040B:
 242                case (unsigned char) STM_ID_29W040B:
 243                        info->flash_id += FLASH_AM040;
 244                        info->sector_count = 8;
 245                        info->size = 0x00080000;
 246                        break;  /* => 512Kb */
 247                default:
 248                        *addr2 = 0xf0;  /* => no or unknown flash */
 249                        return 0;
 250                }
 251        } else {                /* MAIN Flash */
 252                unsigned long value;
 253                volatile unsigned long *addr2 = (unsigned long *) addr;
 254
 255                /* Write auto select command: read Manufacturer ID */
 256                *addr2 = 0x90909090;
 257
 258                /* Manufacture ID */
 259                value = *addr2;
 260                switch (value) {
 261                case (unsigned long) INTEL_MANUFACT:
 262                        info->flash_id = FLASH_MAN_INTEL;
 263                        break;
 264                default:
 265                        *addr2 = 0xff;  /* no or unknown flash  */
 266                        return 0;
 267                }
 268
 269                /* Device ID - This shit is interleaved... */
 270                value = *(addr2 + 1);
 271                switch (value) {
 272                case (unsigned long) INTEL_ID_28F320J3A:
 273                        info->flash_id += FLASH_28F320J3A;
 274                        info->sector_count = 32;
 275                        info->size = 0x00400000 * 2;
 276                        break;  /* => 2 X 4 MB */
 277                case (unsigned long) INTEL_ID_28F640J3A:
 278                        info->flash_id += FLASH_28F640J3A;
 279                        info->sector_count = 64;
 280                        info->size = 0x00800000 * 2;
 281                        break;  /* => 2 X 8 MB */
 282                case (unsigned long) INTEL_ID_28F128J3A:
 283                        info->flash_id += FLASH_28F128J3A;
 284                        info->sector_count = 128;
 285                        info->size = 0x01000000 * 2;
 286                        break;  /* => 2 X 16 MB */
 287                default:
 288                        *addr2 = 0xff;  /* => no or unknown flash */
 289                }
 290        }
 291
 292        /* Make sure we don't exceed CONFIG_SYS_MAX_FLASH_SECT */
 293        if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) {
 294                printf("** ERROR: sector count %d > max (%d) **\n",
 295                       info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
 296                info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
 297        }
 298
 299        /* set up sector start address table */
 300        switch (info->flash_id & FLASH_TYPEMASK) {
 301        case FLASH_AM040:
 302                for (i = 0; i < info->sector_count; i++)
 303                        info->start[i] = base + (i * 0x00010000);
 304                break;
 305        case FLASH_28F320J3A:
 306        case FLASH_28F640J3A:
 307        case FLASH_28F128J3A:
 308                for (i = 0; i < info->sector_count; i++)
 309                        info->start[i] = base +
 310                                        (i * 0x00020000 * 2);   /* 2 Banks */
 311                break;
 312        }
 313
 314        /* Test for Boot Flash */
 315        if (base == FLASH_BASE0_PRELIM) {
 316                volatile unsigned char *addr2;
 317
 318                /* check for protected sectors */
 319                for (i = 0; i < info->sector_count; i++) {
 320                        /*
 321                         * read sector protection at sector address,
 322                         * (AX .. A0) = 0x02
 323                         * D0 = 1 if protected
 324                         */
 325                        addr2 = (volatile unsigned char *) (info->start[i]);
 326                        info->protect[i] = *(addr2 + 2) & 1;
 327                }
 328
 329                /* Restore read mode */
 330                *(unsigned char *) base = 0xF0; /* Reset NORMAL Flash */
 331        } else {                /* Main Flash */
 332                volatile unsigned long *addr2;
 333
 334                /* check for protected sectors */
 335                for (i = 0; i < info->sector_count; i++) {
 336                        /*
 337                         * read sector protection at sector address,
 338                         * (AX .. A0) = 0x02
 339                         * D0 = 1 if protected
 340                         */
 341                        addr2 = (volatile unsigned long *) (info->start[i]);
 342                        info->protect[i] = *(addr2 + 2) & 0x1;
 343                }
 344
 345                /* Restore read mode */
 346                *(unsigned long *) base = 0xFFFFFFFF;   /* Reset  Flash */
 347        }
 348
 349        return info->size;
 350}                               /* end flash_get_size() */
 351
 352static int wait_for_DQ7(ulong addr, uchar cmp_val, ulong tout)
 353{
 354        int i;
 355
 356        volatile uchar *vaddr = (uchar *) addr;
 357
 358        /* Loop X times */
 359        for (i = 1; i <= (100 * tout); i++) {   /* Wait up to tout ms */
 360                udelay(10);
 361                /* Pause 10 us */
 362
 363                /* Check for completion */
 364                if ((vaddr[0] & 0x80) == (cmp_val & 0x80))
 365                        return 0;
 366
 367                /* KEEP THE LUSER HAPPY - Print a dot every 1.1 seconds */
 368                if (!(i % 110000))
 369                        putc('.');
 370
 371                /* Kick the dog if needed */
 372                WATCHDOG_RESET();
 373        }
 374
 375        return 1;
 376}                               /* wait_for_DQ7() */
 377
 378static int flash_erase8(flash_info_t *info, int s_first, int s_last)
 379{
 380        int tcode, rcode = 0;
 381        volatile uchar *addr = (uchar *) (info->start[0]);
 382        volatile uchar *sector_addr;
 383        int flag, prot, sect;
 384
 385        /* Validate arguments */
 386        if ((s_first < 0) || (s_first > s_last)) {
 387                if (info->flash_id == FLASH_UNKNOWN)
 388                        printf("- missing\n");
 389                else
 390                        printf("- no sectors to erase\n");
 391                return 1;
 392        }
 393
 394        /* Check for KNOWN flash type */
 395        if (info->flash_id == FLASH_UNKNOWN) {
 396                printf("Can't erase unknown flash type - aborted\n");
 397                return 1;
 398        }
 399
 400        /* Check for protected sectors */
 401        prot = 0;
 402        for (sect = s_first; sect <= s_last; ++sect) {
 403                if (info->protect[sect])
 404                        prot++;
 405        }
 406        if (prot) {
 407                printf("- Warning: %d protected sectors will not be erased!\n",
 408                        prot);
 409        } else {
 410                printf("\n");
 411        }
 412
 413        /* Start erase on unprotected sectors */
 414        for (sect = s_first; sect <= s_last; sect++) {
 415                if (info->protect[sect] == 0) { /* not protected */
 416                        sector_addr = (uchar *) (info->start[sect]);
 417
 418                        if ((info->flash_id & FLASH_VENDMASK) ==
 419                            FLASH_MAN_STM)
 420                                printf("Erasing block %p\n", sector_addr);
 421                        else
 422                                printf("Erasing sector %p\n", sector_addr);
 423
 424                        /* Disable interrupts which might cause timeout */
 425                        flag = disable_interrupts();
 426
 427                        *(addr + 0x555) = (uchar) 0xAA;
 428                        *(addr + 0x2aa) = (uchar) 0x55;
 429                        *(addr + 0x555) = (uchar) 0x80;
 430                        *(addr + 0x555) = (uchar) 0xAA;
 431                        *(addr + 0x2aa) = (uchar) 0x55;
 432                        *sector_addr = (uchar) 0x30;    /* sector erase */
 433
 434                        /*
 435                         * Wait for each sector to complete, it's more
 436                         * reliable.  According to AMD Spec, you must
 437                         * issue all erase commands within a specified
 438                         * timeout.  This has been seen to fail, especially
 439                         * if printf()s are included (for debug)!!
 440                         * Takes up to 6 seconds.
 441                         */
 442                        tcode = wait_for_DQ7((ulong) sector_addr, 0x80, 6000);
 443
 444                        /* re-enable interrupts if necessary */
 445                        if (flag)
 446                                enable_interrupts();
 447
 448                        /* Make sure we didn't timeout */
 449                        if (tcode) {
 450                                printf("Timeout\n");
 451                                rcode = 1;
 452                        }
 453                }
 454        }
 455
 456        /* wait at least 80us - let's wait 1 ms */
 457        udelay(1000);
 458
 459        /* reset to read mode */
 460        addr = (uchar *) info->start[0];
 461        *addr = (uchar) 0xF0;   /* reset bank */
 462
 463        printf(" done\n");
 464        return rcode;
 465}                               /* end flash_erase8() */
 466
 467static int flash_erase32(flash_info_t *info, int s_first, int s_last)
 468{
 469        int flag, sect;
 470        ulong start, now, last;
 471        int prot = 0;
 472
 473        /* Validate arguments */
 474        if ((s_first < 0) || (s_first > s_last)) {
 475                if (info->flash_id == FLASH_UNKNOWN)
 476                        printf("- missing\n");
 477                else
 478                        printf("- no sectors to erase\n");
 479                return 1;
 480        }
 481
 482        /* Check for KNOWN flash type */
 483        if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
 484                printf("Can erase only Intel flash types - aborted\n");
 485                return 1;
 486        }
 487
 488        /* Check for protected sectors */
 489        for (sect = s_first; sect <= s_last; ++sect) {
 490                if (info->protect[sect])
 491                        prot++;
 492        }
 493        if (prot) {
 494                printf("- Warning: %d protected sectors will not be erased!\n",
 495                        prot);
 496        } else {
 497                printf("\n");
 498        }
 499
 500        start = get_timer(0);
 501        last = start;
 502        /* Start erase on unprotected sectors */
 503        for (sect = s_first; sect <= s_last; sect++) {
 504                WATCHDOG_RESET();
 505                if (info->protect[sect] == 0) { /* not protected */
 506                        vu_long *addr = (vu_long *) (info->start[sect]);
 507                        unsigned long status;
 508
 509                        /* Disable interrupts which might cause a timeout */
 510                        flag = disable_interrupts();
 511
 512                        *addr = 0x00500050;     /* clear status register */
 513                        *addr = 0x00200020;     /* erase setup */
 514                        *addr = 0x00D000D0;     /* erase confirm */
 515
 516                        /* re-enable interrupts if necessary */
 517                        if (flag)
 518                                enable_interrupts();
 519
 520                        /* Wait at least 80us - let's wait 1 ms */
 521                        udelay(1000);
 522
 523                        while (((status = *addr) & 0x00800080) != 0x00800080) {
 524                                now = get_timer(start);
 525                                if (now > CONFIG_SYS_FLASH_ERASE_TOUT) {
 526                                        printf("Timeout\n");
 527                                        /* suspend erase      */
 528                                        *addr = 0x00B000B0;
 529                                        /* reset to read mode */
 530                                        *addr = 0x00FF00FF;
 531                                        return 1;
 532                                }
 533
 534                                /*
 535                                 * show that we're waiting
 536                                 * every second (?)
 537                                 */
 538                                if ((now - last) > 990) {
 539                                        putc('.');
 540                                        last = now;
 541                                }
 542                        }
 543                        *addr = 0x00FF00FF;     /* reset to read mode */
 544                }
 545        }
 546        printf(" done\n");
 547        return 0;
 548}
 549
 550int flash_erase(flash_info_t *info, int s_first, int s_last)
 551{
 552        if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040)
 553                return flash_erase8(info, s_first, s_last);
 554        else
 555                return flash_erase32(info, s_first, s_last);
 556}
 557
 558/*
 559 * Copy memory to flash, returns:
 560 * 0 - OK
 561 * 1 - write timeout
 562 * 2 - Flash not erased
 563 */
 564static int write_buff8(flash_info_t *info, uchar *src, ulong addr,
 565                       ulong cnt)
 566{
 567        ulong cp, wp, data;
 568        ulong start;
 569        int i, l, rc;
 570
 571        start = get_timer(0);
 572
 573        wp = (addr & ~3);       /* get lower word
 574                                   aligned address */
 575
 576        /*
 577         * handle unaligned start bytes
 578         */
 579        l = addr - wp;
 580        if (l != 0) {
 581                data = 0;
 582                for (i = 0, cp = wp; i < l; ++i, ++cp)
 583                        data = (data << 8) | (*(uchar *) cp);
 584
 585                for (; i < 4 && cnt > 0; ++i) {
 586                        data = (data << 8) | *src++;
 587                        --cnt;
 588                        ++cp;
 589                }
 590
 591                for (; cnt == 0 && i < 4; ++i, ++cp)
 592                        data = (data << 8) | (*(uchar *) cp);
 593
 594                rc = write_word8(info, wp, data);
 595                if (rc != 0)
 596                        return rc;
 597
 598                wp += 4;
 599        }
 600
 601        /*
 602         * handle word aligned part
 603         */
 604        while (cnt >= 4) {
 605                data = 0;
 606                for (i = 0; i < 4; ++i)
 607                        data = (data << 8) | *src++;
 608
 609                rc = write_word8(info, wp, data);
 610                if (rc != 0)
 611                        return rc;
 612
 613                wp += 4;
 614                cnt -= 4;
 615                if (get_timer(start) > 1000) {  /* every second */
 616                        WATCHDOG_RESET();
 617                        putc('.');
 618                        start = get_timer(0);
 619                }
 620        }
 621
 622        if (cnt == 0)
 623                return 0;
 624
 625        /*
 626         * handle unaligned tail bytes
 627         */
 628        data = 0;
 629        for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
 630                data = (data << 8) | *src++;
 631                --cnt;
 632        }
 633
 634        for (; i < 4; ++i, ++cp)
 635                data = (data << 8) | (*(uchar *) cp);
 636
 637        return write_word8(info, wp, data);
 638}
 639
 640#define FLASH_WIDTH     4       /* flash bus width in bytes */
 641static int write_buff32(flash_info_t *info, uchar *src, ulong addr,
 642                        ulong cnt)
 643{
 644        ulong cp, wp, data;
 645        int i, l, rc;
 646        ulong start;
 647
 648        start = get_timer(0);
 649
 650        if (info->flash_id == FLASH_UNKNOWN)
 651                return 4;
 652
 653        /* get lower FLASH_WIDTH aligned address */
 654        wp = (addr & ~(FLASH_WIDTH - 1));
 655
 656        /*
 657         * handle unaligned start bytes
 658         */
 659        if ((l = addr - wp) != 0) {
 660                data = 0;
 661                for (i = 0, cp = wp; i < l; ++i, ++cp)
 662                        data = (data << 8) | (*(uchar *) cp);
 663
 664                for (; i < FLASH_WIDTH && cnt > 0; ++i) {
 665                        data = (data << 8) | *src++;
 666                        --cnt;
 667                        ++cp;
 668                }
 669
 670                for (; cnt == 0 && i < FLASH_WIDTH; ++i, ++cp)
 671                        data = (data << 8) | (*(uchar *) cp);
 672
 673                rc = write_word32(info, wp, data);
 674                if (rc != 0)
 675                        return rc;
 676
 677                wp += FLASH_WIDTH;
 678        }
 679
 680        /*
 681         * handle FLASH_WIDTH aligned part
 682         */
 683        while (cnt >= FLASH_WIDTH) {
 684                data = 0;
 685                for (i = 0; i < FLASH_WIDTH; ++i)
 686                        data = (data << 8) | *src++;
 687
 688                rc = write_word32(info, wp, data);
 689                if (rc != 0)
 690                        return rc;
 691
 692                wp += FLASH_WIDTH;
 693                cnt -= FLASH_WIDTH;
 694                if (get_timer(start) > 990) {   /* every second */
 695                        putc('.');
 696                        start = get_timer(0);
 697                }
 698        }
 699
 700        if (cnt == 0)
 701                return 0;
 702
 703        /*
 704         * handle unaligned tail bytes
 705         */
 706        data = 0;
 707        for (i = 0, cp = wp; i < FLASH_WIDTH && cnt > 0; ++i, ++cp) {
 708                data = (data << 8) | *src++;
 709                --cnt;
 710        }
 711
 712        for (; i < FLASH_WIDTH; ++i, ++cp)
 713                data = (data << 8) | (*(uchar *) cp);
 714
 715        return write_word32(info, wp, data);
 716}
 717
 718int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
 719{
 720        int retval;
 721
 722        if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040)
 723                retval = write_buff8(info, src, addr, cnt);
 724        else
 725                retval = write_buff32(info, src, addr, cnt);
 726
 727        return retval;
 728}
 729
 730/*
 731 * Write a word to Flash, returns:
 732 * 0 - OK
 733 * 1 - write timeout
 734 * 2 - Flash not erased
 735 */
 736
 737static int write_word8(flash_info_t *info, ulong dest, ulong data)
 738{
 739        volatile uchar *addr2 = (uchar *) (info->start[0]);
 740        volatile uchar *dest2 = (uchar *) dest;
 741        volatile uchar *data2 = (uchar *) &data;
 742        int flag;
 743        int i, tcode, rcode = 0;
 744
 745        /* Check if Flash is (sufficently) erased */
 746        if ((*((volatile uchar *)dest) & (uchar)data) != (uchar)data)
 747                return 2;
 748
 749        for (i = 0; i < (4 / sizeof(uchar)); i++) {
 750                /* Disable interrupts which might cause a timeout here */
 751                flag = disable_interrupts();
 752
 753                *(addr2 + 0x555) = (uchar) 0xAA;
 754                *(addr2 + 0x2aa) = (uchar) 0x55;
 755                *(addr2 + 0x555) = (uchar) 0xA0;
 756
 757                dest2[i] = data2[i];
 758
 759                /* Wait for write to complete, up to 1ms */
 760                tcode = wait_for_DQ7((ulong) &dest2[i], data2[i], 1);
 761
 762                /* re-enable interrupts if necessary */
 763                if (flag)
 764                        enable_interrupts();
 765
 766                /* Make sure we didn't timeout */
 767                if (tcode)
 768                        rcode = 1;
 769        }
 770
 771        return rcode;
 772}
 773
 774static int write_word32(flash_info_t *info, ulong dest, ulong data)
 775{
 776        vu_long *addr = (vu_long *) dest;
 777        ulong status;
 778        ulong start;
 779        int flag;
 780
 781        /* Check if Flash is (sufficiently) erased */
 782        if ((*addr & data) != data)
 783                return 2;
 784
 785        /* Disable interrupts which might cause a timeout here */
 786        flag = disable_interrupts();
 787
 788        *addr = 0x00400040;     /* write setup */
 789        *addr = data;
 790
 791        /* re-enable interrupts if necessary */
 792        if (flag)
 793                enable_interrupts();
 794
 795        start = get_timer(0);
 796
 797        while (((status = *addr) & 0x00800080) != 0x00800080) {
 798                WATCHDOG_RESET();
 799                if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 800                        *addr = 0x00FF00FF;     /* restore read mode */
 801                        return 1;
 802                }
 803        }
 804
 805        *addr = 0x00FF00FF;     /* restore read mode */
 806
 807        return 0;
 808}
 809
 810static int _flash_protect(flash_info_t *info, long sector)
 811{
 812        int i;
 813        int flag;
 814        ulong status;
 815        int rcode = 0;
 816        volatile long *addr = (long *)sector;
 817
 818        switch (info->flash_id & FLASH_TYPEMASK) {
 819        case FLASH_28F320J3A:
 820        case FLASH_28F640J3A:
 821        case FLASH_28F128J3A:
 822                /* Disable interrupts which might cause Flash to timeout */
 823                flag = disable_interrupts();
 824
 825                /* Issue command */
 826                *addr = 0x00500050L;    /* Clear the status register */
 827                *addr = 0x00600060L;    /* Set lock bit setup */
 828                *addr = 0x00010001L;    /* Set lock bit confirm */
 829
 830                /* Wait for command completion */
 831                for (i = 0; i < 10; i++) {      /* 75us timeout, wait 100us */
 832                        udelay(10);
 833                        if ((*addr & 0x00800080L) == 0x00800080L)
 834                                break;
 835                }
 836
 837                /* Not successful? */
 838                status = *addr;
 839                if (status != 0x00800080L) {
 840                        printf("Protect %x sector failed: %x\n",
 841                               (uint) sector, (uint) status);
 842                        rcode = 1;
 843                }
 844
 845                /* Restore read mode */
 846                *addr = 0x00ff00ffL;
 847
 848                /* re-enable interrupts if necessary */
 849                if (flag)
 850                        enable_interrupts();
 851
 852                break;
 853        case FLASH_AM040:       /* No soft sector protection */
 854                break;
 855        }
 856
 857        /* Turn protection on for this sector */
 858        for (i = 0; i < info->sector_count; i++) {
 859                if (info->start[i] == sector) {
 860                        info->protect[i] = 1;
 861                        break;
 862                }
 863        }
 864
 865        return rcode;
 866}
 867
 868static int _flash_unprotect(flash_info_t *info, long sector)
 869{
 870        int i;
 871        int flag;
 872        ulong status;
 873        int rcode = 0;
 874        volatile long *addr = (long *) sector;
 875
 876        switch (info->flash_id & FLASH_TYPEMASK) {
 877        case FLASH_28F320J3A:
 878        case FLASH_28F640J3A:
 879        case FLASH_28F128J3A:
 880                /* Disable interrupts which might cause Flash to timeout */
 881                flag = disable_interrupts();
 882
 883                *addr = 0x00500050L;    /* Clear the status register */
 884                *addr = 0x00600060L;    /* Clear lock bit setup */
 885                *addr = 0x00D000D0L;    /* Clear lock bit confirm */
 886
 887                /* Wait for command completion */
 888                for (i = 0; i < 80; i++) {      /* 700ms timeout, wait 800 */
 889                        udelay(10000);  /* Delay 10ms */
 890                        if ((*addr & 0x00800080L) == 0x00800080L)
 891                                break;
 892                }
 893
 894                /* Not successful? */
 895                status = *addr;
 896                if (status != 0x00800080L) {
 897                        printf("Un-protect %x sector failed: %x\n",
 898                               (uint) sector, (uint) status);
 899                        *addr = 0x00ff00ffL;
 900                        rcode = 1;
 901                }
 902
 903                /* restore read mode */
 904                *addr = 0x00ff00ffL;
 905
 906                /* re-enable interrupts if necessary */
 907                if (flag)
 908                        enable_interrupts();
 909
 910                break;
 911        case FLASH_AM040:       /* No soft sector protection */
 912                break;
 913        }
 914
 915        /*
 916         * Fix Intel's little red wagon.  Reprotect
 917         * sectors that were protected before we undid
 918         * protection on a specific sector.
 919         */
 920        for (i = 0; i < info->sector_count; i++) {
 921                if (info->start[i] != sector) {
 922                        if (info->protect[i]) {
 923                                if (_flash_protect(info, info->start[i]))
 924                                        rcode = 1;
 925                        }
 926                } else          /* Turn protection off for this sector */
 927                        info->protect[i] = 0;
 928        }
 929
 930        return rcode;
 931}
 932
 933int flash_real_protect(flash_info_t *info, long sector, int prot)
 934{
 935        int rcode;
 936
 937        if (prot)
 938                rcode = _flash_protect(info, info->start[sector]);
 939        else
 940                rcode = _flash_unprotect(info, info->start[sector]);
 941
 942        return rcode;
 943}
 944