diff options
Diffstat (limited to 'board/purple/flash.c')
-rw-r--r-- | board/purple/flash.c | 595 |
1 files changed, 0 insertions, 595 deletions
diff --git a/board/purple/flash.c b/board/purple/flash.c deleted file mode 100644 index 5cee35e..0000000 --- a/board/purple/flash.c +++ /dev/null @@ -1,595 +0,0 @@ -/* - * (C) Copyright 2003 - * Wolfgang Denk, DENX Software Engineering, wd@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 - */ - -#include <common.h> -#include <asm/inca-ip.h> - -flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips */ - -typedef unsigned long FLASH_PORT_WIDTH; -typedef volatile unsigned long FLASH_PORT_WIDTHV; - -#define FLASH_ID_MASK 0xFFFFFFFF - -#define FPW FLASH_PORT_WIDTH -#define FPWV FLASH_PORT_WIDTHV - -#define ORMASK(size) ((-size) & OR_AM_MSK) - -#define FLASH29_REG_ADRS(reg) ((FPWV *)PHYS_FLASH_1 + (reg)) - -/* FLASH29 command register addresses */ - -#define FLASH29_REG_FIRST_CYCLE FLASH29_REG_ADRS (0x1555) -#define FLASH29_REG_SECOND_CYCLE FLASH29_REG_ADRS (0x2aaa) -#define FLASH29_REG_THIRD_CYCLE FLASH29_REG_ADRS (0x3555) -#define FLASH29_REG_FOURTH_CYCLE FLASH29_REG_ADRS (0x4555) -#define FLASH29_REG_FIFTH_CYCLE FLASH29_REG_ADRS (0x5aaa) -#define FLASH29_REG_SIXTH_CYCLE FLASH29_REG_ADRS (0x6555) - -/* FLASH29 command definitions */ - -#define FLASH29_CMD_FIRST 0xaaaaaaaa -#define FLASH29_CMD_SECOND 0x55555555 -#define FLASH29_CMD_FOURTH 0xaaaaaaaa -#define FLASH29_CMD_FIFTH 0x55555555 -#define FLASH29_CMD_SIXTH 0x10101010 - -#define FLASH29_CMD_SECTOR 0x30303030 -#define FLASH29_CMD_PROGRAM 0xa0a0a0a0 -#define FLASH29_CMD_CHIP_ERASE 0x80808080 -#define FLASH29_CMD_READ_RESET 0xf0f0f0f0 -#define FLASH29_CMD_AUTOSELECT 0x90909090 -#define FLASH29_CMD_READ 0x70707070 - -#define IN_RAM_CMD_READ 0x1 -#define IN_RAM_CMD_WRITE 0x2 - -#define FLASH_WRITE_CMD ((ulong)(flash_write_cmd) & 0x7)+0xbf008000 -#define FLASH_READ_CMD ((ulong)(flash_read_cmd) & 0x7)+0xbf008000 - -typedef void (*FUNCPTR_CP)(ulong *source, ulong *destination, ulong nlongs); -typedef void (*FUNCPTR_RD)(int cmd, FPWV * pFA, char * string, int strLen); -typedef void (*FUNCPTR_WR)(int cmd, FPWV * pFA, FPW value); - -static ulong flash_get_size(FPWV *addr, flash_info_t *info); -static int write_word(flash_info_t *info, FPWV *dest, FPW data); -static void flash_get_offsets(ulong base, flash_info_t *info); -static flash_info_t *flash_get_info(ulong base); - -static void load_cmd(ulong cmd); -static ulong in_ram_cmd = 0; - - -/****************************************************************************** -* -* Don't change the program architecture -* This architecture assure the program -* can be relocated to scratch ram -*/ -static void flash_read_cmd(int cmd, FPWV * pFA, char * string, int strLen) -{ - int i,j; - FPW temp,temp1; - FPWV *str; - - str = (FPWV *)string; - - j= strLen/4; - - if(cmd == FLASH29_CMD_AUTOSELECT) - { - *(FLASH29_REG_FIRST_CYCLE) = FLASH29_CMD_FIRST; - *(FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND; - *(FLASH29_REG_THIRD_CYCLE) = FLASH29_CMD_AUTOSELECT; - } - - if(cmd == FLASH29_CMD_READ) - { - i = 0; - while(i<j) - { - temp = *pFA++; - temp1 = *(int *)0xa0000000; - *(int *)0xbf0081f8 = temp1 + temp; - *str++ = temp; - i++; - } - } - - if(cmd == FLASH29_CMD_READ_RESET) - { - *(FLASH29_REG_FIRST_CYCLE) = FLASH29_CMD_FIRST; - *(FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND; - *(FLASH29_REG_THIRD_CYCLE) = FLASH29_CMD_READ_RESET; - } - - *(int *)0xbf0081f8 = *(int *)0xa0000000; /* dummy read switch back to sdram interface */ -} - -/****************************************************************************** -* -* Don't change the program architecture -* This architecture assure the program -* can be relocated to scratch ram -*/ -static void flash_write_cmd(int cmd, FPWV * pFA, FPW value) -{ - *(FLASH29_REG_FIRST_CYCLE) = FLASH29_CMD_FIRST; - *(FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND; - - if (cmd == FLASH29_CMD_SECTOR) - { - *(FLASH29_REG_THIRD_CYCLE) = FLASH29_CMD_CHIP_ERASE; - *(FLASH29_REG_FOURTH_CYCLE) = FLASH29_CMD_FOURTH; - *(FLASH29_REG_FIFTH_CYCLE) = FLASH29_CMD_FIFTH; - *pFA = FLASH29_CMD_SECTOR; - } - - if (cmd == FLASH29_CMD_SIXTH) - { - *(FLASH29_REG_THIRD_CYCLE) = FLASH29_CMD_CHIP_ERASE; - *(FLASH29_REG_FOURTH_CYCLE) = FLASH29_CMD_FOURTH; - *(FLASH29_REG_FIFTH_CYCLE) = FLASH29_CMD_FIFTH; - *(FLASH29_REG_SIXTH_CYCLE) = FLASH29_CMD_SIXTH; - } - - if (cmd == FLASH29_CMD_PROGRAM) - { - *(FLASH29_REG_THIRD_CYCLE) = FLASH29_CMD_PROGRAM; - *pFA = value; - } - - if (cmd == FLASH29_CMD_READ_RESET) - { - *(FLASH29_REG_THIRD_CYCLE) = FLASH29_CMD_READ_RESET; - } - - *(int *)0xbf0081f8 = *(int *)0xa0000000; /* dummy read switch back to sdram interface */ -} - -static void load_cmd(ulong cmd) -{ - ulong *src; - ulong *dst; - FUNCPTR_CP absEntry; - ulong func; - - if (in_ram_cmd & cmd) return; - - if (cmd == IN_RAM_CMD_READ) - { - func = (ulong)flash_read_cmd; - } - else - { - func = (ulong)flash_write_cmd; - } - - src = (ulong *)(func & 0xfffffff8); - dst = (ulong *)0xbf008000; - absEntry = (FUNCPTR_CP)(0xbf0081d0); - absEntry(src,dst,0x38); - - in_ram_cmd = cmd; -} - -/*----------------------------------------------------------------------- - * flash_init() - * - * sets up flash_info and returns size of FLASH (bytes) - */ -unsigned long flash_init (void) -{ - unsigned long size = 0; - int i; - - load_cmd(IN_RAM_CMD_READ); - - /* Init: no FLASHes known */ - for (i=0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) { - ulong flashbase = PHYS_FLASH_1; - ulong * buscon = (ulong *) INCA_IP_EBU_EBU_BUSCON0; - - /* Disable write protection */ - *buscon &= ~INCA_IP_EBU_EBU_BUSCON1_WRDIS; - -#if 1 - memset(&flash_info[i], 0, sizeof(flash_info_t)); -#endif - - flash_info[i].size = - flash_get_size((FPW *)flashbase, &flash_info[i]); - - if (flash_info[i].flash_id == FLASH_UNKNOWN) { - printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx\n", - i, flash_info[i].size); - } - - size += flash_info[i].size; - } - -#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE - /* monitor protection ON by default */ - flash_protect(FLAG_PROTECT_SET, - CONFIG_SYS_MONITOR_BASE, - CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1, - flash_get_info(CONFIG_SYS_MONITOR_BASE)); -#endif - -#ifdef CONFIG_ENV_IS_IN_FLASH - /* ENV protection ON by default */ - flash_protect(FLAG_PROTECT_SET, - CONFIG_ENV_ADDR, - CONFIG_ENV_ADDR+CONFIG_ENV_SIZE-1, - flash_get_info(CONFIG_ENV_ADDR)); -#endif - - return size; -} - -/*----------------------------------------------------------------------- - */ -static void flash_get_offsets (ulong base, flash_info_t *info) -{ - int i; - - if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD - && (info->flash_id & FLASH_TYPEMASK) == FLASH_AM160B) { - - int bootsect_size[4]; /* number of bytes/boot sector */ - int sect_size; /* number of bytes/regular sector */ - - bootsect_size[0] = 0x00008000; - bootsect_size[1] = 0x00004000; - bootsect_size[2] = 0x00004000; - bootsect_size[3] = 0x00010000; - sect_size = 0x00020000; - - /* set sector offsets for bottom boot block type */ - for (i = 0; i < info->sector_count; i++) { - info->start[i] = base; - base += i < 4 ? bootsect_size[i] : sect_size; - } - } -} - -/*----------------------------------------------------------------------- - */ - -static flash_info_t *flash_get_info(ulong base) -{ - int i; - flash_info_t * info; - - for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i ++) { - info = & flash_info[i]; - if (info->start[0] <= base && base < info->start[0] + info->size) - break; - } - - return i == CONFIG_SYS_MAX_FLASH_BANKS ? 0 : info; -} - -/*----------------------------------------------------------------------- - */ - -void flash_print_info (flash_info_t *info) -{ - int i; - uchar *boottype; - uchar *bootletter; - char *fmt; - uchar botbootletter[] = "B"; - uchar topbootletter[] = "T"; - uchar botboottype[] = "bottom boot sector"; - uchar topboottype[] = "top boot sector"; - - if (info->flash_id == FLASH_UNKNOWN) { - printf ("missing or unknown FLASH type\n"); - return; - } - - switch (info->flash_id & FLASH_VENDMASK) { - case FLASH_MAN_AMD: printf ("AMD "); break; - case FLASH_MAN_BM: printf ("BRIGHT MICRO "); break; - case FLASH_MAN_FUJ: printf ("FUJITSU "); break; - case FLASH_MAN_SST: printf ("SST "); break; - case FLASH_MAN_STM: printf ("STM "); break; - case FLASH_MAN_INTEL: printf ("INTEL "); break; - default: printf ("Unknown Vendor "); break; - } - - /* check for top or bottom boot, if it applies */ - if (info->flash_id & FLASH_BTYPE) { - boottype = botboottype; - bootletter = botbootletter; - } - else { - boottype = topboottype; - bootletter = topbootletter; - } - - switch (info->flash_id & FLASH_TYPEMASK) { - case FLASH_AM160B: - fmt = "29LV160B%s (16 Mbit, %s)\n"; - break; - case FLASH_28F800C3B: - case FLASH_28F800C3T: - fmt = "28F800C3%s (8 Mbit, %s)\n"; - break; - case FLASH_INTEL800B: - case FLASH_INTEL800T: - fmt = "28F800B3%s (8 Mbit, %s)\n"; - break; - case FLASH_28F160C3B: - case FLASH_28F160C3T: - fmt = "28F160C3%s (16 Mbit, %s)\n"; - break; - case FLASH_INTEL160B: - case FLASH_INTEL160T: - fmt = "28F160B3%s (16 Mbit, %s)\n"; - break; - case FLASH_28F320C3B: - case FLASH_28F320C3T: - fmt = "28F320C3%s (32 Mbit, %s)\n"; - break; - case FLASH_INTEL320B: - case FLASH_INTEL320T: - fmt = "28F320B3%s (32 Mbit, %s)\n"; - break; - case FLASH_28F640C3B: - case FLASH_28F640C3T: - fmt = "28F640C3%s (64 Mbit, %s)\n"; - break; - case FLASH_INTEL640B: - case FLASH_INTEL640T: - fmt = "28F640B3%s (64 Mbit, %s)\n"; - break; - default: - fmt = "Unknown Chip Type\n"; - break; - } - - printf (fmt, bootletter, boottype); - - 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"); -} - -/*----------------------------------------------------------------------- - */ - -/* - * The following code cannot be run from FLASH! - */ - -ulong flash_get_size (FPWV *addr, flash_info_t *info) -{ - FUNCPTR_RD absEntry; - FPW retValue; - int flag; - - load_cmd(IN_RAM_CMD_READ); - absEntry = (FUNCPTR_RD)FLASH_READ_CMD; - - flag = disable_interrupts(); - absEntry(FLASH29_CMD_AUTOSELECT,0,0,0); - if (flag) enable_interrupts(); - - udelay(100); - - flag = disable_interrupts(); - absEntry(FLASH29_CMD_READ, addr + 1, (char *)&retValue, sizeof(retValue)); - absEntry(FLASH29_CMD_READ_RESET,0,0,0); - if (flag) enable_interrupts(); - - udelay(100); - - switch (retValue) { - - case (FPW)AMD_ID_LV160B: - info->flash_id += FLASH_AM160B; - info->sector_count = 35; - info->size = 0x00400000; - break; /* => 8 or 16 MB */ - - default: - info->flash_id = FLASH_UNKNOWN; - info->sector_count = 0; - info->size = 0; - return (0); /* => no or unknown flash */ - } - - flash_get_offsets((ulong)addr, info); - - return (info->size); -} - -/*----------------------------------------------------------------------- - */ - -int flash_erase (flash_info_t *info, int s_first, int s_last) -{ - FPWV *addr; - int flag, prot, sect; - ulong start, now, last; - FUNCPTR_WR absEntry; - - load_cmd(IN_RAM_CMD_WRITE); - absEntry = (FUNCPTR_WR)FLASH_WRITE_CMD; - - if ((s_first < 0) || (s_first > s_last)) { - if (info->flash_id == FLASH_UNKNOWN) { - printf ("- missing\n"); - } else { - printf ("- no sectors to erase\n"); - } - return 1; - } - - switch (info->flash_id & FLASH_TYPEMASK) { - case FLASH_AM160B: - break; - case FLASH_UNKNOWN: - default: - printf ("Can't erase unknown flash type %08lx - aborted\n", - info->flash_id); - return 1; - } - - 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"); - } - - last = get_timer(0); - - /* Start erase on unprotected sectors */ - for (sect = s_first; sect<=s_last; sect++) { - - if (info->protect[sect] != 0) /* protected, skip it */ - continue; - - /* Disable interrupts which might cause a timeout here */ - flag = disable_interrupts(); - - addr = (FPWV *)(info->start[sect]); - absEntry(FLASH29_CMD_SECTOR, addr, 0); - - /* re-enable interrupts if necessary */ - if (flag) - enable_interrupts(); - - start = get_timer(0); - - while ((now = get_timer(start)) <= CONFIG_SYS_FLASH_ERASE_TOUT) { - - /* show that we're waiting */ - if ((get_timer(last)) > CONFIG_SYS_HZ) {/* every second */ - putc ('.'); - last = get_timer(0); - } - } - - flag = disable_interrupts(); - absEntry(FLASH29_CMD_READ_RESET,0,0); - if (flag) - enable_interrupts(); - } - - printf (" done\n"); - return 0; -} - -/*----------------------------------------------------------------------- - * Copy memory to flash, returns: - * 0 - OK - * 1 - write timeout - * 2 - Flash not erased - */ -int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) -{ - FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */ - int bytes; /* number of bytes to program in current word */ - int left; /* number of bytes left to program */ - int i, res; - - for (left = cnt, res = 0; - left > 0 && res == 0; - addr += sizeof(data), left -= sizeof(data) - bytes) { - - bytes = addr & (sizeof(data) - 1); - addr &= ~(sizeof(data) - 1); - - /* combine source and destination data so can program - * an entire word of 16 or 32 bits - */ - for (i = 0; i < sizeof(data); i++) { - data <<= 8; - if (i < bytes || i - bytes >= left ) - data += *((uchar *)addr + i); - else - data += *src++; - } - - res = write_word(info, (FPWV *)addr, data); - } - - return (res); -} - -static int write_word (flash_info_t *info, FPWV *dest, FPW data) -{ - int res = 0; /* result, assume success */ - FUNCPTR_WR absEntry; - int flag; - - /* Check if Flash is (sufficiently) erased */ - if ((*dest & data) != data) { - return (2); - } - - if (info->start[0] != PHYS_FLASH_1) - { - return (3); - } - - load_cmd(IN_RAM_CMD_WRITE); - absEntry = (FUNCPTR_WR)FLASH_WRITE_CMD; - - flag = disable_interrupts(); - absEntry(FLASH29_CMD_PROGRAM,dest,data); - if (flag) enable_interrupts(); - - udelay(100); - - flag = disable_interrupts(); - absEntry(FLASH29_CMD_READ_RESET,0,0); - if (flag) enable_interrupts(); - - return (res); -} |