uboot/board/Marvell/common/flash.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2001
   3 * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
   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/*
  25 * flash.c - flash support for the 512k, 8bit boot flash
  26        and the 8MB 32bit extra flash on the DB64360
  27 *           most of this file was based on the existing U-Boot
  28 *           flash drivers.
  29 *
  30 * written or collected and sometimes rewritten by
  31 * Ingo Assmus <ingo.assmus@keymile.com>
  32 *
  33 */
  34
  35#include <common.h>
  36#include <mpc8xx.h>
  37#include "../include/mv_gen_reg.h"
  38#include "../include/memory.h"
  39#include "intel_flash.h"
  40
  41#define FLASH_ROM       0xFFFD  /* unknown flash type                   */
  42#define FLASH_RAM       0xFFFE  /* unknown flash type                   */
  43#define FLASH_MAN_UNKNOWN 0xFFFF0000
  44
  45/* #define DEBUG */
  46
  47/* Intel flash commands */
  48int flash_erase_intel (flash_info_t * info, int s_first, int s_last);
  49int write_word_intel (bank_addr_t addr, bank_word_t value);
  50
  51flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];    /* info for FLASH chips */
  52
  53/*-----------------------------------------------------------------------
  54 * Functions
  55 */
  56static ulong flash_get_size (int portwidth, vu_long * addr,
  57                             flash_info_t * info);
  58static int write_word (flash_info_t * info, ulong dest, ulong data);
  59static void flash_get_offsets (ulong base, flash_info_t * info);
  60
  61/*-----------------------------------------------------------------------
  62 */
  63
  64unsigned long flash_init (void)
  65{
  66        unsigned int i;
  67        unsigned long size_b0 = 0, size_b1 = 0;
  68        unsigned long base, flash_size;
  69
  70        /* Init: no FLASHes known */
  71        for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
  72                flash_info[i].flash_id = FLASH_UNKNOWN;
  73        }
  74
  75        /* the boot flash */
  76        base = CONFIG_SYS_FLASH_BASE;
  77        size_b0 =
  78                flash_get_size (CONFIG_SYS_BOOT_FLASH_WIDTH, (vu_long *) base,
  79                                &flash_info[0]);
  80
  81        printf ("[%ldkB@%lx] ", size_b0 / 1024, base);
  82
  83        if (flash_info[0].flash_id == FLASH_UNKNOWN) {
  84                printf ("## Unknown FLASH at %08lx: Size = 0x%08lx = %ld MB\n", base, size_b0, size_b0 << 20);
  85        }
  86
  87        base = memoryGetDeviceBaseAddress (CONFIG_SYS_EXTRA_FLASH_DEVICE);
  88/*      base = memoryGetDeviceBaseAddress(DEV_CS3_BASE_ADDR);*/
  89        for (i = 1; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
  90                unsigned long size =
  91                        flash_get_size (CONFIG_SYS_EXTRA_FLASH_WIDTH,
  92                                        (vu_long *) base, &flash_info[i]);
  93
  94                printf ("[%ldMB@%lx] ", size >> 20, base);
  95
  96                if (flash_info[i].flash_id == FLASH_UNKNOWN) {
  97                        if (i == 1) {
  98                                printf ("## Unknown FLASH at %08lx: Size = 0x%08lx = %ld MB\n", base, size_b1, size_b1 << 20);
  99                        }
 100                        break;
 101                }
 102                size_b1 += size;
 103                base += size;
 104        }
 105
 106        flash_size = size_b0 + size_b1;
 107        return flash_size;
 108}
 109
 110/*-----------------------------------------------------------------------
 111 */
 112static void flash_get_offsets (ulong base, flash_info_t * info)
 113{
 114        int i;
 115        int sector_size;
 116
 117        if (!info->sector_count)
 118                return;
 119
 120        /* set up sector start address table */
 121        switch (info->flash_id & FLASH_TYPEMASK) {
 122        case FLASH_AM040:
 123        case FLASH_28F128J3A:
 124        case FLASH_28F640J3A:
 125        case FLASH_RAM:
 126                /* this chip has uniformly spaced sectors */
 127                sector_size = info->size / info->sector_count;
 128                for (i = 0; i < info->sector_count; i++)
 129                        info->start[i] = base + (i * sector_size);
 130                break;
 131        default:
 132                if (info->flash_id & FLASH_BTYPE) {
 133                        /* set sector offsets for bottom boot block type    */
 134                        info->start[0] = base + 0x00000000;
 135                        info->start[1] = base + 0x00008000;
 136                        info->start[2] = base + 0x0000C000;
 137                        info->start[3] = base + 0x00010000;
 138                        for (i = 4; i < info->sector_count; i++) {
 139                                info->start[i] =
 140                                        base + (i * 0x00020000) - 0x00060000;
 141                        }
 142                } else {
 143                        /* set sector offsets for top boot block type               */
 144                        i = info->sector_count - 1;
 145                        info->start[i--] = base + info->size - 0x00008000;
 146                        info->start[i--] = base + info->size - 0x0000C000;
 147                        info->start[i--] = base + info->size - 0x00010000;
 148                        for (; i >= 0; i--) {
 149                                info->start[i] = base + i * 0x00020000;
 150                        }
 151                }
 152        }
 153}
 154
 155/*-----------------------------------------------------------------------
 156 */
 157void flash_print_info (flash_info_t * info)
 158{
 159        int i;
 160
 161        if (info->flash_id == FLASH_UNKNOWN) {
 162                printf ("missing or unknown FLASH type\n");
 163                return;
 164        }
 165
 166        switch (info->flash_id & FLASH_VENDMASK) {
 167        case FLASH_MAN_STM:
 168                printf ("STM ");
 169                break;
 170        case FLASH_MAN_AMD:
 171                printf ("AMD ");
 172                break;
 173        case FLASH_MAN_FUJ:
 174                printf ("FUJITSU ");
 175                break;
 176        case FLASH_MAN_INTEL:
 177                printf ("INTEL ");
 178                break;
 179        default:
 180                printf ("Unknown Vendor ");
 181                break;
 182        }
 183
 184        switch (info->flash_id & FLASH_TYPEMASK) {
 185        case FLASH_AM040:
 186                printf ("AM29LV040B (4 Mbit, bottom boot sect)\n");
 187                break;
 188        case FLASH_AM400B:
 189                printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
 190                break;
 191        case FLASH_AM400T:
 192                printf ("AM29LV400T (4 Mbit, top boot sector)\n");
 193                break;
 194        case FLASH_AM800B:
 195                printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
 196                break;
 197        case FLASH_AM800T:
 198                printf ("AM29LV800T (8 Mbit, top boot sector)\n");
 199                break;
 200        case FLASH_AM160B:
 201                printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
 202                break;
 203        case FLASH_AM160T:
 204                printf ("AM29LV160T (16 Mbit, top boot sector)\n");
 205                break;
 206        case FLASH_AM320B:
 207                printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
 208                break;
 209        case FLASH_AM320T:
 210                printf ("AM29LV320T (32 Mbit, top boot sector)\n");
 211                break;
 212        case FLASH_28F640J3A:
 213                printf ("28F640J3A (64 Mbit)\n");
 214                break;
 215        case FLASH_28F128J3A:
 216                printf ("28F128J3A (128 Mbit)\n");
 217                break;
 218        case FLASH_ROM:
 219                printf ("ROM\n");
 220                break;
 221        case FLASH_RAM:
 222                printf ("RAM\n");
 223                break;
 224        default:
 225                printf ("Unknown Chip Type\n");
 226                break;
 227        }
 228
 229        if ((info->size >> 20) > 0) {
 230                printf ("  Size: %ld MB in %d Sectors\n",
 231                        info->size >> 20, info->sector_count);
 232        } else {
 233                printf ("  Size: %ld kB in %d Sectors\n",
 234                        info->size >> 10, info->sector_count);
 235        }
 236
 237        printf ("  Sector Start Addresses:");
 238        for (i = 0; i < info->sector_count; ++i) {
 239                if ((i % 5) == 0)
 240                        printf ("\n   ");
 241                printf (" %08lX%s",
 242                        info->start[i], info->protect[i] ? " (RO)" : "     ");
 243        }
 244        printf ("\n");
 245        return;
 246}
 247
 248/*-----------------------------------------------------------------------
 249 */
 250
 251
 252/*-----------------------------------------------------------------------
 253 */
 254
 255/*
 256 * The following code cannot be run from FLASH!
 257 */
 258
 259static inline void flash_cmd (int width, volatile unsigned char *addr,
 260                              int offset, unsigned char cmd)
 261{
 262        /* supports 1x8, 1x16, and 2x16 */
 263        /* 2x8 and 4x8 are not supported */
 264        if (width == 4) {
 265                /* assuming chips are in 16 bit mode */
 266                /* 2x16 */
 267                unsigned long cmd32 = (cmd << 16) | cmd;
 268
 269                *(volatile unsigned long *) (addr + offset * 2) = cmd32;
 270        } else {
 271                /* 1x16 or 1x8 */
 272                *(volatile unsigned char *) (addr + offset) = cmd;
 273        }
 274}
 275
 276static ulong
 277flash_get_size (int portwidth, vu_long * addr, flash_info_t * info)
 278{
 279        short i;
 280        volatile unsigned char *caddr = (unsigned char *) addr;
 281        volatile unsigned short *saddr = (unsigned short *) addr;
 282        volatile unsigned long *laddr = (unsigned long *) addr;
 283        char old[2], save;
 284        ulong id = 0, manu = 0, base = (ulong) addr;
 285
 286#ifdef DEBUG
 287        printf ("%s: enter\n", __FUNCTION__);
 288#endif
 289        info->portwidth = portwidth;
 290
 291        save = *caddr;
 292
 293        flash_cmd (portwidth, caddr, 0, 0xf0);
 294        flash_cmd (portwidth, caddr, 0, 0xf0);
 295
 296        udelay (10);
 297
 298        old[0] = caddr[0];
 299        old[1] = caddr[1];
 300
 301
 302        if (old[0] != 0xf0) {
 303                flash_cmd (portwidth, caddr, 0, 0xf0);
 304                flash_cmd (portwidth, caddr, 0, 0xf0);
 305
 306                udelay (10);
 307
 308                if (*caddr == 0xf0) {
 309                        /* this area is ROM */
 310                        *caddr = save;
 311                        info->flash_id = FLASH_ROM + FLASH_MAN_UNKNOWN;
 312                        info->sector_count = 8;
 313                        info->size = 0x80000;
 314                        flash_get_offsets (base, info);
 315                        return info->size;
 316                }
 317        } else {
 318                *caddr = 0;
 319
 320                udelay (10);
 321
 322                if (*caddr == 0) {
 323                        /* this area is RAM */
 324                        *caddr = save;
 325                        info->flash_id = FLASH_RAM + FLASH_MAN_UNKNOWN;
 326                        info->sector_count = 8;
 327                        info->size = 0x80000;
 328                        flash_get_offsets (base, info);
 329                        return info->size;
 330                }
 331                flash_cmd (portwidth, caddr, 0, 0xf0);
 332
 333                udelay (10);
 334        }
 335
 336        /* Write auto select command: read Manufacturer ID */
 337        flash_cmd (portwidth, caddr, 0x555, 0xAA);
 338        flash_cmd (portwidth, caddr, 0x2AA, 0x55);
 339        flash_cmd (portwidth, caddr, 0x555, 0x90);
 340
 341        udelay (10);
 342
 343        if ((caddr[0] == old[0]) && (caddr[1] == old[1])) {
 344
 345                /* this area is ROM */
 346                info->flash_id = FLASH_ROM + FLASH_MAN_UNKNOWN;
 347                info->sector_count = 8;
 348                info->size = 0x80000;
 349                flash_get_offsets (base, info);
 350                return info->size;
 351#ifdef DEBUG
 352        } else {
 353                printf ("%px%d: %02x:%02x -> %02x:%02x\n",
 354                        caddr, portwidth, old[0], old[1], caddr[0], caddr[1]);
 355#endif
 356        }
 357
 358        switch (portwidth) {
 359        case 1:
 360                manu = caddr[0];
 361                manu |= manu << 16;
 362                id = caddr[1];
 363                break;
 364        case 2:
 365                manu = saddr[0];
 366                manu |= manu << 16;
 367                id = saddr[1];
 368                id |= id << 16;
 369                break;
 370        case 4:
 371                manu = laddr[0];
 372                id = laddr[1];
 373                break;
 374        }
 375
 376#ifdef DEBUG
 377        flash_cmd (portwidth, caddr, 0, 0xf0);
 378
 379        printf ("\n%08lx:%08lx:%08lx\n", base, manu, id);
 380        printf ("%08lx %08lx %08lx %08lx\n",
 381                laddr[0], laddr[1], laddr[2], laddr[3]);
 382#endif
 383
 384        switch (manu) {
 385        case STM_MANUFACT:
 386                info->flash_id = FLASH_MAN_STM;
 387                break;
 388        case AMD_MANUFACT:
 389                info->flash_id = FLASH_MAN_AMD;
 390                break;
 391        case FUJ_MANUFACT:
 392                info->flash_id = FLASH_MAN_FUJ;
 393                break;
 394        case INTEL_MANUFACT:
 395                info->flash_id = FLASH_MAN_INTEL;
 396                break;
 397        default:
 398                flash_cmd (portwidth, caddr, 0, 0xf0);
 399
 400                printf ("Unknown Mfr [%08lx]:%08lx\n", manu, id);
 401                info->flash_id = FLASH_UNKNOWN;
 402                info->sector_count = 0;
 403                info->size = 0;
 404                return (0);     /* no or unknown flash  */
 405        }
 406
 407        switch (id) {
 408        case AMD_ID_LV400T:
 409                info->flash_id += FLASH_AM400T;
 410                info->sector_count = 11;
 411                info->size = 0x00100000;
 412                info->chipwidth = 1;
 413                break;          /* => 1 MB      */
 414
 415        case AMD_ID_LV400B:
 416                info->flash_id += FLASH_AM400B;
 417                info->sector_count = 11;
 418                info->size = 0x00100000;
 419                info->chipwidth = 1;
 420                break;          /* => 1 MB      */
 421
 422        case AMD_ID_LV800T:
 423                info->flash_id += FLASH_AM800T;
 424                info->sector_count = 19;
 425                info->size = 0x00200000;
 426                info->chipwidth = 1;
 427                break;          /* => 2 MB      */
 428
 429        case AMD_ID_LV800B:
 430                info->flash_id += FLASH_AM800B;
 431                info->sector_count = 19;
 432                info->size = 0x00200000;
 433                info->chipwidth = 1;
 434                break;          /* => 2 MB      */
 435
 436        case AMD_ID_LV160T:
 437                info->flash_id += FLASH_AM160T;
 438                info->sector_count = 35;
 439                info->size = 0x00400000;
 440                info->chipwidth = 1;
 441                break;          /* => 4 MB      */
 442
 443        case AMD_ID_LV160B:
 444                info->flash_id += FLASH_AM160B;
 445                info->sector_count = 35;
 446                info->size = 0x00400000;
 447                info->chipwidth = 1;
 448                break;          /* => 4 MB      */
 449#if 0                           /* enable when device IDs are available */
 450        case AMD_ID_LV320T:
 451                info->flash_id += FLASH_AM320T;
 452                info->sector_count = 67;
 453                info->size = 0x00800000;
 454                break;          /* => 8 MB      */
 455
 456        case AMD_ID_LV320B:
 457                info->flash_id += FLASH_AM320B;
 458                info->sector_count = 67;
 459                info->size = 0x00800000;
 460                break;          /* => 8 MB      */
 461#endif
 462        case AMD_ID_LV040B:
 463                info->flash_id += FLASH_AM040;
 464                info->sector_count = 8;
 465                info->size = 0x80000;
 466                info->chipwidth = 1;
 467                break;          /* => 512 kB    */
 468
 469        case INTEL_ID_28F640J3A:
 470                info->flash_id += FLASH_28F640J3A;
 471                info->sector_count = 64;
 472                info->size = 128 * 1024 * 64;   /* 128kbytes x 64 blocks */
 473                info->chipwidth = 2;
 474                if (portwidth == 4)
 475                        info->size *= 2;        /* 2x16 */
 476                break;
 477
 478        case INTEL_ID_28F128J3A:
 479                info->flash_id += FLASH_28F128J3A;
 480                info->sector_count = 128;
 481                info->size = 128 * 1024 * 128;  /* 128kbytes x 128 blocks */
 482                info->chipwidth = 2;
 483                if (portwidth == 4)
 484                        info->size *= 2;        /* 2x16 */
 485                break;
 486
 487        default:
 488                flash_cmd (portwidth, caddr, 0, 0xf0);
 489
 490                printf ("Unknown id %lx:[%lx]\n", manu, id);
 491                info->flash_id = FLASH_UNKNOWN;
 492                info->chipwidth = 1;
 493                return (0);     /* => no or unknown flash */
 494
 495        }
 496
 497        flash_get_offsets (base, info);
 498
 499
 500        /* check for protected sectors */
 501        for (i = 0; i < info->sector_count; i++) {
 502                /* read sector protection at sector address, (A7 .. A0)=0x02 */
 503                /* D0 = 1 if protected */
 504                caddr = (volatile unsigned char *) (info->start[i]);
 505                saddr = (volatile unsigned short *) (info->start[i]);
 506                laddr = (volatile unsigned long *) (info->start[i]);
 507                if (portwidth == 1)
 508                        info->protect[i] = caddr[2] & 1;
 509                else if (portwidth == 2)
 510                        info->protect[i] = saddr[2] & 1;
 511                else
 512                        info->protect[i] = laddr[2] & 1;
 513        }
 514
 515        /*
 516         * Prevent writes to uninitialized FLASH.
 517         */
 518        if (info->flash_id != FLASH_UNKNOWN) {
 519                caddr = (volatile unsigned char *) info->start[0];
 520
 521                flash_cmd (portwidth, caddr, 0, 0xF0);  /* reset bank */
 522        }
 523
 524        return (info->size);
 525}
 526
 527int flash_erase (flash_info_t * info, int s_first, int s_last)
 528{
 529        volatile unsigned char *addr = (uchar *) (info->start[0]);
 530        int flag, prot, sect, l_sect;
 531        ulong start, now, last;
 532
 533/* modified to support 2x16 Intel flash */
 534/* Note that the code will not exit on a flash erasure error or timeout */
 535/* but will print and error message and continue processing sectors */
 536/* until they are all erased. */
 537/* 10-16-2002 P. Marchese */
 538        ulong mask;
 539        int timeout;
 540
 541        if (info->portwidth == 4)
 542/*              {
 543                printf ("- Warning: erasing of 32Bit (2*16Bit i.e. 2*28F640J3A) not supported yet !!!! \n");
 544                return 1;
 545                }*/
 546        {
 547                /* make sure it's Intel flash */
 548                if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
 549                        /* yup! it's an Intel flash */
 550                        /* is it 16-bits wide? */
 551                        if (info->chipwidth == 2) {
 552                                /* yup! it's 16-bits wide */
 553                                /* are there any sectors to process? */
 554                                if ((s_first < 0) || (s_first > s_last)) {
 555                                        printf ("Error:  There are no sectors to erase\n");
 556                                        printf ("Either sector %d is less than zero\n", s_first);
 557                                        printf ("or sector %d is greater than sector %d\n", s_first, s_last);
 558                                        return 1;
 559                                }
 560                                /* check for protected sectors */
 561                                prot = 0;
 562                                for (sect = s_first; sect <= s_last; ++sect)
 563                                        if (info->protect[sect])
 564                                                prot++;
 565                                /* if variable "prot" is nonzero, there are protected sectors */
 566                                if (prot)
 567                                        printf ("- Warning: %d protected sectors will not be erased!\n", prot);
 568                                /* reset the flash */
 569                                flash_cmd (info->portwidth, addr, 0,
 570                                           CHIP_CMD_RST);
 571                                /* Disable interrupts which might cause a timeout here */
 572                                flag = disable_interrupts ();
 573                                /* Clear the status register */
 574                                flash_cmd (info->portwidth, addr, 0,
 575                                           CHIP_CMD_CLR_STAT);
 576                                flash_cmd (info->portwidth, addr, 0,
 577                                           CHIP_CMD_RST);
 578                                /* Start erase on unprotected sectors */
 579                                for (sect = s_first; sect <= s_last; sect++) {
 580                                        /* is the sector unprotected? */
 581                                        if (info->protect[sect] == 0) { /* not protected */
 582                                                /* issue the single block erase command, 0x20 */
 583                                                flash_cmd (info->portwidth,
 584                                                           (volatile unsigned
 585                                                            char *) info->
 586                                                           start[sect], 0,
 587                                                           CHIP_CMD_ERASE1);
 588                                                /* issue the erase confirm command, 0xD0 */
 589                                                flash_cmd (info->portwidth,
 590                                                           (volatile unsigned
 591                                                            char *) info->
 592                                                           start[sect], 0,
 593                                                           CHIP_CMD_ERASE2);
 594                                                l_sect = sect;
 595                                                /* re-enable interrupts if necessary */
 596                                                if (flag)
 597                                                        enable_interrupts ();
 598                                                /* poll for erasure completion */
 599                                                /* put flash into read status mode by writing 0x70 to it */
 600                                                flash_cmd (info->portwidth,
 601                                                           addr, 0,
 602                                                           CHIP_CMD_RD_STAT);
 603                                                /* setup the status register mask */
 604                                                mask = CHIP_STAT_RDY |
 605                                                        (CHIP_STAT_RDY << 16);
 606                                                /* init. the timeout counter */
 607                                                start = get_timer (0);
 608                                                /* keep looping while the flash is not ready */
 609                                                /* exit the loop by timing out or the flash */
 610                                                /* becomes ready again */
 611                                                timeout = 0;
 612                                                while ((*
 613                                                        (volatile unsigned
 614                                                         long *) info->
 615                                                        start[sect] & mask) !=
 616                                                       mask) {
 617                                                        /* has the timeout limit been reached? */
 618                                                        if (get_timer (start)
 619                                                            >
 620                                                            CONFIG_SYS_FLASH_ERASE_TOUT)
 621                                                        {
 622                                                                /* timeout limit reached */
 623                                                                printf ("Time out limit reached erasing sector at address %08lx\n", info->start[sect]);
 624                                                                printf ("Continuing with next sector\n");
 625                                                                timeout = 1;
 626                                                                goto timed_out_error;
 627                                                        }
 628                                                        /* put flash into read status mode by writing 0x70 to it */
 629                                                        flash_cmd (info->
 630                                                                   portwidth,
 631                                                                   addr, 0,
 632                                                                   CHIP_CMD_RD_STAT);
 633                                                }
 634                                                /* did we timeout? */
 635                                              timed_out_error:if (timeout == 0)
 636                                                {
 637                                                        /* didn't timeout, so check the status register */
 638                                                        /* create the status mask to check for errors */
 639                                                        mask = CHIP_STAT_ECLBS;
 640                                                        mask = mask | (mask <<
 641                                                                       16);
 642                                                        /* put flash into read status mode by writing 0x70 to it */
 643                                                        flash_cmd (info->
 644                                                                   portwidth,
 645                                                                   addr, 0,
 646                                                                   CHIP_CMD_RD_STAT);
 647                                                        /* are there any errors? */
 648                                                        if ((*
 649                                                             (volatile
 650                                                              unsigned long *)
 651                                                             info->
 652                                                             start[sect] &
 653                                                             mask) != 0) {
 654                                                                /* We got an erasure error */
 655                                                                printf ("Flash erasure error at address 0x%08lx\n", info->start[sect]);
 656                                                                printf ("Continuing with next sector\n");
 657                                                                /* reset the flash */
 658                                                                flash_cmd
 659                                                                        (info->
 660                                                                         portwidth,
 661                                                                         addr,
 662                                                                         0,
 663                                                                         CHIP_CMD_RST);
 664                                                        }
 665                                                }
 666                                                /* erasure completed without errors */
 667                                                /* reset the flash */
 668                                                flash_cmd (info->portwidth,
 669                                                           addr, 0,
 670                                                           CHIP_CMD_RST);
 671                                        }       /* end if not protected */
 672                                }       /* end for loop */
 673                                printf ("Flash erasure done\n");
 674                                return 0;
 675                        } else {
 676                                /* The Intel flash is not 16-bit wide */
 677                                /* print and error message and return */
 678                                /* NOTE: you can add routines here to handle other size flash */
 679                                printf ("Error: Intel flash device is only %d-bits wide\n", info->chipwidth * 8);
 680                                printf ("The erasure code only handles Intel 16-bit wide flash memory\n");
 681                                return 1;
 682                        }
 683                } else {
 684                        /* Not Intel flash so return an error as a write timeout */
 685                        /* NOTE: if it's another type flash, stick its routine here */
 686                        printf ("Error: The flash device is not Intel type\n");
 687                        printf ("The erasure code only supports Intel flash in a 32-bit port width\n");
 688                        return 1;
 689                }
 690        }
 691
 692        /* end 32-bit wide flash code */
 693        if ((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM)
 694                return 1;       /* Rom can not be erased */
 695        if ((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) {   /* RAM just copy 0s to RAM */
 696                for (sect = s_first; sect <= s_last; sect++) {
 697                        int sector_size = info->size / info->sector_count;
 698
 699                        addr = (uchar *) (info->start[sect]);
 700                        memset ((void *) addr, 0, sector_size);
 701                }
 702                return 0;
 703        }
 704
 705        if ((s_first < 0) || (s_first > s_last)) {
 706                if (info->flash_id == FLASH_UNKNOWN) {
 707                        printf ("- missing\n");
 708                } else {
 709                        printf ("- no sectors to erase\n");
 710                }
 711                return 1;
 712        }
 713
 714        if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {     /* Intel works spezial */
 715                return flash_erase_intel (info,
 716                                          (unsigned short) s_first,
 717                                          (unsigned short) s_last);
 718        }
 719#if 0
 720        if ((info->flash_id == FLASH_UNKNOWN) ||        /* Flash is unknown to PPCBoot */
 721            (info->flash_id > FLASH_AMD_COMP)) {
 722                printf ("Can't erase unknown flash type %08lx - aborted\n",
 723                        info->flash_id);
 724                return 1;
 725        }
 726#endif
 727
 728        prot = 0;
 729        for (sect = s_first; sect <= s_last; ++sect) {
 730                if (info->protect[sect]) {
 731                        prot++;
 732                }
 733        }
 734
 735        if (prot) {
 736                printf ("- Warning: %d protected sectors will not be erased!\n", prot);
 737        } else {
 738                printf ("\n");
 739        }
 740
 741        l_sect = -1;
 742
 743        /* Disable interrupts which might cause a timeout here */
 744        flag = disable_interrupts ();
 745
 746        flash_cmd (info->portwidth, addr, 0x555, 0xAA); /* start erase routine */
 747        flash_cmd (info->portwidth, addr, 0x2AA, 0x55);
 748        flash_cmd (info->portwidth, addr, 0x555, 0x80);
 749        flash_cmd (info->portwidth, addr, 0x555, 0xAA);
 750        flash_cmd (info->portwidth, addr, 0x2AA, 0x55);
 751
 752        /* Start erase on unprotected sectors */
 753        for (sect = s_first; sect <= s_last; sect++) {
 754                if (info->protect[sect] == 0) { /* not protected */
 755                        addr = (uchar *) (info->start[sect]);
 756                        flash_cmd (info->portwidth, addr, 0, 0x30);
 757                        l_sect = sect;
 758                }
 759        }
 760
 761        /* re-enable interrupts if necessary */
 762        if (flag)
 763                enable_interrupts ();
 764
 765        /* wait at least 80us - let's wait 1 ms */
 766        udelay (1000);
 767
 768        /*
 769         * We wait for the last triggered sector
 770         */
 771        if (l_sect < 0)
 772                goto DONE;
 773
 774        start = get_timer (0);
 775        last = start;
 776        addr = (volatile unsigned char *) (info->start[l_sect]);
 777        /* broken for 2x16: TODO */
 778        while ((addr[0] & 0x80) != 0x80) {
 779                if ((now = get_timer (start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 780                        printf ("Timeout\n");
 781                        return 1;
 782                }
 783                /* show that we're waiting */
 784                if ((now - last) > 1000) {      /* every second */
 785                        putc ('.');
 786                        last = now;
 787                }
 788        }
 789
 790      DONE:
 791        /* reset to read mode */
 792        addr = (volatile unsigned char *) info->start[0];
 793        flash_cmd (info->portwidth, addr, 0, 0xf0);
 794        flash_cmd (info->portwidth, addr, 0, 0xf0);
 795
 796        printf (" done\n");
 797        return 0;
 798}
 799
 800/*-----------------------------------------------------------------------
 801 * Copy memory to flash, returns:
 802 * 0 - OK
 803 * 1 - write timeout
 804 * 2 - Flash not erased
 805 */
 806
 807/* broken for 2x16: TODO */
 808int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 809{
 810        ulong cp, wp, data;
 811        int i, l, rc;
 812
 813/* Commented out since the below code should work for 32-bit(2x 16 flash) */
 814/* 10-16-2002 P. Marchese */
 815/*      if(info->portwidth==4) return 1; */
 816/*      if(info->portwidth==4) {
 817                printf ("- Warning: writting of 32Bit (2*16Bit i.e. 2*28F640J3A) not supported yet !!!! \n");
 818                return 1;
 819                }*/
 820
 821        if ((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM)
 822                return 0;
 823        if ((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) {
 824                memcpy ((void *) addr, src, cnt);
 825                return 0;
 826        }
 827
 828        wp = (addr & ~3);       /* get lower word aligned address */
 829
 830        /*
 831         * handle unaligned start bytes
 832         */
 833        if ((l = addr - wp) != 0) {
 834                data = 0;
 835                for (i = 0, cp = wp; i < l; ++i, ++cp) {
 836                        data = (data << 8) | (*(uchar *) cp);
 837                }
 838                for (; i < 4 && cnt > 0; ++i) {
 839                        data = (data << 8) | *src++;
 840                        --cnt;
 841                        ++cp;
 842                }
 843                for (; cnt == 0 && i < 4; ++i, ++cp) {
 844                        data = (data << 8) | (*(uchar *) cp);
 845                }
 846
 847                if ((rc = write_word (info, wp, data)) != 0) {
 848                        return (rc);
 849                }
 850                wp += 4;
 851        }
 852
 853        /*
 854         * handle word aligned part
 855         */
 856        while (cnt >= 4) {
 857                data = 0;
 858                for (i = 0; i < 4; ++i) {
 859                        data = (data << 8) | *src++;
 860                }
 861                if ((rc = write_word (info, wp, data)) != 0) {
 862                        return (rc);
 863                }
 864                wp += 4;
 865                cnt -= 4;
 866        }
 867
 868        if (cnt == 0) {
 869                return (0);
 870        }
 871
 872        /*
 873         * handle unaligned tail bytes
 874         */
 875        data = 0;
 876        for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) {
 877                data = (data << 8) | *src++;
 878                --cnt;
 879        }
 880        for (; i < 4; ++i, ++cp) {
 881                data = (data << 8) | (*(uchar *) cp);
 882        }
 883
 884        return (write_word (info, wp, data));
 885}
 886
 887/*-----------------------------------------------------------------------
 888 * Write a word to Flash, returns:
 889 * 0 - OK
 890 * 1 - write timeout
 891 * 2 - Flash not erased
 892 */
 893/* broken for 2x16: TODO */
 894static int write_word (flash_info_t * info, ulong dest, ulong data)
 895{
 896        volatile unsigned char *addr = (uchar *) (info->start[0]);
 897        ulong start;
 898        int flag, i;
 899        ulong mask;
 900
 901/* modified so that it handles 32-bit(2x16 Intel flash programming */
 902/* 10-16-2002 P. Marchese */
 903
 904        if (info->portwidth == 4)
 905/*              {
 906                printf ("- Warning: writting of 32Bit (2*16Bit i.e. 2*28F640J3A) not supported yet !!!! \n");
 907                return 1;
 908                }*/
 909        {
 910                /* make sure it's Intel flash */
 911                if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
 912                        /* yup! it's an Intel flash */
 913                        /* is it 16-bits wide? */
 914                        if (info->chipwidth == 2) {
 915                                /* yup! it's 16-bits wide */
 916                                /* so we know how to program it */
 917                                /* reset the flash */
 918                                flash_cmd (info->portwidth, addr, 0,
 919                                           CHIP_CMD_RST);
 920                                /* Disable interrupts which might cause a timeout here */
 921                                flag = disable_interrupts ();
 922                                /* Clear the status register */
 923                                flash_cmd (info->portwidth, addr, 0,
 924                                           CHIP_CMD_CLR_STAT);
 925                                flash_cmd (info->portwidth, addr, 0,
 926                                           CHIP_CMD_RST);
 927                                /* 1st cycle of word/byte program */
 928                                /* write 0x40 to the location to program */
 929                                flash_cmd (info->portwidth, (uchar *) dest, 0,
 930                                           CHIP_CMD_PROG);
 931                                /* 2nd cycle of word/byte program */
 932                                /* write the data to the destination address */
 933                                *(ulong *) dest = data;
 934                                /* re-enable interrupts if necessary */
 935                                if (flag)
 936                                        enable_interrupts ();
 937                                /* setup the status register mask */
 938                                mask = CHIP_STAT_RDY | (CHIP_STAT_RDY << 16);
 939                                /* put flash into read status mode by writing 0x70 to it */
 940                                flash_cmd (info->portwidth, addr, 0,
 941                                           CHIP_CMD_RD_STAT);
 942                                /* init. the timeout counter */
 943                                start = get_timer (0);
 944                                /* keep looping while the flash is not ready */
 945                                /* exit the loop by timing out or the flash */
 946                                /* becomes ready again */
 947/* 11-13-2002 Paul Marchese */
 948/* modified while loop conditional statement */
 949/* because we were always timing out.  */
 950/* there is a type mismatch, "addr[0]" */
 951/* returns a byte but "mask" is a 32-bit value */
 952                                while ((*(volatile unsigned long *) info->
 953                                        start[0] & mask) != mask)
 954/* original code */
 955/* while (addr[0] & mask) != mask) */
 956                                {
 957                                        /* has the timeout limit been reached? */
 958                                        if (get_timer (start) >
 959                                            CONFIG_SYS_FLASH_WRITE_TOUT) {
 960                                                /* timeout limit reached */
 961                                                printf ("Time out limit reached programming address %08lx with data %08lx\n", dest, data);
 962                                                /* reset the flash */
 963                                                flash_cmd (info->portwidth,
 964                                                           addr, 0,
 965                                                           CHIP_CMD_RST);
 966                                                return (1);
 967                                        }
 968                                        /* put flash into read status mode by writing 0x70 to it */
 969                                        flash_cmd (info->portwidth, addr, 0,
 970                                                   CHIP_CMD_RD_STAT);
 971                                }
 972                                /* flash is ready, so check the status */
 973                                /* create the status mask to check for errors */
 974                                mask = CHIP_STAT_DPS | CHIP_STAT_VPPS |
 975                                        CHIP_STAT_PSLBS;
 976                                mask = mask | (mask << 16);
 977                                /* put flash into read status mode by writing 0x70 to it */
 978                                flash_cmd (info->portwidth, addr, 0,
 979                                           CHIP_CMD_RD_STAT);
 980                                /* are there any errors? */
 981                                if ((addr[0] & mask) != 0) {
 982                                        /* We got a one of the following errors: */
 983                                        /* Voltage range, Device protect, or programming */
 984                                        /* return the error as a device timeout */
 985                                        /* put flash into read status mode by writing 0x70 to it */
 986                                        flash_cmd (info->portwidth, addr, 0,
 987                                                   CHIP_CMD_RD_STAT);
 988                                        printf ("Flash programming error at address 0x%08lx\n", dest);
 989                                        printf ("Flash status register contains 0x%08lx\n", (unsigned long) addr[0]);
 990                                        /* reset the flash */
 991                                        flash_cmd (info->portwidth, addr, 0,
 992                                                   CHIP_CMD_RST);
 993                                        return 1;
 994                                }
 995                                /* write completed without errors */
 996                                /* reset the flash */
 997                                flash_cmd (info->portwidth, addr, 0,
 998                                           CHIP_CMD_RST);
 999                                return 0;
1000                        } else {
1001                                /* it's not 16-bits wide, so return an error as a write timeout */
1002                                /* NOTE: you can add routines here to handle other size flash */
1003                                printf ("Error: Intel flash device is only %d-bits wide\n", info->chipwidth * 8);
1004                                printf ("The write code only handles Intel 16-bit wide flash memory\n");
1005                                return 1;
1006                        }
1007                } else {
1008                        /* not Intel flash so return an error as a write timeout */
1009                        /* NOTE: if it's another type flash, stick its routine here */
1010                        printf ("Error: The flash device is not Intel type\n");
1011                        printf ("The code only supports Intel flash in a 32-bit port width\n");
1012                        return 1;
1013                }
1014        }
1015
1016        /* end of 32-bit flash code */
1017        if ((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM)
1018                return 1;
1019        if ((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) {
1020                *(unsigned long *) dest = data;
1021                return 0;
1022        }
1023        if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
1024                unsigned short low = data & 0xffff;
1025                unsigned short hi = (data >> 16) & 0xffff;
1026                int ret = write_word_intel ((bank_addr_t) dest, hi);
1027
1028                if (!ret)
1029                        ret = write_word_intel ((bank_addr_t) (dest + 2),
1030                                                low);
1031
1032                return ret;
1033        }
1034
1035        /* Check if Flash is (sufficiently) erased */
1036        if ((*((vu_long *) dest) & data) != data) {
1037                return (2);
1038        }
1039        /* Disable interrupts which might cause a timeout here */
1040        flag = disable_interrupts ();
1041
1042        /* first, perform an unlock bypass command to speed up flash writes */
1043        addr[0x555] = 0xAA;
1044        addr[0x2AA] = 0x55;
1045        addr[0x555] = 0x20;
1046
1047        /* write each byte out */
1048        for (i = 0; i < 4; i++) {
1049                char *data_ch = (char *) &data;
1050
1051                addr[0] = 0xA0;
1052                *(((char *) dest) + i) = data_ch[i];
1053                udelay (10);    /* XXX */
1054        }
1055
1056        /* we're done, now do an unlock bypass reset */
1057        addr[0] = 0x90;
1058        addr[0] = 0x00;
1059
1060        /* re-enable interrupts if necessary */
1061        if (flag)
1062                enable_interrupts ();
1063
1064        /* data polling for D7 */
1065        start = get_timer (0);
1066        while ((*((vu_long *) dest) & 0x00800080) != (data & 0x00800080)) {
1067                if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
1068                        return (1);
1069                }
1070        }
1071        return (0);
1072}
1073