/*
 * (C) Copyright 2001
 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
 *
 * (C) Copyright 2001-2004
 * 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 <linux/byteorder/swab.h>


flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];	/* info for FLASH chips    */

/* Board support for 1 or 2 flash devices */
#define FLASH_PORT_WIDTH8

typedef unsigned char FLASH_PORT_WIDTH;
typedef volatile unsigned char FLASH_PORT_WIDTHV;

#define SWAP(x)         (x)

/* Intel-compatible flash ID */
#define INTEL_COMPAT    0x89
#define INTEL_ALT       0xB0

/* Intel-compatible flash commands */
#define INTEL_PROGRAM   0x10
#define INTEL_ERASE     0x20
#define INTEL_CLEAR     0x50
#define INTEL_LOCKBIT   0x60
#define INTEL_PROTECT   0x01
#define INTEL_STATUS    0x70
#define INTEL_READID    0x90
#define INTEL_CONFIRM   0xD0
#define INTEL_RESET     0xFF

/* Intel-compatible flash status bits */
#define INTEL_FINISHED  0x80
#define INTEL_OK        0x80

#define FPW             FLASH_PORT_WIDTH
#define FPWV            FLASH_PORT_WIDTHV

#define FLASH_CYCLE1    0x0555
#define FLASH_CYCLE2    0x02aa

#define WR_BLOCK        0x20
/*-----------------------------------------------------------------------
 * Functions
 */
static ulong flash_get_size (FPW * addr, flash_info_t * info);
static int write_data (flash_info_t * info, ulong dest, FPW data);
static int write_data_block (flash_info_t * info, ulong src, ulong dest);
static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data);
static void flash_get_offsets (ulong base, flash_info_t * info);
void inline spin_wheel (void);
static void flash_sync_real_protect (flash_info_t * info);
static unsigned char intel_sector_protected (flash_info_t *info, ushort sector);
static unsigned char same_chip_banks (int bank1, int bank2);

/*-----------------------------------------------------------------------
 */

unsigned long flash_init (void)
{
	int i;
	ulong size = 0;
	ulong fsize = 0;

	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
		memset (&flash_info[i], 0, sizeof (flash_info_t));

		switch (i) {
		case 0:
			flash_get_size ((FPW *) CONFIG_SYS_FLASH1_BASE,
					&flash_info[i]);
			flash_get_offsets (CONFIG_SYS_FLASH1_BASE, &flash_info[i]);
			break;
		case 1:
			flash_get_size ((FPW *) CONFIG_SYS_FLASH1_BASE,
					&flash_info[i]);
			fsize = CONFIG_SYS_FLASH1_BASE + flash_info[i - 1].size;
			flash_get_offsets (fsize, &flash_info[i]);
			break;
		case 2:
			flash_get_size ((FPW *) CONFIG_SYS_FLASH0_BASE,
					&flash_info[i]);
			flash_get_offsets (CONFIG_SYS_FLASH0_BASE, &flash_info[i]);
			break;
		case 3:
			flash_get_size ((FPW *) CONFIG_SYS_FLASH0_BASE,
					&flash_info[i]);
			fsize = CONFIG_SYS_FLASH0_BASE + flash_info[i - 1].size;
			flash_get_offsets (fsize, &flash_info[i]);
			break;
		default:
			panic ("configured to many flash banks!\n");
			break;
		}
		size += flash_info[i].size;

		/* get the h/w and s/w protection status in sync */
		flash_sync_real_protect(&flash_info[i]);
	}

	/* Protect monitor and environment sectors
	 */
#if defined (CONFIG_SYS_AMD_BOOT)
	flash_protect (FLAG_PROTECT_SET,
		       CONFIG_SYS_MONITOR_BASE,
		       CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
		       &flash_info[2]);
	flash_protect (FLAG_PROTECT_SET,
		       CONFIG_SYS_INTEL_BASE,
		       CONFIG_SYS_INTEL_BASE + monitor_flash_len - 1,
		       &flash_info[1]);
#else
	flash_protect (FLAG_PROTECT_SET,
		       CONFIG_SYS_MONITOR_BASE,
		       CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
		       &flash_info[3]);
	flash_protect (FLAG_PROTECT_SET,
		       CONFIG_SYS_AMD_BASE,
		       CONFIG_SYS_AMD_BASE + monitor_flash_len - 1, &flash_info[0]);
#endif

	flash_protect (FLAG_PROTECT_SET,
		       CONFIG_ENV1_ADDR,
		       CONFIG_ENV1_ADDR + CONFIG_ENV1_SIZE - 1, &flash_info[1]);
	flash_protect (FLAG_PROTECT_SET,
		       CONFIG_ENV_ADDR,
		       CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[3]);

	return size;
}

/*-----------------------------------------------------------------------
 */
static void flash_get_offsets (ulong base, flash_info_t * info)
{
	int i;

	if (info->flash_id == FLASH_UNKNOWN)
		return;

	if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) {
		for (i = 0; i < info->sector_count; i++) {
			info->start[i] = base + (i * PHYS_AMD_SECT_SIZE);
			info->protect[i] = 0;
		}
	}

	if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
		for (i = 0; i < info->sector_count; i++) {
			info->start[i] = base + (i * PHYS_INTEL_SECT_SIZE);
		}
	}
}

/*-----------------------------------------------------------------------
 */
void flash_print_info (flash_info_t * info)
{
	int i;

	if (info->flash_id == FLASH_UNKNOWN) {
		printf ("missing or unknown FLASH type\n");
		return;
	}

	switch (info->flash_id & FLASH_VENDMASK) {
	case FLASH_MAN_INTEL:
		printf ("INTEL ");
		break;
	case FLASH_MAN_AMD:
		printf ("AMD ");
		break;
	default:
		printf ("Unknown Vendor ");
		break;
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
	case FLASH_28F128J3A:
		printf ("28F128J3A\n");
		break;

	case FLASH_AM040:
		printf ("AMD29F040B\n");
		break;

	default:
		printf ("Unknown Chip Type\n");
		break;
	}

	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");
	return;
}

/*
 * The following code cannot be run from FLASH!
 */
static ulong flash_get_size (FPW * addr, flash_info_t * info)
{
	FPWV value;
	static int amd = 0;

	/* Write auto select command: read Manufacturer ID */
	/* Write auto select command sequence and test FLASH answer */
	addr[FLASH_CYCLE1] = (FPW) 0x00AA00AA;	/* for AMD, Intel ignores this */
	__asm__ ("sync");
	addr[FLASH_CYCLE2] = (FPW) 0x00550055;	/* for AMD, Intel ignores this */
	__asm__ ("sync");
	addr[FLASH_CYCLE1] = (FPW) 0x00900090;	/* selects Intel or AMD */
	__asm__ ("sync");

	udelay (100);

	switch (addr[0] & 0xff) {

	case (uchar) AMD_MANUFACT:
		info->flash_id = FLASH_MAN_AMD;
		value = addr[1];
		break;

	case (uchar) INTEL_MANUFACT:
		info->flash_id = FLASH_MAN_INTEL;
		value = addr[2];
		break;

	default:
		printf ("unknown\n");
		info->flash_id = FLASH_UNKNOWN;
		info->sector_count = 0;
		info->size = 0;
		addr[0] = (FPW) 0x00FF00FF;	/* restore read mode */
		return (0);	/* no or unknown flash  */
	}

	switch (value) {

	case (FPW) INTEL_ID_28F128J3A:
		info->flash_id += FLASH_28F128J3A;
		info->sector_count = 64;
		info->size = 0x00800000;	/* => 16 MB     */
		break;

	case (FPW) AMD_ID_LV040B:
		info->flash_id += FLASH_AM040;
		if (amd == 0) {
			info->sector_count = 7;
			info->size = 0x00070000;	/* => 448 KB     */
			amd = 1;
		} else {
			/* for Environment settings */
			info->sector_count = 1;
			info->size = PHYS_AMD_SECT_SIZE;	/* => 64 KB     */
			amd = 0;
		}
		break;

	default:
		info->flash_id = FLASH_UNKNOWN;
		break;
	}

	if (info->sector_count > CONFIG_SYS_MAX_FLASH_SECT) {
		printf ("** ERROR: sector count %d > max (%d) **\n",
			info->sector_count, CONFIG_SYS_MAX_FLASH_SECT);
		info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
	}

	if (value == (FPW) INTEL_ID_28F128J3A)
		addr[0] = (FPW) 0x00FF00FF;	/* restore read mode */
	else
		addr[0] = (FPW) 0x00F000F0;	/* restore read mode */

	return (info->size);
}


/*
 * This function gets the u-boot flash sector protection status
 * (flash_info_t.protect[]) in sync with the sector protection
 * status stored in hardware.
 */
static void flash_sync_real_protect (flash_info_t * info)
{
	int i;

	switch (info->flash_id & FLASH_TYPEMASK) {
	case FLASH_28F128J3A:
		for (i = 0; i < info->sector_count; ++i) {
			info->protect[i] = intel_sector_protected(info, i);
		}
		break;
	case FLASH_AM040:
	default:
		/* no h/w protect support */
		break;
	}
}


/*
 * checks if "sector" in bank "info" is protected. Should work on intel
 * strata flash chips 28FxxxJ3x in 8-bit mode.
 * Returns 1 if sector is protected (or timed-out while trying to read
 * protection status), 0 if it is not.
 */
static unsigned char intel_sector_protected (flash_info_t *info, ushort sector)
{
	FPWV *addr;
	FPWV *lock_conf_addr;
	ulong start;
	unsigned char ret;

	/*
	 * first, wait for the WSM to be finished. The rationale for
	 * waiting for the WSM to become idle for at most
	 * CONFIG_SYS_FLASH_ERASE_TOUT is as follows. The WSM can be busy
	 * because of: (1) erase, (2) program or (3) lock bit
	 * configuration. So we just wait for the longest timeout of
	 * the (1)-(3), i.e. the erase timeout.
	 */

	/* wait at least 35ns (W12) before issuing Read Status Register */
	udelay(1);
	addr = (FPWV *) info->start[sector];
	*addr = (FPW) INTEL_STATUS;

	start = get_timer (0);
	while ((*addr & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) {
		if (get_timer (start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
			*addr = (FPW) INTEL_RESET; /* restore read mode */
			printf("WSM busy too long, can't get prot status\n");
			return 1;
		}
	}

	/* issue the Read Identifier Codes command */
	*addr = (FPW) INTEL_READID;

	/* wait at least 35ns (W12) before reading */
	udelay(1);

	/* Intel example code uses offset of 4 for 8-bit flash */
	lock_conf_addr = (FPWV *) info->start[sector] + 4;
	ret = (*lock_conf_addr & (FPW) INTEL_PROTECT) ? 1 : 0;

	/* put flash back in read mode */
	*addr = (FPW) INTEL_RESET;

	return ret;
}


/*
 * Checks if "bank1" and "bank2" are on the same chip.  Returns 1 if they
 * are and 0 otherwise.
 */
static unsigned char same_chip_banks (int bank1, int bank2)
{
	unsigned char same_chip[CONFIG_SYS_MAX_FLASH_BANKS][CONFIG_SYS_MAX_FLASH_BANKS] = {
		{1, 1, 0, 0},
		{1, 1, 0, 0},
		{0, 0, 1, 1},
		{0, 0, 1, 1}
	};
	return same_chip[bank1][bank2];
}


/*-----------------------------------------------------------------------
 */
int flash_erase (flash_info_t * info, int s_first, int s_last)
{
	int flag, prot, sect;
	ulong type, start, last;
	int rcode = 0, intel = 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;
	}

	type = (info->flash_id & FLASH_VENDMASK);
	if ((type != FLASH_MAN_INTEL)) {
		type = (info->flash_id & FLASH_VENDMASK);
		if ((type != FLASH_MAN_AMD)) {
			printf ("Can't erase unknown flash type %08lx - aborted\n",
				info->flash_id);
			return 1;
		}
	}

	if (type == FLASH_MAN_INTEL)
		intel = 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");
	}

	start = get_timer (0);
	last = start;

	/* 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 */
			FPWV *addr = (FPWV *) (info->start[sect]);
			FPW status;

			printf ("Erasing sector %2d ... ", sect);

			/* arm simple, non interrupt dependent timer */
			start = get_timer (0);

			if (intel) {
				*addr = (FPW) 0x00500050;	/* clear status register */
				*addr = (FPW) 0x00200020;	/* erase setup */
				*addr = (FPW) 0x00D000D0;	/* erase confirm */
			} else {
				FPWV *base;	/* first address in bank */

				base = (FPWV *) (CONFIG_SYS_AMD_BASE);
				base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;	/* unlock */
				base[FLASH_CYCLE2] = (FPW) 0x00550055;	/* unlock */
				base[FLASH_CYCLE1] = (FPW) 0x00800080;	/* erase mode */
				base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;	/* unlock */
				base[FLASH_CYCLE2] = (FPW) 0x00550055;	/* unlock */
				*addr = (FPW) 0x00300030;	/* erase sector */
			}

			while (((status =
				 *addr) & (FPW) 0x00800080) !=
			       (FPW) 0x00800080) {
				if (get_timer (start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
					printf ("Timeout\n");
					if (intel) {
						*addr = (FPW) 0x00B000B0;	/* suspend erase     */
						*addr = (FPW) 0x00FF00FF;	/* reset to read mode */
					} else
						*addr = (FPW) 0x00F000F0;	/* reset to read mode */

					rcode = 1;
					break;
				}
			}

			if (intel) {
				*addr = (FPW) 0x00500050;	/* clear status register cmd.   */
				*addr = (FPW) 0x00FF00FF;	/* resest to read mode          */
			} else
				*addr = (FPW) 0x00F000F0;	/* reset to read mode */

			printf (" done\n");
		}
	}
	return rcode;
}

/*-----------------------------------------------------------------------
 * Copy memory to flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 * 4 - Flash not identified
 */

int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
	if (info->flash_id == FLASH_UNKNOWN) {
		return 4;
	}

	switch (info->flash_id & FLASH_VENDMASK) {
	case FLASH_MAN_AMD:
	    {
		FPW data = 0;	/* 16 or 32 bit word, matches flash bus width */
		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_amd (info, (FPWV *) addr,
					      data);
		}
		return res;
	    }		/* case FLASH_MAN_AMD */

	case FLASH_MAN_INTEL:
	    {
		ulong cp, wp;
		FPW data;
		int count, i, l, rc, port_width;

		/* get lower word aligned address */
		wp = addr;
		port_width = 1;

		/*
		 * 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 < port_width && cnt > 0; ++i) {
				data = (data << 8) | *src++;
				--cnt;
				++cp;
			}

			for (; cnt == 0 && i < port_width; ++i, ++cp)
				data = (data << 8) | (*(uchar *) cp);

			if ((rc =
			     write_data (info, wp, SWAP (data))) != 0)
				return (rc);
			wp += port_width;
		}

		if (cnt > WR_BLOCK) {
			/*
			 * handle word aligned part
			 */
			count = 0;
			while (cnt >= WR_BLOCK) {

				if ((rc =
				     write_data_block (info,
						       (ulong) src,
						       wp)) != 0)
					return (rc);

				wp += WR_BLOCK;
				src += WR_BLOCK;
				cnt -= WR_BLOCK;

				if (count++ > 0x800) {
					spin_wheel ();
					count = 0;
				}
			}
		}

		if (cnt < WR_BLOCK) {
			/*
			 * handle word aligned part
			 */
			count = 0;
			while (cnt >= port_width) {
				data = 0;
				for (i = 0; i < port_width; ++i)
					data = (data << 8) | *src++;

				if ((rc =
				     write_data (info, wp,
						 SWAP (data))) != 0)
					return (rc);

				wp += port_width;
				cnt -= port_width;
				if (count++ > 0x800) {
					spin_wheel ();
					count = 0;
				}
			}
		}

		if (cnt == 0)
			return (0);

		/*
		 * handle unaligned tail bytes
		 */
		data = 0;
		for (i = 0, cp = wp; i < port_width && cnt > 0;
		     ++i, ++cp) {
			data = (data << 8) | *src++;
			--cnt;
		}

		for (; i < port_width; ++i, ++cp)
			data = (data << 8) | (*(uchar *) cp);

		return (write_data (info, wp, SWAP (data)));
	    }		/* case FLASH_MAN_INTEL */

	}			/* switch */
	return (0);
}

/*-----------------------------------------------------------------------
 * Write a word or halfword to Flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
static int write_data (flash_info_t * info, ulong dest, FPW data)
{
	FPWV *addr = (FPWV *) dest;
	ulong start;
	int flag;

	/* Check if Flash is (sufficiently) erased */
	if ((*addr & data) != data) {
		printf ("not erased at %08lx (%lx)\n", (ulong)addr, (ulong)*addr);
		return (2);
	}
	/* Disable interrupts which might cause a timeout here */
	flag = disable_interrupts ();

	*addr = (FPW) 0x00400040;	/* write setup */
	*addr = data;

	/* arm simple, non interrupt dependent timer */
	start = get_timer (0);

	/* wait while polling the status register */
	while ((*addr & (FPW) 0x00800080) != (FPW) 0x00800080) {
		if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
			*addr = (FPW) 0x00FF00FF;	/* restore read mode */
			return (1);
		}
	}

	*addr = (FPW) 0x00FF00FF;	/* restore read mode */

	return (0);
}

/*-----------------------------------------------------------------------
 * Write a word or halfword to Flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
static int write_data_block (flash_info_t * info, ulong src, ulong dest)
{
	FPWV *srcaddr = (FPWV *) src;
	FPWV *dstaddr = (FPWV *) dest;
	ulong start;
	int flag, i;

	/* Check if Flash is (sufficiently) erased */
	for (i = 0; i < WR_BLOCK; i++)
		if ((*dstaddr++ & 0xff) != 0xff) {
			printf ("not erased at %08lx (%lx)\n",
				(ulong)dstaddr, (ulong)*dstaddr);
			return (2);
		}

	dstaddr = (FPWV *) dest;

	/* Disable interrupts which might cause a timeout here */
	flag = disable_interrupts ();

	*dstaddr = (FPW) 0x00e800e8;	/* write block setup */

	/* arm simple, non interrupt dependent timer */
	start = get_timer (0);

	/* wait while polling the status register */
	while ((*dstaddr & (FPW) 0x00800080) != (FPW) 0x00800080) {
		if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
			*dstaddr = (FPW) 0x00FF00FF;	/* restore read mode */
			return (1);
		}
	}

	*dstaddr = (FPW) 0x001f001f;	/* write 32 to buffer */
	for (i = 0; i < WR_BLOCK; i++)
		*dstaddr++ = *srcaddr++;

	dstaddr -= 1;
	*dstaddr = (FPW) 0x00d000d0;	/* write 32 to buffer */

	/* arm simple, non interrupt dependent timer */
	start = get_timer (0);

	/* wait while polling the status register */
	while ((*dstaddr & (FPW) 0x00800080) != (FPW) 0x00800080) {
		if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
			*dstaddr = (FPW) 0x00FF00FF;	/* restore read mode */
			return (1);
		}
	}

	*dstaddr = (FPW) 0x00FF00FF;	/* restore read mode */

	return (0);
}

/*-----------------------------------------------------------------------
 * Write a word to Flash for AMD FLASH
 * A word is 16 or 32 bits, whichever the bus width of the flash bank
 * (not an individual chip) is.
 *
 * returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
static int write_word_amd (flash_info_t * info, FPWV * dest, FPW data)
{
	ulong start;
	int flag;
	int res = 0;		/* result, assume success */
	FPWV *base;		/* first address in flash bank */

	/* Check if Flash is (sufficiently) erased */
	if ((*dest & data) != data) {
		return (2);
	}

	base = (FPWV *) (CONFIG_SYS_AMD_BASE);

	/* Disable interrupts which might cause a timeout here */
	flag = disable_interrupts ();

	base[FLASH_CYCLE1] = (FPW) 0x00AA00AA;	/* unlock */
	base[FLASH_CYCLE2] = (FPW) 0x00550055;	/* unlock */
	base[FLASH_CYCLE1] = (FPW) 0x00A000A0;	/* selects program mode */

	*dest = data;		/* start programming the data */

	/* re-enable interrupts if necessary */
	if (flag)
		enable_interrupts ();

	start = get_timer (0);

	/* data polling for D7 */
	while (res == 0
	       && (*dest & (FPW) 0x00800080) != (data & (FPW) 0x00800080)) {
		if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
			*dest = (FPW) 0x00F000F0;	/* reset bank */
			res = 1;
		}
	}

	return (res);
}

void inline spin_wheel (void)
{
	static int p = 0;
	static char w[] = "\\/-";

	printf ("\010%c", w[p]);
	(++p == 3) ? (p = 0) : 0;
}

/*-----------------------------------------------------------------------
 * Set/Clear sector's lock bit, returns:
 * 0 - OK
 * 1 - Error (timeout, voltage problems, etc.)
 */
int flash_real_protect (flash_info_t * info, long sector, int prot)
{
	ulong start;
	int i, j;
	int curr_bank;
	int bank;
	int rc = 0;
	FPWV *addr = (FPWV *) (info->start[sector]);
	int flag = disable_interrupts ();

	/*
	 * 29F040B AMD flash does not support software protection/unprotection,
	 * the only way to protect the AMD flash is marked it as prot bit.
	 * This flash only support hardware protection, by supply or not supply
	 * 12vpp to the flash
	 */
	if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) {
		info->protect[sector] = prot;

		return 0;
	}

	*addr = INTEL_CLEAR;	/* Clear status register    */
	if (prot) {		/* Set sector lock bit      */
		*addr = INTEL_LOCKBIT;	/* Sector lock bit          */
		*addr = INTEL_PROTECT;	/* set                      */
	} else {		/* Clear sector lock bit    */
		*addr = INTEL_LOCKBIT;	/* All sectors lock bits    */
		*addr = INTEL_CONFIRM;	/* clear                    */
	}

	start = get_timer (0);

	while ((*addr & INTEL_FINISHED) != INTEL_FINISHED) {
		if (get_timer (start) > CONFIG_SYS_FLASH_UNLOCK_TOUT) {
			printf ("Flash lock bit operation timed out\n");
			rc = 1;
			break;
		}
	}

	if (*addr != INTEL_OK) {
		printf ("Flash lock bit operation failed at %08X, CSR=%08X\n",
			(uint) addr, (uint) * addr);
		rc = 1;
	}

	if (!rc)
		info->protect[sector] = prot;

	/*
	 * Clear lock bit command clears all sectors lock bits, so
	 * we have to restore lock bits of protected sectors.
	 */
	if (!prot) {
		/*
		 * re-locking must be done for all banks that belong on one
		 * FLASH chip, as all the sectors on the chip were unlocked
		 * by INTEL_LOCKBIT/INTEL_CONFIRM commands. (let's hope
		 * that banks never span chips, in particular chips which
		 * support h/w protection differently).
		 */

		/* find the current bank number */
		curr_bank = CONFIG_SYS_MAX_FLASH_BANKS + 1;
		for (j = 0; j < CONFIG_SYS_MAX_FLASH_BANKS; ++j) {
			if (&flash_info[j] == info) {
				curr_bank = j;
			}
		}
		if (curr_bank == CONFIG_SYS_MAX_FLASH_BANKS + 1) {
			printf("Error: can't determine bank number!\n");
		}

		for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank) {
			if (!same_chip_banks(curr_bank, bank)) {
				continue;
			}
			info = &flash_info[bank];
			for (i = 0; i < info->sector_count; i++) {
				if (info->protect[i]) {
					start = get_timer (0);
					addr = (FPWV *) (info->start[i]);
					*addr = INTEL_LOCKBIT;	/* Sector lock bit  */
					*addr = INTEL_PROTECT;	/* set              */
					while ((*addr & INTEL_FINISHED) !=
					       INTEL_FINISHED) {
						if (get_timer (start) >
						    CONFIG_SYS_FLASH_UNLOCK_TOUT) {
							printf ("Flash lock bit operation timed out\n");
							rc = 1;
							break;
						}
					}
				}
			}
		}

		/*
		 * get the s/w sector protection status in sync with the h/w,
		 * in case something went wrong during the re-locking.
		 */
		flash_sync_real_protect(info); /* resets flash to read  mode */
	}

	if (flag)
		enable_interrupts ();

	*addr = INTEL_RESET;	/* Reset to read array mode */

	return rc;
}
