/*
 * (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+CFG_MONITOR_LEN-1,
		      &flash_info[0]);
	flash_protect(FLAG_PROTECT_SET,
		      CFG_MONITOR_BASE,
		      CFG_MONITOR_BASE+CFG_MONITOR_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;
}
