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