uboot/board/evb64260/intel_flash.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 * Hacked for the Hymod board by Murray.Jensen@cmst.csiro.au, 20-Oct-00
   7 */
   8
   9#include <common.h>
  10#include <mpc8xx.h>
  11#include <galileo/gt64260R.h>
  12#include <galileo/memory.h>
  13#include "intel_flash.h"
  14
  15
  16/*-----------------------------------------------------------------------
  17 * Protection Flags:
  18 */
  19#define FLAG_PROTECT_SET        0x01
  20#define FLAG_PROTECT_CLEAR      0x02
  21
  22static void
  23bank_reset(flash_info_t *info, int sect)
  24{
  25        bank_addr_t addrw, eaddrw;
  26
  27        addrw = (bank_addr_t)info->start[sect];
  28        eaddrw = BANK_ADDR_NEXT_WORD(addrw);
  29
  30        while (addrw < eaddrw) {
  31#ifdef FLASH_DEBUG
  32                printf("  writing reset cmd to addr 0x%08lx\n",
  33                        (unsigned long)addrw);
  34#endif
  35                *addrw = BANK_CMD_RST;
  36                addrw++;
  37        }
  38}
  39
  40static void
  41bank_erase_init(flash_info_t *info, int sect)
  42{
  43        bank_addr_t addrw, saddrw, eaddrw;
  44        int flag;
  45
  46#ifdef FLASH_DEBUG
  47        printf("0x%08x BANK_CMD_PROG\n", BANK_CMD_PROG);
  48        printf("0x%08x BANK_CMD_ERASE1\n", BANK_CMD_ERASE1);
  49        printf("0x%08x BANK_CMD_ERASE2\n", BANK_CMD_ERASE2);
  50        printf("0x%08x BANK_CMD_CLR_STAT\n", BANK_CMD_CLR_STAT);
  51        printf("0x%08x BANK_CMD_RST\n", BANK_CMD_RST);
  52        printf("0x%08x BANK_STAT_RDY\n", BANK_STAT_RDY);
  53        printf("0x%08x BANK_STAT_ERR\n", BANK_STAT_ERR);
  54#endif
  55
  56        saddrw = (bank_addr_t)info->start[sect];
  57        eaddrw = BANK_ADDR_NEXT_WORD(saddrw);
  58
  59#ifdef FLASH_DEBUG
  60        printf("erasing sector %d, start addr = 0x%08lx "
  61                "(bank next word addr = 0x%08lx)\n", sect,
  62                (unsigned long)saddrw, (unsigned long)eaddrw);
  63#endif
  64
  65        /* Disable intrs which might cause a timeout here */
  66        flag = disable_interrupts();
  67
  68        for (addrw = saddrw; addrw < eaddrw; addrw++) {
  69#ifdef FLASH_DEBUG
  70                printf("  writing erase cmd to addr 0x%08lx\n",
  71                        (unsigned long)addrw);
  72#endif
  73                *addrw = BANK_CMD_ERASE1;
  74                *addrw = BANK_CMD_ERASE2;
  75        }
  76
  77        /* re-enable interrupts if necessary */
  78        if (flag)
  79                enable_interrupts();
  80}
  81
  82static int
  83bank_erase_poll(flash_info_t *info, int sect)
  84{
  85        bank_addr_t addrw, saddrw, eaddrw;
  86        int sectdone, haderr;
  87
  88        saddrw = (bank_addr_t)info->start[sect];
  89        eaddrw = BANK_ADDR_NEXT_WORD(saddrw);
  90
  91        sectdone = 1;
  92        haderr = 0;
  93
  94        for (addrw = saddrw; addrw < eaddrw; addrw++) {
  95                bank_word_t stat = *addrw;
  96
  97#ifdef FLASH_DEBUG
  98                printf("  checking status at addr "
  99                        "0x%08x [0x%08x]\n",
 100                        (unsigned long)addrw, stat);
 101#endif
 102                if ((stat & BANK_STAT_RDY) != BANK_STAT_RDY)
 103                        sectdone = 0;
 104                else if ((stat & BANK_STAT_ERR) != 0) {
 105                        printf(" failed on sector %d "
 106                                "(stat = 0x%08x) at "
 107                                "address 0x%p\n",
 108                                sect, stat, addrw);
 109                        *addrw = BANK_CMD_CLR_STAT;
 110                        haderr = 1;
 111                }
 112        }
 113
 114        if (haderr)
 115                return (-1);
 116        else
 117                return (sectdone);
 118}
 119
 120int
 121write_word_intel(bank_addr_t addr, bank_word_t value)
 122{
 123        bank_word_t stat;
 124        ulong start;
 125        int flag, retval;
 126
 127        /* Disable interrupts which might cause a timeout here */
 128        flag = disable_interrupts();
 129
 130        *addr = BANK_CMD_PROG;
 131
 132        *addr = value;
 133
 134        /* re-enable interrupts if necessary */
 135        if (flag)
 136                enable_interrupts();
 137
 138        retval = 0;
 139
 140        /* data polling for D7 */
 141        start = get_timer (0);
 142        do {
 143                if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 144                        retval = 1;
 145                        goto done;
 146                }
 147                stat = *addr;
 148        } while ((stat & BANK_STAT_RDY) != BANK_STAT_RDY);
 149
 150        if ((stat & BANK_STAT_ERR) != 0) {
 151                printf("flash program failed (stat = 0x%08lx) "
 152                        "at address 0x%08lx\n", (ulong)stat, (ulong)addr);
 153                *addr = BANK_CMD_CLR_STAT;
 154                retval = 3;
 155        }
 156
 157done:
 158        /* reset to read mode */
 159        *addr = BANK_CMD_RST;
 160
 161        return (retval);
 162}
 163
 164/*-----------------------------------------------------------------------
 165 */
 166
 167int
 168flash_erase_intel(flash_info_t *info, int s_first, int s_last)
 169{
 170        int prot, sect, haderr;
 171        ulong start, now, last;
 172
 173#ifdef FLASH_DEBUG
 174        printf("\nflash_erase: erase %d sectors (%d to %d incl.) from\n"
 175                "  Bank # %d: ", s_last - s_first + 1, s_first, s_last,
 176                (info - flash_info) + 1);
 177        flash_print_info(info);
 178#endif
 179
 180        if ((s_first < 0) || (s_first > s_last)) {
 181                if (info->flash_id == FLASH_UNKNOWN) {
 182                        printf ("- missing\n");
 183                } else {
 184                        printf ("- no sectors to erase\n");
 185                }
 186                return 1;
 187        }
 188
 189        prot = 0;
 190        for (sect=s_first; sect<=s_last; ++sect) {
 191                if (info->protect[sect]) {
 192                        prot++;
 193                }
 194        }
 195
 196        if (prot) {
 197                printf("- Warning: %d protected sector%s will not be erased!\n",
 198                        prot, (prot > 1 ? "s" : ""));
 199        }
 200
 201        start = get_timer (0);
 202        last = 0;
 203        haderr = 0;
 204
 205        for (sect = s_first; sect <= s_last; sect++) {
 206                if (info->protect[sect] == 0) { /* not protected */
 207                        ulong estart;
 208                        int sectdone;
 209
 210                        bank_erase_init(info, sect);
 211
 212                        /* wait at least 80us - let's wait 1 ms */
 213                        udelay (1000);
 214
 215                        estart = get_timer(start);
 216
 217                        do {
 218                                now = get_timer(start);
 219
 220                                if (now - estart > CONFIG_SYS_FLASH_ERASE_TOUT) {
 221                                        printf ("Timeout (sect %d)\n", sect);
 222                                        haderr = 1;
 223                                        break;
 224                                }
 225
 226#ifndef FLASH_DEBUG
 227                                /* show that we're waiting */
 228                                if ((now - last) > 1000) { /* every second */
 229                                        putc ('.');
 230                                        last = now;
 231                                }
 232#endif
 233
 234                                sectdone = bank_erase_poll(info, sect);
 235
 236                                if (sectdone < 0) {
 237                                        haderr = 1;
 238                                        break;
 239                                }
 240
 241                        } while (!sectdone);
 242
 243                        if (haderr)
 244                                break;
 245                }
 246        }
 247
 248        if (haderr > 0)
 249                printf (" failed\n");
 250        else
 251                printf (" done\n");
 252
 253        /* reset to read mode */
 254        for (sect = s_first; sect <= s_last; sect++) {
 255                if (info->protect[sect] == 0) { /* not protected */
 256                        bank_reset(info, sect);
 257                }
 258        }
 259        return haderr;
 260}
 261