/*
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Marius Groeger <mgroeger@sysgo.de>
 *
 * (C) Copyright 2002
 * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/* #define DEBUG */

#include <common.h>
#include <environment.h>

#define FLASH_BANK_SIZE 0x1000000	/* 2 x   8 MB */
#define MAIN_SECT_SIZE  0x40000		/* 2 x 128 kB */

flash_info_t flash_info[CFG_MAX_FLASH_BANKS];


#define CMD_READ_ARRAY		0x00FF00FF
#define CMD_IDENTIFY		0x00900090
#define CMD_ERASE_SETUP		0x00200020
#define CMD_ERASE_CONFIRM	0x00D000D0
#define CMD_PROGRAM		0x00400040
#define CMD_RESUME		0x00D000D0
#define CMD_SUSPEND		0x00B000B0
#define CMD_STATUS_READ		0x00700070
#define CMD_STATUS_RESET	0x00500050

#define BIT_BUSY		0x00800080
#define BIT_ERASE_SUSPEND	0x00400040
#define BIT_ERASE_ERROR		0x00200020
#define BIT_PROGRAM_ERROR	0x00100010
#define BIT_VPP_RANGE_ERROR	0x00080008
#define BIT_PROGRAM_SUSPEND	0x00040004
#define BIT_PROTECT_ERROR	0x00020002
#define BIT_UNDEFINED		0x00010001

#define BIT_SEQUENCE_ERROR	0x00300030
#define BIT_TIMEOUT		0x80000000

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

ulong flash_init (void)
{
	int i, j;
	ulong size = 0;

	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
		ulong flashbase = 0;

		flash_info[i].flash_id =
			(INTEL_MANUFACT     & FLASH_VENDMASK) |
			(INTEL_ID_28F640J3A & FLASH_TYPEMASK);
		flash_info[i].size = FLASH_BANK_SIZE;
		flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
		memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
		if (i == 0)
			flashbase = CFG_FLASH_BASE;
		else
			panic ("configured too many flash banks!\n");
		for (j = 0; j < flash_info[i].sector_count; j++) {
			flash_info[i].start[j] = flashbase;

			/* uniform sector size */
			flashbase += MAIN_SECT_SIZE;
		}
		size += flash_info[i].size;
	}

	/*
	 * Protect monitor and environment sectors
	 */
	flash_protect ( FLAG_PROTECT_SET,
			CFG_FLASH_BASE,
			CFG_FLASH_BASE + monitor_flash_len - 1,
			&flash_info[0]);

	flash_protect ( FLAG_PROTECT_SET,
			CFG_ENV_ADDR,
			CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);

#ifdef CFG_ENV_ADDR_REDUND
	flash_protect ( FLAG_PROTECT_SET,
			CFG_ENV_ADDR_REDUND,
			CFG_ENV_ADDR_REDUND + CFG_ENV_SIZE_REDUND - 1,
			&flash_info[0]);
#endif

	return size;
}

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

	switch (info->flash_id & FLASH_VENDMASK) {
	case (INTEL_MANUFACT & FLASH_VENDMASK):
		printf ("Intel: ");
		break;
	default:
		printf ("Unknown Vendor ");
		break;
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
	case (INTEL_ID_28F640J3A & FLASH_TYPEMASK):
		printf ("2x 28F640J3A (64Mbit)\n");
		break;
	default:
		printf ("Unknown Chip Type\n");
		goto Done;
		break;
	}

	printf ("  Size: %ld MB in %d Sectors\n",
			info->size >> 20, 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");

Done:	;
}

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

int flash_error (ulong code)
{
	/* Check bit patterns */
	/* SR.7=0 is busy, SR.7=1 is ready */
	/* all other flags indicate error on 1 */
	/* SR.0 is undefined */
	/* Timeout is our faked flag */

	/* sequence is described in Intel 290644-005 document */

	/* check Timeout */
	if (code & BIT_TIMEOUT) {
		puts ("Timeout\n");
		return ERR_TIMOUT;
	}

	/* check Busy, SR.7 */
	if (~code & BIT_BUSY) {
		puts ("Busy\n");
		return ERR_PROG_ERROR;
	}

	/* check Vpp low, SR.3 */
	if (code & BIT_VPP_RANGE_ERROR) {
		puts ("Vpp range error\n");
		return ERR_PROG_ERROR;
	}

	/* check Device Protect Error, SR.1 */
	if (code & BIT_PROTECT_ERROR) {
		puts ("Device protect error\n");
		return ERR_PROG_ERROR;
	}

	/* check Command Seq Error, SR.4 & SR.5 */
	if (code & BIT_SEQUENCE_ERROR) {
		puts ("Command seqence error\n");
		return ERR_PROG_ERROR;
	}

	/* check Block Erase Error, SR.5 */
	if (code & BIT_ERASE_ERROR) {
		puts ("Block erase error\n");
		return ERR_PROG_ERROR;
	}

	/* check Program Error, SR.4 */
	if (code & BIT_PROGRAM_ERROR) {
		puts ("Program error\n");
		return ERR_PROG_ERROR;
	}

	/* check Block Erase Suspended, SR.6 */
	if (code & BIT_ERASE_SUSPEND) {
		puts ("Block erase suspended\n");
		return ERR_PROG_ERROR;
	}

	/* check Program Suspended, SR.2 */
	if (code & BIT_PROGRAM_SUSPEND) {
		puts ("Program suspended\n");
		return ERR_PROG_ERROR;
	}

	/* OK, no error */
	return ERR_OK;
}

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

int flash_erase (flash_info_t * info, int s_first, int s_last)
{
	ulong result, result1;
	int iflag, prot, sect;
	int rc = ERR_OK;

#ifdef USE_920T_MMU
	int cflag;
#endif

	debug ("flash_erase: s_first %d  s_last %d\n", s_first, s_last);

	/* first look for protection bits */

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

	if ((s_first < 0) || (s_first > s_last)) {
		return ERR_INVAL;
	}

	if ((info->flash_id & FLASH_VENDMASK) !=
		(INTEL_MANUFACT & FLASH_VENDMASK)) {
		return ERR_UNKNOWN_FLASH_VENDOR;
	}

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

	/*
	 * Disable interrupts which might cause a timeout
	 * here. Remember that our exception vectors are
	 * at address 0 in the flash, and we don't want a
	 * (ticker) exception to happen while the flash
	 * chip is in programming mode.
	 */
#ifdef USE_920T_MMU
	cflag = dcache_status ();
	dcache_disable ();
#endif
	iflag = disable_interrupts ();

	/* Start erase on unprotected sectors */
	for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {

		debug ("Erasing sector %2d @ %08lX... ",
			sect, info->start[sect]);

		/* arm simple, non interrupt dependent timer */
		reset_timer_masked ();

		if (info->protect[sect] == 0) {	/* not protected */
			vu_long *addr = (vu_long *) (info->start[sect]);
			ulong bsR7, bsR7_2, bsR5, bsR5_2;

			/* *addr = CMD_STATUS_RESET; */
			*addr = CMD_ERASE_SETUP;
			*addr = CMD_ERASE_CONFIRM;

			/* wait until flash is ready */
			do {
				/* check timeout */
				if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
					*addr = CMD_STATUS_RESET;
					result = BIT_TIMEOUT;
					break;
				}

				*addr = CMD_STATUS_READ;
				result = *addr;
				bsR7 = result & (1 << 7);
				bsR7_2 = result & (1 << 23);
			} while (!bsR7 | !bsR7_2);

			*addr = CMD_STATUS_READ;
			result1 = *addr;
			bsR5 = result1 & (1 << 5);
			bsR5_2 = result1 & (1 << 21);
#ifdef SAMSUNG_FLASH_DEBUG
			printf ("bsR5 %lx bsR5_2 %lx\n", bsR5, bsR5_2);
			if (bsR5 != 0 && bsR5_2 != 0)
				printf ("bsR5 %lx bsR5_2 %lx\n", bsR5, bsR5_2);
#endif

			*addr = CMD_READ_ARRAY;
			*addr = CMD_RESUME;

			if ((rc = flash_error (result)) != ERR_OK)
				goto outahere;
#if 0
			printf ("ok.\n");
		} else {		/* it was protected */

			printf ("protected!\n");
#endif
		}
	}

outahere:
	/* allow flash to settle - wait 10 ms */
	udelay_masked (10000);

	if (iflag)
		enable_interrupts ();

#ifdef USE_920T_MMU
	if (cflag)
		dcache_enable ();
#endif
	return rc;
}

/*-----------------------------------------------------------------------
 * Copy memory to flash
 */

static int write_word (flash_info_t * info, ulong dest, ulong data)
{
	vu_long *addr = (vu_long *) dest;
	ulong result;
	int rc = ERR_OK;
	int iflag;

#ifdef USE_920T_MMU
	int cflag;
#endif

	/*
	 * Check if Flash is (sufficiently) erased
	 */
	result = *addr;
	if ((result & data) != data)
		return ERR_NOT_ERASED;

	/*
	 * Disable interrupts which might cause a timeout
	 * here. Remember that our exception vectors are
	 * at address 0 in the flash, and we don't want a
	 * (ticker) exception to happen while the flash
	 * chip is in programming mode.
	 */
#ifdef USE_920T_MMU
	cflag = dcache_status ();
	dcache_disable ();
#endif
	iflag = disable_interrupts ();

	/* *addr = CMD_STATUS_RESET; */
	*addr = CMD_PROGRAM;
	*addr = data;

	/* arm simple, non interrupt dependent timer */
	reset_timer_masked ();

	/* wait until flash is ready */
	do {
		/* check timeout */
		if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
			*addr = CMD_SUSPEND;
			result = BIT_TIMEOUT;
			break;
		}

		*addr = CMD_STATUS_READ;
		result = *addr;
	} while (~result & BIT_BUSY);

	/* *addr = CMD_READ_ARRAY; */
	*addr = CMD_STATUS_READ;
	result = *addr;

	rc = flash_error (result);

	if (iflag)
		enable_interrupts ();

#ifdef USE_920T_MMU
	if (cflag)
		dcache_enable ();
#endif
	*addr = CMD_READ_ARRAY;
	*addr = CMD_RESUME;
	return rc;
}

/*-----------------------------------------------------------------------
 * Copy memory to flash.
 */

int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
	ulong cp, wp, data;
	int l;
	int i, rc;

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

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

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

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

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

	return write_word (info, wp, data);
}
