/*
 * (C) Copyright 2004
 * Elmeg Communications Systems GmbH, Juergen Selent (j.selent@elmeg.de)
 *
 * Support for the Elmeg VoVPN Gateway Module
 * ------------------------------------------
 * This is a signle bank flashdriver for INTEL 28F320J3, 28F640J3
 * and 28F128J3A flashs working in 8 Bit mode.
 *
 * Most of this code is taken from existing u-boot source code.
 *
 * 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>

flash_info_t				flash_info[CONFIG_SYS_MAX_FLASH_BANKS];

#define FLASH_CMD_READ_ID		0x90
#define FLASH_CMD_READ_STATUS		0x70
#define FLASH_CMD_RESET			0xff
#define FLASH_CMD_BLOCK_ERASE		0x20
#define FLASH_CMD_ERASE_CONFIRM		0xd0
#define FLASH_CMD_CLEAR_STATUS		0x50
#define FLASH_CMD_SUSPEND_ERASE		0xb0
#define FLASH_CMD_WRITE			0x40
#define FLASH_CMD_WRITE_BUFF		0xe8
#define FLASH_CMD_PROG_RESUME		0xd0
#define FLASH_CMD_PROTECT		0x60
#define FLASH_CMD_PROTECT_SET		0x01
#define FLASH_CMD_PROTECT_CLEAR		0xd0
#define FLASH_STATUS_DONE		0x80

#define FLASH_WRITE_BUFFER_SIZE		32

#ifdef CONFIG_SYS_FLASH_16BIT
#define FLASH_WORD_SIZE			unsigned short
#define FLASH_ID_MASK			0xffff
#define FLASH_CMD_ADDR_SHIFT		0
#else
#define FLASH_WORD_SIZE			unsigned char
#define FLASH_ID_MASK			0xff
/* A0 is not used in either 8x or 16x for READ ID */
#define FLASH_CMD_ADDR_SHIFT		1
#endif


static unsigned long
flash_get(volatile FLASH_WORD_SIZE *addr, flash_info_t *info)
{
	volatile FLASH_WORD_SIZE *p;
	FLASH_WORD_SIZE value;
	int i;

	addr[0] = FLASH_CMD_READ_ID;

	/* manufactor */
	value = addr[0 << FLASH_CMD_ADDR_SHIFT];
	switch (value) {
	case (INTEL_MANUFACT & FLASH_ID_MASK):
		info->flash_id = FLASH_MAN_INTEL;
		break;
	default:
		info->flash_id = FLASH_UNKNOWN;
		info->sector_count = 0;
		info->size = 0;
		*addr = FLASH_CMD_RESET;
		return (0);

	}

	/* device */
	value = addr[1 << FLASH_CMD_ADDR_SHIFT];
	switch (value) {
	case (INTEL_ID_28F320J3A & FLASH_ID_MASK):
		info->flash_id += FLASH_28F320J3A;
		info->sector_count = 32;
		info->size = 0x00400000;
		break;
	case (INTEL_ID_28F640J3A & FLASH_ID_MASK):
		info->flash_id += FLASH_28F640J3A;
		info->sector_count = 64;
		info->size = 0x00800000;
		break;
	case (INTEL_ID_28F128J3A & FLASH_ID_MASK):
		info->flash_id += FLASH_28F128J3A;
		info->sector_count = 128;
		info->size = 0x01000000;
		break;
	default:
		info->flash_id = FLASH_UNKNOWN;
		info->sector_count = 0;
		info->size = 0;
		*addr = FLASH_CMD_RESET;
		return (0);
	}

	/* setup sectors */
	for (i = 0; i < info->sector_count; i++) {
		info->start[i] = (unsigned long)addr + (i * info->size/info->sector_count);
	}

	/* check protected sectors */
	for (i = 0; i < info->sector_count; i++) {
		p = (volatile FLASH_WORD_SIZE *)(info->start[i]);
		info->protect[i] = p[2 << FLASH_CMD_ADDR_SHIFT] & 1;
	}

	/* reset bank */
	*addr = FLASH_CMD_RESET;
	return (info->size);
}

unsigned long
flash_init(void)
{
	unsigned long	size;
	int		i;

	for (i=0; i<CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
		flash_info[i].flash_id = FLASH_UNKNOWN;
	}
	size = flash_get((volatile FLASH_WORD_SIZE *)CONFIG_SYS_FLASH_BASE, &flash_info[0]);
	if (flash_info[0].flash_id == FLASH_UNKNOWN) {
		printf ("## Unknown FLASH Size=0x%08lx\n", size);
		return (0);
	}

	/* always protect 1 sector containing the HRCW */
	flash_protect(FLAG_PROTECT_SET,
		      flash_info[0].start[0],
		      flash_info[0].start[1] - 1,
		      &flash_info[0]);

#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
	flash_protect(FLAG_PROTECT_SET,
		      CONFIG_SYS_MONITOR_FLASH,
		      CONFIG_SYS_MONITOR_FLASH+CONFIG_SYS_MONITOR_LEN-1,
		      &flash_info[0]);
#endif
#ifdef	CONFIG_ENV_IS_IN_FLASH
	flash_protect(FLAG_PROTECT_SET,
		      CONFIG_ENV_ADDR,
		      CONFIG_ENV_ADDR+CONFIG_ENV_SECT_SIZE-1,
		      &flash_info[0]);
#endif
	return (size);
}

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_INTEL:	printf ("INTEL ");		break;
	default:		printf ("Unknown Vendor ");	break;
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
	case FLASH_28F320J3A:	printf ("28F320JA3 (32 Mbit)\n");
				break;
	case FLASH_28F640J3A:	printf ("28F640JA3 (64 Mbit)\n");
				break;
	case FLASH_28F128J3A:	printf ("28F128JA3 (128 Mbit)\n");
				break;
	default:		printf ("Unknown Chip Type");
				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");
}

int
flash_erase(flash_info_t *info, int s_first, int s_last)
{
	unsigned long start, now, last;
	int flag, prot, sect;
	volatile FLASH_WORD_SIZE *addr;
	FLASH_WORD_SIZE status;

	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_UNKNOWN) {
		printf ("Cannot erase unknown flash - aborted\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");
	}

	start = get_timer (0);
	last  = start;

	for (sect = s_first; sect<=s_last; sect++) {
		if (info->protect[sect]) {
			continue;
		}

		addr = (volatile FLASH_WORD_SIZE *)(info->start[sect]);
		/* Disable interrupts which might cause a timeout here */
		flag = disable_interrupts();

#ifdef DEBUG
		printf("Erase sector %d at start addr 0x%08X", sect, (unsigned int)info->start[sect]);
#endif

		*addr = FLASH_CMD_CLEAR_STATUS;
		*addr = FLASH_CMD_BLOCK_ERASE;
		*addr = FLASH_CMD_ERASE_CONFIRM;

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

		/* wait at least 80us - let's wait 1 ms */
		udelay (1000);

		while (((status = *addr) & FLASH_STATUS_DONE) != FLASH_STATUS_DONE) {
			if ((now=get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
				printf("Flash erase timeout at address %lx\n", info->start[sect]);
				*addr = FLASH_CMD_SUSPEND_ERASE;
				*addr = FLASH_CMD_RESET;
				return (1);
			}

			/* show that we're waiting */
			if ((now - last) > 1000) {	/* every second */
				putc ('.');
				last = now;
			}
		}
		*addr = FLASH_CMD_RESET;
	}
	printf (" done\n");
	return (0);
}

static int
write_buff2( volatile FLASH_WORD_SIZE *dst,
	     volatile FLASH_WORD_SIZE *src,
	     unsigned long cnt )
{
	unsigned long start;
	FLASH_WORD_SIZE status;
	int flag, i;

	start = get_timer (0);
	while (1) {
		/* Disable interrupts which might cause a timeout here */
		flag = disable_interrupts();
		dst[0] = FLASH_CMD_WRITE_BUFF;
		if ((status = *dst) & FLASH_STATUS_DONE) {
			break;
		}

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

		if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
			return (-1);
		}
	}
	dst[0] = (FLASH_WORD_SIZE)(cnt - 1);
	for (i=0; i<cnt; i++) {
		dst[i] = src[i];
	}
	dst[0] = FLASH_CMD_PROG_RESUME;

	if (flag) {
		enable_interrupts();
	}

	return( 0 );
}

static int
poll_status( volatile FLASH_WORD_SIZE *addr )
{
	unsigned long start;

	start = get_timer (0);
	/* wait for error or finish */
	while (1) {
		if (*addr == FLASH_STATUS_DONE) {
			if (*addr == FLASH_STATUS_DONE) {
				break;
			}
		}
		if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
			*addr = FLASH_CMD_RESET;
			return (-1);
		}
	}
	*addr = FLASH_CMD_RESET;
	return (0);
}

/*
 * write_buff return values:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 * 4 - Flash not identified
 */
int
write_buff(flash_info_t *info, uchar *src, ulong udst, ulong cnt)
{
	volatile FLASH_WORD_SIZE *addr, *dst;
	unsigned long bcnt;
	int flag, i;

	if (info->flash_id == FLASH_UNKNOWN) {
		return (4);
	}

	addr = (volatile FLASH_WORD_SIZE *)(info->start[0]);
	dst = (volatile FLASH_WORD_SIZE *) udst;

#ifdef CONFIG_SYS_FLASH_16BIT
#error NYI
#else
	while (cnt > 0) {
		/* Check if buffer write is possible */
		if (cnt > 1 && (((unsigned long)dst & (FLASH_WRITE_BUFFER_SIZE - 1)) == 0)) {
			bcnt = cnt > FLASH_WRITE_BUFFER_SIZE ? FLASH_WRITE_BUFFER_SIZE : cnt;
			/* Check if Flash is (sufficiently) erased */
			for (i=0; i<bcnt; i++) {
				if ((dst[i] & src[i]) != src[i]) {
					return (2);
				}
			}
			if (write_buff2( dst,src,bcnt ) != 0) {
				addr[0] = FLASH_CMD_READ_STATUS;
			}
			if (poll_status( dst ) != 0) {
				return (1);
			}
			cnt -= bcnt;
			dst += bcnt;
			src += bcnt;
			continue;
		}

		/* Check if Flash is (sufficiently) erased */
		if ((*dst & *src) != *src) {
			return (2);
		}

		/* Disable interrupts which might cause a timeout here */
		flag = disable_interrupts();
		addr[0] = FLASH_CMD_ERASE_CONFIRM;
		addr[0] = FLASH_CMD_WRITE;
		*dst++ = *src++;
		/* re-enable interrupts if necessary */
		if (flag) {
			enable_interrupts();
		}

		if (poll_status( dst ) != 0) {
			return (1);
		}
		cnt --;
	}
#endif
	return (0);
}

int
flash_real_protect(flash_info_t *info, long sector, int prot)
{
	volatile FLASH_WORD_SIZE *addr;
	unsigned long start;

	addr = (volatile FLASH_WORD_SIZE *)(info->start[sector]);
	*addr = FLASH_CMD_CLEAR_STATUS;
	*addr = FLASH_CMD_PROTECT;

	if(prot) {
		*addr = FLASH_CMD_PROTECT_SET;
	} else {
		*addr = FLASH_CMD_PROTECT_CLEAR;
	}

	/* wait for error or finish */
	start = get_timer (0);
	while(!(addr[0] & FLASH_STATUS_DONE)){
		if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
			printf("Flash protect timeout at address %lx\n",  info->start[sector]);
			addr[0] = FLASH_CMD_RESET;
			return (1);
		}
	}

	/* Set software protect flag */
	info->protect[sector] = prot;
	*addr = FLASH_CMD_RESET;
	return (0);
}
