uboot/board/mx1ads/syncflash.c
<<
>>
Prefs
   1/*
   2 * board/mx1ads/syncflash.c
   3 *
   4 * (c) Copyright 2004
   5 * Techware Information Technology, Inc.
   6 * http://www.techware.com.tw/
   7 *
   8 * Ming-Len Wu <minglen_wu@techware.com.tw>
   9 *
  10 * This program is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU General Public License as
  12 * published by the Free Software Foundation; either version 2 of
  13 * the License, or (at your option) any later version.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18 * GNU General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public License
  21 * along with this program; if not, write to the Free Software
  22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23 * MA 02111-1307 USA
  24 */
  25
  26#include <common.h>
  27/*#include <mc9328.h>*/
  28#include <asm/arch/imx-regs.h>
  29
  30typedef unsigned long * p_u32;
  31
  32/* 4Mx16x2 IAM=0 CSD1 */
  33
  34flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];    /* info for FLASH chips    */
  35
  36/*  Following Setting is for CSD1       */
  37#define SFCTL                   0x00221004
  38#define reg_SFCTL               __REG(SFCTL)
  39
  40#define SYNCFLASH_A10           (0x00100000)
  41
  42#define CMD_NORMAL              (0x81020300)                    /* Normal Mode                  */
  43#define CMD_PREC                (CMD_NORMAL + 0x10000000)       /* Precharge Command            */
  44#define CMD_AUTO                (CMD_NORMAL + 0x20000000)       /* Auto Refresh Command         */
  45#define CMD_LMR                 (CMD_NORMAL + 0x30000000)       /* Load Mode Register Command   */
  46#define CMD_LCR                 (CMD_NORMAL + 0x60000000)       /* LCR Command                  */
  47#define CMD_PROGRAM             (CMD_NORMAL + 0x70000000)
  48
  49#define MODE_REG_VAL            (CONFIG_SYS_FLASH_BASE+0x0008CC00)      /* Cas Latency 3                */
  50
  51/* LCR Command */
  52#define LCR_READSTATUS          (0x0001C000)                    /* 0x70                         */
  53#define LCR_ERASE_CONFIRM       (0x00008000)                    /* 0x20                         */
  54#define LCR_ERASE_NVMODE        (0x0000C000)                    /* 0x30                         */
  55#define LCR_PROG_NVMODE         (0x00028000)                    /* 0xA0                         */
  56#define LCR_SR_CLEAR            (0x00014000)                    /* 0x50                         */
  57
  58/* Get Status register                  */
  59u32 SF_SR(void) {
  60        u32 tmp;
  61
  62        reg_SFCTL       = CMD_PROGRAM;
  63        tmp             = __REG(CONFIG_SYS_FLASH_BASE);
  64
  65        reg_SFCTL       = CMD_NORMAL;
  66
  67        reg_SFCTL       = CMD_LCR;                      /* Activate LCR Mode            */
  68        __REG(CONFIG_SYS_FLASH_BASE + LCR_SR_CLEAR);
  69
  70        return tmp;
  71}
  72
  73/* check if SyncFlash is ready          */
  74u8 SF_Ready(void) {
  75        u32 tmp;
  76
  77        tmp     = SF_SR();
  78
  79        if ((tmp & 0x00800000) && (tmp & 0x001C0000)) {
  80                printf ("SyncFlash Error code %08x\n",tmp);
  81        };
  82
  83        if ((tmp & 0x00000080) && (tmp & 0x0000001C)) {
  84                printf ("SyncFlash Error code %08x\n",tmp);
  85        };
  86
  87        if (tmp == 0x00800080)          /* Test Bit 7 of SR     */
  88                return 1;
  89        else
  90                return 0;
  91}
  92
  93/* Issue the precharge all command              */
  94void SF_PrechargeAll(void) {
  95
  96        /* Set Precharge Command        */
  97        reg_SFCTL       = CMD_PREC;
  98        /* Issue Precharge All Command */
  99        __REG(CONFIG_SYS_FLASH_BASE + SYNCFLASH_A10);
 100}
 101
 102/* set SyncFlash to normal mode                 */
 103void SF_Normal(void) {
 104
 105        SF_PrechargeAll();
 106
 107        reg_SFCTL       = CMD_NORMAL;
 108}
 109
 110/* Erase SyncFlash                              */
 111void SF_Erase(u32 RowAddress) {
 112
 113        reg_SFCTL       = CMD_NORMAL;
 114        __REG(RowAddress);
 115
 116        reg_SFCTL       = CMD_PREC;
 117        __REG(RowAddress);
 118
 119        reg_SFCTL       = CMD_LCR;                      /* Set LCR mode         */
 120        __REG(RowAddress + LCR_ERASE_CONFIRM)   = 0;    /* Issue Erase Setup Command    */
 121
 122        reg_SFCTL       = CMD_NORMAL;                   /* return to Normal mode        */
 123        __REG(RowAddress)       = 0xD0D0D0D0;           /* Confirm                      */
 124
 125        while(!SF_Ready());
 126}
 127
 128void SF_NvmodeErase(void) {
 129        SF_PrechargeAll();
 130
 131        reg_SFCTL       = CMD_LCR;                      /* Set to LCR mode              */
 132        __REG(CONFIG_SYS_FLASH_BASE + LCR_ERASE_NVMODE)  = 0;   /* Issue Erase Nvmode Reg Command */
 133
 134        reg_SFCTL       = CMD_NORMAL;                   /* Return to Normal mode        */
 135        __REG(CONFIG_SYS_FLASH_BASE + LCR_ERASE_NVMODE) = 0xC0C0C0C0;   /* Confirm              */
 136
 137        while(!SF_Ready());
 138}
 139
 140void SF_NvmodeWrite(void) {
 141        SF_PrechargeAll();
 142
 143        reg_SFCTL       = CMD_LCR;                      /* Set to LCR mode              */
 144        __REG(CONFIG_SYS_FLASH_BASE+LCR_PROG_NVMODE) = 0;       /* Issue Program Nvmode reg command */
 145
 146        reg_SFCTL       = CMD_NORMAL;                   /* Return to Normal mode        */
 147        __REG(CONFIG_SYS_FLASH_BASE+LCR_PROG_NVMODE) = 0xC0C0C0C0;      /* Confirm not needed   */
 148}
 149
 150/****************************************************************************************/
 151
 152ulong flash_init(void) {
 153        int i, j;
 154
 155/* Turn on CSD1 for negating RESETSF of SyncFLash */
 156
 157        reg_SFCTL       |= 0x80000000;          /* enable CSD1 for SyncFlash            */
 158        udelay(200);
 159
 160        reg_SFCTL       = CMD_LMR;              /* Set Load Mode Register Command       */
 161        __REG(MODE_REG_VAL);    /* Issue Load Mode Register Command     */
 162
 163        SF_Normal();
 164
 165        i = 0;
 166
 167        flash_info[i].flash_id  =  FLASH_MAN_MT | FLASH_MT28S4M16LC;
 168
 169        flash_info[i].size      = FLASH_BANK_SIZE;
 170        flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;
 171
 172        memset(flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);
 173
 174        for (j = 0; j < flash_info[i].sector_count; j++) {
 175                flash_info[i].start[j] = CONFIG_SYS_FLASH_BASE + j * 0x00100000;
 176        }
 177
 178        flash_protect(FLAG_PROTECT_SET,
 179                CONFIG_SYS_FLASH_BASE,
 180                CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1,
 181                &flash_info[0]);
 182
 183        flash_protect(FLAG_PROTECT_SET,
 184                CONFIG_ENV_ADDR,
 185                CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1,
 186                &flash_info[0]);
 187
 188        return FLASH_BANK_SIZE;
 189}
 190
 191void flash_print_info (flash_info_t *info) {
 192
 193        int i;
 194
 195        switch (info->flash_id & FLASH_VENDMASK) {
 196                case (FLASH_MAN_MT & FLASH_VENDMASK):
 197                        printf("Micron: ");
 198                        break;
 199                default:
 200                        printf("Unknown Vendor ");
 201                        break;
 202        }
 203
 204        switch (info->flash_id & FLASH_TYPEMASK) {
 205                case (FLASH_MT28S4M16LC & FLASH_TYPEMASK):
 206                        printf("2x FLASH_MT28S4M16LC (16MB Total)\n");
 207                        break;
 208                default:
 209                        printf("Unknown Chip Type\n");
 210                        return;
 211                        break;
 212        }
 213
 214        printf("  Size: %ld MB in %d Sectors\n",
 215                info->size >> 20, info->sector_count);
 216
 217        printf("  Sector Start Addresses: ");
 218
 219        for (i = 0; i < info->sector_count; i++) {
 220                if ((i % 5) == 0)
 221                        printf ("\n   ");
 222
 223                printf (" %08lX%s", info->start[i],
 224                        info->protect[i] ? " (RO)" : "     ");
 225        }
 226
 227        printf ("\n");
 228}
 229
 230/*-----------------------------------------------------------------------*/
 231
 232int flash_erase (flash_info_t *info, int s_first, int s_last) {
 233        int iflag, cflag, prot, sect;
 234        int rc = ERR_OK;
 235
 236/* first look for protection bits */
 237
 238        if (info->flash_id == FLASH_UNKNOWN)
 239                return ERR_UNKNOWN_FLASH_TYPE;
 240
 241        if ((s_first < 0) || (s_first > s_last))
 242                return ERR_INVAL;
 243
 244        if ((info->flash_id & FLASH_VENDMASK) != (FLASH_MAN_MT & FLASH_VENDMASK))
 245                return ERR_UNKNOWN_FLASH_VENDOR;
 246
 247        prot = 0;
 248
 249        for (sect = s_first; sect <= s_last; ++sect) {
 250                if (info->protect[sect])
 251                        prot++;
 252        }
 253
 254        if (prot) {
 255                printf("protected!\n");
 256                return ERR_PROTECTED;
 257        }
 258/*
 259 * Disable interrupts which might cause a timeout
 260 * here. Remember that our exception vectors are
 261 * at address 0 in the flash, and we don't want a
 262 * (ticker) exception to happen while the flash
 263 * chip is in programming mode.
 264 */
 265
 266        cflag = icache_status();
 267        icache_disable();
 268        iflag = disable_interrupts();
 269
 270/* Start erase on unprotected sectors */
 271        for (sect = s_first; sect <= s_last && !ctrlc(); sect++) {
 272
 273                printf("Erasing sector %2d ... ", sect);
 274
 275/* arm simple, non interrupt dependent timer */
 276
 277                get_timer(0);
 278
 279                SF_NvmodeErase();
 280                SF_NvmodeWrite();
 281
 282                SF_Erase(CONFIG_SYS_FLASH_BASE + (0x0100000 * sect));
 283                SF_Normal();
 284
 285                printf("ok.\n");
 286        }
 287
 288        if (ctrlc())
 289                printf("User Interrupt!\n");
 290
 291        if (iflag)
 292                enable_interrupts();
 293
 294        if (cflag)
 295                icache_enable();
 296
 297        return rc;
 298}
 299
 300/*-----------------------------------------------------------------------
 301 * Copy memory to flash.
 302 */
 303
 304int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) {
 305        int i;
 306
 307        for(i = 0; i < cnt; i += 4) {
 308
 309                SF_PrechargeAll();
 310
 311                reg_SFCTL       = CMD_PROGRAM;          /* Enter SyncFlash Program mode */
 312                __REG(addr + i) = __REG((u32)src  + i);
 313
 314                while(!SF_Ready());
 315        }
 316
 317        SF_Normal();
 318
 319        return ERR_OK;
 320}
 321