uboot/board/bf533-ezkit/flash.c
<<
>>
Prefs
   1/*
   2 * U-boot - flash.c Flash driver for PSD4256GV
   3 *
   4 * Copyright (c) 2005-2007 Analog Devices Inc.
   5 * This file is based on BF533EzFlash.c originally written by Analog Devices, Inc.
   6 *
   7 * (C) Copyright 2000-2004
   8 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   9 *
  10 * See file CREDITS for list of people who contributed to this
  11 * project.
  12 *
  13 * This program is free software; you can redistribute it and/or
  14 * modify it under the terms of the GNU General Public License as
  15 * published by the Free Software Foundation; either version 2 of
  16 * the License, or (at your option) any later version.
  17 *
  18 * This program is distributed in the hope that it will be useful,
  19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21 * GNU General Public License for more details.
  22 *
  23 * You should have received a copy of the GNU General Public License
  24 * along with this program; if not, write to the Free Software
  25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
  26 * MA 02110-1301 USA
  27 */
  28
  29#include <asm/io.h>
  30#include "flash-defines.h"
  31
  32int AFP_NumSectors = 40;
  33long AFP_SectorSize1 = 0x10000;
  34int AFP_SectorSize2 = 0x4000;
  35
  36void flash_reset(void)
  37{
  38        reset_flash();
  39}
  40
  41unsigned long flash_get_size(ulong baseaddr, flash_info_t * info, int bank_flag)
  42{
  43        int id = 0, i = 0;
  44        static int FlagDev = 1;
  45
  46        id = get_codes();
  47        if (FlagDev) {
  48#ifdef DEBUG
  49                printf("Device ID of the Flash is %x\n", id);
  50#endif
  51                FlagDev = 0;
  52        }
  53        info->flash_id = id;
  54
  55        switch (bank_flag) {
  56        case 0:
  57                for (i = PriFlashABegin; i < SecFlashABegin; i++)
  58                        info->start[i] = (baseaddr + (i * AFP_SectorSize1));
  59                info->size = 0x200000;
  60                info->sector_count = 32;
  61                break;
  62        case 1:
  63                info->start[0] = baseaddr + SecFlashASec1Off;
  64                info->start[1] = baseaddr + SecFlashASec2Off;
  65                info->start[2] = baseaddr + SecFlashASec3Off;
  66                info->start[3] = baseaddr + SecFlashASec4Off;
  67                info->size = 0x10000;
  68                info->sector_count = 4;
  69                break;
  70        case 2:
  71                info->start[0] = baseaddr + SecFlashBSec1Off;
  72                info->start[1] = baseaddr + SecFlashBSec2Off;
  73                info->start[2] = baseaddr + SecFlashBSec3Off;
  74                info->start[3] = baseaddr + SecFlashBSec4Off;
  75                info->size = 0x10000;
  76                info->sector_count = 4;
  77                break;
  78        }
  79        return (info->size);
  80}
  81
  82unsigned long flash_init(void)
  83{
  84        unsigned long size_b0, size_b1, size_b2;
  85        int i;
  86
  87        size_b0 = size_b1 = size_b2 = 0;
  88#ifdef DEBUG
  89        printf("Flash Memory Start 0x%x\n", CONFIG_SYS_FLASH_BASE);
  90        printf("Memory Map for the Flash\n");
  91        printf("0x20000000 - 0x200FFFFF Flash A Primary (1MB)\n");
  92        printf("0x20100000 - 0x201FFFFF Flash B Primary (1MB)\n");
  93        printf("0x20200000 - 0x2020FFFF Flash A Secondary (64KB)\n");
  94        printf("0x20280000 - 0x2028FFFF Flash B Secondary (64KB)\n");
  95        printf("Please type command flinfo for information on Sectors \n");
  96#endif
  97        for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
  98                flash_info[i].flash_id = FLASH_UNKNOWN;
  99        }
 100
 101        size_b0 = flash_get_size(CONFIG_SYS_FLASH0_BASE, &flash_info[0], 0);
 102        size_b1 = flash_get_size(CONFIG_SYS_FLASH0_BASE, &flash_info[1], 1);
 103        size_b2 = flash_get_size(CONFIG_SYS_FLASH0_BASE, &flash_info[2], 2);
 104
 105        if (flash_info[0].flash_id == FLASH_UNKNOWN || size_b0 == 0) {
 106                printf("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
 107                       size_b0, size_b0 >> 20);
 108        }
 109
 110        (void)flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_FLASH0_BASE,
 111                            (flash_info[0].start[2] - 1), &flash_info[0]);
 112
 113        return (size_b0 + size_b1 + size_b2);
 114}
 115
 116void flash_print_info(flash_info_t * info)
 117{
 118        int i;
 119
 120        if (info->flash_id == FLASH_UNKNOWN) {
 121                printf("missing or unknown FLASH type\n");
 122                return;
 123        }
 124
 125        switch (info->flash_id) {
 126        case FLASH_PSD4256GV:
 127                printf("ST Microelectronics ");
 128                break;
 129        default:
 130                printf("Unknown Vendor: (0x%08lX) ", info->flash_id);
 131                break;
 132        }
 133        for (i = 0; i < info->sector_count; ++i) {
 134                if ((i % 5) == 0)
 135                        printf("\n   ");
 136                printf(" %08lX%s",
 137                       info->start[i], info->protect[i] ? " (RO)" : "     ");
 138        }
 139        printf("\n");
 140        return;
 141}
 142
 143int flash_erase(flash_info_t * info, int s_first, int s_last)
 144{
 145        int cnt = 0, i;
 146        int prot, sect;
 147
 148        prot = 0;
 149        for (sect = s_first; sect <= s_last; ++sect) {
 150                if (info->protect[sect])
 151                        prot++;
 152        }
 153
 154        if (prot)
 155                printf("- Warning: %d protected sectors will not be erased!\n",
 156                       prot);
 157        else
 158                printf("\n");
 159
 160        cnt = s_last - s_first + 1;
 161
 162        if (cnt == FLASH_TOT_SECT) {
 163                printf("Erasing flash, Please Wait \n");
 164                if (erase_flash() < 0) {
 165                        printf("Erasing flash failed \n");
 166                        return FLASH_FAIL;
 167                }
 168        } else {
 169                printf("Erasing Flash locations, Please Wait\n");
 170                for (i = s_first; i <= s_last; i++) {
 171                        if (info->protect[i] == 0) {    /* not protected */
 172                                if (erase_block_flash(i, info->start[i]) < 0) {
 173                                        printf("Error Sector erasing \n");
 174                                        return FLASH_FAIL;
 175                                }
 176                        }
 177                }
 178        }
 179        return FLASH_SUCCESS;
 180}
 181
 182int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 183{
 184        int ret;
 185        int d;
 186        if (addr % 2) {
 187                read_flash(addr - 1 - CONFIG_SYS_FLASH_BASE, &d);
 188                d = (int)((d & 0x00FF) | (*src++ << 8));
 189                ret = write_data(addr - 1, 2, (uchar *) & d);
 190                if (ret == FLASH_FAIL)
 191                        return ERR_NOT_ERASED;
 192                ret = write_data(addr + 1, cnt - 1, src);
 193        } else
 194                ret = write_data(addr, cnt, src);
 195        if (ret == FLASH_FAIL)
 196                return ERR_NOT_ERASED;
 197        return FLASH_SUCCESS;
 198}
 199
 200int write_data(long lStart, long lCount, uchar * pnData)
 201{
 202        long i = 0;
 203        unsigned long ulOffset = lStart - CONFIG_SYS_FLASH_BASE;
 204        int d;
 205        int nSector = 0;
 206        int flag = 0;
 207
 208        if (lCount % 2) {
 209                flag = 1;
 210                lCount = lCount - 1;
 211        }
 212
 213        for (i = 0; i < lCount - 1; i += 2, ulOffset += 2) {
 214                get_sector_number(ulOffset, &nSector);
 215                read_flash(ulOffset, &d);
 216                if (d != 0xffff) {
 217                        printf
 218                            ("Flash not erased at offset 0x%lx Please erase to reprogram\n",
 219                             ulOffset);
 220                        return FLASH_FAIL;
 221                }
 222                unlock_flash(ulOffset);
 223                d = (int)(pnData[i] | pnData[i + 1] << 8);
 224                write_flash(ulOffset, d);
 225                if (poll_toggle_bit(ulOffset) < 0) {
 226                        printf("Error programming the flash \n");
 227                        return FLASH_FAIL;
 228                }
 229                if ((i > 0) && (!(i % AFP_SectorSize2)))
 230                        printf(".");
 231        }
 232        if (flag) {
 233                get_sector_number(ulOffset, &nSector);
 234                read_flash(ulOffset, &d);
 235                if (d != 0xffff) {
 236                        printf
 237                            ("Flash not erased at offset 0x%lx Please erase to reprogram\n",
 238                             ulOffset);
 239                        return FLASH_FAIL;
 240                }
 241                unlock_flash(ulOffset);
 242                d = (int)(pnData[i] | (d & 0xFF00));
 243                write_flash(ulOffset, d);
 244                if (poll_toggle_bit(ulOffset) < 0) {
 245                        printf("Error programming the flash \n");
 246                        return FLASH_FAIL;
 247                }
 248        }
 249        return FLASH_SUCCESS;
 250}
 251
 252int read_data(long ulStart, long lCount, long lStride, int *pnData)
 253{
 254        long i = 0;
 255        int j = 0;
 256        long ulOffset = ulStart;
 257        int iShift = 0;
 258        int iNumWords = 2;
 259        int nLeftover = lCount % 4;
 260        int nHi, nLow;
 261        int nSector = 0;
 262
 263        for (i = 0; (i < lCount / 4) && (i < BUFFER_SIZE); i++) {
 264                for (iShift = 0, j = 0; j < iNumWords; j += 2) {
 265                        if ((ulOffset >= INVALIDLOCNSTART)
 266                            && (ulOffset < INVALIDLOCNEND))
 267                                return FLASH_FAIL;
 268
 269                        get_sector_number(ulOffset, &nSector);
 270                        read_flash(ulOffset, &nLow);
 271                        ulOffset += (lStride * 2);
 272                        read_flash(ulOffset, &nHi);
 273                        ulOffset += (lStride * 2);
 274                        pnData[i] = (nHi << 16) | nLow;
 275                }
 276        }
 277        if (nLeftover > 0) {
 278                if ((ulOffset >= INVALIDLOCNSTART)
 279                    && (ulOffset < INVALIDLOCNEND))
 280                        return FLASH_FAIL;
 281
 282                get_sector_number(ulOffset, &nSector);
 283                read_flash(ulOffset, &pnData[i]);
 284        }
 285        return FLASH_SUCCESS;
 286}
 287
 288int write_flash(long nOffset, int nValue)
 289{
 290        long addr;
 291
 292        addr = (CONFIG_SYS_FLASH_BASE + nOffset);
 293        SSYNC();
 294        *(unsigned volatile short *)addr = nValue;
 295        SSYNC();
 296        if (poll_toggle_bit(nOffset) < 0)
 297                return FLASH_FAIL;
 298        return FLASH_SUCCESS;
 299}
 300
 301int read_flash(long nOffset, int *pnValue)
 302{
 303        int nValue = 0x0;
 304        long addr = (CONFIG_SYS_FLASH_BASE + nOffset);
 305
 306        if (nOffset != 0x2)
 307                reset_flash();
 308        SSYNC();
 309        nValue = *(volatile unsigned short *)addr;
 310        SSYNC();
 311        *pnValue = nValue;
 312        return TRUE;
 313}
 314
 315int poll_toggle_bit(long lOffset)
 316{
 317        unsigned int u1, u2;
 318        unsigned long timeout = 0xFFFFFFFF;
 319        volatile unsigned long *FB =
 320            (volatile unsigned long *)(0x20000000 + lOffset);
 321        while (1) {
 322                if (timeout < 0)
 323                        break;
 324                u1 = *(volatile unsigned short *)FB;
 325                u2 = *(volatile unsigned short *)FB;
 326                if ((u1 & 0x0040) == (u2 & 0x0040))
 327                        return FLASH_SUCCESS;
 328                if ((u2 & 0x0020) == 0x0000)
 329                        continue;
 330                u1 = *(volatile unsigned short *)FB;
 331                if ((u2 & 0x0040) == (u1 & 0x0040))
 332                        return FLASH_SUCCESS;
 333                else {
 334                        reset_flash();
 335                        return FLASH_FAIL;
 336                }
 337                timeout--;
 338        }
 339        printf("Time out occured \n");
 340        if (timeout < 0)
 341                return FLASH_FAIL;
 342}
 343
 344void reset_flash(void)
 345{
 346        write_flash(WRITESEQ1, RESET_VAL);
 347        /* Wait for 10 micro seconds */
 348        udelay(10);
 349}
 350
 351int erase_flash(void)
 352{
 353        write_flash(WRITESEQ1, WRITEDATA1);
 354        write_flash(WRITESEQ2, WRITEDATA2);
 355        write_flash(WRITESEQ3, WRITEDATA3);
 356        write_flash(WRITESEQ4, WRITEDATA4);
 357        write_flash(WRITESEQ5, WRITEDATA5);
 358        write_flash(WRITESEQ6, WRITEDATA6);
 359
 360        if (poll_toggle_bit(0x0000) < 0)
 361                return FLASH_FAIL;
 362
 363        write_flash(SecFlashAOff + WRITESEQ1, WRITEDATA1);
 364        write_flash(SecFlashAOff + WRITESEQ2, WRITEDATA2);
 365        write_flash(SecFlashAOff + WRITESEQ3, WRITEDATA3);
 366        write_flash(SecFlashAOff + WRITESEQ4, WRITEDATA4);
 367        write_flash(SecFlashAOff + WRITESEQ5, WRITEDATA5);
 368        write_flash(SecFlashAOff + WRITESEQ6, WRITEDATA6);
 369
 370        if (poll_toggle_bit(SecFlashASec1Off) < 0)
 371                return FLASH_FAIL;
 372
 373        write_flash(PriFlashBOff + WRITESEQ1, WRITEDATA1);
 374        write_flash(PriFlashBOff + WRITESEQ2, WRITEDATA2);
 375        write_flash(PriFlashBOff + WRITESEQ3, WRITEDATA3);
 376        write_flash(PriFlashBOff + WRITESEQ4, WRITEDATA4);
 377        write_flash(PriFlashBOff + WRITESEQ5, WRITEDATA5);
 378        write_flash(PriFlashBOff + WRITESEQ6, WRITEDATA6);
 379
 380        if (poll_toggle_bit(PriFlashBOff) < 0)
 381                return FLASH_FAIL;
 382
 383        write_flash(SecFlashBOff + WRITESEQ1, WRITEDATA1);
 384        write_flash(SecFlashBOff + WRITESEQ2, WRITEDATA2);
 385        write_flash(SecFlashBOff + WRITESEQ3, WRITEDATA3);
 386        write_flash(SecFlashBOff + WRITESEQ4, WRITEDATA4);
 387        write_flash(SecFlashBOff + WRITESEQ5, WRITEDATA5);
 388        write_flash(SecFlashBOff + WRITESEQ6, WRITEDATA6);
 389
 390        if (poll_toggle_bit(SecFlashBOff) < 0)
 391                return FLASH_FAIL;
 392
 393        return FLASH_SUCCESS;
 394}
 395
 396int erase_block_flash(int nBlock, unsigned long address)
 397{
 398        long ulSectorOff = 0x0;
 399
 400        if ((nBlock < 0) || (nBlock > AFP_NumSectors))
 401                return FALSE;
 402
 403        ulSectorOff = (address - CONFIG_SYS_FLASH_BASE);
 404
 405        write_flash((WRITESEQ1 | ulSectorOff), WRITEDATA1);
 406        write_flash((WRITESEQ2 | ulSectorOff), WRITEDATA2);
 407        write_flash((WRITESEQ3 | ulSectorOff), WRITEDATA3);
 408        write_flash((WRITESEQ4 | ulSectorOff), WRITEDATA4);
 409        write_flash((WRITESEQ5 | ulSectorOff), WRITEDATA5);
 410
 411        write_flash(ulSectorOff, BlockEraseVal);
 412
 413        if (poll_toggle_bit(ulSectorOff) < 0)
 414                return FLASH_FAIL;
 415
 416        return FLASH_SUCCESS;
 417}
 418
 419void unlock_flash(long ulOffset)
 420{
 421        unsigned long ulOffsetAddr = ulOffset;
 422        ulOffsetAddr &= 0xFFFF0000;
 423
 424        write_flash((WRITESEQ1 | ulOffsetAddr), UNLOCKDATA1);
 425        write_flash((WRITESEQ2 | ulOffsetAddr), UNLOCKDATA2);
 426        write_flash((WRITESEQ3 | ulOffsetAddr), UNLOCKDATA3);
 427}
 428
 429int get_codes()
 430{
 431        int dev_id = 0;
 432
 433        write_flash(WRITESEQ1, GETCODEDATA1);
 434        write_flash(WRITESEQ2, GETCODEDATA2);
 435        write_flash(WRITESEQ3, GETCODEDATA3);
 436
 437        read_flash(0x0002, &dev_id);
 438        dev_id &= 0x00FF;
 439
 440        reset_flash();
 441
 442        return dev_id;
 443}
 444
 445void get_sector_number(long ulOffset, int *pnSector)
 446{
 447        int nSector = 0;
 448
 449        if (ulOffset >= SecFlashAOff) {
 450                if ((ulOffset < SecFlashASec1Off)
 451                    && (ulOffset < SecFlashASec2Off)) {
 452                        nSector = SECT32;
 453                } else if ((ulOffset >= SecFlashASec2Off)
 454                           && (ulOffset < SecFlashASec3Off)) {
 455                        nSector = SECT33;
 456                } else if ((ulOffset >= SecFlashASec3Off)
 457                           && (ulOffset < SecFlashASec4Off)) {
 458                        nSector = SECT34;
 459                } else if ((ulOffset >= SecFlashASec4Off)
 460                           && (ulOffset < SecFlashAEndOff)) {
 461                        nSector = SECT35;
 462                }
 463        } else if (ulOffset >= SecFlashBOff) {
 464                if ((ulOffset < SecFlashBSec1Off)
 465                    && (ulOffset < SecFlashBSec2Off)) {
 466                        nSector = SECT36;
 467                }
 468                if ((ulOffset < SecFlashBSec2Off)
 469                    && (ulOffset < SecFlashBSec3Off)) {
 470                        nSector = SECT37;
 471                }
 472                if ((ulOffset < SecFlashBSec3Off)
 473                    && (ulOffset < SecFlashBSec4Off)) {
 474                        nSector = SECT38;
 475                }
 476                if ((ulOffset < SecFlashBSec4Off)
 477                    && (ulOffset < SecFlashBEndOff)) {
 478                        nSector = SECT39;
 479                }
 480        } else if ((ulOffset >= PriFlashAOff) && (ulOffset < SecFlashAOff)) {
 481                nSector = ulOffset & 0xffff0000;
 482                nSector = ulOffset >> 16;
 483                nSector = nSector & 0x000ff;
 484        }
 485
 486        if ((nSector >= 0) && (nSector < AFP_NumSectors)) {
 487                *pnSector = nSector;
 488        }
 489}
 490