/*
 * (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 AMD 29F080B devices
 * Added support for 64bit and AMD 29DL323B
 *
 *--------------------------------------------------------------------
 * 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 <asm/io.h>

flash_info_t flash_info[CFG_MAX_FLASH_BANKS];

#define RD_SWP32(x) in_le32((volatile u32*)x)

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

static ulong flash_get_size (vu_long *addr, flash_info_t *info);
static int write_word (flash_info_t *info, ulong dest, ulong data);

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

unsigned long flash_init (void)
{
    unsigned long size;
    int i;

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

    /* for now, only support the 4 MB Flash SIMM */
    size = flash_get_size((vu_long *)CFG_FLASH0_BASE, &flash_info[0]);

    /*
     * protect monitor and environment sectors
     */

#if CFG_MONITOR_BASE >= CFG_FLASH0_BASE
    flash_protect(FLAG_PROTECT_SET,
		  CFG_MONITOR_BASE,
		  CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
		  &flash_info[0]);
#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]);
#endif

    return /*size*/ (CFG_FLASH0_SIZE * 1024 * 1024);
}

/*-----------------------------------------------------------------------
 */
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 (AMD_MANUFACT & FLASH_VENDMASK):
	printf ("AMD ");
	break;
    case (FUJ_MANUFACT & FLASH_VENDMASK):
	printf ("FUJITSU ");
	break;
    case (SST_MANUFACT & FLASH_VENDMASK):
	printf ("SST ");
	break;
    default:
	printf ("Unknown Vendor ");
	break;
    }

    switch (info->flash_id & FLASH_TYPEMASK) {
    case (AMD_ID_DL323B & FLASH_TYPEMASK):
	printf("AM29DL323B (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;
}

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

static ulong flash_get_size (vu_long *addr, flash_info_t *info)
{
    short i;
    vu_long vendor[2], devid[2];
    ulong base = (ulong)addr;

    /* Reset and Write auto select command: read Manufacturer ID */
    addr[0] = 0xf0f0f0f0;
    addr[2 * 0x0555] = 0xAAAAAAAA;
    addr[2 * 0x02AA] = 0x55555555;
    addr[2 * 0x0555] = 0x90909090;
    addr[1] = 0xf0f0f0f0;
    addr[2 * 0x0555 + 1] = 0xAAAAAAAA;
    addr[2 * 0x02AA + 1] = 0x55555555;
    addr[2 * 0x0555 + 1] = 0x90909090;
    udelay (1000);

    vendor[0] = RD_SWP32(&addr[0]);
    vendor[1] = RD_SWP32(&addr[1]);
    if (vendor[0] != vendor[1] || vendor[0] != AMD_MANUFACT) {
	info->size = 0;
	goto out;
    }

    devid[0] = RD_SWP32(&addr[2]);
    devid[1] = RD_SWP32(&addr[3]);

    if (devid[0] == AMD_ID_DL323B) {
	/*
	* we have 2 Banks
	* Bank 1 (23 Sectors): 0-7=8kbyte, 8-22=64kbyte
	* Bank 2 (48 Sectors): 23-70=64kbyte
	*/
	info->flash_id     = (AMD_MANUFACT & FLASH_VENDMASK) |
                             (AMD_ID_DL323B & FLASH_TYPEMASK);
	info->sector_count = 71;
	info->size         = 4 * (8 * 8 + 63 * 64) * 1024;
    }
    else {
	info->size = 0;
	goto out;
    }

    /* set up sector start address table */
    for (i = 0; i < 8; i++) {
        info->start[i] = base + (i * 0x8000);
    }
    for (i = 8; i < info->sector_count; i++) {
        info->start[i] = base + (i * 0x40000) + 8 * 0x8000 - 8 * 0x40000;
    }

    /* check for protected sectors */
    for (i = 0; i < info->sector_count; i++) {
        /* read sector protection at sector address */
	addr = (volatile unsigned long *)(info->start[i]);
        addr[2 * 0x0555] = 0xAAAAAAAA;
	addr[2 * 0x02AA] = 0x55555555;
	addr[2 * 0x0555] = 0x90909090;
	addr[2 * 0x0555 + 1] = 0xAAAAAAAA;
	addr[2 * 0x02AA + 1] = 0x55555555;
	addr[2 * 0x0555 + 1] = 0x90909090;
	udelay (1000);
    	base = RD_SWP32(&addr[4]);
	base |= RD_SWP32(&addr[5]);
	info->protect[i] = base & 0x00010001 ? 1 : 0;
    }
    addr = (vu_long*)info->start[0];

out:
    /* reset command */
    addr[0] = 0xf0f0f0f0;
    addr[1] = 0xf0f0f0f0;

    return info->size;
}


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

int flash_erase (flash_info_t *info, int s_first, int s_last)
{
    vu_long *addr = (vu_long*)(info->start[0]);
    int flag, prot, sect, l_sect;
    ulong start, now, last;

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

    l_sect = -1;

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

    addr[2 * 0x0555] = 0xAAAAAAAA;
    addr[2 * 0x02AA] = 0x55555555;
    addr[2 * 0x0555] = 0x80808080;
    addr[2 * 0x0555] = 0xAAAAAAAA;
    addr[2 * 0x02AA] = 0x55555555;
    addr[2 * 0x0555 + 1] = 0xAAAAAAAA;
    addr[2 * 0x02AA + 1] = 0x55555555;
    addr[2 * 0x0555 + 1] = 0x80808080;
    addr[2 * 0x0555 + 1] = 0xAAAAAAAA;
    addr[2 * 0x02AA + 1] = 0x55555555;
    udelay (100);

    /* Start erase on unprotected sectors */
    for (sect = s_first; sect<=s_last; sect++) {
	if (info->protect[sect] == 0) {	/* not protected */
	    addr = (vu_long*)(info->start[sect]);
	    addr[0] = 0x30303030;
	    addr[1] = 0x30303030;
	    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 = (vu_long*)(info->start[l_sect]);
    while (	(addr[0] & 0x80808080) != 0x80808080 ||
		(addr[1] & 0x80808080) != 0x80808080) {
	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 = (volatile unsigned long *)info->start[0];
    addr[0] = 0xF0F0F0F0;	/* reset bank */
    addr[1] = 0xF0F0F0F0;	/* 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)
{
    vu_long *addr = (vu_long*)(info->start[0]);
    ulong start;
    int flag;

    /* Check if Flash is (sufficiently) erased */
    if ((*((vu_long *)dest) & data) != data) {
	return (2);
    }
    /* Disable interrupts which might cause a timeout here */
    flag = disable_interrupts();

    if ((dest & 0x00000004) == 0) {
        addr[2 * 0x0555] = 0xAAAAAAAA;
	addr[2 * 0x02AA] = 0x55555555;
        addr[2 * 0x0555] = 0xA0A0A0A0;
    }
    else {
        addr[2 * 0x0555 + 1] = 0xAAAAAAAA;
	addr[2 * 0x02AA + 1] = 0x55555555;
        addr[2 * 0x0555 + 1] = 0xA0A0A0A0;
    }

    *((vu_long *)dest) = data;

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

    /* data polling for D7 */
    start = get_timer (0);
    while ((*((vu_long *)dest) & 0x80808080) != (data & 0x80808080)) {
	if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
	    return (1);
	}
    }
    return (0);
}

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