/*
 * (C) Copyright 2001
 * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com.
 *  Based on code by:
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#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;
}
