/*
 * (C) Copyright 2001, 2002
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * (C) Copyright 2002
 * Frank Panno <fpanno@delphintech.com>, Delphin Technology AG
 *
 * Flash Routines for AMD device AM29DL323DB on the EP8260 board.
 *
 * This file is based on board/tqm8260/flash.c.
 *--------------------------------------------------------------------
 * 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>

#define V_ULONG(a)	(*(volatile unsigned long *)( a ))
#define V_BYTE(a)	(*(volatile unsigned char *)( a ))


flash_info_t flash_info[CFG_MAX_FLASH_BANKS];


/*-----------------------------------------------------------------------
 */
void flash_reset(void)
{
  if( flash_info[0].flash_id != FLASH_UNKNOWN ) {
    V_ULONG( flash_info[0].start[0] ) = 0x00F000F0;
    V_ULONG( flash_info[0].start[0] + 4 ) = 0x00F000F0;
  }
}

/*-----------------------------------------------------------------------
 */
ulong flash_get_size( ulong baseaddr, flash_info_t *info )
{
  short i;
  unsigned long flashtest_h, flashtest_l;

  /* Write auto select command sequence and test FLASH answer */
  V_ULONG(baseaddr + ((ulong)0x0555 << 3)) = 0x00AA00AA;
  V_ULONG(baseaddr + ((ulong)0x02AA << 3)) = 0x00550055;
  V_ULONG(baseaddr + ((ulong)0x0555 << 3)) = 0x00900090;
  V_ULONG(baseaddr + 4 + ((ulong)0x0555 << 3)) = 0x00AA00AA;
  V_ULONG(baseaddr + 4 + ((ulong)0x02AA << 3)) = 0x00550055;
  V_ULONG(baseaddr + 4 + ((ulong)0x0555 << 3)) = 0x00900090;

  flashtest_h = V_ULONG(baseaddr);		/* manufacturer ID	   */
  flashtest_l = V_ULONG(baseaddr + 4);

  if ((int)flashtest_h == AMD_MANUFACT) {
  	info->flash_id = FLASH_MAN_AMD;
  } else {
	info->flash_id = FLASH_UNKNOWN;
	info->sector_count = 0;
	info->size = 0;
	return (0);  				/* no or unknown flash	   */
  }

  flashtest_h = V_ULONG(baseaddr + 8);	        /* device ID		   */
  flashtest_l = V_ULONG(baseaddr + 12);
  if (flashtest_h != flashtest_l) {
    info->flash_id = FLASH_UNKNOWN;
    return(0);
  }
  if (flashtest_h == AMD_ID_DL323B) {
    info->flash_id += FLASH_AMDL323B;
    info->sector_count = 71;
    info->size = 0x01000000;	                /* 4 * 4 MB = 16 MB	*/
  } else {
    info->flash_id = FLASH_UNKNOWN;
    return(0);  			 	/* no or unknown flash	   */
  }

  /* set up sector start adress table (bottom sector type) */
  for (i = 0; i < 8; i++) {
    info->start[i] = baseaddr + (i * 0x00008000);
  }
  for (i = 8; i < info->sector_count; i++) {
    info->start[i] = baseaddr + (i * 0x00040000) - 0x001C0000;
  }

  /* check for protected sectors */
  for (i = 0; i < info->sector_count; i++) {
    /* read sector protection at sector address, (A7 .. A0) = 0x02 */
    if ((V_ULONG( info->start[i] + 16 ) & 0x00010001) ||
        (V_ULONG( info->start[i] + 20 ) & 0x00010001)) {
	info->protect[i] = 1;		/* D0 = 1 if protected */
    } else {
    	info->protect[i] = 0;
    }
  }

  flash_reset();
  return(info->size);
}

/*-----------------------------------------------------------------------
 */
unsigned long flash_init (void)
{
    unsigned long size_b0 = 0;
    int i;

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

    /* Static FLASH Bank configuration here (only one bank) */

    size_b0 = flash_get_size(CFG_FLASH0_BASE, &flash_info[0]);
    if (flash_info[0].flash_id == FLASH_UNKNOWN || size_b0 == 0) {
	printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
		size_b0, size_b0>>20);
    }

    /*
     * 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_b0);
}

/*-----------------------------------------------------------------------
 */
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) & 0xff) {
    case FLASH_MAN_AMD:	    printf ("AMD ");		    break;
    default:		    printf ("Unknown Vendor ");	    break;
    }

    switch (info->flash_id & FLASH_TYPEMASK) {
    case FLASH_AMDL323B:	printf ("29DL323B (32 M, bottom sector)\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, 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();

    V_ULONG( info->start[0] + (0x0555 << 3) ) = 0x00AA00AA;
    V_ULONG( info->start[0] + (0x02AA << 3) ) = 0x00550055;
    V_ULONG( info->start[0] + (0x0555 << 3) ) = 0x00800080;
    V_ULONG( info->start[0] + (0x0555 << 3) ) = 0x00AA00AA;
    V_ULONG( info->start[0] + (0x02AA << 3) ) = 0x00550055;
    V_ULONG( info->start[0] + 4 + (0x0555 << 3) ) = 0x00AA00AA;
    V_ULONG( info->start[0] + 4 + (0x02AA << 3) ) = 0x00550055;
    V_ULONG( info->start[0] + 4 + (0x0555 << 3) ) = 0x00800080;
    V_ULONG( info->start[0] + 4 + (0x0555 << 3) ) = 0x00AA00AA;
    V_ULONG( info->start[0] + 4 + (0x02AA << 3) ) = 0x00550055;
    udelay (1000);

    /* Start erase on unprotected sectors */
    for (sect = s_first; sect<=s_last; sect++) {
	if (info->protect[sect] == 0) {	/* not protected */
	    V_ULONG( info->start[sect] ) = 0x00300030;
	    V_ULONG( info->start[sect] + 4 ) = 0x00300030;
	    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;
    while ((V_ULONG( info->start[l_sect] ) & 0x00800080) != 0x00800080 ||
	   (V_ULONG( info->start[l_sect] + 4 ) & 0x00800080) != 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 */
    flash_reset ();

    printf (" done\n");
    return 0;
}

static int write_dword (flash_info_t *, ulong, unsigned char *);

/*-----------------------------------------------------------------------
 * 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 dp;
    static unsigned char bb[8];
    int i, l, rc, cc = cnt;

    dp = (addr & ~7);	/* get lower dword aligned address */

    /*
     * handle unaligned start bytes
     */
    if ((l = addr - dp) != 0) {
	for (i = 0; i < 8; i++)
	    bb[i] = (i < l || (i-l) >= cc) ? V_BYTE(dp+i) : *src++;
	if ((rc = write_dword(info, dp, bb)) != 0)
	{
	    return (rc);
	}
	dp += 8;
	cc -= 8 - l;
    }

    /*
     * handle word aligned part
     */
    while (cc >= 8) {
	if ((rc = write_dword(info, dp, src)) != 0) {
	    return (rc);
	}
	dp  += 8;
	src += 8;
	cc -= 8;
    }

    if (cc <= 0) {
	return (0);
    }

    /*
     * handle unaligned tail bytes
     */
    for (i = 0; i < 8; i++) {
	bb[i] = (i < cc) ? *src++ : V_BYTE(dp+i);
    }
    return (write_dword(info, dp, bb));
}

/*-----------------------------------------------------------------------
 * Write a dword to Flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
static int write_dword (flash_info_t *info, ulong dest, unsigned char * pdata)
{
    ulong start;
    ulong cl = 0, ch =0;
    int flag, i;

    for (ch=0, i=0; i < 4; i++)
	ch = (ch << 8) + *pdata++;	/* high word	*/
    for (cl=0, i=0; i < 4; i++)
	cl = (cl << 8) + *pdata++;	/* low word	*/

    /* Check if Flash is (sufficiently) erased */
    if ((*((vu_long *)dest) & ch)	!= ch
      ||(*((vu_long *)(dest + 4)) & cl)	!= cl)
    {
	return (2);
    }

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

    V_ULONG( info->start[0] + (0x0555 << 3) ) = 0x00AA00AA;
    V_ULONG( info->start[0] + (0x02AA << 3) ) = 0x00550055;
    V_ULONG( info->start[0] + (0x0555 << 3) ) = 0x00A000A0;
    V_ULONG( dest ) = ch;
    V_ULONG( info->start[0] + 4 + (0x0555 << 3) ) = 0x00AA00AA;
    V_ULONG( info->start[0] + 4 + (0x02AA << 3) ) = 0x00550055;
    V_ULONG( info->start[0] + 4 + (0x0555 << 3) ) = 0x00A000A0;
    V_ULONG( dest + 4 ) = cl;

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

    /* data polling for D7 */
    start = get_timer (0);
    while (((V_ULONG( dest ) & 0x00800080) != (ch & 0x00800080)) ||
           ((V_ULONG( dest + 4 ) & 0x00800080) != (cl & 0x00800080))) {
	if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
	    return (1);
	}
    }
    return (0);
}
