/*
 * (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
 *
 * Hacked for the Hymod board by Murray.Jensen@csiro.au, 20-Oct-00
 */

#include <common.h>
#include <mpc8260.h>
#include <board/hymod/flash.h>

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

/*-----------------------------------------------------------------------
 * Protection Flags:
 */
#define FLAG_PROTECT_SET	0x01
#define FLAG_PROTECT_CLEAR	0x02

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

/*
 * probe for flash bank at address "base" and store info about it
 * in the flash_info entry "fip". Fatal error if nothing there.
 */
static void
bank_probe (flash_info_t *fip, volatile bank_addr_t base)
{
	volatile bank_addr_t addr;
	bank_word_t word;
	int i;

	/* reset the flash */
	*base = BANK_CMD_RST;

	/* put flash into read id mode */
	*base = BANK_CMD_RD_ID;

	/* check the manufacturer id - must be intel */
	word = *BANK_REG_MAN_CODE (base);
	if (word != BANK_FILL_WORD (INTEL_MANUFACT&0xff))
		panic ("\nbad manufacturer's code (0x%08lx) at addr 0x%08lx",
			(unsigned long)word, (unsigned long)base);

	/* check the device id */
	word = *BANK_REG_DEV_CODE (base);
	switch (word) {

	case BANK_FILL_WORD (INTEL_ID_28F320J5&0xff):
		fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J5;
		fip->sector_count = 32;
		break;

	case BANK_FILL_WORD (INTEL_ID_28F640J5&0xff):
		fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J5;
		fip->sector_count = 64;
		break;

	case BANK_FILL_WORD (INTEL_ID_28F320J3A&0xff):
		fip->flash_id = FLASH_MAN_INTEL | FLASH_28F320J3A;
		fip->sector_count = 32;
		break;

	case BANK_FILL_WORD (INTEL_ID_28F640J3A&0xff):
		fip->flash_id = FLASH_MAN_INTEL | FLASH_28F640J3A;
		fip->sector_count = 64;
		break;

	case BANK_FILL_WORD (INTEL_ID_28F128J3A&0xff):
		fip->flash_id = FLASH_MAN_INTEL | FLASH_28F128J3A;
		fip->sector_count = 128;
		break;

	default:
		panic ("\nbad device code (0x%08lx) at addr 0x%08lx",
			(unsigned long)word, (unsigned long)base);
	}

	if (fip->sector_count >= CFG_MAX_FLASH_SECT)
		panic ("\ntoo many sectors (%d) in flash at address 0x%08lx",
			fip->sector_count, (unsigned long)base);

	addr = base;
	for (i = 0; i < fip->sector_count; i++) {
		fip->start[i] = (unsigned long)addr;
		fip->protect[i] = 0;
		addr = BANK_ADDR_NEXT_BLK (addr);
	}

	fip->size = (bank_size_t)addr - (bank_size_t)base;

	/* reset the flash */
	*base = BANK_CMD_RST;
}

static void
bank_reset (flash_info_t *info, int sect)
{
	volatile bank_addr_t addr = (bank_addr_t)info->start[sect];

#ifdef FLASH_DEBUG
	printf ("writing reset cmd to addr 0x%08lx\n", (unsigned long)addr);
#endif

	*addr = BANK_CMD_RST;
}

static void
bank_erase_init (flash_info_t *info, int sect)
{
	volatile bank_addr_t addr = (bank_addr_t)info->start[sect];
	int flag;

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

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

#ifdef FLASH_DEBUG
	printf ("writing erase cmd to addr 0x%08lx\n", (unsigned long)addr);
#endif
	*addr = BANK_CMD_ERASE1;
	*addr = BANK_CMD_ERASE2;

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

static int
bank_erase_poll (flash_info_t *info, int sect)
{
	volatile bank_addr_t addr = (bank_addr_t)info->start[sect];
	bank_word_t stat = *addr;

#ifdef FLASH_DEBUG
	printf ("checking status at addr 0x%08lx [0x%08lx]\n",
		(unsigned long)addr, (unsigned long)stat);
#endif

	if ((stat & BANK_STAT_RDY) == BANK_STAT_RDY) {
		if ((stat & BANK_STAT_ERR) != 0) {
			printf ("failed on sector %d [0x%08lx] at "
				"address 0x%08lx\n", sect,
				(unsigned long)stat, (unsigned long)addr);
			*addr = BANK_CMD_CLR_STAT;
			return (-1);
		}
		else
			return (1);
	}
	else
		return (0);
}

static int
bank_write_word (volatile bank_addr_t addr, bank_word_t value)
{
	bank_word_t stat;
	ulong start;
	int flag, retval;

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

	*addr = BANK_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 & BANK_STAT_RDY) != BANK_STAT_RDY);

	if ((stat & BANK_STAT_ERR) != 0) {
		printf ("flash program failed [0x%08lx] at address 0x%08lx\n",
			(unsigned long)stat, (unsigned long)addr);
		*addr = BANK_CMD_CLR_STAT;
		retval = 3;
	}

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

	return (retval);
}

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

unsigned long
flash_init (void)
{
	int i;

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

	bank_probe (&flash_info[0], (bank_addr_t)CFG_FLASH_BASE);

	/*
	 * protect monitor and environment sectors
	 */

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

#if defined(CFG_FLASH_ENV_ADDR)
	(void)flash_protect (FLAG_PROTECT_SET,
		      CFG_FLASH_ENV_ADDR,
#if defined(CFG_FLASH_ENV_BUF)
		      CFG_FLASH_ENV_ADDR + CFG_FLASH_ENV_BUF - 1,
#else
		      CFG_FLASH_ENV_ADDR + CFG_FLASH_ENV_SIZE - 1,
#endif
		      &flash_info[0]);
#endif

	return flash_info[0].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_28F320J5:	printf ("28F320J5 (32 Mbit, 2 x 16bit)\n");
				break;
	case FLASH_28F640J5:	printf ("28F640J5 (64 Mbit, 2 x 16bit)\n");
				break;
	case FLASH_28F320J3A:	printf ("28F320J3A (32 Mbit, 2 x 16bit)\n");
				break;
	case FLASH_28F640J3A:	printf ("28F640J3A (64 Mbit, 2 x 16bit)\n");
				break;
	case FLASH_28F128J3A:	printf ("28F320J3A (128 Mbit, 2 x 16bit)\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 % 5) == 0)
			printf ("\n   ");
		printf (" %08lX%s",
			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;
	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;
	}

	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;

			bank_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;
					rcode = 1;
					break;
				}

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

				sectdone = bank_erase_poll (info, sect);

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

			} while (!sectdone);

			if (haderr)
				break;
		}
	}

	if (haderr > 0)
		printf (" failed\n");
	else
		printf (" done\n");

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

/*-----------------------------------------------------------------------
 * Write a word to Flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 * 3 - Program failed
 */
static int
write_word (flash_info_t *info, ulong dest, ulong data)
{
	/* Check if Flash is (sufficiently) erased */
	if ((*(ulong *)dest & data) != data)
		return (2);

	return (bank_write_word ((bank_addr_t)dest, (bank_word_t)data));
}

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

int
write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
	ulong cp, wp, data;
	int i, l, 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);
		}
		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
	 */
	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;
	}

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

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