/*
 * (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 <mpc8xx.h>
#include <flash.h>

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

/*-----------------------------------------------------------------------
 * Functions
 */
ulong flash_recognize (vu_long *base);
int write_word (flash_info_t *info, ulong dest, ulong data);
void flash_get_geometry (vu_long *base, flash_info_t *info);
void flash_unprotect(flash_info_t *info);
int _flash_real_protect(flash_info_t *info, long idx, int on);


unsigned long flash_init (void)
{
	volatile immap_t	*immap  = (immap_t *)CFG_IMMR;
	volatile memctl8xx_t	*memctl = &immap->im_memctl;
	int i;
	int rec;

	for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
		flash_info[i].flash_id = FLASH_UNKNOWN;
	}

	*((vu_short*)CFG_FLASH_BASE) = 0xffff;

	flash_get_geometry ((vu_long*)CFG_FLASH_BASE, &flash_info[0]);

	/* Remap FLASH according to real size */
	memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-flash_info[0].size & 0xFFFF8000);
	memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) |
		(memctl->memc_br0 & ~(BR_BA_MSK));

	rec = flash_recognize((vu_long*)CFG_FLASH_BASE);

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

#if CFG_FLASH_PROTECTION
	/*Unprotect all the flash memory*/
	flash_unprotect(&flash_info[0]);
#endif

	*((vu_short*)CFG_FLASH_BASE) = 0xffff;

	return (flash_info[0].size);

#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
	/* monitor protection ON by default */
	flash_protect(FLAG_PROTECT_SET,
		      CFG_MONITOR_BASE,
		      CFG_MONITOR_BASE+monitor_flash_len-1,
		      &flash_info[0]);
#endif

#ifdef	CFG_ENV_IS_IN_FLASH
	/* ENV protection ON by default */
	flash_protect(FLAG_PROTECT_SET,
		      CFG_ENV_OFFSET,
		      CFG_ENV_OFFSET+CFG_ENV_SIZE-1,
		      &flash_info[0]);
#endif
	return (flash_info[0].size);
}


int flash_get_protect_status(flash_info_t * info, long idx)
{
	vu_short * base;
	ushort res;

#ifdef DEBUG
	printf("\n Attempting to set protection info with %d sectors\n", info->sector_count);
#endif


	base = (vu_short*)info->start[idx];

	*(base) = 0xffff;

	*(base + 0x55) = 0x0098;
	res = base[0x2];

	*(base) = 0xffff;

	if(res != 0)
		res = 1;
	else
		res = 0;

	return res;
}

void flash_get_geometry (vu_long *base, flash_info_t *info)
{
	int i,j;
	ulong ner = 0;
	vu_short * sb  = (vu_short*)base;
	ulong offset = (ulong)base;

	/* Read Device geometry */

	*sb = 0xffff;

	*sb = 0x0090;

	info->flash_id = ((ulong)base[0x0]);
#ifdef DEBUG
	printf("Id is %x\n", (uint)(ulong)info->flash_id);
#endif

	*sb = 0xffff;

	*(sb+0x55) = 0x0098;

	info->size = 1 << (sb[0x27]); /* Read flash size */

#ifdef DEBUG
	printf("Size is %x\n", (uint)(ulong)info->size);
#endif

	*sb = 0xffff;

	*(sb + 0x55) = 0x0098;
	ner = sb[0x2c] ; /*Number of erase regions*/

#ifdef DEBUG
	printf("Number of erase regions %x\n", (uint)ner);
#endif

	info->sector_count = 0;

	for(i = 0; i < ner; i++)
	{
		uint s;
		uint count;
		uint t1,t2,t3,t4;

		*sb = 0xffff;

		*(sb + 0x55) = 0x0098;

		t1 = sb[0x2d + i*4];
		t2 = sb[0x2e + i*4];
		t3 = sb[0x2f + i*4];
		t4 = sb[0x30 + i*4];

		count = ((t1 & 0x00ff) | (((t2 & 0x00ff) << 8) & 0xff00) )+ 1; /*sector count*/
		s = ((t3 & 0x00ff) | (((t4 & 0x00ff) << 8) & 0xff00)) * 256;; /*Sector size*/

#ifdef DEBUG
		printf("count and size %x, %x\n", count, s);
		printf("sector count for erase region %d is %d\n", i, count);
#endif
		for(j = 0; j < count; j++)
		{
#ifdef DEBUG
			printf("%x, ", (uint)offset);
#endif
			info->start[ info->sector_count + j] = offset;
			offset += s;
		}
		info->sector_count += count;
	}

	if ((offset - (ulong)base) != info->size)
		printf("WARNING reported size %x does not match to calculted size %x.\n"
				, (uint)info->size, (uint)(offset - (ulong)base) );

	/* Next check if there are any sectors protected.*/

	for(i = 0; i < info->sector_count; i++)
		info->protect[i] = flash_get_protect_status(info, i);

	*sb = 0xffff;
}

/*-----------------------------------------------------------------------
 */
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 INTEL_MANUFACT & FLASH_VENDMASK:
		printf ("Intel ");
		break;
	default:
		printf ("Unknown Vendor ");
		break;
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
	case INTEL_ID_28F320C3B & FLASH_TYPEMASK:
		printf ("28F320RC3(4 MB)\n");
		break;
	case INTEL_ID_28F320J3A:
		printf("28F320J3A (4 MB)\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 % 4) == 0)
			printf ("\n   ");
		printf ("  %02d %08lX%s",
			i, info->start[i],
			info->protect[i]!=0 ? " (RO)" : "     "
		);
	}
	printf ("\n");
	return ;
}

ulong flash_recognize (vu_long *base)
{
	ulong id;
	ulong res = FLASH_UNKNOWN;
	vu_short * sb = (vu_short*)base;

	*sb = 0xffff;

	*sb = 0x0090;
	id = base[0];

	switch (id & 0x00FF0000)
	{
		case (MT_MANUFACT & 0x00FF0000):	/* MT or => Intel */
		case (INTEL_ALT_MANU & 0x00FF0000):
		res = FLASH_MAN_INTEL;
		break;
	default:
		res = FLASH_UNKNOWN;
	}

	*sb = 0xffff;

	return res;
}

/*-----------------------------------------------------------------------*/
#define INTEL_FLASH_STATUS_BLS	0x02
#define INTEL_FLASH_STATUS_PSS	0x04
#define INTEL_FLASH_STATUS_VPPS	0x08
#define INTEL_FLASH_STATUS_PS	0x10
#define INTEL_FLASH_STATUS_ES	0x20
#define INTEL_FLASH_STATUS_ESS	0x40
#define INTEL_FLASH_STATUS_WSMS	0x80

int	flash_decode_status_bits(char status)
{
	int err = 0;

	if(!(status & INTEL_FLASH_STATUS_WSMS)) {
		printf("Busy\n");
		err = -1;
	}

	if(status & INTEL_FLASH_STATUS_ESS) {
		printf("Erase suspended\n");
		err = -1;
	}

	if(status & INTEL_FLASH_STATUS_ES) {
		printf("Error in block erase\n");
		err = -1;
	}

	if(status & INTEL_FLASH_STATUS_PS) {
		printf("Error in programming\n");
		err = -1;
	}

	if(status & INTEL_FLASH_STATUS_VPPS) {
		printf("Vpp low, operation aborted\n");
		err = -1;
	}

	if(status & INTEL_FLASH_STATUS_PSS) {
		printf("Program is suspended\n");
		err = -1;
	}

	if(status & INTEL_FLASH_STATUS_BLS) {
		printf("Attempting to program/erase a locked sector\n");
		err = -1;
	}

	if((status & INTEL_FLASH_STATUS_PS) &&
	   (status & INTEL_FLASH_STATUS_ES) &&
	   (status & INTEL_FLASH_STATUS_ESS)) {
		printf("A command sequence error\n");
		return -1;
	}

	return err;
}

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

int	flash_erase (flash_info_t *info, int s_first, int s_last)
{
	vu_short *addr;
	int flag, prot, sect;
	ulong start, now;
	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_VENDMASK) != (INTEL_MANUFACT & 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");
	}

	start = get_timer (0);

	/* Start erase on unprotected sectors */
	for (sect = s_first; sect<=s_last; sect++) {
		char tmp;

		if (info->protect[sect] == 0) {	/* not protected */
			addr = (vu_short *)(info->start[sect]);

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

			/* Single Block Erase Command */
			*addr = 0x0020;
			/* Confirm */
			*addr = 0x00D0;
			/* Resume Command, as per errata update */
			*addr = 0x00D0;

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

			*addr = 0x70; /*Read status register command*/
			tmp = (short)*addr & 0x00FF; /* Read the status */
			while (!(tmp & INTEL_FLASH_STATUS_WSMS)) {
				if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
					*addr = 0x0050; /* Reset the status register */
					*addr = 0xffff;
					printf ("Timeout\n");
					return 1;
				}
				/* show that we're waiting */
				if ((now - start) > 1000) {	/* every second */
					putc ('.');
				}
				udelay(100000); /* 100 ms */
				*addr = 0x0070; /*Read status register command*/
				tmp = (short)*addr & 0x00FF; /* Read status */
				start = get_timer(0);
			}
			if( tmp & INTEL_FLASH_STATUS_ES )
				flash_decode_status_bits(tmp);

			*addr = 0x0050; /* Reset the status register */
			*addr = 0xffff; /* Reset to read mode */
		}
	}


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

void flash_unprotect (flash_info_t *info)
{
	/*We can only unprotect the whole flash at once*/
	/*Therefore we must prevent the _flash_real_protect()*/
	/*from re-protecting sectors, that ware protected before */
	/*we called flash_real_protect();*/

	int i;

	for(i = 0; i < info->sector_count; i++)
		info->protect[i] = 0;

#ifdef CFG_FLASH_PROTECTION
		_flash_real_protect(info, 0, 0);
#endif
}

/*-----------------------------------------------------------------------
 * 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
 */
int write_word (flash_info_t *info, ulong dest, ulong da)
{
	vu_short *addr = (vu_short *)dest;
	ulong start;
	char csr;
	int flag;
	ushort * d = (ushort*)&da;
	int i;

	/* Check if Flash is (sufficiently) erased */
	if (((*addr & d[0]) != d[0]) || ((*(addr+1) & d[1]) != d[1])) {
		return (2);
	}
	/* Disable interrupts which might cause a timeout here */
	flag = disable_interrupts();

	for(i = 0; i < 2; i++)
	{
		/* Write Command */
		*addr = 0x0010;

		/* Write Data */
		*addr = d[i];

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

		/* data polling for D7 */
		start = get_timer (0);
		flag  = 0;
		*addr = 0x0070; /*Read statusregister command */
		while (((csr = *addr) & INTEL_FLASH_STATUS_WSMS)!=INTEL_FLASH_STATUS_WSMS) {
			if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
				flag = 1;
				break;
			}
			*addr = 0x0070; /*Read statusregister command */
		}
		if (csr & INTEL_FLASH_STATUS_PSS) {
			printf ("CSR indicates write error (%0x) at %08lx\n",
					csr, (ulong)addr);
			flag = 1;
		}

		/* Clear Status Registers Command */
		*addr = 0x0050;
		/* Reset to read array mode */
		*addr = 0xffff;
		addr++;
	}

	return (flag);
}

int flash_real_protect(flash_info_t *info, long offset, int prot)
{
	int i, idx;

	for(idx = 0; idx < info->sector_count; idx++)
		if(info->start[idx] == offset)
			break;

	if(idx==info->sector_count)
		return -1;

	if(prot == 0) {
		/* Unprotect one sector, which means unprotect all flash
		 * and reprotect the other protected sectors.
		 */
		_flash_real_protect(info, 0, 0); /* Unprotects the whole flash*/
		info->protect[idx] = 0;

		for(i = 0; i < info->sector_count; i++)
			if(info->protect[i])
				_flash_real_protect(info, i, 1);
		}
	else {
		/* We can protect individual sectors */
		_flash_real_protect(info, idx, 1);
	}

	for( i = 0; i < info->sector_count; i++)
		info->protect[i] = flash_get_protect_status(info, i);

	return 0;
}

int _flash_real_protect(flash_info_t *info, long idx, int prot)
{
	vu_short *addr;
	int flag;
	ushort cmd;
	ushort tmp;
	ulong now, start;

	if ((info->flash_id & FLASH_VENDMASK) != (INTEL_MANUFACT & FLASH_VENDMASK)) {
		printf ("Can't change protection for unknown flash type %08lx - aborted\n",
			info->flash_id);
		return -1;
	}

	if(prot == 0) {
		/*Unlock the sector*/
		cmd = 0x00D0;
	}
	else {
		/*Lock the sector*/
		cmd = 0x0001;
	}

	addr = (vu_short *)(info->start[idx]);

	/* If chip is busy, wait for it */
	start = get_timer(0);
	*addr = 0x0070; /*Read status register command*/
	tmp = ((ushort)(*addr))&0x00ff; /*Read the status*/
	while(!(tmp & INTEL_FLASH_STATUS_WSMS)) {
		/*Write State Machine Busy*/
		/*Wait untill done or timeout.*/
		if ((now=get_timer(start)) > CFG_FLASH_WRITE_TOUT) {
			*addr = 0x0050; /* Reset the status register */
			*addr = 0xffff; /* Reset the chip */
			printf ("TTimeout\n");
			return 1;
		}
		*addr = 0x0070;
		tmp = ((ushort)(*addr))&0x00ff; /*Read the status*/
		start = get_timer(0);
	}

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

	/* Unlock block*/
	*addr = 0x0060;

	*addr = cmd;

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

	start = get_timer(0);
	*addr = 0x0070; /*Read status register command*/
	tmp = ((ushort)(*addr)) & 0x00FF; /* Read the status */
	while (!(tmp & INTEL_FLASH_STATUS_WSMS)) {
		/* Write State Machine Busy */
		if ((now=get_timer(start)) > CFG_FLASH_WRITE_TOUT) {
			*addr = 0x0050; /* Reset the status register */
			*addr = 0xffff;
			printf ("Timeout\n");
			return 1;
		}
		/* show that we're waiting */
		if ((now - start) > 1000) {	/* every second */
			putc ('.');
		}
		udelay(100000); /* 100 ms */
		*addr = 0x70; /*Read status register command*/
		tmp = (short)*addr & 0x00FF; /* Read status */
		start = get_timer(0);
	}
	if( tmp & INTEL_FLASH_STATUS_PS )
		flash_decode_status_bits(tmp);

	*addr =0x0050; /*Clear status register*/

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

	return 0;
}
