uboot/board/lwmon/flash.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2001
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24/* #define DEBUG */
  25
  26#include <common.h>
  27#include <mpc8xx.h>
  28
  29#if defined(CONFIG_ENV_IS_IN_FLASH)
  30# ifndef  CONFIG_ENV_ADDR
  31#  define CONFIG_ENV_ADDR       (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
  32# endif
  33# ifndef  CONFIG_ENV_SIZE
  34#  define CONFIG_ENV_SIZE       CONFIG_ENV_SECT_SIZE
  35# endif
  36# ifndef  CONFIG_ENV_SECT_SIZE
  37#  define CONFIG_ENV_SECT_SIZE  CONFIG_ENV_SIZE
  38# endif
  39#endif
  40
  41/*---------------------------------------------------------------------*/
  42
  43flash_info_t    flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
  44
  45/*-----------------------------------------------------------------------
  46 * Functions
  47 */
  48static ulong flash_get_size (vu_long *addr, flash_info_t *info);
  49static int write_data (flash_info_t *info, ulong dest, ulong data);
  50#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
  51static int write_data_buf (flash_info_t * info, ulong dest, uchar * cp, int len);
  52#endif
  53static void flash_get_offsets (ulong base, flash_info_t *info);
  54
  55/*-----------------------------------------------------------------------
  56 */
  57
  58unsigned long flash_init (void)
  59{
  60        volatile immap_t     *immap  = (immap_t *)CONFIG_SYS_IMMR;
  61        volatile memctl8xx_t *memctl = &immap->im_memctl;
  62        unsigned long size_b0, size_b1;
  63        int i;
  64
  65        /* Init: no FLASHes known */
  66        for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
  67                flash_info[i].flash_id = FLASH_UNKNOWN;
  68        }
  69
  70        /* Static FLASH Bank configuration here - FIXME XXX */
  71
  72        debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_PRELIM);
  73
  74        size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
  75
  76        if (flash_info[0].flash_id == FLASH_UNKNOWN) {
  77                printf ("## Unknown FLASH on Bank 0: "
  78                        "ID 0x%lx, Size = 0x%08lx = %ld MB\n",
  79                        flash_info[0].flash_id,
  80                        size_b0, size_b0<<20);
  81        }
  82
  83        debug ("## Get flash bank 2 size @ 0x%08x\n",FLASH_BASE1_PRELIM);
  84
  85        size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
  86
  87        debug ("## Prelim. Flash bank sizes: %08lx + 0x%08lx\n",size_b0,size_b1);
  88
  89        if (size_b1 > size_b0) {
  90                printf ("## ERROR: "
  91                        "Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
  92                        size_b1, size_b1<<20,
  93                        size_b0, size_b0<<20
  94                );
  95                flash_info[0].flash_id  = FLASH_UNKNOWN;
  96                flash_info[1].flash_id  = FLASH_UNKNOWN;
  97                flash_info[0].sector_count      = -1;
  98                flash_info[1].sector_count      = -1;
  99                flash_info[0].size              = 0;
 100                flash_info[1].size              = 0;
 101                return (0);
 102        }
 103
 104        debug  ("## Before remap: "
 105                "BR0: 0x%08x    OR0: 0x%08x    "
 106                "BR1: 0x%08x    OR1: 0x%08x\n",
 107                memctl->memc_br0, memctl->memc_or0,
 108                memctl->memc_br1, memctl->memc_or1);
 109
 110        /* Remap FLASH according to real size */
 111        memctl->memc_or0 = (-size_b0 & 0xFFFF8000) | CONFIG_SYS_OR_TIMING_FLASH |
 112                                OR_CSNT_SAM | OR_ACS_DIV1;
 113        memctl->memc_br0 = (CONFIG_SYS_FLASH_BASE & BR_BA_MSK) | BR_PS_32 | BR_V;
 114
 115        debug ("## BR0: 0x%08x    OR0: 0x%08x\n",
 116                memctl->memc_br0, memctl->memc_or0);
 117
 118        /* Re-do sizing to get full correct info */
 119        size_b0 = flash_get_size((vu_long *)CONFIG_SYS_FLASH_BASE, &flash_info[0]);
 120
 121        flash_get_offsets (CONFIG_SYS_FLASH_BASE, &flash_info[0]);
 122
 123        flash_info[0].size = size_b0;
 124
 125#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
 126        /* monitor protection ON by default */
 127        flash_protect(FLAG_PROTECT_SET,
 128                      CONFIG_SYS_MONITOR_BASE,
 129                      CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1,
 130                      &flash_info[0]);
 131#endif
 132
 133#ifdef  CONFIG_ENV_IS_IN_FLASH
 134        /* ENV protection ON by default */
 135        flash_protect(FLAG_PROTECT_SET,
 136                      CONFIG_ENV_ADDR,
 137                      CONFIG_ENV_ADDR+CONFIG_ENV_SECT_SIZE-1,
 138                      &flash_info[0]);
 139#endif
 140
 141        if (size_b1) {
 142                memctl->memc_or1 = (-size_b1 & 0xFFFF8000) | CONFIG_SYS_OR_TIMING_FLASH |
 143                                        OR_CSNT_SAM | OR_ACS_DIV1;
 144                memctl->memc_br1 = ((CONFIG_SYS_FLASH_BASE + size_b0) & BR_BA_MSK) |
 145                                        BR_PS_32 | BR_V;
 146
 147                debug ("## BR1: 0x%08x    OR1: 0x%08x\n",
 148                        memctl->memc_br1, memctl->memc_or1);
 149
 150                /* Re-do sizing to get full correct info */
 151                size_b1 = flash_get_size((vu_long *)(CONFIG_SYS_FLASH_BASE + size_b0),
 152                                          &flash_info[1]);
 153
 154                flash_info[1].size = size_b1;
 155
 156                flash_get_offsets (CONFIG_SYS_FLASH_BASE + size_b0, &flash_info[1]);
 157
 158#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
 159                /* monitor protection ON by default */
 160                flash_protect(FLAG_PROTECT_SET,
 161                              CONFIG_SYS_MONITOR_BASE,
 162                              CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1,
 163                              &flash_info[1]);
 164#endif
 165
 166#ifdef  CONFIG_ENV_IS_IN_FLASH
 167                /* ENV protection ON by default */
 168                flash_protect(FLAG_PROTECT_SET,
 169                              CONFIG_ENV_ADDR,
 170                              CONFIG_ENV_ADDR+CONFIG_ENV_SECT_SIZE-1,
 171                              &flash_info[1]);
 172#endif
 173        } else {
 174                memctl->memc_br1 = 0;           /* invalidate bank */
 175                memctl->memc_or1 = 0;           /* invalidate bank */
 176
 177                debug ("## DISABLE BR1: 0x%08x    OR1: 0x%08x\n",
 178                        memctl->memc_br1, memctl->memc_or1);
 179
 180                flash_info[1].flash_id = FLASH_UNKNOWN;
 181                flash_info[1].sector_count = -1;
 182                flash_info[1].size = 0;
 183        }
 184
 185        debug ("## Final Flash bank sizes: %08lx + 0x%08lx\n",size_b0,size_b1);
 186
 187        return (size_b0 + size_b1);
 188}
 189
 190/*-----------------------------------------------------------------------
 191 */
 192static void flash_get_offsets (ulong base, flash_info_t *info)
 193{
 194        int i;
 195
 196        if (info->flash_id == FLASH_UNKNOWN) {
 197                return;
 198        }
 199
 200        switch (info->flash_id & FLASH_VENDMASK) {
 201        case FLASH_MAN_INTEL:
 202            for (i = 0; i < info->sector_count; i++) {
 203                info->start[i] = base;
 204                base += 0x00020000 * 2;         /* 128k * 2 chips per bank */
 205            }
 206            return;
 207
 208        default:
 209            printf ("Don't know sector ofsets for flash type 0x%lx\n",
 210                info->flash_id);
 211            return;
 212        }
 213}
 214
 215/*-----------------------------------------------------------------------
 216 */
 217void flash_print_info  (flash_info_t *info)
 218{
 219        int i;
 220
 221        if (info->flash_id == FLASH_UNKNOWN) {
 222                printf ("missing or unknown FLASH type\n");
 223                return;
 224        }
 225
 226        switch (info->flash_id & FLASH_VENDMASK) {
 227        case FLASH_MAN_AMD:     printf ("AMD ");                break;
 228        case FLASH_MAN_FUJ:     printf ("Fujitsu ");            break;
 229        case FLASH_MAN_SST:     printf ("SST ");                break;
 230        case FLASH_MAN_STM:     printf ("STM ");                break;
 231        case FLASH_MAN_INTEL:   printf ("Intel ");              break;
 232        case FLASH_MAN_MT:      printf ("MT ");                 break;
 233        default:                printf ("Unknown Vendor ");     break;
 234        }
 235
 236        switch (info->flash_id & FLASH_TYPEMASK) {
 237        case FLASH_28F320J3A:   printf ("28F320J3A (32Mbit = 128K x 32)\n");
 238                                break;
 239        case FLASH_28F640J3A:   printf ("28F640J3A (64Mbit = 128K x 64)\n");
 240                                break;
 241        case FLASH_28F128J3A:   printf ("28F128J3A (128Mbit = 128K x 128)\n");
 242                                break;
 243        default:                printf ("Unknown Chip Type\n");
 244                                break;
 245        }
 246
 247        if (info->size >= (1 << 20)) {
 248                i = 20;
 249        } else {
 250                i = 10;
 251        }
 252        printf ("  Size: %ld %cB in %d Sectors\n",
 253                info->size >> i,
 254                (i == 20) ? 'M' : 'k',
 255                info->sector_count);
 256
 257        printf ("  Sector Start Addresses:");
 258        for (i=0; i<info->sector_count; ++i) {
 259                if ((i % 5) == 0)
 260                        printf ("\n   ");
 261                printf (" %08lX%s",
 262                        info->start[i],
 263                        info->protect[i] ? " (RO)" : "     "
 264                );
 265        }
 266        printf ("\n");
 267        return;
 268}
 269
 270/*-----------------------------------------------------------------------
 271 */
 272
 273
 274/*-----------------------------------------------------------------------
 275 */
 276
 277/*
 278 * The following code cannot be run from FLASH!
 279 */
 280
 281static ulong flash_get_size (vu_long *addr, flash_info_t *info)
 282{
 283        ulong value;
 284
 285        /* Read Manufacturer ID */
 286        addr[0] = 0x00900090;
 287        value = addr[0];
 288
 289        debug ("Manuf. ID @ 0x%08lx: 0x%08lx\n", (ulong)addr, value);
 290
 291        switch (value) {
 292        case AMD_MANUFACT:
 293                info->flash_id = FLASH_MAN_AMD;
 294                break;
 295        case FUJ_MANUFACT:
 296                info->flash_id = FLASH_MAN_FUJ;
 297                break;
 298        case SST_MANUFACT:
 299                info->flash_id = FLASH_MAN_SST;
 300                break;
 301        case STM_MANUFACT:
 302                info->flash_id = FLASH_MAN_STM;
 303                break;
 304        case INTEL_MANUFACT:
 305                info->flash_id = FLASH_MAN_INTEL;
 306                break;
 307        default:
 308                info->flash_id = FLASH_UNKNOWN;
 309                info->sector_count = 0;
 310                info->size = 0;
 311                addr[0] = 0x00FF00FF;           /* restore read mode */
 312                return (0);                     /* no or unknown flash  */
 313        }
 314
 315        value = addr[1];                        /* device ID            */
 316
 317        debug ("Device ID @ 0x%08lx: 0x%08lx\n", (ulong)(&addr[1]), value);
 318
 319        switch (value) {
 320        case INTEL_ID_28F320J3A:
 321                info->flash_id += FLASH_28F320J3A;
 322                info->sector_count = 32;
 323                info->size = 0x00400000 * 2;
 324                break;                          /* =>  8 MB             */
 325
 326        case INTEL_ID_28F640J3A:
 327                info->flash_id += FLASH_28F640J3A;
 328                info->sector_count = 64;
 329                info->size = 0x00800000 * 2;
 330                break;                          /* => 16 MB             */
 331
 332        case INTEL_ID_28F128J3A:
 333                info->flash_id += FLASH_28F128J3A;
 334                info->sector_count = 128;
 335                info->size = 0x01000000 * 2;
 336                break;                          /* => 32 MB             */
 337
 338        default:
 339                info->flash_id = FLASH_UNKNOWN;
 340                addr[0] = 0x00FF00FF;           /* restore read mode */
 341                return (0);                     /* => no or unknown flash */
 342
 343        }
 344
 345        if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) {
 346                printf ("** ERROR: sector count %d > max (%d) **\n",
 347                        info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
 348                info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
 349        }
 350
 351        addr[0] = 0x00FF00FF;           /* restore read mode */
 352
 353        return (info->size);
 354}
 355
 356
 357/*-----------------------------------------------------------------------
 358 */
 359
 360int     flash_erase (flash_info_t *info, int s_first, int s_last)
 361{
 362        int flag, prot, sect;
 363        ulong start, now, last;
 364
 365        debug ("flash_erase: first: %d last: %d\n", s_first, s_last);
 366
 367        if ((s_first < 0) || (s_first > s_last)) {
 368                if (info->flash_id == FLASH_UNKNOWN) {
 369                        printf ("- missing\n");
 370                } else {
 371                        printf ("- no sectors to erase\n");
 372                }
 373                return 1;
 374        }
 375
 376        if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
 377                printf ("Can erase only Intel flash types - aborted\n");
 378                return 1;
 379        }
 380
 381        prot = 0;
 382        for (sect=s_first; sect<=s_last; ++sect) {
 383                if (info->protect[sect]) {
 384                        prot++;
 385                }
 386        }
 387
 388        if (prot) {
 389                printf ("- Warning: %d protected sectors will not be erased!\n",
 390                        prot);
 391        } else {
 392                printf ("\n");
 393        }
 394
 395        start = get_timer (0);
 396        last  = start;
 397        /* Start erase on unprotected sectors */
 398        for (sect = s_first; sect<=s_last; sect++) {
 399                if (info->protect[sect] == 0) { /* not protected */
 400                        vu_long *addr = (vu_long *)(info->start[sect]);
 401                        unsigned long status;
 402
 403                        /* Disable interrupts which might cause a timeout here */
 404                        flag = disable_interrupts();
 405
 406                        *addr = 0x00600060;     /* clear lock bit setup */
 407                        *addr = 0x00D000D0;     /* clear lock bit confirm */
 408
 409                        udelay (1000);
 410                        /* This takes awfully long - up to 50 ms and more */
 411                        while (((status = *addr) & 0x00800080) != 0x00800080) {
 412                                if ((now=get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 413                                        printf ("Timeout\n");
 414                                        *addr = 0x00FF00FF; /* reset to read mode */
 415                                        return 1;
 416                                }
 417
 418                                /* show that we're waiting */
 419                                if ((now - last) > 1000) {      /* every second */
 420                                        putc ('.');
 421                                        last = now;
 422                                }
 423                                udelay (1000);  /* to trigger the watchdog */
 424                        }
 425
 426                        *addr = 0x00500050;     /* clear status register */
 427                        *addr = 0x00200020;     /* erase setup */
 428                        *addr = 0x00D000D0;     /* erase confirm */
 429
 430                        /* re-enable interrupts if necessary */
 431                        if (flag)
 432                                enable_interrupts();
 433
 434                        /* wait at least 80us - let's wait 1 ms */
 435                        udelay (1000);
 436
 437                        while (((status = *addr) & 0x00800080) != 0x00800080) {
 438                                if ((now=get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 439                                        printf ("Timeout\n");
 440                                        *addr = 0x00B000B0; /* suspend erase      */
 441                                        *addr = 0x00FF00FF; /* reset to read mode */
 442                                        return 1;
 443                                }
 444
 445                                /* show that we're waiting */
 446                                if ((now - last) > 1000) {      /* every second */
 447                                        putc ('.');
 448                                        last = now;
 449                                }
 450                                udelay (1000);  /* to trigger the watchdog */
 451                        }
 452
 453                        *addr = 0x00FF00FF;     /* reset to read mode */
 454                }
 455        }
 456        printf (" done\n");
 457        return 0;
 458}
 459
 460/*-----------------------------------------------------------------------
 461 * Copy memory to flash, returns:
 462 * 0 - OK
 463 * 1 - write timeout
 464 * 2 - Flash not erased
 465 * 4 - Flash not identified
 466 */
 467
 468#define FLASH_WIDTH     4       /* flash bus width in bytes */
 469
 470int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
 471{
 472        ulong cp, wp, data;
 473        int i, l, rc;
 474
 475        if (info->flash_id == FLASH_UNKNOWN) {
 476                return 4;
 477        }
 478
 479        wp = (addr & ~(FLASH_WIDTH-1)); /* get lower FLASH_WIDTH aligned address */
 480
 481        /*
 482         * handle unaligned start bytes
 483         */
 484        if ((l = addr - wp) != 0) {
 485                data = 0;
 486                for (i=0, cp=wp; i<l; ++i, ++cp) {
 487                        data = (data << 8) | (*(uchar *)cp);
 488                }
 489                for (; i<FLASH_WIDTH && cnt>0; ++i) {
 490                        data = (data << 8) | *src++;
 491                        --cnt;
 492                        ++cp;
 493                }
 494                for (; cnt==0 && i<FLASH_WIDTH; ++i, ++cp) {
 495                        data = (data << 8) | (*(uchar *)cp);
 496                }
 497
 498                if ((rc = write_data(info, wp, data)) != 0) {
 499                        return (rc);
 500                }
 501                wp += FLASH_WIDTH;
 502        }
 503
 504        /*
 505         * handle FLASH_WIDTH aligned part
 506         */
 507#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
 508        while(cnt >= FLASH_WIDTH) {
 509                i = CONFIG_SYS_FLASH_BUFFER_SIZE > cnt ?
 510                    (cnt & ~(FLASH_WIDTH - 1)) : CONFIG_SYS_FLASH_BUFFER_SIZE;
 511                if((rc = write_data_buf(info, wp, src,i)) != 0)
 512                        return rc;
 513                wp += i;
 514                src += i;
 515                cnt -=i;
 516        }
 517#else
 518        while (cnt >= FLASH_WIDTH) {
 519                data = 0;
 520                for (i=0; i<FLASH_WIDTH; ++i) {
 521                        data = (data << 8) | *src++;
 522                }
 523                if ((rc = write_data(info, wp, data)) != 0) {
 524                        return (rc);
 525                }
 526                wp  += FLASH_WIDTH;
 527                cnt -= FLASH_WIDTH;
 528        }
 529#endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */
 530
 531        if (cnt == 0) {
 532                return (0);
 533        }
 534
 535        /*
 536         * handle unaligned tail bytes
 537         */
 538        data = 0;
 539        for (i=0, cp=wp; i<FLASH_WIDTH && cnt>0; ++i, ++cp) {
 540                data = (data << 8) | *src++;
 541                --cnt;
 542        }
 543        for (; i<FLASH_WIDTH; ++i, ++cp) {
 544                data = (data << 8) | (*(uchar *)cp);
 545        }
 546
 547        return (write_data(info, wp, data));
 548}
 549
 550/*-----------------------------------------------------------------------
 551 * Check flash status, returns:
 552 * 0 - OK
 553 * 1 - timeout
 554 */
 555static int flash_status_check(vu_long *addr, ulong tout, char * prompt)
 556{
 557        ulong status;
 558        ulong start;
 559
 560        /* Wait for command completion */
 561        start = get_timer (0);
 562        while(((status = *addr) & 0x00800080) != 0x00800080) {
 563                if (get_timer(start) > tout) {
 564                        printf("Flash %s timeout at address %p\n", prompt, addr);
 565                        *addr = 0x00FF00FF;     /* restore read mode */
 566                        return (1);
 567                }
 568        }
 569        return 0;
 570}
 571
 572/*-----------------------------------------------------------------------
 573 * Write a word to Flash, returns:
 574 * 0 - OK
 575 * 1 - write timeout
 576 * 2 - Flash not erased
 577 */
 578static int write_data (flash_info_t *info, ulong dest, ulong data)
 579{
 580        vu_long *addr = (vu_long *)dest;
 581        int flag;
 582
 583        /* Check if Flash is (sufficiently) erased */
 584        if ((*addr & data) != data) {
 585                return (2);
 586        }
 587        /* Disable interrupts which might cause a timeout here */
 588        flag = disable_interrupts();
 589
 590        *addr = 0x00400040;             /* write setup */
 591        *addr = data;
 592
 593        /* re-enable interrupts if necessary */
 594        if (flag)
 595                enable_interrupts();
 596
 597        if (flash_status_check(addr, CONFIG_SYS_FLASH_WRITE_TOUT, "write") != 0) {
 598                return (1);
 599        }
 600
 601        *addr = 0x00FF00FF;     /* restore read mode */
 602
 603        return (0);
 604}
 605
 606#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
 607/*-----------------------------------------------------------------------
 608 * Write a buffer to Flash, returns:
 609 * 0 - OK
 610 * 1 - write timeout
 611 */
 612static int write_data_buf(flash_info_t * info, ulong dest, uchar * cp, int len)
 613{
 614        vu_long *addr = (vu_long *)dest;
 615        int sector;
 616        int cnt;
 617        int retcode;
 618        vu_long * src = (vu_long *)cp;
 619        vu_long * dst = (vu_long *)dest;
 620
 621        /* find sector */
 622        for(sector = info->sector_count - 1; sector >= 0; sector--) {
 623                if(dest >= info->start[sector])
 624                        break;
 625        }
 626
 627        *addr = 0x00500050;             /* clear status */
 628        *addr = 0x00e800e8;             /* write buffer */
 629
 630        if((retcode = flash_status_check(addr, CONFIG_SYS_FLASH_BUFFER_WRITE_TOUT,
 631                                         "write to buffer")) == 0) {
 632                cnt = len / FLASH_WIDTH;
 633                *addr = (cnt-1) | ((cnt-1) << 16);
 634                while(cnt-- > 0) {
 635                        *dst++ = *src++;
 636                }
 637                *addr = 0x00d000d0;             /* write buffer confirm */
 638                retcode = flash_status_check(addr, CONFIG_SYS_FLASH_BUFFER_WRITE_TOUT,
 639                                                 "buffer write");
 640        }
 641        *addr = 0x00FF00FF;     /* restore read mode */
 642        *addr = 0x00500050;     /* clear status */
 643        return retcode;
 644}
 645#endif /* CONFIG_SYS_USE_FLASH_BUFFER_WRITE */
 646
 647/*-----------------------------------------------------------------------
 648 */
 649