/********************************************************************
 *
 * Unless otherwise specified, Copyright (C) 2004-2005 Barco Control Rooms
 *
 * $Source: /home/services/cvs/firmware/ppc/u-boot-1.1.2/board/barco/flash.c,v $
 * $Revision: 1.3 $
 * $Author: mleeman $
 * $Date: 2005/02/21 12:48:58 $
 *
 * Last ChangeLog Entry
 * $Log: flash.c,v $
 * Revision 1.3  2005/02/21 12:48:58  mleeman
 * update of copyright years (feedback wd)
 *
 * Revision 1.2  2005/02/21 11:04:04  mleeman
 * remove dead code and Coding style (feedback wd)
 *
 * Revision 1.1  2005/02/14 09:23:46  mleeman
 * - moved 'barcohydra' directory to a more generic barco; since we will be
 *   supporting and adding multiple boards
 *
 * Revision 1.2  2005/02/09 12:56:23  mleeman
 * add generic header to track changes in sources
 *
 *
 *******************************************************************/

/*
 * (C) Copyright 2000
 * 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 <mpc824x.h>
#include <asm/processor.h>
#include <flash.h>

#define ROM_CS0_START	0xFF800000
#define ROM_CS1_START	0xFF000000

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

#if defined(CONFIG_ENV_IS_IN_FLASH)
# ifndef  CONFIG_ENV_ADDR
#  define CONFIG_ENV_ADDR  (CFG_FLASH_BASE + CONFIG_ENV_OFFSET)
# endif
# ifndef  CONFIG_ENV_SIZE
#  define CONFIG_ENV_SIZE  CONFIG_ENV_SECT_SIZE
# endif
# ifndef  CONFIG_ENV_SECT_SIZE
#  define CONFIG_ENV_SECT_SIZE  CONFIG_ENV_SIZE
# endif
#endif

/*-----------------------------------------------------------------------
 * Functions
 */
static int write_word (flash_info_t *info, ulong dest, ulong data);

/*flash command address offsets*/

#define ADDR0		(0xAAA)
#define ADDR1		(0x555)
#define ADDR3		(0x001)

#define FLASH_WORD_SIZE unsigned char

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

static unsigned long flash_id(unsigned char mfct, unsigned char chip) __attribute__ ((const));

typedef struct{
  FLASH_WORD_SIZE extval;
  unsigned short intval;
} map_entry;

static unsigned long flash_id(unsigned char mfct, unsigned char chip)
{
	static const map_entry mfct_map[] = {
		{(FLASH_WORD_SIZE) AMD_MANUFACT,	(unsigned short) ((unsigned long) FLASH_MAN_AMD >> 16)},
		{(FLASH_WORD_SIZE) FUJ_MANUFACT,	(unsigned short) ((unsigned long) FLASH_MAN_FUJ >> 16)},
		{(FLASH_WORD_SIZE) STM_MANUFACT,	(unsigned short) ((unsigned long) FLASH_MAN_STM >> 16)},
		{(FLASH_WORD_SIZE) MT_MANUFACT,	(unsigned short) ((unsigned long) FLASH_MAN_MT >> 16)},
		{(FLASH_WORD_SIZE) INTEL_MANUFACT,(unsigned short) ((unsigned long) FLASH_MAN_INTEL >> 16)},
		{(FLASH_WORD_SIZE) INTEL_ALT_MANU,(unsigned short) ((unsigned long) FLASH_MAN_INTEL >> 16)}
	};

	static const map_entry chip_map[] = {
		{AMD_ID_F040B,	FLASH_AM040},
		{AMD_ID_F033C,	FLASH_AM033},
		{AMD_ID_F065D,	FLASH_AM065},
		{ATM_ID_LV040,	FLASH_AT040},
		{(FLASH_WORD_SIZE) STM_ID_x800AB,	FLASH_STM800AB}
	};

	const map_entry *p;
	unsigned long result = FLASH_UNKNOWN;

	/* find chip id */
	for(p = &chip_map[0]; p < &chip_map[sizeof chip_map / sizeof chip_map[0]]; p++){
		if(p->extval == chip){
			result = FLASH_VENDMASK | p->intval;
			break;
		}
	}

	/* find vendor id */
	for(p = &mfct_map[0]; p < &mfct_map[sizeof mfct_map / sizeof mfct_map[0]]; p++){
		if(p->extval == mfct){
			result &= ~FLASH_VENDMASK;
			result |= (unsigned long) p->intval << 16;
			break;
		}
	}

	return result;
}


unsigned long flash_init(void)
{
	unsigned long i;
	unsigned char j;
	static const ulong flash_banks[] = CFG_FLASH_BANKS;

	/* Init: no FLASHes known */
	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++){
		flash_info_t * const pflinfo = &flash_info[i];
		pflinfo->flash_id = FLASH_UNKNOWN;
		pflinfo->size = 0;
		pflinfo->sector_count = 0;
	}

	/* Enable writes to Hydra/Argus flash */
	{
		register unsigned int temp;
		CONFIG_READ_WORD(PICR1,temp);
		temp |= PICR1_FLASH_WR_EN;
		CONFIG_WRITE_WORD(PICR1,temp);
	}

	for(i = 0; i < sizeof flash_banks / sizeof flash_banks[0]; i++){
		flash_info_t * const pflinfo = &flash_info[i];
		const unsigned long base_address = flash_banks[i];
		volatile FLASH_WORD_SIZE * const flash = (FLASH_WORD_SIZE *) base_address;

		/* write autoselect sequence */
		flash[0x5555] = 0xaa;
		flash[0x2aaa] = 0x55;
		flash[0x5555] = 0x90;
		__asm__ __volatile__("sync");

		pflinfo->flash_id = flash_id(flash[0x0], flash[0x1]);

		switch(pflinfo->flash_id & FLASH_TYPEMASK){
			case FLASH_AM033:
				pflinfo->size = 0x00200000;
				pflinfo->sector_count = 64;
				for(j = 0; j < 64; j++){
					pflinfo->start[j] = base_address + 0x00010000 * j;
					pflinfo->protect[j] = flash[(j << 16) | 0x2];
				}
				break;
			case FLASH_AM065:
				pflinfo->size = 0x00800000;
				pflinfo->sector_count =128;
				for(j = 0; j < 128; j++){
					pflinfo->start[j] = base_address + 0x00010000 * j;
					pflinfo->protect[j] = flash[(j << 16) | 0x2];
				}
				break;
			case FLASH_AT040:
				pflinfo->size = 0x00080000;
				pflinfo->sector_count = 2;
				pflinfo->start[0] = base_address ;
				pflinfo->start[1] = base_address + 0x00004000;
				pflinfo->protect[0] = ((flash[0x02] & 0X01)==0) ? 0X02 : 0X01;
				pflinfo->protect[1] = 0X02;
				break;
			case FLASH_AM040:
				pflinfo->size = 0x00080000;
				pflinfo->sector_count = 8;
				for(j = 0; j < 8; j++){
					pflinfo->start[j] = base_address + 0x00010000 * j;
					pflinfo->protect[j] = flash[(j << 16) | 0x2];
				}
				break;
			case FLASH_STM800AB:
				pflinfo->size = 0x00100000;
				pflinfo->sector_count = 19;
				pflinfo->start[0] = base_address;
				pflinfo->start[1] = base_address + 0x4000;
				pflinfo->start[2] = base_address + 0x6000;
				pflinfo->start[3] = base_address + 0x8000;
				for(j = 1; j < 16; j++){
					pflinfo->start[j+3] = base_address + 0x00010000 * j;
				}
				break;
		}
		/* 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 defined(CONFIG_ENV_IS_IN_FLASH) && defined(CONFIG_ENV_ADDR)
		flash_protect(FLAG_PROTECT_SET,
				CONFIG_ENV_ADDR,
				CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1,
				&flash_info[0]);
#endif

		/* reset device to read mode */
		flash[0x0000] = 0xf0;
		__asm__ __volatile__("sync");
	}

	return flash_info[0].size + flash_info[1].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_ATM:
				mfct = "Atmel";
				break;
			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_AT040:
				type = "AT49LV040 (512K * 8, uniform sector size)";
				break;
			case FLASH_AM033:
				type = "AM29F033C (4 Mbit * 8, uniform sector size)";
				break;
			case FLASH_AM040:
				type = "AM29F040B (512K * 8, uniform sector size)";
				break;
			case FLASH_AM065:
				type = "AM29F0465D ( 8 MBit * 8, uniform sector size) or part of AM29F652D( 16 MB)";
				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_AM160T:
				type = "AM29LV160T (16 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);
}

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