/*
 * (C) Copyright 2002
 * Brad Kemp, Seranoa Networks, Brad.Kemp@seranoa.com
 *
 * 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/processor.h>

#undef  DEBUG_FLASH
/*
 * This file implements a Common Flash Interface (CFI) driver for ppcboot.
 * The width of the port and the width of the chips are determined at initialization.
 * These widths are used to calculate the address for access CFI data structures.
 * It has been tested on an Intel Strataflash implementation.
 *
 * References
 * JEDEC Standard JESD68 - Common Flash Interface (CFI)
 * JEDEC Standard JEP137-A Common Flash Interface (CFI) ID Codes
 * Intel Application Note 646 Common Flash Interface (CFI) and Command Sets
 * Intel 290667-008 3 Volt Intel StrataFlash Memory datasheet
 *
 * TODO
 * Use Primary Extended Query table (PRI) and Alternate Algorithm Query Table (ALT) to determine if protection is available
 * Add support for other command sets Use the PRI and ALT to determine command set
 * Verify erase and program timeouts.
 */

#define FLASH_CMD_CFI			0x98
#define FLASH_CMD_READ_ID		0x90
#define FLASH_CMD_RESET			0xff
#define FLASH_CMD_BLOCK_ERASE		0x20
#define FLASH_CMD_ERASE_CONFIRM		0xD0
#define FLASH_CMD_WRITE			0x40
#define FLASH_CMD_PROTECT		0x60
#define FLASH_CMD_PROTECT_SET		0x01
#define FLASH_CMD_PROTECT_CLEAR		0xD0
#define FLASH_CMD_CLEAR_STATUS		0x50
#define FLASH_CMD_WRITE_TO_BUFFER       0xE8
#define FLASH_CMD_WRITE_BUFFER_CONFIRM  0xD0

#define FLASH_STATUS_DONE		0x80
#define FLASH_STATUS_ESS		0x40
#define FLASH_STATUS_ECLBS		0x20
#define FLASH_STATUS_PSLBS		0x10
#define FLASH_STATUS_VPENS		0x08
#define FLASH_STATUS_PSS		0x04
#define FLASH_STATUS_DPS		0x02
#define FLASH_STATUS_R			0x01
#define FLASH_STATUS_PROTECT		0x01

#define FLASH_OFFSET_CFI		0x55
#define FLASH_OFFSET_CFI_RESP		0x10
#define FLASH_OFFSET_WTOUT		0x1F
#define FLASH_OFFSET_WBTOUT             0x20
#define FLASH_OFFSET_ETOUT		0x21
#define FLASH_OFFSET_CETOUT             0x22
#define FLASH_OFFSET_WMAX_TOUT		0x23
#define FLASH_OFFSET_WBMAX_TOUT         0x24
#define FLASH_OFFSET_EMAX_TOUT		0x25
#define FLASH_OFFSET_CEMAX_TOUT         0x26
#define FLASH_OFFSET_SIZE		0x27
#define FLASH_OFFSET_INTERFACE          0x28
#define FLASH_OFFSET_BUFFER_SIZE        0x2A
#define FLASH_OFFSET_NUM_ERASE_REGIONS	0x2C
#define FLASH_OFFSET_ERASE_REGIONS	0x2D
#define FLASH_OFFSET_PROTECT		0x02
#define FLASH_OFFSET_USER_PROTECTION    0x85
#define FLASH_OFFSET_INTEL_PROTECTION   0x81

#define FLASH_MAN_CFI			0x01000000

typedef union {
	unsigned char c;
	unsigned short w;
	unsigned long l;
} cfiword_t;

typedef union {
	unsigned char * cp;
	unsigned short *wp;
	unsigned long *lp;
} cfiptr_t;

#define NUM_ERASE_REGIONS 4

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

/*-----------------------------------------------------------------------
 * Functions
 */

static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c);
static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf);
static void flash_write_cmd(flash_info_t * info, int sect, uchar offset, uchar cmd);
static int flash_isequal(flash_info_t * info, int sect, uchar offset, uchar cmd);
static int flash_isset(flash_info_t * info, int sect, uchar offset, uchar cmd);
static int flash_detect_cfi(flash_info_t * info);
static ulong flash_get_size (ulong base, int banknum);
static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword);
static int flash_full_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt);
#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len);
#endif
/*-----------------------------------------------------------------------
 * create an address based on the offset and the port width
 */
inline uchar * flash_make_addr(flash_info_t * info, int sect, int offset)
{
	return ((uchar *)(info->start[sect] + (offset * info->portwidth)));
}
/*-----------------------------------------------------------------------
 * read a character at a port width address
 */
inline uchar flash_read_uchar(flash_info_t * info, uchar offset)
{
	uchar *cp;
	cp = flash_make_addr(info, 0, offset);
	return (cp[info->portwidth - 1]);
}

/*-----------------------------------------------------------------------
 * read a short word by swapping for ppc format.
 */
ushort flash_read_ushort(flash_info_t * info, int sect,  uchar offset)
{
    uchar * addr;

    addr = flash_make_addr(info, sect, offset);
    return ((addr[(2*info->portwidth) - 1] << 8) | addr[info->portwidth - 1]);

}

/*-----------------------------------------------------------------------
 * read a long word by picking the least significant byte of each maiximum
 * port size word. Swap for ppc format.
 */
ulong flash_read_long(flash_info_t * info, int sect,  uchar offset)
{
    uchar * addr;

    addr = flash_make_addr(info, sect, offset);
    return ( (addr[(2*info->portwidth) - 1] << 24 ) | (addr[(info->portwidth) -1] << 16) |
	    (addr[(4*info->portwidth) - 1] << 8) | addr[(3*info->portwidth) - 1]);

}

/*-----------------------------------------------------------------------
 */
unsigned long flash_init (void)
{
	unsigned long size;
	int i;
	unsigned long  address;


	/* The flash is positioned back to back, with the demultiplexing of the chip
	 * based on the A24 address line.
	 *
	 */

	address = CONFIG_SYS_FLASH_BASE;
	size = 0;

	/* Init: no FLASHes known */
	for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
		flash_info[i].flash_id = FLASH_UNKNOWN;
		size += flash_info[i].size = flash_get_size(address, i);
		address += CONFIG_SYS_FLASH_INCREMENT;
		if (flash_info[0].flash_id == FLASH_UNKNOWN) {
			printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx = %ld MB\n",i,
				flash_info[0].size, flash_info[i].size<<20);
		}
	}

#if 0 /* test-only */
	/* Monitor protection ON by default */
#if (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
	for(i=0; flash_info[0].start[i] < CONFIG_SYS_MONITOR_BASE+CONFIG_SYS_MONITOR_LEN-1; i++)
		(void)flash_real_protect(&flash_info[0], i, 1);
#endif
#else
	/* monitor protection ON by default */
	flash_protect (FLAG_PROTECT_SET,
		       - CONFIG_SYS_MONITOR_LEN,
		       - 1, &flash_info[1]);
#endif

	return (size);
}

/*-----------------------------------------------------------------------
 */
int flash_erase (flash_info_t *info, int s_first, int s_last)
{
	int rcode = 0;
	int prot;
	int sect;

	if( info->flash_id != FLASH_MAN_CFI) {
		printf ("Can't erase unknown flash type - aborted\n");
		return 1;
	}
	if ((s_first < 0) || (s_first > s_last)) {
		printf ("- no sectors to erase\n");
		return 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");
	}


	for (sect = s_first; sect<=s_last; sect++) {
		if (info->protect[sect] == 0) { /* not protected */
			flash_write_cmd(info, sect, 0, FLASH_CMD_CLEAR_STATUS);
			flash_write_cmd(info, sect, 0, FLASH_CMD_BLOCK_ERASE);
			flash_write_cmd(info, sect, 0, FLASH_CMD_ERASE_CONFIRM);

			if(flash_full_status_check(info, sect, info->erase_blk_tout, "erase")) {
				rcode = 1;
			} else
				printf(".");
		}
	}
	printf (" done\n");
	return rcode;
}

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

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

	printf("CFI conformant FLASH (%d x %d)",
	       (info->portwidth	 << 3 ), (info->chipwidth  << 3 ));
	printf ("  Size: %ld MB in %d Sectors\n",
		info->size >> 20, info->sector_count);
	printf(" Erase timeout %ld ms, write timeout %ld ms, buffer write timeout %ld ms, buffer size %d\n",
	       info->erase_blk_tout, info->write_tout, info->buffer_write_tout, info->buffer_size);

	printf ("  Sector Start Addresses:");
	for (i=0; i<info->sector_count; ++i) {
#ifdef CONFIG_SYS_FLASH_EMPTY_INFO
		int k;
		int size;
		int erased;
		volatile unsigned long *flash;

		/*
		 * 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   ");
		/* print empty and read-only info */
		printf (" %08lX%s%s",
			info->start[i],
			erased ? " E" : "  ",
			info->protect[i] ? "RO " : "   ");
#else
		if ((i % 5) == 0)
			printf ("\n   ");
		printf (" %08lX%s",
			info->start[i],
			info->protect[i] ? " (RO)" : "     ");
#endif
	}
	printf ("\n");
	return;
}

/*-----------------------------------------------------------------------
 * Copy memory to flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
	ulong wp;
	ulong cp;
	int aln;
	cfiword_t cword;
	int i, rc;

	/* get lower aligned address */
	wp = (addr & ~(info->portwidth - 1));

	/* handle unaligned start */
	if((aln = addr - wp) != 0) {
		cword.l = 0;
		cp = wp;
		for(i=0;i<aln; ++i, ++cp)
			flash_add_byte(info, &cword, (*(uchar *)cp));

		for(; (i< info->portwidth) && (cnt > 0) ; i++) {
			flash_add_byte(info, &cword, *src++);
			cnt--;
			cp++;
		}
		for(; (cnt == 0) && (i < info->portwidth); ++i, ++cp)
			flash_add_byte(info, &cword, (*(uchar *)cp));
		if((rc = flash_write_cfiword(info, wp, cword)) != 0)
			return rc;
		wp = cp;
	}

#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
	while(cnt >= info->portwidth) {
		i = info->buffer_size > cnt? cnt: info->buffer_size;
		if((rc = flash_write_cfibuffer(info, wp, src,i)) != ERR_OK)
			return rc;
		wp += i;
		src += i;
		cnt -=i;
	}
#else
	/* handle the aligned part */
	while(cnt >= info->portwidth) {
		cword.l = 0;
		for(i = 0; i < info->portwidth; i++) {
			flash_add_byte(info, &cword, *src++);
		}
		if((rc = flash_write_cfiword(info, wp, cword)) != 0)
			return rc;
		wp += info->portwidth;
		cnt -= info->portwidth;
	}
#endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */
	if (cnt == 0) {
		return (0);
	}

	/*
	 * handle unaligned tail bytes
	 */
	cword.l = 0;
	for (i=0, cp=wp; (i<info->portwidth) && (cnt>0); ++i, ++cp) {
		flash_add_byte(info, &cword, *src++);
		--cnt;
	}
	for (; i<info->portwidth; ++i, ++cp) {
		flash_add_byte(info, & cword, (*(uchar *)cp));
	}

	return flash_write_cfiword(info, wp, cword);
}

/*-----------------------------------------------------------------------
 */
int flash_real_protect(flash_info_t *info, long sector, int prot)
{
	int retcode = 0;

	flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
	flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT);
	if(prot)
		flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_SET);
	else
		flash_write_cmd(info, sector, 0, FLASH_CMD_PROTECT_CLEAR);

	if((retcode = flash_full_status_check(info, sector, info->erase_blk_tout,
					 prot?"protect":"unprotect")) == 0) {

		info->protect[sector] = prot;
		/* Intel's unprotect unprotects all locking */
		if(prot == 0) {
			int i;
			for(i = 0 ; i<info->sector_count; i++) {
				if(info->protect[i])
					flash_real_protect(info, i, 1);
			}
		}
	}

	return retcode;
}
/*-----------------------------------------------------------------------
 *  wait for XSR.7 to be set. Time out with an error if it does not.
 *  This routine does not set the flash to read-array mode.
 */
static int flash_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt)
{
	ulong start;

	/* Wait for command completion */
	start = get_timer (0);
	while(!flash_isset(info, sector, 0, FLASH_STATUS_DONE)) {
		if (get_timer(start) > info->erase_blk_tout) {
			printf("Flash %s timeout at address %lx\n", prompt, info->start[sector]);
			flash_write_cmd(info, sector, 0, FLASH_CMD_RESET);
			return ERR_TIMOUT;
		}
	}
	return ERR_OK;
}
/*-----------------------------------------------------------------------
 * Wait for XSR.7 to be set, if it times out print an error, otherwise do a full status check.
 * This routine sets the flash to read-array mode.
 */
static int flash_full_status_check(flash_info_t * info, ulong sector, ulong tout, char * prompt)
{
	int retcode;
	retcode = flash_status_check(info, sector, tout, prompt);
	if((retcode == ERR_OK) && !flash_isequal(info,sector, 0, FLASH_STATUS_DONE)) {
		retcode = ERR_INVAL;
		printf("Flash %s error at address %lx\n", prompt,info->start[sector]);
		if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS | FLASH_STATUS_PSLBS)){
			printf("Command Sequence Error.\n");
		} else if(flash_isset(info, sector, 0, FLASH_STATUS_ECLBS)){
			printf("Block Erase Error.\n");
			retcode = ERR_NOT_ERASED;
		} else if (flash_isset(info, sector, 0, FLASH_STATUS_PSLBS)) {
			printf("Locking Error\n");
		}
		if(flash_isset(info, sector, 0, FLASH_STATUS_DPS)){
			printf("Block locked.\n");
			retcode = ERR_PROTECTED;
		}
		if(flash_isset(info, sector, 0, FLASH_STATUS_VPENS))
			printf("Vpp Low Error.\n");
	}
	flash_write_cmd(info, sector, 0, FLASH_CMD_RESET);
	return retcode;
}
/*-----------------------------------------------------------------------
 */
static void flash_add_byte(flash_info_t *info, cfiword_t * cword, uchar c)
{
	switch(info->portwidth) {
	case FLASH_CFI_8BIT:
		cword->c = c;
		break;
	case FLASH_CFI_16BIT:
		cword->w = (cword->w << 8) | c;
		break;
	case FLASH_CFI_32BIT:
		cword->l = (cword->l << 8) | c;
	}
}


/*-----------------------------------------------------------------------
 * make a proper sized command based on the port and chip widths
 */
static void flash_make_cmd(flash_info_t * info, uchar cmd, void * cmdbuf)
{
	int i;
	uchar *cp = (uchar *)cmdbuf;
	for(i=0; i< info->portwidth; i++)
		*cp++ = ((i+1) % info->chipwidth) ? '\0':cmd;
}

/*
 * Write a proper sized command to the correct address
 */
static void flash_write_cmd(flash_info_t * info, int sect, uchar offset, uchar cmd)
{

	volatile cfiptr_t addr;
	cfiword_t cword;
	addr.cp = flash_make_addr(info, sect, offset);
	flash_make_cmd(info, cmd, &cword);
	switch(info->portwidth) {
	case FLASH_CFI_8BIT:
		*addr.cp = cword.c;
		break;
	case FLASH_CFI_16BIT:
		*addr.wp = cword.w;
		break;
	case FLASH_CFI_32BIT:
		*addr.lp = cword.l;
		break;
	}
}

/*-----------------------------------------------------------------------
 */
static int flash_isequal(flash_info_t * info, int sect, uchar offset, uchar cmd)
{
	cfiptr_t cptr;
	cfiword_t cword;
	int retval;
	cptr.cp = flash_make_addr(info, sect, offset);
	flash_make_cmd(info, cmd, &cword);
	switch(info->portwidth) {
	case FLASH_CFI_8BIT:
		retval = (cptr.cp[0] == cword.c);
		break;
	case FLASH_CFI_16BIT:
		retval = (cptr.wp[0] == cword.w);
		break;
	case FLASH_CFI_32BIT:
		retval = (cptr.lp[0] == cword.l);
		break;
	default:
		retval = 0;
		break;
	}
	return retval;
}
/*-----------------------------------------------------------------------
 */
static int flash_isset(flash_info_t * info, int sect, uchar offset, uchar cmd)
{
	cfiptr_t cptr;
	cfiword_t cword;
	int retval;
	cptr.cp = flash_make_addr(info, sect, offset);
	flash_make_cmd(info, cmd, &cword);
	switch(info->portwidth) {
	case FLASH_CFI_8BIT:
		retval = ((cptr.cp[0] & cword.c) == cword.c);
		break;
	case FLASH_CFI_16BIT:
		retval = ((cptr.wp[0] & cword.w) == cword.w);
		break;
	case FLASH_CFI_32BIT:
		retval = ((cptr.lp[0] & cword.l) == cword.l);
		break;
	default:
		retval = 0;
		break;
	}
	return retval;
}

/*-----------------------------------------------------------------------
 * detect if flash is compatible with the Common Flash Interface (CFI)
 * http://www.jedec.org/download/search/jesd68.pdf
 *
*/
static int flash_detect_cfi(flash_info_t * info)
{

	for(info->portwidth=FLASH_CFI_8BIT; info->portwidth <= FLASH_CFI_32BIT;
	    info->portwidth <<= 1) {
		for(info->chipwidth =FLASH_CFI_BY8;
		    info->chipwidth <= info->portwidth;
		    info->chipwidth <<= 1) {
			flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
			flash_write_cmd(info, 0, FLASH_OFFSET_CFI, FLASH_CMD_CFI);
			if(flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP,'Q') &&
			   flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 1, 'R') &&
			   flash_isequal(info, 0, FLASH_OFFSET_CFI_RESP + 2, 'Y'))
				return 1;
		}
	}
	return 0;
}
/*
 * The following code cannot be run from FLASH!
 *
 */
static ulong flash_get_size (ulong base, int banknum)
{
	flash_info_t * info = &flash_info[banknum];
	int i, j;
	int sect_cnt;
	unsigned long sector;
	unsigned long tmp;
	int size_ratio;
	uchar num_erase_regions;
	int  erase_region_size;
	int  erase_region_count;

	info->start[0] = base;

	if(flash_detect_cfi(info)){
#ifdef DEBUG_FLASH
		printf("portwidth=%d chipwidth=%d\n", info->portwidth, info->chipwidth); /* test-only */
#endif
		size_ratio = info->portwidth / info->chipwidth;
		num_erase_regions = flash_read_uchar(info, FLASH_OFFSET_NUM_ERASE_REGIONS);
#ifdef DEBUG_FLASH
		printf("found %d erase regions\n", num_erase_regions);
#endif
		sect_cnt = 0;
		sector = base;
		for(i = 0 ; i < num_erase_regions; i++) {
			if(i > NUM_ERASE_REGIONS) {
				printf("%d erase regions found, only %d used\n",
				       num_erase_regions, NUM_ERASE_REGIONS);
				break;
			}
			tmp = flash_read_long(info, 0, FLASH_OFFSET_ERASE_REGIONS);
			erase_region_size = (tmp & 0xffff)? ((tmp & 0xffff) * 256): 128;
			tmp >>= 16;
			erase_region_count = (tmp & 0xffff) +1;
			for(j = 0; j< erase_region_count; j++) {
				info->start[sect_cnt] = sector;
				sector += (erase_region_size * size_ratio);
				info->protect[sect_cnt] = flash_isset(info, sect_cnt, FLASH_OFFSET_PROTECT, FLASH_STATUS_PROTECT);
				sect_cnt++;
			}
		}

		info->sector_count = sect_cnt;
		/* multiply the size by the number of chips */
		info->size = (1 << flash_read_uchar(info, FLASH_OFFSET_SIZE)) * size_ratio;
		info->buffer_size = (1 << flash_read_ushort(info, 0, FLASH_OFFSET_BUFFER_SIZE));
		tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_ETOUT);
		info->erase_blk_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_EMAX_TOUT)));
		tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WBTOUT);
		info->buffer_write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WBMAX_TOUT)));
		tmp = 1 << flash_read_uchar(info, FLASH_OFFSET_WTOUT);
		info->write_tout = (tmp * (1 << flash_read_uchar(info, FLASH_OFFSET_WMAX_TOUT)))/ 1000;
		info->flash_id = FLASH_MAN_CFI;
	}

	flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
	return(info->size);
}


/*-----------------------------------------------------------------------
 */
static int flash_write_cfiword (flash_info_t *info, ulong dest, cfiword_t cword)
{

	cfiptr_t cptr;
	int flag;

	cptr.cp = (uchar *)dest;

	/* Check if Flash is (sufficiently) erased */
	switch(info->portwidth) {
	case FLASH_CFI_8BIT:
		flag = ((cptr.cp[0] & cword.c) == cword.c);
		break;
	case FLASH_CFI_16BIT:
		flag = ((cptr.wp[0] & cword.w) == cword.w);
		break;
	case FLASH_CFI_32BIT:
		flag = ((cptr.lp[0] & cword.l)	== cword.l);
		break;
	default:
		return 2;
	}
	if(!flag)
		return 2;

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

	flash_write_cmd(info, 0, 0, FLASH_CMD_CLEAR_STATUS);
	flash_write_cmd(info, 0, 0, FLASH_CMD_WRITE);

	switch(info->portwidth) {
	case FLASH_CFI_8BIT:
		cptr.cp[0] = cword.c;
		break;
	case FLASH_CFI_16BIT:
		cptr.wp[0] = cword.w;
		break;
	case FLASH_CFI_32BIT:
		cptr.lp[0] = cword.l;
		break;
	}

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

	return flash_full_status_check(info, 0, info->write_tout, "write");
}

#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE

/* loop through the sectors from the highest address
 * when the passed address is greater or equal to the sector address
 * we have a match
 */
static int find_sector(flash_info_t *info, ulong addr)
{
	int sector;
	for(sector = info->sector_count - 1; sector >= 0; sector--) {
		if(addr >= info->start[sector])
			break;
	}
	return sector;
}

static int flash_write_cfibuffer(flash_info_t * info, ulong dest, uchar * cp, int len)
{

	int sector;
	int cnt;
	int retcode;
	volatile cfiptr_t src;
	volatile cfiptr_t dst;

	src.cp = cp;
	dst.cp = (uchar *)dest;
	sector = find_sector(info, dest);
	flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
	flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_TO_BUFFER);
	if((retcode = flash_status_check(info, sector, info->buffer_write_tout,
					 "write to buffer")) == ERR_OK) {
		switch(info->portwidth) {
		case FLASH_CFI_8BIT:
			cnt = len;
			break;
		case FLASH_CFI_16BIT:
			cnt = len >> 1;
			if (len & 0x1) { /* test-only: unaligned size */
				puts("\nUnalgined size!!!\n"); /* test-only */
				cnt++;
			}
			break;
		case FLASH_CFI_32BIT:
			cnt = len >> 2;
			break;
		default:
			return ERR_INVAL;
			break;
		}
		flash_write_cmd(info, sector, 0, (uchar)cnt-1);
		while(cnt-- > 0) {
			switch(info->portwidth) {
			case FLASH_CFI_8BIT:
				*dst.cp++ = *src.cp++;
				break;
			case FLASH_CFI_16BIT:
				*dst.wp++ = *src.wp++;
				break;
			case FLASH_CFI_32BIT:
				*dst.lp++ = *src.lp++;
				break;
			default:
				return ERR_INVAL;
				break;
			}
		}
		flash_write_cmd(info, sector, 0, FLASH_CMD_WRITE_BUFFER_CONFIRM);
		retcode = flash_full_status_check(info, sector, info->buffer_write_tout,
					     "buffer write");
	}
	flash_write_cmd(info, sector, 0, FLASH_CMD_CLEAR_STATUS);
	return retcode;
}
#endif /* CONFIG_SYS_USE_FLASH_BUFFER_WRITE */
