/*
 * (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;

    /* 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 */
	reset_timer_masked();

	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_masked() > 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;

    /*
     * 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 */
    reset_timer_masked();

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

	/* check timeout */
	if (get_timer_masked() > 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);
}
