diff options
Diffstat (limited to 'board/emk/top860/flash.c')
| -rw-r--r-- | board/emk/top860/flash.c | 489 | 
1 files changed, 0 insertions, 489 deletions
| diff --git a/board/emk/top860/flash.c b/board/emk/top860/flash.c deleted file mode 100644 index 0f827df06..000000000 --- a/board/emk/top860/flash.c +++ /dev/null @@ -1,489 +0,0 @@ -/* - * (C) Copyright 2003 - * EMK Elektronik GmbH <www.emk-elektronik.de> - * Reinhard Meyer <r.meyer@emk-elektronik.de> - * - * copied from the BMW Port - seems that its similiar enough - * to be easily adaped ;) --- Well, it turned out to become a - * merger between parts of the EMKstax Flash routines and the - * BMW funtion frames... - * - * (C) Copyright 2000 - * 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 <mpc8xx.h> - -#define	FLASH_WORD_SIZE		unsigned short -#define FLASH_WORD_WIDTH	(sizeof (FLASH_WORD_SIZE)) - -flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips    */ - -/*----------------------------------------------------------------------- - * Functions - */ -static int write_word (flash_info_t *info, ulong dest, ulong data); - - -/***************************************************************************** - * software product ID entry/exit - *****************************************************************************/ -static void FlashProductIdMode ( -	volatile FLASH_WORD_SIZE *b, -	int on_off) -{ -	b[0x5555] = 0xaa; -	b[0x2aaa] = 0x55; -	b[0x5555] = on_off ? 0x90 : 0xf0; -} - -/***************************************************************************** - * sector erase start - *****************************************************************************/ -static void FlashSectorErase ( -	volatile FLASH_WORD_SIZE *b, -	volatile FLASH_WORD_SIZE *a) -{ -	b[0x5555] = 0xaa; -	b[0x2aaa] = 0x55; -	b[0x5555] = 0x80; -	b[0x5555] = 0xaa; -	b[0x2aaa] = 0x55; -	a[0] = 0x30; -} - -/***************************************************************************** - * program a word - *****************************************************************************/ -static void FlashProgWord ( -	volatile FLASH_WORD_SIZE *b, -	volatile FLASH_WORD_SIZE *a, -	FLASH_WORD_SIZE v) -{ -	b[0x5555] = 0xaa; -	b[0x2aaa] = 0x55; -	b[0x5555] = 0xa0; -	a[0] = v; -} - -/***************************************************************************** - * reset bank, back to read mode - *****************************************************************************/ -static void FlashReset (volatile FLASH_WORD_SIZE *b) -{ -	b[0] = 0xf0; -} - -/***************************************************************************** - * identify FLASH chip - * this code is a stripped version of the FlashGetType() function in EMKstax - *****************************************************************************/ -unsigned long flash_init (void) -{ -	volatile FLASH_WORD_SIZE * const flash = (volatile FLASH_WORD_SIZE *) CFG_FLASH_BASE; -	FLASH_WORD_SIZE	manu, dev; -	flash_info_t * const pflinfo = &flash_info[0]; -	int j; - -	/* get Id Bytes */ -	FlashProductIdMode (flash, 1); -	manu = flash[0]; -	dev  = flash[1]; -	FlashProductIdMode (flash, 0); - -	pflinfo->size = 0; -	pflinfo->sector_count = 0; -	pflinfo->flash_id = 0xffffffff; -	pflinfo->portwidth = FLASH_CFI_16BIT; -	pflinfo->chipwidth = FLASH_CFI_BY16; - -	switch (manu&0xff) -	{ -	case 0x01:	/* AMD */ -		pflinfo->flash_id = FLASH_MAN_AMD; -		switch (dev&0xff) -		{ -		case 0x49: -			pflinfo->size = 0x00200000; -			pflinfo->sector_count = 35; -			pflinfo->flash_id |= FLASH_AM160B; -			pflinfo->start[0] = CFG_FLASH_BASE; -			pflinfo->start[1] = CFG_FLASH_BASE + 0x4000; -			pflinfo->start[2] = CFG_FLASH_BASE + 0x6000; -			pflinfo->start[3] = CFG_FLASH_BASE + 0x8000; -			for (j = 4; j < 35; j++) -			{ -				pflinfo->start[j] = CFG_FLASH_BASE + 0x00010000 * (j-3); -			} -			break; - -		case 0xf9: -			pflinfo->size = 0x00400000; -			pflinfo->sector_count = 71; -			pflinfo->flash_id |= FLASH_AM320B; -			pflinfo->start[0] = CFG_FLASH_BASE; -			pflinfo->start[1] = CFG_FLASH_BASE + 0x4000; -			pflinfo->start[2] = CFG_FLASH_BASE + 0x6000; -			pflinfo->start[3] = CFG_FLASH_BASE + 0x8000; -			for (j = 0; j < 8; j++) -			{ -				pflinfo->start[j] = CFG_FLASH_BASE + 0x00002000 * (j); -			} -			for (j = 8; j < 71; j++) -			{ -				pflinfo->start[j] = CFG_FLASH_BASE + 0x00010000 * (j-7); -			} -			break; - -		default: -			printf ("unknown AMD dev=%x ", dev); -			pflinfo->flash_id |= FLASH_UNKNOWN; -		} -		break; - -	default: -		printf ("unknown manu=%x ", manu); -	} -	return pflinfo->size; -} - -/***************************************************************************** - * print info about a FLASH - *****************************************************************************/ -void flash_print_info (flash_info_t *info) -{ -	static const char	unk[] = "Unknown"; -	unsigned int		i; -	const char			*mfct=unk, -						*type=unk; - -	if(info->flash_id != FLASH_UNKNOWN) -	{ -		switch (info->flash_id & FLASH_VENDMASK) -		{ -		case FLASH_MAN_AMD: -			mfct = "AMD"; -			break; -		} - -		switch (info->flash_id & FLASH_TYPEMASK) -		{ -		case FLASH_AM160B: -			type = "AM29LV160B (16 Mbit, bottom boot sect)"; -			break; -		case FLASH_AM320B: -			type = "AM29LV320B (32 Mbit, bottom boot sect)"; -			break; -		} -	} - -	printf ( -		"\n  Brand: %s Type: %s\n" -		"  Size: %lu KB in %d Sectors\n", -		mfct, -		type, -		info->size >> 10, -		info->sector_count -		); - -	printf ("  Sector Start Addresses:"); - -	for (i = 0; i < info->sector_count; i++) -	{ -		unsigned long	size; -		unsigned int	erased; -		unsigned long	*flash = (unsigned long *) info->start[i]; - -		/* -		 * Check if whole sector is erased -		 */ -		size = -			(i != (info->sector_count - 1)) ? -			(info->start[i + 1] - info->start[i]) >> 2 : -		(info->start[0] + info->size - info->start[i]) >> 2; - -		for ( -			flash = (unsigned long *) info->start[i], erased = 1; -				(flash != (unsigned long *) info->start[i] + size) && erased; -					flash++ -			) -			erased = *flash == ~0x0UL; - -		printf ( -			"%s %08lX %s %s", -			(i % 5) ? "" : "\n   ", -			info->start[i], -			erased ? "E" : " ", -			info->protect[i] ? "RO" : "  " -			); -	} - -	puts ("\n"); -	return; -} - -/***************************************************************************** - * erase one or more sectors - *****************************************************************************/ -int	flash_erase (flash_info_t *info, int s_first, int s_last) -{ -	volatile FLASH_WORD_SIZE	*addr = (FLASH_WORD_SIZE *)(info->start[0]); -	int							flag, -								prot, -								sect, -								l_sect; -	ulong						start, -								now, -								last; - -	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) || -		(info->flash_id > (FLASH_MAN_STM | FLASH_AMD_COMP))) -	{ -		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"); -	} - -	l_sect = -1; - -	/* 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 */ -			FlashSectorErase ((FLASH_WORD_SIZE *)info->start[0], (FLASH_WORD_SIZE *)info->start[sect]); -			l_sect = sect; -		} -	} - -	/* re-enable interrupts if necessary */ -	if (flag) -		enable_interrupts(); - -	/* wait at least 80us - let's wait 1 ms */ -	udelay (1000); - -	/* -	* We wait for the last triggered sector -	*/ -	if (l_sect < 0) -		goto DONE; - -	start = get_timer (0); -	last  = start; -	addr = (FLASH_WORD_SIZE *)info->start[l_sect]; -	while ((addr[0] & 0x0080) != 0x0080) -	{ -		if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) -		{ -			printf ("Timeout\n"); -			return 1; -		} -		/* show that we're waiting */ -		if ((now - last) > 1000) -		{  /* every second */ -			serial_putc ('.'); -			last = now; -		} -	} - -	DONE: -	/* reset to read mode */ -	FlashReset ((FLASH_WORD_SIZE *)info->start[0]); - -	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) -{ -	ulong		cp, -				wp, -				data; -	int			i, -				l, -				rc; - -	wp = (addr & ~(FLASH_WORD_WIDTH-1));   /* get lower word aligned address */ - -	/* -	 * handle unaligned start bytes, if there are... -	 */ -	if ((l = addr - wp) != 0) -	{ -		data = 0; - -		/* get the current before the new data into our data word */ -		for (i=0, cp=wp; i<l; ++i, ++cp) -		{ -			data = (data << 8) | (*(uchar *)cp); -		} - -		/* now merge the to be programmed values */ -		for (; i<4 && cnt>0; ++i, ++cp, --cnt) -		{ -			data = (data << 8) | *src++; -		} - -		/* get the current after the new data into our data word */ -		for (; cnt==0 && i<FLASH_WORD_WIDTH; ++i, ++cp) -		{ -			data = (data << 8) | (*(uchar *)cp); -		} - -		/* now write the combined word */ -		if ((rc = write_word (info, wp, data)) != 0) -		{ -			return (rc); -		} -		wp += FLASH_WORD_WIDTH; -	} - -	/* -	 * handle word aligned part -	 */ -	while (cnt >= FLASH_WORD_WIDTH) -	{ -		data = 0; -		for (i=0; i<FLASH_WORD_WIDTH; ++i) -		{ -			data = (data << 8) | *src++; -		} -		if ((rc = write_word (info, wp, data)) != 0) -		{ -			return (rc); -		} -		wp  += FLASH_WORD_WIDTH; -		cnt -= FLASH_WORD_WIDTH; -	} - -	if (cnt == 0) -	{ -		return (0); -	} - -	/* -	 * handle unaligned tail bytes, if there are... -	 */ -	data = 0; - -	/* now merge the to be programmed values */ -	for (i=0, cp=wp; i<FLASH_WORD_WIDTH && cnt>0; ++i, ++cp) -	{ -		data = (data << 8) | *src++; -		--cnt; -	} - -	/* get the current after the new data into our data word */ -	for (; i<FLASH_WORD_WIDTH; ++i, ++cp) -	{ -		data = (data << 8) | (*(uchar *)cp); -	} - -	/* now write the combined word */ -	return (write_word (info, wp, data)); -} - -/***************************************************************************** - * Write a word to Flash, returns: - * 0 - OK - * 1 - write timeout - * 2 - Flash not erased - *****************************************************************************/ -static int write_word (flash_info_t *info, ulong dest, ulong data) -{ -	volatile FLASH_WORD_SIZE	*addr2 = (FLASH_WORD_SIZE *)info->start[0]; -	volatile FLASH_WORD_SIZE	*dest2 = (FLASH_WORD_SIZE *)dest; -	FLASH_WORD_SIZE				data2 = data; -	ulong						start; -	int							flag; - -	/* Check if Flash is (sufficiently) erased */ -	if ((*dest2 & data2) != data2) -	{ -		return (2); -	} - -	/* Disable interrupts which might cause a timeout here */ -	flag = disable_interrupts (); - -	FlashProgWord (addr2, dest2, data2); - -	/* re-enable interrupts if necessary */ -	if (flag) -		enable_interrupts (); - -	/* data polling for D7 */ -	start = get_timer (0); -	while ((*dest2 & 0x0080) != (data2 & 0x0080)) -	{ -		if (get_timer (start) > CFG_FLASH_WRITE_TOUT) -		{ -			return (1); -		} -	} - -	return (0); -} - -/*----------------------------------------------------------------------- - */ |