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
 161        volatile u16 *addr =
 162                                (volatile u16 *) (info->start[sector]);
 163
 164        MEM_FLASH_ADDR1 = CMD_UNLOCK1;
 165        MEM_FLASH_ADDR2 = CMD_UNLOCK2;
 166        MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
 167
 168        MEM_FLASH_ADDR1 = CMD_UNLOCK1;
 169        MEM_FLASH_ADDR2 = CMD_UNLOCK2;
 170        *addr = CMD_ERASE_CONFIRM;
 171
 172        /* wait until flash is ready */
 173        state = 0;
 174        set_timer (0);
 175
 176        do {
 177                result = *addr;
 178
 179                /* check timeout */
 180                if (get_timer (0) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 181                        MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
 182                        state = ERR_TIMOUT;
 183                }
 184
 185                if (!state && (result & 0xFFFF) & BIT_ERASE_DONE)
 186                        state = ERR_READY;
 187        }
 188        while (!state);
 189        if (state == ERR_READY)
 190                state = ERR_OK;
 191
 192        MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
 193
 194        return state;
 195}
 196
 197int flash_erase (flash_info_t * info, int s_first, int s_last)
 198{
 199        int iflag, cflag;
 200        int sector;
 201        int rc;
 202
 203        rc = ERR_OK;
 204
 205        if (info->flash_id == FLASH_UNKNOWN)
 206        {
 207                rc = ERR_UNKNOWN_FLASH_TYPE;
 208        } /* (info->flash_id == FLASH_UNKNOWN) */
 209
 210        if ((s_first < 0) || (s_first > s_last) || s_last >= info->sector_count)
 211        {
 212                rc = ERR_INVAL;
 213        }
 214
 215        cflag = icache_status ();
 216        icache_disable ();
 217        iflag = disable_interrupts ();
 218
 219        for (sector = s_first; (sector <= s_last) && (rc == ERR_OK); sector++) {
 220
 221                if (info->protect[sector])
 222                {
 223                        putc('P'); /*  protected sector will not erase */
 224                }
 225                else
 226                {
 227                        /* erase on unprotected sector */
 228                        puts("E\b");
 229                        switch (info->flash_id & FLASH_VENDMASK)
 230                        {
 231                        case (AMD_MANUFACT & FLASH_VENDMASK):
 232                                rc = amd_flash_erase_sector(info,sector);
 233                                break;
 234                        case (FREESCALE_MANUFACT & FLASH_VENDMASK):
 235                                rc = cfm_flash_erase_sector(info,sector);
 236                                break;
 237                        default:
 238                                return ERR_UNKNOWN_FLASH_VENDOR;
 239                        }
 240                        putc('.');
 241                }
 242        }
 243        if (rc!=ERR_OK)
 244        {
 245                printf ("\n   ");
 246                flash_perror (rc);
 247        }
 248        else
 249        {
 250                printf (" done\n");
 251        }
 252
 253        udelay (10000); /* allow flash to settle - wait 10 ms */
 254
 255        if (iflag)
 256                enable_interrupts ();
 257
 258        if (cflag)
 259                icache_enable ();
 260
 261        return rc;
 262}
 263
 264volatile static int amd_write_word (flash_info_t * info, ulong dest, u16 data)
 265{
 266        volatile u16 *addr;
 267        ulong result;
 268        int cflag, iflag;
 269        int state;
 270
 271        /*
 272         * Check if Flash is (sufficiently) erased
 273         */
 274        addr = (volatile u16 *) dest;
 275
 276        result = *addr;
 277        if ((result & data) != data)
 278                return ERR_NOT_ERASED;
 279
 280        /*
 281         * Disable interrupts which might cause a timeout
 282         * here. Remember that our exception vectors are
 283         * at address 0 in the flash, and we don't want a
 284         * (ticker) exception to happen while the flash
 285         * chip is in programming mode.
 286         */
 287
 288        cflag = icache_status ();
 289        icache_disable ();
 290        iflag = disable_interrupts ();
 291
 292        MEM_FLASH_ADDR1 = CMD_UNLOCK1;
 293        MEM_FLASH_ADDR2 = CMD_UNLOCK2;
 294        MEM_FLASH_ADDR1 = CMD_PROGRAM;
 295        *addr = data;
 296
 297        /* arm simple, non interrupt dependent timer */
 298        set_timer (0);
 299
 300        /* wait until flash is ready */
 301        state = 0;
 302        do {
 303                result = *addr;
 304
 305                /* check timeout */
 306                if (get_timer (0) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 307                                state = ERR_TIMOUT;
 308                }
 309                if (!state && ((result & BIT_RDY_MASK) == (data & BIT_RDY_MASK)))
 310                        state = ERR_READY;
 311
 312        } while (!state);
 313
 314        *addr = CMD_READ_ARRAY;
 315
 316        if (state == ERR_READY)
 317                state = ERR_OK;
 318        if ((*addr != data) && (state != ERR_TIMOUT))
 319                state = ERR_PROG_ERROR;
 320
 321        if (iflag)
 322                enable_interrupts ();
 323
 324        if (cflag)
 325                icache_enable ();
 326
 327        return state;
 328}
 329
 330int amd_flash_write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 331{
 332        int rc;
 333        ulong dest;
 334        u16 data;
 335
 336        rc = ERR_OK;
 337        if (addr & 1)
 338        {
 339                debug ("Byte alignment not supported\n");
 340                rc = ERR_ALIGN;
 341        }
 342        if (cnt & 1)
 343        {
 344                debug ("Byte transfer not supported\n");
 345                rc = ERR_ALIGN;
 346        }
 347
 348        dest = addr;
 349        while ((cnt>=2) && (rc == ERR_OK))
 350        {
 351                data = *((volatile u16 *) src);
 352                rc=amd_write_word (info,dest,data);
 353                src +=2;
 354                dest +=2;
 355                cnt -=2;
 356        }
 357        return rc;
 358}
 359
 360int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 361{
 362        int rc;
 363
 364        switch (info->flash_id & FLASH_VENDMASK)
 365        {
 366                case (AMD_MANUFACT & FLASH_VENDMASK):
 367                        rc = amd_flash_write_buff(info,src,addr,cnt);
 368                        break;
 369                case (FREESCALE_MANUFACT & FLASH_VENDMASK):
 370                        rc = cfm_flash_write_buff(info,src,addr,cnt);
 371                        break;
 372                default:
 373                        rc = ERR_UNKNOWN_FLASH_VENDOR;
 374        }
 375        return rc;
 376
 377}
 378int amd_flash_protect(flash_info_t * info,long sector,int prot)
 379{
 380        int rc;
 381        rc= ERR_OK;
 382        if (prot)
 383        {
 384                info->protect[sector]=1;
 385        }
 386        else
 387        {
 388                info->protect[sector]=0;
 389        }
 390        return rc;
 391}
 392
 393#ifdef CONFIG_SYS_FLASH_PROTECTION
 394
 395int flash_real_protect(flash_info_t * info,long sector,int prot)
 396{
 397        int rc;
 398
 399        switch (info->flash_id & FLASH_VENDMASK)
 400        {
 401                case (AMD_MANUFACT & FLASH_VENDMASK):
 402                        rc = amd_flash_protect(info,sector,prot);
 403                        break;
 404                case (FREESCALE_MANUFACT & FLASH_VENDMASK):
 405                        rc = cfm_flash_protect(info,sector,prot);
 406                        break;
 407                default:
 408                        rc = ERR_UNKNOWN_FLASH_VENDOR;
 409        }
 410        return rc;
 411}
 412
 413#endif
 414