/*
 * (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;
	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);

	/* 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");
		}
	}
	if (flag)
		enable_interrupts();

	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, rc = 0;

	/* 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) {
			rc = 1;
			goto OUT;
		}
	}

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

	if (flag)
		enable_interrupts();

	return rc;
}

/*-----------------------------------------------------------------------
 * 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, rc = 0;

	/* 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) {
			rc = 1;
			goto OUT;
		}
	}

	*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);
		}
	}

OUT:
	*dstaddr = (FPW)0x00FF00FF;	/* restore read mode */
	if (flag)
		enable_interrupts();

	return rc;
}

/*-----------------------------------------------------------------------
 * 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;
}
