/*
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Alex Zuepke <azu@sysgo.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>

ulong myflush(void);


#define FLASH_BANK_SIZE 0x400000	/* 4 MB */
#define MAIN_SECT_SIZE  0x20000		/* 128 KB */

flash_info_t    flash_info[CONFIG_SYS_MAX_FLASH_BANKS];


#define CMD_READ_ARRAY		0x00F000F0
#define CMD_UNLOCK1		0x00AA00AA
#define CMD_UNLOCK2		0x00550055
#define CMD_ERASE_SETUP		0x00800080
#define CMD_ERASE_CONFIRM	0x00300030
#define CMD_PROGRAM		0x00A000A0
#define CMD_UNLOCK_BYPASS	0x00200020

#define MEM_FLASH_ADDR1		(*(volatile u32 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 << 2)))
#define MEM_FLASH_ADDR2		(*(volatile u32 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA << 2)))

#define BIT_ERASE_DONE		0x00800080
#define BIT_RDY_MASK		0x00800080
#define BIT_PROGRAM_ERROR	0x00200020
#define BIT_TIMEOUT		0x80000000 /* our flag */

#define READY 1
#define ERR   2
#define TMO   4

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

ulong flash_init(void)
{
    int i, j;
    ulong size = 0;

    for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++)
    {
	ulong flashbase = 0;
	flash_info[i].flash_id =
	  (AMD_MANUFACT & FLASH_VENDMASK) |
	  (AMD_ID_LV160B & FLASH_TYPEMASK);
	flash_info[i].size = FLASH_BANK_SIZE;
	flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;
	memset(flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);
	if (i == 0)
	  flashbase = PHYS_FLASH_1;
	else
	  panic("configured too many flash banks!\n");
	for (j = 0; j < flash_info[i].sector_count; j++)
	{

	    if (j <= 3)
	    {
		/* 1st one is 32 KB */
		if (j == 0)
		{
			flash_info[i].start[j] = flashbase + 0;
		}

		/* 2nd and 3rd are both 16 KB */
		if ((j == 1) || (j == 2))
		{
			flash_info[i].start[j] = flashbase + 0x8000 + (j-1)*0x4000;
		}

		/* 4th 64 KB */
		if (j == 3)
		{
			flash_info[i].start[j] = flashbase + 0x10000;
		}
	    }
	    else
	    {
		flash_info[i].start[j] = flashbase + (j - 3)*MAIN_SECT_SIZE;
	    }
	}
	size += flash_info[i].size;
    }

    /*
     * Protect monitor and environment sectors
     * Inferno is complicated, it's hardware locked
     */
#ifdef CONFIG_INFERNO
    /* first one, 0x00000 to 0x07fff */
    flash_protect(FLAG_PROTECT_SET,
		  CONFIG_SYS_FLASH_BASE + 0x00000,
		  CONFIG_SYS_FLASH_BASE + 0x08000 - 1,
		  &flash_info[0]);

    /* third to 10th, 0x0c000 - 0xdffff */
    flash_protect(FLAG_PROTECT_SET,
		  CONFIG_SYS_FLASH_BASE + 0x0c000,
		  CONFIG_SYS_FLASH_BASE + 0xe0000 - 1,
		  &flash_info[0]);
#else
    flash_protect(FLAG_PROTECT_SET,
		  CONFIG_SYS_FLASH_BASE,
		  CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1,
		  &flash_info[0]);

    flash_protect(FLAG_PROTECT_SET,
		  CONFIG_ENV_ADDR,
		  CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1,
		  &flash_info[0]);
#endif
    return size;
}

/*-----------------------------------------------------------------------
 */
void flash_print_info  (flash_info_t *info)
{
    int i;

    switch (info->flash_id & FLASH_VENDMASK)
    {
    case (AMD_MANUFACT & FLASH_VENDMASK):
	printf("AMD: ");
	break;
    default:
	printf("Unknown Vendor ");
	break;
    }

    switch (info->flash_id & FLASH_TYPEMASK)
    {
    case (AMD_ID_LV160B & FLASH_TYPEMASK):
	printf("2x Amd29F160BB (16Mbit)\n");
	break;
    default:
	printf("Unknown Chip Type\n");
	goto Done;
	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");

Done:
    ;
}

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

int	flash_erase (flash_info_t *info, int s_first, int s_last)
{
    ulong result;
    int iflag, cflag, prot, sect;
    int rc = ERR_OK;
    int chip1, chip2;
    ulong start;

    /* first look for protection bits */

    if (info->flash_id == FLASH_UNKNOWN)
	return ERR_UNKNOWN_FLASH_TYPE;

    if ((s_first < 0) || (s_first > s_last)) {
	return ERR_INVAL;
    }

    if ((info->flash_id & FLASH_VENDMASK) !=
	(AMD_MANUFACT & FLASH_VENDMASK)) {
	return ERR_UNKNOWN_FLASH_VENDOR;
    }

    prot = 0;
    for (sect=s_first; sect<=s_last; ++sect) {
	if (info->protect[sect]) {
	    prot++;
	}
    }
    if (prot)
	return ERR_PROTECTED;

    /*
     * Disable interrupts which might cause a timeout
     * here. Remember that our exception vectors are
     * at address 0 in the flash, and we don't want a
     * (ticker) exception to happen while the flash
     * chip is in programming mode.
     */
    cflag = icache_status();
    icache_disable();
    iflag = disable_interrupts();

    /* Start erase on unprotected sectors */
    for (sect = s_first; sect<=s_last && !ctrlc(); sect++)
    {
	printf("Erasing sector %2d ... ", sect);

	/* arm simple, non interrupt dependent timer */
	start = get_timer(0);

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

	    MEM_FLASH_ADDR1 = CMD_UNLOCK1;
	    MEM_FLASH_ADDR2 = CMD_UNLOCK2;
	    MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;

	    MEM_FLASH_ADDR1 = CMD_UNLOCK1;
	    MEM_FLASH_ADDR2 = CMD_UNLOCK2;
	    *addr = CMD_ERASE_CONFIRM;

	    /* wait until flash is ready */
	    chip1 = chip2 = 0;

	    do
	    {
		result = *addr;

		/* check timeout */
		if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT)
		{
		    MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
		    chip1 = TMO;
		    break;
		}

		if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE)
			chip1 = READY;

		if (!chip1 && (result & 0xFFFF) & BIT_PROGRAM_ERROR)
			chip1 = ERR;

		if (!chip2 && (result >> 16) & BIT_ERASE_DONE)
			chip2 = READY;

		if (!chip2 && (result >> 16) & BIT_PROGRAM_ERROR)
			chip2 = ERR;

	    }  while (!chip1 || !chip2);

	    MEM_FLASH_ADDR1 = CMD_READ_ARRAY;

	    if (chip1 == ERR || chip2 == ERR)
	    {
		rc = ERR_PROG_ERROR;
		goto outahere;
	    }
	    if (chip1 == TMO)
	    {
		rc = ERR_TIMOUT;
		goto outahere;
	    }

	    printf("ok.\n");
	}
	else /* it was protected */
	{
	    printf("protected!\n");
	}
    }

    if (ctrlc())
      printf("User Interrupt!\n");

outahere:
    /* allow flash to settle - wait 10 ms */
    udelay_masked(10000);

    if (iflag)
      enable_interrupts();

    if (cflag)
      icache_enable();

    return rc;
}

/*-----------------------------------------------------------------------
 * Copy memory to flash
 */

static int write_word (flash_info_t *info, ulong dest, ulong data)
{
    vu_long *addr = (vu_long *)dest;
    ulong result;
    int rc = ERR_OK;
    int cflag, iflag;
    int chip1, chip2;
    ulong start;

    /*
     * Check if Flash is (sufficiently) erased
     */
    result = *addr;
    if ((result & data) != data)
	return ERR_NOT_ERASED;


    /*
     * Disable interrupts which might cause a timeout
     * here. Remember that our exception vectors are
     * at address 0 in the flash, and we don't want a
     * (ticker) exception to happen while the flash
     * chip is in programming mode.
     */
    cflag = icache_status();
    icache_disable();
    iflag = disable_interrupts();

    MEM_FLASH_ADDR1 = CMD_UNLOCK1;
    MEM_FLASH_ADDR2 = CMD_UNLOCK2;
    MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;
    *addr = CMD_PROGRAM;
    *addr = data;

    /* arm simple, non interrupt dependent timer */
    start = get_timer(0);

    /* wait until flash is ready */
    chip1 = chip2 = 0;
    do
    {
	result = *addr;

	/* check timeout */
	if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT)
	{
	    chip1 = ERR | TMO;
	    break;
	}
	if (!chip1 && ((result & 0x80) == (data & 0x80)))
		chip1 = READY;

	if (!chip1 && ((result & 0xFFFF) & BIT_PROGRAM_ERROR))
	{
		result = *addr;

		if ((result & 0x80) == (data & 0x80))
			chip1 = READY;
		else
			chip1 = ERR;
	}

	if (!chip2 && ((result & (0x80 << 16)) == (data & (0x80 << 16))))
		chip2 = READY;

	if (!chip2 && ((result >> 16) & BIT_PROGRAM_ERROR))
	{
		result = *addr;

		if ((result & (0x80 << 16)) == (data & (0x80 << 16)))
			chip2 = READY;
		else
			chip2 = ERR;
	}

    }  while (!chip1 || !chip2);

    *addr = CMD_READ_ARRAY;

    if (chip1 == ERR || chip2 == ERR || *addr != data)
	rc = ERR_PROG_ERROR;

    if (iflag)
      enable_interrupts();

    if (cflag)
      icache_enable();

    return rc;
}

/*-----------------------------------------------------------------------
 * Copy memory to flash.
 */

int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
    ulong cp, wp, data;
    int l;
    int i, 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 << 24);
	}
	for (; i<4 && cnt>0; ++i) {
	    data = (data >> 8) | (*src++ << 24);
	    --cnt;
	    ++cp;
	}
	for (; cnt==0 && i<4; ++i, ++cp) {
	    data = (data >> 8) | (*(uchar *)cp << 24);
	}

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

    /*
     * handle word aligned part
     */
    while (cnt >= 4) {
	data = *((vu_long*)src);
	if ((rc = write_word(info, wp, data)) != 0) {
	    return (rc);
	}
	src += 4;
	wp  += 4;
	cnt -= 4;
    }

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

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

    return write_word(info, wp, data);
}
