/*
 * (C) Copyright 2000-2003
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
 * TsiChung Liew (Tsi-Chung.Liew@freescale.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/immap.h>

#ifndef CONFIG_SYS_FLASH_CFI
typedef unsigned short FLASH_PORT_WIDTH;
typedef volatile unsigned short FLASH_PORT_WIDTHV;

#define FPW             FLASH_PORT_WIDTH
#define FPWV            FLASH_PORT_WIDTHV

#define FLASH_CYCLE1    0x5555
#define FLASH_CYCLE2    0x2aaa

#define SYNC			__asm__("nop")

/*-----------------------------------------------------------------------
 * Functions
 */

ulong flash_get_size(FPWV * addr, flash_info_t * info);
int flash_get_offsets(ulong base, flash_info_t * info);
int write_word(flash_info_t * info, FPWV * dest, u16 data);
void inline spin_wheel(void);

flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];

ulong flash_init(void)
{
	ulong size = 0;
	ulong fbase = 0;

	fbase = (ulong) CONFIG_SYS_FLASH_BASE;
	flash_get_size((FPWV *) fbase, &flash_info[0]);
	flash_get_offsets((ulong) fbase, &flash_info[0]);
	fbase += flash_info[0].size;
	size += flash_info[0].size;

	/* Protect monitor and environment sectors */
	flash_protect(FLAG_PROTECT_SET,
		      CONFIG_SYS_MONITOR_BASE,
		      CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1, &flash_info[0]);

	return size;
}

int flash_get_offsets(ulong base, flash_info_t * info)
{
	int j, k;

	if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_SST) {

		info->start[0] = base;
		for (k = 0, j = 0; j < CONFIG_SYS_SST_SECT; j++, k++) {
			info->start[k + 1] = info->start[k] + CONFIG_SYS_SST_SECTSZ;
			info->protect[k] = 0;
		}
	}

	return ERR_OK;
}

void flash_print_info(flash_info_t * info)
{
	int i;

	switch (info->flash_id & FLASH_VENDMASK) {
	case FLASH_MAN_SST:
		printf("SST ");
		break;
	default:
		printf("Unknown Vendor ");
		break;
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
	case FLASH_SST6401B:
		printf("SST39VF6401B\n");
		break;
	default:
		printf("Unknown Chip Type\n");
		return;
	}

	if (info->size > 0x100000) {
		int remainder;

		printf("  Size: %ld", info->size >> 20);

		remainder = (info->size % 0x100000);
		if (remainder) {
			remainder >>= 10;
			remainder = (int)((float)
					  (((float)remainder / (float)1024) *
					   10000));
			printf(".%d ", remainder);
		}

		printf("MB in %d Sectors\n", info->sector_count);
	} else
		printf("  Size: %ld KB in %d Sectors\n",
		       info->size >> 10, 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");
}

/*
 * The following code cannot be run from FLASH!
 */
ulong flash_get_size(FPWV * addr, flash_info_t * info)
{
	u16 value;

	addr[FLASH_CYCLE1] = (FPWV) 0x00AA00AA;	/* for Atmel, Intel ignores this */
	addr[FLASH_CYCLE2] = (FPWV) 0x00550055;	/* for Atmel, Intel ignores this */
	addr[FLASH_CYCLE1] = (FPWV) 0x00900090;	/* selects Intel or Atmel */

	switch (addr[0] & 0xffff) {
	case (u8) SST_MANUFACT:
		info->flash_id = FLASH_MAN_SST;
		value = addr[1];
		break;
	default:
		printf("Unknown Flash\n");
		info->flash_id = FLASH_UNKNOWN;
		info->sector_count = 0;
		info->size = 0;

		*addr = (FPW) 0x00F000F0;
		return (0);	/* no or unknown flash  */
	}

	switch (value) {
	case (u16) SST_ID_xF6401B:
		info->flash_id += FLASH_SST6401B;
		break;
	default:
		info->flash_id = FLASH_UNKNOWN;
		break;
	}

	info->sector_count = 0;
	info->size = 0;
	info->sector_count = CONFIG_SYS_SST_SECT;
	info->size = CONFIG_SYS_SST_SECT * CONFIG_SYS_SST_SECTSZ;

	/* reset ID mode */
	*addr = (FPWV) 0x00F000F0;

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

	return (info->size);
}

int flash_erase(flash_info_t * info, int s_first, int s_last)
{
	FPWV *addr;
	int flag, prot, sect, count;
	ulong type, start, last;
	int rcode = 0, flashtype = 0;

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

	switch (type) {
	case FLASH_MAN_SST:
		flashtype = 1;
		break;
	default:
		type = (info->flash_id & FLASH_VENDMASK);
		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");

	flag = disable_interrupts();

	start = get_timer(0);
	last = start;

	if ((s_last - s_first) == (CONFIG_SYS_SST_SECT - 1)) {
		if (prot == 0) {
			addr = (FPWV *) info->start[0];

			addr[FLASH_CYCLE1] = 0x00AA;	/* unlock */
			addr[FLASH_CYCLE2] = 0x0055;	/* unlock */
			addr[FLASH_CYCLE1] = 0x0080;	/* erase mode */
			addr[FLASH_CYCLE1] = 0x00AA;	/* unlock */
			addr[FLASH_CYCLE2] = 0x0055;	/* unlock */
			*addr = 0x0030;	/* erase chip */

			count = 0;
			start = get_timer(0);

			while ((*addr & 0x0080) != 0x0080) {
				if (count++ > 0x10000) {
					spin_wheel();
					count = 0;
				}

				if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
					printf("Timeout\n");
					*addr = 0x00F0;	/* reset to read mode */

					return 1;
				}
			}

			*addr = 0x00F0;	/* reset to read mode */

			printf("\b. done\n");

			if (flag)
				enable_interrupts();

			return 0;
		} else if (prot == CONFIG_SYS_SST_SECT) {
			return 1;
		}
	}

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

			addr = (FPWV *) (info->start[sect]);

			printf(".");

			/* arm simple, non interrupt dependent timer */
			start = get_timer(0);

			switch (flashtype) {
			case 1:
				{
					FPWV *base;	/* first address in bank */

					flag = disable_interrupts();

					base = (FPWV *) (CONFIG_SYS_FLASH_BASE);	/* First sector */

					base[FLASH_CYCLE1] = 0x00AA;	/* unlock */
					base[FLASH_CYCLE2] = 0x0055;	/* unlock */
					base[FLASH_CYCLE1] = 0x0080;	/* erase mode */
					base[FLASH_CYCLE1] = 0x00AA;	/* unlock */
					base[FLASH_CYCLE2] = 0x0055;	/* unlock */
					*addr = 0x0050;	/* erase sector */

					if (flag)
						enable_interrupts();

					while ((*addr & 0x0080) != 0x0080) {
						if (get_timer(start) >
						    CONFIG_SYS_FLASH_ERASE_TOUT) {
							printf("Timeout\n");
							*addr = 0x00F0;	/* reset to read mode */

							rcode = 1;
							break;
						}
					}

					*addr = 0x00F0;	/* reset to read mode */
					break;
				}
			}	/* switch (flashtype) */
		}
	}
	printf(" done\n");

	if (flag)
		enable_interrupts();

	return rcode;
}

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

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

	/* get lower word aligned address */
	wp = addr;
	port_width = sizeof(FPW);

	/* handle unaligned start bytes */
	if (wp & 1) {
		data = *((FPWV *) wp);
		data = (data << 8) | *src;

		if ((rc = write_word(info, (FPWV *) wp, data)) != 0)
			return (rc);

		wp++;
		cnt -= 1;
		src++;
	}

	while (cnt >= 2) {
		/*
		 * handle word aligned part
		 */
		count = 0;
		data = *((FPWV *) src);

		if ((rc = write_word(info, (FPWV *) wp, data)) != 0)
			return (rc);

		wp += 2;
		src += 2;
		cnt -= 2;

		if (count++ > 0x800) {
			spin_wheel();
			count = 0;
		}
	}
	/* handle word aligned part */
	if (cnt) {
		/* handle word aligned part */
		count = 0;
		data = *((FPWV *) wp);

		data = (data & 0x00FF) | (*src << 8);

		if ((rc = write_word(info, (FPWV *) wp, data)) != 0)
			return (rc);

		wp++;
		src++;
		cnt -= 1;
		if (count++ > 0x800) {
			spin_wheel();
			count = 0;
		}
	}

	if (cnt == 0)
		return ERR_OK;

	return ERR_OK;
}

/*-----------------------------------------------------------------------
 * Write a word to Flash
 * A word is 16 bits, whichever the bus width of the flash bank
 * (not an individual chip) is.
 *
 * returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
int write_word(flash_info_t * info, FPWV * dest, u16 data)
{
	ulong start;
	int flag;
	int res = 0;		/* result, assume success */
	FPWV *base;		/* first address in flash bank */

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

	base = (FPWV *) (CONFIG_SYS_FLASH_BASE);

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

	base[FLASH_CYCLE1] = (u8) 0x00AA00AA;	/* unlock */
	base[FLASH_CYCLE2] = (u8) 0x00550055;	/* unlock */
	base[FLASH_CYCLE1] = (u8) 0x00A000A0;	/* selects program mode */

	*dest = data;		/* start programming the data */

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

	start = get_timer(0);

	/* data polling for D7 */
	while (res == 0
	       && (*dest & (u8) 0x00800080) != (data & (u8) 0x00800080)) {
		if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
			*dest = (u8) 0x00F000F0;	/* reset bank */
			res = 1;
		}
	}

	*dest++ = (u8) 0x00F000F0;	/* reset bank */

	return (res);
}

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

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

#endif
