uboot/board/cpu87/flash.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2001-2005
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * Flash Routines for Intel devices
   6 *
   7 *--------------------------------------------------------------------
   8 * See file CREDITS for list of people who contributed to this
   9 * project.
  10 *
  11 * This program is free software; you can redistribute it and/or
  12 * modify it under the terms of the GNU General Public License as
  13 * published by the Free Software Foundation; either version 2 of
  14 * the License, or (at your option) any later version.
  15 *
  16 * This program is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19 * GNU General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24 * MA 02111-1307 USA
  25 */
  26
  27#include <common.h>
  28#include <mpc8xx.h>
  29#include "cpu87.h"
  30
  31flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
  32
  33/*-----------------------------------------------------------------------
  34 */
  35ulong flash_int_get_size (volatile unsigned long *baseaddr,
  36                                          flash_info_t * info)
  37{
  38        short i;
  39        unsigned long flashtest_h, flashtest_l;
  40
  41        info->sector_count = info->size = 0;
  42        info->flash_id = FLASH_UNKNOWN;
  43
  44        /* Write identify command sequence and test FLASH answer
  45         */
  46        baseaddr[0] = 0x00900090;
  47        baseaddr[1] = 0x00900090;
  48
  49        flashtest_h = baseaddr[0];      /* manufacturer ID      */
  50        flashtest_l = baseaddr[1];
  51
  52        if (flashtest_h != INTEL_MANUFACT || flashtest_l != INTEL_MANUFACT)
  53                return (0);             /* no or unknown flash  */
  54
  55        flashtest_h = baseaddr[2];      /* device ID            */
  56        flashtest_l = baseaddr[3];
  57
  58        if (flashtest_h != flashtest_l)
  59                return (0);
  60
  61        switch (flashtest_h) {
  62        case INTEL_ID_28F160C3B:
  63                info->flash_id = FLASH_28F160C3B;
  64                info->sector_count = 39;
  65                info->size = 0x00800000;        /* 4 * 2 MB = 8 MB      */
  66                break;
  67        case INTEL_ID_28F160F3B:
  68                info->flash_id = FLASH_28F160F3B;
  69                info->sector_count = 39;
  70                info->size = 0x00800000;        /* 4 * 2 MB = 8 MB      */
  71                break;
  72        case INTEL_ID_28F640C3B:
  73                info->flash_id = FLASH_28F640C3B;
  74                info->sector_count = 135;
  75                info->size = 0x02000000;        /* 16 * 2 MB = 32 MB    */
  76                break;
  77        default:
  78                return (0);                     /* no or unknown flash  */
  79        }
  80
  81        info->flash_id |= INTEL_MANUFACT << 16; /* set manufacturer offset */
  82
  83        if (info->flash_id & FLASH_BTYPE) {
  84                volatile unsigned long *tmp = baseaddr;
  85
  86                /* set up sector start adress table (bottom sector type)
  87                 * AND unlock the sectors (if our chip is 160C3)
  88                 */
  89                for (i = 0; i < info->sector_count; i++) {
  90                        if (((info->flash_id & FLASH_TYPEMASK) == FLASH_28F160C3B) ||
  91                            ((info->flash_id & FLASH_TYPEMASK) == FLASH_28F640C3B)) {
  92                                tmp[0] = 0x00600060;
  93                                tmp[1] = 0x00600060;
  94                                tmp[0] = 0x00D000D0;
  95                                tmp[1] = 0x00D000D0;
  96                        }
  97                        info->start[i] = (uint) tmp;
  98                        tmp += i < 8 ? 0x2000 : 0x10000; /* pointer arith       */
  99                }
 100        }
 101
 102        memset (info->protect, 0, info->sector_count);
 103
 104        baseaddr[0] = 0x00FF00FF;
 105        baseaddr[1] = 0x00FF00FF;
 106
 107        return (info->size);
 108}
 109
 110static ulong flash_amd_get_size (vu_char *addr, flash_info_t *info)
 111{
 112        short i;
 113        uchar vendor, devid;
 114        ulong base = (ulong)addr;
 115
 116        /* Write auto select command: read Manufacturer ID */
 117        addr[0x0555] = 0xAA;
 118        addr[0x02AA] = 0x55;
 119        addr[0x0555] = 0x90;
 120
 121        udelay(1000);
 122
 123        vendor = addr[0];
 124        devid = addr[1] & 0xff;
 125
 126        /* only support AMD */
 127        if (vendor != 0x01) {
 128                return 0;
 129        }
 130
 131        vendor &= 0xf;
 132        devid &= 0xff;
 133
 134        if (devid == AMD_ID_F040B) {
 135                info->flash_id     = vendor << 16 | devid;
 136                info->sector_count = 8;
 137                info->size         = info->sector_count * 0x10000;
 138        }
 139        else if (devid == AMD_ID_F080B) {
 140                info->flash_id     = vendor << 16 | devid;
 141                info->sector_count = 16;
 142                info->size         = 4 * info->sector_count * 0x10000;
 143        }
 144        else if (devid == AMD_ID_F016D) {
 145                info->flash_id     = vendor << 16 | devid;
 146                info->sector_count = 32;
 147                info->size         = 4 * info->sector_count * 0x10000;
 148        }
 149        else {
 150                printf ("## Unknown Flash Type: %02x\n", devid);
 151                return 0;
 152        }
 153
 154        /* check for protected sectors */
 155        for (i = 0; i < info->sector_count; i++) {
 156                /* sector base address */
 157                info->start[i] = base + i * (info->size / info->sector_count);
 158                /* read sector protection at sector address, (A7 .. A0) = 0x02 */
 159                /* D0 = 1 if protected */
 160                addr = (volatile unsigned char *)(info->start[i]);
 161                info->protect[i] = addr[2] & 1;
 162        }
 163
 164        /*
 165         * Prevent writes to uninitialized FLASH.
 166         */
 167        if (info->flash_id != FLASH_UNKNOWN) {
 168                addr = (vu_char *)info->start[0];
 169                addr[0] = 0xF0; /* reset bank */
 170        }
 171
 172        return (info->size);
 173}
 174
 175
 176/*-----------------------------------------------------------------------
 177 */
 178unsigned long flash_init (void)
 179{
 180        unsigned long size_b0 = 0;
 181        unsigned long size_b1 = 0;
 182        int i;
 183
 184        /* Init: no FLASHes known
 185         */
 186        for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
 187                flash_info[i].flash_id = FLASH_UNKNOWN;
 188        }
 189
 190        /* Disable flash protection */
 191        CPU86_BCR |= (CPU86_BCR_FWPT | CPU86_BCR_FWRE);
 192
 193        /* Static FLASH Bank configuration here (only one bank) */
 194
 195        size_b0 = flash_int_get_size ((ulong *) CONFIG_SYS_FLASH_BASE, &flash_info[0]);
 196        size_b1 = flash_amd_get_size ((uchar *) CONFIG_SYS_BOOTROM_BASE, &flash_info[1]);
 197
 198        if (size_b0 > 0 || size_b1 > 0) {
 199
 200                printf("(");
 201
 202                if (size_b0 > 0) {
 203                        puts ("Bank#1 - ");
 204                        print_size (size_b0, (size_b1 > 0) ? ", " : ") ");
 205                }
 206
 207                if (size_b1 > 0) {
 208                        puts ("Bank#2 - ");
 209                        print_size (size_b1, ") ");
 210                }
 211        }
 212        else {
 213                printf ("## No FLASH found.\n");
 214                return 0;
 215        }
 216        /* protect monitor and environment sectors
 217         */
 218
 219#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_BOOTROM_BASE
 220        if (size_b1) {
 221                /* If U-Boot is booted from ROM the CONFIG_SYS_MONITOR_BASE > CONFIG_SYS_FLASH_BASE
 222                 * but we shouldn't protect it.
 223                 */
 224
 225                flash_protect  (FLAG_PROTECT_SET,
 226                                CONFIG_SYS_MONITOR_BASE,
 227                                CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1, &flash_info[1]
 228                );
 229        }
 230#else
 231#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
 232        flash_protect (FLAG_PROTECT_SET,
 233                       CONFIG_SYS_MONITOR_BASE,
 234                       CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1, &flash_info[0]
 235        );
 236#endif
 237#endif
 238
 239#if defined(CONFIG_ENV_IS_IN_FLASH) && defined(CONFIG_ENV_ADDR)
 240# ifndef  CONFIG_ENV_SIZE
 241#  define CONFIG_ENV_SIZE       CONFIG_ENV_SECT_SIZE
 242# endif
 243# if CONFIG_ENV_ADDR >= CONFIG_SYS_BOOTROM_BASE
 244        if (size_b1) {
 245                flash_protect (FLAG_PROTECT_SET,
 246                                CONFIG_ENV_ADDR,
 247                                CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[1]);
 248        }
 249# else
 250        flash_protect (FLAG_PROTECT_SET,
 251                       CONFIG_ENV_ADDR,
 252                       CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
 253# endif
 254#endif
 255
 256        return (size_b0 + size_b1);
 257}
 258
 259/*-----------------------------------------------------------------------
 260 */
 261void flash_print_info (flash_info_t * info)
 262{
 263        int i;
 264
 265        if (info->flash_id == FLASH_UNKNOWN) {
 266                printf ("missing or unknown FLASH type\n");
 267                return;
 268        }
 269
 270        switch ((info->flash_id >> 16) & 0xff) {
 271        case 0x89:
 272                printf ("INTEL ");
 273                break;
 274        case 0x1:
 275                printf ("AMD ");
 276                break;
 277        default:
 278                printf ("Unknown Vendor ");
 279                break;
 280        }
 281
 282        switch (info->flash_id & FLASH_TYPEMASK) {
 283        case FLASH_28F160C3B:
 284                printf ("28F160C3B (16 Mbit, bottom sector)\n");
 285                break;
 286        case FLASH_28F160F3B:
 287                printf ("28F160F3B (16 Mbit, bottom sector)\n");
 288                break;
 289        case FLASH_28F640C3B:
 290                printf ("28F640C3B (64 M, bottom sector)\n");
 291                break;
 292        case AMD_ID_F040B:
 293                printf ("AM29F040B (4 Mbit)\n");
 294                break;
 295        default:
 296                printf ("Unknown Chip Type\n");
 297                break;
 298        }
 299
 300        if (info->size < 0x100000)
 301                printf ("  Size: %ld KB in %d Sectors\n",
 302                                info->size >> 10, info->sector_count);
 303        else
 304                printf ("  Size: %ld MB in %d Sectors\n",
 305                                info->size >> 20, info->sector_count);
 306
 307        printf ("  Sector Start Addresses:");
 308        for (i = 0; i < info->sector_count; ++i) {
 309                if ((i % 5) == 0)
 310                        printf ("\n   ");
 311                printf (" %08lX%s",
 312                        info->start[i],
 313                        info->protect[i] ? " (RO)" : "     "
 314                );
 315        }
 316        printf ("\n");
 317}
 318
 319/*-----------------------------------------------------------------------
 320 */
 321int flash_erase (flash_info_t * info, int s_first, int s_last)
 322{
 323        vu_char *addr = (vu_char *)(info->start[0]);
 324        int flag, prot, sect, l_sect;
 325        ulong start, now, last;
 326
 327        if ((s_first < 0) || (s_first > s_last)) {
 328                if (info->flash_id == FLASH_UNKNOWN) {
 329                        printf ("- missing\n");
 330                } else {
 331                        printf ("- no sectors to erase\n");
 332                }
 333                return 1;
 334        }
 335
 336        prot = 0;
 337        for (sect = s_first; sect <= s_last; sect++) {
 338                if (info->protect[sect])
 339                        prot++;
 340        }
 341
 342        if (prot) {
 343                printf ("- Warning: %d protected sectors will not be erased!\n",
 344                                prot);
 345        } else {
 346                printf ("\n");
 347        }
 348
 349        /* Check the type of erased flash
 350         */
 351        if (info->flash_id >> 16 == 0x1) {
 352                /* Erase AMD flash
 353                 */
 354                l_sect = -1;
 355
 356                /* Disable interrupts which might cause a timeout here */
 357                flag = disable_interrupts();
 358
 359                addr[0x0555] = 0xAA;
 360                addr[0x02AA] = 0x55;
 361                addr[0x0555] = 0x80;
 362                addr[0x0555] = 0xAA;
 363                addr[0x02AA] = 0x55;
 364
 365                /* wait at least 80us - let's wait 1 ms */
 366                udelay (1000);
 367
 368                /* Start erase on unprotected sectors */
 369                for (sect = s_first; sect<=s_last; sect++) {
 370                        if (info->protect[sect] == 0) { /* not protected */
 371                                addr = (vu_char *)(info->start[sect]);
 372                                addr[0] = 0x30;
 373                                l_sect = sect;
 374                        }
 375                }
 376
 377                /* re-enable interrupts if necessary */
 378                if (flag)
 379                        enable_interrupts();
 380
 381                /* wait at least 80us - let's wait 1 ms */
 382                udelay (1000);
 383
 384                /*
 385                 * We wait for the last triggered sector
 386                 */
 387                if (l_sect < 0)
 388                        goto AMD_DONE;
 389
 390                start = get_timer (0);
 391                last  = start;
 392                addr = (vu_char *)(info->start[l_sect]);
 393                while ((addr[0] & 0x80) != 0x80) {
 394                        if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 395                                printf ("Timeout\n");
 396                                return 1;
 397                        }
 398                        /* show that we're waiting */
 399                        if ((now - last) > 1000) {      /* every second */
 400                                serial_putc ('.');
 401                                last = now;
 402                        }
 403                }
 404
 405AMD_DONE:
 406                /* reset to read mode */
 407                addr = (volatile unsigned char *)info->start[0];
 408                addr[0] = 0xF0;     /* reset bank */
 409
 410        } else {
 411                /* Erase Intel flash
 412                 */
 413
 414                /* Start erase on unprotected sectors
 415                 */
 416                for (sect = s_first; sect <= s_last; sect++) {
 417                        volatile ulong *addr =
 418                                (volatile unsigned long *) info->start[sect];
 419
 420                        start = get_timer (0);
 421                        last = start;
 422                        if (info->protect[sect] == 0) {
 423                        /* Disable interrupts which might cause a timeout here
 424                         */
 425                                flag = disable_interrupts ();
 426
 427                                /* Erase the block
 428                                 */
 429                                addr[0] = 0x00200020;
 430                                addr[1] = 0x00200020;
 431                                addr[0] = 0x00D000D0;
 432                                addr[1] = 0x00D000D0;
 433
 434                                /* re-enable interrupts if necessary
 435                                 */
 436                                if (flag)
 437                                        enable_interrupts ();
 438
 439                                /* wait at least 80us - let's wait 1 ms
 440                                 */
 441                                udelay (1000);
 442
 443                                last = start;
 444                                while ((addr[0] & 0x00800080) != 0x00800080 ||
 445                                   (addr[1] & 0x00800080) != 0x00800080) {
 446                                        if ((now = get_timer (start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 447                                                printf ("Timeout (erase suspended!)\n");
 448                                                /* Suspend erase
 449                                                 */
 450                                                addr[0] = 0x00B000B0;
 451                                                addr[1] = 0x00B000B0;
 452                                                goto DONE;
 453                                        }
 454                                        /* show that we're waiting
 455                                         */
 456                                        if ((now - last) > 1000) {      /* every second */
 457                                                serial_putc ('.');
 458                                                last = now;
 459                                        }
 460                                }
 461                                if (addr[0] & 0x00220022 || addr[1] & 0x00220022) {
 462                                        printf ("*** ERROR: erase failed!\n");
 463                                        goto DONE;
 464                                }
 465                        }
 466                        /* Clear status register and reset to read mode
 467                         */
 468                        addr[0] = 0x00500050;
 469                        addr[1] = 0x00500050;
 470                        addr[0] = 0x00FF00FF;
 471                        addr[1] = 0x00FF00FF;
 472                }
 473        }
 474
 475        printf (" done\n");
 476
 477DONE:
 478        return 0;
 479}
 480
 481static int write_word (flash_info_t *, volatile unsigned long *, ulong);
 482static int write_byte (flash_info_t *info, ulong dest, uchar data);
 483
 484/*-----------------------------------------------------------------------
 485 * Copy memory to flash, returns:
 486 * 0 - OK
 487 * 1 - write timeout
 488 * 2 - Flash not erased
 489 */
 490int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 491{
 492        ulong v;
 493        int i, l, rc, cc = cnt, res = 0;
 494
 495        if (info->flash_id >> 16 == 0x1) {
 496
 497                /* Write to AMD 8-bit flash
 498                 */
 499                while (cnt > 0) {
 500                        if ((rc = write_byte(info, addr, *src)) != 0) {
 501                                return (rc);
 502                        }
 503                        addr++;
 504                        src++;
 505                        cnt--;
 506                }
 507
 508                return (0);
 509        } else {
 510
 511                /* Write to Intel 64-bit flash
 512                 */
 513                for (v=0; cc > 0; addr += 4, cc -= 4 - l) {
 514                        l = (addr & 3);
 515                        addr &= ~3;
 516
 517                        for (i = 0; i < 4; i++) {
 518                                v = (v << 8) + (i < l || i - l >= cc ?
 519                                        *((unsigned char *) addr + i) : *src++);
 520                        }
 521
 522                        if ((res = write_word (info, (volatile unsigned long *) addr, v)) != 0)
 523                                break;
 524                }
 525        }
 526
 527        return (res);
 528}
 529
 530/*-----------------------------------------------------------------------
 531 * Write a word to Flash, returns:
 532 * 0 - OK
 533 * 1 - write timeout
 534 * 2 - Flash not erased
 535 */
 536static int write_word (flash_info_t * info, volatile unsigned long *addr,
 537                                           ulong data)
 538{
 539        int flag, res = 0;
 540        ulong start;
 541
 542        /* Check if Flash is (sufficiently) erased
 543         */
 544        if ((*addr & data) != data)
 545                return (2);
 546
 547        /* Disable interrupts which might cause a timeout here
 548         */
 549        flag = disable_interrupts ();
 550
 551        *addr = 0x00400040;
 552        *addr = data;
 553
 554        /* re-enable interrupts if necessary
 555         */
 556        if (flag)
 557                enable_interrupts ();
 558
 559        start = get_timer (0);
 560        while ((*addr & 0x00800080) != 0x00800080) {
 561                if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 562                        /* Suspend program
 563                         */
 564                        *addr = 0x00B000B0;
 565                        res = 1;
 566                        goto OUT;
 567                }
 568        }
 569
 570        if (*addr & 0x00220022) {
 571                printf ("*** ERROR: program failed!\n");
 572                res = 1;
 573        }
 574
 575OUT:
 576        /* Clear status register and reset to read mode
 577         */
 578        *addr = 0x00500050;
 579        *addr = 0x00FF00FF;
 580
 581        return (res);
 582}
 583
 584/*-----------------------------------------------------------------------
 585 * Write a byte to Flash, returns:
 586 * 0 - OK
 587 * 1 - write timeout
 588 * 2 - Flash not erased
 589 */
 590static int write_byte (flash_info_t *info, ulong dest, uchar data)
 591{
 592        vu_char *addr = (vu_char *)(info->start[0]);
 593        ulong start;
 594        int flag;
 595
 596        /* Check if Flash is (sufficiently) erased */
 597        if ((*((vu_char *)dest) & data) != data) {
 598                return (2);
 599        }
 600        /* Disable interrupts which might cause a timeout here */
 601        flag = disable_interrupts();
 602
 603        addr[0x0555] = 0xAA;
 604        addr[0x02AA] = 0x55;
 605        addr[0x0555] = 0xA0;
 606
 607        *((vu_char *)dest) = data;
 608
 609        /* re-enable interrupts if necessary */
 610        if (flag)
 611                enable_interrupts();
 612
 613        /* data polling for D7 */
 614        start = get_timer (0);
 615        while ((*((vu_char *)dest) & 0x80) != (data & 0x80)) {
 616                if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 617                        return (1);
 618                }
 619        }
 620        return (0);
 621}
 622
 623/*-----------------------------------------------------------------------
 624 */
 625