/*
 * (C) Copyright 2001
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * (C) Copyright 2002
 * Gregory E. Allen, gallen@arlut.utexas.edu
 * Matthew E. Karger, karger@arlut.utexas.edu
 * Applied Research Laboratories, The University of Texas at Austin
 *
 * 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 <mpc824x.h>
#include <asm/processor.h>

#define ROM_CS0_START	0xFF800000
#define ROM_CS1_START	0xFF000000

#if defined(CFG_ENV_IS_IN_FLASH)
# ifndef  CFG_ENV_ADDR
#  define CFG_ENV_ADDR	(CFG_FLASH_BASE + CFG_ENV_OFFSET)
# endif
# ifndef  CFG_ENV_SIZE
#  define CFG_ENV_SIZE	CFG_ENV_SECT_SIZE
# endif
# ifndef  CFG_ENV_SECT_SIZE
#  define CFG_ENV_SECT_SIZE  CFG_ENV_SIZE
# endif
#endif

#define	FLASH_BANK_SIZE	0x200000
#define	MAIN_SECT_SIZE 	0x10000
#define	SECT_SIZE_32KB	0x8000
#define	SECT_SIZE_8KB	0x2000

flash_info_t    flash_info[CFG_MAX_FLASH_BANKS];

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

static __inline__ unsigned long get_msr(void)
{	unsigned long msr;
	__asm__ __volatile__ ("mfmsr %0" : "=r" (msr) :);
    return msr;
}

static __inline__ void set_msr(unsigned long msr)
{
    __asm__ __volatile__ ("mtmsr %0" : : "r" (msr));
}

/*flash command address offsets*/
#define ADDR0		(0x555)
#define ADDR1		(0xAAA)
#define ADDR3		(0x001)

#define FLASH_WORD_SIZE unsigned char

/*---------------------------------------------------------------------*/
/*#define	DEBUG_FLASH	1 */

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

unsigned long flash_init(void)
{
    int i, j;
    ulong size = 0;
	unsigned char manuf_id, device_id;

    for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
	{
    	vu_char *addr = (vu_char *)(CFG_FLASH_BASE + i * FLASH_BANK_SIZE);

	addr[0x555] = 0xAA;			/* 3 cycles to read device info.  See */
	addr[0x2AA] = 0x55;			/* AM29LV116D datasheet for list of */
	addr[0x555] = 0x90;			/* available commands. */

	manuf_id = addr[0];
	device_id = addr[1];

#if defined DEBUG_FLASH
	printf("manuf_id = %x, device_id = %x\n", manuf_id, device_id);
#endif

		if (  (manuf_id == (uchar)(AMD_MANUFACT)) &&
	    	( device_id == AMD_ID_LV116DT))
		{
	    	flash_info[i].flash_id = ((FLASH_MAN_AMD & FLASH_VENDMASK) << 16) |
	    			     (AMD_ID_LV116DT & FLASH_TYPEMASK);
		} else {
	    	flash_info[i].flash_id = FLASH_UNKNOWN;
	    	addr[0] = (long)0xFFFFFFFF;
	    	goto Done;
		}

#if defined DEBUG_FLASH
		printf ("flash_id = 0x%08lX\n", flash_info[i].flash_id);
#endif

		addr[0] = (long)0xFFFFFFFF;

		flash_info[i].size = FLASH_BANK_SIZE;
		flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
		memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);

		for (j = 0; j < flash_info[i].sector_count; j++)
		{

			if (j < (CFG_MAX_FLASH_SECT - 3) )

				flash_info[i].start[j] = CFG_FLASH_BASE + i * FLASH_BANK_SIZE +
			                       			j * MAIN_SECT_SIZE;

			else if (j == (CFG_MAX_FLASH_SECT - 3) )

				flash_info[i].start[j] =  flash_info[i].start[j-1] + SECT_SIZE_32KB;


			else

				flash_info[i].start[j] =  flash_info[i].start[j-1] + SECT_SIZE_8KB;

		}

	size += flash_info[i].size;
    }

    /* Protect monitor and environment sectors
     */
#if CFG_MONITOR_BASE >= CFG_FLASH_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)
    flash_protect(FLAG_PROTECT_SET, CFG_ENV_ADDR,
					CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
#endif

Done:
    return size;
}

/*-----------------------------------------------------------------------
 */
void flash_print_info(flash_info_t *info)
{
  static const char unk[] = "Unknown";
  const char *mfct = unk, *type = unk;
  unsigned int i;

  if(info->flash_id != FLASH_UNKNOWN)
  {
    switch(info->flash_id & FLASH_VENDMASK)
    {
      case FLASH_MAN_AMD:	mfct = "AMD";				break;
      case FLASH_MAN_FUJ:	mfct = "FUJITSU";			break;
      case FLASH_MAN_STM:	mfct = "STM";				break;
      case FLASH_MAN_SST:	mfct = "SST";				break;
      case FLASH_MAN_BM:	mfct = "Bright Microelectonics";	break;
      case FLASH_MAN_INTEL:	mfct = "Intel";				break;
    }

    switch(info->flash_id & FLASH_TYPEMASK)
    {
      case FLASH_AM040:		type = "AM29F040B (512K * 8, uniform sector size)";	break;
      case FLASH_AM400B:	type = "AM29LV400B (4 Mbit, bottom boot sect)";		break;
      case FLASH_AM400T:	type = "AM29LV400T (4 Mbit, top boot sector)";		break;
      case FLASH_AM800B:	type = "AM29LV800B (8 Mbit, bottom boot sect)";		break;
      case FLASH_AM800T:	type = "AM29LV800T (8 Mbit, top boot sector)";		break;
      case FLASH_AM160T:	type = "AM29LV160T (16 Mbit, top boot sector)";		break;
      case FLASH_AM320B:	type = "AM29LV320B (32 Mbit, bottom boot sect)";	break;
      case FLASH_AM320T:	type = "AM29LV320T (32 Mbit, top boot sector)";		break;
      case FLASH_STM800AB:	type = "M29W800AB (8 Mbit, bottom boot sect)";		break;
      case FLASH_SST800A:	type = "SST39LF/VF800 (8 Mbit, uniform sector size)";	break;
      case FLASH_SST160A:	type = "SST39LF/VF160 (16 Mbit, uniform sector size)";	break;
    }
  }

  printf(
    "\n  Brand: %s Type: %s\n"
    "  Size: %lu KB in %d Sectors\n",
    mfct,
    type,
    info->size >> 10,
    info->sector_count
  );

  printf ("  Sector Start Addresses:");

  for (i = 0; i < info->sector_count; i++)
  {
    unsigned long size;
    unsigned int erased;
    unsigned long * flash = (unsigned long *) info->start[i];

    /*
     * Check if whole sector is erased
     */
    size =
      (i != (info->sector_count - 1)) ?
      (info->start[i + 1] - info->start[i]) >> 2 :
      (info->start[0] + info->size - info->start[i]) >> 2;

    for(
      flash = (unsigned long *) info->start[i], erased = 1;
      (flash != (unsigned long *) info->start[i] + size) && erased;
      flash++
    )
      erased = *flash == ~0x0UL;

    printf(
      "%s %08lX %s %s",
      (i % 5) ? "" : "\n   ",
      info->start[i],
      erased ? "E" : " ",
      info->protect[i] ? "RO" : "  "
    );
  }

  puts("\n");
  return;
}

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

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

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

    if ((info->flash_id == FLASH_UNKNOWN) ||
        (info->flash_id > (FLASH_MAN_STM | FLASH_AMD_COMP))) {
        printf ("Can't erase unknown flash type - aborted\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;

    /* Check the ROM CS */
    if ((info->start[0] >= ROM_CS1_START) && (info->start[0] < ROM_CS0_START))
      sh8b = 3;
    else
      sh8b = 0;

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

    addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA;
    addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055;
    addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00800080;
    addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA;
    addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055;

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

			if (info->flash_id & FLASH_MAN_SST)
			{
				addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA;
				addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055;
 				addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00800080;
				addr[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA;
				addr[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055;
				addr[0] = (FLASH_WORD_SIZE)0x00500050;  /* block erase */
				udelay(30000);  /* wait 30 ms */
			}

			else
				addr[0] = (FLASH_WORD_SIZE)0x00300030;  /* sector erase */

			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 = (FLASH_WORD_SIZE *)(info->start[0] + (
			(info->start[l_sect] - info->start[0]) << sh8b));
    while ((addr[0] & (FLASH_WORD_SIZE)0x00800080) != (FLASH_WORD_SIZE)0x00800080) {
        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 = (FLASH_WORD_SIZE *)info->start[0];
    addr[0] = (FLASH_WORD_SIZE)0x00F000F0;  /* 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)
{
	volatile FLASH_WORD_SIZE *addr2 = (FLASH_WORD_SIZE *)info->start[0];
	volatile FLASH_WORD_SIZE *dest2;
	volatile FLASH_WORD_SIZE *data2 = (FLASH_WORD_SIZE *)&data;
	ulong start;
	int flag;
	int i;
	unsigned char sh8b;

    /* Check the ROM CS */
    if ((info->start[0] >= ROM_CS1_START) && (info->start[0] < ROM_CS0_START))
      sh8b = 3;
    else
      sh8b = 0;

    dest2 = (FLASH_WORD_SIZE *)(((dest - info->start[0]) << sh8b) +
				info->start[0]);

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

        for (i=0; i<4/sizeof(FLASH_WORD_SIZE); i++)
          {
            addr2[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00AA00AA;
            addr2[ADDR1 << sh8b] = (FLASH_WORD_SIZE)0x00550055;
            addr2[ADDR0 << sh8b] = (FLASH_WORD_SIZE)0x00A000A0;

            dest2[i << sh8b] = data2[i];

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

            /* data polling for D7 */
            start = get_timer (0);
            while ((dest2[i << sh8b] & (FLASH_WORD_SIZE)0x00800080) !=
                   (data2[i] & (FLASH_WORD_SIZE)0x00800080)) {
              if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
                return (1);
              }
            }
          }

    return (0);
}
/*-----------------------------------------------------------------------
 */
