uboot/board/alaska/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_WIDTH8
  35
  36typedef unsigned char FLASH_PORT_WIDTH;
  37typedef volatile unsigned char FLASH_PORT_WIDTHV;
  38
  39#define SWAP(x)         (x)
  40
  41/* Intel-compatible flash ID */
  42#define INTEL_COMPAT    0x89
  43#define INTEL_ALT       0xB0
  44
  45/* Intel-compatible flash commands */
  46#define INTEL_PROGRAM   0x10
  47#define INTEL_ERASE     0x20
  48#define INTEL_CLEAR     0x50
  49#define INTEL_LOCKBIT   0x60
  50#define INTEL_PROTECT   0x01
  51#define INTEL_STATUS    0x70
  52#define INTEL_READID    0x90
  53#define INTEL_CONFIRM   0xD0
  54#define INTEL_RESET     0xFF
  55
  56/* Intel-compatible flash status bits */
  57#define INTEL_FINISHED  0x80
  58#define INTEL_OK        0x80
  59
  60#define FPW             FLASH_PORT_WIDTH
  61#define FPWV            FLASH_PORT_WIDTHV
  62
  63#define FLASH_CYCLE1    0x0555
  64#define FLASH_CYCLE2    0x02aa
  65
  66#define WR_BLOCK        0x20
  67/*-----------------------------------------------------------------------
  68 * Functions
  69 */
  70static ulong flash_get_size (FPW * addr, flash_info_t * info);
  71static int write_data (flash_info_t * info, ulong dest, FPW data);
  72static int write_data_block (flash_info_t * info, ulong src, ulong dest);
  73static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data);
  74static void flash_get_offsets (ulong base, flash_info_t * info);
  75void inline spin_wheel (void);
  76static void flash_sync_real_protect (flash_info_t * info);
  77static unsigned char intel_sector_protected (flash_info_t *info, ushort sector);
  78static unsigned char same_chip_banks (int bank1, int bank2);
  79
  80/*-----------------------------------------------------------------------
  81 */
  82
  83unsigned long flash_init (void)
  84{
  85        int i;
  86        ulong size = 0;
  87        ulong fsize = 0;
  88
  89        for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
  90                memset (&flash_info[i], 0, sizeof (flash_info_t));
  91
  92                switch (i) {
  93                case 0:
  94                        flash_get_size ((FPW *) CONFIG_SYS_FLASH1_BASE,
  95                                        &flash_info[i]);
  96                        flash_get_offsets (CONFIG_SYS_FLASH1_BASE, &flash_info[i]);
  97                        break;
  98                case 1:
  99                        flash_get_size ((FPW *) CONFIG_SYS_FLASH1_BASE,
 100                                        &flash_info[i]);
 101                        fsize = CONFIG_SYS_FLASH1_BASE + flash_info[i - 1].size;
 102                        flash_get_offsets (fsize, &flash_info[i]);
 103                        break;
 104                case 2:
 105                        flash_get_size ((FPW *) CONFIG_SYS_FLASH0_BASE,
 106                                        &flash_info[i]);
 107                        flash_get_offsets (CONFIG_SYS_FLASH0_BASE, &flash_info[i]);
 108                        break;
 109                case 3:
 110                        flash_get_size ((FPW *) CONFIG_SYS_FLASH0_BASE,
 111                                        &flash_info[i]);
 112                        fsize = CONFIG_SYS_FLASH0_BASE + flash_info[i - 1].size;
 113                        flash_get_offsets (fsize, &flash_info[i]);
 114                        break;
 115                default:
 116                        panic ("configured to many flash banks!\n");
 117                        break;
 118                }
 119                size += flash_info[i].size;
 120
 121                /* get the h/w and s/w protection status in sync */
 122                flash_sync_real_protect(&flash_info[i]);
 123        }
 124
 125        /* Protect monitor and environment sectors
 126         */
 127#if defined (CONFIG_SYS_AMD_BOOT)
 128        flash_protect (FLAG_PROTECT_SET,
 129                       CONFIG_SYS_MONITOR_BASE,
 130                       CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
 131                       &flash_info[2]);
 132        flash_protect (FLAG_PROTECT_SET,
 133                       CONFIG_SYS_INTEL_BASE,
 134                       CONFIG_SYS_INTEL_BASE + monitor_flash_len - 1,
 135                       &flash_info[1]);
 136#else
 137        flash_protect (FLAG_PROTECT_SET,
 138                       CONFIG_SYS_MONITOR_BASE,
 139                       CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
 140                       &flash_info[3]);
 141        flash_protect (FLAG_PROTECT_SET,
 142                       CONFIG_SYS_AMD_BASE,
 143                       CONFIG_SYS_AMD_BASE + monitor_flash_len - 1, &flash_info[0]);
 144#endif
 145
 146        flash_protect (FLAG_PROTECT_SET,
 147                       CONFIG_ENV1_ADDR,
 148                       CONFIG_ENV1_ADDR + CONFIG_ENV1_SIZE - 1, &flash_info[1]);
 149        flash_protect (FLAG_PROTECT_SET,
 150                       CONFIG_ENV_ADDR,
 151                       CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[3]);
 152
 153        return size;
 154}
 155
 156/*-----------------------------------------------------------------------
 157 */
 158static void flash_get_offsets (ulong base, flash_info_t * info)
 159{
 160        int i;
 161
 162        if (info->flash_id == FLASH_UNKNOWN)
 163                return;
 164
 165        if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) {
 166                for (i = 0; i < info->sector_count; i++) {
 167                        info->start[i] = base + (i * PHYS_AMD_SECT_SIZE);
 168                        info->protect[i] = 0;
 169                }
 170        }
 171
 172        if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
 173                for (i = 0; i < info->sector_count; i++) {
 174                        info->start[i] = base + (i * PHYS_INTEL_SECT_SIZE);
 175                }
 176        }
 177}
 178
 179/*-----------------------------------------------------------------------
 180 */
 181void flash_print_info (flash_info_t * info)
 182{
 183        int i;
 184
 185        if (info->flash_id == FLASH_UNKNOWN) {
 186                printf ("missing or unknown FLASH type\n");
 187                return;
 188        }
 189
 190        switch (info->flash_id & FLASH_VENDMASK) {
 191        case FLASH_MAN_INTEL:
 192                printf ("INTEL ");
 193                break;
 194        case FLASH_MAN_AMD:
 195                printf ("AMD ");
 196                break;
 197        default:
 198                printf ("Unknown Vendor ");
 199                break;
 200        }
 201
 202        switch (info->flash_id & FLASH_TYPEMASK) {
 203        case FLASH_28F128J3A:
 204                printf ("28F128J3A\n");
 205                break;
 206
 207        case FLASH_AM040:
 208                printf ("AMD29F040B\n");
 209                break;
 210
 211        default:
 212                printf ("Unknown Chip Type\n");
 213                break;
 214        }
 215
 216        printf ("  Size: %ld MB in %d Sectors\n",
 217                info->size >> 20, info->sector_count);
 218
 219        printf ("  Sector Start Addresses:");
 220        for (i = 0; i < info->sector_count; ++i) {
 221                if ((i % 5) == 0)
 222                        printf ("\n   ");
 223                printf (" %08lX%s",
 224                        info->start[i], info->protect[i] ? " (RO)" : "     ");
 225        }
 226        printf ("\n");
 227        return;
 228}
 229
 230/*
 231 * The following code cannot be run from FLASH!
 232 */
 233static ulong flash_get_size (FPW * addr, flash_info_t * info)
 234{
 235        FPWV value;
 236        static int amd = 0;
 237
 238        /* Write auto select command: read Manufacturer ID */
 239        /* Write auto select command sequence and test FLASH answer */
 240        addr[FLASH_CYCLE1] = (FPW) 0x00AA00AA;  /* for AMD, Intel ignores this */
 241        __asm__ ("sync");
 242        addr[FLASH_CYCLE2] = (FPW) 0x00550055;  /* for AMD, Intel ignores this */
 243        __asm__ ("sync");
 244        addr[FLASH_CYCLE1] = (FPW) 0x00900090;  /* selects Intel or AMD */
 245        __asm__ ("sync");
 246
 247        udelay (100);
 248
 249        switch (addr[0] & 0xff) {
 250
 251        case (uchar) AMD_MANUFACT:
 252                info->flash_id = FLASH_MAN_AMD;
 253                value = addr[1];
 254                break;
 255
 256        case (uchar) INTEL_MANUFACT:
 257                info->flash_id = FLASH_MAN_INTEL;
 258                value = addr[2];
 259                break;
 260
 261        default:
 262                printf ("unknown\n");
 263                info->flash_id = FLASH_UNKNOWN;
 264                info->sector_count = 0;
 265                info->size = 0;
 266                addr[0] = (FPW) 0x00FF00FF;     /* restore read mode */
 267                return (0);     /* no or unknown flash  */
 268        }
 269
 270        switch (value) {
 271
 272        case (FPW) INTEL_ID_28F128J3A:
 273                info->flash_id += FLASH_28F128J3A;
 274                info->sector_count = 64;
 275                info->size = 0x00800000;        /* => 16 MB     */
 276                break;
 277
 278        case (FPW) AMD_ID_LV040B:
 279                info->flash_id += FLASH_AM040;
 280                if (amd == 0) {
 281                        info->sector_count = 7;
 282                        info->size = 0x00070000;        /* => 448 KB     */
 283                        amd = 1;
 284                } else {
 285                        /* for Environment settings */
 286                        info->sector_count = 1;
 287                        info->size = PHYS_AMD_SECT_SIZE;        /* => 64 KB     */
 288                        amd = 0;
 289                }
 290                break;
 291
 292        default:
 293                info->flash_id = FLASH_UNKNOWN;
 294                break;
 295        }
 296
 297        if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) {
 298                printf ("** ERROR: sector count %d > max (%d) **\n",
 299                        info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
 300                info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
 301        }
 302
 303        if (value == (FPW) INTEL_ID_28F128J3A)
 304                addr[0] = (FPW) 0x00FF00FF;     /* restore read mode */
 305        else
 306                addr[0] = (FPW) 0x00F000F0;     /* restore read mode */
 307
 308        return (info->size);
 309}
 310
 311
 312/*
 313 * This function gets the u-boot flash sector protection status
 314 * (flash_info_t.protect[]) in sync with the sector protection
 315 * status stored in hardware.
 316 */
 317static void flash_sync_real_protect (flash_info_t * info)
 318{
 319        int i;
 320
 321        switch (info->flash_id & FLASH_TYPEMASK) {
 322        case FLASH_28F128J3A:
 323                for (i = 0; i < info->sector_count; ++i) {
 324                        info->protect[i] = intel_sector_protected(info, i);
 325                }
 326                break;
 327        case FLASH_AM040:
 328        default:
 329                /* no h/w protect support */
 330                break;
 331        }
 332}
 333
 334
 335/*
 336 * checks if "sector" in bank "info" is protected. Should work on intel
 337 * strata flash chips 28FxxxJ3x in 8-bit mode.
 338 * Returns 1 if sector is protected (or timed-out while trying to read
 339 * protection status), 0 if it is not.
 340 */
 341static unsigned char intel_sector_protected (flash_info_t *info, ushort sector)
 342{
 343        FPWV *addr;
 344        FPWV *lock_conf_addr;
 345        ulong start;
 346        unsigned char ret;
 347
 348        /*
 349         * first, wait for the WSM to be finished. The rationale for
 350         * waiting for the WSM to become idle for at most
 351         * CONFIG_SYS_FLASH_ERASE_TOUT is as follows. The WSM can be busy
 352         * because of: (1) erase, (2) program or (3) lock bit
 353         * configuration. So we just wait for the longest timeout of
 354         * the (1)-(3), i.e. the erase timeout.
 355         */
 356
 357        /* wait at least 35ns (W12) before issuing Read Status Register */
 358        udelay(1);
 359        addr = (FPWV *) info->start[sector];
 360        *addr = (FPW) INTEL_STATUS;
 361
 362        start = get_timer (0);
 363        while ((*addr & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) {
 364                if (get_timer (start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 365                        *addr = (FPW) INTEL_RESET; /* restore read mode */
 366                        printf("WSM busy too long, can't get prot status\n");
 367                        return 1;
 368                }
 369        }
 370
 371        /* issue the Read Identifier Codes command */
 372        *addr = (FPW) INTEL_READID;
 373
 374        /* wait at least 35ns (W12) before reading */
 375        udelay(1);
 376
 377        /* Intel example code uses offset of 4 for 8-bit flash */
 378        lock_conf_addr = (FPWV *) info->start[sector] + 4;
 379        ret = (*lock_conf_addr & (FPW) INTEL_PROTECT) ? 1 : 0;
 380
 381        /* put flash back in read mode */
 382        *addr = (FPW) INTEL_RESET;
 383
 384        return ret;
 385}
 386
 387
 388/*
 389 * Checks if "bank1" and "bank2" are on the same chip.  Returns 1 if they
 390 * are and 0 otherwise.
 391 */
 392static unsigned char same_chip_banks (int bank1, int bank2)
 393{
 394        unsigned char same_chip[CONFIG_SYS_MAX_FLASH_BANKS][CONFIG_SYS_MAX_FLASH_BANKS] = {
 395                {1, 1, 0, 0},
 396                {1, 1, 0, 0},
 397                {0, 0, 1, 1},
 398                {0, 0, 1, 1}
 399        };
 400        return same_chip[bank1][bank2];
 401}
 402
 403
 404/*-----------------------------------------------------------------------
 405 */
 406int flash_erase (flash_info_t * info, int s_first, int s_last)
 407{
 408        int flag, prot, sect;
 409        ulong type, start, last;
 410        int rcode = 0, intel = 0;
 411
 412        if ((s_first < 0) || (s_first > s_last)) {
 413                if (info->flash_id == FLASH_UNKNOWN)
 414                        printf ("- missing\n");
 415                else
 416                        printf ("- no sectors to erase\n");
 417                return 1;
 418        }
 419
 420        type = (info->flash_id & FLASH_VENDMASK);
 421        if ((type != FLASH_MAN_INTEL)) {
 422                type = (info->flash_id & FLASH_VENDMASK);
 423                if ((type != FLASH_MAN_AMD)) {
 424                        printf ("Can't erase unknown flash type %08lx - aborted\n",
 425                                info->flash_id);
 426                        return 1;
 427                }
 428        }
 429
 430        if (type == FLASH_MAN_INTEL)
 431                intel = 1;
 432
 433        prot = 0;
 434        for (sect = s_first; sect <= s_last; ++sect) {
 435                if (info->protect[sect]) {
 436                        prot++;
 437                }
 438        }
 439
 440        if (prot) {
 441                printf ("- Warning: %d protected sectors will not be erased!\n", prot);
 442        } else {
 443                printf ("\n");
 444        }
 445
 446        start = get_timer (0);
 447        last = start;
 448
 449        /* Disable interrupts which might cause a timeout here */
 450        flag = disable_interrupts ();
 451
 452        /* Start erase on unprotected sectors */
 453        for (sect = s_first; sect <= s_last; sect++) {
 454                if (info->protect[sect] == 0) { /* not protected */
 455                        FPWV *addr = (FPWV *) (info->start[sect]);
 456                        FPW status;
 457
 458                        printf ("Erasing sector %2d ... ", sect);
 459
 460                        /* arm simple, non interrupt dependent timer */
 461                        start = get_timer (0);
 462
 463                        if (intel) {
 464                                *addr = (FPW) 0x00500050;       /* clear status register */
 465                                *addr = (FPW) 0x00200020;       /* erase setup */
 466                                *addr = (FPW) 0x00D000D0;       /* erase confirm */
 467                        } else {
 468                                FPWV *base;     /* first address in bank */
 469
 470                                base = (FPWV *) (CONFIG_SYS_AMD_BASE);
 471                                base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;  /* unlock */
 472                                base[FLASH_CYCLE2] = (FPW) 0x00550055;  /* unlock */
 473                                base[FLASH_CYCLE1] = (FPW) 0x00800080;  /* erase mode */
 474                                base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;  /* unlock */
 475                                base[FLASH_CYCLE2] = (FPW) 0x00550055;  /* unlock */
 476                                *addr = (FPW) 0x00300030;       /* erase sector */
 477                        }
 478
 479                        while (((status =
 480                                 *addr) & (FPW) 0x00800080) !=
 481                               (FPW) 0x00800080) {
 482                                if (get_timer (start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 483                                        printf ("Timeout\n");
 484                                        if (intel) {
 485                                                *addr = (FPW) 0x00B000B0;       /* suspend erase     */
 486                                                *addr = (FPW) 0x00FF00FF;       /* reset to read mode */
 487                                        } else
 488                                                *addr = (FPW) 0x00F000F0;       /* reset to read mode */
 489
 490                                        rcode = 1;
 491                                        break;
 492                                }
 493                        }
 494
 495                        if (intel) {
 496                                *addr = (FPW) 0x00500050;       /* clear status register cmd.   */
 497                                *addr = (FPW) 0x00FF00FF;       /* resest to read mode          */
 498                        } else
 499                                *addr = (FPW) 0x00F000F0;       /* reset to read mode */
 500
 501                        printf (" done\n");
 502                }
 503        }
 504        return rcode;
 505}
 506
 507/*-----------------------------------------------------------------------
 508 * Copy memory to flash, returns:
 509 * 0 - OK
 510 * 1 - write timeout
 511 * 2 - Flash not erased
 512 * 4 - Flash not identified
 513 */
 514
 515int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 516{
 517        if (info->flash_id == FLASH_UNKNOWN) {
 518                return 4;
 519        }
 520
 521        switch (info->flash_id & FLASH_VENDMASK) {
 522        case FLASH_MAN_AMD:
 523            {
 524                FPW data = 0;   /* 16 or 32 bit word, matches flash bus width */
 525                int bytes;      /* number of bytes to program in current word */
 526                int left;       /* number of bytes left to program */
 527                int i, res;
 528
 529                for (left = cnt, res = 0;
 530                     left > 0 && res == 0;
 531                     addr += sizeof (data), left -=
 532                     sizeof (data) - bytes) {
 533
 534                        bytes = addr & (sizeof (data) - 1);
 535                        addr &= ~(sizeof (data) - 1);
 536
 537                        /* combine source and destination data so can program
 538                         * an entire word of 16 or 32 bits
 539                         */
 540                        for (i = 0; i < sizeof (data); i++) {
 541                                data <<= 8;
 542                                if (i < bytes || i - bytes >= left)
 543                                        data += *((uchar *) addr + i);
 544                                else
 545                                        data += *src++;
 546                        }
 547
 548                        res = write_word_amd (info, (FPWV *) addr,
 549                                              data);
 550                }
 551                return res;
 552            }           /* case FLASH_MAN_AMD */
 553
 554        case FLASH_MAN_INTEL:
 555            {
 556                ulong cp, wp;
 557                FPW data;
 558                int count, i, l, rc, port_width;
 559
 560                /* get lower word aligned address */
 561                wp = addr;
 562                port_width = 1;
 563
 564                /*
 565                 * handle unaligned start bytes
 566                 */
 567                if ((l = addr - wp) != 0) {
 568                        data = 0;
 569                        for (i = 0, cp = wp; i < l; ++i, ++cp) {
 570                                data = (data << 8) | (*(uchar *) cp);
 571                        }
 572
 573                        for (; i < port_width && cnt > 0; ++i) {
 574                                data = (data << 8) | *src++;
 575                                --cnt;
 576                                ++cp;
 577                        }
 578
 579                        for (; cnt == 0 && i < port_width; ++i, ++cp)
 580                                data = (data << 8) | (*(uchar *) cp);
 581
 582                        if ((rc =
 583                             write_data (info, wp, SWAP (data))) != 0)
 584                                return (rc);
 585                        wp += port_width;
 586                }
 587
 588                if (cnt > WR_BLOCK) {
 589                        /*
 590                         * handle word aligned part
 591                         */
 592                        count = 0;
 593                        while (cnt >= WR_BLOCK) {
 594
 595                                if ((rc =
 596                                     write_data_block (info,
 597                                                       (ulong) src,
 598                                                       wp)) != 0)
 599                                        return (rc);
 600
 601                                wp += WR_BLOCK;
 602                                src += WR_BLOCK;
 603                                cnt -= WR_BLOCK;
 604
 605                                if (count++ > 0x800) {
 606                                        spin_wheel ();
 607                                        count = 0;
 608                                }
 609                        }
 610                }
 611
 612                if (cnt < WR_BLOCK) {
 613                        /*
 614                         * handle word aligned part
 615                         */
 616                        count = 0;
 617                        while (cnt >= port_width) {
 618                                data = 0;
 619                                for (i = 0; i < port_width; ++i)
 620                                        data = (data << 8) | *src++;
 621
 622                                if ((rc =
 623                                     write_data (info, wp,
 624                                                 SWAP (data))) != 0)
 625                                        return (rc);
 626
 627                                wp += port_width;
 628                                cnt -= port_width;
 629                                if (count++ > 0x800) {
 630                                        spin_wheel ();
 631                                        count = 0;
 632                                }
 633                        }
 634                }
 635
 636                if (cnt == 0)
 637                        return (0);
 638
 639                /*
 640                 * handle unaligned tail bytes
 641                 */
 642                data = 0;
 643                for (i = 0, cp = wp; i < port_width && cnt > 0;
 644                     ++i, ++cp) {
 645                        data = (data << 8) | *src++;
 646                        --cnt;
 647                }
 648
 649                for (; i < port_width; ++i, ++cp)
 650                        data = (data << 8) | (*(uchar *) cp);
 651
 652                return (write_data (info, wp, SWAP (data)));
 653            }           /* case FLASH_MAN_INTEL */
 654
 655        }                       /* switch */
 656        return (0);
 657}
 658
 659/*-----------------------------------------------------------------------
 660 * Write a word or halfword to Flash, returns:
 661 * 0 - OK
 662 * 1 - write timeout
 663 * 2 - Flash not erased
 664 */
 665static int write_data (flash_info_t * info, ulong dest, FPW data)
 666{
 667        FPWV *addr = (FPWV *) dest;
 668        ulong start;
 669        int flag;
 670
 671        /* Check if Flash is (sufficiently) erased */
 672        if ((*addr & data) != data) {
 673                printf ("not erased at %08lx (%lx)\n", (ulong)addr, (ulong)*addr);
 674                return (2);
 675        }
 676        /* Disable interrupts which might cause a timeout here */
 677        flag = disable_interrupts ();
 678
 679        *addr = (FPW) 0x00400040;       /* write setup */
 680        *addr = data;
 681
 682        /* arm simple, non interrupt dependent timer */
 683        start = get_timer (0);
 684
 685        /* wait while polling the status register */
 686        while ((*addr & (FPW) 0x00800080) != (FPW) 0x00800080) {
 687                if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 688                        *addr = (FPW) 0x00FF00FF;       /* restore read mode */
 689                        return (1);
 690                }
 691        }
 692
 693        *addr = (FPW) 0x00FF00FF;       /* restore read mode */
 694
 695        return (0);
 696}
 697
 698/*-----------------------------------------------------------------------
 699 * Write a word or halfword to Flash, returns:
 700 * 0 - OK
 701 * 1 - write timeout
 702 * 2 - Flash not erased
 703 */
 704static int write_data_block (flash_info_t * info, ulong src, ulong dest)
 705{
 706        FPWV *srcaddr = (FPWV *) src;
 707        FPWV *dstaddr = (FPWV *) dest;
 708        ulong start;
 709        int flag, i;
 710
 711        /* Check if Flash is (sufficiently) erased */
 712        for (i = 0; i < WR_BLOCK; i++)
 713                if ((*dstaddr++ & 0xff) != 0xff) {
 714                        printf ("not erased at %08lx (%lx)\n",
 715                                (ulong)dstaddr, (ulong)*dstaddr);
 716                        return (2);
 717                }
 718
 719        dstaddr = (FPWV *) dest;
 720
 721        /* Disable interrupts which might cause a timeout here */
 722        flag = disable_interrupts ();
 723
 724        *dstaddr = (FPW) 0x00e800e8;    /* write block setup */
 725
 726        /* arm simple, non interrupt dependent timer */
 727        start = get_timer (0);
 728
 729        /* wait while polling the status register */
 730        while ((*dstaddr & (FPW) 0x00800080) != (FPW) 0x00800080) {
 731                if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 732                        *dstaddr = (FPW) 0x00FF00FF;    /* restore read mode */
 733                        return (1);
 734                }
 735        }
 736
 737        *dstaddr = (FPW) 0x001f001f;    /* write 32 to buffer */
 738        for (i = 0; i < WR_BLOCK; i++)
 739                *dstaddr++ = *srcaddr++;
 740
 741        dstaddr -= 1;
 742        *dstaddr = (FPW) 0x00d000d0;    /* write 32 to buffer */
 743
 744        /* arm simple, non interrupt dependent timer */
 745        start = get_timer (0);
 746
 747        /* wait while polling the status register */
 748        while ((*dstaddr & (FPW) 0x00800080) != (FPW) 0x00800080) {
 749                if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 750                        *dstaddr = (FPW) 0x00FF00FF;    /* restore read mode */
 751                        return (1);
 752                }
 753        }
 754
 755        *dstaddr = (FPW) 0x00FF00FF;    /* restore read mode */
 756
 757        return (0);
 758}
 759
 760/*-----------------------------------------------------------------------
 761 * Write a word to Flash for AMD FLASH
 762 * A word is 16 or 32 bits, whichever the bus width of the flash bank
 763 * (not an individual chip) is.
 764 *
 765 * returns:
 766 * 0 - OK
 767 * 1 - write timeout
 768 * 2 - Flash not erased
 769 */
 770static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data)
 771{
 772        ulong start;
 773        int flag;
 774        int res = 0;            /* result, assume success */
 775        FPWV *base;             /* first address in flash bank */
 776
 777        /* Check if Flash is (sufficiently) erased */
 778        if ((*dest & data) != data) {
 779                return (2);
 780        }
 781
 782        base = (FPWV *) (CONFIG_SYS_AMD_BASE);
 783
 784        /* Disable interrupts which might cause a timeout here */
 785        flag = disable_interrupts ();
 786
 787        base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;  /* unlock */
 788        base[FLASH_CYCLE2] = (FPW) 0x00550055;  /* unlock */
 789        base[FLASH_CYCLE1] = (FPW) 0x00A000A0;  /* selects program mode */
 790
 791        *dest = data;           /* start programming the data */
 792
 793        /* re-enable interrupts if necessary */
 794        if (flag)
 795                enable_interrupts ();
 796
 797        start = get_timer (0);
 798
 799        /* data polling for D7 */
 800        while (res == 0
 801               && (*dest & (FPW) 0x00800080) != (data & (FPW) 0x00800080)) {
 802                if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 803                        *dest = (FPW) 0x00F000F0;       /* reset bank */
 804                        res = 1;
 805                }
 806        }
 807
 808        return (res);
 809}
 810
 811void inline spin_wheel (void)
 812{
 813        static int p = 0;
 814        static char w[] = "\\/-";
 815
 816        printf ("\010%c", w[p]);
 817        (++p == 3) ? (p = 0) : 0;
 818}
 819
 820/*-----------------------------------------------------------------------
 821 * Set/Clear sector's lock bit, returns:
 822 * 0 - OK
 823 * 1 - Error (timeout, voltage problems, etc.)
 824 */
 825int flash_real_protect (flash_info_t * info, long sector, int prot)
 826{
 827        ulong start;
 828        int i, j;
 829        int curr_bank;
 830        int bank;
 831        int rc = 0;
 832        FPWV *addr = (FPWV *) (info->start[sector]);
 833        int flag = disable_interrupts ();
 834
 835        /*
 836         * 29F040B AMD flash does not support software protection/unprotection,
 837         * the only way to protect the AMD flash is marked it as prot bit.
 838         * This flash only support hardware protection, by supply or not supply
 839         * 12vpp to the flash
 840         */
 841        if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) {
 842                info->protect[sector] = prot;
 843
 844                return 0;
 845        }
 846
 847        *addr = INTEL_CLEAR;    /* Clear status register    */
 848        if (prot) {             /* Set sector lock bit      */
 849                *addr = INTEL_LOCKBIT;  /* Sector lock bit          */
 850                *addr = INTEL_PROTECT;  /* set                      */
 851        } else {                /* Clear sector lock bit    */
 852                *addr = INTEL_LOCKBIT;  /* All sectors lock bits    */
 853                *addr = INTEL_CONFIRM;  /* clear                    */
 854        }
 855
 856        start = get_timer (0);
 857
 858        while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
 859                if (get_timer (start) > CONFIG_SYS_FLASH_UNLOCK_TOUT) {
 860                        printf ("Flash lock bit operation timed out\n");
 861                        rc = 1;
 862                        break;
 863                }
 864        }
 865
 866        if (*addr != INTEL_OK) {
 867                printf ("Flash lock bit operation failed at %08X, CSR=%08X\n",
 868                        (uint) addr, (uint) * addr);
 869                rc = 1;
 870        }
 871
 872        if (!rc)
 873                info->protect[sector] = prot;
 874
 875        /*
 876         * Clear lock bit command clears all sectors lock bits, so
 877         * we have to restore lock bits of protected sectors.
 878         */
 879        if (!prot) {
 880                /*
 881                 * re-locking must be done for all banks that belong on one
 882                 * FLASH chip, as all the sectors on the chip were unlocked
 883                 * by INTEL_LOCKBIT/INTEL_CONFIRM commands. (let's hope
 884                 * that banks never span chips, in particular chips which
 885                 * support h/w protection differently).
 886                 */
 887
 888                /* find the current bank number */
 889                curr_bank = CONFIG_SYS_MAX_FLASH_BANKS + 1;
 890                for (j = 0; j < CONFIG_SYS_MAX_FLASH_BANKS; ++j) {
 891                        if (&flash_info[j] == info) {
 892                                curr_bank = j;
 893                        }
 894                }
 895                if (curr_bank == CONFIG_SYS_MAX_FLASH_BANKS + 1) {
 896                        printf("Error: can't determine bank number!\n");
 897                }
 898
 899                for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
 900                        if (!same_chip_banks(curr_bank, bank)) {
 901                                continue;
 902                        }
 903                        info = &flash_info[bank];
 904                        for (i = 0; i < info->sector_count; i++) {
 905                                if (info->protect[i]) {
 906                                        start = get_timer (0);
 907                                        addr = (FPWV *) (info->start[i]);
 908                                        *addr = INTEL_LOCKBIT;  /* Sector lock bit  */
 909                                        *addr = INTEL_PROTECT;  /* set              */
 910                                        while ((*addr & INTEL_FINISHED) !=
 911                                               INTEL_FINISHED) {
 912                                                if (get_timer (start) >
 913                                                    CONFIG_SYS_FLASH_UNLOCK_TOUT) {
 914                                                        printf ("Flash lock bit operation timed out\n");
 915                                                        rc = 1;
 916                                                        break;
 917                                                }
 918                                        }
 919                                }
 920                        }
 921                }
 922
 923                /*
 924                 * get the s/w sector protection status in sync with the h/w,
 925                 * in case something went wrong during the re-locking.
 926                 */
 927                flash_sync_real_protect(info); /* resets flash to read  mode */
 928        }
 929
 930        if (flag)
 931                enable_interrupts ();
 932
 933        *addr = INTEL_RESET;    /* Reset to read array mode */
 934
 935        return rc;
 936}
 937