/*
 * (C) Copyright 2003
 * 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 <asm/inca-ip.h>

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

typedef unsigned long FLASH_PORT_WIDTH;
typedef volatile unsigned long FLASH_PORT_WIDTHV;

#define	FLASH_ID_MASK	0xFFFFFFFF

#define FPW	FLASH_PORT_WIDTH
#define FPWV	FLASH_PORT_WIDTHV

#define ORMASK(size) ((-size) & OR_AM_MSK)

#define FLASH29_REG_ADRS(reg) ((FPWV *)PHYS_FLASH_1 + (reg))

/* FLASH29 command register addresses */

#define FLASH29_REG_FIRST_CYCLE		FLASH29_REG_ADRS (0x1555)
#define FLASH29_REG_SECOND_CYCLE	FLASH29_REG_ADRS (0x2aaa)
#define FLASH29_REG_THIRD_CYCLE		FLASH29_REG_ADRS (0x3555)	
#define	FLASH29_REG_FOURTH_CYCLE	FLASH29_REG_ADRS (0x4555)
#define	FLASH29_REG_FIFTH_CYCLE		FLASH29_REG_ADRS (0x5aaa)
#define	FLASH29_REG_SIXTH_CYCLE		FLASH29_REG_ADRS (0x6555)

/* FLASH29 command definitions */

#define	FLASH29_CMD_FIRST		0xaaaaaaaa
#define	FLASH29_CMD_SECOND		0x55555555
#define	FLASH29_CMD_FOURTH		0xaaaaaaaa
#define	FLASH29_CMD_FIFTH		0x55555555
#define	FLASH29_CMD_SIXTH		0x10101010

#define	FLASH29_CMD_SECTOR		0x30303030
#define	FLASH29_CMD_PROGRAM		0xa0a0a0a0
#define	FLASH29_CMD_CHIP_ERASE		0x80808080
#define	FLASH29_CMD_READ_RESET		0xf0f0f0f0
#define	FLASH29_CMD_AUTOSELECT		0x90909090
#define FLASH29_CMD_READ		0x70707070	

#define IN_RAM_CMD_READ		0x1
#define IN_RAM_CMD_WRITE	0x2

#define FLASH_WRITE_CMD	((ulong)(flash_write_cmd) & 0x7)+0xbf008000
#define FLASH_READ_CMD  ((ulong)(flash_read_cmd) & 0x7)+0xbf008000

typedef void (*FUNCPTR_CP)(ulong *source, ulong *destination, ulong nlongs);
typedef void (*FUNCPTR_RD)(int cmd, FPWV * pFA, char * string, int strLen);
typedef void (*FUNCPTR_WR)(int cmd, FPWV * pFA, FPW value);

static ulong flash_get_size(FPWV *addr, flash_info_t *info);
static int write_word(flash_info_t *info, FPWV *dest, FPW data);
static void flash_get_offsets(ulong base, flash_info_t *info);
static flash_info_t *flash_get_info(ulong base);

static void load_cmd(ulong cmd);
static ulong in_ram_cmd = 0;


/******************************************************************************
*
* Don't change the program architecture
* This architecture assure the program
* can be relocated to scratch ram
*/
static void flash_read_cmd(int cmd, FPWV * pFA, char * string, int strLen)
{					
	int i,j;
	FPW temp,temp1;	
	FPWV *str;

	str = (FPWV *)string;

	j=  strLen/4;
	
	if(cmd == FLASH29_CMD_AUTOSELECT)
	   {
            *(FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
            *(FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
            *(FLASH29_REG_THIRD_CYCLE)  = FLASH29_CMD_AUTOSELECT;
           }

        if(cmd == FLASH29_CMD_READ)
           { 
	    i = 0;		
	    while(i<j)	
            {
		temp = *pFA++;
		temp1 = *(int *)0xa0000000;
                *(int *)0xbf0081f8 = temp1 + temp;
		*str++ = temp;
		i++;
	    }  		
           }

         if(cmd == FLASH29_CMD_READ_RESET) 
         {
            *(FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
            *(FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;
            *(FLASH29_REG_THIRD_CYCLE)  = FLASH29_CMD_READ_RESET;
         } 			 	
	    	
	*(int *)0xbf0081f8 = *(int *)0xa0000000;	/* dummy read switch back to sdram interface */	
}

/******************************************************************************
*
* Don't change the program architecture
* This architecture assure the program
* can be relocated to scratch ram
*/
static void flash_write_cmd(int cmd, FPWV * pFA, FPW value)
{						
        *(FLASH29_REG_FIRST_CYCLE)  = FLASH29_CMD_FIRST;
        *(FLASH29_REG_SECOND_CYCLE) = FLASH29_CMD_SECOND;

	if (cmd == FLASH29_CMD_SECTOR)
	   {
            *(FLASH29_REG_THIRD_CYCLE)  = FLASH29_CMD_CHIP_ERASE;
            *(FLASH29_REG_FOURTH_CYCLE) = FLASH29_CMD_FOURTH;
            *(FLASH29_REG_FIFTH_CYCLE)  = FLASH29_CMD_FIFTH;
            *pFA		        = FLASH29_CMD_SECTOR;
           }

        if (cmd == FLASH29_CMD_SIXTH)
           { 
            *(FLASH29_REG_THIRD_CYCLE)  = FLASH29_CMD_CHIP_ERASE;
            *(FLASH29_REG_FOURTH_CYCLE) = FLASH29_CMD_FOURTH;
            *(FLASH29_REG_FIFTH_CYCLE)  = FLASH29_CMD_FIFTH;
            *(FLASH29_REG_SIXTH_CYCLE)  = FLASH29_CMD_SIXTH;
	   }

        if (cmd == FLASH29_CMD_PROGRAM)
           {
            *(FLASH29_REG_THIRD_CYCLE)  = FLASH29_CMD_PROGRAM;
	    *pFA = value;
           }

        if (cmd == FLASH29_CMD_READ_RESET)    
           {
            *(FLASH29_REG_THIRD_CYCLE)  = FLASH29_CMD_READ_RESET;
           } 			 	
	    	
	*(int *)0xbf0081f8 = *(int *)0xa0000000;	/* dummy read switch back to sdram interface */	
}

static void load_cmd(ulong cmd)
{
	ulong *src;
	ulong *dst;
	FUNCPTR_CP absEntry;
	ulong func;
	 
	if (in_ram_cmd & cmd) return;
	
	if (cmd == IN_RAM_CMD_READ)
	{
		func = (ulong)flash_read_cmd;
	}
	else
	{
		func = (ulong)flash_write_cmd;
	}

    	src = (ulong *)(func & 0xfffffff8);
    	dst = (ulong *)0xbf008000;
    	absEntry = (FUNCPTR_CP)(0xbf0081d0);
    	absEntry(src,dst,0x38);

        in_ram_cmd = cmd;
}

/*-----------------------------------------------------------------------
 * flash_init()
 *
 * sets up flash_info and returns size of FLASH (bytes)
 */
unsigned long flash_init (void)
{
	unsigned long size = 0;
	int i;
	 
        load_cmd(IN_RAM_CMD_READ);

	/* Init: no FLASHes known */
	for (i=0; i < CFG_MAX_FLASH_BANKS; ++i) {
		ulong flashbase = PHYS_FLASH_1;
		ulong * buscon = (ulong *) INCA_IP_EBU_EBU_BUSCON0;
		
		/* Disable write protection */
		*buscon &= ~INCA_IP_EBU_EBU_BUSCON1_WRDIS;

#if 1
		memset(&flash_info[i], 0, sizeof(flash_info_t));
#endif

		flash_info[i].size = 
			flash_get_size((FPW *)flashbase, &flash_info[i]);

		if (flash_info[i].flash_id == FLASH_UNKNOWN) {
			printf ("## Unknown FLASH on Bank %d - Size = 0x%08lx\n",
			i, flash_info[i].size);
		}
		
		size += flash_info[i].size;
	}

#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
	/* monitor protection ON by default */
	flash_protect(FLAG_PROTECT_SET,
		      CFG_MONITOR_BASE,
		      CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
		      flash_get_info(CFG_MONITOR_BASE));
#endif

#ifdef	CFG_ENV_IS_IN_FLASH
	/* ENV protection ON by default */
	flash_protect(FLAG_PROTECT_SET,
		      CFG_ENV_ADDR,
		      CFG_ENV_ADDR+CFG_ENV_SIZE-1,
		      flash_get_info(CFG_ENV_ADDR));
#endif

	return size;
}

/*-----------------------------------------------------------------------
 */
static void flash_get_offsets (ulong base, flash_info_t *info)
{
	int i;

	if ((info->flash_id & FLASH_VENDMASK) == FLASH_MAN_AMD
		 && (info->flash_id & FLASH_TYPEMASK) == FLASH_AM160B) {

		int bootsect_size[4];	/* number of bytes/boot sector  */
		int sect_size;		/* number of bytes/regular sector */

		bootsect_size[0] = 0x00008000;
		bootsect_size[1] = 0x00004000;
		bootsect_size[2] = 0x00004000;
		bootsect_size[3] = 0x00010000;
		sect_size =        0x00020000;

		/* set sector offsets for bottom boot block type	*/
		for (i = 0; i < info->sector_count; i++) {
			info->start[i] = base;
			base += i < 4 ? bootsect_size[i] : sect_size;
		}
	}
}

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

static flash_info_t *flash_get_info(ulong base)
{
	int i;
	flash_info_t * info;
	
	for (i = 0; i < CFG_MAX_FLASH_BANKS; i ++) {
		info = & flash_info[i];
		if (info->start[0] <= base && base < info->start[0] + info->size)
			break;
	}
	
	return i == CFG_MAX_FLASH_BANKS ? 0 : info;
}

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

void flash_print_info (flash_info_t *info)
{
	int i;
	uchar *boottype;
	uchar *bootletter;
	uchar *fmt;
	uchar botbootletter[] = "B";
	uchar topbootletter[] = "T";
	uchar botboottype[] = "bottom boot sector";
	uchar topboottype[] = "top boot sector";

	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_BM:	printf ("BRIGHT MICRO ");	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;
	}

	/* check for top or bottom boot, if it applies */
	if (info->flash_id & FLASH_BTYPE) {
		boottype = botboottype;
		bootletter = botbootletter;
	}
	else {
		boottype = topboottype;
		bootletter = topbootletter;
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
	case FLASH_AM160B:
		fmt = "29LV160B%s (16 Mbit, %s)\n";
		break;
        case FLASH_28F800C3B:
        case FLASH_28F800C3T:
		fmt = "28F800C3%s (8 Mbit, %s)\n";
		break;
	case FLASH_INTEL800B:
	case FLASH_INTEL800T:
		fmt = "28F800B3%s (8 Mbit, %s)\n";
		break;
        case FLASH_28F160C3B:
        case FLASH_28F160C3T:
		fmt = "28F160C3%s (16 Mbit, %s)\n";
		break;
	case FLASH_INTEL160B:
	case FLASH_INTEL160T:
		fmt = "28F160B3%s (16 Mbit, %s)\n";
		break;
        case FLASH_28F320C3B:
        case FLASH_28F320C3T:
		fmt = "28F320C3%s (32 Mbit, %s)\n";
		break;
	case FLASH_INTEL320B:
	case FLASH_INTEL320T:
		fmt = "28F320B3%s (32 Mbit, %s)\n";
		break;
        case FLASH_28F640C3B:
        case FLASH_28F640C3T:
		fmt = "28F640C3%s (64 Mbit, %s)\n";
		break;
	case FLASH_INTEL640B:
	case FLASH_INTEL640T:
		fmt = "28F640B3%s (64 Mbit, %s)\n";
		break;
	default:
		fmt = "Unknown Chip Type\n";
		break;
	}

	printf (fmt, bootletter, boottype);

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

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

/*
 * The following code cannot be run from FLASH!
 */

ulong flash_get_size (FPWV *addr, flash_info_t *info)
{
	FUNCPTR_RD absEntry;
	FPW retValue;	
	int flag;

        load_cmd(IN_RAM_CMD_READ);
	absEntry = (FUNCPTR_RD)FLASH_READ_CMD;

	flag = disable_interrupts();
	absEntry(FLASH29_CMD_AUTOSELECT,0,0,0);
	if (flag) enable_interrupts();
	
	udelay(100);

	flag = disable_interrupts();
	absEntry(FLASH29_CMD_READ, addr + 1, (char *)&retValue, sizeof(retValue));
	absEntry(FLASH29_CMD_READ_RESET,0,0,0);
	if (flag) enable_interrupts();

	udelay(100);

	switch (retValue) {

	case (FPW)AMD_ID_LV160B:
		info->flash_id += FLASH_AM160B;
		info->sector_count = 35;
		info->size = 0x00400000;
		break;				/* => 8 or 16 MB	*/

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

	flash_get_offsets((ulong)addr, info);

	return (info->size);
}

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

int	flash_erase (flash_info_t *info, int s_first, int s_last)
{
	FPWV *addr;
	int flag, prot, sect;
	ulong start, now, last;
	int rcode = 0;
	FUNCPTR_WR absEntry;

        load_cmd(IN_RAM_CMD_WRITE);
	absEntry = (FUNCPTR_WR)FLASH_WRITE_CMD;

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

	switch (info->flash_id & FLASH_TYPEMASK) {
	case FLASH_AM160B:
		break;
	case FLASH_UNKNOWN:
	default:
		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");
	}

	last  = get_timer(0);

	/* Start erase on unprotected sectors */
	for (sect = s_first; sect<=s_last && rcode == 0; sect++) {

		if (info->protect[sect] != 0)	/* protected, skip it */
			continue;

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

		addr = (FPWV *)(info->start[sect]);
		absEntry(FLASH29_CMD_SECTOR, addr, 0);

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

		start = get_timer(0);

		while ((now = get_timer(start)) <= CFG_FLASH_ERASE_TOUT) {

			/* show that we're waiting */
			if ((get_timer(last)) > CFG_HZ) {/* every second */
				putc ('.');
				last = get_timer(0);
			}
		}

		flag = disable_interrupts();
		absEntry(FLASH29_CMD_READ_RESET,0,0);
		if (flag)
			enable_interrupts();
	}

	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)
{
    FPW data = 0; /* 16 or 32 bit word, matches flash bus width on MPC8XX */
    int bytes;	  /* number of bytes to program in current word		*/
    int left;	  /* number of bytes left to program			*/
    int i, res;

    for (left = cnt, res = 0;
	 left > 0 && res == 0;
	 addr += sizeof(data), left -= sizeof(data) - bytes) {

        bytes = addr & (sizeof(data) - 1);
        addr &= ~(sizeof(data) - 1);

	/* combine source and destination data so can program
	 * an entire word of 16 or 32 bits
	 */
        for (i = 0; i < sizeof(data); i++) {
            data <<= 8;
            if (i < bytes || i - bytes >= left )
		data += *((uchar *)addr + i);
	    else
		data += *src++;
	}

	res = write_word(info, (FPWV *)addr, data);
    }

    return (res);
}

static int write_word (flash_info_t *info, FPWV *dest, FPW data)
{
    int res = 0;	/* result, assume success	*/
    FUNCPTR_WR absEntry;
    int flag;

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

    if (info->start[0] != PHYS_FLASH_1)
    {
	return (3);
    }

    load_cmd(IN_RAM_CMD_WRITE);
    absEntry = (FUNCPTR_WR)FLASH_WRITE_CMD;

    flag = disable_interrupts();
    absEntry(FLASH29_CMD_PROGRAM,dest,data);
    if (flag) enable_interrupts();

    udelay(100);

    flag = disable_interrupts();
    absEntry(FLASH29_CMD_READ_RESET,0,0);
    if (flag) enable_interrupts();

    return (res);
}
