/*
 * (C) Copyright 2000
 * Wolfgang Denk, DENX Software Engineering, wd@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
 */

#include <common.h>
#include <board/cogent/flash.h>

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

#if defined(CFG_ENV_IS_IN_FLASH)
# ifndef  CFG_ENV_ADDR
#  define CFG_ENV_ADDR	(CFG_FLASH_BASE + CFG_ENV_OFFSET)
# endif
# ifndef  CFG_ENV_SIZE
#  define CFG_ENV_SIZE	CFG_ENV_SECT_SIZE
# endif
# ifndef  CFG_ENV_SECT_SIZE
#  define CFG_ENV_SECT_SIZE  CFG_ENV_SIZE
# endif
#endif

/*-----------------------------------------------------------------------
 * Functions
 */
static int write_word (flash_info_t *info, ulong dest, ulong data);

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


#if defined(CONFIG_CMA302)

/*
 * probe for the existence of flash at address "addr"
 * 0 = yes, 1 = bad Manufacturer's Id, 2 = bad Device Id
 */
static int
c302f_probe_word(c302f_addr_t addr)
{
	/* reset the flash */
	*addr = C302F_BNK_CMD_RST;

	/* check the manufacturer id */
	*addr = C302F_BNK_CMD_RD_ID;
	if (*C302F_BNK_ADDR_MAN(addr) != C302F_BNK_RD_ID_MAN)
		return 1;

	/* check the device id */
	*addr = C302F_BNK_CMD_RD_ID;
	if (*C302F_BNK_ADDR_DEV(addr) != C302F_BNK_RD_ID_DEV)
		return 2;

#ifdef FLASH_DEBUG
	{
		int i;

		printf("\nMaster Lock Config = 0x%08lx\n",
			*C302F_BNK_ADDR_CFGM(addr));
		for (i = 0; i < C302F_BNK_NBLOCKS; i++)
			printf("Block %2d Lock Config = 0x%08lx\n",
				i, *C302F_BNK_ADDR_CFG(i, addr));
	}
#endif

	/* reset the flash again */
	*addr = C302F_BNK_CMD_RST;

	return 0;
}

/*
 * probe for Cogent CMA302 flash module at address "base" and store
 * info for any found into flash_info entry "fip". Must find at least
 * one bank.
 */
static void
c302f_probe(flash_info_t *fip, c302f_addr_t base)
{
	c302f_addr_t addr, eaddr;
	int nbanks;

	fip->size = 0L;
	fip->sector_count = 0;

	addr = base;
	eaddr = C302F_BNK_ADDR_BASE(addr, C302F_MAX_BANKS);
	nbanks = 0;

	while (addr < eaddr) {
		c302f_addr_t addrw, eaddrw, addrb;
		int i, osc, nsc;

		addrw = addr;
		eaddrw = C302F_BNK_ADDR_NEXT_WORD(addrw);

		while (addrw < eaddrw)
			if (c302f_probe_word(addrw++) != 0)
				goto out;

		/* bank exists - append info for this bank to *fip */
		fip->flash_id = FLASH_MAN_INTEL|FLASH_28F008S5;
		fip->size += C302F_BNK_SIZE;
		osc = fip->sector_count;
		fip->sector_count += C302F_BNK_NBLOCKS;
		if ((nsc = fip->sector_count) >= CFG_MAX_FLASH_SECT)
			panic("Too many sectors in flash at address 0x%08lx\n",
				(unsigned long)base);

		addrb = addr;
		for (i = osc; i < nsc; i++) {
			fip->start[i] = (ulong)addrb;
			fip->protect[i] = 0;
			addrb = C302F_BNK_ADDR_NEXT_BLK(addrb);
		}

		addr = C302F_BNK_ADDR_NEXT_BNK(addr);
		nbanks++;
	}

out:
	if (nbanks == 0)
		panic("ERROR: no flash found at address 0x%08lx\n",
			(unsigned long)base);
}

static void
c302f_reset(flash_info_t *info, int sect)
{
	c302f_addr_t addrw, eaddrw;

	addrw = (c302f_addr_t)info->start[sect];
	eaddrw = C302F_BNK_ADDR_NEXT_WORD(addrw);

	while (addrw < eaddrw) {
#ifdef FLASH_DEBUG
		printf("  writing reset cmd to addr 0x%08lx\n",
			(unsigned long)addrw);
#endif
		*addrw = C302F_BNK_CMD_RST;
		addrw++;
	}
}

static void
c302f_erase_init(flash_info_t *info, int sect)
{
	c302f_addr_t addrw, saddrw, eaddrw;
	int flag;

#ifdef FLASH_DEBUG
	printf("0x%08lx C302F_BNK_CMD_PROG\n", C302F_BNK_CMD_PROG);
	printf("0x%08lx C302F_BNK_CMD_ERASE1\n", C302F_BNK_CMD_ERASE1);
	printf("0x%08lx C302F_BNK_CMD_ERASE2\n", C302F_BNK_CMD_ERASE2);
	printf("0x%08lx C302F_BNK_CMD_CLR_STAT\n", C302F_BNK_CMD_CLR_STAT);
	printf("0x%08lx C302F_BNK_CMD_RST\n", C302F_BNK_CMD_RST);
	printf("0x%08lx C302F_BNK_STAT_RDY\n", C302F_BNK_STAT_RDY);
	printf("0x%08lx C302F_BNK_STAT_ERR\n", C302F_BNK_STAT_ERR);
#endif

	saddrw = (c302f_addr_t)info->start[sect];
	eaddrw = C302F_BNK_ADDR_NEXT_WORD(saddrw);

#ifdef FLASH_DEBUG
	printf("erasing sector %d, start addr = 0x%08lx "
		"(bank next word addr = 0x%08lx)\n", sect,
		(unsigned long)saddrw, (unsigned long)eaddrw);
#endif

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

	for (addrw = saddrw; addrw < eaddrw; addrw++) {
#ifdef FLASH_DEBUG
		printf("  writing erase cmd to addr 0x%08lx\n",
			(unsigned long)addrw);
#endif
		*addrw = C302F_BNK_CMD_ERASE1;
		*addrw = C302F_BNK_CMD_ERASE2;
	}

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

static int
c302f_erase_poll(flash_info_t *info, int sect)
{
	c302f_addr_t addrw, saddrw, eaddrw;
	int sectdone, haderr;

	saddrw = (c302f_addr_t)info->start[sect];
	eaddrw = C302F_BNK_ADDR_NEXT_WORD(saddrw);

	sectdone = 1;
	haderr = 0;

	for (addrw = saddrw; addrw < eaddrw; addrw++) {
		c302f_word_t stat = *addrw;

#ifdef FLASH_DEBUG
		printf("  checking status at addr "
			"0x%08lx [0x%08lx]\n",
			(unsigned long)addrw, stat);
#endif
		if ((stat & C302F_BNK_STAT_RDY) != C302F_BNK_STAT_RDY)
			sectdone = 0;
		else if ((stat & C302F_BNK_STAT_ERR) != 0) {
			printf(" failed on sector %d "
				"(stat = 0x%08lx) at "
				"address 0x%08lx\n",
				sect, stat,
				(unsigned long)addrw);
			*addrw = C302F_BNK_CMD_CLR_STAT;
			haderr = 1;
		}
	}

	if (haderr)
		return (-1);
	else
		return (sectdone);
}

static int
c302f_write_word(c302f_addr_t addr, c302f_word_t value)
{
	c302f_word_t stat;
	ulong start;
	int flag, retval;

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

	*addr = C302F_BNK_CMD_PROG;

	*addr = value;

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

	retval = 0;

	/* data polling for D7 */
	start = get_timer (0);
	do {
		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
			retval = 1;
			goto done;
		}
		stat = *addr;
	} while ((stat & C302F_BNK_STAT_RDY) != C302F_BNK_STAT_RDY);

	if ((stat & C302F_BNK_STAT_ERR) != 0) {
		printf("flash program failed (stat = 0x%08lx) "
			"at address 0x%08lx\n", (ulong)stat, (ulong)addr);
		*addr = C302F_BNK_CMD_CLR_STAT;
		retval = 3;
	}

done:
	/* reset to read mode */
	*addr = C302F_BNK_CMD_RST;

	return (retval);
}

#endif	/* CONFIG_CMA302 */

unsigned long
flash_init(void)
{
	unsigned long total;
	int i;
	flash_info_t *fip;

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

	fip = &flash_info[0];
	total = 0L;

#if defined(CONFIG_CMA302)
	c302f_probe(fip, (c302f_addr_t)CFG_FLASH_BASE);
	total += fip->size;
	fip++;
#endif

#if (CMA_MB_CAPS & CMA_MB_CAP_FLASH)
	/* not yet ...
	cmbf_probe(fip, (cmbf_addr_t)CMA_MB_FLASH_BASE);
	total += fip->size;
	fip++;
	*/
#endif

	/*
	 * protect monitor and environment sectors
	 */

#if CFG_MONITOR_BASE == CFG_FLASH_BASE
	flash_protect(FLAG_PROTECT_SET,
		      CFG_MONITOR_BASE,
		      CFG_MONITOR_BASE+monitor_flash_len-1,
		      &flash_info[0]);
#endif

#ifdef	CFG_ENV_IS_IN_FLASH
	/* ENV protection ON by default */
	flash_protect(FLAG_PROTECT_SET,
		      CFG_ENV_ADDR,
		      CFG_ENV_ADDR+CFG_ENV_SECT_SIZE-1,
		      &flash_info[0]);
#endif
	return total;
}

/*-----------------------------------------------------------------------
 */
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_28F008S5:	printf ("28F008S5\n");
				break;
	default:		printf ("Unknown Chip Type\n");
				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 % 4) == 0)
			printf ("\n   ");
		printf (" %2d - %08lX%s", i,
			info->start[i],
			info->protect[i] ? " (RO)" : "     "
		);
	}
	printf ("\n");
	return;
}

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


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

/*
 * The following code cannot be run from FLASH!
 */

int
flash_erase(flash_info_t *info, int s_first, int s_last)
{
	int prot, sect, haderr;
	ulong start, now, last;
	void (*erase_init)(flash_info_t *, int);
	int (*erase_poll)(flash_info_t *, int);
	void (*reset)(flash_info_t *, int);
	int rcode = 0;

#ifdef FLASH_DEBUG
	printf("\nflash_erase: erase %d sectors (%d to %d incl.) from\n"
		"  Bank # %d: ", s_last - s_first + 1, s_first, s_last,
		(info - flash_info) + 1);
	flash_print_info(info);
#endif

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

	switch (info->flash_id) {

#if defined(CONFIG_CMA302)
	case FLASH_MAN_INTEL|FLASH_28F008S5:
		erase_init = c302f_erase_init;
		erase_poll = c302f_erase_poll;
		reset = c302f_reset;
		break;
#endif

#if (CMA_MB_CAPS & CMA_MB_CAP_FLASH)
	case FLASH_MAN_INTEL|FLASH_28F800_B:
	case FLASH_MAN_AMD|FLASH_AM29F800B:
		/* not yet ...
		erase_init = cmbf_erase_init;
		erase_poll = cmbf_erase_poll;
		reset = cmbf_reset;
		break;
		*/
#endif

	default:
		printf ("Flash type %08lx not supported - aborted\n",
			info->flash_id);
		return 1;
	}

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

	if (prot) {
		printf("- Warning: %d protected sector%s will not be erased!\n",
			prot, (prot > 1 ? "s" : ""));
	}

	start = get_timer (0);
	last = 0;
	haderr = 0;

	for (sect = s_first; sect <= s_last; sect++) {
		if (info->protect[sect] == 0) {	/* not protected */
			ulong estart;
			int sectdone;

			(*erase_init)(info, sect);

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

			estart = get_timer(start);

			do {
				now = get_timer(start);

				if (now - estart > CFG_FLASH_ERASE_TOUT) {
					printf ("Timeout (sect %d)\n", sect);
					haderr = 1;
					break;
				}

#ifndef FLASH_DEBUG
				/* show that we're waiting */
				if ((now - last) > 1000) { /* every second */
					putc ('.');
					last = now;
				}
#endif

				sectdone = (*erase_poll)(info, sect);

				if (sectdone < 0) {
					haderr = 1;
					break;
				}

			} while (!sectdone);

			if (haderr)
				break;
		}
	}

	if (haderr > 0) {
		printf (" failed\n");
	        rcode = 1;
	}
	else
		printf (" done\n");

	/* reset to read mode */
	for (sect = s_first; sect <= s_last; sect++) {
		if (info->protect[sect] == 0) {	/* not protected */
			(*reset)(info, sect);
		}
	}
	return rcode;
}

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

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

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

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

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

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

		/* show that we're waiting */
		now = get_timer(start);
		if ((now - last) > 1000) {	/* every second */
			putc ('.');
			last = now;
		}
	}

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

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

	return (write_word(info, wp, data));
}

/*-----------------------------------------------------------------------
 * Write a word to Flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 * 3 - write error
 */
static int
write_word(flash_info_t *info, ulong dest, ulong data)
{
	int retval;

	/* Check if Flash is (sufficiently) erased */
	if ((*(ulong *)dest & data) != data) {
		return (2);
	}

	switch (info->flash_id) {

#if defined(CONFIG_CMA302)
	case FLASH_MAN_INTEL|FLASH_28F008S5:
		retval = c302f_write_word((c302f_addr_t)dest, (c302f_word_t)data);
		break;
#endif

#if (CMA_MB_CAPS & CMA_MB_CAP_FLASH)
	case FLASH_MAN_INTEL|FLASH_28F800_B:
	case FLASH_MAN_AMD|FLASH_AM29F800B:
		/* not yet ...
		retval = cmbf_write_word((cmbf_addr_t)dest, (cmbf_word_t)data);
		*/
		retval = 3;
		break;
#endif

	default:
		printf ("Flash type %08lx not supported - aborted\n",
			info->flash_id);
		retval = 3;
		break;
	}

	return (retval);
}

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