/*
 * (C) Copyright 2001
 * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
 *  Based on code by:
 * 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 <asm/ppc4xx.h>
#include <asm/processor.h>

#include <watchdog.h>

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

/*
 * Functions
 */
static ulong flash_get_size(vu_long *addr, flash_info_t *info);
static int write_word8(flash_info_t *info, ulong dest, ulong data);
static int write_word32(flash_info_t *info, ulong dest, ulong data);
static void flash_get_offsets(ulong base, flash_info_t *info);

unsigned long flash_init(void)
{
	int i;
	unsigned long size_b0, base_b0;
	unsigned long size_b1;

	/* Init: no FLASHes known */
	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i)
		flash_info[i].flash_id = FLASH_UNKNOWN;

	/* Get Size of Boot and Main Flashes */
	size_b0 = flash_get_size((vu_long *) FLASH_BASE0_PRELIM,
			       &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);
		return 0;
	}
	size_b1 =
		flash_get_size((vu_long *) FLASH_BASE1_PRELIM,
			       &flash_info[1]);
	if (flash_info[1].flash_id == FLASH_UNKNOWN) {
		printf("## Unknown FLASH on Bank 1 - Size = 0x%08lx = %ld MB\n",
			size_b1, size_b1 << 20);
		return 0;
	}

	/* Calculate base addresses */
	base_b0 = -size_b0;

	/* Setup offsets for Boot Flash */
	flash_get_offsets(base_b0, &flash_info[0]);

	/* Protect board level data */
	(void) flash_protect(FLAG_PROTECT_SET,
			     base_b0,
			     flash_info[0].start[1] - 1, &flash_info[0]);

	/* Monitor protection ON by default */
	(void) flash_protect(FLAG_PROTECT_SET,
			     base_b0 + size_b0 - monitor_flash_len,
			     base_b0 + size_b0 - 1, &flash_info[0]);

	/* Protect the FPGA image */
	(void) flash_protect(FLAG_PROTECT_SET,
			     FLASH_BASE1_PRELIM,
			     FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN -
			     1, &flash_info[1]);

	/* Protect the default boot image */
	(void) flash_protect(FLAG_PROTECT_SET,
			     FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN,
			     FLASH_BASE1_PRELIM + CONFIG_SYS_FPGA_IMAGE_LEN +
			     0x600000 - 1, &flash_info[1]);

	/* Setup offsets for Main Flash */
	flash_get_offsets(FLASH_BASE1_PRELIM, &flash_info[1]);

	return size_b0 + size_b1;
}

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

	/* set up sector start address table - FOR BOOT ROM ONLY!!! */
	if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040) {
		for (i = 0; i < info->sector_count; i++)
			info->start[i] = base + (i * 0x00010000);
	}
}				/* end flash_get_offsets() */

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("1 x AMD ");
		break;
	case FLASH_MAN_STM:
		printf("1 x STM ");
		break;
	case FLASH_MAN_INTEL:
		printf("2 x Intel ");
		break;
	default:
		printf("Unknown Vendor ");
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
	case FLASH_AM040:
		if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD)
			printf("AM29LV040 (4096 Kbit, uniform sector size)\n");
		else if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM)
			printf("M29W040B (4096 Kbit, uniform block size)\n");
		else
			printf("UNKNOWN 29x040x (4096 Kbit, uniform sector size)\n");
		break;
	case FLASH_28F320J3A:
		printf("28F320J3A (32 Mbit = 128K x 32)\n");
		break;
	case FLASH_28F640J3A:
		printf("28F640J3A (64 Mbit = 128K x 64)\n");
		break;
	case FLASH_28F128J3A:
		printf("28F128J3A (128 Mbit = 128K x 128)\n");
		break;
	default:
		printf("Unknown Chip Type\n");
	}

	if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_STM) {
		printf("  Size: %ld KB in %d Blocks\n",
		       info->size >> 10, info->sector_count);
	} else {
		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");
}				/* end flash_print_info() */

/*
 * The following code cannot be run from FLASH!
 */
static ulong flash_get_size(vu_long *addr, flash_info_t *info)
{
	short i;
	ulong base = (ulong) addr;

	/* Setup default type */
	info->flash_id = FLASH_UNKNOWN;
	info->sector_count = 0;
	info->size = 0;

	/* Test for Boot Flash */
	if (base == FLASH_BASE0_PRELIM) {
		unsigned char value;
		volatile unsigned char *addr2 = (unsigned char *) addr;

		/* Write auto select command: read Manufacturer ID */
		*(addr2 + 0x555) = 0xaa;
		*(addr2 + 0x2aa) = 0x55;
		*(addr2 + 0x555) = 0x90;

		/* Manufacture ID */
		value = *addr2;
		switch (value) {
		case (unsigned char) AMD_MANUFACT:
			info->flash_id = FLASH_MAN_AMD;
			break;
		case (unsigned char) STM_MANUFACT:
			info->flash_id = FLASH_MAN_STM;
			break;
		default:
			*addr2 = 0xf0;	/* no or unknown flash  */
			return 0;
		}

		/* Device ID */
		value = *(addr2 + 1);
		switch (value) {
		case (unsigned char) AMD_ID_LV040B:
		case (unsigned char) STM_ID_29W040B:
			info->flash_id += FLASH_AM040;
			info->sector_count = 8;
			info->size = 0x00080000;
			break;	/* => 512Kb */
		default:
			*addr2 = 0xf0;	/* => no or unknown flash */
			return 0;
		}
	} else {		/* MAIN Flash */
		unsigned long value;
		volatile unsigned long *addr2 = (unsigned long *) addr;

		/* Write auto select command: read Manufacturer ID */
		*addr2 = 0x90909090;

		/* Manufacture ID */
		value = *addr2;
		switch (value) {
		case (unsigned long) INTEL_MANUFACT:
			info->flash_id = FLASH_MAN_INTEL;
			break;
		default:
			*addr2 = 0xff;	/* no or unknown flash  */
			return 0;
		}

		/* Device ID - This shit is interleaved... */
		value = *(addr2 + 1);
		switch (value) {
		case (unsigned long) INTEL_ID_28F320J3A:
			info->flash_id += FLASH_28F320J3A;
			info->sector_count = 32;
			info->size = 0x00400000 * 2;
			break;	/* => 2 X 4 MB */
		case (unsigned long) INTEL_ID_28F640J3A:
			info->flash_id += FLASH_28F640J3A;
			info->sector_count = 64;
			info->size = 0x00800000 * 2;
			break;	/* => 2 X 8 MB */
		case (unsigned long) INTEL_ID_28F128J3A:
			info->flash_id += FLASH_28F128J3A;
			info->sector_count = 128;
			info->size = 0x01000000 * 2;
			break;	/* => 2 X 16 MB */
		default:
			*addr2 = 0xff;	/* => no or unknown flash */
		}
	}

	/* Make sure we don't exceed CONFIG_SYS_MAX_FLASH_SECT */
	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;
	}

	/* set up sector start address table */
	switch (info->flash_id & FLASH_TYPEMASK) {
	case FLASH_AM040:
		for (i = 0; i < info->sector_count; i++)
			info->start[i] = base + (i * 0x00010000);
		break;
	case FLASH_28F320J3A:
	case FLASH_28F640J3A:
	case FLASH_28F128J3A:
		for (i = 0; i < info->sector_count; i++)
			info->start[i] = base +
					(i * 0x00020000 * 2);	/* 2 Banks */
		break;
	}

	/* Test for Boot Flash */
	if (base == FLASH_BASE0_PRELIM) {
		volatile unsigned char *addr2;

		/* check for protected sectors */
		for (i = 0; i < info->sector_count; i++) {
			/*
			 * read sector protection at sector address,
			 * (AX .. A0) = 0x02
			 * D0 = 1 if protected
			 */
			addr2 = (volatile unsigned char *) (info->start[i]);
			info->protect[i] = *(addr2 + 2) & 1;
		}

		/* Restore read mode */
		*(unsigned char *) base = 0xF0;	/* Reset NORMAL Flash */
	} else {		/* Main Flash */
		volatile unsigned long *addr2;

		/* check for protected sectors */
		for (i = 0; i < info->sector_count; i++) {
			/*
			 * read sector protection at sector address,
			 * (AX .. A0) = 0x02
			 * D0 = 1 if protected
			 */
			addr2 = (volatile unsigned long *) (info->start[i]);
			info->protect[i] = *(addr2 + 2) & 0x1;
		}

		/* Restore read mode */
		*(unsigned long *) base = 0xFFFFFFFF;	/* Reset  Flash */
	}

	return info->size;
}				/* end flash_get_size() */

static int wait_for_DQ7(ulong addr, uchar cmp_val, ulong tout)
{
	int i;

	volatile uchar *vaddr = (uchar *) addr;

	/* Loop X times */
	for (i = 1; i <= (100 * tout); i++) {	/* Wait up to tout ms */
		udelay(10);
		/* Pause 10 us */

		/* Check for completion */
		if ((vaddr[0] & 0x80) == (cmp_val & 0x80))
			return 0;

		/* KEEP THE LUSER HAPPY - Print a dot every 1.1 seconds */
		if (!(i % 110000))
			putc('.');

		/* Kick the dog if needed */
		WATCHDOG_RESET();
	}

	return 1;
}				/* wait_for_DQ7() */

static int flash_erase8(flash_info_t *info, int s_first, int s_last)
{
	int tcode, rcode = 0;
	volatile uchar *addr = (uchar *) (info->start[0]);
	volatile uchar *sector_addr;
	int flag, prot, sect;

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

	/* Check for KNOWN flash type */
	if (info->flash_id == FLASH_UNKNOWN) {
		printf("Can't erase unknown flash type - aborted\n");
		return 1;
	}

	/* Check for protected sectors */
	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 erase on unprotected sectors */
	for (sect = s_first; sect <= s_last; sect++) {
		if (info->protect[sect] == 0) {	/* not protected */
			sector_addr = (uchar *) (info->start[sect]);

			if ((info->flash_id & FLASH_VENDMASK) ==
			    FLASH_MAN_STM)
				printf("Erasing block %p\n", sector_addr);
			else
				printf("Erasing sector %p\n", sector_addr);

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

			*(addr + 0x555) = (uchar) 0xAA;
			*(addr + 0x2aa) = (uchar) 0x55;
			*(addr + 0x555) = (uchar) 0x80;
			*(addr + 0x555) = (uchar) 0xAA;
			*(addr + 0x2aa) = (uchar) 0x55;
			*sector_addr = (uchar) 0x30;	/* sector erase */

			/*
			 * 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)!!
			 * Takes up to 6 seconds.
			 */
			tcode = wait_for_DQ7((ulong) sector_addr, 0x80, 6000);

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

			/* Make sure we didn't timeout */
			if (tcode) {
				printf("Timeout\n");
				rcode = 1;
			}
		}
	}

	/* wait at least 80us - let's wait 1 ms */
	udelay(1000);

	/* reset to read mode */
	addr = (uchar *) info->start[0];
	*addr = (uchar) 0xF0;	/* reset bank */

	printf(" done\n");
	return rcode;
}				/* end flash_erase8() */

static int flash_erase32(flash_info_t *info, int s_first, int s_last)
{
	int flag, sect;
	ulong start, now, last;
	int prot = 0;

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

	/* Check for KNOWN flash type */
	if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
		printf("Can erase only Intel flash types - aborted\n");
		return 1;
	}

	/* Check for protected sectors */
	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;
	/* Start erase on unprotected sectors */
	for (sect = s_first; sect <= s_last; sect++) {
		WATCHDOG_RESET();
		if (info->protect[sect] == 0) {	/* not protected */
			vu_long *addr = (vu_long *) (info->start[sect]);
			unsigned long status;

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

			*addr = 0x00500050;	/* clear status register */
			*addr = 0x00200020;	/* erase setup */
			*addr = 0x00D000D0;	/* erase confirm */

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

			/* Wait at least 80us - let's wait 1 ms */
			udelay(1000);

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

				/*
				 * show that we're waiting
				 * every second (?)
				 */
				if ((now - last) > 990) {
					putc('.');
					last = now;
				}
			}
			*addr = 0x00FF00FF;	/* reset to read mode */
		}
	}
	printf(" done\n");
	return 0;
}

int flash_erase(flash_info_t *info, int s_first, int s_last)
{
	if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040)
		return flash_erase8(info, s_first, s_last);
	else
		return flash_erase32(info, s_first, s_last);
}

/*
 * Copy memory to flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
static int write_buff8(flash_info_t *info, uchar *src, ulong addr,
		       ulong cnt)
{
	ulong cp, wp, data;
	ulong start;
	int i, l, rc;

	start = get_timer(0);

	wp = (addr & ~3);	/* get lower word
				   aligned address */

	/*
	 * handle unaligned start bytes
	 */
	l = addr - wp;
	if (l != 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);

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

		wp += 4;
	}

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

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

		wp += 4;
		cnt -= 4;
		if (get_timer(start) > 1000) {	/* every second */
			WATCHDOG_RESET();
			putc('.');
			start = get_timer(0);
		}
	}

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

	return write_word8(info, wp, data);
}

#define	FLASH_WIDTH	4	/* flash bus width in bytes */
static int write_buff32(flash_info_t *info, uchar *src, ulong addr,
			ulong cnt)
{
	ulong cp, wp, data;
	int i, l, rc;
	ulong start;

	start = get_timer(0);

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

	/* get lower FLASH_WIDTH aligned address */
	wp = (addr & ~(FLASH_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 < FLASH_WIDTH && cnt > 0; ++i) {
			data = (data << 8) | *src++;
			--cnt;
			++cp;
		}

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

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

		wp += FLASH_WIDTH;
	}

	/*
	 * handle FLASH_WIDTH aligned part
	 */
	while (cnt >= FLASH_WIDTH) {
		data = 0;
		for (i = 0; i < FLASH_WIDTH; ++i)
			data = (data << 8) | *src++;

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

		wp += FLASH_WIDTH;
		cnt -= FLASH_WIDTH;
		if (get_timer(start) > 990) {	/* every second */
			putc('.');
			start = get_timer(0);
		}
	}

	if (cnt == 0)
		return 0;

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

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

	return write_word32(info, wp, data);
}

int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
	int retval;

	if ((info->flash_id & FLASH_TYPEMASK) == FLASH_AM040)
		retval = write_buff8(info, src, addr, cnt);
	else
		retval = write_buff32(info, src, addr, cnt);

	return retval;
}

/*
 * Write a word to Flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */

static int write_word8(flash_info_t *info, ulong dest, ulong data)
{
	volatile uchar *addr2 = (uchar *) (info->start[0]);
	volatile uchar *dest2 = (uchar *) dest;
	volatile uchar *data2 = (uchar *) &data;
	int flag;
	int i, tcode, rcode = 0;

	/* Check if Flash is (sufficently) erased */
	if ((*((volatile uchar *)dest) & (uchar)data) != (uchar)data)
		return 2;

	for (i = 0; i < (4 / sizeof(uchar)); i++) {
		/* Disable interrupts which might cause a timeout here */
		flag = disable_interrupts();

		*(addr2 + 0x555) = (uchar) 0xAA;
		*(addr2 + 0x2aa) = (uchar) 0x55;
		*(addr2 + 0x555) = (uchar) 0xA0;

		dest2[i] = data2[i];

		/* Wait for write to complete, up to 1ms */
		tcode = wait_for_DQ7((ulong) &dest2[i], data2[i], 1);

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

		/* Make sure we didn't timeout */
		if (tcode)
			rcode = 1;
	}

	return rcode;
}

static int write_word32(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 */
	if ((*addr & data) != data)
		return 2;

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

	*addr = 0x00400040;	/* write setup */
	*addr = data;

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

	start = get_timer(0);

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

	*addr = 0x00FF00FF;	/* restore read mode */

	return 0;
}

static int _flash_protect(flash_info_t *info, long sector)
{
	int i;
	int flag;
	ulong status;
	int rcode = 0;
	volatile long *addr = (long *)sector;

	switch (info->flash_id & FLASH_TYPEMASK) {
	case FLASH_28F320J3A:
	case FLASH_28F640J3A:
	case FLASH_28F128J3A:
		/* Disable interrupts which might cause Flash to timeout */
		flag = disable_interrupts();

		/* Issue command */
		*addr = 0x00500050L;	/* Clear the status register */
		*addr = 0x00600060L;	/* Set lock bit setup */
		*addr = 0x00010001L;	/* Set lock bit confirm */

		/* Wait for command completion */
		for (i = 0; i < 10; i++) {	/* 75us timeout, wait 100us */
			udelay(10);
			if ((*addr & 0x00800080L) == 0x00800080L)
				break;
		}

		/* Not successful? */
		status = *addr;
		if (status != 0x00800080L) {
			printf("Protect %x sector failed: %x\n",
			       (uint) sector, (uint) status);
			rcode = 1;
		}

		/* Restore read mode */
		*addr = 0x00ff00ffL;

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

		break;
	case FLASH_AM040:	/* No soft sector protection */
		break;
	}

	/* Turn protection on for this sector */
	for (i = 0; i < info->sector_count; i++) {
		if (info->start[i] == sector) {
			info->protect[i] = 1;
			break;
		}
	}

	return rcode;
}

static int _flash_unprotect(flash_info_t *info, long sector)
{
	int i;
	int flag;
	ulong status;
	int rcode = 0;
	volatile long *addr = (long *) sector;

	switch (info->flash_id & FLASH_TYPEMASK) {
	case FLASH_28F320J3A:
	case FLASH_28F640J3A:
	case FLASH_28F128J3A:
		/* Disable interrupts which might cause Flash to timeout */
		flag = disable_interrupts();

		*addr = 0x00500050L;	/* Clear the status register */
		*addr = 0x00600060L;	/* Clear lock bit setup */
		*addr = 0x00D000D0L;	/* Clear lock bit confirm */

		/* Wait for command completion */
		for (i = 0; i < 80; i++) {	/* 700ms timeout, wait 800 */
			udelay(10000);	/* Delay 10ms */
			if ((*addr & 0x00800080L) == 0x00800080L)
				break;
		}

		/* Not successful? */
		status = *addr;
		if (status != 0x00800080L) {
			printf("Un-protect %x sector failed: %x\n",
			       (uint) sector, (uint) status);
			*addr = 0x00ff00ffL;
			rcode = 1;
		}

		/* restore read mode */
		*addr = 0x00ff00ffL;

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

		break;
	case FLASH_AM040:	/* No soft sector protection */
		break;
	}

	/*
	 * Fix Intel's little red wagon.  Reprotect
	 * sectors that were protected before we undid
	 * protection on a specific sector.
	 */
	for (i = 0; i < info->sector_count; i++) {
		if (info->start[i] != sector) {
			if (info->protect[i]) {
				if (_flash_protect(info, info->start[i]))
					rcode = 1;
			}
		} else		/* Turn protection off for this sector */
			info->protect[i] = 0;
	}

	return rcode;
}

int flash_real_protect(flash_info_t *info, long sector, int prot)
{
	int rcode;

	if (prot)
		rcode = _flash_protect(info, info->start[sector]);
	else
		rcode = _flash_unprotect(info, info->start[sector]);

	return rcode;
}
