/*
 * (C) Copyright 2003
 * MuLogic B.V.
 *
 * (C) Copyright 2001
 * 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 <ppc4xx.h>
#include <asm/u-boot.h>
#include <asm/processor.h>

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


#define FLASH_WORD_SIZE unsigned long
#define FLASH_ID_MASK 0xFFFFFFFF

/*-----------------------------------------------------------------------
 * Functions
 */
/* stolen from esteem192e/flash.c */
ulong flash_get_size (volatile FLASH_WORD_SIZE *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);


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

unsigned long flash_init (void)
{
	unsigned long size_b0, size_b1;
	int i;
	uint pbcr;
	unsigned long base_b0, base_b1;
	volatile FLASH_WORD_SIZE* flash_base;

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

	/* Static FLASH Bank configuration here */
	/* Test for 8M Flash first */
	debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_8M_PRELIM);
	flash_base = (volatile FLASH_WORD_SIZE*)(FLASH_BASE0_8M_PRELIM);
	size_b0 = flash_get_size(flash_base, &flash_info[0]);

	if (flash_info[0].flash_id == FLASH_UNKNOWN) {
		printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
		size_b0, size_b0<<20);
		return 0;
	}

	if (size_b0 < 8*1024*1024) {
		/* Not quite 8M, try 4M Flash base address */
		debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_4M_PRELIM);
		flash_base = (volatile FLASH_WORD_SIZE*)(FLASH_BASE0_4M_PRELIM);
		size_b0 = flash_get_size(flash_base, &flash_info[0]);
	}

	if (flash_info[0].flash_id == FLASH_UNKNOWN) {
		printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
		size_b0, size_b0<<20);
		return 0;
	}

	/* Only one bank */
	if (CFG_MAX_FLASH_BANKS == 1) {
		/* Setup offsets */
		flash_get_offsets ((ulong)flash_base, &flash_info[0]);

		/* Monitor protection ON by default */
		(void)flash_protect(FLAG_PROTECT_SET, CFG_MONITOR_BASE,
			CFG_MONITOR_BASE+CFG_MONITOR_LEN-1, &flash_info[0]);
		size_b1 = 0 ;
		flash_info[0].size = size_b0;
		return(size_b0);
	}

	/* We have 2 banks */
	size_b1 = flash_get_size(flash_base, &flash_info[1]);

	/* Re-do sizing to get full correct info */
	if (size_b1) {
		mtdcr(ebccfga, pb0cr);
		pbcr = mfdcr(ebccfgd);
		mtdcr(ebccfga, pb0cr);
		base_b1 = -size_b1;
		pbcr = (pbcr & 0x0001ffff) | base_b1 | (((size_b1/1024/1024)-1)<<17);
		mtdcr(ebccfgd, pbcr);
	}

	if (size_b0) {
		mtdcr(ebccfga, pb1cr);
		pbcr = mfdcr(ebccfgd);
		mtdcr(ebccfga, pb1cr);
		base_b0 = base_b1 - size_b0;
		pbcr = (pbcr & 0x0001ffff) | base_b0 | (((size_b0/1024/1024)-1)<<17);
		mtdcr(ebccfgd, pbcr);
	}

	size_b0 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b0, &flash_info[0]);
	flash_get_offsets (base_b0, &flash_info[0]);

	/* monitor protection ON by default */
	(void)flash_protect(FLAG_PROTECT_SET, CFG_MONITOR_BASE,
		CFG_MONITOR_BASE+CFG_MONITOR_LEN-1, &flash_info[0]);

	if (size_b1) {
		/* Re-do sizing to get full correct info */
		size_b1 = flash_get_size((volatile FLASH_WORD_SIZE *)base_b1, &flash_info[1]);
		flash_get_offsets (base_b1, &flash_info[1]);

		/* monitor protection ON by default */
		(void)flash_protect(FLAG_PROTECT_SET, base_b1+size_b1-CFG_MONITOR_LEN,
			base_b1+size_b1-1, &flash_info[1]);

		/* monitor protection OFF by default (one is enough) */
		(void)flash_protect(FLAG_PROTECT_CLEAR, base_b0+size_b0-CFG_MONITOR_LEN,
			base_b0+size_b0-1, &flash_info[0]);
	} else {
		flash_info[1].flash_id = FLASH_UNKNOWN;
		flash_info[1].sector_count = -1;
	}

	flash_info[0].size = size_b0;
	flash_info[1].size = size_b1;
	return (size_b0 + size_b1);
}



/*-----------------------------------------------------------------------
 This code is specific to the AM29DL163/AM29DL232 for the QS850/QS823.
 */

static void flash_get_offsets (ulong base, flash_info_t *info)
{
	int i;
	long large_sect_size;
	long small_sect_size;

	/* set up sector start adress table */
	large_sect_size = info->size / (info->sector_count - 8 + 1);
	small_sect_size = large_sect_size / 8;

	if (info->flash_id & FLASH_BTYPE) {

		/* set sector offsets for bottom boot block type */
		for (i = 0; i < 7; i++) {
			info->start[i] = base;
			base += small_sect_size;
		}

		for (; i < info->sector_count; i++) {
			info->start[i] = base;
			base += large_sect_size;
		}
	}
	else
	{
		/* set sector offsets for top boot block type */
		for (i = 0; i < (info->sector_count - 8); i++) {
			info->start[i] = base;
			base += large_sect_size;
		}

		for (; i < info->sector_count; i++) {
			info->start[i] = base;
			base += small_sect_size;
		}
	}
}

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

void flash_print_info  (flash_info_t *info)
{
	int i;
	uchar *boottype;
	uchar botboot[]=", bottom boot sect)\n";
	uchar topboot[]=", top boot sector)\n";

	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;
		case FLASH_MAN_SST:
			printf ("SST ");
			break;
		case FLASH_MAN_STM:
			printf ("STM ");
			break;
		case FLASH_MAN_INTEL:
			printf ("INTEL ");
			break;
		default:
			printf ("Unknown Vendor ");
			break;
	}

	if (info->flash_id & 0x0001 ) {
		boottype = botboot;
	} else {
		boottype = topboot;
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
		case FLASH_AM160B:
			printf ("AM29LV160B (16 Mbit%s",boottype);
			break;
		case FLASH_AM160T:
			printf ("AM29LV160T (16 Mbit%s",boottype);
			break;
		case FLASH_AMDL163T:
			printf ("AM29DL163T (16 Mbit%s",boottype);
			break;
		case FLASH_AMDL163B:
			printf ("AM29DL163B (16 Mbit%s",boottype);
			break;
		case FLASH_AM320B:
			printf ("AM29LV320B (32 Mbit%s",boottype);
			break;
		case FLASH_AM320T:
			printf ("AM29LV320T (32 Mbit%s",boottype);
			break;
		case FLASH_AMDL323T:
			printf ("AM29DL323T (32 Mbit%s",boottype);
			break;
		case FLASH_AMDL323B:
			printf ("AM29DL323B (32 Mbit%s",boottype);
			break;
		case FLASH_AMDL322T:
			printf ("AM29DL322T (32 Mbit%s",boottype);
			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!
 */
ulong flash_get_size (volatile FLASH_WORD_SIZE *addr, flash_info_t *info)
{
	short i;
	ulong base = (ulong)addr;
	FLASH_WORD_SIZE value;

	/* Write auto select command: read Manufacturer ID */

	/*
	 * Note: if it is an AMD flash and the word at addr[0000]
	 * is 0x00890089 this routine will think it is an Intel
	 * flash device and may(most likely) cause trouble.
	 */

	addr[0x0000] = 0x00900090;
	if(addr[0x0000] != 0x00890089){
		addr[0x0555] = 0x00AA00AA;
		addr[0x02AA] = 0x00550055;
		addr[0x0555] = 0x00900090;
	}
	value = addr[0];

	switch (value) {
		case (AMD_MANUFACT & FLASH_ID_MASK):
			info->flash_id = FLASH_MAN_AMD;
			break;
		case (FUJ_MANUFACT & FLASH_ID_MASK):
			info->flash_id = FLASH_MAN_FUJ;
			break;
		case (STM_MANUFACT & FLASH_ID_MASK):
			info->flash_id = FLASH_MAN_STM;
			break;
		case (SST_MANUFACT & FLASH_ID_MASK):
			info->flash_id = FLASH_MAN_SST;
			break;
		case (INTEL_MANUFACT & FLASH_ID_MASK):
			info->flash_id = FLASH_MAN_INTEL;
			break;
		default:
			info->flash_id = FLASH_UNKNOWN;
			info->sector_count = 0;
			info->size = 0;
			return (0); /* no or unknown flash */
	}

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

	switch (value) {
		case (AMD_ID_LV160T & FLASH_ID_MASK):
			info->flash_id += FLASH_AM160T;
			info->sector_count = 35;
			info->size = 0x00400000;
			break; /* => 4 MB */

		case (AMD_ID_LV160B & FLASH_ID_MASK):
			info->flash_id += FLASH_AM160B;
			info->sector_count = 35;
			info->size = 0x00400000;
			break; /* => 4 MB */

		case (AMD_ID_DL163T & FLASH_ID_MASK):
			info->flash_id += FLASH_AMDL163T;
			info->sector_count = 39;
			info->size = 0x00400000;
			break; /* => 4 MB */

		case (AMD_ID_DL163B & FLASH_ID_MASK):
			info->flash_id += FLASH_AMDL163B;
			info->sector_count = 39;
			info->size = 0x00400000;
			break; /* => 4 MB */

		case (AMD_ID_DL323T & FLASH_ID_MASK):
			info->flash_id += FLASH_AMDL323T;
			info->sector_count = 71;
			info->size = 0x00800000;
			break; /* => 8 MB */

		case (AMD_ID_DL323B & FLASH_ID_MASK):
			info->flash_id += FLASH_AMDL323B;
			info->sector_count = 71;
			info->size = 0x00800000;
			break; /* => 8 MB */

		case (AMD_ID_DL322T & FLASH_ID_MASK):
			info->flash_id += FLASH_AMDL322T;
			info->sector_count = 71;
			info->size = 0x00800000;
			break; /* => 8 MB */

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

	flash_get_offsets(base, info);

	/* 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 FLASH_WORD_SIZE *)(info->start[i]);
		info->protect[i] = addr[2] & 1;
	}

	/*
	 * Prevent writes to uninitialized FLASH.
	 */
	if (info->flash_id != FLASH_UNKNOWN) {
		addr = (volatile FLASH_WORD_SIZE *)info->start[0];
		*addr = (0x00FF00FF & FLASH_ID_MASK);	/* reset bank */
	}

	return (info->size);
}


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

int flash_erase (flash_info_t *info, int s_first, int s_last)
{
	volatile FLASH_WORD_SIZE *addr=(volatile FLASH_WORD_SIZE*)(info->start[0]);
	int flag, prot, sect, l_sect;
	ulong start, now, last;
	int rcode = 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;
	}

	if ((info->flash_id == FLASH_UNKNOWN) ||
		(info->flash_id > 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;

	/* 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 = (volatile FLASH_WORD_SIZE *)(info->start[sect]);
			addr[0] = (0x00300030 & FLASH_ID_MASK);
			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 = (volatile FLASH_WORD_SIZE*)(info->start[l_sect]);
	while ((addr[0] & (0x00800080&FLASH_ID_MASK)) !=
			(0x00800080&FLASH_ID_MASK)  )
	{
		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 = (volatile FLASH_WORD_SIZE *)info->start[0];
	addr[0] = (0x00F000F0 & FLASH_ID_MASK); /* reset bank */

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

/*-----------------------------------------------------------------------
 * 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 l;
	int i, 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)
{
	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();

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