diff options
| author | wdenk <wdenk> | 2004-01-20 23:12:12 +0000 | 
|---|---|---|
| committer | wdenk <wdenk> | 2004-01-20 23:12:12 +0000 | 
| commit | c837dcb1a316745092567bfe4fb266d0941884ff (patch) | |
| tree | 8b275e8c982d1b0a411ff33c08c86cd3d343eed6 /board/lwmon/flash.c | |
| parent | b0aef11c9f1f98d018adaa484f1e048fa626801e (diff) | |
| download | olio-uboot-2014.01-c837dcb1a316745092567bfe4fb266d0941884ff.tar.xz olio-uboot-2014.01-c837dcb1a316745092567bfe4fb266d0941884ff.zip | |
* The PS/2 mux on the BMS2003 board needs 450 ms after power on
  before we can access it; add delay in case we are faster (with no
  CF card inserted)
* Cleanup of some init functions
* Make sure SCC Ethernet is always stopped by the time we boot Linux
  to avoid Linux crashes by early packets coming in.
* Accelerate flash accesses on LWMON board by using buffered writes
Diffstat (limited to 'board/lwmon/flash.c')
| -rw-r--r-- | board/lwmon/flash.c | 89 | 
1 files changed, 80 insertions, 9 deletions
| diff --git a/board/lwmon/flash.c b/board/lwmon/flash.c index 127738a4b..4004865c3 100644 --- a/board/lwmon/flash.c +++ b/board/lwmon/flash.c @@ -47,6 +47,9 @@ flash_info_t	flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips	*/   */  static ulong flash_get_size (vu_long *addr, flash_info_t *info);  static int write_data (flash_info_t *info, ulong dest, ulong data); +#ifdef CFG_FLASH_USE_BUFFER_WRITE +static int write_data_buf (flash_info_t * info, ulong dest, uchar * cp, int len); +#endif  static void flash_get_offsets (ulong base, flash_info_t *info);  /*----------------------------------------------------------------------- @@ -480,6 +483,17 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)  	/*  	 * handle FLASH_WIDTH aligned part  	 */ +#ifdef CFG_FLASH_USE_BUFFER_WRITE +	while(cnt >= FLASH_WIDTH) { +		i = CFG_FLASH_BUFFER_SIZE > cnt ? +		    (cnt & ~(FLASH_WIDTH - 1)) : CFG_FLASH_BUFFER_SIZE; +		if((rc = write_data_buf(info, wp, src,i)) != 0) +			return rc; +		wp += i; +		src += i; +		cnt -=i; +	} +#else  	while (cnt >= FLASH_WIDTH) {  		data = 0;  		for (i=0; i<FLASH_WIDTH; ++i) { @@ -491,6 +505,7 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)  		wp  += FLASH_WIDTH;  		cnt -= FLASH_WIDTH;  	} +#endif /* CFG_FLASH_USE_BUFFER_WRITE */  	if (cnt == 0) {  		return (0); @@ -512,6 +527,28 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)  }  /*----------------------------------------------------------------------- + * Check flash status, returns: + * 0 - OK + * 1 - timeout + */ +static int flash_status_check(vu_long *addr, ulong tout, char * prompt) +{ +	ulong status; +	ulong start; + +	/* Wait for command completion */ +	start = get_timer (0); +	while(((status = *addr) & 0x00800080) != 0x00800080) { +		if (get_timer(start) > tout) { +			printf("Flash %s timeout at address %p\n", prompt, addr); +			*addr = 0x00FF00FF;	/* restore read mode */ +			return (1); +		} +	} +	return 0; +} + +/*-----------------------------------------------------------------------   * Write a word to Flash, returns:   * 0 - OK   * 1 - write timeout @@ -520,8 +557,6 @@ int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)  static int write_data (flash_info_t *info, ulong dest, ulong data)  {  	vu_long *addr = (vu_long *)dest; -	ulong status; -	ulong start;  	int flag;  	/* Check if Flash is (sufficiently) erased */ @@ -538,13 +573,8 @@ static int write_data (flash_info_t *info, ulong dest, ulong data)  	if (flag)  		enable_interrupts(); -	start = get_timer (0); - -	while (((status = *addr) & 0x00800080) != 0x00800080) { -		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) { -			*addr = 0x00FF00FF;	/* restore read mode */ -			return (1); -		} +	if (flash_status_check(addr, CFG_FLASH_WRITE_TOUT, "write") != 0) { +		return (1);  	}  	*addr = 0x00FF00FF;	/* restore read mode */ @@ -552,5 +582,46 @@ static int write_data (flash_info_t *info, ulong dest, ulong data)  	return (0);  } +#ifdef CFG_FLASH_USE_BUFFER_WRITE +/*----------------------------------------------------------------------- + * Write a buffer to Flash, returns: + * 0 - OK + * 1 - write timeout + */ +static int write_data_buf(flash_info_t * info, ulong dest, uchar * cp, int len) +{ +	vu_long *addr = (vu_long *)dest; +	int sector; +	int cnt; +	int retcode; +	vu_long * src = (vu_long *)cp; +	vu_long * dst = (vu_long *)dest; + +	/* find sector */ +	for(sector = info->sector_count - 1; sector >= 0; sector--) { +		if(dest >= info->start[sector]) +			break; +	} + +	*addr = 0x00500050;		/* clear status */ +	*addr = 0x00e800e8;		/* write buffer */ + +	if((retcode = flash_status_check(addr, CFG_FLASH_BUFFER_WRITE_TOUT, +					 "write to buffer")) == 0) { +		cnt = len / FLASH_WIDTH; +		*addr = (cnt-1) | ((cnt-1) << 16); +		while(cnt-- > 0) { +			*dst++ = *src++; +		} +		*addr = 0x00d000d0;		/* write buffer confirm */ +		retcode = flash_status_check(addr, CFG_FLASH_BUFFER_WRITE_TOUT, +						 "buffer write"); +	} +	*addr = 0x00FF00FF;	/* restore read mode */ +	*addr = 0x00500050;	/* clear status */ +	return retcode; +} +#endif /* CFG_USE_FLASH_BUFFER_WRITE */ +  /*-----------------------------------------------------------------------   */ |