diff options
Diffstat (limited to 'board/trab/flash.c')
-rw-r--r-- | board/trab/flash.c | 569 |
1 files changed, 0 insertions, 569 deletions
diff --git a/board/trab/flash.c b/board/trab/flash.c deleted file mode 100644 index 4e89c41..0000000 --- a/board/trab/flash.c +++ /dev/null @@ -1,569 +0,0 @@ -/* - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* #define DEBUG */ - -#include <common.h> -#include <environment.h> - -static ulong flash_get_size (vu_long *addr, flash_info_t *info); - -flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; - - -#define CMD_READ_ARRAY 0x00F000F0 -#define CMD_UNLOCK1 0x00AA00AA -#define CMD_UNLOCK2 0x00550055 -#define CMD_ERASE_SETUP 0x00800080 -#define CMD_ERASE_CONFIRM 0x00300030 -#define CMD_PROGRAM 0x00A000A0 -#define CMD_UNLOCK_BYPASS 0x00200020 -#define CMD_READ_MANF_ID 0x00900090 -#define CMD_UNLOCK_BYPASS_RES1 0x00900090 -#define CMD_UNLOCK_BYPASS_RES2 0x00000000 - -#define MEM_FLASH_ADDR (*(volatile u32 *)CONFIG_SYS_FLASH_BASE) -#define MEM_FLASH_ADDR1 (*(volatile u32 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 << 2))) -#define MEM_FLASH_ADDR2 (*(volatile u32 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA << 2))) - -#define BIT_ERASE_DONE 0x00800080 -#define BIT_RDY_MASK 0x00800080 -#define BIT_PROGRAM_ERROR 0x00200020 -#define BIT_TIMEOUT 0x80000000 /* our flag */ - -#define READY 1 -#define ERR 2 -#define TMO 4 - -/*----------------------------------------------------------------------- - */ - -ulong flash_init (void) -{ - int i, j; - ulong size = 0; - - for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) { - ulong flashbase = 0; - flash_info_t *info = &flash_info[i]; - - /* Init: no FLASHes known */ - info->flash_id = FLASH_UNKNOWN; - - size += flash_get_size (CONFIG_SYS_FLASH_BASE, info); - - if (i == 0) - flashbase = CONFIG_SYS_FLASH_BASE; - else - panic ("configured too many flash banks!\n"); - for (j = 0; j < info->sector_count; j++) { - - info->protect[j] = 0; - info->start[j] = flashbase; - - switch (info->flash_id & FLASH_TYPEMASK) { - case (FLASH_AM320B & FLASH_TYPEMASK): - case (FLASH_MXLV320B & FLASH_TYPEMASK): - /* Boot sector type: 8 x 8 + N x 128 kB */ - flashbase += (j < 8) ? 0x4000 : 0x20000; - break; - case (FLASH_AM640U & FLASH_TYPEMASK): - /* Uniform sector type: 128 kB */ - flashbase += 0x20000; - break; - default: - printf ("## Bad flash chip type 0x%04lX\n", - info->flash_id & FLASH_TYPEMASK); - } - } - } - - /* - * Protect monitor and environment sectors - */ - flash_protect ( FLAG_PROTECT_SET, - CONFIG_SYS_FLASH_BASE, - CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1, - &flash_info[0]); - - flash_protect ( FLAG_PROTECT_SET, - CONFIG_ENV_ADDR, - CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1, &flash_info[0]); - -#ifdef CONFIG_ENV_ADDR_REDUND - flash_protect ( FLAG_PROTECT_SET, - CONFIG_ENV_ADDR_REDUND, - CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1, - &flash_info[0]); -#endif - - return size; -} - -/*----------------------------------------------------------------------- - */ -void flash_print_info (flash_info_t * info) -{ - int i; - - switch (info->flash_id & FLASH_VENDMASK) { - case (FLASH_MAN_AMD & FLASH_VENDMASK): - printf ("AMD "); break; - case (FLASH_MAN_FUJ & FLASH_VENDMASK): - printf ("FUJITSU "); break; - case (FLASH_MAN_MX & FLASH_VENDMASK): - printf ("MACRONIX "); break; - default: printf ("Unknown Vendor "); break; - } - - switch (info->flash_id & FLASH_TYPEMASK) { - case (FLASH_AM320B & FLASH_TYPEMASK): - printf ("2x Am29LV320DB (32Mbit)\n"); - break; - case (FLASH_MXLV320B & FLASH_TYPEMASK): - printf ("2x MX29LV320DB (32Mbit)\n"); - break; - case (FLASH_AM640U & FLASH_TYPEMASK): - printf ("2x Am29LV640D (64Mbit)\n"); - break; - default: - printf ("Unknown Chip Type\n"); - goto Done; - break; - } - - printf (" Size: %ld MB in %d Sectors\n", - info->size >> 20, info->sector_count); - - printf (" Sector Start Addresses:"); - for (i = 0; i < info->sector_count; i++) { - if ((i % 5) == 0) { - printf ("\n "); - } - printf (" %08lX%s", - info->start[i], - info->protect[i] ? " (RO)" : " "); - } - printf ("\n"); - -Done: ; -} - -/*----------------------------------------------------------------------- - */ - -int flash_erase (flash_info_t * info, int s_first, int s_last) -{ - ulong result; - -#if 0 - int cflag; -#endif - int iflag, prot, sect; - int rc = ERR_OK; - int chip1, chip2; - - debug ("flash_erase: s_first %d s_last %d\n", s_first, s_last); - - /* first look for protection bits */ - - if (info->flash_id == FLASH_UNKNOWN) - return ERR_UNKNOWN_FLASH_TYPE; - - if ((s_first < 0) || (s_first > s_last)) { - return ERR_INVAL; - } - - switch (info->flash_id & FLASH_VENDMASK) { - case (FLASH_MAN_AMD & FLASH_VENDMASK): break; /* OK */ - case (FLASH_MAN_FUJ & FLASH_VENDMASK): break; /* OK */ - case (FLASH_MAN_MX & FLASH_VENDMASK): break; /* OK */ - default: - debug ("## flash_erase: unknown manufacturer\n"); - return (ERR_UNKNOWN_FLASH_VENDOR); - } - - prot = 0; - for (sect = s_first; sect <= s_last; ++sect) { - if (info->protect[sect]) { - prot++; - } - } - - if (prot) { - printf ("- Warning: %d protected sectors will not be erased!\n", - prot); - } else { - printf ("\n"); - } - - /* - * Disable interrupts which might cause a timeout - * here. Remember that our exception vectors are - * at address 0 in the flash, and we don't want a - * (ticker) exception to happen while the flash - * chip is in programming mode. - */ -#if 0 - cflag = icache_status (); - icache_disable (); -#endif - iflag = disable_interrupts (); - - /* Start erase on unprotected sectors */ - for (sect = s_first; sect <= s_last && !ctrlc (); sect++) { - - debug ("Erasing sector %2d @ %08lX... ", - sect, info->start[sect]); - - /* arm simple, non interrupt dependent timer */ - reset_timer_masked (); - - if (info->protect[sect] == 0) { /* not protected */ - vu_long *addr = (vu_long *) (info->start[sect]); - - MEM_FLASH_ADDR1 = CMD_UNLOCK1; - MEM_FLASH_ADDR2 = CMD_UNLOCK2; - MEM_FLASH_ADDR1 = CMD_ERASE_SETUP; - - MEM_FLASH_ADDR1 = CMD_UNLOCK1; - MEM_FLASH_ADDR2 = CMD_UNLOCK2; - *addr = CMD_ERASE_CONFIRM; - - /* wait until flash is ready */ - chip1 = chip2 = 0; - - do { - result = *addr; - - /* check timeout */ - if (get_timer_masked () > CONFIG_SYS_FLASH_ERASE_TOUT) { - MEM_FLASH_ADDR1 = CMD_READ_ARRAY; - chip1 = TMO; - break; - } - - if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE) - chip1 = READY; - - if (!chip1 && (result & 0xFFFF) & BIT_PROGRAM_ERROR) - chip1 = ERR; - - if (!chip2 && (result >> 16) & BIT_ERASE_DONE) - chip2 = READY; - - if (!chip2 && (result >> 16) & BIT_PROGRAM_ERROR) - chip2 = ERR; - - } while (!chip1 || !chip2); - - MEM_FLASH_ADDR1 = CMD_READ_ARRAY; - - if (chip1 == ERR || chip2 == ERR) { - rc = ERR_PROG_ERROR; - printf ("Flash erase error\n"); - goto outahere; - } - if (chip1 == TMO) { - rc = ERR_TIMOUT; - printf ("Flash erase timeout error\n"); - goto outahere; - } - } - } - -outahere: - /* allow flash to settle - wait 10 ms */ - udelay_masked (10000); - - if (iflag) - enable_interrupts (); - -#if 0 - if (cflag) - icache_enable (); -#endif - return rc; -} - -/*----------------------------------------------------------------------- - * Copy memory to flash - */ - -static int write_word (flash_info_t * info, ulong dest, ulong data) -{ - vu_long *addr = (vu_long *) dest; - ulong result; - int rc = ERR_OK; - -#if 0 - int cflag; -#endif - int iflag; - int chip1, chip2; - - /* - * Check if Flash is (sufficiently) erased - */ - result = *addr; - if ((result & data) != data) - return ERR_NOT_ERASED; - - /* - * Disable interrupts which might cause a timeout - * here. Remember that our exception vectors are - * at address 0 in the flash, and we don't want a - * (ticker) exception to happen while the flash - * chip is in programming mode. - */ -#if 0 - cflag = icache_status (); - icache_disable (); -#endif - iflag = disable_interrupts (); - - MEM_FLASH_ADDR1 = CMD_UNLOCK1; - MEM_FLASH_ADDR2 = CMD_UNLOCK2; - MEM_FLASH_ADDR1 = CMD_PROGRAM; - *addr = data; - - /* arm simple, non interrupt dependent timer */ - reset_timer_masked (); - - /* wait until flash is ready */ - chip1 = chip2 = 0; - do { - result = *addr; - - /* check timeout */ - if (get_timer_masked () > CONFIG_SYS_FLASH_WRITE_TOUT) { - chip1 = ERR | TMO; - break; - } - if (!chip1 && ((result & 0x80) == (data & 0x80))) - chip1 = READY; - - if (!chip1 && ((result & 0xFFFF) & BIT_PROGRAM_ERROR)) { - result = *addr; - - if ((result & 0x80) == (data & 0x80)) - chip1 = READY; - else - chip1 = ERR; - } - - if (!chip2 && ((result & (0x80 << 16)) == (data & (0x80 << 16)))) - chip2 = READY; - - if (!chip2 && ((result >> 16) & BIT_PROGRAM_ERROR)) { - result = *addr; - - if ((result & (0x80 << 16)) == (data & (0x80 << 16))) - chip2 = READY; - else - chip2 = ERR; - } - - } while (!chip1 || !chip2); - - *addr = CMD_READ_ARRAY; - - if (chip1 == ERR || chip2 == ERR || *addr != data) { - rc = ERR_PROG_ERROR; - printf ("Flash program error\n"); - debug ("chip1: %#x, chip2: %#x, addr: %#lx *addr: %#lx, " - "data: %#lx\n", - chip1, chip2, addr, *addr, data); - } - - if (iflag) - enable_interrupts (); - -#if 0 - if (cflag) - icache_enable (); -#endif - - return rc; -} - -/*----------------------------------------------------------------------- - * Copy memory to flash. - */ - -int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt) -{ - ulong cp, wp, data; - int l; - int i, rc; - - wp = (addr & ~3); /* get lower word aligned address */ - - /* - * handle unaligned start bytes - */ - if ((l = addr - wp) != 0) { - data = 0; - for (i = 0, cp = wp; i < l; ++i, ++cp) { - data = (data >> 8) | (*(uchar *) cp << 24); - } - for (; i < 4 && cnt > 0; ++i) { - data = (data >> 8) | (*src++ << 24); - --cnt; - ++cp; - } - for (; cnt == 0 && i < 4; ++i, ++cp) { - data = (data >> 8) | (*(uchar *) cp << 24); - } - - if ((rc = write_word (info, wp, data)) != 0) { - goto Done; - } - wp += 4; - } - - /* - * handle word aligned part - */ - while (cnt >= 4) { - if (((ulong)src) & 0x3) { - for (i = 0; i < 4; i++) { - ((char *)&data)[i] = ((vu_char *)src)[i]; - } - } - else { - data = *((vu_long *) src); - } - - if ((rc = write_word (info, wp, data)) != 0) { - goto Done; - } - src += 4; - wp += 4; - cnt -= 4; - } - - if (cnt == 0) { - rc = ERR_OK; - goto Done; - } - - /* - * handle unaligned tail bytes - */ - data = 0; - for (i = 0, cp = wp; i < 4 && cnt > 0; ++i, ++cp) { - data = (data >> 8) | (*src++ << 24); - --cnt; - } - for (; i < 4; ++i, ++cp) { - data = (data >> 8) | (*(uchar *) cp << 24); - } - - rc = write_word (info, wp, data); - - Done: - - return (rc); -} - -/*----------------------------------------------------------------------- - */ - -static ulong flash_get_size (vu_long *addr, flash_info_t *info) -{ - ulong value; - - /* Write auto select command sequence and read Manufacturer ID */ - addr[0x0555] = CMD_UNLOCK1; - addr[0x02AA] = CMD_UNLOCK2; - addr[0x0555] = CMD_READ_MANF_ID; - - value = addr[0]; - - debug ("Manuf. ID @ 0x%08lx: 0x%08lx\n", (ulong)addr, value); - - switch (value) { - case AMD_MANUFACT: - info->flash_id = FLASH_MAN_AMD; - break; - case FUJ_MANUFACT: - info->flash_id = FLASH_MAN_FUJ; - break; - case MX_MANUFACT: - info->flash_id = FLASH_MAN_MX; - break; - default: - info->flash_id = FLASH_UNKNOWN; - info->sector_count = 0; - info->size = 0; - addr[0] = CMD_READ_ARRAY; /* restore read mode */ - debug ("## flash_init: unknown manufacturer\n"); - return (0); /* no or unknown flash */ - } - - value = addr[1]; /* device ID */ - - debug ("Device ID @ 0x%08lx: 0x%08lx\n", (ulong)(&addr[1]), value); - - switch (value) { - case AMD_ID_LV320B: - info->flash_id += FLASH_AM320B; - info->sector_count = 71; - info->size = 0x00800000; - - addr[0] = CMD_READ_ARRAY; /* restore read mode */ - break; /* => 8 MB */ - - case AMD_ID_LV640U: - info->flash_id += FLASH_AM640U; - info->sector_count = 128; - info->size = 0x01000000; - - addr[0] = CMD_READ_ARRAY; /* restore read mode */ - break; /* => 16 MB */ - - case MX_ID_LV320B: - info->flash_id += FLASH_MXLV320B; - info->sector_count = 71; - info->size = 0x00800000; - - addr[0] = CMD_READ_ARRAY; /* restore read mode */ - break; /* => 8 MB */ - - default: - debug ("## flash_init: unknown flash chip\n"); - info->flash_id = FLASH_UNKNOWN; - addr[0] = CMD_READ_ARRAY; /* restore read mode */ - return (0); /* => no or unknown flash */ - - } - - if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) { - printf ("** ERROR: sector count %d > max (%d) **\n", - info->sector_count, CONFIG_SYS_MAX_FLASH_SECT); - info->sector_count = CONFIG_SYS_MAX_FLASH_SECT; - } - - return (info->size); -} |