uboot/board/tqc/tqm5200/cam5200_flash.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2006
   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#include <common.h>
  25#include <mpc5xxx.h>
  26#include <asm/processor.h>
  27
  28#if defined(CONFIG_CAM5200) && defined(CONFIG_CAM5200_NIOSFLASH)
  29
  30#if 0
  31#define DEBUGF(x...) printf(x)
  32#else
  33#define DEBUGF(x...)
  34#endif
  35
  36#define swap16(x) __swab16(x)
  37
  38flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];    /* info for FLASH chips */
  39
  40/*
  41 * CAM5200 is a TQM5200B based board. Additionally it also features
  42 * a NIOS cpu. The NIOS CPU peripherals are accessible through MPC5xxx
  43 * Local Bus on CS5. This includes 32 bit wide RAM and SRAM as well as
  44 * 16 bit wide flash device. Big Endian order on a 32 bit CS5 makes
  45 * access to flash chip slightly more complicated as additional byte
  46 * swapping is necessary within each 16 bit wide flash 'word'.
  47 *
  48 * This driver's task is to handle both flash devices: 32 bit TQM5200B
  49 * flash chip and 16 bit NIOS cpu flash chip. In the below
  50 * flash_addr_table table we use least significant address bit to mark
  51 * 16 bit flash bank and two sets of routines *_32 and *_16 to handle
  52 * specifics of both flashes.
  53 */
  54static unsigned long flash_addr_table[][CONFIG_SYS_MAX_FLASH_BANKS] = {
  55        {CONFIG_SYS_BOOTCS_START, CONFIG_SYS_CS5_START | 1}
  56};
  57
  58/*-----------------------------------------------------------------------
  59 * Functions
  60 */
  61static int write_word(flash_info_t * info, ulong dest, ulong data);
  62#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
  63static int write_word_32(flash_info_t * info, ulong dest, ulong data);
  64static int write_word_16(flash_info_t * info, ulong dest, ulong data);
  65static int flash_erase_32(flash_info_t * info, int s_first, int s_last);
  66static int flash_erase_16(flash_info_t * info, int s_first, int s_last);
  67static ulong flash_get_size_32(vu_long * addr, flash_info_t * info);
  68static ulong flash_get_size_16(vu_long * addr, flash_info_t * info);
  69#endif
  70
  71void flash_print_info(flash_info_t * info)
  72{
  73        int i, k;
  74        int size, erased;
  75        volatile unsigned long *flash;
  76
  77        if (info->flash_id == FLASH_UNKNOWN) {
  78                printf("missing or unknown FLASH type\n");
  79                return;
  80        }
  81
  82        switch (info->flash_id & FLASH_VENDMASK) {
  83                case FLASH_MAN_AMD:
  84                        printf("AMD ");
  85                        break;
  86                case FLASH_MAN_FUJ:
  87                        printf("FUJITSU ");
  88                        break;
  89                default:
  90                        printf("Unknown Vendor ");
  91                        break;
  92        }
  93
  94        switch (info->flash_id & FLASH_TYPEMASK) {
  95                case FLASH_S29GL128N:
  96                        printf ("S29GL128N (256 Mbit, uniform sector size)\n");
  97                        break;
  98                case FLASH_AM320B:
  99                        printf ("29LV320B (32 Mbit, bottom boot sect)\n");
 100                        break;
 101                case FLASH_AM320T:
 102                        printf ("29LV320T (32 Mbit, top boot sect)\n");
 103                        break;
 104                default:
 105                        printf("Unknown Chip Type\n");
 106                        break;
 107        }
 108
 109        printf("  Size: %ld KB in %d Sectors\n",
 110                        info->size >> 10, info->sector_count);
 111
 112        printf("  Sector Start Addresses:");
 113        for (i = 0; i < info->sector_count; ++i) {
 114                /*
 115                 * Check if whole sector is erased
 116                 */
 117                if (i != (info->sector_count - 1))
 118                        size = info->start[i + 1] - info->start[i];
 119                else
 120                        size = info->start[0] + info->size - info->start[i];
 121
 122                erased = 1;
 123                flash = (volatile unsigned long *)info->start[i];
 124                size = size >> 2;       /* divide by 4 for longword access */
 125
 126                for (k = 0; k < size; k++) {
 127                        if (*flash++ != 0xffffffff) {
 128                                erased = 0;
 129                                break;
 130                        }
 131                }
 132
 133                if ((i % 5) == 0)
 134                        printf("\n   ");
 135
 136                printf(" %08lX%s%s", info->start[i],
 137                                erased ? " E" : "  ",
 138                                info->protect[i] ? "RO " : "   ");
 139        }
 140        printf("\n");
 141        return;
 142}
 143
 144
 145/*
 146 * The following code cannot be run from FLASH!
 147 */
 148#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
 149static ulong flash_get_size(vu_long * addr, flash_info_t * info)
 150{
 151
 152        DEBUGF("get_size: FLASH ADDR %08lx\n", addr);
 153
 154        /* bit 0 used for big flash marking */
 155        if ((ulong)addr & 0x1)
 156                return flash_get_size_16((vu_long *)((ulong)addr & 0xfffffffe), info);
 157        else
 158                return flash_get_size_32(addr, info);
 159}
 160
 161static ulong flash_get_size_32(vu_long * addr, flash_info_t * info)
 162#else
 163static ulong flash_get_size(vu_long * addr, flash_info_t * info)
 164#endif
 165{
 166        short i;
 167        CONFIG_SYS_FLASH_WORD_SIZE value;
 168        ulong base = (ulong) addr;
 169        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) addr;
 170
 171        DEBUGF("get_size32: FLASH ADDR: %08x\n", (unsigned)addr);
 172
 173        /* Write auto select command: read Manufacturer ID */
 174        addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
 175        addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
 176        addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00900090;
 177        udelay(1000);
 178
 179        value = addr2[0];
 180        DEBUGF("FLASH MANUFACT: %x\n", value);
 181
 182        switch (value) {
 183                case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_MANUFACT:
 184                        info->flash_id = FLASH_MAN_AMD;
 185                        break;
 186                default:
 187                        info->flash_id = FLASH_UNKNOWN;
 188                        info->sector_count = 0;
 189                        info->size = 0;
 190                        return (0);     /* no or unknown flash  */
 191        }
 192
 193        value = addr2[1];       /* device ID            */
 194        DEBUGF("\nFLASH DEVICEID: %x\n", value);
 195
 196        switch (value) {
 197                case AMD_ID_MIRROR:
 198                        DEBUGF("Mirror Bit flash: addr[14] = %08lX  addr[15] = %08lX\n",
 199                                        addr[14], addr[15]);
 200                        switch(addr[14]) {
 201                                case AMD_ID_GL128N_2:
 202                                        if (addr[15] != AMD_ID_GL128N_3) {
 203                                                DEBUGF("Chip: S29GL128N -> unknown\n");
 204                                                info->flash_id = FLASH_UNKNOWN;
 205                                        } else {
 206                                                DEBUGF("Chip: S29GL128N\n");
 207                                                info->flash_id += FLASH_S29GL128N;
 208                                                info->sector_count = 128;
 209                                                info->size = 0x02000000;
 210                                        }
 211                                        break;
 212                                default:
 213                                        info->flash_id = FLASH_UNKNOWN;
 214                                        return(0);
 215                        }
 216                        break;
 217
 218                default:
 219                        info->flash_id = FLASH_UNKNOWN;
 220                        return (0);     /* => no or unknown flash */
 221        }
 222
 223        /* set up sector start address table */
 224        for (i = 0; i < info->sector_count; i++)
 225                info->start[i] = base + (i * 0x00040000);
 226
 227        /* check for protected sectors */
 228        for (i = 0; i < info->sector_count; i++) {
 229                /* read sector protection at sector address, (A7 .. A0) = 0x02 */
 230                /* D0 = 1 if protected */
 231                addr2 = (volatile CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[i]);
 232
 233                info->protect[i] = addr2[2] & 1;
 234        }
 235
 236        /* issue bank reset to return to read mode */
 237        addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00F000F0;
 238
 239        return (info->size);
 240}
 241
 242static int wait_for_DQ7_32(flash_info_t * info, int sect)
 243{
 244        ulong start, now, last;
 245        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr =
 246                (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
 247
 248        start = get_timer(0);
 249        last = start;
 250        while ((addr[0] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080) !=
 251                        (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080) {
 252                if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 253                        printf("Timeout\n");
 254                        return -1;
 255                }
 256                /* show that we're waiting */
 257                if ((now - last) > 1000) {      /* every second */
 258                        putc('.');
 259                        last = now;
 260                }
 261        }
 262        return 0;
 263}
 264
 265#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
 266int flash_erase(flash_info_t * info, int s_first, int s_last)
 267{
 268        if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) {
 269                return flash_erase_16(info, s_first, s_last);
 270        } else {
 271                return flash_erase_32(info, s_first, s_last);
 272        }
 273}
 274
 275static int flash_erase_32(flash_info_t * info, int s_first, int s_last)
 276#else
 277int flash_erase(flash_info_t * info, int s_first, int s_last)
 278#endif
 279{
 280        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
 281        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2;
 282        int flag, prot, sect, l_sect;
 283
 284        if ((s_first < 0) || (s_first > s_last)) {
 285                if (info->flash_id == FLASH_UNKNOWN)
 286                        printf("- missing\n");
 287                else
 288                        printf("- no sectors to erase\n");
 289                return 1;
 290        }
 291
 292        if (info->flash_id == FLASH_UNKNOWN) {
 293                printf("Can't erase unknown flash type - aborted\n");
 294                return 1;
 295        }
 296
 297        prot = 0;
 298        for (sect = s_first; sect <= s_last; ++sect) {
 299                if (info->protect[sect])
 300                        prot++;
 301        }
 302
 303        if (prot)
 304                printf("- Warning: %d protected sectors will not be erased!", prot);
 305
 306        printf("\n");
 307
 308        l_sect = -1;
 309
 310        /* Disable interrupts which might cause a timeout here */
 311        flag = disable_interrupts();
 312
 313        /* Start erase on unprotected sectors */
 314        for (sect = s_first; sect <= s_last; sect++) {
 315                if (info->protect[sect] == 0) { /* not protected */
 316                        addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
 317
 318                        addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
 319                        addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
 320                        addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080;
 321                        addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
 322                        addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
 323                        addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00300030;     /* sector erase */
 324
 325                        l_sect = sect;
 326                        /*
 327                         * Wait for each sector to complete, it's more
 328                         * reliable.  According to AMD Spec, you must
 329                         * issue all erase commands within a specified
 330                         * timeout.  This has been seen to fail, especially
 331                         * if printf()s are included (for debug)!!
 332                         */
 333                        wait_for_DQ7_32(info, sect);
 334                }
 335        }
 336
 337        /* re-enable interrupts if necessary */
 338        if (flag)
 339                enable_interrupts();
 340
 341        /* wait at least 80us - let's wait 1 ms */
 342        udelay(1000);
 343
 344        /* reset to read mode */
 345        addr = (CONFIG_SYS_FLASH_WORD_SIZE *) info->start[0];
 346        addr[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00F000F0;      /* reset bank */
 347
 348        printf(" done\n");
 349        return 0;
 350}
 351
 352/*-----------------------------------------------------------------------
 353 * Copy memory to flash, returns:
 354 * 0 - OK
 355 * 1 - write timeout
 356 * 2 - Flash not erased
 357 */
 358int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 359{
 360        ulong cp, wp, data;
 361        int i, l, rc;
 362
 363        wp = (addr & ~3);       /* get lower word aligned address */
 364
 365        /*
 366         * handle unaligned start bytes
 367         */
 368        if ((l = addr - wp) != 0) {
 369                data = 0;
 370                for (i = 0, cp = wp; i < l; ++i, ++cp)
 371                        data = (data << 8) | (*(uchar *) cp);
 372
 373                for (; i < 4 && cnt > 0; ++i) {
 374                        data = (data << 8) | *src++;
 375                        --cnt;
 376                        ++cp;
 377                }
 378
 379                for (; cnt == 0 && i < 4; ++i, ++cp)
 380                        data = (data << 8) | (*(uchar *) cp);
 381
 382                if ((rc = write_word(info, wp, data)) != 0)
 383                        return (rc);
 384
 385                wp += 4;
 386        }
 387
 388        /*
 389         * handle word aligned part
 390         */
 391        while (cnt >= 4) {
 392                data = 0;
 393                for (i = 0; i < 4; ++i)
 394                        data = (data << 8) | *src++;
 395
 396                if ((rc = write_word(info, wp, data)) != 0)
 397                        return (rc);
 398
 399                wp += 4;
 400                cnt -= 4;
 401        }
 402
 403        if (cnt == 0)
 404                return (0);
 405
 406        /*
 407         * handle unaligned tail bytes
 408         */
 409        data = 0;
 410        for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
 411                data = (data << 8) | *src++;
 412                --cnt;
 413        }
 414        for (; i < 4; ++i, ++cp)
 415                data = (data << 8) | (*(uchar *) cp);
 416
 417        return (write_word(info, wp, data));
 418}
 419
 420/*-----------------------------------------------------------------------
 421 * Copy memory to flash, returns:
 422 * 0 - OK
 423 * 1 - write timeout
 424 * 2 - Flash not erased
 425 */
 426#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
 427static int write_word(flash_info_t * info, ulong dest, ulong data)
 428{
 429        if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) {
 430                return write_word_16(info, dest, data);
 431        } else {
 432                return write_word_32(info, dest, data);
 433        }
 434}
 435
 436static int write_word_32(flash_info_t * info, ulong dest, ulong data)
 437#else
 438static int write_word(flash_info_t * info, ulong dest, ulong data)
 439#endif
 440{
 441        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
 442        volatile CONFIG_SYS_FLASH_WORD_SIZE *dest2 = (CONFIG_SYS_FLASH_WORD_SIZE *) dest;
 443        volatile CONFIG_SYS_FLASH_WORD_SIZE *data2 = (CONFIG_SYS_FLASH_WORD_SIZE *) & data;
 444        ulong start;
 445        int i, flag;
 446
 447        /* Check if Flash is (sufficiently) erased */
 448        if ((*((vu_long *)dest) & data) != data)
 449                return (2);
 450
 451        for (i = 0; i < 4 / sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) {
 452                /* Disable interrupts which might cause a timeout here */
 453                flag = disable_interrupts();
 454
 455                addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
 456                addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
 457                addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00A000A0;
 458
 459                dest2[i] = data2[i];
 460
 461                /* re-enable interrupts if necessary */
 462                if (flag)
 463                        enable_interrupts();
 464
 465                /* data polling for D7 */
 466                start = get_timer(0);
 467                while ((dest2[i] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080) !=
 468                                (data2[i] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080)) {
 469
 470                        if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
 471                                return (1);
 472                }
 473        }
 474
 475        return (0);
 476}
 477
 478#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
 479
 480#undef  CONFIG_SYS_FLASH_WORD_SIZE
 481#define CONFIG_SYS_FLASH_WORD_SIZE unsigned short
 482
 483/*
 484 * The following code cannot be run from FLASH!
 485 */
 486static ulong flash_get_size_16(vu_long * addr, flash_info_t * info)
 487{
 488        short i;
 489        CONFIG_SYS_FLASH_WORD_SIZE value;
 490        ulong base = (ulong) addr;
 491        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) addr;
 492
 493        DEBUGF("get_size16: FLASH ADDR: %08x\n", (unsigned)addr);
 494
 495        /* issue bank reset to return to read mode */
 496        addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xF000F000;
 497
 498        /* Write auto select command: read Manufacturer ID */
 499        addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAA00AA00;
 500        addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55005500;
 501        addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x90009000;
 502        udelay(1000);
 503
 504        value = swap16(addr2[0]);
 505        DEBUGF("FLASH MANUFACT: %x\n", value);
 506
 507        switch (value) {
 508                case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_MANUFACT:
 509                        info->flash_id = FLASH_MAN_AMD;
 510                        break;
 511                case (CONFIG_SYS_FLASH_WORD_SIZE) FUJ_MANUFACT:
 512                        info->flash_id = FLASH_MAN_FUJ;
 513                        break;
 514                default:
 515                        info->flash_id = FLASH_UNKNOWN;
 516                        info->sector_count = 0;
 517                        info->size = 0;
 518                        return (0);     /* no or unknown flash  */
 519        }
 520
 521        value = swap16(addr2[1]);       /* device ID            */
 522        DEBUGF("\nFLASH DEVICEID: %x\n", value);
 523
 524        switch (value) {
 525                case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320B:
 526                        info->flash_id += FLASH_AM320B;
 527                        info->sector_count = 71;
 528                        info->size = 0x00400000;
 529                        break;  /* => 4 MB      */
 530                case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320T:
 531                        info->flash_id += FLASH_AM320T;
 532                        info->sector_count = 71;
 533                        info->size = 0x00400000;
 534                        break;  /* => 4 MB      */
 535                default:
 536                        info->flash_id = FLASH_UNKNOWN;
 537                        return (0);     /* => no or unknown flash */
 538        }
 539
 540        if (info->flash_id & FLASH_BTYPE) {
 541                /* set sector offsets for bottom boot block type        */
 542                info->start[0] = base + 0x00000000;
 543                info->start[1] = base + 0x00002000;
 544                info->start[2] = base + 0x00004000;
 545                info->start[3] = base + 0x00006000;
 546                info->start[4] = base + 0x00008000;
 547                info->start[5] = base + 0x0000a000;
 548                info->start[6] = base + 0x0000c000;
 549                info->start[7] = base + 0x0000e000;
 550
 551                for (i = 8; i < info->sector_count; i++)
 552                        info->start[i] = base + (i * 0x00010000) - 0x00070000;
 553        } else {
 554                /* set sector offsets for top boot block type           */
 555                i = info->sector_count - 1;
 556                info->start[i--] = base + info->size - 0x00002000;
 557                info->start[i--] = base + info->size - 0x00004000;
 558                info->start[i--] = base + info->size - 0x00006000;
 559                info->start[i--] = base + info->size - 0x00008000;
 560                info->start[i--] = base + info->size - 0x0000a000;
 561                info->start[i--] = base + info->size - 0x0000c000;
 562                info->start[i--] = base + info->size - 0x0000e000;
 563
 564                for (; i >= 0; i--)
 565                        info->start[i] = base + i * 0x00010000;
 566        }
 567
 568        /* check for protected sectors */
 569        for (i = 0; i < info->sector_count; i++) {
 570                /* read sector protection at sector address, (A7 .. A0) = 0x02 */
 571                /* D0 = 1 if protected */
 572                addr2 = (volatile CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[i]);
 573
 574                info->protect[i] = addr2[2] & 1;
 575        }
 576
 577        /* issue bank reset to return to read mode */
 578        addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xF000F000;
 579
 580        return (info->size);
 581}
 582
 583static int wait_for_DQ7_16(flash_info_t * info, int sect)
 584{
 585        ulong start, now, last;
 586        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr =
 587                (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
 588
 589        start = get_timer(0);
 590        last = start;
 591        while ((addr[0] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000) !=
 592                        (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000) {
 593                if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 594                        printf("Timeout\n");
 595                        return -1;
 596                }
 597                /* show that we're waiting */
 598                if ((now - last) > 1000) {      /* every second */
 599                        putc('.');
 600                        last = now;
 601                }
 602        }
 603        return 0;
 604}
 605
 606static int flash_erase_16(flash_info_t * info, int s_first, int s_last)
 607{
 608        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
 609        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2;
 610        int flag, prot, sect, l_sect;
 611
 612        if ((s_first < 0) || (s_first > s_last)) {
 613                if (info->flash_id == FLASH_UNKNOWN)
 614                        printf("- missing\n");
 615                else
 616                        printf("- no sectors to erase\n");
 617                return 1;
 618        }
 619
 620        if (info->flash_id == FLASH_UNKNOWN) {
 621                printf("Can't erase unknown flash type - aborted\n");
 622                return 1;
 623        }
 624
 625        prot = 0;
 626        for (sect = s_first; sect <= s_last; ++sect) {
 627                if (info->protect[sect])
 628                        prot++;
 629        }
 630
 631        if (prot)
 632                printf("- Warning: %d protected sectors will not be erased!",   prot);
 633
 634        printf("\n");
 635
 636        l_sect = -1;
 637
 638        /* Disable interrupts which might cause a timeout here */
 639        flag = disable_interrupts();
 640
 641        /* Start erase on unprotected sectors */
 642        for (sect = s_first; sect <= s_last; sect++) {
 643                if (info->protect[sect] == 0) { /* not protected */
 644                        addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
 645
 646                        addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAA00AA00;
 647                        addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55005500;
 648                        addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000;
 649                        addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAA00AA00;
 650                        addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55005500;
 651                        addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x30003000;     /* sector erase */
 652
 653                        l_sect = sect;
 654                        /*
 655                         * Wait for each sector to complete, it's more
 656                         * reliable.  According to AMD Spec, you must
 657                         * issue all erase commands within a specified
 658                         * timeout.  This has been seen to fail, especially
 659                         * if printf()s are included (for debug)!!
 660                         */
 661                        wait_for_DQ7_16(info, sect);
 662                }
 663        }
 664
 665        /* re-enable interrupts if necessary */
 666        if (flag)
 667                enable_interrupts();
 668
 669        /* wait at least 80us - let's wait 1 ms */
 670        udelay(1000);
 671
 672        /* reset to read mode */
 673        addr = (CONFIG_SYS_FLASH_WORD_SIZE *) info->start[0];
 674        addr[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xF000F000;      /* reset bank */
 675
 676        printf(" done\n");
 677        return 0;
 678}
 679
 680static int write_word_16(flash_info_t * info, ulong dest, ulong data)
 681{
 682        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
 683        volatile CONFIG_SYS_FLASH_WORD_SIZE *dest2 = (CONFIG_SYS_FLASH_WORD_SIZE *) dest;
 684        volatile CONFIG_SYS_FLASH_WORD_SIZE *data2 = (CONFIG_SYS_FLASH_WORD_SIZE *) & data;
 685        ulong start;
 686        int i;
 687
 688        /* Check if Flash is (sufficiently) erased */
 689        for (i = 0; i < 4 / sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) {
 690                if ((dest2[i] & swap16(data2[i])) != swap16(data2[i]))
 691                        return (2);
 692        }
 693
 694        for (i = 0; i < 4 / sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) {
 695                int flag;
 696
 697                /* Disable interrupts which might cause a timeout here */
 698                flag = disable_interrupts();
 699
 700                addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAA00AA00;
 701                addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55005500;
 702                addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xA000A000;
 703
 704                dest2[i] = swap16(data2[i]);
 705
 706                /* re-enable interrupts if necessary */
 707                if (flag)
 708                        enable_interrupts();
 709
 710                /* data polling for D7 */
 711                start = get_timer(0);
 712                while ((dest2[i] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000) !=
 713                                (swap16(data2[i]) & (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000)) {
 714
 715                        if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 716                                return (1);
 717                        }
 718                }
 719        }
 720
 721        return (0);
 722}
 723#endif /* CONFIG_SYS_FLASH_2ND_16BIT_DEV */
 724
 725/*-----------------------------------------------------------------------
 726 * Functions
 727 */
 728static ulong flash_get_size(vu_long * addr, flash_info_t * info);
 729static int write_word(flash_info_t * info, ulong dest, ulong data);
 730
 731/*-----------------------------------------------------------------------
 732 */
 733
 734unsigned long flash_init(void)
 735{
 736        unsigned long total_b = 0;
 737        unsigned long size_b[CONFIG_SYS_MAX_FLASH_BANKS];
 738        unsigned short index = 0;
 739        int i;
 740
 741        DEBUGF("\n");
 742        DEBUGF("FLASH: Index: %d\n", index);
 743
 744        /* Init: no FLASHes known */
 745        for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
 746                flash_info[i].flash_id = FLASH_UNKNOWN;
 747                flash_info[i].sector_count = -1;
 748                flash_info[i].size = 0;
 749
 750                /* check whether the address is 0 */
 751                if (flash_addr_table[index][i] == 0)
 752                        continue;
 753
 754                /* call flash_get_size() to initialize sector address */
 755                size_b[i] = flash_get_size((vu_long *) flash_addr_table[index][i],
 756                                &flash_info[i]);
 757
 758                flash_info[i].size = size_b[i];
 759
 760                if (flash_info[i].flash_id == FLASH_UNKNOWN) {
 761                        printf("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
 762                                        i+1, size_b[i], size_b[i] << 20);
 763                        flash_info[i].sector_count = -1;
 764                        flash_info[i].size = 0;
 765                }
 766
 767                /* Monitor protection ON by default */
 768                (void)flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_MONITOR_BASE,
 769                                    CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN - 1,
 770                                    &flash_info[i]);
 771#if defined(CONFIG_ENV_IS_IN_FLASH)
 772                (void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR,
 773                                    CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
 774                                    &flash_info[i]);
 775#if defined(CONFIG_ENV_ADDR_REDUND)
 776                (void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR_REDUND,
 777                                    CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1,
 778                                    &flash_info[i]);
 779#endif
 780#endif
 781                total_b += flash_info[i].size;
 782        }
 783
 784        return total_b;
 785}
 786#endif /* if defined(CONFIG_CAM5200) && defined(CONFIG_CAM5200_NIOSFLASH) */
 787