uboot/board/o2dnt/flash.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2005
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * flash_real_protect() routine based on boards/alaska/flash.c
   6 * (C) Copyright 2001
   7 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
   8 *
   9 * See file CREDITS for list of people who contributed to this
  10 * project.
  11 *
  12 * This program is free software; you can redistribute it and/or
  13 * modify it under the terms of the GNU General Public License as
  14 * published by the Free Software Foundation; either version 2 of
  15 * the License, or (at your option) any later version.
  16 *
  17 * This program is distributed in the hope that it will be useful,
  18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 * GNU General Public License for more details.
  21 *
  22 * You should have received a copy of the GNU General Public License
  23 * along with this program; if not, write to the Free Software
  24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  25 * MA 02111-1307 USA
  26 */
  27
  28#include <common.h>
  29
  30/* Intel-compatible flash commands */
  31#define INTEL_ERASE     0x20
  32#define INTEL_PROGRAM   0x40
  33#define INTEL_CLEAR     0x50
  34#define INTEL_LOCKBIT   0x60
  35#define INTEL_PROTECT   0x01
  36#define INTEL_STATUS    0x70
  37#define INTEL_READID    0x90
  38#define INTEL_READID    0x90
  39#define INTEL_SUSPEND   0xB0
  40#define INTEL_CONFIRM   0xD0
  41#define INTEL_RESET     0xFF
  42
  43/* Intel-compatible flash status bits */
  44#define INTEL_FINISHED  0x80
  45#define INTEL_OK        0x80
  46
  47typedef unsigned char FLASH_PORT_WIDTH;
  48typedef volatile unsigned char FLASH_PORT_WIDTHV;
  49#define FPW             FLASH_PORT_WIDTH
  50#define FPWV            FLASH_PORT_WIDTHV
  51#define FLASH_ID_MASK   0xFF
  52
  53#define ORMASK(size) ((-size) & OR_AM_MSK)
  54
  55#define FLASH_CYCLE1    0x0555
  56#define FLASH_CYCLE2    0x02aa
  57
  58flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
  59
  60/*-----------------------------------------------------------------------
  61 * Functions
  62 */
  63static ulong flash_get_size(FPWV *addr, flash_info_t *info);
  64static void flash_reset(flash_info_t *info);
  65static flash_info_t *flash_get_info(ulong base);
  66static int write_data (flash_info_t *info, FPWV *dest, FPW data); /* O2D */
  67static void flash_sync_real_protect (flash_info_t * info);
  68static unsigned char intel_sector_protected (flash_info_t *info, ushort sector);
  69
  70/*-----------------------------------------------------------------------
  71 * flash_init()
  72 *
  73 * sets up flash_info and returns size of FLASH (bytes)
  74 */
  75unsigned long flash_init (void)
  76{
  77        unsigned long size = 0;
  78        int i;
  79        extern void flash_preinit(void);
  80        extern void flash_afterinit(ulong);
  81
  82        flash_preinit();
  83
  84        /* Init: no FLASHes known */
  85        for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
  86                memset(&flash_info[i], 0, sizeof(flash_info_t));
  87                flash_info[i].flash_id = FLASH_UNKNOWN;
  88        }
  89
  90        /* Query flash chip */
  91        flash_info[0].size =
  92                flash_get_size((FPW *)CONFIG_SYS_FLASH_BASE, &flash_info[0]);
  93        size += flash_info[0].size;
  94
  95        /* get the h/w and s/w protection status in sync */
  96        flash_sync_real_protect(&flash_info[0]);
  97
  98#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
  99        /* monitor protection ON by default */
 100        flash_protect(FLAG_PROTECT_SET,
 101                        CONFIG_SYS_MONITOR_BASE,
 102                        CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1,
 103                        flash_get_info(CONFIG_SYS_MONITOR_BASE));
 104#endif
 105
 106#ifdef  CONFIG_ENV_IS_IN_FLASH
 107        /* ENV protection ON by default */
 108        flash_protect(FLAG_PROTECT_SET,
 109                        CONFIG_ENV_ADDR,
 110                        CONFIG_ENV_ADDR+CONFIG_ENV_SIZE-1,
 111                        flash_get_info(CONFIG_ENV_ADDR));
 112#endif
 113
 114
 115        flash_afterinit(size);
 116        return (size ? size : 1);
 117}
 118
 119/*-----------------------------------------------------------------------
 120 */
 121static void flash_reset(flash_info_t *info)
 122{
 123        FPWV *base = (FPWV *)(info->start[0]);
 124
 125        /* Put FLASH back in read mode */
 126        if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)
 127                *base = (FPW) INTEL_RESET;      /* Intel Read Mode */
 128}
 129
 130/*-----------------------------------------------------------------------
 131 */
 132
 133static flash_info_t *flash_get_info(ulong base)
 134{
 135        int i;
 136        flash_info_t * info;
 137
 138        for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i ++) {
 139                info = & flash_info[i];
 140                if (info->size &&
 141                                info->start[0] <= base &&
 142                                base <= info->start[0] + info->size - 1)
 143                        break;
 144        }
 145
 146        return (i == CONFIG_SYS_MAX_FLASH_BANKS ? 0 : info);
 147}
 148
 149/*-----------------------------------------------------------------------
 150 */
 151
 152void flash_print_info (flash_info_t *info)
 153{
 154        int i;
 155        uchar *boottype;
 156        uchar *bootletter;
 157        char *fmt;
 158        uchar botbootletter[] = "B";
 159        uchar topbootletter[] = "T";
 160        uchar botboottype[] = "bottom boot sector";
 161        uchar topboottype[] = "top boot sector";
 162
 163        if (info->flash_id == FLASH_UNKNOWN) {
 164                printf ("missing or unknown FLASH type\n");
 165                return;
 166        }
 167
 168        switch (info->flash_id & FLASH_VENDMASK) {
 169                case FLASH_MAN_INTEL:
 170                        printf ("INTEL ");
 171                        break;
 172                default:
 173                        printf ("Unknown Vendor ");
 174                        break;
 175        }
 176
 177        /* check for top or bottom boot, if it applies */
 178        if (info->flash_id & FLASH_BTYPE) {
 179                boottype = botboottype;
 180                bootletter = botbootletter;
 181        } else {
 182                boottype = topboottype;
 183                bootletter = topbootletter;
 184        }
 185
 186        switch (info->flash_id & FLASH_TYPEMASK) {
 187                case FLASH_28F128J3A:
 188                        fmt = "28F128J3 (128 Mbit, uniform sectors)\n";
 189                        break;
 190                default:
 191                        fmt = "Unknown Chip Type\n";
 192                        break;
 193        }
 194
 195        printf (fmt, bootletter, boottype);
 196        printf ("  Size: %ld MB in %d Sectors\n",
 197                        info->size >> 20,
 198                        info->sector_count);
 199
 200        printf ("  Sector Start Addresses:");
 201        for (i=0; i<info->sector_count; ++i) {
 202                if ((i % 5) == 0)
 203                        printf ("\n   ");
 204
 205                printf (" %08lX%s", info->start[i],
 206                                info->protect[i] ? " (RO)" : "     ");
 207        }
 208        printf ("\n");
 209}
 210
 211/*-----------------------------------------------------------------------
 212 */
 213
 214/*
 215 * The following code cannot be run from FLASH!
 216 */
 217ulong flash_get_size (FPWV *addr, flash_info_t *info)
 218{
 219        int i;
 220
 221        /* Write auto select command: read Manufacturer ID */
 222        /* Write auto select command sequence and test FLASH answer */
 223        addr[FLASH_CYCLE1] = (FPW) INTEL_READID;        /* selects Intel or AMD */
 224
 225        /* The manufacturer codes are only 1 byte, so just use 1 byte.
 226         * This works for any bus width and any FLASH device width.
 227         */
 228        udelay(100);
 229        switch (addr[0] & 0xff) {
 230                case (uchar)INTEL_MANUFACT:
 231                        info->flash_id = FLASH_MAN_INTEL;
 232                        break;
 233                default:
 234                        info->flash_id = FLASH_UNKNOWN;
 235                        info->sector_count = 0;
 236                        info->size = 0;
 237                        break;
 238        }
 239
 240        /* Strataflash is configurable to 8/16bit Bus,
 241         * but the Query-Structure is Word-orientated */
 242        if (info->flash_id != FLASH_UNKNOWN) {
 243                switch ((FPW)addr[2]) {
 244                        case (FPW)INTEL_ID_28F128J3:
 245                                info->flash_id += FLASH_28F128J3A;
 246                                info->sector_count = 128;
 247                                info->size = 0x01000000;
 248                                for( i = 0; i < info->sector_count; i++ )
 249                                        info->start[i] = (ulong)addr + (i * 0x20000);
 250                                break;                          /* => Intel Strataflash 16MB */
 251                        default:
 252                                printf("Flash_id != %xd\n", (FPW)addr[2]);
 253                                info->flash_id = FLASH_UNKNOWN;
 254                                info->sector_count = 0;
 255                                info->size = 0;
 256                                return (0);                     /* => no or unknown flash */
 257                }
 258        }
 259
 260        /* Put FLASH back in read mode */
 261        flash_reset(info);
 262
 263        return (info->size);
 264}
 265
 266/*-----------------------------------------------------------------------
 267 */
 268
 269int flash_erase (flash_info_t *info, int s_first, int s_last)
 270{
 271        FPWV *addr;
 272        int flag, prot, sect;
 273        ulong start, now, last;
 274        int rcode = 0;
 275
 276        if ((s_first < 0) || (s_first > s_last)) {
 277                if (info->flash_id == FLASH_UNKNOWN) {
 278                        printf ("- missing\n");
 279                } else {
 280                        printf ("- no sectors to erase\n");
 281                }
 282                return 1;
 283        }
 284
 285        switch (info->flash_id & FLASH_TYPEMASK) {
 286                case FLASH_28F128J3A:
 287                        break;
 288                case FLASH_UNKNOWN:
 289                default:
 290                        printf ("Can't erase unknown flash type %08lx - aborted\n",
 291                                        info->flash_id);
 292                        return 1;
 293        }
 294
 295        prot = 0;
 296        for (sect = s_first; sect <= s_last; ++sect)
 297                if (info->protect[sect])
 298                        prot++;
 299
 300        if (prot)
 301                printf ("- Warning: %d protected sectors will not be erased!",
 302                                prot);
 303
 304        printf ("\n");
 305        last = get_timer(0);
 306
 307        /* Start erase on unprotected sectors */
 308        for (sect = s_first; sect <= s_last && rcode == 0; sect++) {
 309
 310                if (info->protect[sect] != 0)   /* protected, skip it */
 311                        continue;
 312
 313                /* Disable interrupts which might cause a timeout here */
 314                flag = disable_interrupts();
 315
 316                addr = (FPWV *)(info->start[sect]);
 317                *addr = (FPW) INTEL_CLEAR; /* clear status register */
 318                *addr = (FPW) INTEL_ERASE; /* erase setup */
 319                *addr = (FPW) INTEL_CONFIRM; /* erase confirm */
 320
 321                /* re-enable interrupts if necessary */
 322                if (flag)
 323                        enable_interrupts();
 324
 325                start = get_timer(0);
 326
 327                /* wait at least 80us for Intel - let's wait 1 ms */
 328                udelay (1000);
 329
 330                while ((*addr & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) {
 331                        if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 332                                printf ("Timeout\n");
 333                                *addr = (FPW) INTEL_SUSPEND;/* suspend erase */
 334                                flash_reset(info);      /* reset to read mode */
 335                                rcode = 1;              /* failed */
 336                                break;
 337                        }
 338
 339                        /* show that we're waiting */
 340                        if ((get_timer(last)) > CONFIG_SYS_HZ) { /* every second */
 341                                putc ('.');
 342                                last = get_timer(0);
 343                        }
 344                }
 345
 346                flash_reset(info);      /* reset to read mode */
 347        }
 348
 349        printf (" done\n");
 350        return rcode;
 351}
 352
 353/*-----------------------------------------------------------------------
 354 * Copy memory to flash, returns:
 355 * 0 - OK
 356 * 1 - write timeout
 357 * 2 - Flash not erased
 358 */
 359int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
 360{
 361        FPW data = 0;   /* 16 or 32 bit word, matches flash bus width on MPC8XX */
 362        int bytes;      /* number of bytes to program in current word           */
 363        int left;       /* number of bytes left to program                      */
 364        int i, res;
 365
 366        for (left = cnt, res = 0;
 367                        left > 0 && res == 0;
 368                        addr += sizeof(data), left -= sizeof(data) - bytes) {
 369
 370                bytes = addr & (sizeof(data) - 1);
 371                addr &= ~(sizeof(data) - 1);
 372
 373                /* combine source and destination data so can program
 374                 * an entire word of 16 or 32 bits  */
 375                for (i = 0; i < sizeof(data); i++) {
 376                        data <<= 8;
 377                        if (i < bytes || i - bytes >= left )
 378                                data += *((uchar *)addr + i);
 379                        else
 380                                data += *src++;
 381                }
 382
 383                /* write one word to the flash */
 384                switch (info->flash_id & FLASH_VENDMASK) {
 385                        case FLASH_MAN_INTEL:
 386                                res = write_data(info, (FPWV *)addr, data);
 387                                break;
 388                        default:
 389                                /* unknown flash type, error! */
 390                                printf ("missing or unknown FLASH type\n");
 391                                res = 1;        /* not really a timeout, but gives error */
 392                                break;
 393                }
 394        }
 395
 396        return (res);
 397}
 398
 399/*-----------------------------------------------------------------------
 400 * Write a word or halfword to Flash, returns:
 401 * 0 - OK
 402 * 1 - write timeout
 403 * 2 - Flash not erased
 404 */
 405static int write_data (flash_info_t *info, FPWV *dest, FPW data)
 406{
 407        FPWV *addr = dest;
 408        ulong status;
 409        ulong start;
 410        int flag;
 411
 412        /* Check if Flash is (sufficiently) erased */
 413        if ((*addr & data) != data) {
 414                printf ("not erased at %08lx (%x)\n", (ulong) addr, *addr);
 415                return (2);
 416        }
 417        /* Disable interrupts which might cause a timeout here */
 418        flag = disable_interrupts ();
 419
 420        *addr = (FPW) INTEL_PROGRAM;    /* write setup */
 421        *addr = data;
 422
 423        /* arm simple, non interrupt dependent timer */
 424        start = get_timer(0);
 425
 426        /* wait while polling the status register */
 427        while (((status = *addr) & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) {
 428                if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 429                        *addr = (FPW) INTEL_RESET;      /* restore read mode */
 430                        return (1);
 431                }
 432        }
 433
 434        *addr = (FPW) INTEL_RESET;      /* restore read mode */
 435        if (flag)
 436                enable_interrupts();
 437
 438        return (0);
 439}
 440
 441
 442/*-----------------------------------------------------------------------
 443 * Set/Clear sector's lock bit, returns:
 444 * 0 - OK
 445 * 1 - Error (timeout, voltage problems, etc.)
 446 */
 447int flash_real_protect (flash_info_t * info, long sector, int prot)
 448{
 449        ulong start;
 450        int i;
 451        int rc = 0;
 452        FPWV *addr = (FPWV *) (info->start[sector]);
 453        int flag = disable_interrupts ();
 454
 455        *addr = INTEL_CLEAR;    /* Clear status register    */
 456        if (prot) {             /* Set sector lock bit      */
 457                *addr = INTEL_LOCKBIT;  /* Sector lock bit          */
 458                *addr = INTEL_PROTECT;  /* set                      */
 459        } else {                /* Clear sector lock bit    */
 460                *addr = INTEL_LOCKBIT;  /* All sectors lock bits    */
 461                *addr = INTEL_CONFIRM;  /* clear                    */
 462        }
 463
 464        start = get_timer (0);
 465
 466        while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
 467                if (get_timer (start) > CONFIG_SYS_FLASH_UNLOCK_TOUT) {
 468                        printf ("Flash lock bit operation timed out\n");
 469                        rc = 1;
 470                        break;
 471                }
 472        }
 473
 474        if (*addr != INTEL_OK) {
 475                printf ("Flash lock bit operation failed at %08X, CSR=%08X\n",
 476                        (uint) addr, (uint) * addr);
 477                rc = 1;
 478        }
 479
 480        if (!rc)
 481                info->protect[sector] = prot;
 482
 483        /*
 484         * Clear lock bit command clears all sectors lock bits, so
 485         * we have to restore lock bits of protected sectors.
 486         */
 487        if (!prot) {
 488                for (i = 0; i < info->sector_count; i++) {
 489                        if (info->protect[i]) {
 490                                start = get_timer (0);
 491                                addr = (FPWV *) (info->start[i]);
 492                                *addr = INTEL_LOCKBIT;  /* Sector lock bit  */
 493                                *addr = INTEL_PROTECT;  /* set              */
 494                                while ((*addr & INTEL_FINISHED) !=
 495                                       INTEL_FINISHED) {
 496                                        if (get_timer (start) >
 497                                            CONFIG_SYS_FLASH_UNLOCK_TOUT) {
 498                                                printf ("Flash lock bit operation timed out\n");
 499                                                rc = 1;
 500                                                break;
 501                                        }
 502                                }
 503                        }
 504                }
 505        }
 506
 507        if (flag)
 508                enable_interrupts ();
 509
 510        *addr = INTEL_RESET;    /* Reset to read array mode */
 511
 512        return rc;
 513}
 514
 515
 516/*
 517 * This function gets the u-boot flash sector protection status
 518 * (flash_info_t.protect[]) in sync with the sector protection
 519 * status stored in hardware.
 520 */
 521static void flash_sync_real_protect (flash_info_t * info)
 522{
 523        int i;
 524        switch (info->flash_id & FLASH_TYPEMASK) {
 525        case FLASH_28F128J3A:
 526                for (i = 0; i < info->sector_count; ++i) {
 527                        info->protect[i] = intel_sector_protected(info, i);
 528                }
 529                break;
 530        default:
 531                /* no h/w protect support */
 532                break;
 533        }
 534}
 535
 536
 537/*
 538 * checks if "sector" in bank "info" is protected. Should work on intel
 539 * strata flash chips 28FxxxJ3x in 8-bit mode.
 540 * Returns 1 if sector is protected (or timed-out while trying to read
 541 * protection status), 0 if it is not.
 542 */
 543static unsigned char intel_sector_protected (flash_info_t *info, ushort sector)
 544{
 545        FPWV *addr;
 546        FPWV *lock_conf_addr;
 547        ulong start;
 548        unsigned char ret;
 549
 550        /*
 551         * first, wait for the WSM to be finished. The rationale for
 552         * waiting for the WSM to become idle for at most
 553         * CONFIG_SYS_FLASH_ERASE_TOUT is as follows. The WSM can be busy
 554         * because of: (1) erase, (2) program or (3) lock bit
 555         * configuration. So we just wait for the longest timeout of
 556         * the (1)-(3), i.e. the erase timeout.
 557         */
 558
 559        /* wait at least 35ns (W12) before issuing Read Status Register */
 560        udelay(1);
 561        addr = (FPWV *) info->start[sector];
 562        *addr = (FPW) INTEL_STATUS;
 563
 564        start = get_timer (0);
 565        while ((*addr & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) {
 566                if (get_timer (start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 567                        *addr = (FPW) INTEL_RESET; /* restore read mode */
 568                        printf("WSM busy too long, can't get prot status\n");
 569                        return 1;
 570                }
 571        }
 572
 573        /* issue the Read Identifier Codes command */
 574        *addr = (FPW) INTEL_READID;
 575
 576        /* wait at least 35ns (W12) before reading */
 577        udelay(1);
 578
 579        /* Intel example code uses offset of 4 for 8-bit flash */
 580        lock_conf_addr = (FPWV *) info->start[sector] + 4;
 581        ret = (*lock_conf_addr & (FPW) INTEL_PROTECT) ? 1 : 0;
 582
 583        /* put flash back in read mode */
 584        *addr = (FPW) INTEL_RESET;
 585
 586        return ret;
 587}
 588