/*
 * (C) Copyright 2001
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * (C) Copyright 2002
 * Gregory E. Allen, gallen@arlut.utexas.edu
 * Matthew E. Karger, karger@arlut.utexas.edu
 * Applied Research Laboratories, The University of Texas at Austin
 *
 * 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 <mpc824x.h>
#include <asm/processor.h>

#define ROM_CS0_START	0xFF800000
#define ROM_CS1_START	0xFF000000

#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

#define	FLASH_BANK_SIZE	((uint)(16 * 1024 * 1024))	/* max 16Mbyte */
#define	MAIN_SECT_SIZE	0x10000
#define	SECT_SIZE_32KB	0x8000
#define	SECT_SIZE_8KB	0x2000

flash_info_t flash_info[CFG_MAX_FLASH_BANKS];

static int write_word (flash_info_t * info, ulong dest, ulong data);
#if 0
static void write_via_fpu (vu_long * addr, ulong * data);
#endif
static __inline__ unsigned long get_msr (void);
static __inline__ void set_msr (unsigned long msr);

/*flash command address offsets*/
#define ADDR0		(0x555)
#define ADDR1		(0xAAA)
#define ADDR3		(0x001)

#define FLASH_WORD_SIZE unsigned char

/*---------------------------------------------------------------------*/
/*#define	DEBUG_FLASH	1 */

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

unsigned long flash_init (void)
{
	int i;		/* flash bank counter */
	int j;		/* flash device sector counter */
	int k;		/* flash size calculation loop counter */
	int N;		/* pow(2,N) is flash size, but we don't have <math.h> */
	ulong total_size = 0, device_size = 1;
	unsigned char manuf_id, device_id;

	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
		vu_char *addr = (vu_char *) (CFG_FLASH_BASE + i * FLASH_BANK_SIZE);

		addr[0x555] = 0xAA;		/* get manuf/device info command */
		addr[0x2AA] = 0x55;		/* 3-cycle command */
		addr[0x555] = 0x90;

		manuf_id = addr[0];		/* read back manuf/device info */
		device_id = addr[1];

		addr[0x55] = 0x98;		/* CFI command */
		N = addr[0x27];			/* read back device_size = pow(2,N) */

		for (k = 0; k < N; k++)	/* calculate device_size = pow(2,N) */
			device_size *= 2;

		flash_info[i].size = device_size;
		flash_info[i].sector_count = CFG_MAX_FLASH_SECT;

#if defined DEBUG_FLASH
		printf ("manuf_id = %x, device_id = %x\n", manuf_id, device_id);
#endif
		/* find out what kind of flash we are using */
		if ((manuf_id == (uchar) (AMD_MANUFACT))
			&& (device_id == AMD_ID_LV033C)) {
			flash_info[i].flash_id =
					((FLASH_MAN_AMD & FLASH_VENDMASK) << 16) |
					(FLASH_AM033C & FLASH_TYPEMASK);

			/* set individual sector start addresses */
			for (j = 0; j < flash_info[i].sector_count; j++) {
				flash_info[i].start[j] =
						(CFG_FLASH_BASE + i * FLASH_BANK_SIZE +
						 j * MAIN_SECT_SIZE);
			}
		}

		else if ((manuf_id == (uchar) (AMD_MANUFACT)) &&
				 (device_id == AMD_ID_LV116DT)) {
			flash_info[i].flash_id =
					((FLASH_MAN_AMD & FLASH_VENDMASK) << 16) |
					(FLASH_AM160T & FLASH_TYPEMASK);

			/* set individual sector start addresses */
			for (j = 0; j < flash_info[i].sector_count; j++) {
				flash_info[i].start[j] =
						(CFG_FLASH_BASE + i * FLASH_BANK_SIZE +
						 j * MAIN_SECT_SIZE);

				if (j < (CFG_MAX_FLASH_SECT - 3)) {
					flash_info[i].start[j] =
							(CFG_FLASH_BASE + i * FLASH_BANK_SIZE +
							 j * MAIN_SECT_SIZE);
				} else if (j == (CFG_MAX_FLASH_SECT - 3)) {
					flash_info[i].start[j] =
							(flash_info[i].start[j - 1] + SECT_SIZE_32KB);

				} else {
					flash_info[i].start[j] =
							(flash_info[i].start[j - 1] + SECT_SIZE_8KB);
				}
			}
		}

		else {
			flash_info[i].flash_id = FLASH_UNKNOWN;
			addr[0] = 0xFF;
			goto Done;
		}

#if defined DEBUG_FLASH
		printf ("flash_id = 0x%08lX\n", flash_info[i].flash_id);
#endif

		addr[0] = 0xFF;

		memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);

		total_size += flash_info[i].size;
	}

	/* 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

#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
	flash_protect (FLAG_PROTECT_SET, CFG_ENV_ADDR,
			CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
#endif

  Done:
	return total_size;
}

/*-----------------------------------------------------------------------
 */
void flash_print_info (flash_info_t * info)
{
	static const char unk[] = "Unknown";
	const char *mfct = unk, *type = unk;
	unsigned int i;

	if (info->flash_id != FLASH_UNKNOWN) {
		switch (info->flash_id & FLASH_VENDMASK) {
		case FLASH_MAN_AMD:
			mfct = "AMD";
			break;
		case FLASH_MAN_FUJ:
			mfct = "FUJITSU";
			break;
		case FLASH_MAN_STM:
			mfct = "STM";
			break;
		case FLASH_MAN_SST:
			mfct = "SST";
			break;
		case FLASH_MAN_BM:
			mfct = "Bright Microelectonics";
			break;
		case FLASH_MAN_INTEL:
			mfct = "Intel";
			break;
		}

		switch (info->flash_id & FLASH_TYPEMASK) {
		case FLASH_AM033C:
			type = "AM29LV033C (32 Mbit, uniform sector size)";
			break;
		case FLASH_AM160T:
			type = "AM29LV160T (16 Mbit, top boot sector)";
			break;
		case FLASH_AM040:
			type = "AM29F040B (512K * 8, uniform sector size)";
			break;
		case FLASH_AM400B:
			type = "AM29LV400B (4 Mbit, bottom boot sect)";
			break;
		case FLASH_AM400T:
			type = "AM29LV400T (4 Mbit, top boot sector)";
			break;
		case FLASH_AM800B:
			type = "AM29LV800B (8 Mbit, bottom boot sect)";
			break;
		case FLASH_AM800T:
			type = "AM29LV800T (8 Mbit, top boot sector)";
			break;
		case FLASH_AM320B:
			type = "AM29LV320B (32 Mbit, bottom boot sect)";
			break;
		case FLASH_AM320T:
			type = "AM29LV320T (32 Mbit, top boot sector)";
			break;
		case FLASH_STM800AB:
			type = "M29W800AB (8 Mbit, bottom boot sect)";
			break;
		case FLASH_SST800A:
			type = "SST39LF/VF800 (8 Mbit, uniform sector size)";
			break;
		case FLASH_SST160A:
			type = "SST39LF/VF160 (16 Mbit, uniform sector size)";
			break;
		}
	}

	printf ("\n  Brand: %s Type: %s\n"
			"  Size: %lu KB in %d Sectors\n",
			mfct, type, info->size >> 10, info->sector_count);

	printf ("  Sector Start Addresses:");

	for (i = 0; i < info->sector_count; i++) {
		unsigned long size;
		unsigned int erased;
		unsigned long *flash = (unsigned long *) info->start[i];

		/*
		 * Check if whole sector is erased
		 */
		size = (i != (info->sector_count - 1)) ?
				(info->start[i + 1] - info->start[i]) >> 2 :
				(info->start[0] + info->size - info->start[i]) >> 2;

		for (flash = (unsigned long *) info->start[i], erased = 1;
			 (flash != (unsigned long *) info->start[i] + size) && erased;
			 flash++)
			erased = *flash == ~0x0UL;

		printf ("%s %08lX %s %s",
				(i % 5) ? "" : "\n   ",
				info->start[i],
				erased ? "E" : " ", info->protect[i] ? "RO" : "  ");
	}

	puts ("\n");
	return;
}

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

int flash_erase (flash_info_t * info, int s_first, int s_last)
{
	volatile FLASH_WORD_SIZE *addr = (FLASH_WORD_SIZE *) (info->start[0]);
	int flag, prot, sect, l_sect;
	ulong start, now, last;
	unsigned char sh8b;

	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) ||
		(info->flash_id > (FLASH_MAN_STM | FLASH_AMD_COMP))) {
		printf ("Can't erase unknown flash type - 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");
	}

	l_sect = -1;

	/* Check the ROM CS */
	if ((info->start[0] >= ROM_CS1_START)
		&& (info->start[0] < ROM_CS0_START))
		sh8b = 3;
	else
		sh8b = 0;

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

	addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE) 0x00AA00AA;
	addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE) 0x00550055;
	addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE) 0x00800080;
	addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE) 0x00AA00AA;
	addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE) 0x00550055;

	/* Start erase on unprotected sectors */
	for (sect = s_first; sect <= s_last; sect++) {
		if (info->protect[sect] == 0) {	/* not protected */
			addr = (FLASH_WORD_SIZE *) (info->start[0] + ((info->
														   start[sect] -
														   info->
														   start[0]) <<
														  sh8b));

			if (info->flash_id & FLASH_MAN_SST) {
				addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE) 0x00AA00AA;
				addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE) 0x00550055;
				addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE) 0x00800080;
				addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE) 0x00AA00AA;
				addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE) 0x00550055;
				addr[0] = (FLASH_WORD_SIZE) 0x00500050;	/* block erase */
				udelay (30000);	/* wait 30 ms */
			} else {
				addr[0] = (FLASH_WORD_SIZE) 0x00300030;	/* sector erase */
			}

			l_sect = sect;
		}
	}

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

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

	/*
	 * We wait for the last triggered sector
	 */
	if (l_sect < 0)
		goto DONE;

	start = get_timer (0);
	last = start;
	addr = (FLASH_WORD_SIZE *) (info->start[0] + ((info->start[l_sect] -
												   info->
												   start[0]) << sh8b));
	while ((addr[0] & (FLASH_WORD_SIZE) 0x00800080) !=
		   (FLASH_WORD_SIZE) 0x00800080) {
		if ((now = get_timer (start)) > CFG_FLASH_ERASE_TOUT) {
			printf ("Timeout\n");
			return 1;
		}
		/* show that we're waiting */
		if ((now - last) > 1000) {	/* every second */
			serial_putc ('.');
			last = now;
		}
	}

  DONE:
	/* reset to read mode */
	addr = (FLASH_WORD_SIZE *) info->start[0];
	addr[0] = (FLASH_WORD_SIZE) 0x00F000F0;	/* reset bank */

	printf (" done\n");
	return 0;
}


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


/*-----------------------------------------------------------------------
 * Write a word to Flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
static int write_word (flash_info_t * info, ulong dest, ulong data)
{
	volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *) info->start[0];
	volatile FLASH_WORD_SIZE *dest2;
	volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *) & data;
	ulong start;
	int flag;
	int i;
	unsigned char sh8b;

	/* Check the ROM CS */
	if ((info->start[0] >= ROM_CS1_START)
		&& (info->start[0] < ROM_CS0_START))
		sh8b = 3;
	else
		sh8b = 0;

	dest2 = (FLASH_WORD_SIZE *) (((dest - info->start[0]) << sh8b) +
								 info->start[0]);

	/* Check if Flash is (sufficiently) erased */
	if ((*dest2 & (FLASH_WORD_SIZE) data) != (FLASH_WORD_SIZE) data) {
		return (2);
	}
	/* Disable interrupts which might cause a timeout here */
	flag = disable_interrupts ();

	for (i = 0; i < 4 / sizeof (FLASH_WORD_SIZE); i++) {
		addr2[ADDR0 << sh8b] = (FLASH_WORD_SIZE) 0x00AA00AA;
		addr2[ADDR1 << sh8b] = (FLASH_WORD_SIZE) 0x00550055;
		addr2[ADDR0 << sh8b] = (FLASH_WORD_SIZE) 0x00A000A0;

		dest2[i << sh8b] = data2[i];

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

		/* data polling for D7 */
		start = get_timer (0);
		while ((dest2[i << sh8b] & (FLASH_WORD_SIZE) 0x00800080) !=
			   (data2[i] & (FLASH_WORD_SIZE) 0x00800080)) {
			if (get_timer (start) > CFG_FLASH_WRITE_TOUT) {
				return (1);
			}
		}
	}

	return (0);
}

/*-----------------------------------------------------------------------
 */
#if 0
static void write_via_fpu (vu_long * addr, ulong * data)
{
	__asm__ __volatile__ ("lfd  1, 0(%0)"::"r" (data));
	__asm__ __volatile__ ("stfd 1, 0(%0)"::"r" (addr));
}
#endif

/*-----------------------------------------------------------------------
 */
static __inline__ unsigned long get_msr (void)
{
	unsigned long msr;

	__asm__ __volatile__ ("mfmsr %0":"=r" (msr):);

	return msr;
}

static __inline__ void set_msr (unsigned long msr)
{
	__asm__ __volatile__ ("mtmsr %0"::"r" (msr));
}
