diff options
Diffstat (limited to 'board')
| -rw-r--r-- | board/mpl/common/common_util.c | 202 | ||||
| -rw-r--r-- | board/mpl/common/common_util.h | 4 | ||||
| -rw-r--r-- | board/mpl/common/flash.c | 872 | 
3 files changed, 182 insertions, 896 deletions
| diff --git a/board/mpl/common/common_util.c b/board/mpl/common/common_util.c index d3300ed68..a61a98cf7 100644 --- a/board/mpl/common/common_util.c +++ b/board/mpl/common/common_util.c @@ -53,13 +53,156 @@ extern int mem_test(ulong start, ulong ramsize, int quiet);  #define I2C_BACKUP_ADDR 0x7C00		/* 0x200 bytes for backup */  #define IMAGE_SIZE CONFIG_SYS_MONITOR_LEN	/* ugly, but it works for now */ -extern flash_info_t flash_info[];	/* info for FLASH chips */ +#if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) +/*----------------------------------------------------------------------- + * On PIP/MIP405 we have 3 (4) possible boot mode + * + * - Boot from Flash (Flash CS = CS0, MPS CS = CS1) + * - Boot from MPS   (Flash CS = CS1, MPS CS = CS0) + * - Boot from PCI with Flash map (Flash CS = CS0, MPS CS = CS1) + * - Boot from PCI with MPS map   (Flash CS = CS1, MPS CS = CS0) + * The flash init is the first board specific routine which is called + * after code relocation (running from SDRAM) + * The first thing we do is to map the Flash CS to the Flash area and + * the MPS CS to the MPS area. Since the flash size is unknown at this + * point, we use the max flash size and the lowest flash address as base. + * + * After flash detection we adjust the size of the CS area accordingly. + * update_flash_size() will fix in wrong values in the flash_info structure, + * misc_init_r() will fix the values in the board info structure + */ +int get_boot_mode(void) +{ +	unsigned long pbcr; +	int res = 0; +	pbcr = mfdcr(CPC0_PSR); +	if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) +		/* boot via MPS or MPS mapping */ +		res = BOOT_MPS; +	if (pbcr & PSR_ROM_LOC) +		/* boot via PCI.. */ +		res |= BOOT_PCI; +	 return res; +} + +/* Map the flash high (in boot area) +   This code can only be executed from SDRAM (after relocation). +*/ +void setup_cs_reloc(void) +{ +	int mode; +	/* +	 * since we are relocated, we can set-up the CS finaly +	 * but first of all, switch off PCI mapping (in case it +	 * was a PCI boot) +	 */ +	out32r(PMM0MA, 0L); +	/* get boot mode */ +	mode = get_boot_mode(); +	/* +	 * we map the flash high in every case +	 * first find out to which CS the flash is attached to +	 */ +	if (mode & BOOT_MPS) { +		/* map flash high on CS1 and MPS on CS0 */ +		mtdcr(EBC0_CFGADDR, PB0AP); +		mtdcr(EBC0_CFGDATA, MPS_AP); +		mtdcr(EBC0_CFGADDR, PB0CR); +		mtdcr(EBC0_CFGDATA, MPS_CR); +		/* +		 * we use the default values (max values) for the flash +		 * because its real size is not yet known +		 */ +		mtdcr(EBC0_CFGADDR, PB1AP); +		mtdcr(EBC0_CFGDATA, FLASH_AP); +		mtdcr(EBC0_CFGADDR, PB1CR); +		mtdcr(EBC0_CFGDATA, FLASH_CR_B); +	} else { +		/* map flash high on CS0 and MPS on CS1 */ +		mtdcr(EBC0_CFGADDR, PB1AP); +		mtdcr(EBC0_CFGDATA, MPS_AP); +		mtdcr(EBC0_CFGADDR, PB1CR); +		mtdcr(EBC0_CFGDATA, MPS_CR); +		/* +		 * we use the default values (max values) for the flash +		 * because its real size is not yet known +		 */ +		mtdcr(EBC0_CFGADDR, PB0AP); +		mtdcr(EBC0_CFGDATA, FLASH_AP); +		mtdcr(EBC0_CFGADDR, PB0CR); +		mtdcr(EBC0_CFGDATA, FLASH_CR_B); +	} +} +#endif /* #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) */ + +#ifdef CONFIG_SYS_UPDATE_FLASH_SIZE +/* adjust flash start and protection info */ +int update_flash_size(int flash_size) +{ +	int i = 0, mode; +	flash_info_t *info = &flash_info[0]; +	unsigned long flashcr; +	unsigned long flash_base = (0 - flash_size) & 0xFFF00000; + +	if (flash_size > 128*1024*1024) { +		printf("\n ### ERROR, wrong flash size: %X, reset board ###\n", +		       flash_size); +		hang(); +	} + +	if ((flash_size >> 20) != 0) +		i = __ilog2(flash_size >> 20); + +	/* set up flash CS according to the size */ +	mode = get_boot_mode(); +	if (mode & BOOT_MPS) { +		/* flash is on CS1 */ +		mtdcr(EBC0_CFGADDR, PB1CR); +		flashcr = mfdcr(EBC0_CFGDATA); +		/* we map the flash high in every case */ +		flashcr &= 0x0001FFFF; /* mask out address bits */ +		flashcr |= flash_base; /* start addr */ +		flashcr |= (i << 17); /* size addr */ +		mtdcr(EBC0_CFGADDR, PB1CR); +		mtdcr(EBC0_CFGDATA, flashcr); +	} else { +		/* flash is on CS0 */ +		mtdcr(EBC0_CFGADDR, PB0CR); +		flashcr = mfdcr(EBC0_CFGDATA); +		/* we map the flash high in every case */ +		flashcr &= 0x0001FFFF; /* mask out address bits */ +		flashcr |= flash_base; /* start addr */ +		flashcr |= (i << 17); /* size addr */ +		mtdcr(EBC0_CFGADDR, PB0CR); +		mtdcr(EBC0_CFGDATA, flashcr); +	} + +	for (i = 0; i < info->sector_count; i++) +		/* adjust sector start address */ +		info->start[i] = flash_base + +				(info->start[i] - CONFIG_SYS_FLASH_BASE); + +	/* unprotect all sectors */ +	flash_protect(FLAG_PROTECT_CLEAR, +		      info->start[0], +		      0xFFFFFFFF, +		      info); +	flash_protect_default(); +	/* protect reset vector too*/ +	flash_protect(FLAG_PROTECT_SET, +		      info->start[info->sector_count-1], +		      0xFFFFFFFF, +		      info); + +	return 0; +} +#endif  static int  mpl_prg(uchar *src, ulong size)  {  	ulong start; -	flash_info_t *info; +	flash_info_t *info = &flash_info[0];  	int i, rc;  #if defined(CONFIG_PATI)  	int start_sect; @@ -69,8 +212,6 @@ mpl_prg(uchar *src, ulong size)  	ulong *magic = (ulong *)src;  #endif -	info = &flash_info[0]; -  #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405) || defined(CONFIG_PATI)  	if (uimage_to_cpu (magic[0]) != IH_MAGIC) {  		puts("Bad Magic number\n"); @@ -96,12 +237,18 @@ mpl_prg(uchar *src, ulong size)  	}  #if !defined(CONFIG_PATI)  	start = 0 - size; -	for (i = info->sector_count-1; i > 0; i--) { -		info->protect[i] = 0; /* unprotect this sector */ + +	/* unprotect sectors used by u-boot */ +	flash_protect(FLAG_PROTECT_CLEAR, +		      start, +		      0xFFFFFFFF, +		      info); + +	/* search start sector */ +	for (i = info->sector_count-1; i > 0; i--)  		if (start >= info->start[i])  			break; -	} -	/* set-up flash location */ +  	/* now erase flash */  	printf("Erasing at %lx (sector %d) (start %lx)\n",  				start,i,info->start[i]); @@ -114,22 +261,24 @@ mpl_prg(uchar *src, ulong size)  #else /* #if !defined(CONFIG_PATI */  	start = FIRM_START;  	start_sect = -1; -	for (i = 0; i < info->sector_count; i++) { -		if (start < info->start[i]) { -			start_sect = i - 1; + +	/* search start sector */ +	for (i = info->sector_count-1; i > 0; i--) +		if (start >= info->start[i])  			break; -		} -	} -	info->protect[i - 1] = 0;	/* unprotect this sector */ -	for (; i < info->sector_count; i++) { -		if ((start + size) < info->start[i]) +	start_sect = i; + +	for (i = info->sector_count-1; i > 0; i--) +		if ((start + size) >= info->start[i])  			break; -		info->protect[i] = 0;	/* unprotect this sector */ -	} -	i--; -	/* set-up flash location */ +	/* unprotect sectors used by u-boot */ +	flash_protect(FLAG_PROTECT_CLEAR, +		      start, +		      start + size, +		      info); +  	/* now erase flash */  	printf ("Erasing at %lx to %lx (sector %d to %d) (%lx to %lx)\n",  		start, start + size, start_sect, i, @@ -143,12 +292,17 @@ mpl_prg(uchar *src, ulong size)  #elif defined(CONFIG_VCMA9)  	start = 0; -	for (i = 0; i <info->sector_count; i++) { -		info->protect[i] = 0; /* unprotect this sector */ + +	/* search end sector */ +	for (i = 0; i < info->sector_count; i++)  		if (size < info->start[i])  		    break; -	} -	/* set-up flash location */ + +	flash_protect(FLAG_PROTECT_CLEAR, +		      start, +		      size, +		      info); +  	/* now erase flash */  	printf("Erasing at %lx (sector %d) (start %lx)\n",  				start,0,info->start[0]); diff --git a/board/mpl/common/common_util.h b/board/mpl/common/common_util.h index 29cd14fa6..a0ea23974 100644 --- a/board/mpl/common/common_util.h +++ b/board/mpl/common/common_util.h @@ -30,11 +30,15 @@ typedef struct {  	char eth_addr[21];	/* "00:60:C2:0a:00:00" */  } backup_t; +extern flash_info_t flash_info[];	/* info for FLASH chips */ +  void get_backup_values(backup_t *buf);  #if defined(CONFIG_PIP405) || defined(CONFIG_MIP405)  #define BOOT_MPS	0x01  #define BOOT_PCI	0x02 +int get_boot_mode(void); +void setup_cs_reloc(void);  #endif  void check_env(void); diff --git a/board/mpl/common/flash.c b/board/mpl/common/flash.c deleted file mode 100644 index d5b63c019..000000000 --- a/board/mpl/common/flash.c +++ /dev/null @@ -1,872 +0,0 @@ -/* - * (C) Copyright 2000, 2001 - * 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 - */ - -/* - * Modified 4/5/2001 - * Wait for completion of each sector erase command issued - * 4/5/2001 - * Chris Hallinan - DS4.COM, Inc. - clh@net1plus.com - */ - -/* - * Modified 3/7/2001 - * - adapted for pip405, Denis Peter, MPL AG Switzerland - * TODO: - * clean-up - */ - -#include <common.h> - -#if !defined(CONFIG_PATI) -#include <asm/ppc4xx.h> -#include <asm/processor.h> -#include "common_util.h" -#if defined(CONFIG_MIP405) -#include "../mip405/mip405.h" -#endif -#if defined(CONFIG_PIP405) -#include "../pip405/pip405.h" -#endif -#include <asm/4xx_pci.h> -#else /* defined(CONFIG_PATI) */ -#include <mpc5xx.h> -#endif - -flash_info_t	flash_info[CONFIG_SYS_MAX_FLASH_BANKS]; /* info for FLASH chips	*/ -/*----------------------------------------------------------------------- - * 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); - -void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt); - -#define ADDR0           0x5555 -#define ADDR1           0x2aaa -#define FLASH_WORD_SIZE unsigned short - -#define FALSE           0 -#define TRUE            1 - -#if !defined(CONFIG_PATI) - -/*----------------------------------------------------------------------- - * Some CS switching routines: - * - * On PIP/MIP405 we have 3 (4) possible boot mode - * - * - Boot from Flash (Flash CS = CS0, MPS CS = CS1) - * - Boot from MPS   (Flash CS = CS1, MPS CS = CS0) - * - Boot from PCI with Flash map (Flash CS = CS0, MPS CS = CS1) - * - Boot from PCI with MPS map   (Flash CS = CS1, MPS CS = CS0) - * The flash init is the first board specific routine which is called - * after code relocation (running from SDRAM) - * The first thing we do is to map the Flash CS to the Flash area and - * the MPS CS to the MPS area. Since the flash size is unknown at this - * point, we use the max flash size and the lowest flash address as base. - * - * After flash detection we adjust the size of the CS area accordingly. - * The board_init_r will fill in wrong values in the board init structure, - * but this will be fixed in the misc_init_r routine: - * bd->bi_flashstart=0-flash_info[0].size - * bd->bi_flashsize=flash_info[0].size-CONFIG_SYS_MONITOR_LEN - * bd->bi_flashoffset=0 - * - */ -int get_boot_mode(void) -{ -	unsigned long pbcr; -	int res = 0; -	pbcr = mfdcr (CPC0_PSR); -	if ((pbcr & PSR_ROM_WIDTH_MASK) == 0) -		/* boot via MPS or MPS mapping */ -		res = BOOT_MPS; -	if(pbcr & PSR_ROM_LOC) -		/* boot via PCI.. */ -		res |= BOOT_PCI; -	 return res; -} - -/* Map the flash high (in boot area) -   This code can only be executed from SDRAM (after relocation). -*/ -void setup_cs_reloc(void) -{ -	int mode; -	/* Since we are relocated, we can set-up the CS finaly -	 * but first of all, switch off PCI mapping (in case it was a PCI boot) */ -	out32r(PMM0MA,0L); -	icache_enable (); /* we are relocated */ -	/* get boot mode */ -	mode=get_boot_mode(); -	/* we map the flash high in every case */ -	/* first findout on which cs the flash is */ -	if(mode & BOOT_MPS) { -		/* map flash high on CS1 and MPS on CS0 */ -		mtdcr (EBC0_CFGADDR, PB0AP); -		mtdcr (EBC0_CFGDATA, MPS_AP); -		mtdcr (EBC0_CFGADDR, PB0CR); -		mtdcr (EBC0_CFGDATA, MPS_CR); -		/* we use the default values (max values) for the flash -		 * because its real size is not yet known */ -		mtdcr (EBC0_CFGADDR, PB1AP); -		mtdcr (EBC0_CFGDATA, FLASH_AP); -		mtdcr (EBC0_CFGADDR, PB1CR); -		mtdcr (EBC0_CFGDATA, FLASH_CR_B); -	} -	else { -		/* map flash high on CS0 and MPS on CS1 */ -		mtdcr (EBC0_CFGADDR, PB1AP); -		mtdcr (EBC0_CFGDATA, MPS_AP); -		mtdcr (EBC0_CFGADDR, PB1CR); -		mtdcr (EBC0_CFGDATA, MPS_CR); -		/* we use the default values (max values) for the flash -		 * because its real size is not yet known */ -		mtdcr (EBC0_CFGADDR, PB0AP); -		mtdcr (EBC0_CFGDATA, FLASH_AP); -		mtdcr (EBC0_CFGADDR, PB0CR); -		mtdcr (EBC0_CFGDATA, FLASH_CR_B); -	} -} - -#endif /* #if !defined(CONFIG_PATI) */ - -unsigned long flash_init (void) -{ -	unsigned long size_b0; -	int i; - -#if !defined(CONFIG_PATI) -	unsigned long flashcr,size_reg; -	int mode; -	extern char version_string; -	char *p = &version_string; - -	/* Since we are relocated, we can set-up the CS finally */ -	setup_cs_reloc(); -	/* get and display boot mode */ -	mode=get_boot_mode(); -	if(mode & BOOT_PCI) -		printf("(PCI Boot %s Map) ",(mode & BOOT_MPS) ? -			"MPS" : "Flash"); -	else -		printf("(%s Boot) ",(mode & BOOT_MPS) ? -			"MPS" : "Flash"); -#endif /* #if !defined(CONFIG_PATI) */ -	/* Init: no FLASHes known */ -	for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) { -		flash_info[i].flash_id = FLASH_UNKNOWN; -	} - -	/* Static FLASH Bank configuration here - FIXME XXX */ - -	size_b0 = flash_get_size((vu_long *)CONFIG_SYS_MONITOR_BASE, &flash_info[0]); - -	if (flash_info[0].flash_id == FLASH_UNKNOWN) { -		printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n", -			size_b0, size_b0<<20); -	} -	/* protect the bootloader */ -	/* Monitor protection ON by default */ -#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE -	flash_protect(FLAG_PROTECT_SET, -			CONFIG_SYS_MONITOR_BASE, -			CONFIG_SYS_MONITOR_BASE+monitor_flash_len-1, -			&flash_info[0]); -#endif -#if !defined(CONFIG_PATI) -	/* protect reset vector */ -	flash_info[0].protect[flash_info[0].sector_count-1] = 1; -	flash_info[0].size = size_b0; -	/* set up flash cs according to the size */ -	size_reg=(flash_info[0].size >>20); -	switch (size_reg) { -		case 0: -		case 1: i=0; break; /* <= 1MB */ -		case 2: i=1; break; /* = 2MB */ -		case 4: i=2; break; /* = 4MB */ -		case 8: i=3; break; /* = 8MB */ -		case 16: i=4; break; /* = 16MB */ -		case 32: i=5; break; /* = 32MB */ -		case 64: i=6; break; /* = 64MB */ -		case 128: i=7; break; /*= 128MB */ -		default: -			printf("\n #### ERROR, wrong size %ld MByte reset board #####\n",size_reg); -			while(1); -	} -	if(mode & BOOT_MPS) { -		/* flash is on CS1 */ -		mtdcr(EBC0_CFGADDR, PB1CR); -		flashcr = mfdcr (EBC0_CFGDATA); -		/* we map the flash high in every case */ -		flashcr&=0x0001FFFF; /* mask out address bits */ -		flashcr|= ((0-flash_info[0].size) & 0xFFF00000); /* start addr */ -		flashcr|= (i << 17); /* size addr */ -		mtdcr(EBC0_CFGADDR, PB1CR); -		mtdcr(EBC0_CFGDATA, flashcr); -	} -	else { -		/* flash is on CS0 */ -		mtdcr(EBC0_CFGADDR, PB0CR); -		flashcr = mfdcr (EBC0_CFGDATA); -		/* we map the flash high in every case */ -		flashcr&=0x0001FFFF; /* mask out address bits */ -		flashcr|= ((0-flash_info[0].size) & 0xFFF00000); /* start addr */ -		flashcr|= (i << 17); /* size addr */ -		mtdcr(EBC0_CFGADDR, PB0CR); -		mtdcr(EBC0_CFGDATA, flashcr); -	} -#if 0 -	/* enable this (PIP405/MIP405 only) if you want to test if -	   the relocation has be done ok. -	   This will disable both Chipselects */ -	mtdcr (EBC0_CFGADDR, PB0CR); -	mtdcr (EBC0_CFGDATA, 0L); -	mtdcr (EBC0_CFGADDR, PB1CR); -	mtdcr (EBC0_CFGDATA, 0L); -	printf("CS0 & CS1 switched off for test\n"); -#endif -	/* patch version_string */ -	for(i=0;i<0x100;i++) { -		if(*p=='\n') { -			*p=0; -			break; -		} -		p++; -	} -#else /* #if !defined(CONFIG_PATI) */ -#ifdef	CONFIG_ENV_IS_IN_FLASH -	/* ENV protection ON by default */ -	flash_protect(FLAG_PROTECT_SET, -		      CONFIG_ENV_ADDR, -		      CONFIG_ENV_ADDR+CONFIG_ENV_SECT_SIZE-1, -		      &flash_info[0]); -#endif -#endif /* #if !defined(CONFIG_PATI) */ -	return (size_b0); -} - - -/*----------------------------------------------------------------------- - */ -void flash_print_info  (flash_info_t *info) -{ -	int i; -	int k; -	int size; -	int erased; -	volatile unsigned long *flash; - -	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_FUJ:	printf ("FUJITSU ");		break; -	case FLASH_MAN_SST:	printf ("SST ");		break; -	case FLASH_MAN_INTEL:	printf ("Intel ");		break; -	default:		printf ("Unknown Vendor ");	break; -	} - -	switch (info->flash_id & FLASH_TYPEMASK) { -	case FLASH_AM040:	printf ("AM29F040 (512 Kbit, uniform sector size)\n"); -				break; -	case FLASH_AM400B:	printf ("AM29LV400B (4 Mbit, bottom boot sect)\n"); -				break; -	case FLASH_AM400T:	printf ("AM29LV400T (4 Mbit, top boot sector)\n"); -				break; -	case FLASH_AM800B:	printf ("AM29LV800B (8 Mbit, bottom boot sect)\n"); -				break; -	case FLASH_AM800T:	printf ("AM29LV800T (8 Mbit, top boot sector)\n"); -				break; -	case FLASH_AM160B:	printf ("AM29LV160B (16 Mbit, bottom boot sect)\n"); -				break; -	case FLASH_AM160T:	printf ("AM29LV160T (16 Mbit, top boot sector)\n"); -				break; -	case FLASH_AM320B:	printf ("AM29LV320B (32 Mbit, bottom boot sect)\n"); -				break; -	case FLASH_AM320T:	printf ("AM29LV320T (32 Mbit, top boot sector)\n"); -				break; -	case FLASH_SST800A:	printf ("SST39LF/VF800 (8 Mbit, uniform sector size)\n"); -				break; -	case FLASH_SST160A:	printf ("SST39LF/VF160 (16 Mbit, uniform sector size)\n"); -				break; -	case FLASH_INTEL320T:	printf ("TE28F320C3 (32 Mbit, top sector size)\n"); -				break; -	case FLASH_AM640U:	printf ("AM29LV640U (64 Mbit, uniform sector size)\n"); -				break; -	default:		printf ("Unknown Chip Type\n"); -				break; -	} - -	printf ("  Size: %ld KB in %d Sectors\n", -		info->size >> 10, info->sector_count); - -	printf ("  Sector Start Addresses:"); -	for (i=0; i<info->sector_count; ++i) { -		/* -		 * Check if whole sector is erased -		*/ -		if (i != (info->sector_count-1)) -			size = info->start[i+1] - info->start[i]; -		else -			size = info->start[0] + info->size - info->start[i]; -		erased = 1; -		flash = (volatile unsigned long *)info->start[i]; -		size = size >> 2;        /* divide by 4 for longword access */ -		for (k=0; k<size; k++) { -			if (*flash++ != 0xffffffff) { -				erased = 0; -				break; -			} -		} -		if ((i % 5) == 0) -			printf ("\n   "); -		printf (" %08lX%s%s", -			info->start[i], -			erased ? " E" : "  ", -			info->protect[i] ? "RO " : "   "); -	} -	printf ("\n"); -} - -/*----------------------------------------------------------------------- - */ - - -/*----------------------------------------------------------------------- - -*/ - -/* - * The following code cannot be run from FLASH! - */ -static ulong flash_get_size (vu_long *addr, flash_info_t *info) -{ -	short i; -	FLASH_WORD_SIZE value; -	ulong base; -	volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)addr; - -	/* Write auto select command: read Manufacturer ID */ -	addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; -	addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055; -	addr2[ADDR0] = (FLASH_WORD_SIZE)0x00900090; - -	value = addr2[0]; -	/*	printf("flash_get_size value: %x\n",value); */ -	switch (value) { -	case (FLASH_WORD_SIZE)AMD_MANUFACT: -		info->flash_id = FLASH_MAN_AMD; -		break; -	case (FLASH_WORD_SIZE)FUJ_MANUFACT: -		info->flash_id = FLASH_MAN_FUJ; -		break; -	case (FLASH_WORD_SIZE)INTEL_MANUFACT: -		info->flash_id = FLASH_MAN_INTEL; -		break; -	case (FLASH_WORD_SIZE)SST_MANUFACT: -		info->flash_id = FLASH_MAN_SST; -		break; -	default: -		info->flash_id = FLASH_UNKNOWN; -		info->sector_count = 0; -		info->size = 0; -		return (0);			/* no or unknown flash	*/ -	} -	value = addr2[1];			/* device ID		*/ -	/*	printf("Device value %x\n",value);		    */ -	switch (value) { -	case (FLASH_WORD_SIZE)AMD_ID_F040B: -		info->flash_id += FLASH_AM040; -		info->sector_count = 8; -		info->size = 0x0080000; /* => 512 ko */ -		break; -	case (FLASH_WORD_SIZE)AMD_ID_LV400T: -		info->flash_id += FLASH_AM400T; -		info->sector_count = 11; -		info->size = 0x00080000; -		break;				/* => 0.5 MB		*/ - -	case (FLASH_WORD_SIZE)AMD_ID_LV400B: -		info->flash_id += FLASH_AM400B; -		info->sector_count = 11; -		info->size = 0x00080000; -		break;				/* => 0.5 MB		*/ - -	case (FLASH_WORD_SIZE)AMD_ID_LV800T: -		info->flash_id += FLASH_AM800T; -		info->sector_count = 19; -		info->size = 0x00100000; -		break;				/* => 1 MB		*/ - -	case (FLASH_WORD_SIZE)AMD_ID_LV800B: -		info->flash_id += FLASH_AM800B; -		info->sector_count = 19; -		info->size = 0x00100000; -		break;				/* => 1 MB		*/ - -	case (FLASH_WORD_SIZE)AMD_ID_LV160T: -		info->flash_id += FLASH_AM160T; -		info->sector_count = 35; -		info->size = 0x00200000; -		break;				/* => 2 MB		*/ - -	case (FLASH_WORD_SIZE)AMD_ID_LV160B: -		info->flash_id += FLASH_AM160B; -		info->sector_count = 35; -		info->size = 0x00200000; -		break;				/* => 2 MB		*/ -	case (FLASH_WORD_SIZE)AMD_ID_LV320T: -		info->flash_id += FLASH_AM320T; -		info->sector_count = 67; -		info->size = 0x00400000; -		break;				/* => 4 MB		*/ -	case (FLASH_WORD_SIZE)AMD_ID_LV640U: -		info->flash_id += FLASH_AM640U; -		info->sector_count = 128; -		info->size = 0x00800000; -		break;				/* => 8 MB		*/ -#if 0	/* enable when device IDs are available */ - -	case (FLASH_WORD_SIZE)AMD_ID_LV320B: -		info->flash_id += FLASH_AM320B; -		info->sector_count = 67; -		info->size = 0x00400000; -		break;				/* => 4 MB		*/ -#endif -	case (FLASH_WORD_SIZE)SST_ID_xF800A: -		info->flash_id += FLASH_SST800A; -		info->sector_count = 16; -		info->size = 0x00100000; -		break;				/* => 1 MB		*/ -	case (FLASH_WORD_SIZE)INTEL_ID_28F320C3T: -		info->flash_id += FLASH_INTEL320T; -		info->sector_count = 71; -		info->size = 0x00400000; -		break;				/* => 4 MB		*/ - - -	case (FLASH_WORD_SIZE)SST_ID_xF160A: -		info->flash_id += FLASH_SST160A; -		info->sector_count = 32; -		info->size = 0x00200000; -		break;				/* => 2 MB		*/ - -	default: -		info->flash_id = FLASH_UNKNOWN; -		return (0);			/* => no or unknown flash */ - -	} -	/* base address calculation */ -	base=0-info->size; -	/* set up sector start address table */ -	if (((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) || -	     (info->flash_id  == FLASH_AM040) || -	     (info->flash_id  == FLASH_AM640U)){ -		for (i = 0; i < info->sector_count; i++) -			info->start[i] = base + (i * 0x00010000); -	} -	else { -		if (info->flash_id & FLASH_BTYPE) { -			/* set sector offsets for bottom boot block type	*/ -			info->start[0] = base + 0x00000000; -			info->start[1] = base + 0x00004000; -			info->start[2] = base + 0x00006000; -			info->start[3] = base + 0x00008000; -			for (i = 4; i < info->sector_count; i++) -				info->start[i] = base + (i * 0x00010000) - 0x00030000; -		} -		else { -			/* set sector offsets for top boot block type		*/ -			i = info->sector_count - 1; -			if(info->sector_count==71) { - -				info->start[i--] = base + info->size - 0x00002000; -				info->start[i--] = base + info->size - 0x00004000; -				info->start[i--] = base + info->size - 0x00006000; -				info->start[i--] = base + info->size - 0x00008000; -				info->start[i--] = base + info->size - 0x0000A000; -				info->start[i--] = base + info->size - 0x0000C000; -				info->start[i--] = base + info->size - 0x0000E000; -				for (; i >= 0; i--) -					info->start[i] = base + i * 0x000010000; -			} -			else { -				info->start[i--] = base + info->size - 0x00004000; -				info->start[i--] = base + info->size - 0x00006000; -				info->start[i--] = base + info->size - 0x00008000; -				for (; i >= 0; i--) -					info->start[i] = base + i * 0x00010000; -			} -		} -	} - -	/* check for protected sectors */ -	for (i = 0; i < info->sector_count; i++) { -		/* read sector protection at sector address, (A7 .. A0) = 0x02 */ -		/* D0 = 1 if protected */ -		addr2 = (volatile FLASH_WORD_SIZE *)(info->start[i]); -		if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) -			info->protect[i] = 0; -		else -			info->protect[i] = addr2[2] & 1; -	} - -	/* -	 * Prevent writes to uninitialized FLASH. -	 */ -	if (info->flash_id != FLASH_UNKNOWN) { -		addr2 = (FLASH_WORD_SIZE *)info->start[0]; -		*addr2 = (FLASH_WORD_SIZE)0x00F000F0;	/* reset bank */ -	} -	return (info->size); -} - - -int wait_for_DQ7(flash_info_t *info, int sect) -{ -	ulong start, now, last; -	volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]); - -	start = get_timer (0); -	last  = start; -	while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) { -		if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) { -			printf ("Timeout\n"); -			return ERR_TIMOUT; -		} -		/* show that we're waiting */ -		if ((now - last) > 1000) {  /* every second */ -			putc ('.'); -			last = now; -		} -	} -	return ERR_OK; -} - -int intel_wait_for_DQ7(flash_info_t *info, int sect) -{ -	ulong start, now, last, status; -	volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[sect]); - -	start = get_timer (0); -	last  = start; -	while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) { -		if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) { -			printf ("Timeout\n"); -			return ERR_TIMOUT; -		} -		/* show that we're waiting */ -		if ((now - last) > 1000) {  /* every second */ -			putc ('.'); -			last = now; -		} -	} -	status = addr[0] & (FLASH_WORD_SIZE)0x00280028; -	/* clear status register */ -	addr[0] = (FLASH_WORD_SIZE)0x00500050; -	/* check status for block erase fail and VPP low */ -	return (status == 0 ? ERR_OK : ERR_NOT_ERASED); -} - -/*----------------------------------------------------------------------- - */ - -int	flash_erase (flash_info_t *info, int s_first, int s_last) -{ -	volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *)(info->start[0]); -	volatile FLASH_WORD_SIZE *addr2; -	int flag, prot, sect; -	int i, rcode = 0; - - -	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; -	} - -	if (info->flash_id == FLASH_UNKNOWN) { -		printf ("Can't erase unknown flash type - aborted\n"); -		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"); -	} - -	/* Disable interrupts which might cause a timeout here */ -	flag = disable_interrupts(); - -	/* Start erase on unprotected sectors */ -	for (sect = s_first; sect<=s_last; sect++) { -		if (info->protect[sect] == 0) {	/* not protected */ -			addr2 = (FLASH_WORD_SIZE *)(info->start[sect]); -			/*  printf("Erasing sector %p\n", addr2); */ /* CLH */ -			if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) { -				addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; -				addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055; -				addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080; -				addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; -				addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055; -				addr2[0] = (FLASH_WORD_SIZE)0x00500050;  /* block erase */ -				for (i=0; i<50; i++) -					udelay(1000);  /* wait 1 ms */ -				rcode |= wait_for_DQ7(info, sect); -			} -			else { -				if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){ -					addr2[0] = (FLASH_WORD_SIZE)0x00600060;  /* unlock sector */ -					addr2[0] = (FLASH_WORD_SIZE)0x00D000D0;  /* sector erase */ -					intel_wait_for_DQ7(info, sect); -					addr2[0] = (FLASH_WORD_SIZE)0x00200020;  /* sector erase */ -					addr2[0] = (FLASH_WORD_SIZE)0x00D000D0;  /* sector erase */ -					rcode |= intel_wait_for_DQ7(info, sect); -				} -				else { -					addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; -					addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055; -					addr[ADDR0] = (FLASH_WORD_SIZE)0x00800080; -					addr[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; -					addr[ADDR1] = (FLASH_WORD_SIZE)0x00550055; -					addr2[0] = (FLASH_WORD_SIZE)0x00300030;  /* sector erase */ -					rcode |= wait_for_DQ7(info, sect); -				} -			} -			/* -			 * Wait for each sector to complete, it's more -			 * reliable.  According to AMD Spec, you must -			 * issue all erase commands within a specified -			 * timeout.  This has been seen to fail, especially -			 * if printf()s are included (for debug)!! -			 */ -			/*   wait_for_DQ7(info, sect); */ -		} -	} - -	/* re-enable interrupts if necessary */ -	if (flag) -		enable_interrupts(); - -	/* wait at least 80us - let's wait 1 ms */ -	udelay (1000); - -	/* reset to read mode */ -	addr = (FLASH_WORD_SIZE *)info->start[0]; -	addr[0] = (FLASH_WORD_SIZE)0x00F000F0;	/* reset bank */ - -	if (!rcode) -	    printf (" done\n"); - -	return rcode; -} - - -void unlock_intel_sectors(flash_info_t *info,ulong addr,ulong cnt) -{ -	int i; -	volatile FLASH_WORD_SIZE *addr2; -	long c; -	c= (long)cnt; -	for(i=info->sector_count-1;i>0;i--) -	{ -		if(addr>=info->start[i]) -			break; -	} -	do { -		addr2 = (FLASH_WORD_SIZE *)(info->start[i]); -		addr2[0] = (FLASH_WORD_SIZE)0x00600060;  /* unlock sector setup */ -		addr2[0] = (FLASH_WORD_SIZE)0x00D000D0;  /* unlock sector */ -		intel_wait_for_DQ7(info, i); -		i++; -		c-=(info->start[i]-info->start[i-1]); -	}while(c>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) -{ -	ulong cp, wp, data; -	int i, l, rc; - -	if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){ -		unlock_intel_sectors(info,addr,cnt); -	} -	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); -		} -		for (; i<4 && cnt>0; ++i) { -			data = (data << 8) | *src++; -			--cnt; -			++cp; -		} -		for (; cnt==0 && i<4; ++i, ++cp) { -			data = (data << 8) | (*(uchar *)cp); -		} - -		if ((rc = write_word(info, wp, data)) != 0) { -			return (rc); -		} -		wp += 4; -	} - -	/* -	 * handle word aligned part -	 */ -	while (cnt >= 4) { -		data = 0; -		for (i=0; i<4; ++i) { -			data = (data << 8) | *src++; -		} -		if ((rc = write_word(info, wp, data)) != 0) { -			return (rc); -		} -		wp  += 4; -		if((wp % 0x10000)==0) -			printf("."); /* show Progress */ -		cnt -= 4; -	} - -	if (cnt == 0) { -		return (0); -	} - -	/* -	 * handle unaligned tail bytes -	 */ -	data = 0; -	for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) { -		data = (data << 8) | *src++; -		--cnt; -	} -	for (; i<4; ++i, ++cp) { -		data = (data << 8) | (*(uchar *)cp); -	} -	rc=write_word(info, wp, data); -	return rc; -} - -/*----------------------------------------------------------------------- - * Write a word to Flash, returns: - * 0 - OK - * 1 - write timeout - * 2 - Flash not erased - */ -static FLASH_WORD_SIZE *read_val = (FLASH_WORD_SIZE *)0x200000; - -static int write_word (flash_info_t *info, ulong dest, ulong data) -{ -	volatile FLASH_WORD_SIZE *addr2 = (volatile FLASH_WORD_SIZE *)(info->start[0]); -	volatile FLASH_WORD_SIZE *dest2 = (volatile FLASH_WORD_SIZE *)dest; -	volatile FLASH_WORD_SIZE *data2; -	ulong start; -	ulong *data_p; -	int flag; -	int i; - -	data_p = &data; -	data2 = (volatile FLASH_WORD_SIZE *)data_p; - -	/* Check if Flash is (sufficiently) erased */ -	if ((*((volatile FLASH_WORD_SIZE *)dest) & -		(FLASH_WORD_SIZE)data) != (FLASH_WORD_SIZE)data) { -		return (2); -	} -	/* Disable interrupts which might cause a timeout here */ -	flag = disable_interrupts(); -	for (i=0; i<4/sizeof(FLASH_WORD_SIZE); i++) -	{ -		if((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL){ -			/* intel style writting */ -			dest2[i] = (FLASH_WORD_SIZE)0x00500050; -			dest2[i] = (FLASH_WORD_SIZE)0x00400040; -			*read_val++ = data2[i]; -			dest2[i] = data2[i]; -			if (flag) -				enable_interrupts(); -			/* data polling for D7 */ -			start = get_timer (0); -			udelay(10); -			while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) -			{ -				if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) -					return (1); -			} -			dest2[i] = (FLASH_WORD_SIZE)0x00FF00FF; /* return to read mode */ -			udelay(10); -			dest2[i] = (FLASH_WORD_SIZE)0x00FF00FF; /* return to read mode */ -			if(dest2[i]!=data2[i]) -				printf("Error at %p 0x%04X != 0x%04X\n",&dest2[i],dest2[i],data2[i]); -		} -		else { -			addr2[ADDR0] = (FLASH_WORD_SIZE)0x00AA00AA; -			addr2[ADDR1] = (FLASH_WORD_SIZE)0x00550055; -			addr2[ADDR0] = (FLASH_WORD_SIZE)0x00A000A0; -			dest2[i] = data2[i]; -			/* re-enable interrupts if necessary */ -			if (flag) -				enable_interrupts(); -			/* data polling for D7 */ -			start = get_timer (0); -			while ((dest2[i] & (FLASH_WORD_SIZE)0x00800080) != -				(data2[i] & (FLASH_WORD_SIZE)0x00800080)) { -				if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) { -					return (1); -				} -			} -		} -	} -	return (0); -} - -/*----------------------------------------------------------------------- - */ |