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