uboot/board/BuS/EB+MCF-EV123/flash.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2005
   3 * BuS Elektronik GmbH & Co.KG <esw@bus-elektonik.de>
   4 *
   5 * Based On
   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  "cfm_flash.h"
  29
  30#define PHYS_FLASH_1 CONFIG_SYS_FLASH_BASE
  31#define FLASH_BANK_SIZE 0x200000
  32
  33flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
  34
  35void flash_print_info (flash_info_t * info)
  36{
  37        int i;
  38
  39        switch (info->flash_id & FLASH_VENDMASK) {
  40        case (AMD_MANUFACT & FLASH_VENDMASK):
  41                printf ("AMD: ");
  42                switch (info->flash_id & FLASH_TYPEMASK) {
  43                case (AMD_ID_LV160B & FLASH_TYPEMASK):
  44                        printf ("AM29LV160B (16Bit)\n");
  45                        break;
  46                default:
  47                        printf ("Unknown Chip Type\n");
  48                        break;
  49                }
  50                break;
  51        case FREESCALE_MANUFACT & FLASH_VENDMASK:
  52                cfm_flash_print_info (info);
  53                break;
  54        default:
  55                printf ("Unknown Vendor ");
  56                break;
  57        }
  58
  59        puts ("  Size: ");
  60        if ((info->size >> 20) > 0)
  61        {
  62                printf ("%ld MiB",info->size >> 20);
  63        }
  64        else
  65        {
  66                printf ("%ld KiB",info->size >> 10);
  67        }
  68        printf (" in %d Sectors\n", info->sector_count);
  69
  70        printf ("  Sector Start Addresses:");
  71        for (i = 0; i < info->sector_count; i++) {
  72                if ((i % 4) == 0) {
  73                        printf ("\n    ");
  74                }
  75                printf ("%02d: %08lX%s  ", i,info->start[i],
  76                        info->protect[i] ? " P" : "  ");
  77        }
  78        printf ("\n\n");
  79}
  80
  81unsigned long flash_init (void)
  82{
  83        int i, j;
  84        ulong size = 0;
  85
  86        for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
  87                ulong flashbase = 0;
  88
  89                switch (i)
  90                {
  91                case 1:
  92                        flash_info[i].flash_id =
  93                                (AMD_MANUFACT & FLASH_VENDMASK) |
  94                                (AMD_ID_LV160B & FLASH_TYPEMASK);
  95                        flash_info[i].size = FLASH_BANK_SIZE;
  96                        flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;
  97                        memset (flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);
  98                        flashbase = PHYS_FLASH_1;
  99                        for (j = 0; j < flash_info[i].sector_count; j++) {
 100                                if (j == 0) {
 101                                        /* 1st is 16 KiB */
 102                                        flash_info[i].start[j] = flashbase;
 103                                }
 104                                if ((j >= 1) && (j <= 2)) {
 105                                /* 2nd and 3rd are 8 KiB */
 106                                        flash_info[i].start[j] =
 107                                                flashbase + 0x4000 + 0x2000 * (j - 1);
 108                                }
 109                                if (j == 3) {
 110                                        /* 4th is 32 KiB */
 111                                        flash_info[i].start[j] = flashbase + 0x8000;
 112                                }
 113                                if ((j >= 4) && (j <= 34)) {
 114                                        /* rest is 256 KiB */
 115                                        flash_info[i].start[j] =
 116                                                flashbase + 0x10000 + 0x10000 * (j - 4);
 117                                }
 118                        }
 119                        break;
 120                case 0:
 121                        cfm_flash_init (&flash_info[i]);
 122                        break;
 123                default:
 124                        panic ("configured to many flash banks!\n");
 125                }
 126
 127                size += flash_info[i].size;
 128        }
 129
 130        flash_protect (FLAG_PROTECT_SET,
 131                       CONFIG_SYS_FLASH_BASE,
 132                       CONFIG_SYS_FLASH_BASE + 0xffff, &flash_info[0]);
 133
 134        return size;
 135}
 136
 137#define CMD_READ_ARRAY          0x00F0
 138#define CMD_UNLOCK1             0x00AA
 139#define CMD_UNLOCK2             0x0055
 140#define CMD_ERASE_SETUP         0x0080
 141#define CMD_ERASE_CONFIRM       0x0030
 142#define CMD_PROGRAM             0x00A0
 143#define CMD_UNLOCK_BYPASS       0x0020
 144
 145#define MEM_FLASH_ADDR1         (*(volatile u16 *)(info->start[0] + (0x00000555<<1)))
 146#define MEM_FLASH_ADDR2         (*(volatile u16 *)(info->start[0] + (0x000002AA<<1)))
 147
 148
 149#define BIT_ERASE_DONE          0x0080
 150#define BIT_RDY_MASK            0x0080
 151#define BIT_PROGRAM_ERROR       0x0020
 152#define BIT_TIMEOUT             0x80000000      /* our flag */
 153
 154#define ERR_READY -1
 155
 156int amd_flash_erase_sector(flash_info_t * info, int sector)
 157{
 158        int state;
 159        ulong result;
 160        ulong start;
 161
 162        volatile u16 *addr =
 163                                (volatile u16 *) (info->start[sector]);
 164
 165        MEM_FLASH_ADDR1 = CMD_UNLOCK1;
 166        MEM_FLASH_ADDR2 = CMD_UNLOCK2;
 167        MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
 168
 169        MEM_FLASH_ADDR1 = CMD_UNLOCK1;
 170        MEM_FLASH_ADDR2 = CMD_UNLOCK2;
 171        *addr = CMD_ERASE_CONFIRM;
 172
 173        /* wait until flash is ready */
 174        state = 0;
 175        start = get_timer(0);
 176
 177        do {
 178                result = *addr;
 179
 180                /* check timeout */
 181                if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 182                        MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
 183                        state = ERR_TIMOUT;
 184                }
 185
 186                if (!state && (result & 0xFFFF) & BIT_ERASE_DONE)
 187                        state = ERR_READY;
 188        }
 189        while (!state);
 190        if (state == ERR_READY)
 191                state = ERR_OK;
 192
 193        MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
 194
 195        return state;
 196}
 197
 198int flash_erase (flash_info_t * info, int s_first, int s_last)
 199{
 200        int iflag, cflag;
 201        int sector;
 202        int rc;
 203
 204        rc = ERR_OK;
 205
 206        if (info->flash_id == FLASH_UNKNOWN)
 207        {
 208                rc = ERR_UNKNOWN_FLASH_TYPE;
 209        } /* (info->flash_id == FLASH_UNKNOWN) */
 210
 211        if ((s_first < 0) || (s_first > s_last) || s_last >= info->sector_count)
 212        {
 213                rc = ERR_INVAL;
 214        }
 215
 216        cflag = icache_status ();
 217        icache_disable ();
 218        iflag = disable_interrupts ();
 219
 220        for (sector = s_first; (sector <= s_last) && (rc == ERR_OK); sector++) {
 221
 222                if (info->protect[sector])
 223                {
 224                        putc('P'); /*  protected sector will not erase */
 225                }
 226                else
 227                {
 228                        /* erase on unprotected sector */
 229                        puts("E\b");
 230                        switch (info->flash_id & FLASH_VENDMASK)
 231                        {
 232                        case (AMD_MANUFACT & FLASH_VENDMASK):
 233                                rc = amd_flash_erase_sector(info,sector);
 234                                break;
 235                        case (FREESCALE_MANUFACT & FLASH_VENDMASK):
 236                                rc = cfm_flash_erase_sector(info,sector);
 237                                break;
 238                        default:
 239                                return ERR_UNKNOWN_FLASH_VENDOR;
 240                        }
 241                        putc('.');
 242                }
 243        }
 244        if (rc!=ERR_OK)
 245        {
 246                printf ("\n   ");
 247                flash_perror (rc);
 248        }
 249        else
 250        {
 251                printf (" done\n");
 252        }
 253
 254        udelay (10000); /* allow flash to settle - wait 10 ms */
 255
 256        if (iflag)
 257                enable_interrupts ();
 258
 259        if (cflag)
 260                icache_enable ();
 261
 262        return rc;
 263}
 264
 265volatile static int amd_write_word (flash_info_t * info, ulong dest, u16 data)
 266{
 267        volatile u16 *addr;
 268        ulong result;
 269        int cflag, iflag;
 270        int state;
 271        ulong start;
 272
 273        /*
 274         * Check if Flash is (sufficiently) erased
 275         */
 276        addr = (volatile u16 *) dest;
 277
 278        result = *addr;
 279        if ((result & data) != data)
 280                return ERR_NOT_ERASED;
 281
 282        /*
 283         * Disable interrupts which might cause a timeout
 284         * here. Remember that our exception vectors are
 285         * at address 0 in the flash, and we don't want a
 286         * (ticker) exception to happen while the flash
 287         * chip is in programming mode.
 288         */
 289
 290        cflag = icache_status ();
 291        icache_disable ();
 292        iflag = disable_interrupts ();
 293
 294        MEM_FLASH_ADDR1 = CMD_UNLOCK1;
 295        MEM_FLASH_ADDR2 = CMD_UNLOCK2;
 296        MEM_FLASH_ADDR1 = CMD_PROGRAM;
 297        *addr = data;
 298
 299        /* arm simple, non interrupt dependent timer */
 300        start = get_timer(0);
 301
 302        /* wait until flash is ready */
 303        state = 0;
 304        do {
 305                result = *addr;
 306
 307                /* check timeout */
 308                if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 309                                state = ERR_TIMOUT;
 310                }
 311                if (!state && ((result & BIT_RDY_MASK) == (data & BIT_RDY_MASK)))
 312                        state = ERR_READY;
 313
 314        } while (!state);
 315
 316        *addr = CMD_READ_ARRAY;
 317
 318        if (state == ERR_READY)
 319                state = ERR_OK;
 320        if ((*addr != data) && (state != ERR_TIMOUT))
 321                state = ERR_PROG_ERROR;
 322
 323        if (iflag)
 324                enable_interrupts ();
 325
 326        if (cflag)
 327                icache_enable ();
 328
 329        return state;
 330}
 331
 332int amd_flash_write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 333{
 334        int rc;
 335        ulong dest;
 336        u16 data;
 337
 338        rc = ERR_OK;
 339        if (addr & 1)
 340        {
 341                debug ("Byte alignment not supported\n");
 342                rc = ERR_ALIGN;
 343        }
 344        if (cnt & 1)
 345        {
 346                debug ("Byte transfer not supported\n");
 347                rc = ERR_ALIGN;
 348        }
 349
 350        dest = addr;
 351        while ((cnt>=2) && (rc == ERR_OK))
 352        {
 353                data = *((volatile u16 *) src);
 354                rc=amd_write_word (info,dest,data);
 355                src +=2;
 356                dest +=2;
 357                cnt -=2;
 358        }
 359        return rc;
 360}
 361
 362int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 363{
 364        int rc;
 365
 366        switch (info->flash_id & FLASH_VENDMASK)
 367        {
 368                case (AMD_MANUFACT & FLASH_VENDMASK):
 369                        rc = amd_flash_write_buff(info,src,addr,cnt);
 370                        break;
 371                case (FREESCALE_MANUFACT & FLASH_VENDMASK):
 372                        rc = cfm_flash_write_buff(info,src,addr,cnt);
 373                        break;
 374                default:
 375                        rc = ERR_UNKNOWN_FLASH_VENDOR;
 376        }
 377        return rc;
 378
 379}
 380int amd_flash_protect(flash_info_t * info,long sector,int prot)
 381{
 382        int rc;
 383        rc= ERR_OK;
 384        if (prot)
 385        {
 386                info->protect[sector]=1;
 387        }
 388        else
 389        {
 390                info->protect[sector]=0;
 391        }
 392        return rc;
 393}
 394
 395#ifdef CONFIG_SYS_FLASH_PROTECTION
 396
 397int flash_real_protect(flash_info_t * info,long sector,int prot)
 398{
 399        int rc;
 400
 401        switch (info->flash_id & FLASH_VENDMASK)
 402        {
 403                case (AMD_MANUFACT & FLASH_VENDMASK):
 404                        rc = amd_flash_protect(info,sector,prot);
 405                        break;
 406                case (FREESCALE_MANUFACT & FLASH_VENDMASK):
 407                        rc = cfm_flash_protect(info,sector,prot);
 408                        break;
 409                default:
 410                        rc = ERR_UNKNOWN_FLASH_VENDOR;
 411        }
 412        return rc;
 413}
 414
 415#endif
 416