/*
 * (C) Copyright 2002-2004
 * Brad Kemp, Seranoa Networks, Brad.Kemp@seranoa.com
 *
 * Copyright (C) 2003 Arabella Software Ltd.
 * Yuli Barcohen <yuli@arabellasw.com>
 *
 * Copyright (C) 2004
 * Ed Okerson
 *
 * Copyright (C) 2006
 * Tolunay Orkun <listmember@orkun.us>
 *
 * 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
 *
 */

/* The DEBUG define must be before common to enable debugging */
/* #define DEBUG	*/

#include <common.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <environment.h>
#include <mtd/cfi_flash.h>

/*
 * This file implements a Common Flash Interface (CFI) driver for
 * U-Boot.
 *
 * 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.
 *
 * 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
 * AMD CFI Specification, Release 2.0 December 1, 2001
 * AMD/Spansion Application Note: Migration from Single-byte to Three-byte
 *   Device IDs, Publication Number 25538 Revision A, November 8, 2001
 *
 * Define CONFIG_SYS_WRITE_SWAPPED_DATA, if you have to swap the Bytes between
 * reading and writing ... (yes there is such a Hardware).
 */

#ifndef CONFIG_SYS_FLASH_BANKS_LIST
#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE }
#endif

static uint flash_offset_cfi[2] = { FLASH_OFFSET_CFI, FLASH_OFFSET_CFI_ALT };
static uint flash_verbose = 1;

/* use CONFIG_SYS_MAX_FLASH_BANKS_DETECT if defined */
#ifdef CONFIG_SYS_MAX_FLASH_BANKS_DETECT
# define CFI_MAX_FLASH_BANKS	CONFIG_SYS_MAX_FLASH_BANKS_DETECT
#else
# define CFI_MAX_FLASH_BANKS	CONFIG_SYS_MAX_FLASH_BANKS
#endif

flash_info_t flash_info[CFI_MAX_FLASH_BANKS];	/* FLASH chips info */

/*
 * Check if chip width is defined. If not, start detecting with 8bit.
 */
#ifndef CONFIG_SYS_FLASH_CFI_WIDTH
#define CONFIG_SYS_FLASH_CFI_WIDTH	FLASH_CFI_8BIT
#endif

static void __flash_write8(u8 value, void *addr)
{
	__raw_writeb(value, addr);
}

static void __flash_write16(u16 value, void *addr)
{
	__raw_writew(value, addr);
}

static void __flash_write32(u32 value, void *addr)
{
	__raw_writel(value, addr);
}

static void __flash_write64(u64 value, void *addr)
{
	/* No architectures currently implement __raw_writeq() */
	*(volatile u64 *)addr = value;
}

static u8 __flash_read8(void *addr)
{
	return __raw_readb(addr);
}

static u16 __flash_read16(void *addr)
{
	return __raw_readw(addr);
}

static u32 __flash_read32(void *addr)
{
	return __raw_readl(addr);
}

static u64 __flash_read64(void *addr)
{
	/* No architectures currently implement __raw_readq() */
	return *(volatile u64 *)addr;
}

#ifdef CONFIG_CFI_FLASH_USE_WEAK_ACCESSORS
void flash_write8(u8 value, void *addr)__attribute__((weak, alias("__flash_write8")));
void flash_write16(u16 value, void *addr)__attribute__((weak, alias("__flash_write16")));
void flash_write32(u32 value, void *addr)__attribute__((weak, alias("__flash_write32")));
void flash_write64(u64 value, void *addr)__attribute__((weak, alias("__flash_write64")));
u8 flash_read8(void *addr)__attribute__((weak, alias("__flash_read8")));
u16 flash_read16(void *addr)__attribute__((weak, alias("__flash_read16")));
u32 flash_read32(void *addr)__attribute__((weak, alias("__flash_read32")));
u64 flash_read64(void *addr)__attribute__((weak, alias("__flash_read64")));
#else
#define flash_write8	__flash_write8
#define flash_write16	__flash_write16
#define flash_write32	__flash_write32
#define flash_write64	__flash_write64
#define flash_read8	__flash_read8
#define flash_read16	__flash_read16
#define flash_read32	__flash_read32
#define flash_read64	__flash_read64
#endif

/*-----------------------------------------------------------------------
 */
#if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
flash_info_t *flash_get_info(ulong base)
{
	int i;
	flash_info_t * info = 0;

	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
		info = & flash_info[i];
		if (info->size && info->start[0] <= base &&
		    base <= info->start[0] + info->size - 1)
			break;
	}

	return i == CONFIG_SYS_MAX_FLASH_BANKS ? 0 : info;
}
#endif

unsigned long flash_sector_size(flash_info_t *info, flash_sect_t sect)
{
	if (sect != (info->sector_count - 1))
		return info->start[sect + 1] - info->start[sect];
	else
		return info->start[0] + info->size - info->start[sect];
}

/*-----------------------------------------------------------------------
 * create an address based on the offset and the port width
 */
static inline void *
flash_map (flash_info_t * info, flash_sect_t sect, uint offset)
{
	unsigned int byte_offset = offset * info->portwidth;

	return (void *)(info->start[sect] + byte_offset);
}

static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
		unsigned int offset, void *addr)
{
}

/*-----------------------------------------------------------------------
 * make a proper sized command based on the port and chip widths
 */
static void flash_make_cmd(flash_info_t *info, u32 cmd, void *cmdbuf)
{
	int i;
	int cword_offset;
	int cp_offset;
#if defined(__LITTLE_ENDIAN) || defined(CONFIG_SYS_WRITE_SWAPPED_DATA)
	u32 cmd_le = cpu_to_le32(cmd);
#endif
	uchar val;
	uchar *cp = (uchar *) cmdbuf;

	for (i = info->portwidth; i > 0; i--){
		cword_offset = (info->portwidth-i)%info->chipwidth;
#if defined(__LITTLE_ENDIAN) || defined(CONFIG_SYS_WRITE_SWAPPED_DATA)
		cp_offset = info->portwidth - i;
		val = *((uchar*)&cmd_le + cword_offset);
#else
		cp_offset = i - 1;
		val = *((uchar*)&cmd + sizeof(u32) - cword_offset - 1);
#endif
		cp[cp_offset] = (cword_offset >= sizeof(u32)) ? 0x00 : val;
	}
}

#ifdef DEBUG
/*-----------------------------------------------------------------------
 * Debug support
 */
static void print_longlong (char *str, unsigned long long data)
{
	int i;
	char *cp;

	cp = (char *) &data;
	for (i = 0; i < 8; i++)
		sprintf (&str[i * 2], "%2.2x", *cp++);
}

static void flash_printqry (struct cfi_qry *qry)
{
	u8 *p = (u8 *)qry;
	int x, y;

	for (x = 0; x < sizeof(struct cfi_qry); x += 16) {
		debug("%02x : ", x);
		for (y = 0; y < 16; y++)
			debug("%2.2x ", p[x + y]);
		debug(" ");
		for (y = 0; y < 16; y++) {
			unsigned char c = p[x + y];
			if (c >= 0x20 && c <= 0x7e)
				debug("%c", c);
			else
				debug(".");
		}
		debug("\n");
	}
}
#endif


/*-----------------------------------------------------------------------
 * read a character at a port width address
 */
static inline uchar flash_read_uchar (flash_info_t * info, uint offset)
{
	uchar *cp;
	uchar retval;

	cp = flash_map (info, 0, offset);
#if defined(__LITTLE_ENDIAN) || defined(CONFIG_SYS_WRITE_SWAPPED_DATA)
	retval = flash_read8(cp);
#else
	retval = flash_read8(cp + info->portwidth - 1);
#endif
	flash_unmap (info, 0, offset, cp);
	return retval;
}

/*-----------------------------------------------------------------------
 * read a word at a port width address, assume 16bit bus
 */
static inline ushort flash_read_word (flash_info_t * info, uint offset)
{
	ushort *addr, retval;

	addr = flash_map (info, 0, offset);
	retval = flash_read16 (addr);
	flash_unmap (info, 0, offset, addr);
	return retval;
}


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

#ifdef DEBUG
	int x;
#endif
	addr = flash_map (info, sect, offset);

#ifdef DEBUG
	debug ("long addr is at %p info->portwidth = %d\n", addr,
	       info->portwidth);
	for (x = 0; x < 4 * info->portwidth; x++) {
		debug ("addr[%x] = 0x%x\n", x, flash_read8(addr + x));
	}
#endif
#if defined(__LITTLE_ENDIAN) || defined(CONFIG_SYS_WRITE_SWAPPED_DATA)
	retval = ((flash_read8(addr) << 16) |
		  (flash_read8(addr + info->portwidth) << 24) |
		  (flash_read8(addr + 2 * info->portwidth)) |
		  (flash_read8(addr + 3 * info->portwidth) << 8));
#else
	retval = ((flash_read8(addr + 2 * info->portwidth - 1) << 24) |
		  (flash_read8(addr + info->portwidth - 1) << 16) |
		  (flash_read8(addr + 4 * info->portwidth - 1) << 8) |
		  (flash_read8(addr + 3 * info->portwidth - 1)));
#endif
	flash_unmap(info, sect, offset, addr);

	return retval;
}

/*
 * Write a proper sized command to the correct address
 */
void flash_write_cmd (flash_info_t * info, flash_sect_t sect,
		      uint offset, u32 cmd)
{

	void *addr;
	cfiword_t cword;

	addr = flash_map (info, sect, offset);
	flash_make_cmd (info, cmd, &cword);
	switch (info->portwidth) {
	case FLASH_CFI_8BIT:
		debug ("fwc addr %p cmd %x %x 8bit x %d bit\n", addr, cmd,
		       cword.c, info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
		flash_write8(cword.c, addr);
		break;
	case FLASH_CFI_16BIT:
		debug ("fwc addr %p cmd %x %4.4x 16bit x %d bit\n", addr,
		       cmd, cword.w,
		       info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
		flash_write16(cword.w, addr);
		break;
	case FLASH_CFI_32BIT:
		debug ("fwc addr %p cmd %x %8.8lx 32bit x %d bit\n", addr,
		       cmd, cword.l,
		       info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
		flash_write32(cword.l, addr);
		break;
	case FLASH_CFI_64BIT:
#ifdef DEBUG
		{
			char str[20];

			print_longlong (str, cword.ll);

			debug ("fwrite addr %p cmd %x %s 64 bit x %d bit\n",
			       addr, cmd, str,
			       info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
		}
#endif
		flash_write64(cword.ll, addr);
		break;
	}

	/* Ensure all the instructions are fully finished */
	sync();

	flash_unmap(info, sect, offset, addr);
}

static void flash_unlock_seq (flash_info_t * info, flash_sect_t sect)
{
	flash_write_cmd (info, sect, info->addr_unlock1, AMD_CMD_UNLOCK_START);
	flash_write_cmd (info, sect, info->addr_unlock2, AMD_CMD_UNLOCK_ACK);
}

/*-----------------------------------------------------------------------
 */
static int flash_isequal (flash_info_t * info, flash_sect_t sect,
			  uint offset, uchar cmd)
{
	void *addr;
	cfiword_t cword;
	int retval;

	addr = flash_map (info, sect, offset);
	flash_make_cmd (info, cmd, &cword);

	debug ("is= cmd %x(%c) addr %p ", cmd, cmd, addr);
	switch (info->portwidth) {
	case FLASH_CFI_8BIT:
		debug ("is= %x %x\n", flash_read8(addr), cword.c);
		retval = (flash_read8(addr) == cword.c);
		break;
	case FLASH_CFI_16BIT:
		debug ("is= %4.4x %4.4x\n", flash_read16(addr), cword.w);
		retval = (flash_read16(addr) == cword.w);
		break;
	case FLASH_CFI_32BIT:
		debug ("is= %8.8x %8.8lx\n", flash_read32(addr), cword.l);
		retval = (flash_read32(addr) == cword.l);
		break;
	case FLASH_CFI_64BIT:
#ifdef DEBUG
		{
			char str1[20];
			char str2[20];

			print_longlong (str1, flash_read64(addr));
			print_longlong (str2, cword.ll);
			debug ("is= %s %s\n", str1, str2);
		}
#endif
		retval = (flash_read64(addr) == cword.ll);
		break;
	default:
		retval = 0;
		break;
	}
	flash_unmap(info, sect, offset, addr);

	return retval;
}

/*-----------------------------------------------------------------------
 */
static int flash_isset (flash_info_t * info, flash_sect_t sect,
			uint offset, uchar cmd)
{
	void *addr;
	cfiword_t cword;
	int retval;

	addr = flash_map (info, sect, offset);
	flash_make_cmd (info, cmd, &cword);
	switch (info->portwidth) {
	case FLASH_CFI_8BIT:
		retval = ((flash_read8(addr) & cword.c) == cword.c);
		break;
	case FLASH_CFI_16BIT:
		retval = ((flash_read16(addr) & cword.w) == cword.w);
		break;
	case FLASH_CFI_32BIT:
		retval = ((flash_read32(addr) & cword.l) == cword.l);
		break;
	case FLASH_CFI_64BIT:
		retval = ((flash_read64(addr) & cword.ll) == cword.ll);
		break;
	default:
		retval = 0;
		break;
	}
	flash_unmap(info, sect, offset, addr);

	return retval;
}

/*-----------------------------------------------------------------------
 */
static int flash_toggle (flash_info_t * info, flash_sect_t sect,
			 uint offset, uchar cmd)
{
	void *addr;
	cfiword_t cword;
	int retval;

	addr = flash_map (info, sect, offset);
	flash_make_cmd (info, cmd, &cword);
	switch (info->portwidth) {
	case FLASH_CFI_8BIT:
		retval = flash_read8(addr) != flash_read8(addr);
		break;
	case FLASH_CFI_16BIT:
		retval = flash_read16(addr) != flash_read16(addr);
		break;
	case FLASH_CFI_32BIT:
		retval = flash_read32(addr) != flash_read32(addr);
		break;
	case FLASH_CFI_64BIT:
		retval = ( (flash_read32( addr ) != flash_read32( addr )) ||
			   (flash_read32(addr+4) != flash_read32(addr+4)) );
		break;
	default:
		retval = 0;
		break;
	}
	flash_unmap(info, sect, offset, addr);

	return retval;
}

/*
 * flash_is_busy - check to see if the flash is busy
 *
 * This routine checks the status of the chip and returns true if the
 * chip is busy.
 */
static int flash_is_busy (flash_info_t * info, flash_sect_t sect)
{
	int retval;

	switch (info->vendor) {
	case CFI_CMDSET_INTEL_PROG_REGIONS:
	case CFI_CMDSET_INTEL_STANDARD:
	case CFI_CMDSET_INTEL_EXTENDED:
		retval = !flash_isset (info, sect, 0, FLASH_STATUS_DONE);
		break;
	case CFI_CMDSET_AMD_STANDARD:
	case CFI_CMDSET_AMD_EXTENDED:
#ifdef CONFIG_FLASH_CFI_LEGACY
	case CFI_CMDSET_AMD_LEGACY:
#endif
		retval = flash_toggle (info, sect, 0, AMD_STATUS_TOGGLE);
		break;
	default:
		retval = 0;
	}
	debug ("flash_is_busy: %d\n", retval);
	return retval;
}

/*-----------------------------------------------------------------------
 *  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, flash_sect_t sector,
			       ulong tout, char *prompt)
{
	ulong start;

#if CONFIG_SYS_HZ != 1000
	tout *= CONFIG_SYS_HZ/1000;
#endif

	/* Wait for command completion */
	start = get_timer (0);
	while (flash_is_busy (info, sector)) {
		if (get_timer (start) > tout) {
			printf ("Flash %s timeout at address %lx data %lx\n",
				prompt, info->start[sector],
				flash_read_long (info, sector, 0));
			flash_write_cmd (info, sector, 0, info->cmd_reset);
			return ERR_TIMOUT;
		}
		udelay (1);		/* also triggers watchdog */
	}
	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, flash_sect_t sector,
				    ulong tout, char *prompt)
{
	int retcode;

	retcode = flash_status_check (info, sector, tout, prompt);
	switch (info->vendor) {
	case CFI_CMDSET_INTEL_PROG_REGIONS:
	case CFI_CMDSET_INTEL_EXTENDED:
	case CFI_CMDSET_INTEL_STANDARD:
		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)) {
				puts ("Command Sequence Error.\n");
			} else if (flash_isset (info, sector, 0,
						FLASH_STATUS_ECLBS)) {
				puts ("Block Erase Error.\n");
				retcode = ERR_NOT_ERASED;
			} else if (flash_isset (info, sector, 0,
						FLASH_STATUS_PSLBS)) {
				puts ("Locking Error\n");
			}
			if (flash_isset (info, sector, 0, FLASH_STATUS_DPS)) {
				puts ("Block locked.\n");
				retcode = ERR_PROTECTED;
			}
			if (flash_isset (info, sector, 0, FLASH_STATUS_VPENS))
				puts ("Vpp Low Error.\n");
		}
		flash_write_cmd (info, sector, 0, info->cmd_reset);
		break;
	default:
		break;
	}
	return retcode;
}

/*-----------------------------------------------------------------------
 */
static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)
{
#if defined(__LITTLE_ENDIAN) && !defined(CONFIG_SYS_WRITE_SWAPPED_DATA)
	unsigned short	w;
	unsigned int	l;
	unsigned long long ll;
#endif

	switch (info->portwidth) {
	case FLASH_CFI_8BIT:
		cword->c = c;
		break;
	case FLASH_CFI_16BIT:
#if defined(__LITTLE_ENDIAN) && !defined(CONFIG_SYS_WRITE_SWAPPED_DATA)
		w = c;
		w <<= 8;
		cword->w = (cword->w >> 8) | w;
#else
		cword->w = (cword->w << 8) | c;
#endif
		break;
	case FLASH_CFI_32BIT:
#if defined(__LITTLE_ENDIAN) && !defined(CONFIG_SYS_WRITE_SWAPPED_DATA)
		l = c;
		l <<= 24;
		cword->l = (cword->l >> 8) | l;
#else
		cword->l = (cword->l << 8) | c;
#endif
		break;
	case FLASH_CFI_64BIT:
#if defined(__LITTLE_ENDIAN) && !defined(CONFIG_SYS_WRITE_SWAPPED_DATA)
		ll = c;
		ll <<= 56;
		cword->ll = (cword->ll >> 8) | ll;
#else
		cword->ll = (cword->ll << 8) | c;
#endif
		break;
	}
}

/*
 * Loop through the sector table starting from the previously found sector.
 * Searches forwards or backwards, dependent on the passed address.
 */
static flash_sect_t find_sector (flash_info_t * info, ulong addr)
{
	static flash_sect_t saved_sector = 0; /* previously found sector */
	flash_sect_t sector = saved_sector;

	while ((info->start[sector] < addr)
			&& (sector < info->sector_count - 1))
		sector++;
	while ((info->start[sector] > addr) && (sector > 0))
		/*
		 * also decrements the sector in case of an overshot
		 * in the first loop
		 */
		sector--;

	saved_sector = sector;
	return sector;
}

/*-----------------------------------------------------------------------
 */
static int flash_write_cfiword (flash_info_t * info, ulong dest,
				cfiword_t cword)
{
	void *dstaddr = (void *)dest;
	int flag;
	flash_sect_t sect = 0;
	char sect_found = 0;

	/* Check if Flash is (sufficiently) erased */
	switch (info->portwidth) {
	case FLASH_CFI_8BIT:
		flag = ((flash_read8(dstaddr) & cword.c) == cword.c);
		break;
	case FLASH_CFI_16BIT:
		flag = ((flash_read16(dstaddr) & cword.w) == cword.w);
		break;
	case FLASH_CFI_32BIT:
		flag = ((flash_read32(dstaddr) & cword.l) == cword.l);
		break;
	case FLASH_CFI_64BIT:
		flag = ((flash_read64(dstaddr) & cword.ll) == cword.ll);
		break;
	default:
		flag = 0;
		break;
	}
	if (!flag)
		return ERR_NOT_ERASED;

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

	switch (info->vendor) {
	case CFI_CMDSET_INTEL_PROG_REGIONS:
	case CFI_CMDSET_INTEL_EXTENDED:
	case CFI_CMDSET_INTEL_STANDARD:
		flash_write_cmd (info, 0, 0, FLASH_CMD_CLEAR_STATUS);
		flash_write_cmd (info, 0, 0, FLASH_CMD_WRITE);
		break;
	case CFI_CMDSET_AMD_EXTENDED:
	case CFI_CMDSET_AMD_STANDARD:
		sect = find_sector(info, dest);
		flash_unlock_seq (info, sect);
		flash_write_cmd (info, sect, info->addr_unlock1, AMD_CMD_WRITE);
		sect_found = 1;
		break;
#ifdef CONFIG_FLASH_CFI_LEGACY
	case CFI_CMDSET_AMD_LEGACY:
		sect = find_sector(info, dest);
		flash_unlock_seq (info, 0);
		flash_write_cmd (info, 0, info->addr_unlock1, AMD_CMD_WRITE);
		sect_found = 1;
		break;
#endif
	}

	switch (info->portwidth) {
	case FLASH_CFI_8BIT:
		flash_write8(cword.c, dstaddr);
		break;
	case FLASH_CFI_16BIT:
		flash_write16(cword.w, dstaddr);
		break;
	case FLASH_CFI_32BIT:
		flash_write32(cword.l, dstaddr);
		break;
	case FLASH_CFI_64BIT:
		flash_write64(cword.ll, dstaddr);
		break;
	}

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

	if (!sect_found)
		sect = find_sector (info, dest);

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

#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE

static int flash_write_cfibuffer (flash_info_t * info, ulong dest, uchar * cp,
				  int len)
{
	flash_sect_t sector;
	int cnt;
	int retcode;
	void *src = cp;
	void *dst = (void *)dest;
	void *dst2 = dst;
	int flag = 0;
	uint offset = 0;
	unsigned int shift;
	uchar write_cmd;

	switch (info->portwidth) {
	case FLASH_CFI_8BIT:
		shift = 0;
		break;
	case FLASH_CFI_16BIT:
		shift = 1;
		break;
	case FLASH_CFI_32BIT:
		shift = 2;
		break;
	case FLASH_CFI_64BIT:
		shift = 3;
		break;
	default:
		retcode = ERR_INVAL;
		goto out_unmap;
	}

	cnt = len >> shift;

	while ((cnt-- > 0) && (flag == 0)) {
		switch (info->portwidth) {
		case FLASH_CFI_8BIT:
			flag = ((flash_read8(dst2) & flash_read8(src)) ==
				flash_read8(src));
			src += 1, dst2 += 1;
			break;
		case FLASH_CFI_16BIT:
			flag = ((flash_read16(dst2) & flash_read16(src)) ==
				flash_read16(src));
			src += 2, dst2 += 2;
			break;
		case FLASH_CFI_32BIT:
			flag = ((flash_read32(dst2) & flash_read32(src)) ==
				flash_read32(src));
			src += 4, dst2 += 4;
			break;
		case FLASH_CFI_64BIT:
			flag = ((flash_read64(dst2) & flash_read64(src)) ==
				flash_read64(src));
			src += 8, dst2 += 8;
			break;
		}
	}
	if (!flag) {
		retcode = ERR_NOT_ERASED;
		goto out_unmap;
	}

	src = cp;
	sector = find_sector (info, dest);

	switch (info->vendor) {
	case CFI_CMDSET_INTEL_PROG_REGIONS:
	case CFI_CMDSET_INTEL_STANDARD:
	case CFI_CMDSET_INTEL_EXTENDED:
		write_cmd = (info->vendor == CFI_CMDSET_INTEL_PROG_REGIONS) ?
					FLASH_CMD_WRITE_BUFFER_PROG : FLASH_CMD_WRITE_TO_BUFFER;
		flash_write_cmd (info, sector, 0, FLASH_CMD_CLEAR_STATUS);
		flash_write_cmd (info, sector, 0, FLASH_CMD_READ_STATUS);
		flash_write_cmd (info, sector, 0, write_cmd);
		retcode = flash_status_check (info, sector,
					      info->buffer_write_tout,
					      "write to buffer");
		if (retcode == ERR_OK) {
			/* reduce the number of loops by the width of
			 * the port */
			cnt = len >> shift;
			flash_write_cmd (info, sector, 0, cnt - 1);
			while (cnt-- > 0) {
				switch (info->portwidth) {
				case FLASH_CFI_8BIT:
					flash_write8(flash_read8(src), dst);
					src += 1, dst += 1;
					break;
				case FLASH_CFI_16BIT:
					flash_write16(flash_read16(src), dst);
					src += 2, dst += 2;
					break;
				case FLASH_CFI_32BIT:
					flash_write32(flash_read32(src), dst);
					src += 4, dst += 4;
					break;
				case FLASH_CFI_64BIT:
					flash_write64(flash_read64(src), dst);
					src += 8, dst += 8;
					break;
				default:
					retcode = ERR_INVAL;
					goto out_unmap;
				}
			}
			flash_write_cmd (info, sector, 0,
					 FLASH_CMD_WRITE_BUFFER_CONFIRM);
			retcode = flash_full_status_check (
				info, sector, info->buffer_write_tout,
				"buffer write");
		}

		break;

	case CFI_CMDSET_AMD_STANDARD:
	case CFI_CMDSET_AMD_EXTENDED:
		flash_unlock_seq(info,0);

#ifdef CONFIG_FLASH_SPANSION_S29WS_N
		offset = ((unsigned long)dst - info->start[sector]) >> shift;
#endif
		flash_write_cmd(info, sector, offset, AMD_CMD_WRITE_TO_BUFFER);
		cnt = len >> shift;
		flash_write_cmd(info, sector, offset, cnt - 1);

		switch (info->portwidth) {
		case FLASH_CFI_8BIT:
			while (cnt-- > 0) {
				flash_write8(flash_read8(src), dst);
				src += 1, dst += 1;
			}
			break;
		case FLASH_CFI_16BIT:
			while (cnt-- > 0) {
				flash_write16(flash_read16(src), dst);
				src += 2, dst += 2;
			}
			break;
		case FLASH_CFI_32BIT:
			while (cnt-- > 0) {
				flash_write32(flash_read32(src), dst);
				src += 4, dst += 4;
			}
			break;
		case FLASH_CFI_64BIT:
			while (cnt-- > 0) {
				flash_write64(flash_read64(src), dst);
				src += 8, dst += 8;
			}
			break;
		default:
			retcode = ERR_INVAL;
			goto out_unmap;
		}

		flash_write_cmd (info, sector, 0, AMD_CMD_WRITE_BUFFER_CONFIRM);
		retcode = flash_full_status_check (info, sector,
						   info->buffer_write_tout,
						   "buffer write");
		break;

	default:
		debug ("Unknown Command Set\n");
		retcode = ERR_INVAL;
		break;
	}

out_unmap:
	return retcode;
}
#endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */


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

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


	for (sect = s_first; sect <= s_last; sect++) {
		if (info->protect[sect] == 0) { /* not protected */
			switch (info->vendor) {
			case CFI_CMDSET_INTEL_PROG_REGIONS:
			case CFI_CMDSET_INTEL_STANDARD:
			case CFI_CMDSET_INTEL_EXTENDED:
				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);
				break;
			case CFI_CMDSET_AMD_STANDARD:
			case CFI_CMDSET_AMD_EXTENDED:
				flash_unlock_seq (info, sect);
				flash_write_cmd (info, sect,
						info->addr_unlock1,
						AMD_CMD_ERASE_START);
				flash_unlock_seq (info, sect);
				flash_write_cmd (info, sect, 0,
						 AMD_CMD_ERASE_SECTOR);
				break;
#ifdef CONFIG_FLASH_CFI_LEGACY
			case CFI_CMDSET_AMD_LEGACY:
				flash_unlock_seq (info, 0);
				flash_write_cmd (info, 0, info->addr_unlock1,
						AMD_CMD_ERASE_START);
				flash_unlock_seq (info, 0);
				flash_write_cmd (info, sect, 0,
						AMD_CMD_ERASE_SECTOR);
				break;
#endif
			default:
				debug ("Unkown flash vendor %d\n",
				       info->vendor);
				break;
			}

			if (flash_full_status_check
			    (info, sect, info->erase_blk_tout, "erase")) {
				rcode = 1;
			} else if (flash_verbose)
				putc ('.');
		}
	}

	if (flash_verbose)
		puts (" done\n");

	return rcode;
}

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

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

	printf ("%s FLASH (%d x %d)",
		info->name,
		(info->portwidth << 3), (info->chipwidth << 3));
	if (info->size < 1024*1024)
		printf ("  Size: %ld kB in %d Sectors\n",
			info->size >> 10, info->sector_count);
	else
		printf ("  Size: %ld MB in %d Sectors\n",
			info->size >> 20, info->sector_count);
	printf ("  ");
	switch (info->vendor) {
		case CFI_CMDSET_INTEL_PROG_REGIONS:
			printf ("Intel Prog Regions");
			break;
		case CFI_CMDSET_INTEL_STANDARD:
			printf ("Intel Standard");
			break;
		case CFI_CMDSET_INTEL_EXTENDED:
			printf ("Intel Extended");
			break;
		case CFI_CMDSET_AMD_STANDARD:
			printf ("AMD Standard");
			break;
		case CFI_CMDSET_AMD_EXTENDED:
			printf ("AMD Extended");
			break;
#ifdef CONFIG_FLASH_CFI_LEGACY
		case CFI_CMDSET_AMD_LEGACY:
			printf ("AMD Legacy");
			break;
#endif
		default:
			printf ("Unknown (%d)", info->vendor);
			break;
	}
	printf (" command set, Manufacturer ID: 0x%02X, Device ID: 0x%02X",
		info->manufacturer_id, info->device_id);
	if (info->device_id == 0x7E) {
		printf("%04X", info->device_id2);
	}
	printf ("\n  Erase timeout: %ld ms, write timeout: %ld ms\n",
		info->erase_blk_tout,
		info->write_tout);
	if (info->buffer_size > 1) {
		printf ("  Buffer write timeout: %ld ms, "
			"buffer size: %d bytes\n",
		info->buffer_write_tout,
		info->buffer_size);
	}

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

		/*
		 * Check if whole sector is erased
		 */
		size = flash_sector_size(info, 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;
			}
		}

		/* print empty and read-only info */
		printf ("  %08lX %c %s ",
			info->start[i],
			erased ? 'E' : ' ',
			info->protect[i] ? "RO" : "  ");
#else	/* ! CONFIG_SYS_FLASH_EMPTY_INFO */
		printf ("  %08lX   %s ",
			info->start[i],
			info->protect[i] ? "RO" : "  ");
#endif
	}
	putc ('\n');
	return;
}

/*-----------------------------------------------------------------------
 * This is used in a few places in write_buf() to show programming
 * progress.  Making it a function is nasty because it needs to do side
 * effect updates to digit and dots.  Repeated code is nasty too, so
 * we define it once here.
 */
#ifdef CONFIG_FLASH_SHOW_PROGRESS
#define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub) \
	if (flash_verbose) { \
		dots -= dots_sub; \
		if ((scale > 0) && (dots <= 0)) { \
			if ((digit % 5) == 0) \
				printf ("%d", digit / 5); \
			else \
				putc ('.'); \
			digit--; \
			dots += scale; \
		} \
	}
#else
#define FLASH_SHOW_PROGRESS(scale, dots, digit, dots_sub)
#endif

/*-----------------------------------------------------------------------
 * 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;
	uchar *p;
	int aln;
	cfiword_t cword;
	int i, rc;
#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
	int buffered_size;
#endif
#ifdef CONFIG_FLASH_SHOW_PROGRESS
	int digit = CONFIG_FLASH_SHOW_PROGRESS;
	int scale = 0;
	int dots  = 0;

	/*
	 * Suppress if there are fewer than CONFIG_FLASH_SHOW_PROGRESS writes.
	 */
	if (cnt >= CONFIG_FLASH_SHOW_PROGRESS) {
		scale = (int)((cnt + CONFIG_FLASH_SHOW_PROGRESS - 1) /
			CONFIG_FLASH_SHOW_PROGRESS);
	}
#endif

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

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

		for (; (i < info->portwidth) && (cnt > 0); i++) {
			flash_add_byte (info, &cword, *src++);
			cnt--;
		}
		for (; (cnt == 0) && (i < info->portwidth); ++i)
			flash_add_byte (info, &cword, flash_read8(p + i));

		rc = flash_write_cfiword (info, wp, cword);
		if (rc != 0)
			return rc;

		wp += i;
		FLASH_SHOW_PROGRESS(scale, dots, digit, i);
	}

	/* handle the aligned part */
#ifdef CONFIG_SYS_FLASH_USE_BUFFER_WRITE
	buffered_size = (info->portwidth / info->chipwidth);
	buffered_size *= info->buffer_size;
	while (cnt >= info->portwidth) {
		/* prohibit buffer write when buffer_size is 1 */
		if (info->buffer_size == 1) {
			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;
			continue;
		}

		/* write buffer until next buffered_size aligned boundary */
		i = buffered_size - (wp % buffered_size);
		if (i > cnt)
			i = cnt;
		if ((rc = flash_write_cfibuffer (info, wp, src, i)) != ERR_OK)
			return rc;
		i -= i & (info->portwidth - 1);
		wp += i;
		src += i;
		cnt -= i;
		FLASH_SHOW_PROGRESS(scale, dots, digit, i);
	}
#else
	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;
		FLASH_SHOW_PROGRESS(scale, dots, digit, info->portwidth);
	}
#endif /* CONFIG_SYS_FLASH_USE_BUFFER_WRITE */

	if (cnt == 0) {
		return (0);
	}

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

	return flash_write_cfiword (info, wp, cword);
}

/*-----------------------------------------------------------------------
 */
#ifdef CONFIG_SYS_FLASH_PROTECTION

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

	switch (info->vendor) {
		case CFI_CMDSET_INTEL_PROG_REGIONS:
		case CFI_CMDSET_INTEL_STANDARD:
		case CFI_CMDSET_INTEL_EXTENDED:
			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);
			break;
		case CFI_CMDSET_AMD_EXTENDED:
		case CFI_CMDSET_AMD_STANDARD:
			/* U-Boot only checks the first byte */
			if (info->manufacturer_id == (uchar)ATM_MANUFACT) {
				if (prot) {
					flash_unlock_seq (info, 0);
					flash_write_cmd (info, 0,
							info->addr_unlock1,
							ATM_CMD_SOFTLOCK_START);
					flash_unlock_seq (info, 0);
					flash_write_cmd (info, sector, 0,
							ATM_CMD_LOCK_SECT);
				} else {
					flash_write_cmd (info, 0,
							info->addr_unlock1,
							AMD_CMD_UNLOCK_START);
					if (info->device_id == ATM_ID_BV6416)
						flash_write_cmd (info, sector,
							0, ATM_CMD_UNLOCK_SECT);
				}
			}
			break;
#ifdef CONFIG_FLASH_CFI_LEGACY
		case CFI_CMDSET_AMD_LEGACY:
			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);
#endif
	};

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

		info->protect[sector] = prot;

		/*
		 * On some of Intel's flash chips (marked via legacy_unlock)
		 * unprotect unprotects all locking.
		 */
		if ((prot == 0) && (info->legacy_unlock)) {
			flash_sect_t i;

			for (i = 0; i < info->sector_count; i++) {
				if (info->protect[i])
					flash_real_protect (info, i, 1);
			}
		}
	}
	return retcode;
}

/*-----------------------------------------------------------------------
 * flash_read_user_serial - read the OneTimeProgramming cells
 */
void flash_read_user_serial (flash_info_t * info, void *buffer, int offset,
			     int len)
{
	uchar *src;
	uchar *dst;

	dst = buffer;
	src = flash_map (info, 0, FLASH_OFFSET_USER_PROTECTION);
	flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
	memcpy (dst, src + offset, len);
	flash_write_cmd (info, 0, 0, info->cmd_reset);
	flash_unmap(info, 0, FLASH_OFFSET_USER_PROTECTION, src);
}

/*
 * flash_read_factory_serial - read the device Id from the protection area
 */
void flash_read_factory_serial (flash_info_t * info, void *buffer, int offset,
				int len)
{
	uchar *src;

	src = flash_map (info, 0, FLASH_OFFSET_INTEL_PROTECTION);
	flash_write_cmd (info, 0, 0, FLASH_CMD_READ_ID);
	memcpy (buffer, src + offset, len);
	flash_write_cmd (info, 0, 0, info->cmd_reset);
	flash_unmap(info, 0, FLASH_OFFSET_INTEL_PROTECTION, src);
}

#endif /* CONFIG_SYS_FLASH_PROTECTION */

/*-----------------------------------------------------------------------
 * Reverse the order of the erase regions in the CFI QRY structure.
 * This is needed for chips that are either a) correctly detected as
 * top-boot, or b) buggy.
 */
static void cfi_reverse_geometry(struct cfi_qry *qry)
{
	unsigned int i, j;
	u32 tmp;

	for (i = 0, j = qry->num_erase_regions - 1; i < j; i++, j--) {
		tmp = qry->erase_region_info[i];
		qry->erase_region_info[i] = qry->erase_region_info[j];
		qry->erase_region_info[j] = tmp;
	}
}

/*-----------------------------------------------------------------------
 * read jedec ids from device and set corresponding fields in info struct
 *
 * Note: assume cfi->vendor, cfi->portwidth and cfi->chipwidth are correct
 *
 */
static void cmdset_intel_read_jedec_ids(flash_info_t *info)
{
	flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
	flash_write_cmd(info, 0, 0, FLASH_CMD_READ_ID);
	udelay(1000); /* some flash are slow to respond */
	info->manufacturer_id = flash_read_uchar (info,
					FLASH_OFFSET_MANUFACTURER_ID);
	info->device_id = flash_read_uchar (info,
					FLASH_OFFSET_DEVICE_ID);
	flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
}

static int cmdset_intel_init(flash_info_t *info, struct cfi_qry *qry)
{
	info->cmd_reset = FLASH_CMD_RESET;

	cmdset_intel_read_jedec_ids(info);
	flash_write_cmd(info, 0, info->cfi_offset, FLASH_CMD_CFI);

#ifdef CONFIG_SYS_FLASH_PROTECTION
	/* read legacy lock/unlock bit from intel flash */
	if (info->ext_addr) {
		info->legacy_unlock = flash_read_uchar (info,
				info->ext_addr + 5) & 0x08;
	}
#endif

	return 0;
}

static void cmdset_amd_read_jedec_ids(flash_info_t *info)
{
	ushort bankId = 0;
	uchar  manuId;

	flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
	flash_unlock_seq(info, 0);
	flash_write_cmd(info, 0, info->addr_unlock1, FLASH_CMD_READ_ID);
	udelay(1000); /* some flash are slow to respond */

	manuId = flash_read_uchar (info, FLASH_OFFSET_MANUFACTURER_ID);
	/* JEDEC JEP106Z specifies ID codes up to bank 7 */
	while (manuId == FLASH_CONTINUATION_CODE && bankId < 0x800) {
		bankId += 0x100;
		manuId = flash_read_uchar (info,
			bankId | FLASH_OFFSET_MANUFACTURER_ID);
	}
	info->manufacturer_id = manuId;

	switch (info->chipwidth){
	case FLASH_CFI_8BIT:
		info->device_id = flash_read_uchar (info,
						FLASH_OFFSET_DEVICE_ID);
		if (info->device_id == 0x7E) {
			/* AMD 3-byte (expanded) device ids */
			info->device_id2 = flash_read_uchar (info,
						FLASH_OFFSET_DEVICE_ID2);
			info->device_id2 <<= 8;
			info->device_id2 |= flash_read_uchar (info,
						FLASH_OFFSET_DEVICE_ID3);
		}
		break;
	case FLASH_CFI_16BIT:
		info->device_id = flash_read_word (info,
						FLASH_OFFSET_DEVICE_ID);
		break;
	default:
		break;
	}
	flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
}

static int cmdset_amd_init(flash_info_t *info, struct cfi_qry *qry)
{
	info->cmd_reset = AMD_CMD_RESET;

	cmdset_amd_read_jedec_ids(info);
	flash_write_cmd(info, 0, info->cfi_offset, FLASH_CMD_CFI);

	return 0;
}

#ifdef CONFIG_FLASH_CFI_LEGACY
static void flash_read_jedec_ids (flash_info_t * info)
{
	info->manufacturer_id = 0;
	info->device_id       = 0;
	info->device_id2      = 0;

	switch (info->vendor) {
	case CFI_CMDSET_INTEL_PROG_REGIONS:
	case CFI_CMDSET_INTEL_STANDARD:
	case CFI_CMDSET_INTEL_EXTENDED:
		cmdset_intel_read_jedec_ids(info);
		break;
	case CFI_CMDSET_AMD_STANDARD:
	case CFI_CMDSET_AMD_EXTENDED:
		cmdset_amd_read_jedec_ids(info);
		break;
	default:
		break;
	}
}

/*-----------------------------------------------------------------------
 * Call board code to request info about non-CFI flash.
 * board_flash_get_legacy needs to fill in at least:
 * info->portwidth, info->chipwidth and info->interface for Jedec probing.
 */
static int flash_detect_legacy(phys_addr_t base, int banknum)
{
	flash_info_t *info = &flash_info[banknum];

	if (board_flash_get_legacy(base, banknum, info)) {
		/* board code may have filled info completely. If not, we
		   use JEDEC ID probing. */
		if (!info->vendor) {
			int modes[] = {
				CFI_CMDSET_AMD_STANDARD,
				CFI_CMDSET_INTEL_STANDARD
			};
			int i;

			for (i = 0; i < sizeof(modes) / sizeof(modes[0]); i++) {
				info->vendor = modes[i];
				info->start[0] =
					(ulong)map_physmem(base,
							   info->portwidth,
							   MAP_NOCACHE);
				if (info->portwidth == FLASH_CFI_8BIT
					&& info->interface == FLASH_CFI_X8X16) {
					info->addr_unlock1 = 0x2AAA;
					info->addr_unlock2 = 0x5555;
				} else {
					info->addr_unlock1 = 0x5555;
					info->addr_unlock2 = 0x2AAA;
				}
				flash_read_jedec_ids(info);
				debug("JEDEC PROBE: ID %x %x %x\n",
						info->manufacturer_id,
						info->device_id,
						info->device_id2);
				if (jedec_flash_match(info, info->start[0]))
					break;
				else
					unmap_physmem((void *)info->start[0],
						      MAP_NOCACHE);
			}
		}

		switch(info->vendor) {
		case CFI_CMDSET_INTEL_PROG_REGIONS:
		case CFI_CMDSET_INTEL_STANDARD:
		case CFI_CMDSET_INTEL_EXTENDED:
			info->cmd_reset = FLASH_CMD_RESET;
			break;
		case CFI_CMDSET_AMD_STANDARD:
		case CFI_CMDSET_AMD_EXTENDED:
		case CFI_CMDSET_AMD_LEGACY:
			info->cmd_reset = AMD_CMD_RESET;
			break;
		}
		info->flash_id = FLASH_MAN_CFI;
		return 1;
	}
	return 0; /* use CFI */
}
#else
static inline int flash_detect_legacy(phys_addr_t base, int banknum)
{
	return 0; /* use CFI */
}
#endif

/*-----------------------------------------------------------------------
 * detect if flash is compatible with the Common Flash Interface (CFI)
 * http://www.jedec.org/download/search/jesd68.pdf
 */
static void flash_read_cfi (flash_info_t *info, void *buf,
		unsigned int start, size_t len)
{
	u8 *p = buf;
	unsigned int i;

	for (i = 0; i < len; i++)
		p[i] = flash_read_uchar(info, start + i);
}

void __flash_cmd_reset(flash_info_t *info)
{
	/*
	 * We do not yet know what kind of commandset to use, so we issue
	 * the reset command in both Intel and AMD variants, in the hope
	 * that AMD flash roms ignore the Intel command.
	 */
	flash_write_cmd(info, 0, 0, AMD_CMD_RESET);
	flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
}
void flash_cmd_reset(flash_info_t *info)
	__attribute__((weak,alias("__flash_cmd_reset")));

static int __flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
{
	int cfi_offset;

	/* Issue FLASH reset command */
	flash_cmd_reset(info);

	for (cfi_offset=0;
	     cfi_offset < sizeof(flash_offset_cfi) / sizeof(uint);
	     cfi_offset++) {
		flash_write_cmd (info, 0, flash_offset_cfi[cfi_offset],
				 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')) {
			flash_read_cfi(info, qry, FLASH_OFFSET_CFI_RESP,
					sizeof(struct cfi_qry));
			info->interface	= le16_to_cpu(qry->interface_desc);

			info->cfi_offset = flash_offset_cfi[cfi_offset];
			debug ("device interface is %d\n",
			       info->interface);
			debug ("found port %d chip %d ",
			       info->portwidth, info->chipwidth);
			debug ("port %d bits chip %d bits\n",
			       info->portwidth << CFI_FLASH_SHIFT_WIDTH,
			       info->chipwidth << CFI_FLASH_SHIFT_WIDTH);

			/* calculate command offsets as in the Linux driver */
			info->addr_unlock1 = 0x555;
			info->addr_unlock2 = 0x2aa;

			/*
			 * modify the unlock address if we are
			 * in compatibility mode
			 */
			if (	/* x8/x16 in x8 mode */
				((info->chipwidth == FLASH_CFI_BY8) &&
					(info->interface == FLASH_CFI_X8X16)) ||
				/* x16/x32 in x16 mode */
				((info->chipwidth == FLASH_CFI_BY16) &&
					(info->interface == FLASH_CFI_X16X32)))
			{
				info->addr_unlock1 = 0xaaa;
				info->addr_unlock2 = 0x555;
			}

			info->name = "CFI conformant";
			return 1;
		}
	}

	return 0;
}

static int flash_detect_cfi (flash_info_t * info, struct cfi_qry *qry)
{
	debug ("flash detect cfi\n");

	for (info->portwidth = CONFIG_SYS_FLASH_CFI_WIDTH;
	     info->portwidth <= FLASH_CFI_64BIT; info->portwidth <<= 1) {
		for (info->chipwidth = FLASH_CFI_BY8;
		     info->chipwidth <= info->portwidth;
		     info->chipwidth <<= 1)
			if (__flash_detect_cfi(info, qry))
				return 1;
	}
	debug ("not found\n");
	return 0;
}

/*
 * Manufacturer-specific quirks. Add workarounds for geometry
 * reversal, etc. here.
 */
static void flash_fixup_amd(flash_info_t *info, struct cfi_qry *qry)
{
	/* check if flash geometry needs reversal */
	if (qry->num_erase_regions > 1) {
		/* reverse geometry if top boot part */
		if (info->cfi_version < 0x3131) {
			/* CFI < 1.1, try to guess from device id */
			if ((info->device_id & 0x80) != 0)
				cfi_reverse_geometry(qry);
		} else if (flash_read_uchar(info, info->ext_addr + 0xf) == 3) {
			/* CFI >= 1.1, deduct from top/bottom flag */
			/* note: ext_addr is valid since cfi_version > 0 */
			cfi_reverse_geometry(qry);
		}
	}
}

static void flash_fixup_atmel(flash_info_t *info, struct cfi_qry *qry)
{
	int reverse_geometry = 0;

	/* Check the "top boot" bit in the PRI */
	if (info->ext_addr && !(flash_read_uchar(info, info->ext_addr + 6) & 1))
		reverse_geometry = 1;

	/* AT49BV6416(T) list the erase regions in the wrong order.
	 * However, the device ID is identical with the non-broken
	 * AT49BV642D they differ in the high byte.
	 */
	if (info->device_id == 0xd6 || info->device_id == 0xd2)
		reverse_geometry = !reverse_geometry;

	if (reverse_geometry)
		cfi_reverse_geometry(qry);
}

static void flash_fixup_stm(flash_info_t *info, struct cfi_qry *qry)
{
	/* check if flash geometry needs reversal */
	if (qry->num_erase_regions > 1) {
		/* reverse geometry if top boot part */
		if (info->cfi_version < 0x3131) {
			/* CFI < 1.1, guess by device id (M29W320{DT,ET} only) */
			if (info->device_id == 0x22CA ||
			    info->device_id == 0x2256) {
				cfi_reverse_geometry(qry);
			}
		}
	}
}

/*
 * The following code cannot be run from FLASH!
 *
 */
ulong flash_get_size (phys_addr_t base, int banknum)
{
	flash_info_t *info = &flash_info[banknum];
	int i, j;
	flash_sect_t sect_cnt;
	phys_addr_t sector;
	unsigned long tmp;
	int size_ratio;
	uchar num_erase_regions;
	int erase_region_size;
	int erase_region_count;
	struct cfi_qry qry;

	memset(&qry, 0, sizeof(qry));

	info->ext_addr = 0;
	info->cfi_version = 0;
#ifdef CONFIG_SYS_FLASH_PROTECTION
	info->legacy_unlock = 0;
#endif

	info->start[0] = (ulong)map_physmem(base, info->portwidth, MAP_NOCACHE);

	if (flash_detect_cfi (info, &qry)) {
		info->vendor = le16_to_cpu(qry.p_id);
		info->ext_addr = le16_to_cpu(qry.p_adr);
		num_erase_regions = qry.num_erase_regions;

		if (info->ext_addr) {
			info->cfi_version = (ushort) flash_read_uchar (info,
						info->ext_addr + 3) << 8;
			info->cfi_version |= (ushort) flash_read_uchar (info,
						info->ext_addr + 4);
		}

#ifdef DEBUG
		flash_printqry (&qry);
#endif

		switch (info->vendor) {
		case CFI_CMDSET_INTEL_PROG_REGIONS:
		case CFI_CMDSET_INTEL_STANDARD:
		case CFI_CMDSET_INTEL_EXTENDED:
			cmdset_intel_init(info, &qry);
			break;
		case CFI_CMDSET_AMD_STANDARD:
		case CFI_CMDSET_AMD_EXTENDED:
			cmdset_amd_init(info, &qry);
			break;
		default:
			printf("CFI: Unknown command set 0x%x\n",
					info->vendor);
			/*
			 * Unfortunately, this means we don't know how
			 * to get the chip back to Read mode. Might
			 * as well try an Intel-style reset...
			 */
			flash_write_cmd(info, 0, 0, FLASH_CMD_RESET);
			return 0;
		}

		/* Do manufacturer-specific fixups */
		switch (info->manufacturer_id) {
		case 0x0001:
			flash_fixup_amd(info, &qry);
			break;
		case 0x001f:
			flash_fixup_atmel(info, &qry);
			break;
		case 0x0020:
			flash_fixup_stm(info, &qry);
			break;
		}

		debug ("manufacturer is %d\n", info->vendor);
		debug ("manufacturer id is 0x%x\n", info->manufacturer_id);
		debug ("device id is 0x%x\n", info->device_id);
		debug ("device id2 is 0x%x\n", info->device_id2);
		debug ("cfi version is 0x%04x\n", info->cfi_version);

		size_ratio = info->portwidth / info->chipwidth;
		/* if the chip is x8/x16 reduce the ratio by half */
		if ((info->interface == FLASH_CFI_X8X16)
		    && (info->chipwidth == FLASH_CFI_BY8)) {
			size_ratio >>= 1;
		}
		debug ("size_ratio %d port %d bits chip %d bits\n",
		       size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH,
		       info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
		debug ("found %d erase regions\n", num_erase_regions);
		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 = le32_to_cpu(qry.erase_region_info[i]);
			debug("erase region %u: 0x%08lx\n", i, tmp);

			erase_region_count = (tmp & 0xffff) + 1;
			tmp >>= 16;
			erase_region_size =
				(tmp & 0xffff) ? ((tmp & 0xffff) * 256) : 128;
			debug ("erase_region_count = %d erase_region_size = %d\n",
				erase_region_count, erase_region_size);
			for (j = 0; j < erase_region_count; j++) {
				if (sect_cnt >= CONFIG_SYS_MAX_FLASH_SECT) {
					printf("ERROR: too many flash sectors\n");
					break;
				}
				info->start[sect_cnt] =
					(ulong)map_physmem(sector,
							   info->portwidth,
							   MAP_NOCACHE);
				sector += (erase_region_size * size_ratio);

				/*
				 * Only read protection status from
				 * supported devices (intel...)
				 */
				switch (info->vendor) {
				case CFI_CMDSET_INTEL_PROG_REGIONS:
				case CFI_CMDSET_INTEL_EXTENDED:
				case CFI_CMDSET_INTEL_STANDARD:
					info->protect[sect_cnt] =
						flash_isset (info, sect_cnt,
							     FLASH_OFFSET_PROTECT,
							     FLASH_STATUS_PROTECT);
					break;
				default:
					/* default: not protected */
					info->protect[sect_cnt] = 0;
				}

				sect_cnt++;
			}
		}

		info->sector_count = sect_cnt;
		info->size = 1 << qry.dev_size;
		/* multiply the size by the number of chips */
		info->size *= size_ratio;
		info->buffer_size = 1 << le16_to_cpu(qry.max_buf_write_size);
		tmp = 1 << qry.block_erase_timeout_typ;
		info->erase_blk_tout = tmp *
			(1 << qry.block_erase_timeout_max);
		tmp = (1 << qry.buf_write_timeout_typ) *
			(1 << qry.buf_write_timeout_max);

		/* round up when converting to ms */
		info->buffer_write_tout = (tmp + 999) / 1000;
		tmp = (1 << qry.word_write_timeout_typ) *
			(1 << qry.word_write_timeout_max);
		/* round up when converting to ms */
		info->write_tout = (tmp + 999) / 1000;
		info->flash_id = FLASH_MAN_CFI;
		if ((info->interface == FLASH_CFI_X8X16) &&
		    (info->chipwidth == FLASH_CFI_BY8)) {
			/* XXX - Need to test on x8/x16 in parallel. */
			info->portwidth >>= 1;
		}

		flash_write_cmd (info, 0, 0, info->cmd_reset);
	}

	return (info->size);
}

void flash_set_verbose(uint v)
{
	flash_verbose = v;
}

/*-----------------------------------------------------------------------
 */
unsigned long flash_init (void)
{
	unsigned long size = 0;
	int i;
#if defined(CONFIG_SYS_FLASH_AUTOPROTECT_LIST)
	struct apl_s {
		ulong start;
		ulong size;
	} apl[] = CONFIG_SYS_FLASH_AUTOPROTECT_LIST;
#endif

#ifdef CONFIG_SYS_FLASH_PROTECTION
	/* read environment from EEPROM */
	char s[64];
	getenv_r ("unlock", s, sizeof(s));
#endif

#define BANK_BASE(i)	(((phys_addr_t [CFI_MAX_FLASH_BANKS])CONFIG_SYS_FLASH_BANKS_LIST)[i])

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

		if (!flash_detect_legacy (BANK_BASE(i), i))
			flash_get_size (BANK_BASE(i), i);
		size += flash_info[i].size;
		if (flash_info[i].flash_id == FLASH_UNKNOWN) {
#ifndef CONFIG_SYS_FLASH_QUIET_TEST
			printf ("## Unknown FLASH on Bank %d "
				"- Size = 0x%08lx = %ld MB\n",
				i+1, flash_info[i].size,
				flash_info[i].size << 20);
#endif /* CONFIG_SYS_FLASH_QUIET_TEST */
		}
#ifdef CONFIG_SYS_FLASH_PROTECTION
		else if ((s != NULL) && (strcmp(s, "yes") == 0)) {
			/*
			 * Only the U-Boot image and it's environment
			 * is protected, all other sectors are
			 * unprotected (unlocked) if flash hardware
			 * protection is used (CONFIG_SYS_FLASH_PROTECTION)
			 * and the environment variable "unlock" is
			 * set to "yes".
			 */
			if (flash_info[i].legacy_unlock) {
				int k;

				/*
				 * Disable legacy_unlock temporarily,
				 * since flash_real_protect would
				 * relock all other sectors again
				 * otherwise.
				 */
				flash_info[i].legacy_unlock = 0;

				/*
				 * Legacy unlocking (e.g. Intel J3) ->
				 * unlock only one sector. This will
				 * unlock all sectors.
				 */
				flash_real_protect (&flash_info[i], 0, 0);

				flash_info[i].legacy_unlock = 1;

				/*
				 * Manually mark other sectors as
				 * unlocked (unprotected)
				 */
				for (k = 1; k < flash_info[i].sector_count; k++)
					flash_info[i].protect[k] = 0;
			} else {
				/*
				 * No legancy unlocking -> unlock all sectors
				 */
				flash_protect (FLAG_PROTECT_CLEAR,
					       flash_info[i].start[0],
					       flash_info[i].start[0]
					       + flash_info[i].size - 1,
					       &flash_info[i]);
			}
		}
#endif /* CONFIG_SYS_FLASH_PROTECTION */
	}

	/* Monitor protection ON by default */
#if (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
	flash_protect (FLAG_PROTECT_SET,
		       CONFIG_SYS_MONITOR_BASE,
		       CONFIG_SYS_MONITOR_BASE + monitor_flash_len  - 1,
		       flash_get_info(CONFIG_SYS_MONITOR_BASE));
#endif

	/* Environment protection ON by default */
#ifdef CONFIG_ENV_IS_IN_FLASH
	flash_protect (FLAG_PROTECT_SET,
		       CONFIG_ENV_ADDR,
		       CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
		       flash_get_info(CONFIG_ENV_ADDR));
#endif

	/* Redundant environment protection ON by default */
#ifdef CONFIG_ENV_ADDR_REDUND
	flash_protect (FLAG_PROTECT_SET,
		       CONFIG_ENV_ADDR_REDUND,
		       CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1,
		       flash_get_info(CONFIG_ENV_ADDR_REDUND));
#endif

#if defined(CONFIG_SYS_FLASH_AUTOPROTECT_LIST)
	for (i = 0; i < (sizeof(apl) / sizeof(struct apl_s)); i++) {
		debug("autoprotecting from %08x to %08x\n",
		      apl[i].start, apl[i].start + apl[i].size - 1);
		flash_protect (FLAG_PROTECT_SET,
			       apl[i].start,
			       apl[i].start + apl[i].size - 1,
			       flash_get_info(apl[i].start));
	}
#endif

#ifdef CONFIG_FLASH_CFI_MTD
	cfi_mtd_init();
#endif

	return (size);
}
