/*
 * (C) Copyright 2002
 * Robert Schwebel, Pengutronix, <r.schwebel@pengutronix.de>
 *
 * (C) Copyright 2000-2004
 * 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 <linux/byteorder/swab.h>

#if defined CFG_JFFS_CUSTOM_PART
#include <jffs2/jffs2.h>
#endif

#define SWAP(x)               __swab32(x)

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

/* Functions */
static ulong flash_get_size (vu_long *addr, flash_info_t *info);
static int write_word (flash_info_t *info, ulong dest, ulong data);
static void flash_get_offsets (ulong base, flash_info_t *info);

#if defined CFG_JFFS_CUSTOM_PART

/*
 * jffs2_part_info - get information about a JFFS2 partition
 *
 * @part_num: number of the partition you want to get info about
 * @return:   struct part_info* in case of success, 0 if failure
 */

static struct part_info part;
static int current_part = -1;

struct part_info* jffs2_part_info(int part_num) {
	void *jffs2_priv_saved = part.jffs2_priv;

	printf("jffs2_part_info: part_num=%i\n",part_num);

	if (current_part == part_num)
		return &part;

	/* u-boot partition                                                 */
	if(part_num==0){
		memset(&part, 0, sizeof(part));

		part.offset=(char*)0x00000000;
		part.size=256*1024;

		/* Mark the struct as ready */
		current_part = part_num;

		printf("part.offset = 0x%08x\n",(unsigned int)part.offset);
		printf("part.size   = 0x%08x\n",(unsigned int)part.size);
	}

	/* primary OS+firmware partition                                    */
	if(part_num==1){
		memset(&part, 0, sizeof(part));

		part.offset=(char*)0x00040000;
		part.size=1024*1024;

		/* Mark the struct as ready */
		current_part = part_num;

		printf("part.offset = 0x%08x\n",(unsigned int)part.offset);
		printf("part.size   = 0x%08x\n",(unsigned int)part.size);
	}

	/* secondary OS+firmware partition                                  */
	if(part_num==2){
		memset(&part, 0, sizeof(part));

		part.offset=(char*)0x00140000;
		part.size=8*1024*1024;

		/* Mark the struct as ready */
		current_part = part_num;

		printf("part.offset = 0x%08x\n",(unsigned int)part.offset);
		printf("part.size   = 0x%08x\n",(unsigned int)part.size);
	}

	if (current_part == part_num) {
		part.usr_priv = &current_part;
		part.jffs2_priv = jffs2_priv_saved;
		return &part;
	}

	printf("jffs2_part_info: end of partition table\n");
	return 0;
}
#endif


/*-----------------------------------------------------------------------
 */
unsigned long flash_init (void)
{
	int i;
	ulong size = 0;

	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
		switch (i) {
		case 0:
			flash_get_size ((long *) PHYS_FLASH_1, &flash_info[i]);
			flash_get_offsets (PHYS_FLASH_1, &flash_info[i]);
			break;
		case 1:
			flash_get_size ((long *) PHYS_FLASH_2, &flash_info[i]);
			flash_get_offsets (PHYS_FLASH_2, &flash_info[i]);
			break;
		default:
			panic ("configured too many flash banks!\n");
			break;
		}
		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] );

	return size;
}

/*-----------------------------------------------------------------------
 */
static void flash_get_offsets (ulong base, flash_info_t *info)
{
	int i;

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

	if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD) {
		for (i = 0; i < info->sector_count; i++) {
			info->start[i] = base + (i * PHYS_FLASH_SECT_SIZE);
			info->protect[i] = 0;
		}
	}
}

/*-----------------------------------------------------------------------
 */
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_AMD:	printf ("AMD ");		break;
	case FLASH_MAN_FUJ:	printf ("FUJITSU ");		break;
	default:		printf ("Unknown Vendor ");	break;
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
	case FLASH_AMLV128U:	printf ("AM29LV128ML (128Mbit, uniform sector size)\n");
				break;
	case FLASH_AMLV320U:	printf ("AM29LV320ML (32Mbit, uniform sector size)\n");
				break;
	case FLASH_AMLV640U:	printf ("AM29LV640ML (64Mbit, uniform sector size)\n");
				break;
	case FLASH_AMLV320B:	printf ("AM29LV320MB (32Mbit, bottom boot sect)\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!
 */
static ulong flash_get_size (vu_long *addr, flash_info_t *info)
{
	short i;
	ulong value;
	ulong base = (ulong)addr;

	/* Write auto select command: read Manufacturer ID */
	addr[0x0555] = 0x00AA00AA;
	addr[0x02AA] = 0x00550055;
	addr[0x0555] = 0x00900090;

	value = addr[0];

	debug ("Manuf. ID @ 0x%08lx: 0x%08lx\n", (ulong)addr, value);

	switch (value) {
	case AMD_MANUFACT:
		debug ("Manufacturer: AMD\n");
		info->flash_id = FLASH_MAN_AMD;
		break;
	case FUJ_MANUFACT:
		debug ("Manufacturer: FUJITSU\n");
		info->flash_id = FLASH_MAN_FUJ;
		break;
	default:
		debug ("Manufacturer: *** unknown ***\n");
		info->flash_id = FLASH_UNKNOWN;
		info->sector_count = 0;
		info->size = 0;
		return (0);			/* no or unknown flash	*/
	}

	value = addr[1];			/* device ID		*/

	debug ("Device ID @ 0x%08lx: 0x%08lx\n", (ulong)(&addr[1]), value);

	switch (value) {

	case AMD_ID_MIRROR:
		debug ("Mirror Bit flash: addr[14] = %08lX  addr[15] = %08lX\n",
			addr[14], addr[15]);
		switch(addr[14]) {
		case AMD_ID_LV128U_2:
			if (addr[15] != AMD_ID_LV128U_3) {
				debug ("Chip: AMLV128U -> unknown\n");
				info->flash_id = FLASH_UNKNOWN;
			} else {
				debug ("Chip: AMLV128U\n");
				info->flash_id += FLASH_AMLV128U;
				info->sector_count = 256;
				info->size = 0x02000000;
			}
			break;				/* => 32 MB	*/
		case AMD_ID_LV640U_2:
			if (addr[15] != AMD_ID_LV640U_3) {
				debug ("Chip: AMLV640U -> unknown\n");
				info->flash_id = FLASH_UNKNOWN;
			} else {
				debug ("Chip: AMLV640U\n");
				info->flash_id += FLASH_AMLV640U;
				info->sector_count = 128;
				info->size = 0x01000000;
			}
			break;				/* => 16 MB	*/
		case AMD_ID_LV320B_2:
			if (addr[15] != AMD_ID_LV320B_3) {
				debug ("Chip: AMLV320B -> unknown\n");
				info->flash_id = FLASH_UNKNOWN;
			} else {
				debug ("Chip: AMLV320B\n");
				info->flash_id += FLASH_AMLV320B;
				info->sector_count = 71;
				info->size = 0x00800000;
			}
			break;				/* =>  8 MB	*/
		default:
			debug ("Chip: *** unknown ***\n");
			info->flash_id = FLASH_UNKNOWN;
			break;
		}
		break;

	default:
		info->flash_id = FLASH_UNKNOWN;
		return (0);			/* => no or unknown flash */
	}

	/* set up sector start address table */
	switch (value) {
	case AMD_ID_MIRROR:
		switch (info->flash_id & FLASH_TYPEMASK) {
		/* only known types here - no default */
		case FLASH_AMLV128U:
		case FLASH_AMLV640U:
		case FLASH_AMLV320U:
			for (i = 0; i < info->sector_count; i++) {
				info->start[i] = base;
				base += 0x20000;
			}
			break;
		case FLASH_AMLV320B:
			for (i = 0; i < info->sector_count; i++) {
				info->start[i] = base;
				/*
				 * The first 8 sectors are 8 kB,
				 * all the other ones  are 64 kB
				 */
				base += (i < 8)
					?  2 * ( 8 << 10)
					:  2 * (64 << 10);
			}
			break;
		}
		break;

	default:
		return (0);
		break;
	}

#if 0
	/* check for protected sectors */
	for (i = 0; i < info->sector_count; i++) {
		/* read sector protection at sector address, (A7 .. A0) = 0x02 */
		/* D0 = 1 if protected */
		addr = (volatile unsigned long *)(info->start[i]);
		info->protect[i] = addr[2] & 1;
	}
#endif

	/*
	 * Prevent writes to uninitialized FLASH.
	 */
	if (info->flash_id != FLASH_UNKNOWN) {
		addr = (volatile unsigned long *)info->start[0];

		*addr = 0x00F000F0;	/* reset bank */
	}

	return (info->size);
}


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

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

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

	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_AMD_COMP)) {
		printf ("Can't erase unknown flash type %08lx - 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 sectors will not be erased!\n",
			prot);
	} else {
		printf ("\n");
	}

	l_sect = -1;

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

	addr[0x0555] = 0x00AA00AA;
	addr[0x02AA] = 0x00550055;
	addr[0x0555] = 0x00800080;
	addr[0x0555] = 0x00AA00AA;
	addr[0x02AA] = 0x00550055;

	/* Start erase on unprotected sectors */
	for (sect = s_first; sect<=s_last; sect++) {
		if (info->protect[sect] == 0) {	/* not protected */
			addr = (vu_long*)(info->start[sect]);
			addr[0] = 0x00300030;
			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 = (vu_long*)(info->start[l_sect]);
	while ((addr[0] & 0x00800080) != 0x00800080) {
		if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
			printf ("Timeout\n");
			return 1;
		}
		/* show that we're waiting */
		if ((now - last) > 100000) {	/* every second */
			putc ('.');
			last = now;
		}
	}

DONE:
	/* reset to read mode */
	addr = (volatile unsigned long *)info->start[0];
	addr[0] = 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, SWAP(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, SWAP(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, SWAP(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)
{
	vu_long *addr = (vu_long*)(info->start[0]);
	ulong start;
	int flag;

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

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

	addr[0x0555] = 0x00AA00AA;
	addr[0x02AA] = 0x00550055;
	addr[0x0555] = 0x00A000A0;

	*((vu_long *)dest) = data;

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

	/* data polling for D7 */
	start = get_timer (0);
	while ((*((vu_long *)dest) & 0x00800080) != (data & 0x00800080)) {
		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
			return (1);
		}
	}
	return (0);
}
