uboot/board/psyent/common/AMDLV065D.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2000-2004
   3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
   4 *
   5 * See file CREDITS for list of people who contributed to this
   6 * project.
   7 *
   8 * This program is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU General Public License as
  10 * published by the Free Software Foundation; either version 2 of
  11 * the License, or (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU General Public License
  19 * along with this program; if not, write to the Free Software
  20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 * MA 02111-1307 USA
  22 */
  23
  24
  25#include <common.h>
  26#if defined(CONFIG_NIOS)
  27#include <nios.h>
  28#else
  29#include <asm/io.h>
  30#endif
  31
  32#define SECTSZ          (64 * 1024)
  33flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
  34
  35/*----------------------------------------------------------------------*/
  36unsigned long flash_init (void)
  37{
  38        int i;
  39        unsigned long addr;
  40        flash_info_t *fli = &flash_info[0];
  41
  42        fli->size = CONFIG_SYS_FLASH_SIZE;
  43        fli->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
  44        fli->flash_id = FLASH_MAN_AMD + FLASH_AMDLV065D;
  45
  46        addr = CONFIG_SYS_FLASH_BASE;
  47        for (i = 0; i < fli->sector_count; ++i) {
  48                fli->start[i] = addr;
  49                addr += SECTSZ;
  50                fli->protect[i] = 1;
  51        }
  52
  53        return (CONFIG_SYS_FLASH_SIZE);
  54}
  55/*--------------------------------------------------------------------*/
  56void flash_print_info (flash_info_t * info)
  57{
  58        int i, k;
  59        int erased;
  60        unsigned long *addr;
  61
  62        printf ("  Size: %ld KB in %d Sectors\n",
  63                info->size >> 10, info->sector_count);
  64        printf ("  Sector Start Addresses:");
  65        for (i = 0; i < info->sector_count; ++i) {
  66
  67                /* Check if whole sector is erased */
  68                erased = 1;
  69                addr = (unsigned long *) info->start[i];
  70                for (k = 0; k < SECTSZ/sizeof(unsigned long); k++) {
  71                        if ( readl(addr++) != (unsigned long)-1) {
  72                                erased = 0;
  73                                break;
  74                        }
  75                }
  76
  77                /* Print the info */
  78                if ((i % 5) == 0)
  79                        printf ("\n   ");
  80                printf (" %08lX%s%s",
  81                        info->start[i],
  82                        erased ? " E" : "  ",
  83                        info->protect[i] ? "RO " : "   ");
  84        }
  85        printf ("\n");
  86}
  87
  88/*-------------------------------------------------------------------*/
  89
  90
  91int flash_erase (flash_info_t * info, int s_first, int s_last)
  92{
  93        unsigned char *addr = (unsigned char *) info->start[0];
  94        unsigned char *addr2;
  95        int prot, sect;
  96        ulong start;
  97
  98        /* Some sanity checking */
  99        if ((s_first < 0) || (s_first > s_last)) {
 100                printf ("- no sectors to erase\n");
 101                return 1;
 102        }
 103
 104        prot = 0;
 105        for (sect = s_first; sect <= s_last; ++sect) {
 106                if (info->protect[sect]) {
 107                        prot++;
 108                }
 109        }
 110        if (prot) {
 111                printf ("- Warning: %d protected sectors will not be erased!\n",
 112                        prot);
 113        } else {
 114                printf ("\n");
 115        }
 116
 117        /* It's ok to erase multiple sectors provided we don't delay more
 118         * than 50 usec between cmds ... at which point the erase time-out
 119         * occurs. So don't go and put printf() calls in the loop ... it
 120         * won't be very helpful ;-)
 121         */
 122        for (sect = s_first; sect <= s_last; sect++) {
 123                if (info->protect[sect] == 0) { /* not protected */
 124                        addr2 = (unsigned char *) info->start[sect];
 125                        writeb (0xaa, addr);
 126                        writeb (0x55, addr);
 127                        writeb (0x80, addr);
 128                        writeb (0xaa, addr);
 129                        writeb (0x55, addr);
 130                        writeb (0x30, addr2);
 131                        /* Now just wait for 0xff & provide some user
 132                         * feedback while we wait.
 133                         */
 134                        start = get_timer (0);
 135                        while ( readb (addr2) != 0xff) {
 136                                udelay (1000 * 1000);
 137                                putc ('.');
 138                                if (get_timer (start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
 139                                        printf ("timeout\n");
 140                                        return 1;
 141                                }
 142                        }
 143                }
 144        }
 145        printf ("\n");
 146        return 0;
 147}
 148
 149/*-----------------------------------------------------------------------
 150 * Copy memory to flash, returns:
 151 * 0 - OK
 152 * 1 - write timeout
 153 * 2 - Flash not erased
 154 */
 155
 156int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 157{
 158
 159        vu_char *cmd = (vu_char *) info->start[0];
 160        vu_char *dst = (vu_char *) addr;
 161        unsigned char b;
 162        ulong start;
 163
 164        while (cnt) {
 165                /* Check for sufficient erase */
 166                b = *src;
 167                if ((readb (dst) & b) != b) {
 168                        printf ("%02x : %02x\n", readb (dst), b);
 169                        return (2);
 170                }
 171
 172                writeb (0xaa, cmd);
 173                writeb (0x55, cmd);
 174                writeb (0xa0, cmd);
 175                writeb (dst, b);
 176
 177                /* Verify write */
 178                start = get_timer (0);
 179                while (readb (dst) != b) {
 180                        if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
 181                                return 1;
 182                        }
 183                }
 184                dst++;
 185                src++;
 186                cnt--;
 187        }
 188
 189        return (0);
 190}
 191