/*
 * (C) Copyright 2001
 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
 *
 * (C) Copyright 2001-2004
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * (C) Copyright 2003
 * Texas Instruments, <www.ti.com>
 * Kshitij Gupta <Kshitij@ti.com>
 *
 * 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 <asm/arch/sizes.h>
#include <linux/byteorder/swab.h>

#define PHYS_FLASH_SECT_SIZE	SZ_128K
flash_info_t flash_info[CFG_MAX_FLASH_BANKS];	/* info for FLASH chips    */

/* Board support for 1 or 2 flash devices */
#undef FLASH_PORT_WIDTH32
#define FLASH_PORT_WIDTH16

#ifdef FLASH_PORT_WIDTH16
# define FLASH_PORT_WIDTH		ushort
# define FLASH_PORT_WIDTHV		vu_short
# define SWAP(x)			__swab16(x)
#else
# define FLASH_PORT_WIDTH		ulong
# define FLASH_PORT_WIDTHV		vu_long
# define SWAP(x)			__swab32(x)
#endif

#define FPW	FLASH_PORT_WIDTH
#define FPWV	FLASH_PORT_WIDTHV

#define mb() __asm__ __volatile__ ("" : : : "memory")


/* Flash Organization Structure */
typedef struct OrgDef {
	unsigned int sector_number;
	unsigned int sector_size;
} OrgDef;


/* Flash Organizations */
OrgDef OrgIntel_28F256L18T[] = {
	{4, SZ_32K},		/* 4 * 32kBytes sectors */
	{255, SZ_128K},		/* 255 * 128kBytes sectors */
};


/*-----------------------------------------------------------------------
 * Functions
 */
unsigned long flash_init (void);
static ulong flash_get_size (FPW * addr, flash_info_t * info);
static int write_data (flash_info_t * info, ulong dest, FPW data);
static void flash_get_offsets (ulong base, flash_info_t * info);
void inline spin_wheel (void);
void flash_print_info (flash_info_t * info);
void flash_unprotect_sectors (FPWV * addr);
int flash_erase (flash_info_t * info, int s_first, int s_last);
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt);
void flash_unlock(flash_info_t * info, int bank);
int flash_probe(void);

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

/* see if flash is ok */
int flash_probe(void)
{
	return(flash_get_size ((FPW *) PHYS_FLASH_1, &flash_info[0]));
}

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 ((FPW *) PHYS_FLASH_1, &flash_info[i]);
			flash_get_offsets (PHYS_FLASH_1, &flash_info[i]);
			/* to reset the lock bit */
			flash_unlock(&flash_info[i],i);
			break;
		case 1:
			flash_get_size ((FPW *) PHYS_FLASH_2, &flash_info[i]);
			flash_get_offsets (PHYS_FLASH_2, &flash_info[i]);
			/* to reset the lock bit */
			flash_unlock(&flash_info[i],i);
			break;

		default:
			panic ("configured too many flash banks!\n");
			break;
		}
		size += flash_info[i].size;
	}

#ifdef CFG_ENV_IS_IN_FLASH
	/* 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]);
#endif
	return size;
}

/*-----------------------------------------------------------------------
 */
void flash_unlock(flash_info_t * info, int bank)
{
	int j;
	if (!bank)
		j=2;	/* leave 0,1 locked for boot bank */
	else
		j=0;	/* get the whole bank for #2 */

	for (;j<CFG_MAX_FLASH_SECT;j++) {
		FPWV *addr = (FPWV *) (info->start[j]);
		if (addr == NULL) {
			printf("Warning Flash probe failed\n");
			break;
		}
		flash_unprotect_sectors (addr);
		*addr = (FPW) 0x00500050;/* clear status register */
		*addr = (FPW) 0x00FF00FF;/* resest to read mode */
	}
}

/*-----------------------------------------------------------------------
 */
static void flash_get_offsets (ulong base, flash_info_t * info)
{
	int i;
	volatile int r;	 /* gcc 3.4.0-1 strangeness, need to follow up.*/

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

	if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_INTEL) {
		for (i = 0; i < info->sector_count; i++) {
			if (i > 254) { /* 255,256,257,258 */
				r=i;
				info->start[i] = base + (((r-(int)255) * SZ_32K) + (255*PHYS_FLASH_SECT_SIZE));
				info->protect[i] = 0;
			} else {
				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_INTEL:
		printf ("INTEL ");
		break;
	default:
		printf ("Unknown Vendor ");
		break;
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
	case FLASH_28F256L18T:
		printf ("FLASH 28F256L18T\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 (FPW * addr, flash_info_t * info)
{
	volatile FPW value;
	/* mb();  this one makes ARM11 err go away, but I want it :) as a guide to problems */

	/* Write auto select command: read Manufacturer ID */
	addr[0x5555] = (FPW) 0x00AA00AA;
	addr[0x2AAA] = (FPW) 0x00550055;
	addr[0x5555] = (FPW) 0x00900090;

	mb ();
	value = addr[0] & 0xFF;	/* just looking for 89 (8989 is hw pat)*/

	switch (value) {

	case (FPW) INTEL_MANUFACT:
		info->flash_id = FLASH_MAN_INTEL;
		break;

	default:
		info->flash_id = FLASH_UNKNOWN;
		info->sector_count = 0;
		info->size = 0;
		addr[0] = (FPW) 0x00FF00FF;	/* restore read mode */
		return(0);		   /* no or unknown flash	*/
	}

	mb ();
	value = addr[1];	/* device ID */
	switch (value) {

	case (FPW) (INTEL_ID_28F256L18T):	 /* 880D */
		info->flash_id += FLASH_28F256L18T;
		info->sector_count = 259;	/*0-258*/
		info->size = SZ_32M;
		break;			/* => 32 MB	*/

	default:
		info->flash_id = FLASH_UNKNOWN;
		break;
	}

	if (info->sector_count > CFG_MAX_FLASH_SECT) {
		printf ("** ERROR: sector count %d > max (%d) **\n",
				info->sector_count, CFG_MAX_FLASH_SECT);
		info->sector_count = CFG_MAX_FLASH_SECT;
	}

	addr[0] = (FPW) 0x00FF00FF;	/* restore read mode */

	return(info->size);
}


/* unprotects a sector for write and erase
 * on some intel parts, this unprotects the entire chip, but it
 * wont hurt to call this additional times per sector...
 */
void flash_unprotect_sectors (FPWV * addr)
{
#define PD_FINTEL_WSMS_READY_MASK    0x0080

	*addr = (FPW) 0x00500050;	/* clear status register */

	/* this sends the clear lock bit command */
	*addr = (FPW) 0x00600060;
	*addr = (FPW) 0x00D000D0;
}


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

int flash_erase (flash_info_t * info, int s_first, int s_last)
{
	int prot, sect;
	ulong type, start, last;
	int rcode = 0;
#ifdef CONFIG_USE_IRQ
	int iflag;
#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;
	}

	type = (info->flash_id & FLASH_VENDMASK);
	if ((type != FLASH_MAN_INTEL)) {
		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");
	}


	start = get_timer (0);
	last = start;

#ifdef CONFIG_USE_IRQ
	/* Disable interrupts which might cause a timeout here */
	iflag = disable_interrupts ();
#endif

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

			printf ("Erasing sector %2d ... ", sect);

			flash_unprotect_sectors (addr);

			/* arm simple, non interrupt dependent timer */
			reset_timer_masked ();

			*addr = (FPW) 0x00500050;/* clear status register */
			*addr = (FPW) 0x00200020;/* erase setup */
			*addr = (FPW) 0x00D000D0;/* erase confirm */

			while (((status =
					 *addr) & (FPW) 0x00800080) !=
				   (FPW) 0x00800080) {
				if (get_timer_masked () >
					CFG_FLASH_ERASE_TOUT) {
					printf ("Timeout\n");
					/* suspend erase     */
					*addr = (FPW) 0x00B000B0;
					/* reset to read mode */
					*addr = (FPW) 0x00FF00FF;
					rcode = 1;
					break;
				}
			}

			/* clear status register cmd.	*/
			*addr = (FPW) 0x00500050;
			*addr = (FPW) 0x00FF00FF;/* resest to read mode */
			printf (" done\n");
		}
	}
#ifdef CONFIG_USE_IRQ
	if (iflag)
		enable_interrupts();
#endif

	return rcode;
}

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

int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
	ulong cp, wp;
	FPW data;
	int count, i, l, rc, port_width;

	if (info->flash_id == FLASH_UNKNOWN) {
		return 4;
	}
/* get lower word aligned address */
#ifdef FLASH_PORT_WIDTH16
	wp = (addr & ~1);
	port_width = 2;
#else
	wp = (addr & ~3);
	port_width = 4;
#endif

	/*
	 * 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 < port_width && cnt > 0; ++i) {
			data = (data << 8) | *src++;
			--cnt;
			++cp;
		}
		for (; cnt == 0 && i < port_width; ++i, ++cp) {
			data = (data << 8) | (*(uchar *) cp);
		}

		if ((rc = write_data (info, wp, SWAP (data))) != 0) {
			return(rc);
		}
		wp += port_width;
	}

	/*
	 * handle word aligned part
	 */
	count = 0;
	while (cnt >= port_width) {
		data = 0;
		for (i = 0; i < port_width; ++i) {
			data = (data << 8) | *src++;
		}
		if ((rc = write_data (info, wp, SWAP (data))) != 0) {
			return(rc);
		}
		wp += port_width;
		cnt -= port_width;
		if (count++ > 0x800) {
			spin_wheel ();
			count = 0;
		}
	}

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

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

	return(write_data (info, wp, SWAP (data)));
}

/*-----------------------------------------------------------------------
 * Write a word or halfword to Flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
static int write_data (flash_info_t * info, ulong dest, FPW data)
{
	FPWV *addr = (FPWV *) dest;
	ulong status;
#ifdef CONFIG_USE_IRQ
	int iflag;
#endif

	/* Check if Flash is (sufficiently) erased */
	if ((*addr & data) != data) {
		printf ("not erased at %08lx (%x)\n", (ulong) addr, *addr);
		return(2);
	}
	/* Disable interrupts which might cause a timeout here */
#ifdef CONFIG_USE_IRQ
	iflag = disable_interrupts ();
#endif
	*addr = (FPW) 0x00400040;	/* write setup */
	*addr = data;

	/* arm simple, non interrupt dependent timer */
	reset_timer_masked ();

	/* wait while polling the status register */
	while (((status = *addr) & (FPW) 0x00800080) != (FPW) 0x00800080) {
		if (get_timer_masked () > CFG_FLASH_WRITE_TOUT) {
			*addr = (FPW) 0x00FF00FF;	/* restore read mode */
			return(1);
		}
	}
	*addr = (FPW) 0x00FF00FF;	/* restore read mode */

#ifdef CONFIG_USE_IRQ
	if (iflag)
		enable_interrupts();
#endif

	return(0);
}

void inline spin_wheel (void)
{
	static int p = 0;
	static char w[] = "\\/-";

	printf ("\010%c", w[p]);
	(++p == 3) ? (p = 0) : 0;
}
