/*
 * (C) Copyright 2001
 * Josh Huber <huber@mclx.com>, Mission Critical Linux, Inc.
 *
 * 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
 */

/*
 * flash.c - flash support for the 512k, 8bit boot flash on the GEVB
 *           most of this file was based on the existing U-Boot
 *           flash drivers.
 */

#include <common.h>
#include <mpc8xx.h>
#include <galileo/gt64260R.h>
#include <galileo/memory.h>
#include "intel_flash.h"

#define FLASH_ROM       0xFFFD       /* unknown flash type                   */
#define FLASH_RAM       0xFFFE       /* unknown flash type                   */
#define FLASH_MAN_UNKNOWN 0xFFFF0000

/* #define DEBUG */
/* #define FLASH_ID_OVERRIDE */	/* Hack to set type to 040B if ROM emulator is installed.
				 * Can be used to program a ROM in circuit if a programmer
				 * is not available by swapping the rom out. */

/* Intel flash commands */
int flash_erase_intel(flash_info_t *info, int s_first, int s_last);
int write_word_intel(bank_addr_t addr, bank_word_t value);

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

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

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

unsigned long
flash_init (void)
{
	unsigned int i;
	unsigned long size_b0 = 0, size_b1 = 0;
	unsigned long base, flash_size;

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

	/* the boot flash */
	base = CFG_FLASH_BASE;
	size_b0 = flash_get_size(1, (vu_long *)base, &flash_info[0]);

	printf("[%ldkB@%lx] ", size_b0/1024, base);

	if (flash_info[0].flash_id == FLASH_UNKNOWN) {
		printf ("## Unknown FLASH at %08lx: Size = 0x%08lx = %ld MB\n",
			base, size_b0, size_b0<<20);
	}

	base = memoryGetDeviceBaseAddress(CFG_EXTRA_FLASH_DEVICE);
	for(i=1;i<CFG_MAX_FLASH_BANKS;i++) {
	    unsigned long size = flash_get_size(CFG_EXTRA_FLASH_WIDTH, (vu_long *)base, &flash_info[i]);

	    printf("[%ldMB@%lx] ", size>>20, base);

	    if (flash_info[i].flash_id == FLASH_UNKNOWN) {
		if(i==1) {
		    printf ("## Unknown FLASH at %08lx: Size = 0x%08lx = %ld MB\n",
			    base, size_b1, size_b1<<20);
		}
		break;
	    }
	    size_b1+=size;
	    base+=size;
	}

	flash_size = size_b0 + size_b1;
	return flash_size;
}

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

	if(!info->sector_count) return;

	/* set up sector start address table */
	switch(info->flash_id & FLASH_TYPEMASK) {
	    case FLASH_AM040:
	    case FLASH_28F128J3A:
	    case FLASH_28F640J3A:
	    case FLASH_RAM:
		/* this chip has uniformly spaced sectors */
		sector_size=info->size/info->sector_count;
		for (i = 0; i < info->sector_count; i++)
			info->start[i] = base + (i * sector_size);
		break;
	    default:
		if (info->flash_id & FLASH_BTYPE) {
		    /* set sector offsets for bottom boot block type	*/
		    info->start[0] = base + 0x00000000;
		    info->start[1] = base + 0x00008000;
		    info->start[2] = base + 0x0000C000;
		    info->start[3] = base + 0x00010000;
		    for (i = 4; i < info->sector_count; i++) {
			    info->start[i] = base + (i * 0x00020000) - 0x00060000;
		    }
		} else {
		    /* set sector offsets for top boot block type		*/
		    i = info->sector_count - 1;
		    info->start[i--] = base + info->size - 0x00008000;
		    info->start[i--] = base + info->size - 0x0000C000;
		    info->start[i--] = base + info->size - 0x00010000;
		    for (; i >= 0; i--) {
			    info->start[i] = base + i * 0x00020000;
		    }
		}
	}
}

/*-----------------------------------------------------------------------
 */
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_AMD:	printf ("AMD ");		break;
	case FLASH_MAN_FUJ:	printf ("FUJITSU ");		break;
	case FLASH_MAN_INTEL:	printf ("INTEL ");		break;
	default:		printf ("Unknown Vendor ");	break;
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
	case FLASH_AM040:
		printf ("AM29LV040B (4 Mbit, bottom boot sect)\n");
		break;
	case FLASH_AM400B:
		printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
		break;
	case FLASH_AM400T:
		printf ("AM29LV400T (4 Mbit, top boot sector)\n");
		break;
	case FLASH_AM800B:
		printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
		break;
	case FLASH_AM800T:
		printf ("AM29LV800T (8 Mbit, top boot sector)\n");
		break;
	case FLASH_AM160B:
		printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
		break;
	case FLASH_AM160T:
		printf ("AM29LV160T (16 Mbit, top boot sector)\n");
		break;
	case FLASH_AM320B:
		printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
		break;
	case FLASH_AM320T:
		printf ("AM29LV320T (32 Mbit, top boot sector)\n");
		break;
	case FLASH_28F640J3A:
		printf ("28F640J3A (64 Mbit)\n");
		break;
	case FLASH_28F128J3A:
		printf ("28F128J3A (128 Mbit)\n");
		break;
	case FLASH_ROM:
		printf ("ROM\n");
		break;
	case FLASH_RAM:
		printf ("RAM\n");
		break;
	default:
		printf ("Unknown Chip Type\n");
		break;
	}

	puts ("  Size: ");
	print_size (info->size, "");
	printf (" in %d Sectors\n", 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 inline void flash_cmd(int width, volatile unsigned char *addr, int offset, unsigned char cmd)
{
        /* supports 1x8, 1x16, and 2x16 */
        /* 2x8 and 4x8 are not supported */
	if(width==4) {
	    /* assuming chips are in 16 bit mode */
	    /* 2x16 */
	    unsigned long cmd32=(cmd<<16)|cmd;
	    *(volatile unsigned long *)(addr+offset*2)=cmd32;
	} else {
	    /* 1x16 or 1x8 */
	    *(volatile unsigned char *)(addr+offset)=cmd;
	}
}

static ulong
flash_get_size (int portwidth, vu_long *addr, flash_info_t *info)
{
	short i;
	volatile unsigned char *caddr = (unsigned char *)addr;
	volatile unsigned short *saddr = (unsigned short *)addr;
	volatile unsigned long *laddr = (unsigned long *)addr;
	char old[2], save;
	ulong id, manu, base = (ulong)addr;

	info->portwidth=portwidth;

	save = *caddr;

	flash_cmd(portwidth,caddr,0,0xf0);
	flash_cmd(portwidth,caddr,0,0xf0);

	udelay(10);

	old[0] = caddr[0];
	old[1] = caddr[1];


	if(old[0]!=0xf0) {
	    flash_cmd(portwidth,caddr,0,0xf0);
	    flash_cmd(portwidth,caddr,0,0xf0);

	    udelay(10);

	    if(*caddr==0xf0) {
		/* this area is ROM */
		*caddr=save;
#ifndef FLASH_ID_OVERRIDE
		info->flash_id = FLASH_ROM + FLASH_MAN_UNKNOWN;
		info->sector_count = 8;
		info->size = 0x80000;
#else
		info->flash_id = FLASH_MAN_AMD + FLASH_AM040;
		info->sector_count = 8;
		info->size = 0x80000;
		info->chipwidth=1;
#endif
		flash_get_offsets(base, info);
		return info->size;
	    }
	} else {
	    *caddr=0;

	    udelay(10);

	    if(*caddr==0) {
		/* this area is RAM */
		*caddr=save;
		info->flash_id = FLASH_RAM + FLASH_MAN_UNKNOWN;
		info->sector_count = 8;
		info->size = 0x80000;
		flash_get_offsets(base, info);
		return info->size;
	    }
	    flash_cmd(portwidth,caddr,0,0xf0);

	    udelay(10);
	}

	/* Write auto select command: read Manufacturer ID */
	flash_cmd(portwidth,caddr,0x555,0xAA);
	flash_cmd(portwidth,caddr,0x2AA,0x55);
	flash_cmd(portwidth,caddr,0x555,0x90);

	udelay(10);

	if ((caddr[0] == old[0]) &&
	    (caddr[1] == old[1])) {

	    /* this area is ROM */
#ifndef FLASH_ID_OVERRIDE
	    info->flash_id = FLASH_ROM + FLASH_MAN_UNKNOWN;
	    info->sector_count = 8;
	    info->size = 0x80000;
#else
		info->flash_id = FLASH_MAN_AMD + FLASH_AM040;
		info->sector_count = 8;
		info->size = 0x80000;
		info->chipwidth=1;
#endif
	    flash_get_offsets(base, info);
	    return info->size;
#ifdef DEBUG
	} else {
	    printf("%px%d: %02x:%02x -> %02x:%02x\n",
		    caddr, portwidth, old[0], old[1],
		    caddr[0], caddr[1]);
#endif
	}

	switch(portwidth) {
	    case 1:
		manu = caddr[0];
		manu |= manu<<16;
		id = caddr[1];
		break;
	    case 2:
		manu = saddr[0];
		manu |= manu<<16;
		id = saddr[1];
		id |= id<<16;
		break;
	    case 4:
		manu = laddr[0];
		id = laddr[1];
		break;
	default:
		id = manu = -1;
		break;
	}

#ifdef DEBUG
	printf("\n%08lx:%08lx:%08lx\n", base, manu, id);
	printf("%08lx %08lx %08lx %08lx\n",
		laddr[0],laddr[1],laddr[2],laddr[3]);
#endif

	switch (manu) {
	    case AMD_MANUFACT:
		    info->flash_id = FLASH_MAN_AMD;
		    break;
	    case FUJ_MANUFACT:
		    info->flash_id = FLASH_MAN_FUJ;
		    break;
	    case INTEL_MANUFACT:
		    info->flash_id = FLASH_MAN_INTEL;
		    break;
	    default:
		    printf("Unknown Mfr [%08lx]:%08lx\n", manu, id);
		    info->flash_id = FLASH_UNKNOWN;
		    info->sector_count = 0;
		    info->size = 0;
		    return (0);			/* no or unknown flash	*/
	}

	switch (id) {
	    case AMD_ID_LV400T:
		    info->flash_id += FLASH_AM400T;
		    info->sector_count = 11;
		    info->size = 0x00100000;
		    info->chipwidth=1;
		    break;				/* => 1 MB	*/

	    case AMD_ID_LV400B:
		    info->flash_id += FLASH_AM400B;
		    info->sector_count = 11;
		    info->size = 0x00100000;
		    info->chipwidth=1;
		    break;				/* => 1 MB	*/

	    case AMD_ID_LV800T:
		    info->flash_id += FLASH_AM800T;
		    info->sector_count = 19;
		    info->size = 0x00200000;
		    info->chipwidth=1;
		    break;				/* => 2 MB	*/

	    case AMD_ID_LV800B:
		    info->flash_id += FLASH_AM800B;
		    info->sector_count = 19;
		    info->size = 0x00200000;
		    info->chipwidth=1;
		    break;				/* => 2 MB	*/

	    case AMD_ID_LV160T:
		    info->flash_id += FLASH_AM160T;
		    info->sector_count = 35;
		    info->size = 0x00400000;
		    info->chipwidth=1;
		    break;				/* => 4 MB	*/

	    case AMD_ID_LV160B:
		    info->flash_id += FLASH_AM160B;
		    info->sector_count = 35;
		    info->size = 0x00400000;
		    info->chipwidth=1;
		    break;				/* => 4 MB	*/
#if 0	/* enable when device IDs are available */
	    case AMD_ID_LV320T:
		    info->flash_id += FLASH_AM320T;
		    info->sector_count = 67;
		    info->size = 0x00800000;
		    break;				/* => 8 MB	*/

	    case AMD_ID_LV320B:
		    info->flash_id += FLASH_AM320B;
		    info->sector_count = 67;
		    info->size = 0x00800000;
		    break;				/* => 8 MB	*/
#endif
	    case AMD_ID_LV040B:
		    info->flash_id += FLASH_AM040;
		    info->sector_count = 8;
		    info->size = 0x80000;
		    info->chipwidth=1;
		    break;

	    case INTEL_ID_28F640J3A:
		    info->flash_id += FLASH_28F640J3A;
		    info->sector_count = 64;
		    info->size = 128*1024 * 64; /* 128kbytes x 64 blocks */
		    info->chipwidth=2;
		    if(portwidth==4) info->size*=2;	/* 2x16 */
		    break;

	    case INTEL_ID_28F128J3A:
		    info->flash_id += FLASH_28F128J3A;
		    info->sector_count = 128;
		    info->size = 128*1024 * 128; /* 128kbytes x 128 blocks */
		    info->chipwidth=2;
		    if(portwidth==4) info->size*=2;	/* 2x16 */
		    break;

	    default:
		    printf("Unknown id %lx:[%lx]\n", manu, id);
		    info->flash_id = FLASH_UNKNOWN;
		    info->chipwidth=1;
		    return (0);			/* => no or unknown flash */

	}

	flash_get_offsets(base, info);

#if 0
	/* set up sector start address table */
	if (info->flash_id & FLASH_AM040) {
		/* this chip has uniformly spaced sectors */
		for (i = 0; i < info->sector_count; i++)
			info->start[i] = base + (i * 0x00010000);

	} else if (info->flash_id & FLASH_BTYPE) {
		/* set sector offsets for bottom boot block type	*/
		info->start[0] = base + 0x00000000;
		info->start[1] = base + 0x00008000;
		info->start[2] = base + 0x0000C000;
		info->start[3] = base + 0x00010000;
		for (i = 4; i < info->sector_count; i++) {
			info->start[i] = base + (i * 0x00020000) - 0x00060000;
		}
	} else {
		/* set sector offsets for top boot block type		*/
		i = info->sector_count - 1;
		info->start[i--] = base + info->size - 0x00008000;
		info->start[i--] = base + info->size - 0x0000C000;
		info->start[i--] = base + info->size - 0x00010000;
		for (; i >= 0; i--) {
			info->start[i] = base + i * 0x00020000;
		}
	}
#endif

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

	/*
	 * Prevent writes to uninitialized FLASH.
	 */
	if (info->flash_id != FLASH_UNKNOWN) {
		caddr = (volatile unsigned char *)info->start[0];

		flash_cmd(portwidth,caddr,0,0xF0);	/* reset bank */
	}

	return (info->size);
}

/* TODO: 2x16 unsupported */
int
flash_erase (flash_info_t *info, int s_first, int s_last)
{
	volatile unsigned char *addr = (char *)(info->start[0]);
	int flag, prot, sect, l_sect;
	ulong start, now, last;

	/* TODO: 2x16 unsupported */
	if(info->portwidth==4) return 1;

	if((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM) return 1;
	if((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) {
	    for (sect = s_first; sect<=s_last; sect++) {
		int sector_size=info->size/info->sector_count;
		addr = (char *)(info->start[sect]);
		memset((void *)addr, 0, sector_size);
	    }
	    return 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;
	}

	if ((info->flash_id&FLASH_VENDMASK) == FLASH_MAN_INTEL)  {
		return flash_erase_intel(info,
				(unsigned short)s_first,
				(unsigned short)s_last);
	}

#if 0
	if ((info->flash_id == FLASH_UNKNOWN) ||
	    (info->flash_id > FLASH_AMD_COMP)) {
		printf ("Can't erase unknown flash type %08lx - aborted\n",
			info->flash_id);
		return 1;
	}
#endif

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

	flash_cmd(info->portwidth,addr,0x555,0xAA);
	flash_cmd(info->portwidth,addr,0x2AA,0x55);
	flash_cmd(info->portwidth,addr,0x555,0x80);
	flash_cmd(info->portwidth,addr,0x555,0xAA);
	flash_cmd(info->portwidth,addr,0x2AA,0x55);

	/* Start erase on unprotected sectors */
	for (sect = s_first; sect<=s_last; sect++) {
		if (info->protect[sect] == 0) {	/* not protected */
			addr = (char *)(info->start[sect]);
			flash_cmd(info->portwidth,addr,0,0x30);
			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 = (volatile unsigned char *)(info->start[l_sect]);
	/* broken for 2x16: TODO */
	while ((addr[0] & 0x80) != 0x80) {
		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 */
			putc ('.');
			last = now;
		}
	}

DONE:
	/* reset to read mode */
	addr = (volatile unsigned char *)info->start[0];
	flash_cmd(info->portwidth,addr,0,0xf0);
	flash_cmd(info->portwidth,addr,0,0xf0);

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

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

/* broken for 2x16: TODO */
int
write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
	ulong cp, wp, data;
	int i, l, rc;

	if(info->portwidth==4) return 1;

	if((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM) return 0;
	if((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) {
	    memcpy((void *)addr, src, cnt);
	    return 0;
	}

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

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

		if ((rc = write_word(info, wp, data)) != 0) {
			return (rc);
		}
		wp += 4;
	}

	/*
	 * handle word aligned part
	 */
	while (cnt >= 4) {
		data = 0;
		for (i=0; i<4; ++i) {
			data = (data << 8) | *src++;
		}
		if ((rc = write_word(info, wp, data)) != 0) {
			return (rc);
		}
		wp  += 4;
		cnt -= 4;
	}

	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_word(info, wp, data));
}

/*-----------------------------------------------------------------------
 * Write a word to Flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
/* broken for 2x16: TODO */
static int
write_word (flash_info_t *info, ulong dest, ulong data)
{
	volatile unsigned char *addr = (char *)(info->start[0]);
	ulong start;
	int flag, i;

	if(info->portwidth==4) return 1;

	if((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM) return 1;
	if((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) {
	    *(unsigned long *)dest=data;
	    return 0;
	}
	if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL)  {
		unsigned short low = data & 0xffff;
		unsigned short hi  = (data >> 16) & 0xffff;
		int ret = write_word_intel((bank_addr_t)dest, hi);

		if (!ret) ret = write_word_intel((bank_addr_t)(dest+2), low);

		return ret;
	}

	/* Check if Flash is (sufficiently) erased */
	if ((*((vu_long *)dest) & data) != data) {
		return (2);
	}
	/* Disable interrupts which might cause a timeout here */
	flag = disable_interrupts();

	/* first, perform an unlock bypass command to speed up flash writes */
	addr[0x555] = 0xAA;
	addr[0x2AA] = 0x55;
	addr[0x555] = 0x20;

	/* write each byte out */
	for (i = 0; i < 4; i++) {
		char *data_ch = (char *)&data;
		addr[0] = 0xA0;
		*(((char *)dest)+i) = data_ch[i];
		udelay(10); /* XXX */
	}

	/* we're done, now do an unlock bypass reset */
	addr[0] = 0x90;
	addr[0] = 0x00;

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

	/* data polling for D7 */
	start = get_timer (0);
	while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
			return (1);
		}
	}
	return (0);
}
