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;
 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        /* Disable interrupts which might cause a timeout here */
 309        flag = disable_interrupts();
 310
 311        /* Start erase on unprotected sectors */
 312        for (sect = s_first; sect <= s_last; sect++) {
 313                if (info->protect[sect] == 0) { /* not protected */
 314                        addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
 315
 316                        addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
 317                        addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
 318                        addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080;
 319                        addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
 320                        addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
 321                        addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00300030;     /* sector erase */
 322
 323                        /*
 324                         * Wait for each sector to complete, it's more
 325                         * reliable.  According to AMD Spec, you must
 326                         * issue all erase commands within a specified
 327                         * timeout.  This has been seen to fail, especially
 328                         * if printf()s are included (for debug)!!
 329                         */
 330                        wait_for_DQ7_32(info, sect);
 331                }
 332        }
 333
 334        /* re-enable interrupts if necessary */
 335        if (flag)
 336                enable_interrupts();
 337
 338        /* wait at least 80us - let's wait 1 ms */
 339        udelay(1000);
 340
 341        /* reset to read mode */
 342        addr = (CONFIG_SYS_FLASH_WORD_SIZE *) info->start[0];
 343        addr[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00F000F0;      /* reset bank */
 344
 345        printf(" done\n");
 346        return 0;
 347}
 348
 349/*-----------------------------------------------------------------------
 350 * Copy memory to flash, returns:
 351 * 0 - OK
 352 * 1 - write timeout
 353 * 2 - Flash not erased
 354 */
 355int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 356{
 357        ulong cp, wp, data;
 358        int i, l, rc;
 359
 360        wp = (addr & ~3);       /* get lower word aligned address */
 361
 362        /*
 363         * handle unaligned start bytes
 364         */
 365        if ((l = addr - wp) != 0) {
 366                data = 0;
 367                for (i = 0, cp = wp; i < l; ++i, ++cp)
 368                        data = (data << 8) | (*(uchar *) cp);
 369
 370                for (; i < 4 && cnt > 0; ++i) {
 371                        data = (data << 8) | *src++;
 372                        --cnt;
 373                        ++cp;
 374                }
 375
 376                for (; cnt == 0 && i < 4; ++i, ++cp)
 377                        data = (data << 8) | (*(uchar *) cp);
 378
 379                if ((rc = write_word(info, wp, data)) != 0)
 380                        return (rc);
 381
 382                wp += 4;
 383        }
 384
 385        /*
 386         * handle word aligned part
 387         */
 388        while (cnt >= 4) {
 389                data = 0;
 390                for (i = 0; i < 4; ++i)
 391                        data = (data << 8) | *src++;
 392
 393                if ((rc = write_word(info, wp, data)) != 0)
 394                        return (rc);
 395
 396                wp += 4;
 397                cnt -= 4;
 398        }
 399
 400        if (cnt == 0)
 401                return (0);
 402
 403        /*
 404         * handle unaligned tail bytes
 405         */
 406        data = 0;
 407        for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
 408                data = (data << 8) | *src++;
 409                --cnt;
 410        }
 411        for (; i < 4; ++i, ++cp)
 412                data = (data << 8) | (*(uchar *) cp);
 413
 414        return (write_word(info, wp, data));
 415}
 416
 417/*-----------------------------------------------------------------------
 418 * Copy memory to flash, returns:
 419 * 0 - OK
 420 * 1 - write timeout
 421 * 2 - Flash not erased
 422 */
 423#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
 424static int write_word(flash_info_t * info, ulong dest, ulong data)
 425{
 426        if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM320B) {
 427                return write_word_16(info, dest, data);
 428        } else {
 429                return write_word_32(info, dest, data);
 430        }
 431}
 432
 433static int write_word_32(flash_info_t * info, ulong dest, ulong data)
 434#else
 435static int write_word(flash_info_t * info, ulong dest, ulong data)
 436#endif
 437{
 438        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
 439        volatile CONFIG_SYS_FLASH_WORD_SIZE *dest2 = (CONFIG_SYS_FLASH_WORD_SIZE *) dest;
 440        ulong *datap = &data;
 441        volatile CONFIG_SYS_FLASH_WORD_SIZE *data2 =
 442                        (volatile CONFIG_SYS_FLASH_WORD_SIZE *)datap;
 443        ulong start;
 444        int i, flag;
 445
 446        /* Check if Flash is (sufficiently) erased */
 447        if ((*((vu_long *)dest) & data) != data)
 448                return (2);
 449
 450        for (i = 0; i < 4 / sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) {
 451                /* Disable interrupts which might cause a timeout here */
 452                flag = disable_interrupts();
 453
 454                addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00AA00AA;
 455                addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00550055;
 456                addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x00A000A0;
 457
 458                dest2[i] = data2[i];
 459
 460                /* re-enable interrupts if necessary */
 461                if (flag)
 462                        enable_interrupts();
 463
 464                /* data polling for D7 */
 465                start = get_timer(0);
 466                while ((dest2[i] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080) !=
 467                                (data2[i] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x00800080)) {
 468
 469                        if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT)
 470                                return (1);
 471                }
 472        }
 473
 474        return (0);
 475}
 476
 477#ifdef CONFIG_SYS_FLASH_2ND_16BIT_DEV
 478
 479#undef  CONFIG_SYS_FLASH_WORD_SIZE
 480#define CONFIG_SYS_FLASH_WORD_SIZE unsigned short
 481
 482/*
 483 * The following code cannot be run from FLASH!
 484 */
 485static ulong flash_get_size_16(vu_long * addr, flash_info_t * info)
 486{
 487        short i;
 488        CONFIG_SYS_FLASH_WORD_SIZE value;
 489        ulong base = (ulong) addr;
 490        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) addr;
 491
 492        DEBUGF("get_size16: FLASH ADDR: %08x\n", (unsigned)addr);
 493
 494        /* issue bank reset to return to read mode */
 495        addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xF000F000;
 496
 497        /* Write auto select command: read Manufacturer ID */
 498        addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAA00AA00;
 499        addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55005500;
 500        addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x90009000;
 501        udelay(1000);
 502
 503        value = swap16(addr2[0]);
 504        DEBUGF("FLASH MANUFACT: %x\n", value);
 505
 506        switch (value) {
 507                case (CONFIG_SYS_FLASH_WORD_SIZE) AMD_MANUFACT:
 508                        info->flash_id = FLASH_MAN_AMD;
 509                        break;
 510                case (CONFIG_SYS_FLASH_WORD_SIZE) FUJ_MANUFACT:
 511                        info->flash_id = FLASH_MAN_FUJ;
 512                        break;
 513                default:
 514                        info->flash_id = FLASH_UNKNOWN;
 515                        info->sector_count = 0;
 516                        info->size = 0;
 517                        return (0);     /* no or unknown flash  */
 518        }
 519
 520        value = swap16(addr2[1]);       /* device ID            */
 521        DEBUGF("\nFLASH DEVICEID: %x\n", value);
 522
 523        switch (value) {
 524                case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320B:
 525                        info->flash_id += FLASH_AM320B;
 526                        info->sector_count = 71;
 527                        info->size = 0x00400000;
 528                        break;  /* => 4 MB      */
 529                case (CONFIG_SYS_FLASH_WORD_SIZE)AMD_ID_LV320T:
 530                        info->flash_id += FLASH_AM320T;
 531                        info->sector_count = 71;
 532                        info->size = 0x00400000;
 533                        break;  /* => 4 MB      */
 534                default:
 535                        info->flash_id = FLASH_UNKNOWN;
 536                        return (0);     /* => no or unknown flash */
 537        }
 538
 539        if (info->flash_id & FLASH_BTYPE) {
 540                /* set sector offsets for bottom boot block type        */
 541                info->start[0] = base + 0x00000000;
 542                info->start[1] = base + 0x00002000;
 543                info->start[2] = base + 0x00004000;
 544                info->start[3] = base + 0x00006000;
 545                info->start[4] = base + 0x00008000;
 546                info->start[5] = base + 0x0000a000;
 547                info->start[6] = base + 0x0000c000;
 548                info->start[7] = base + 0x0000e000;
 549
 550                for (i = 8; i < info->sector_count; i++)
 551                        info->start[i] = base + (i * 0x00010000) - 0x00070000;
 552        } else {
 553                /* set sector offsets for top boot block type           */
 554                i = info->sector_count - 1;
 555                info->start[i--] = base + info->size - 0x00002000;
 556                info->start[i--] = base + info->size - 0x00004000;
 557                info->start[i--] = base + info->size - 0x00006000;
 558                info->start[i--] = base + info->size - 0x00008000;
 559                info->start[i--] = base + info->size - 0x0000a000;
 560                info->start[i--] = base + info->size - 0x0000c000;
 561                info->start[i--] = base + info->size - 0x0000e000;
 562
 563                for (; i >= 0; i--)
 564                        info->start[i] = base + i * 0x00010000;
 565        }
 566
 567        /* check for protected sectors */
 568        for (i = 0; i < info->sector_count; i++) {
 569                /* read sector protection at sector address, (A7 .. A0) = 0x02 */
 570                /* D0 = 1 if protected */
 571                addr2 = (volatile CONFIG_SYS_FLASH_WORD_SIZE *)(info->start[i]);
 572
 573                info->protect[i] = addr2[2] & 1;
 574        }
 575
 576        /* issue bank reset to return to read mode */
 577        addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xF000F000;
 578
 579        return (info->size);
 580}
 581
 582static int wait_for_DQ7_16(flash_info_t * info, int sect)
 583{
 584        ulong start, now, last;
 585        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr =
 586                (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
 587
 588        start = get_timer(0);
 589        last = start;
 590        while ((addr[0] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000) !=
 591                        (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000) {
 592                if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 593                        printf("Timeout\n");
 594                        return -1;
 595                }
 596                /* show that we're waiting */
 597                if ((now - last) > 1000) {      /* every second */
 598                        putc('.');
 599                        last = now;
 600                }
 601        }
 602        return 0;
 603}
 604
 605static int flash_erase_16(flash_info_t * info, int s_first, int s_last)
 606{
 607        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
 608        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2;
 609        int flag, prot, sect;
 610
 611        if ((s_first < 0) || (s_first > s_last)) {
 612                if (info->flash_id == FLASH_UNKNOWN)
 613                        printf("- missing\n");
 614                else
 615                        printf("- no sectors to erase\n");
 616                return 1;
 617        }
 618
 619        if (info->flash_id == FLASH_UNKNOWN) {
 620                printf("Can't erase unknown flash type - aborted\n");
 621                return 1;
 622        }
 623
 624        prot = 0;
 625        for (sect = s_first; sect <= s_last; ++sect) {
 626                if (info->protect[sect])
 627                        prot++;
 628        }
 629
 630        if (prot)
 631                printf("- Warning: %d protected sectors will not be erased!",   prot);
 632
 633        printf("\n");
 634
 635        /* Disable interrupts which might cause a timeout here */
 636        flag = disable_interrupts();
 637
 638        /* Start erase on unprotected sectors */
 639        for (sect = s_first; sect <= s_last; sect++) {
 640                if (info->protect[sect] == 0) { /* not protected */
 641                        addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[sect]);
 642
 643                        addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAA00AA00;
 644                        addr[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55005500;
 645                        addr[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000;
 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                        addr2[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x30003000;     /* sector erase */
 649
 650                        /*
 651                         * Wait for each sector to complete, it's more
 652                         * reliable.  According to AMD Spec, you must
 653                         * issue all erase commands within a specified
 654                         * timeout.  This has been seen to fail, especially
 655                         * if printf()s are included (for debug)!!
 656                         */
 657                        wait_for_DQ7_16(info, sect);
 658                }
 659        }
 660
 661        /* re-enable interrupts if necessary */
 662        if (flag)
 663                enable_interrupts();
 664
 665        /* wait at least 80us - let's wait 1 ms */
 666        udelay(1000);
 667
 668        /* reset to read mode */
 669        addr = (CONFIG_SYS_FLASH_WORD_SIZE *) info->start[0];
 670        addr[0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xF000F000;      /* reset bank */
 671
 672        printf(" done\n");
 673        return 0;
 674}
 675
 676static int write_word_16(flash_info_t * info, ulong dest, ulong data)
 677{
 678        volatile CONFIG_SYS_FLASH_WORD_SIZE *addr2 = (CONFIG_SYS_FLASH_WORD_SIZE *) (info->start[0]);
 679        volatile CONFIG_SYS_FLASH_WORD_SIZE *dest2 = (CONFIG_SYS_FLASH_WORD_SIZE *) dest;
 680        ulong *datap = &data;
 681        volatile CONFIG_SYS_FLASH_WORD_SIZE *data2 =
 682                        (volatile CONFIG_SYS_FLASH_WORD_SIZE *)datap;
 683        ulong start;
 684        int i;
 685
 686        /* Check if Flash is (sufficiently) erased */
 687        for (i = 0; i < 4 / sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) {
 688                if ((dest2[i] & swap16(data2[i])) != swap16(data2[i]))
 689                        return (2);
 690        }
 691
 692        for (i = 0; i < 4 / sizeof(CONFIG_SYS_FLASH_WORD_SIZE); i++) {
 693                int flag;
 694
 695                /* Disable interrupts which might cause a timeout here */
 696                flag = disable_interrupts();
 697
 698                addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xAA00AA00;
 699                addr2[CONFIG_SYS_FLASH_ADDR1] = (CONFIG_SYS_FLASH_WORD_SIZE) 0x55005500;
 700                addr2[CONFIG_SYS_FLASH_ADDR0] = (CONFIG_SYS_FLASH_WORD_SIZE) 0xA000A000;
 701
 702                dest2[i] = swap16(data2[i]);
 703
 704                /* re-enable interrupts if necessary */
 705                if (flag)
 706                        enable_interrupts();
 707
 708                /* data polling for D7 */
 709                start = get_timer(0);
 710                while ((dest2[i] & (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000) !=
 711                                (swap16(data2[i]) & (CONFIG_SYS_FLASH_WORD_SIZE) 0x80008000)) {
 712
 713                        if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 714                                return (1);
 715                        }
 716                }
 717        }
 718
 719        return (0);
 720}
 721#endif /* CONFIG_SYS_FLASH_2ND_16BIT_DEV */
 722
 723/*-----------------------------------------------------------------------
 724 * Functions
 725 */
 726static ulong flash_get_size(vu_long * addr, flash_info_t * info);
 727static int write_word(flash_info_t * info, ulong dest, ulong data);
 728
 729/*-----------------------------------------------------------------------
 730 */
 731
 732unsigned long flash_init(void)
 733{
 734        unsigned long total_b = 0;
 735        unsigned long size_b[CONFIG_SYS_MAX_FLASH_BANKS];
 736        unsigned short index = 0;
 737        int i;
 738
 739        DEBUGF("\n");
 740        DEBUGF("FLASH: Index: %d\n", index);
 741
 742        /* Init: no FLASHes known */
 743        for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
 744                flash_info[i].flash_id = FLASH_UNKNOWN;
 745                flash_info[i].sector_count = -1;
 746                flash_info[i].size = 0;
 747
 748                /* check whether the address is 0 */
 749                if (flash_addr_table[index][i] == 0)
 750                        continue;
 751
 752                /* call flash_get_size() to initialize sector address */
 753                size_b[i] = flash_get_size((vu_long *) flash_addr_table[index][i],
 754                                &flash_info[i]);
 755
 756                flash_info[i].size = size_b[i];
 757
 758                if (flash_info[i].flash_id == FLASH_UNKNOWN) {
 759                        printf("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",
 760                                        i+1, size_b[i], size_b[i] << 20);
 761                        flash_info[i].sector_count = -1;
 762                        flash_info[i].size = 0;
 763                }
 764
 765                /* Monitor protection ON by default */
 766                (void)flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_MONITOR_BASE,
 767                                    CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN - 1,
 768                                    &flash_info[i]);
 769#if defined(CONFIG_ENV_IS_IN_FLASH)
 770                (void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR,
 771                                    CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
 772                                    &flash_info[i]);
 773#if defined(CONFIG_ENV_ADDR_REDUND)
 774                (void)flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR_REDUND,
 775                                    CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1,
 776                                    &flash_info[i]);
 777#endif
 778#endif
 779                total_b += flash_info[i].size;
 780        }
 781
 782        return total_b;
 783}
 784#endif /* if defined(CONFIG_CAM5200) && defined(CONFIG_CAM5200_NIOSFLASH) */
 785