uboot/board/a3000/flash.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2001
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8
   9#include <common.h>
  10#include <mpc824x.h>
  11
  12#if defined(CONFIG_ENV_IS_IN_FLASH)
  13# ifndef  CONFIG_ENV_ADDR
  14#  define CONFIG_ENV_ADDR  (CONFIG_SYS_FLASH_BASE + CONFIG_ENV_OFFSET)
  15# endif
  16# ifndef  CONFIG_ENV_SIZE
  17#  define CONFIG_ENV_SIZE  CONFIG_ENV_SECT_SIZE
  18# endif
  19# ifndef  CONFIG_ENV_SECT_SIZE
  20#  define CONFIG_ENV_SECT_SIZE  CONFIG_ENV_SIZE
  21# endif
  22#endif
  23
  24
  25/*---------------------------------------------------------------------*/
  26#define DEBUG_FLASH
  27
  28#ifdef DEBUG_FLASH
  29#define DEBUGF(fmt,args...) printf(fmt ,##args)
  30#else
  31#define DEBUGF(fmt,args...)
  32#endif
  33/*---------------------------------------------------------------------*/
  34
  35flash_info_t    flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */
  36
  37/*-----------------------------------------------------------------------
  38 * Functions
  39 */
  40static ulong flash_get_size (vu_char *addr, flash_info_t *info);
  41static int write_data (flash_info_t *info, uchar *dest, uchar data);
  42static void flash_get_offsets (ulong base, flash_info_t *info);
  43
  44#define BS(b)     (b)
  45#define BYTEME(x) ((x) & 0xFF)
  46
  47/*-----------------------------------------------------------------------
  48 */
  49
  50unsigned long flash_init (void)
  51{
  52        unsigned long flash_banks[CONFIG_SYS_MAX_FLASH_BANKS] = CONFIG_SYS_FLASH_BANKS;
  53        unsigned long size, size_b[CONFIG_SYS_MAX_FLASH_BANKS];
  54
  55        int i;
  56
  57        /* Init: no FLASHes known */
  58        for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i)
  59        {
  60                flash_info[i].flash_id = FLASH_UNKNOWN;
  61
  62                DEBUGF("Get flash bank %d @ 0x%08lx\n", i, flash_banks[i]);
  63/*
  64                size_b[i] = flash_get_size((vu_char *)flash_banks[i], &flash_info[i]);
  65*/
  66                size_b[i] = flash_get_size((vu_char *) 0xff800000 , &flash_info[i]);
  67
  68                if (flash_info[i].flash_id == FLASH_UNKNOWN)
  69                {
  70                        printf ("## Unknown FLASH on Bank %d: "
  71                                "ID 0x%lx, Size = 0x%08lx = %ld MB\n",
  72                                i, flash_info[i].flash_id,
  73                                size_b[i], size_b[i]<<20);
  74                }
  75                else
  76                {
  77                        DEBUGF("## Flash bank %d at 0x%08lx sizes: 0x%08lx \n",
  78                                i, flash_banks[i], size_b[i]);
  79
  80                        flash_get_offsets (flash_banks[i], &flash_info[i]);
  81                        flash_info[i].size = size_b[i];
  82                }
  83        }
  84
  85
  86#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
  87        DEBUGF("protect monitor %x @ %x\n", CONFIG_SYS_MONITOR_BASE, CONFIG_SYS_MONITOR_LEN);
  88        /* monitor protection ON by default */
  89        flash_protect(FLAG_PROTECT_SET,
  90                      CONFIG_SYS_MONITOR_BASE,
  91                      CONFIG_SYS_MONITOR_BASE+CONFIG_SYS_MONITOR_LEN-1,
  92                      &flash_info[0]);
  93#endif
  94
  95#ifdef  CONFIG_ENV_IS_IN_FLASH
  96        /* ENV protection ON by default */
  97        DEBUGF("protect environtment %x @ %x\n", CONFIG_ENV_ADDR, CONFIG_ENV_SECT_SIZE);
  98        flash_protect(FLAG_PROTECT_SET,
  99                      CONFIG_ENV_ADDR,
 100                      CONFIG_ENV_ADDR+CONFIG_ENV_SECT_SIZE-1,
 101                      &flash_info[0]);
 102#endif
 103
 104        size = 0;
 105        DEBUGF("## Final Flash bank sizes: ");
 106        for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i)
 107        {
 108                DEBUGF("%08lx ", size_b[i]);
 109                size += size_b[i];
 110        }
 111        DEBUGF("\n");
 112        return (size);
 113}
 114
 115/*-----------------------------------------------------------------------
 116 */
 117static void flash_get_offsets (ulong base, flash_info_t *info)
 118{
 119        int i;
 120
 121        if (info->flash_id == FLASH_UNKNOWN) {
 122                return;
 123        }
 124
 125        switch (info->flash_id & FLASH_VENDMASK) {
 126                case FLASH_MAN_INTEL:
 127                    for (i = 0; i < info->sector_count; i++) {
 128                                info->start[i] = base;
 129                                base += 0x00020000;             /* 128k per bank */
 130                    }
 131                    return;
 132
 133                default:
 134                    printf ("Don't know sector ofsets for flash type 0x%lx\n", info->flash_id);
 135                    return;
 136        }
 137}
 138
 139/*-----------------------------------------------------------------------
 140 */
 141void flash_print_info  (flash_info_t *info)
 142{
 143        int i;
 144
 145        if (info->flash_id == FLASH_UNKNOWN) {
 146                printf ("missing or unknown FLASH type\n");
 147                return;
 148        }
 149
 150        switch (info->flash_id & FLASH_VENDMASK) {
 151        case FLASH_MAN_AMD:     printf ("AMD ");                break;
 152        case FLASH_MAN_FUJ:     printf ("Fujitsu ");            break;
 153        case FLASH_MAN_SST:     printf ("SST ");                break;
 154        case FLASH_MAN_STM:     printf ("STM ");                break;
 155        case FLASH_MAN_INTEL:   printf ("Intel ");              break;
 156        case FLASH_MAN_MT:      printf ("MT ");                 break;
 157        default:                printf ("Unknown Vendor ");     break;
 158        }
 159
 160        switch (info->flash_id & FLASH_TYPEMASK) {
 161        case FLASH_28F320J3A:
 162                        printf ("28F320J3A (32Mbit = 128K x 32)\n");
 163                        break;
 164        case FLASH_28F640J3A:
 165                        printf ("28F640J3A (64Mbit = 128K x 64)\n");
 166                        break;
 167        case FLASH_28F128J3A:
 168                        printf ("28F128J3A (128Mbit = 128K x 128)\n");
 169                        break;
 170        default:
 171                        printf ("Unknown Chip Type\n");
 172                        break;
 173        }
 174
 175#if 1
 176        if (info->size >= (1 << 20)) {
 177                i = 20;
 178        } else {
 179                i = 10;
 180        }
 181        printf ("  Size: %ld %cB in %d Sectors\n",
 182                info->size >> i,
 183                (i == 20) ? 'M' : 'k',
 184                info->sector_count);
 185
 186        printf ("  Sector Start Addresses:");
 187        for (i=0; i<info->sector_count; ++i) {
 188                if ((i % 5) == 0)
 189                        printf ("\n   ");
 190                printf (" %08lX%s",
 191                        info->start[i],
 192                        info->protect[i] ? " (RO)" : "     "
 193                );
 194        }
 195        printf ("\n");
 196#endif
 197        return;
 198}
 199
 200/*-----------------------------------------------------------------------
 201 */
 202
 203
 204/*-----------------------------------------------------------------------
 205 */
 206
 207/*
 208 * The following code cannot be run from FLASH!
 209 */
 210static ulong flash_get_size (vu_char *addr, flash_info_t *info)
 211{
 212        vu_char manuf, device;
 213
 214        addr[0] = BS(0x90);
 215        manuf = BS(addr[0]);
 216        DEBUGF("Manuf. ID @ 0x%08lx: 0x%08x\n", (ulong)addr, manuf);
 217
 218        switch (manuf) {
 219        case BYTEME(AMD_MANUFACT):
 220                info->flash_id = FLASH_MAN_AMD;
 221                break;
 222        case BYTEME(FUJ_MANUFACT):
 223                info->flash_id = FLASH_MAN_FUJ;
 224                break;
 225        case BYTEME(SST_MANUFACT):
 226                info->flash_id = FLASH_MAN_SST;
 227                break;
 228        case BYTEME(STM_MANUFACT):
 229                info->flash_id = FLASH_MAN_STM;
 230                break;
 231        case BYTEME(INTEL_MANUFACT):
 232                info->flash_id = FLASH_MAN_INTEL;
 233                break;
 234        default:
 235                info->flash_id = FLASH_UNKNOWN;
 236                info->sector_count = 0;
 237                info->size = 0;
 238                addr[0] = BS(0xFF);             /* restore read mode, (yes, BS is a NOP) */
 239                return 0;                       /* no or unknown flash  */
 240        }
 241
 242        device = BS(addr[2]);                   /* device ID            */
 243
 244        DEBUGF("Device ID @ 0x%08lx: 0x%08x\n", (ulong)(&addr[1]), device);
 245
 246        switch (device) {
 247        case BYTEME(INTEL_ID_28F320J3A):
 248                info->flash_id += FLASH_28F320J3A;
 249                info->sector_count = 32;
 250                info->size = 0x00400000;
 251                break;                          /* =>  4 MB             */
 252
 253        case BYTEME(INTEL_ID_28F640J3A):
 254                info->flash_id += FLASH_28F640J3A;
 255                info->sector_count = 64;
 256                info->size = 0x00800000;
 257                break;                          /* => 8 MB              */
 258
 259        case BYTEME(INTEL_ID_28F128J3A):
 260                info->flash_id += FLASH_28F128J3A;
 261                info->sector_count = 128;
 262                info->size = 0x01000000;
 263                break;                          /* => 16 MB             */
 264
 265        default:
 266                info->flash_id = FLASH_UNKNOWN;
 267                addr[0] = BS(0xFF);             /* restore read mode (yes, a NOP) */
 268                return 0;                       /* => no or unknown flash */
 269
 270        }
 271
 272        if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) {
 273                printf ("** ERROR: sector count %d > max (%d) **\n",
 274                        info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
 275                info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
 276        }
 277
 278        addr[0] = BS(0xFF);             /* restore read mode */
 279
 280        return (info->size);
 281}
 282
 283
 284/*-----------------------------------------------------------------------
 285 */
 286
 287int     flash_erase (flash_info_t *info, int s_first, int s_last)
 288{
 289        int flag, prot, sect;
 290        ulong start, now, last;
 291
 292        if ((s_first < 0) || (s_first > s_last)) {
 293                if (info->flash_id == FLASH_UNKNOWN) {
 294                        printf ("- missing\n");
 295                } else {
 296                        printf ("- no sectors to erase\n");
 297                }
 298                return 1;
 299        }
 300
 301        if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
 302                printf ("Can erase only Intel flash types - aborted\n");
 303                return 1;
 304        }
 305
 306        prot = 0;
 307        for (sect=s_first; sect<=s_last; ++sect) {
 308                if (info->protect[sect]) {
 309                        prot++;
 310                }
 311        }
 312
 313        if (prot) {
 314                printf ("- Warning: %d protected sectors will not be erased!\n", prot);
 315        } else {
 316                printf ("\n");
 317        }
 318
 319        start = get_timer (0);
 320        last  = start;
 321        /* Start erase on unprotected sectors */
 322        for (sect = s_first; sect<=s_last; sect++) {
 323                if (info->protect[sect] == 0) { /* not protected */
 324                        vu_char *addr = (vu_char *)(info->start[sect]);
 325                        unsigned long status;
 326
 327                        /* Disable interrupts which might cause a timeout here */
 328                        flag = disable_interrupts();
 329
 330                        *addr = BS(0x50);       /* clear status register */
 331                        *addr = BS(0x20);       /* erase setup */
 332                        *addr = BS(0xD0);       /* erase confirm */
 333
 334                        /* re-enable interrupts if necessary */
 335                        if (flag) {
 336                                enable_interrupts();
 337                        }
 338
 339                        /* wait at least 80us - let's wait 1 ms */
 340                        udelay (1000);
 341
 342                        while (((status = BS(*addr)) & BYTEME(0x00800080)) != BYTEME(0x00800080)) {
 343                                if ((now=get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 344                                        printf ("Timeout\n");
 345                                        *addr = BS(0xB0); /* suspend erase        */
 346                                        *addr = BS(0xFF); /* reset to read mode */
 347                                        return 1;
 348                                }
 349
 350                                /* show that we're waiting */
 351                                if ((now - last) > 1000) {      /* every second */
 352                                        putc ('.');
 353                                        last = now;
 354                                }
 355                        }
 356
 357                        *addr = BS(0xFF);       /* reset to read mode */
 358                }
 359        }
 360        printf (" done\n");
 361        return 0;
 362}
 363
 364/*-----------------------------------------------------------------------
 365 * Copy memory to flash, returns:
 366 * 0 - OK
 367 * 1 - write timeout
 368 * 2 - Flash not erased
 369 * 4 - Flash not identified
 370 */
 371
 372#define FLASH_WIDTH     1       /* flash bus width in bytes */
 373
 374int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
 375{
 376        uchar *wp = (uchar *)addr;
 377        int rc;
 378
 379        if (info->flash_id == FLASH_UNKNOWN) {
 380                return 4;
 381        }
 382
 383        while (cnt > 0) {
 384                if ((rc = write_data(info, wp, *src)) != 0) {
 385                        return rc;
 386                }
 387                wp++;
 388                src++;
 389                cnt--;
 390        }
 391
 392        return cnt;
 393}
 394
 395/*-----------------------------------------------------------------------
 396 * Write a word to Flash, returns:
 397 * 0 - OK
 398 * 1 - write timeout
 399 * 2 - Flash not erased
 400 */
 401static int write_data (flash_info_t *info, uchar *dest, uchar data)
 402{
 403        vu_char *addr = (vu_char *)dest;
 404        ulong status;
 405        ulong start;
 406        int flag;
 407
 408        /* Check if Flash is (sufficiently) erased */
 409        if ((BS(*addr) & data) != data) {
 410                return 2;
 411        }
 412        /* Disable interrupts which might cause a timeout here */
 413        flag = disable_interrupts();
 414
 415        *addr = BS(0x40);               /* write setup */
 416        *addr = data;
 417
 418        /* re-enable interrupts if necessary */
 419        if (flag) {
 420                enable_interrupts();
 421        }
 422
 423        start = get_timer (0);
 424
 425        while (((status = BS(*addr)) & BYTEME(0x00800080)) != BYTEME(0x00800080)) {
 426                if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 427                        *addr = BS(0xFF);       /* restore read mode */
 428                        return 1;
 429                }
 430        }
 431
 432        *addr = BS(0xFF);       /* restore read mode */
 433
 434        return 0;
 435}
 436
 437/*-----------------------------------------------------------------------
 438 */
 439