uboot/board/snmc/qs860t/flash.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2003
   3 * MuLogic B.V.
   4 *
   5 * (C) Copyright 2001
   6 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   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 <asm/ppc4xx.h>
  29#include <asm/u-boot.h>
  30#include <asm/processor.h>
  31
  32flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
  33
  34
  35#ifdef CONFIG_SYS_FLASH_16BIT
  36#define FLASH_WORD_SIZE unsigned short
  37#define FLASH_ID_MASK   0xFFFF
  38#else
  39#define FLASH_WORD_SIZE unsigned long
  40#define FLASH_ID_MASK   0xFFFFFFFF
  41#endif
  42
  43/*-----------------------------------------------------------------------
  44 * Functions
  45 */
  46/* stolen from esteem192e/flash.c */
  47ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info);
  48
  49#ifndef CONFIG_SYS_FLASH_16BIT
  50static int write_word (flash_info_t *info, ulong dest, ulong data);
  51#else
  52static int write_short (flash_info_t *info, ulong dest, ushort data);
  53#endif
  54static void flash_get_offsets (ulong base, flash_info_t *info);
  55
  56
  57/*-----------------------------------------------------------------------
  58 */
  59
  60unsigned long flash_init (void)
  61{
  62        unsigned long size_b0, size_b1;
  63        int i;
  64        uint pbcr;
  65        unsigned long base_b0, base_b1;
  66
  67        /* Init: no FLASHes known */
  68        for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
  69                flash_info[i].flash_id = FLASH_UNKNOWN;
  70        }
  71
  72        /* Static FLASH Bank configuration here - FIXME XXX */
  73
  74        size_b0 = flash_get_size((volatile FLASH_WORD_SIZE *)FLASH_BASE1_PRELIM, &flash_info[0]);
  75
  76        if (flash_info[0].flash_id == FLASH_UNKNOWN) {
  77                printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
  78                        size_b0, size_b0<<20);
  79        }
  80
  81        /* Only one bank */
  82        if (CONFIG_SYS_MAX_FLASH_BANKS == 1) {
  83                /* Setup offsets */
  84                flash_get_offsets (FLASH_BASE1_PRELIM, &flash_info[0]);
  85
  86                /* Monitor protection ON by default */
  87#if 0   /* sand: */
  88                (void)flash_protect(FLAG_PROTECT_SET,
  89                        FLASH_BASE1_PRELIM-CONFIG_SYS_MONITOR_LEN+size_b0,
  90                        FLASH_BASE1_PRELIM-1+size_b0,
  91                        &flash_info[0]);
  92#else
  93                (void)flash_protect(FLAG_PROTECT_SET,
  94                        CONFIG_SYS_MONITOR_BASE,
  95                        CONFIG_SYS_MONITOR_BASE+CONFIG_SYS_MONITOR_LEN-1,
  96                        &flash_info[0]);
  97#endif
  98                size_b1 = 0 ;
  99                flash_info[0].size = size_b0;
 100        } else {        /* 2 banks */
 101                size_b1 = flash_get_size((volatile FLASH_WORD_SIZE *)FLASH_BASE1_PRELIM, &flash_info[1]);
 102
 103                /* Re-do sizing to get full correct info */
 104                if (size_b1) {
 105                        mtdcr(EBC0_CFGADDR, PB0CR);
 106                        pbcr = mfdcr(EBC0_CFGDATA);
 107                        mtdcr(EBC0_CFGADDR, PB0CR);
 108                        base_b1 = -size_b1;
 109                        pbcr = (pbcr & 0x0001ffff) | base_b1 | (((size_b1/1024/1024)-1)<<17);
 110                        mtdcr(EBC0_CFGDATA, pbcr);
 111                }
 112
 113                if (size_b0) {
 114                        mtdcr(EBC0_CFGADDR, PB1CR);
 115                        pbcr = mfdcr(EBC0_CFGDATA);
 116                        mtdcr(EBC0_CFGADDR, PB1CR);
 117                        base_b0 = base_b1 - size_b0;
 118                        pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
 119                        mtdcr(EBC0_CFGDATA, pbcr);
 120                }
 121
 122                size_b0 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b0, &flash_info[0]);
 123
 124                flash_get_offsets (base_b0, &flash_info[0]);
 125
 126                /* monitor protection ON by default */
 127#if 0   /* sand: */
 128                (void)flash_protect(FLAG_PROTECT_SET,
 129                        FLASH_BASE1_PRELIM-CONFIG_SYS_MONITOR_LEN+size_b0,
 130                        FLASH_BASE1_PRELIM-1+size_b0,
 131                        &flash_info[0]);
 132#else
 133                (void)flash_protect(FLAG_PROTECT_SET,
 134                        CONFIG_SYS_MONITOR_BASE,
 135                        CONFIG_SYS_MONITOR_BASE+CONFIG_SYS_MONITOR_LEN-1,
 136                        &flash_info[0]);
 137#endif
 138
 139                if (size_b1) {
 140                        /* Re-do sizing to get full correct info */
 141                        size_b1 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b1, &flash_info[1]);
 142
 143                        flash_get_offsets (base_b1, &flash_info[1]);
 144
 145                        /* monitor protection ON by default */
 146                        (void)flash_protect(FLAG_PROTECT_SET,
 147                                base_b1+size_b1-CONFIG_SYS_MONITOR_LEN,
 148                                base_b1+size_b1-1,
 149                                &flash_info[1]);
 150                        /* monitor protection OFF by default (one is enough) */
 151                        (void)flash_protect(FLAG_PROTECT_CLEAR,
 152                                base_b0+size_b0-CONFIG_SYS_MONITOR_LEN,
 153                                base_b0+size_b0-1,
 154                                &flash_info[0]);
 155                } else {
 156                        flash_info[1].flash_id = FLASH_UNKNOWN;
 157                        flash_info[1].sector_count = -1;
 158                }
 159
 160                flash_info[0].size = size_b0;
 161                flash_info[1].size = size_b1;
 162        }/* else 2 banks */
 163        return (size_b0 + size_b1);
 164}
 165
 166
 167/*-----------------------------------------------------------------------
 168 */
 169
 170static void flash_get_offsets (ulong base, flash_info_t *info)
 171{
 172        int i;
 173
 174        /* set up sector start adress table */
 175        if ((info->flash_id & FLASH_TYPEMASK) == INTEL_ID_28F320J3A ||
 176                (info->flash_id & FLASH_TYPEMASK) == INTEL_ID_28F640J3A ||
 177                (info->flash_id & FLASH_TYPEMASK) == INTEL_ID_28F128J3A) {
 178                for (i = 0; i < info->sector_count; i++) {
 179                        info->start[i] = base + (i * info->size/info->sector_count);
 180                }
 181        }
 182        else if (info->flash_id & FLASH_BTYPE) {
 183                if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
 184
 185#ifndef CONFIG_SYS_FLASH_16BIT
 186                        /* set sector offsets for bottom boot block type */
 187                        info->start[0] = base + 0x00000000;
 188                        info->start[1] = base + 0x00004000;
 189                        info->start[2] = base + 0x00008000;
 190                        info->start[3] = base + 0x0000C000;
 191                        info->start[4] = base + 0x00010000;
 192                        info->start[5] = base + 0x00014000;
 193                        info->start[6] = base + 0x00018000;
 194                        info->start[7] = base + 0x0001C000;
 195                        for (i = 8; i < info->sector_count; i++) {
 196                                info->start[i] = base + (i * 0x00020000) - 0x000E0000;
 197                        }
 198                } else {
 199                        /* set sector offsets for bottom boot block type */
 200                        info->start[0] = base + 0x00000000;
 201                        info->start[1] = base + 0x00008000;
 202                        info->start[2] = base + 0x0000C000;
 203                        info->start[3] = base + 0x00010000;
 204                        for (i = 4; i < info->sector_count; i++) {
 205                                info->start[i] = base + (i * 0x00020000) - 0x00060000;
 206                        }
 207                }
 208#else
 209                        /* set sector offsets for bottom boot block type */
 210                        info->start[0] = base + 0x00000000;
 211                        info->start[1] = base + 0x00002000;
 212                        info->start[2] = base + 0x00004000;
 213                        info->start[3] = base + 0x00006000;
 214                        info->start[4] = base + 0x00008000;
 215                        info->start[5] = base + 0x0000A000;
 216                        info->start[6] = base + 0x0000C000;
 217                        info->start[7] = base + 0x0000E000;
 218                        for (i = 8; i < info->sector_count; i++) {
 219                                info->start[i] = base + (i * 0x00010000) - 0x00070000;
 220                        }
 221                } else {
 222                        /* set sector offsets for bottom boot block type */
 223                        info->start[0] = base + 0x00000000;
 224                        info->start[1] = base + 0x00004000;
 225                        info->start[2] = base + 0x00006000;
 226                        info->start[3] = base + 0x00008000;
 227                        for (i = 4; i < info->sector_count; i++) {
 228                                info->start[i] = base + (i * 0x00010000) - 0x00030000;
 229                        }
 230                }
 231#endif
 232        } else {
 233                /* set sector offsets for top boot block type */
 234                i = info->sector_count - 1;
 235                if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
 236
 237#ifndef CONFIG_SYS_FLASH_16BIT
 238                        info->start[i--] = base + info->size - 0x00004000;
 239                        info->start[i--] = base + info->size - 0x00008000;
 240                        info->start[i--] = base + info->size - 0x0000C000;
 241                        info->start[i--] = base + info->size - 0x00010000;
 242                        info->start[i--] = base + info->size - 0x00014000;
 243                        info->start[i--] = base + info->size - 0x00018000;
 244                        info->start[i--] = base + info->size - 0x0001C000;
 245                        for (; i >= 0; i--) {
 246                                info->start[i] = base + i * 0x00020000;
 247                        }
 248                } else {
 249
 250                        info->start[i--] = base + info->size - 0x00008000;
 251                        info->start[i--] = base + info->size - 0x0000C000;
 252                        info->start[i--] = base + info->size - 0x00010000;
 253                        for (; i >= 0; i--) {
 254                                info->start[i] = base + i * 0x00020000;
 255                        }
 256                }
 257#else
 258                        info->start[i--] = base + info->size - 0x00002000;
 259                        info->start[i--] = base + info->size - 0x00004000;
 260                        info->start[i--] = base + info->size - 0x00006000;
 261                        info->start[i--] = base + info->size - 0x00008000;
 262                        info->start[i--] = base + info->size - 0x0000A000;
 263                        info->start[i--] = base + info->size - 0x0000C000;
 264                        info->start[i--] = base + info->size - 0x0000E000;
 265                        for (; i >= 0; i--) {
 266                                info->start[i] = base + i * 0x00010000;
 267                        }
 268                } else {
 269                        info->start[i--] = base + info->size - 0x00004000;
 270                        info->start[i--] = base + info->size - 0x00006000;
 271                        info->start[i--] = base + info->size - 0x00008000;
 272                        for (; i >= 0; i--) {
 273                                info->start[i] = base + i * 0x00010000;
 274                        }
 275                }
 276#endif
 277        }
 278}
 279
 280/*-----------------------------------------------------------------------
 281 */
 282
 283void flash_print_info  (flash_info_t *info)
 284{
 285        int i;
 286        uchar *boottype;
 287        uchar botboot[]=", bottom boot sect)\n";
 288        uchar topboot[]=", top boot sector)\n";
 289
 290        if (info->flash_id == FLASH_UNKNOWN) {
 291                printf ("missing or unknown FLASH type\n");
 292                return;
 293        }
 294
 295        switch (info->flash_id & FLASH_VENDMASK) {
 296        case FLASH_MAN_AMD:     printf ("AMD ");                break;
 297        case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
 298        case FLASH_MAN_SST:     printf ("SST ");                break;
 299        case FLASH_MAN_STM:     printf ("STM ");                break;
 300        case FLASH_MAN_INTEL:   printf ("INTEL ");              break;
 301        default:                printf ("Unknown Vendor ");     break;
 302        }
 303
 304        if (info->flash_id & 0x0001 ) {
 305                boottype = botboot;
 306        } else {
 307                boottype = topboot;
 308        }
 309
 310        switch (info->flash_id & FLASH_TYPEMASK) {
 311        case FLASH_AM400B:      printf ("AM29LV400B (4 Mbit%s",boottype);
 312                                break;
 313        case FLASH_AM400T:      printf ("AM29LV400T (4 Mbit%s",boottype);
 314                                break;
 315        case FLASH_AM800B:      printf ("AM29LV800B (8 Mbit%s",boottype);
 316                                break;
 317        case FLASH_AM800T:      printf ("AM29LV800T (8 Mbit%s",boottype);
 318                                break;
 319        case FLASH_AM160B:      printf ("AM29LV160B (16 Mbit%s",boottype);
 320                                break;
 321        case FLASH_AM160T:      printf ("AM29LV160T (16 Mbit%s",boottype);
 322                                break;
 323        case FLASH_AM320B:      printf ("AM29LV320B (32 Mbit%s",boottype);
 324                                break;
 325        case FLASH_AM320T:      printf ("AM29LV320T (32 Mbit%s",boottype);
 326                                break;
 327        case FLASH_INTEL800B:   printf ("INTEL28F800B (8 Mbit%s",boottype);
 328                                break;
 329        case FLASH_INTEL800T:   printf ("INTEL28F800T (8 Mbit%s",boottype);
 330                                break;
 331        case FLASH_INTEL160B:   printf ("INTEL28F160B (16 Mbit%s",boottype);
 332                                break;
 333        case FLASH_INTEL160T:   printf ("INTEL28F160T (16 Mbit%s",boottype);
 334                                break;
 335        case FLASH_INTEL320B:   printf ("INTEL28F320B (32 Mbit%s",boottype);
 336                                break;
 337        case FLASH_INTEL320T:   printf ("INTEL28F320T (32 Mbit%s",boottype);
 338                                break;
 339        case FLASH_AMDL322T:    printf ("AM29DL322T (32 Mbit%s",boottype);
 340                                break;
 341
 342#if 0 /* enable when devices are available */
 343
 344        case FLASH_INTEL640B:   printf ("INTEL28F640B (64 Mbit%s",boottype);
 345                                break;
 346        case FLASH_INTEL640T:   printf ("INTEL28F640T (64 Mbit%s",boottype);
 347                                break;
 348#endif
 349        case INTEL_ID_28F320J3A:        printf ("INTEL28F320JA3 (32 Mbit%s",boottype);
 350                                break;
 351        case INTEL_ID_28F640J3A:        printf ("INTEL28F640JA3 (64 Mbit%s",boottype);
 352                                break;
 353        case INTEL_ID_28F128J3A:        printf ("INTEL28F128JA3 (128 Mbit%s",boottype);
 354                                break;
 355
 356        default:                printf ("Unknown Chip Type\n");
 357                                break;
 358        }
 359
 360        printf ("  Size: %ld MB in %d Sectors\n",
 361                info->size >> 20, info->sector_count);
 362
 363        printf ("  Sector Start Addresses:");
 364        for (i=0; i<info->sector_count; ++i) {
 365                if ((i % 5) == 0)
 366                        printf ("\n   ");
 367                printf (" %08lX%s",
 368                        info->start[i],
 369                        info->protect[i] ? " (RO)" : "     "
 370                );
 371        }
 372        printf ("\n");
 373        return;
 374}
 375
 376
 377/*-----------------------------------------------------------------------
 378 */
 379
 380
 381/*-----------------------------------------------------------------------
 382 */
 383
 384/*
 385 * The following code cannot be run from FLASH!
 386 */
 387ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info)
 388{
 389        short i;
 390        ulong base = (ulong)addr;
 391        FLASH_WORD_SIZE value;
 392
 393        /* Write auto select command: read Manufacturer ID */
 394
 395
 396#ifndef CONFIG_SYS_FLASH_16BIT
 397
 398        /*
 399         * Note: if it is an AMD flash and the word at addr[0000]
 400         * is 0x00890089 this routine will think it is an Intel
 401         * flash device and may(most likely) cause trouble.
 402         */
 403
 404        addr[0x0000] = 0x00900090;
 405        if(addr[0x0000] != 0x00890089){
 406                addr[0x0555] = 0x00AA00AA;
 407                addr[0x02AA] = 0x00550055;
 408                addr[0x0555] = 0x00900090;
 409#else
 410
 411        /*
 412         * Note: if it is an AMD flash and the word at addr[0000]
 413         * is 0x0089 this routine will think it is an Intel
 414         * flash device and may(most likely) cause trouble.
 415         */
 416
 417        addr[0x0000] = 0x0090;
 418
 419        if(addr[0x0000] != 0x0089){
 420                addr[0x0555] = 0x00AA;
 421                addr[0x02AA] = 0x0055;
 422                addr[0x0555] = 0x0090;
 423#endif
 424        }
 425        value = addr[0];
 426
 427        switch (value) {
 428        case (AMD_MANUFACT & FLASH_ID_MASK):
 429                info->flash_id = FLASH_MAN_AMD;
 430                break;
 431        case (FUJ_MANUFACT & FLASH_ID_MASK):
 432                info->flash_id = FLASH_MAN_FUJ;
 433                break;
 434        case (STM_MANUFACT & FLASH_ID_MASK):
 435                info->flash_id = FLASH_MAN_STM;
 436                break;
 437        case (SST_MANUFACT & FLASH_ID_MASK):
 438                info->flash_id = FLASH_MAN_SST;
 439                break;
 440        case (INTEL_MANUFACT & FLASH_ID_MASK):
 441                info->flash_id = FLASH_MAN_INTEL;
 442                break;
 443        default:
 444                info->flash_id = FLASH_UNKNOWN;
 445                info->sector_count = 0;
 446                info->size = 0;
 447                return (0); /* no or unknown flash */
 448
 449        }
 450
 451        value = addr[1];                        /* device ID            */
 452
 453        switch (value) {
 454
 455        case (AMD_ID_LV400T & FLASH_ID_MASK):
 456                info->flash_id += FLASH_AM400T;
 457                info->sector_count = 11;
 458                info->size = 0x00100000;
 459                break;                          /* => 1 MB              */
 460
 461        case (AMD_ID_LV400B & FLASH_ID_MASK):
 462                info->flash_id += FLASH_AM400B;
 463                info->sector_count = 11;
 464                info->size = 0x00100000;
 465                break;                          /* => 1 MB              */
 466
 467        case (AMD_ID_LV800T & FLASH_ID_MASK):
 468                info->flash_id += FLASH_AM800T;
 469                info->sector_count = 19;
 470                info->size = 0x00200000;
 471                break;                          /* => 2 MB              */
 472
 473        case (AMD_ID_LV800B & FLASH_ID_MASK):
 474                info->flash_id += FLASH_AM800B;
 475                info->sector_count = 19;
 476                info->size = 0x00200000;
 477                break;                          /* => 2 MB              */
 478
 479        case (AMD_ID_LV160T & FLASH_ID_MASK):
 480                info->flash_id += FLASH_AM160T;
 481                info->sector_count = 35;
 482                info->size = 0x00400000;
 483                break;                          /* => 4 MB              */
 484
 485        case (AMD_ID_LV160B & FLASH_ID_MASK):
 486                info->flash_id += FLASH_AM160B;
 487                info->sector_count = 35;
 488                info->size = 0x00400000;
 489                break;                          /* => 4 MB              */
 490#if 0   /* enable when device IDs are available */
 491        case (AMD_ID_LV320T & FLASH_ID_MASK):
 492                info->flash_id += FLASH_AM320T;
 493                info->sector_count = 67;
 494                info->size = 0x00800000;
 495                break;                          /* => 8 MB              */
 496
 497        case (AMD_ID_LV320B & FLASH_ID_MASK):
 498                info->flash_id += FLASH_AM320B;
 499                info->sector_count = 67;
 500                info->size = 0x00800000;
 501                break;                          /* => 8 MB              */
 502#endif
 503
 504        case (AMD_ID_DL322T & FLASH_ID_MASK):
 505                info->flash_id += FLASH_AMDL322T;
 506                info->sector_count = 71;
 507                info->size = 0x00800000;
 508                break;                          /* => 8 MB              */
 509
 510        case (INTEL_ID_28F800B3T & FLASH_ID_MASK):
 511                info->flash_id += FLASH_INTEL800T;
 512                info->sector_count = 23;
 513                info->size = 0x00200000;
 514                break;                          /* => 2 MB              */
 515
 516        case (INTEL_ID_28F800B3B & FLASH_ID_MASK):
 517                info->flash_id += FLASH_INTEL800B;
 518                info->sector_count = 23;
 519                info->size = 0x00200000;
 520                break;                          /* => 2 MB              */
 521
 522        case (INTEL_ID_28F160B3T & FLASH_ID_MASK):
 523                info->flash_id += FLASH_INTEL160T;
 524                info->sector_count = 39;
 525                info->size = 0x00400000;
 526                break;                          /* => 4 MB              */
 527
 528        case (INTEL_ID_28F160B3B & FLASH_ID_MASK):
 529                info->flash_id += FLASH_INTEL160B;
 530                info->sector_count = 39;
 531                info->size = 0x00400000;
 532                break;                          /* => 4 MB              */
 533
 534        case (INTEL_ID_28F320B3T & FLASH_ID_MASK):
 535                info->flash_id += FLASH_INTEL320T;
 536                info->sector_count = 71;
 537                info->size = 0x00800000;
 538                break;                          /* => 8 MB              */
 539
 540        case (INTEL_ID_28F320B3B & FLASH_ID_MASK):
 541                info->flash_id += FLASH_AM320B;
 542                info->sector_count = 71;
 543                info->size = 0x00800000;
 544                break;                          /* => 8 MB              */
 545
 546#if 0 /* enable when devices are available */
 547        case (INTEL_ID_28F320B3T & FLASH_ID_MASK):
 548                info->flash_id += FLASH_INTEL320T;
 549                info->sector_count = 135;
 550                info->size = 0x01000000;
 551                break;                          /* => 16 MB             */
 552
 553        case (INTEL_ID_28F320B3B & FLASH_ID_MASK):
 554                info->flash_id += FLASH_AM320B;
 555                info->sector_count = 135;
 556                info->size = 0x01000000;
 557                break;                          /* => 16 MB             */
 558#endif
 559        case (INTEL_ID_28F320J3A & FLASH_ID_MASK):
 560                info->flash_id += FLASH_28F320J3A;
 561                info->sector_count = 32;
 562                info->size = 0x00400000;
 563                break;                          /* => 32 MBit   */
 564        case (INTEL_ID_28F640J3A & FLASH_ID_MASK):
 565                info->flash_id += FLASH_28F640J3A;
 566                info->sector_count = 64;
 567                info->size = 0x00800000;
 568                break;                          /* => 64 MBit   */
 569        case (INTEL_ID_28F128J3A & FLASH_ID_MASK):
 570                info->flash_id += FLASH_28F128J3A;
 571                info->sector_count = 128;
 572                info->size = 0x01000000;
 573                break;                          /* => 128 MBit  */
 574
 575        default:
 576                /* FIXME*/
 577                info->flash_id = FLASH_UNKNOWN;
 578                return (0);                     /* => no or unknown flash */
 579        }
 580
 581        flash_get_offsets(base, info);
 582
 583        /* check for protected sectors */
 584        for (i = 0; i < info->sector_count; i++) {
 585                /* read sector protection at sector address, (A7 .. A0) = 0x02 */
 586                /* D0 = 1 if protected */
 587                addr = (volatile FLASH_WORD_SIZE *)(info->start[i]);
 588                info->protect[i] = addr[2] & 1;
 589        }
 590
 591        /*
 592         * Prevent writes to uninitialized FLASH.
 593         */
 594        if (info->flash_id != FLASH_UNKNOWN) {
 595                addr = (volatile FLASH_WORD_SIZE *)info->start[0];
 596                if( (info->flash_id & 0xFF00) == FLASH_MAN_INTEL){
 597                        *addr = (0x00F000F0 & FLASH_ID_MASK);   /* reset bank */
 598                } else {
 599                        *addr = (0x00FF00FF & FLASH_ID_MASK);   /* reset bank */
 600                }
 601        }
 602
 603        return (info->size);
 604}
 605
 606
 607/*-----------------------------------------------------------------------
 608 */
 609
 610int flash_erase (flash_info_t * info, int s_first, int s_last)
 611{
 612
 613        volatile FLASH_WORD_SIZE *addr =
 614                (volatile FLASH_WORD_SIZE *) (info->start[0]);
 615        int flag, prot, sect, l_sect, barf;
 616        ulong start, now, last;
 617        int rcode = 0;
 618
 619        if ((s_first < 0) || (s_first > s_last)) {
 620                if (info->flash_id == FLASH_UNKNOWN) {
 621                        printf ("- missing\n");
 622                } else {
 623                        printf ("- no sectors to erase\n");
 624                }
 625                return 1;
 626        }
 627
 628        if ((info->flash_id == FLASH_UNKNOWN) ||
 629            ((info->flash_id > FLASH_AMD_COMP) &&
 630             ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL))) {
 631                printf ("Can't erase unknown flash type - aborted\n");
 632                return 1;
 633        }
 634
 635        prot = 0;
 636        for (sect = s_first; sect <= s_last; ++sect) {
 637                if (info->protect[sect]) {
 638                        prot++;
 639                }
 640        }
 641
 642        if (prot) {
 643                printf ("- Warning: %d protected sectors will not be erased!\n", prot);
 644        } else {
 645                printf ("\n");
 646        }
 647
 648        l_sect = -1;
 649
 650        /* Disable interrupts which might cause a timeout here */
 651        flag = disable_interrupts ();
 652        if (info->flash_id < FLASH_AMD_COMP) {
 653#ifndef CONFIG_SYS_FLASH_16BIT
 654                addr[0x0555] = 0x00AA00AA;
 655                addr[0x02AA] = 0x00550055;
 656                addr[0x0555] = 0x00800080;
 657                addr[0x0555] = 0x00AA00AA;
 658                addr[0x02AA] = 0x00550055;
 659#else
 660                addr[0x0555] = 0x00AA;
 661                addr[0x02AA] = 0x0055;
 662                addr[0x0555] = 0x0080;
 663                addr[0x0555] = 0x00AA;
 664                addr[0x02AA] = 0x0055;
 665#endif
 666                /* Start erase on unprotected sectors */
 667                for (sect = s_first; sect <= s_last; sect++) {
 668                        if (info->protect[sect] == 0) { /* not protected */
 669                                addr = (volatile FLASH_WORD_SIZE *) (info->start[sect]);
 670                                addr[0] = (0x00300030 & FLASH_ID_MASK);
 671                                l_sect = sect;
 672                        }
 673                }
 674
 675                /* re-enable interrupts if necessary */
 676                if (flag)
 677                        enable_interrupts ();
 678
 679                /* wait at least 80us - let's wait 1 ms */
 680                udelay (1000);
 681
 682                /*
 683                 * We wait for the last triggered sector
 684                 */
 685                if (l_sect < 0)
 686                        goto DONE;
 687
 688                start = get_timer (0);
 689                last = start;
 690                addr = (volatile FLASH_WORD_SIZE *) (info->start[l_sect]);
 691                while ((addr[0] & (0x00800080 & FLASH_ID_MASK)) !=
 692                       (0x00800080 & FLASH_ID_MASK)) {
 693                        if ((now = get_timer (start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 694                                printf ("Timeout\n");
 695                                return 1;
 696                        }
 697                        /* show that we're waiting */
 698                        if ((now - last) > 1000) {      /* every second */
 699                                serial_putc ('.');
 700                                last = now;
 701                        }
 702                }
 703
 704              DONE:
 705                /* reset to read mode */
 706                addr = (volatile FLASH_WORD_SIZE *) info->start[0];
 707                addr[0] = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */
 708        } else {
 709
 710
 711                for (sect = s_first; sect <= s_last; sect++) {
 712                        if (info->protect[sect] == 0) { /* not protected */
 713                                barf = 0;
 714#ifndef CONFIG_SYS_FLASH_16BIT
 715                                addr = (vu_long *) (info->start[sect]);
 716                                addr[0] = 0x00200020;
 717                                addr[0] = 0x00D000D0;
 718                                while (!(addr[0] & 0x00800080));        /* wait for error or finish */
 719                                if (addr[0] & 0x003A003A) {     /* check for error */
 720                                        barf = addr[0] & 0x003A0000;
 721                                        if (barf) {
 722                                                barf >>= 16;
 723                                        } else {
 724                                                barf = addr[0] & 0x0000003A;
 725                                        }
 726                                }
 727#else
 728                                addr = (vu_short *) (info->start[sect]);
 729                                addr[0] = 0x0020;
 730                                addr[0] = 0x00D0;
 731                                while (!(addr[0] & 0x0080));    /* wait for error or finish */
 732                                if (addr[0] & 0x003A)   /* check for error */
 733                                        barf = addr[0] & 0x003A;
 734#endif
 735                                if (barf) {
 736                                        printf ("\nFlash error in sector at %lx\n",
 737                                                (unsigned long) addr);
 738                                        if (barf & 0x0002)
 739                                                printf ("Block locked, not erased.\n");
 740                                        if ((barf & 0x0030) == 0x0030)
 741                                                printf ("Command Sequence error.\n");
 742                                        if ((barf & 0x0030) == 0x0020)
 743                                                printf ("Block Erase error.\n");
 744                                        if (barf & 0x0008)
 745                                                printf ("Vpp Low error.\n");
 746                                        rcode = 1;
 747                                } else
 748                                        printf (".");
 749                                l_sect = sect;
 750                        }
 751                        addr = (volatile FLASH_WORD_SIZE *) info->start[0];
 752                        addr[0] = (0x00FF00FF & FLASH_ID_MASK); /* reset bank */
 753
 754                }
 755
 756        }
 757        printf (" done\n");
 758        return rcode;
 759}
 760
 761/*-----------------------------------------------------------------------
 762 */
 763
 764/*flash_info_t *addr2info (ulong addr)
 765{
 766        flash_info_t *info;
 767        int i;
 768
 769        for (i=0, info=&flash_info[0]; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i, ++info) {
 770                if ((addr >= info->start[0]) &&
 771                    (addr < (info->start[0] + info->size)) ) {
 772                        return (info);
 773                }
 774        }
 775
 776        return (NULL);
 777}
 778*/
 779/*-----------------------------------------------------------------------
 780 * Copy memory to flash.
 781 * Make sure all target addresses are within Flash bounds,
 782 * and no protected sectors are hit.
 783 * Returns:
 784 * 0 - OK
 785 * 1 - write timeout
 786 * 2 - Flash not erased
 787 * 4 - target range includes protected sectors
 788 * 8 - target address not in Flash memory
 789 */
 790
 791/*int flash_write (uchar *src, ulong addr, ulong cnt)
 792{
 793        int i;
 794        ulong         end        = addr + cnt - 1;
 795        flash_info_t *info_first = addr2info (addr);
 796        flash_info_t *info_last  = addr2info (end );
 797        flash_info_t *info;
 798
 799        if (cnt == 0) {
 800                return (0);
 801        }
 802
 803        if (!info_first || !info_last) {
 804                return (8);
 805        }
 806
 807        for (info = info_first; info <= info_last; ++info) {
 808                ulong b_end = info->start[0] + info->size;*/    /* bank end addr */
 809/*              short s_end = info->sector_count - 1;
 810                for (i=0; i<info->sector_count; ++i) {
 811                        ulong e_addr = (i == s_end) ? b_end : info->start[i + 1];
 812
 813                        if ((end >= info->start[i]) && (addr < e_addr) &&
 814                            (info->protect[i] != 0) ) {
 815                                return (4);
 816                        }
 817                }
 818        }
 819
 820*/      /* finally write data to flash */
 821/*      for (info = info_first; info <= info_last && cnt>0; ++info) {
 822                ulong len;
 823
 824                len = info->start[0] + info->size - addr;
 825                if (len > cnt)
 826                        len = cnt;
 827                if ((i = write_buff(info, src, addr, len)) != 0) {
 828                        return (i);
 829                }
 830                cnt  -= len;
 831                addr += len;
 832                src  += len;
 833        }
 834        return (0);
 835}
 836*/
 837/*-----------------------------------------------------------------------
 838 * Copy memory to flash, returns:
 839 * 0 - OK
 840 * 1 - write timeout
 841 * 2 - Flash not erased
 842 */
 843
 844int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
 845{
 846#ifndef CONFIG_SYS_FLASH_16BIT
 847        ulong cp, wp, data;
 848        int l;
 849#else
 850        ulong cp, wp;
 851        ushort data;
 852#endif
 853        int i, rc;
 854
 855#ifndef CONFIG_SYS_FLASH_16BIT
 856
 857
 858        wp = (addr & ~3);       /* get lower word aligned address */
 859
 860        /*
 861         * handle unaligned start bytes
 862         */
 863        if ((l = addr - wp) != 0) {
 864                data = 0;
 865                for (i=0, cp=wp; i<l; ++i, ++cp) {
 866                        data = (data << 8) | (*(uchar *)cp);
 867                }
 868                for (; i<4 && cnt>0; ++i) {
 869                        data = (data << 8) | *src++;
 870                        --cnt;
 871                        ++cp;
 872                }
 873                for (; cnt==0 && i<4; ++i, ++cp) {
 874                        data = (data << 8) | (*(uchar *)cp);
 875                }
 876
 877                if ((rc = write_word(info, wp, data)) != 0) {
 878                        return (rc);
 879                }
 880                wp += 4;
 881        }
 882
 883        /*
 884         * handle word aligned part
 885         */
 886        while (cnt >= 4) {
 887                data = 0;
 888                for (i=0; i<4; ++i) {
 889                        data = (data << 8) | *src++;
 890                }
 891                if ((rc = write_word(info, wp, data)) != 0) {
 892                        return (rc);
 893                }
 894                wp  += 4;
 895                cnt -= 4;
 896        }
 897
 898        if (cnt == 0) {
 899                return (0);
 900        }
 901
 902        /*
 903         * handle unaligned tail bytes
 904         */
 905        data = 0;
 906        for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
 907                data = (data << 8) | *src++;
 908                --cnt;
 909        }
 910        for (; i<4; ++i, ++cp) {
 911                data = (data << 8) | (*(uchar *)cp);
 912        }
 913
 914        return (write_word(info, wp, data));
 915
 916#else
 917        wp = (addr & ~1);       /* get lower word aligned address */
 918
 919        /*
 920         * handle unaligned start byte
 921         */
 922        if (addr - wp) {
 923                data = 0;
 924                data = (data << 8) | *src++;
 925                --cnt;
 926                if ((rc = write_short(info, wp, data)) != 0) {
 927                        return (rc);
 928                }
 929                wp += 2;
 930        }
 931
 932        /*
 933         * handle word aligned part
 934         */
 935/*      l = 0; used for debuging  */
 936        while (cnt >= 2) {
 937                data = 0;
 938                for (i=0; i<2; ++i) {
 939                        data = (data << 8) | *src++;
 940                }
 941
 942/*              if(!l){
 943                        printf("%x",data);
 944                        l = 1;
 945                }  used for debuging */
 946
 947                if ((rc = write_short(info, wp, data)) != 0) {
 948                        return (rc);
 949                }
 950                wp  += 2;
 951                cnt -= 2;
 952        }
 953
 954        if (cnt == 0) {
 955                return (0);
 956        }
 957
 958        /*
 959         * handle unaligned tail bytes
 960         */
 961        data = 0;
 962        for (i=0, cp=wp; i<2 && cnt>0; ++i, ++cp) {
 963                data = (data << 8) | *src++;
 964                --cnt;
 965        }
 966        for (; i<2; ++i, ++cp) {
 967                data = (data << 8) | (*(uchar *)cp);
 968        }
 969
 970        return (write_short(info, wp, data));
 971
 972
 973#endif
 974}
 975
 976/*-----------------------------------------------------------------------
 977 * Write a word to Flash, returns:
 978 * 0 - OK
 979 * 1 - write timeout
 980 * 2 - Flash not erased
 981 */
 982#ifndef CONFIG_SYS_FLASH_16BIT
 983static int write_word (flash_info_t *info, ulong dest, ulong data)
 984{
 985        vu_long *addr = (vu_long*)(info->start[0]);
 986        ulong start,barf;
 987        int flag;
 988
 989
 990        /* Check if Flash is (sufficiently) erased */
 991        if ((*((vu_long *)dest) & data) != data) {
 992                return (2);
 993        }
 994
 995        /* Disable interrupts which might cause a timeout here */
 996        flag = disable_interrupts();
 997
 998        if(info->flash_id > FLASH_AMD_COMP) {
 999                /* AMD stuff */
1000                addr[0x0555] = 0x00AA00AA;
1001                addr[0x02AA] = 0x00550055;
1002                addr[0x0555] = 0x00A000A0;
1003        } else {
1004                /* intel stuff */
1005                *addr = 0x00400040;
1006        }
1007        *((vu_long *)dest) = data;
1008
1009        /* re-enable interrupts if necessary */
1010        if (flag)
1011                enable_interrupts();
1012
1013        /* data polling for D7 */
1014        start = get_timer (0);
1015
1016        if(info->flash_id > FLASH_AMD_COMP) {
1017                while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
1018                        if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
1019                                return (1);
1020                        }
1021                }
1022        } else {
1023                while(!(addr[0] & 0x00800080)) {        /* wait for error or finish */
1024                        if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
1025                                return (1);
1026                        }
1027
1028                if( addr[0] & 0x003A003A) {     /* check for error */
1029                        barf = addr[0] & 0x003A0000;
1030                        if( barf ) {
1031                                barf >>=16;
1032                        } else {
1033                                barf = addr[0] & 0x0000003A;
1034                        }
1035                        printf("\nFlash write error at address %lx\n",(unsigned long)dest);
1036                        if(barf & 0x0002) printf("Block locked, not erased.\n");
1037                        if(barf & 0x0010) printf("Programming error.\n");
1038                        if(barf & 0x0008) printf("Vpp Low error.\n");
1039                        return(2);
1040                }
1041        }
1042
1043        return (0);
1044}
1045
1046#else
1047
1048static int write_short (flash_info_t *info, ulong dest, ushort data)
1049{
1050        vu_short *addr = (vu_short*)(info->start[0]);
1051        ulong start,barf;
1052        int flag;
1053
1054        /* Check if Flash is (sufficiently) erased */
1055        if ((*((vu_short *)dest) & data) != data) {
1056                return (2);
1057        }
1058
1059        /* Disable interrupts which might cause a timeout here */
1060        flag = disable_interrupts();
1061
1062        if(info->flash_id < FLASH_AMD_COMP) {
1063                /* AMD stuff */
1064                addr[0x0555] = 0x00AA;
1065                addr[0x02AA] = 0x0055;
1066                addr[0x0555] = 0x00A0;
1067        } else {
1068                /* intel stuff */
1069                *addr = 0x00D0;
1070                *addr = 0x0040;
1071        }
1072        *((vu_short *)dest) = data;
1073
1074        /* re-enable interrupts if necessary */
1075        if (flag)
1076                enable_interrupts();
1077
1078        /* data polling for D7 */
1079        start = get_timer (0);
1080
1081        if(info->flash_id < FLASH_AMD_COMP) {
1082                /* AMD stuff */
1083                while ((*((vu_short *)dest) & 0x0080) != (data & 0x0080)) {
1084                        if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
1085                                return (1);
1086                        }
1087                }
1088
1089        } else {
1090                /* intel stuff */
1091                while(!(addr[0] & 0x0080)){     /* wait for error or finish */
1092                        if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) return (1);
1093                }
1094
1095                if( addr[0] & 0x003A) { /* check for error */
1096                        barf = addr[0] & 0x003A;
1097                        printf("\nFlash write error at address %lx\n",(unsigned long)dest);
1098                        if(barf & 0x0002) printf("Block locked, not erased.\n");
1099                        if(barf & 0x0010) printf("Programming error.\n");
1100                        if(barf & 0x0008) printf("Vpp Low error.\n");
1101                        return(2);
1102                }
1103                *addr = 0x00B0;
1104                *addr = 0x0070;
1105                while(!(addr[0] & 0x0080)){     /* wait for error or finish */
1106                        if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) return (1);
1107                }
1108                *addr = 0x00FF;
1109        }
1110        return (0);
1111}
1112
1113#endif
1114
1115/*-----------------------------------------------------------------------*/
1116