/*
 * (C) Copyright 2000
 * Marius Groeger <mgroeger@sysgo.de>
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 *
 * (C) Copyright 2000
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * Flash Routines for AM290[48]0B devices
 *
 *--------------------------------------------------------------------
 * 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>

/* flash hardware ids */
#define VENDOR_AMD     0x0001
#define AMD_29DL323C_B 0x2253

/* Define this to include autoselect sequence in flash_init(). Does NOT
 * work when executing from flash itself, so this should be turned
 * on only when debugging the RAM version.
 */
#undef WITH_AUTOSELECT

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

#if 1
#define D(x)
#else
#define D(x) printf x
#endif

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

static unsigned char write_ull(flash_info_t *info,
			       unsigned long address,
			       volatile unsigned long long data);

/* from flash_asm.S */
extern void ull_write(unsigned long long volatile *address,
		      unsigned long long volatile *data);
extern void ull_read(unsigned long long volatile *address,
		     unsigned long long volatile *data);

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

unsigned long flash_init (void)
{
    int i;
    ulong addr;

#ifdef WITH_AUTOSELECT
	{
		unsigned long long *f_addr = (unsigned long long *)PHYS_FLASH;
		unsigned long long f_command, vendor, device;
		/* Perform Autoselect */
		f_command 	= 0x00AA00AA00AA00AAULL;
		ull_write(&f_addr[0x555], &f_command);
		f_command 	= 0x0055005500550055ULL;
		ull_write(&f_addr[0x2AA], &f_command);
		f_command 	= 0x0090009000900090ULL;
		ull_write(&f_addr[0x555], &f_command);
		ull_read(&f_addr[0], &vendor);
		vendor &= 0xffff;
		ull_read(&f_addr[1], &device);
		device &= 0xffff;
		f_command 	= 0x00F000F000F000F0ULL;
		ull_write(&f_addr[0x555], &f_command);
		if (vendor != VENDOR_AMD || device != AMD_29DL323C_B)
		  return 0;
	}
#endif

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

	/* 1st bank: 8 x 32 KB sectors */
	flash_info[0].flash_id = VENDOR_AMD << 16 | AMD_29DL323C_B;
	flash_info[0].sector_count = 8;
	flash_info[0].size = flash_info[0].sector_count * 32 * 1024;
	addr = PHYS_FLASH;
    for(i = 0; i < flash_info[0].sector_count; i++) {
		flash_info[0].start[i] = addr;
		addr += flash_info[0].size / flash_info[0].sector_count;
	}
	/* 1st bank: 63 x 256 KB sectors */
	flash_info[1].flash_id = VENDOR_AMD << 16 | AMD_29DL323C_B;
	flash_info[1].sector_count = 63;
	flash_info[1].size = flash_info[1].sector_count * 256 * 1024;
    for(i = 0; i < flash_info[1].sector_count; i++) {
		flash_info[1].start[i] = addr;
		addr += flash_info[1].size / flash_info[1].sector_count;
	}

	/*
	 * protect monitor and environment sectors
	 */

#if CFG_MONITOR_BASE >= PHYS_FLASH
	flash_protect(FLAG_PROTECT_SET,
		      CFG_MONITOR_BASE,
		      CFG_MONITOR_BASE+monitor_flash_len-1,
		      &flash_info[0]);
	flash_protect(FLAG_PROTECT_SET,
		      CFG_MONITOR_BASE,
		      CFG_MONITOR_BASE+monitor_flash_len-1,
		      &flash_info[1]);
#endif

#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
# ifndef  CFG_ENV_SIZE
#  define CFG_ENV_SIZE	CFG_ENV_SECT_SIZE
# endif
	flash_protect(FLAG_PROTECT_SET,
		      CFG_ENV_ADDR,
		      CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
		      &flash_info[0]);
	flash_protect(FLAG_PROTECT_SET,
		      CFG_ENV_ADDR,
		      CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
		      &flash_info[1]);
#endif

    return flash_info[0].size + flash_info[1].size;
}

/*-----------------------------------------------------------------------
 */
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 >> 16) {
    case VENDOR_AMD:
		printf ("AMD ");
		break;
    default:
		printf ("Unknown Vendor ");
		break;
    }

    switch (info->flash_id & FLASH_TYPEMASK) {
    case AMD_29DL323C_B:
		printf ("AM29DL323CB (32 Mbit)\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 % 5) == 0)
		  printf ("\n   ");
		printf (" %08lX%s",
				info->start[i],
				info->protect[i] ? " (RO)" : "     "
				);
    }
    printf ("\n");
    return;
}

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

int	flash_erase (flash_info_t *info, int s_first, int s_last)
{
    int flag, prot, sect, l_sect;
    ulong start;
	unsigned long long volatile *f_addr;
	unsigned long long volatile f_command;

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

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

	f_addr 	= (unsigned long long *)info->start[0];
	f_command 	= 0x00AA00AA00AA00AAULL;
	ull_write(&f_addr[0x555], &f_command);
	f_command 	= 0x0055005500550055ULL;
	ull_write(&f_addr[0x2AA], &f_command);
	f_command 	= 0x0080008000800080ULL;
	ull_write(&f_addr[0x555], &f_command);
	f_command 	= 0x00AA00AA00AA00AAULL;
	ull_write(&f_addr[0x555], &f_command);
	f_command 	= 0x0055005500550055ULL;
	ull_write(&f_addr[0x2AA], &f_command);

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

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

			f_addr 	=
			  (unsigned long long *)(info->start[sect]);
			f_command 	= 0x0030003000300030ULL;
			ull_write(f_addr, &f_command);
			l_sect = sect;
		}
    }

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

	start = get_timer (0);
	do
	{
		if (get_timer(start) > CFG_FLASH_ERASE_TOUT)
		{	/* write reset command, command address is unimportant */
			/* this command turns the flash back to read mode     */
			f_addr =
			  (unsigned long long *)(info->start[l_sect]);
			f_command 	= 0x00F000F000F000F0ULL;
			ull_write(f_addr, &f_command);
			printf (" timeout\n");
			return 1;
	}
	} while(*f_addr != 0xFFFFFFFFFFFFFFFFULL);

    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)
{
    unsigned long cp, wp;
	unsigned long long data;
    int i, l, rc;

    wp = (addr & ~7);	/* get lower long long 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<8 && cnt>0; ++i) {
			data = (data << 8) | *src++;
			--cnt;
			++cp;
		}
		for (; cnt==0 && i<8; ++i, ++cp) {
			data = (data << 8) | (*(uchar *)cp);
		}

		if ((rc = write_ull(info, wp, data)) != 0) {
			return rc;
		}
		wp += 4;
    }

    /*
     * handle long long aligned part
     */
    while (cnt >= 8) {
		data = 0;
		for (i=0; i<8; ++i) {
			data = (data << 8) | *src++;
		}
		if ((rc = write_ull(info, wp, data)) != 0) {
			return rc;
		}
		wp  += 8;
		cnt -= 8;
    }

    if (cnt == 0) {
		return ERR_OK;
    }

    /*
     * handle unaligned tail bytes
     */
    data = 0;
    for (i=0, cp=wp; i<8 && cnt>0; ++i, ++cp) {
		data = (data << 8) | *src++;
		--cnt;
    }
    for (; i<8; ++i, ++cp) {
		data = (data << 8) | (*(uchar *)cp);
    }

    return write_ull(info, wp, data);
}

/*---------------------------------------------------------------------------
*
* FUNCTION NAME:  write_ull
*
* DESCRIPTION:   writes 8 bytes to flash
*
* EXTERNAL EFFECT: nothing
*
* PARAMETERS:   32 bit long pointer to address, 64 bit long pointer to data
*
* RETURNS: 	0 if OK, 1 if timeout, 4 if parameter error
*--------------------------------------------------------------------------*/

static unsigned char write_ull(flash_info_t *info,
							   unsigned long address,
							   volatile unsigned long long data)
{
	static unsigned long long f_command;
	static unsigned long long *f_addr;
	ulong start;

	/* address muss be 8-aligned! */
	if (address & 0x7)
	  return ERR_ALIGN;

	f_addr 	= (unsigned long long *)info->start[0];
	f_command 	= 0x00AA00AA00AA00AAULL;
	ull_write(&f_addr[0x555], &f_command);
	f_command 	= 0x0055005500550055ULL;
	ull_write(&f_addr[0x2AA], &f_command);
	f_command 	= 0x00A000A000A000A0ULL;
	ull_write(&f_addr[0x555], &f_command);

	f_addr 	= (unsigned long long *)address;
	f_command 	= data;
	ull_write(f_addr, &f_command);

	start = get_timer (0);
	do
	{
		if (get_timer(start) > CFG_FLASH_WRITE_TOUT)
		{
			/* write reset command, command address is unimportant */
			/* this command turns the flash back to read mode     */
			f_addr 	= (unsigned long long *)info->start[0];
			f_command 	= 0x00F000F000F000F0ULL;
			ull_write(f_addr, &f_command);
			return ERR_TIMOUT;
		}
	} while(*((unsigned long long *)address) != data);

	return 0;
}
