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