diff options
Diffstat (limited to 'board/amcc/bamboo/flash.c')
-rw-r--r-- | board/amcc/bamboo/flash.c | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/board/amcc/bamboo/flash.c b/board/amcc/bamboo/flash.c new file mode 100644 index 0000000..97a4b98 --- /dev/null +++ b/board/amcc/bamboo/flash.c @@ -0,0 +1,166 @@ +/* + * (C) Copyright 2004-2005 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2002 Jun Gu <jung@artesyncp.com> + * Add support for Am29F016D and dynamic switch setting. + * + * 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 + */ + +/* + * Modified 4/5/2001 + * Wait for completion of each sector erase command issued + * 4/5/2001 + * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com + */ + +#include <common.h> +#include <ppc4xx.h> +#include <asm/processor.h> +#include <ppc440.h> +#include "bamboo.h" + +#undef DEBUG + +#ifdef DEBUG +#define DEBUGF(x...) printf(x) +#else +#define DEBUGF(x...) +#endif /* DEBUG */ + +flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */ + +/* + * Mark big flash bank (16 bit instead of 8 bit access) in address with bit 0 + */ +static unsigned long flash_addr_table[8][CFG_MAX_FLASH_BANKS] = { + {0x87800001, 0xFFF00000, 0xFFF80000}, /* 0:boot from small flash */ + {0x00000000, 0x00000000, 0x00000000}, /* 1:boot from pci 66 */ + {0x00000000, 0x00000000, 0x00000000}, /* 2:boot from nand flash */ + {0x87800000, 0x87880000, 0xFF800001}, /* 3:boot from big flash 33*/ + {0x87800000, 0x87880000, 0xFF800001}, /* 4:boot from big flash 66*/ + {0x00000000, 0x00000000, 0x00000000}, /* 5:boot from */ + {0x00000000, 0x00000000, 0x00000000}, /* 6:boot from pci 66 */ + {0x00000000, 0x00000000, 0x00000000}, /* 7:boot from */ +}; + +/* + * include common flash code (for amcc boards) + */ +#include "../common/flash.c" + +/*----------------------------------------------------------------------- + * Functions + */ +static ulong flash_get_size(vu_long * addr, flash_info_t * info); +static int write_word(flash_info_t * info, ulong dest, ulong data); + +/*----------------------------------------------------------------------- + */ + +unsigned long flash_init(void) +{ + unsigned long total_b = 0; + unsigned long size_b[CFG_MAX_FLASH_BANKS]; + unsigned short index = 0; + int i; + unsigned long val; + unsigned long ebc_boot_size; + unsigned long boot_selection; + + mfsdr(sdr_pstrp0, val); + index = (val & SDR0_PSTRP0_BOOTSTRAP_MASK) >> 29; + + if ((index == 5) || (index == 7)) { + /* + * Boot Settings in IIC EEprom address 0xA8 or 0xA4 + * Read Serial Device Strap Register1 in PPC440EP + */ + mfsdr(sdr_sdstp1, val); + boot_selection = val & SDR0_SDSTP1_BOOT_SEL_MASK; + ebc_boot_size = val & SDR0_SDSTP1_EBC_ROM_BS_MASK; + + switch(boot_selection) { + case SDR0_SDSTP1_BOOT_SEL_EBC: + switch(ebc_boot_size) { + case SDR0_SDSTP1_EBC_ROM_BS_16BIT: + index = 3; + break; + case SDR0_SDSTP1_EBC_ROM_BS_8BIT: + index = 0; + break; + } + break; + + case SDR0_SDSTP1_BOOT_SEL_PCI: + index = 1; + break; + + case SDR0_SDSTP1_BOOT_SEL_NDFC: + index = 2; + break; + } + } + + DEBUGF("\n"); + DEBUGF("FLASH: Index: %d\n", index); + + /* Init: no FLASHes known */ + for (i = 0; i < CFG_MAX_FLASH_BANKS; ++i) { + flash_info[i].flash_id = FLASH_UNKNOWN; + flash_info[i].sector_count = -1; + flash_info[i].size = 0; + + /* check whether the address is 0 */ + if (flash_addr_table[index][i] == 0) { + continue; + } + + /* call flash_get_size() to initialize sector address */ + size_b[i] = flash_get_size((vu_long *) flash_addr_table[index][i], + &flash_info[i]); + flash_info[i].size = size_b[i]; + if (flash_info[i].flash_id == FLASH_UNKNOWN) { + printf("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n", + i, size_b[i], size_b[i] << 20); + flash_info[i].sector_count = -1; + flash_info[i].size = 0; + } + + /* Monitor protection ON by default */ + (void)flash_protect(FLAG_PROTECT_SET, CFG_MONITOR_BASE, + CFG_MONITOR_BASE + CFG_MONITOR_LEN - 1, + &flash_info[i]); +#if defined(CFG_ENV_IS_IN_FLASH) + (void)flash_protect(FLAG_PROTECT_SET, CFG_ENV_ADDR, + CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1, + &flash_info[i]); +#if defined(CFG_ENV_IS_IN_FLASH) && defined(CFG_ENV_ADDR_REDUND) + (void)flash_protect(FLAG_PROTECT_SET, CFG_ENV_ADDR_REDUND, + CFG_ENV_ADDR_REDUND + CFG_ENV_SECT_SIZE - 1, + &flash_info[i]); +#endif +#endif + + total_b += flash_info[i].size; + } + + return total_b; +} |