/*
 * (C) Copyright 2001
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 * Keith Outwater, keith_outwater@mvsi.com
 *
 * 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>

#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

/*
 * Use buffered writes to flash by default - they are about 32x faster than
 * single byte writes.
 */
#ifndef  CFG_GEN860T_FLASH_USE_WRITE_BUFFER
#define CFG_GEN860T_FLASH_USE_WRITE_BUFFER
#endif

/*
 * Max time to wait (in mS) for flash device to allocate a write buffer.
 */
#ifndef CFG_FLASH_ALLOC_BUFFER_TOUT
#define CFG_FLASH_ALLOC_BUFFER_TOUT		100
#endif

/*
 * These functions support a single Intel StrataFlash device (28F128J3A)
 * in byte mode only!.  The flash routines are very basic and simple
 * since there isn't really any remapping necessary.
 */

/*
 * Intel SCS (Scalable Command Set) command definitions
 * (taken from 28F128J3A datasheet)
 */
#define SCS_READ_CMD				0xff
#define SCS_READ_ID_CMD				0x90
#define SCS_QUERY_CMD				0x98
#define SCS_READ_STATUS_CMD			0x70
#define SCS_CLEAR_STATUS_CMD		0x50
#define SCS_WRITE_BUF_CMD			0xe8
#define SCS_PROGRAM_CMD				0x40
#define SCS_BLOCK_ERASE_CMD			0x20
#define SCS_BLOCK_ERASE_RESUME_CMD	0xd0
#define SCS_PROGRAM_RESUME_CMD		0xd0
#define SCS_BLOCK_ERASE_SUSPEND_CMD	0xb0
#define SCS_SET_BLOCK_LOCK_CMD		0x60
#define SCS_CLR_BLOCK_LOCK_CMD		0x60

/*
 * SCS status/extended status register bit definitions
 */
#define  SCS_SR7					0x80
#define  SCS_XSR7					0x80

/*---------------------------------------------------------------------*/
#if 0
#define DEBUG_FLASH
#endif

#ifdef DEBUG_FLASH
#define PRINTF(fmt,args...) printf(fmt ,##args)
#else
#define PRINTF(fmt,args...)
#endif
/*---------------------------------------------------------------------*/

flash_info_t	flash_info[CFG_MAX_FLASH_BANKS];

/*-----------------------------------------------------------------------
 * Functions
 */
static ulong flash_get_size (vu_char *addr, flash_info_t *info);
static int write_data8 (flash_info_t *info, ulong dest, uchar data);
static void flash_get_offsets (ulong base, flash_info_t *info);

/*-----------------------------------------------------------------------
 * Initialize the flash memory.
 */
unsigned long
flash_init (void)
{
	volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
	volatile memctl8xx_t *memctl = &immap->im_memctl;
	unsigned long size_b0;
	int i;

	for (i= 0; i < CFG_MAX_FLASH_BANKS; ++i) {
		flash_info[i].flash_id = FLASH_UNKNOWN;
	}

	/*
	 * The gen860t board only has one FLASH memory device, so the
	 * FLASH Bank configuration is done statically.
	 */
	PRINTF("\n## Get flash bank 1 size @ 0x%08x\n", FLASH_BASE0_PRELIM);
	size_b0 = flash_get_size((vu_char *)FLASH_BASE0_PRELIM, &flash_info[0]);
	if (flash_info[0].flash_id == FLASH_UNKNOWN) {
		printf ("## Unknown FLASH on Bank 0: "
				"ID 0x%lx, Size = 0x%08lx = %ld MB\n",
				flash_info[0].flash_id,size_b0, size_b0 << 20);
	}

	PRINTF("## Before remap:\n"
		   "  BR0: 0x%08x    OR0: 0x%08x\n  BR1: 0x%08x    OR1: 0x%08x\n",
		   memctl->memc_br0, memctl->memc_or0,
		   memctl->memc_br1, memctl->memc_or1);

	/*
	 * Remap FLASH according to real size
	 */
	memctl->memc_or0 |= (-size_b0 & 0xFFFF8000);
	memctl->memc_br0 |= (CFG_FLASH_BASE & BR_BA_MSK);

	PRINTF("## After remap:\n"
		   "  BR0: 0x%08x    OR0: 0x%08x\n", memctl->memc_br0, memctl->memc_or0);

	/*
	 * Re-do sizing to get full correct info
	 */
	size_b0 = flash_get_size ((vu_char *)CFG_FLASH_BASE, &flash_info[0]);
	flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
	flash_info[0].size = size_b0;

#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
	/*
	 * Monitor protection is ON by default
	 */
	flash_protect(FLAG_PROTECT_SET,
		      	  CFG_MONITOR_BASE,
		      	  CFG_MONITOR_BASE + monitor_flash_len - 1,
		      	  &flash_info[0]);
#endif

#ifdef	CFG_ENV_IS_IN_FLASH
	/*
	 * Environment protection ON by default
	 */
	flash_protect(FLAG_PROTECT_SET,
		      	  CFG_ENV_ADDR,
		      	  CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1,
		      	  &flash_info[0]);
#endif

	PRINTF("## Final Flash bank size: 0x%08lx\n",size_b0);
	return (size_b0);
}


/*-----------------------------------------------------------------------
 * Fill in the FLASH offset table
 */
static void
flash_get_offsets (ulong base, flash_info_t *info)
{
	int i;

	if (info->flash_id == FLASH_UNKNOWN) {
		return;
	}

	switch (info->flash_id & FLASH_VENDMASK) {
		case FLASH_MAN_INTEL:
	    	for (i = 0; i < info->sector_count; i++) {
				info->start[i] = base;
				base += 1024 * 128;
	    	}
	    	return;

		default:
	   		printf ("Don't know sector offsets for FLASH"
			        " type 0x%lx\n", info->flash_id);
	    return;
	}
}


/*-----------------------------------------------------------------------
 * Display FLASH device info
 */
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 FLASH_MAN_INTEL:
			printf ("Intel ");
			break;
	default:
			printf ("Unknown Vendor ");
			break;
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
	case FLASH_28F128J3A:
			printf ("28F128J3A (128Mbit = 128K x 128)\n");
			break;
	default:
			printf ("Unknown Chip Type\n");
			break;
	}

	if (info->size >= (1024 * 1024)) {
		i = 20;
	} else {
		i = 10;
	}
	printf ("  Size: %ld %cB in %d Sectors\n",
			info->size >> i,
			(i == 20) ? 'M' : 'k',
			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;
}


/*-----------------------------------------------------------------------
 * Get size and other information for a FLASH device.
 * NOTE: The following code cannot be run from FLASH!
 */
static
ulong flash_get_size (vu_char *addr, flash_info_t *info)
{
#define NO_FLASH	0

	vu_char value[2];

	/*
	 * Try to read the manufacturer ID
	 */
	addr[0] = SCS_READ_CMD;
	addr[0] = SCS_READ_ID_CMD;
	value[0] = addr[0];
	value[1] = addr[2];
	addr[0] = SCS_READ_CMD;

	PRINTF("Manuf. ID @ 0x%08lx: 0x%02x\n", (ulong)addr, value[0]);
	switch (value[0]) {
		case (INTEL_MANUFACT & 0xff):
			info->flash_id = FLASH_MAN_INTEL;
			break;
		default:
			info->flash_id = FLASH_UNKNOWN;
			info->sector_count = 0;
			info->size = 0;
			return (NO_FLASH);
	}

	/*
	 * Read the device ID
	 */
	PRINTF("Device ID @ 0x%08lx: 0x%02x\n", (ulong)(&addr[2]), value[1]);
	switch (value[1]) {
		case (INTEL_ID_28F128J3A & 0xff):
			info->flash_id += FLASH_28F128J3A;
			info->sector_count = 128;
			info->size = 16 * 1024 * 1024;
			break;

		default:
			info->flash_id = FLASH_UNKNOWN;
			return (NO_FLASH);
	}

	if (info->sector_count > CFG_MAX_FLASH_SECT) {
		printf ("** ERROR: sector count %d > max (%d) **\n",
				info->sector_count, CFG_MAX_FLASH_SECT);
				info->sector_count = CFG_MAX_FLASH_SECT;
	}
	return (info->size);
}


/*-----------------------------------------------------------------------
 * Erase the specified sectors in the specified FLASH device
 */
int
flash_erase(flash_info_t *info, int s_first, int s_last)
{
	int flag, prot, 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;
	}

	if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_INTEL) {
		printf ("Can erase only Intel flash types - 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");
	}

	start = get_timer (0);
	last  = start;

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

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

			*addr = SCS_CLEAR_STATUS_CMD;
			*addr = SCS_BLOCK_ERASE_CMD;
			*addr = SCS_BLOCK_ERASE_RESUME_CMD;

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

			/*
			 * Wait at least 80us - let's wait 1 ms
			 */
			udelay (1000);

			while (((status = *addr) & SCS_SR7) != SCS_SR7) {
				if ((now=get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
					printf ("Timeout\n");
					*addr = SCS_BLOCK_ERASE_SUSPEND_CMD;
					*addr = SCS_READ_CMD;
					return 1;
				}

				/*
				 * Show that we're waiting
				 */
				if ((now - last) > 1000) {	/* 1 second */
					putc ('.');
					last = now;
				}
			}
			*addr = SCS_READ_CMD;
		}
	}
	printf (" done\n");
	return 0;
}


#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
/*
 * Allocate a flash buffer, fill it with data and write it to the flash.
 * 0 - OK
 * 1 - Timeout on buffer request
 *
 * NOTE: After the last call to this function, WSM status needs to be checked!
 */
static int
write_flash_buffer8(flash_info_t *info_p, vu_char *src_p, vu_char *dest_p,
				    uint count)
{
	vu_char *block_addr_p = NULL;
	vu_char *start_addr_p = NULL;
	ulong blocksize = info_p->size / (ulong)info_p->sector_count;

	int i;
	uint time = get_timer(0);

	PRINTF("%s:%d: src: 0x%p dest: 0x%p  count: %d\n",
		   __FUNCTION__, __LINE__, src_p, dest_p, count);

	/*
	 * What block are we in? We already know that the source address is
	 * in the flash address range, but we also can't cross a block boundary.
	 * We assume that the block does not cross a boundary (we'll check before
	 * calling this function).
	 */
 	for (i = 0; i < info_p->sector_count; ++i) {
		if ( ((ulong)dest_p >= info_p->start[i]) &&
		    ((ulong)dest_p < (info_p->start[i] + blocksize)) ) {
			PRINTF("%s:%d: Dest addr 0x%p is in block %d @ 0x%.8lx\n",
				   __FUNCTION__, __LINE__, dest_p, i, info_p->start[i]);
			block_addr_p = (vu_char *)info_p->start[i];
			break;
		}
	}

	/*
	 * Request a buffer
	 */
	*block_addr_p = SCS_WRITE_BUF_CMD;
	while ((*block_addr_p & SCS_XSR7) != SCS_XSR7) {
		if (get_timer(time) >  CFG_FLASH_ALLOC_BUFFER_TOUT) {
			PRINTF("%s:%d: Buffer allocation timeout @ 0x%p (waited %d mS)\n",
				   __FUNCTION__, __LINE__, block_addr_p,
				   CFG_FLASH_ALLOC_BUFFER_TOUT);
			return 1;
		}
		*block_addr_p = SCS_WRITE_BUF_CMD;
	}

	/*
	 * Fill the buffer with data
	 */
	start_addr_p = dest_p;
	*block_addr_p = count - 1; /* flash device wants count - 1 */
	PRINTF("%s:%d: Fill buffer at block addr 0x%p\n",
		   __FUNCTION__, __LINE__, block_addr_p);
	for (i = 0; i < count; i++) {
		*start_addr_p++ = *src_p++;
	}

	/*
	 * Flush buffer to flash
	 */
	*block_addr_p = SCS_PROGRAM_RESUME_CMD;
#if 1
	time = get_timer(0);
	while ((*block_addr_p & SCS_SR7) != SCS_SR7) {
		if (get_timer(time) >  CFG_FLASH_WRITE_TOUT) {
			PRINTF("%s:%d: Write timeout @ 0x%p (waited %d mS)\n",
				   __FUNCTION__, __LINE__, block_addr_p, CFG_FLASH_WRITE_TOUT);
			return 1;
		}
	}

#endif
	return 0;
}
#endif


/*-----------------------------------------------------------------------
 * Copy memory to flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 * 4 - Flash not identified
 */
int
write_buff(flash_info_t *info_p, uchar *src_p, ulong addr, ulong count)
{
	int rc = 0;
#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
#define FLASH_WRITE_BUF_SIZE	0x00000020	/* 32 bytes */
	int i;
	uint bufs;
	ulong buf_count;
	vu_char *sp;
	vu_char *dp;
#else
	ulong wp;
#endif

	PRINTF("\n%s:%d: src: 0x%.8lx dest: 0x%.8lx size: %d (0x%.8lx)\n",
		   __FUNCTION__, __LINE__, (ulong)src_p, addr, (uint)count, count);

	if (info_p->flash_id == FLASH_UNKNOWN) {
		return 4;
	}

#ifdef CFG_GEN860T_FLASH_USE_WRITE_BUFFER
	sp = src_p;
	dp = (uchar *)addr;

	/*
	 * For maximum performance, we want to align the start address to
	 * the beginning of a write buffer boundary (i.e. A4-A0 of the
	 * start address = 0). See how many bytes are required to get to a
	 * write-buffer-aligned address.  If that number is non-zero, do
	 * non buffered writes of the non-aligned data.  By doing non-buffered
	 * writes, we avoid the problem of crossing a block (sector) boundary
	 * with buffered writes.
	 */
	buf_count = FLASH_WRITE_BUF_SIZE - (addr & (FLASH_WRITE_BUF_SIZE - 1));
	if (buf_count == FLASH_WRITE_BUF_SIZE) { /* already on a boundary */
		buf_count = 0;
	}
	if (buf_count > count) { /* not a full buffers worth of data to write */
		buf_count = count;
	}
	count -= buf_count;

	PRINTF("%s:%d: Write buffer alignment count = %ld\n",
		   __FUNCTION__, __LINE__, buf_count);
	while (buf_count-- >= 1) {
		if ((rc = write_data8(info_p, (ulong)dp++, *sp++)) != 0)  {
			return (rc);
		}
	}

	PRINTF("%s:%d: count = %ld\n", __FUNCTION__, __LINE__, count);
	if (count == 0) { /* all done */
		PRINTF("%s:%d: Less than 1 buffer (%d) worth of bytes\n",
			   __FUNCTION__, __LINE__, FLASH_WRITE_BUF_SIZE);
		return (rc);
	}

	/*
	 * Now that we are write buffer aligned, write full or partial buffers.
	 * The fact that we are write buffer aligned automatically avoids
	 * crossing a block address during a write buffer operation.
	 */
	bufs = count / FLASH_WRITE_BUF_SIZE;
	PRINTF("%s:%d: %d (0x%x) buffers to write\n", __FUNCTION__, __LINE__,
		   bufs, bufs);
	while (bufs >= 1) {
		rc = write_flash_buffer8(info_p, sp, dp, FLASH_WRITE_BUF_SIZE);
		if (rc != 0) {
			PRINTF("%s:%d: ** Error writing buf %d\n",
				   __FUNCTION__, __LINE__, bufs);
			return (rc);
		}
		bufs--;
		sp += FLASH_WRITE_BUF_SIZE;
		dp += FLASH_WRITE_BUF_SIZE;
	}

	/*
	 * Do the leftovers
	 */
	i = count % FLASH_WRITE_BUF_SIZE;
	PRINTF("%s:%d: %d (0x%x) leftover bytes\n", __FUNCTION__, __LINE__, i, i);
	if (i > 0) {
		rc = write_flash_buffer8(info_p, sp, dp, i);
	}

	sp = (vu_char*)info_p->start[0];
	*sp = SCS_READ_CMD;
	return (rc);

#else
	wp = addr;
	while (count-- >= 1) {
		if((rc = write_data8(info_p, wp++, *src_p++)) != 0)
			return (rc);
	}
	return 0;
#endif
}


/*-----------------------------------------------------------------------
 * Write a byte to Flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
static int
write_data8 (flash_info_t *info, ulong dest, uchar data)
{
	vu_char *addr = (vu_char *)dest;
	vu_char status;
	ulong start;
	int flag;

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

	*addr = SCS_PROGRAM_CMD;
	*addr = data;

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

	start = get_timer (0);

	while (((status = *addr) & SCS_SR7) != SCS_SR7) {
		if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
			*addr = SCS_READ_CMD;
			return (1);
		}
	}
	*addr = SCS_READ_CMD;
	return (0);
}

/* vim: set ts=4 sw=4 tw=78: */
