/*
 *
 * Copyright (c) 2004	Cucy Systems (http://www.cucy.com)
 * Curt Brune <curt@cucy.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 <asm/hardware.h>
#include <flash.h>

flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];

typedef enum {
	FLASH_DEV_U9_512KB = 0,
	FLASH_DEV_U7_2MB = 1
} FLASH_DEV;

#define FLASH_DQ7		(0x80)
#define FLASH_DQ5		(0x20)

#define PROG_ADDR		(0xAAA)
#define SETUP_ADDR		(0xAAA)
#define ID_ADDR			(0xAAA)
#define UNLOCK_ADDR1		(0xAAA)
#define UNLOCK_ADDR2		(0x555)

#define UNLOCK_CMD1		(0xAA)
#define UNLOCK_CMD2		(0x55)
#define ERASE_SUSPEND_CMD	(0xB0)
#define ERASE_RESUME_CMD	(0x30)
#define RESET_CMD		(0xF0)
#define ID_CMD			(0x90)
#define SELECT_CMD		(0x90)
#define CHIPERASE_CMD		(0x10)
#define BYPASS_CMD		(0x20)
#define SECERASE_CMD		(0x30)
#define PROG_CMD		(0xa0)
#define SETUP_CMD		(0x80)

#if 0
#define WRITE_UNLOCK(addr) { \
	PUT__U8( addr + UNLOCK_ADDR1, UNLOCK_CMD1); \
	PUT__U8( addr + UNLOCK_ADDR2, UNLOCK_CMD2); \
}

/* auto select command */
#define CMD_ID(addr) WRITE_UNLOCK(addr); { \
	PUT__U8( addr + ID_ADDR, ID_CMD); \
}

#define CMD_RESET(addr) WRITE_UNLOCK(addr); { \
	PUT__U8( addr + ID_ADDR, RESET_CMD); \
}

#define CMD_ERASE_SEC(base, addr) WRITE_UNLOCK(base); \
	PUT__U8( base + SETUP_ADDR, SETUP_CMD); \
	WRITE_UNLOCK(base); \
	PUT__U8( addr, SECERASE_CMD);

#define CMD_ERASE_CHIP(base) WRITE_UNLOCK(base); \
	PUT__U8( base + SETUP_ADDR, SETUP_CMD); \
	WRITE_UNLOCK(base); \
	PUT__U8( base + SETUP_ADDR, CHIPERASE_CMD);

/* prepare for bypass programming */
#define CMD_UNLOCK_BYPASS(addr) WRITE_UNLOCK(addr); { \
	PUT__U8( addr + ID_ADDR, 0x20); \
}

/* terminate bypass programming */
#define CMD_BYPASS_RESET(addr) { \
	PUT__U8(addr, 0x90); \
	PUT__U8(addr, 0x00); \
}
#endif

inline static void FLASH_CMD_UNLOCK (FLASH_DEV dev, u32 base)
{
	switch (dev) {
	case FLASH_DEV_U7_2MB:
		PUT__U8 (base + 0xAAA, 0xAA);
		PUT__U8 (base + 0x555, 0x55);
		break;
	case FLASH_DEV_U9_512KB:
		PUT__U8 (base + 0x555, 0xAA);
		PUT__U8 (base + 0x2AA, 0x55);
		break;
	}
}

inline static void FLASH_CMD_SELECT (FLASH_DEV dev, u32 base)
{
	switch (dev) {
	case FLASH_DEV_U7_2MB:
		FLASH_CMD_UNLOCK (dev, base);
		PUT__U8 (base + 0xAAA, SELECT_CMD);
		break;
	case FLASH_DEV_U9_512KB:
		FLASH_CMD_UNLOCK (dev, base);
		PUT__U8 (base + 0x555, SELECT_CMD);
		break;
	}
}

inline static void FLASH_CMD_RESET (FLASH_DEV dev, u32 base)
{
	switch (dev) {
	case FLASH_DEV_U7_2MB:
		FLASH_CMD_UNLOCK (dev, base);
		PUT__U8 (base + 0xAAA, RESET_CMD);
		break;
	case FLASH_DEV_U9_512KB:
		FLASH_CMD_UNLOCK (dev, base);
		PUT__U8 (base + 0x555, RESET_CMD);
		break;
	}
}

inline static void FLASH_CMD_ERASE_SEC (FLASH_DEV dev, u32 base, u32 addr)
{
	switch (dev) {
	case FLASH_DEV_U7_2MB:
		FLASH_CMD_UNLOCK (dev, base);
		PUT__U8 (base + 0xAAA, SETUP_CMD);
		FLASH_CMD_UNLOCK (dev, base);
		PUT__U8 (addr, SECERASE_CMD);
		break;
	case FLASH_DEV_U9_512KB:
		FLASH_CMD_UNLOCK (dev, base);
		PUT__U8 (base + 0x555, SETUP_CMD);
		FLASH_CMD_UNLOCK (dev, base);
		PUT__U8 (addr, SECERASE_CMD);
		break;
	}
}

inline static void FLASH_CMD_ERASE_CHIP (FLASH_DEV dev, u32 base)
{
	switch (dev) {
	case FLASH_DEV_U7_2MB:
		FLASH_CMD_UNLOCK (dev, base);
		PUT__U8 (base + 0xAAA, SETUP_CMD);
		FLASH_CMD_UNLOCK (dev, base);
		PUT__U8 (base, CHIPERASE_CMD);
		break;
	case FLASH_DEV_U9_512KB:
		FLASH_CMD_UNLOCK (dev, base);
		PUT__U8 (base + 0x555, SETUP_CMD);
		FLASH_CMD_UNLOCK (dev, base);
		PUT__U8 (base, CHIPERASE_CMD);
		break;
	}
}

inline static void FLASH_CMD_UNLOCK_BYPASS (FLASH_DEV dev, u32 base)
{
	switch (dev) {
	case FLASH_DEV_U7_2MB:
		FLASH_CMD_UNLOCK (dev, base);
		PUT__U8 (base + 0xAAA, BYPASS_CMD);
		break;
	case FLASH_DEV_U9_512KB:
		FLASH_CMD_UNLOCK (dev, base);
		PUT__U8 (base + 0x555, BYPASS_CMD);
		break;
	}
}

inline static void FLASH_CMD_BYPASS_RESET (FLASH_DEV dev, u32 base)
{
	PUT__U8 (base, SELECT_CMD);
	PUT__U8 (base, 0x0);
}

/* poll for flash command completion */
static u16 _flash_poll (FLASH_DEV dev, u32 addr, u16 data, ulong timeOut)
{
	u32 done = 0;
	ulong t0;

	u16 error = 0;
	volatile u16 flashData;

	data = data & 0xFF;
	t0 = get_timer (0);
	while (get_timer (t0) < timeOut) {
		/*	for( i = 0; i < POLL_LOOPS; i++) { */
		/*  Read the Data */
		flashData = GET__U8 (addr);

		/*  FLASH_DQ7 = Data? */
		if ((flashData & FLASH_DQ7) == (data & FLASH_DQ7)) {
			done = 1;
			break;
		}

		/*  Check Timeout (FLASH_DQ5==1) */
		if (flashData & FLASH_DQ5) {
			/*  Read the Data */
			flashData = GET__U8 (addr);

			/*  FLASH_DQ7 = Data? */
			if (!((flashData & FLASH_DQ7) == (data & FLASH_DQ7))) {
				printf ("_flash_poll(): FLASH_DQ7 & flashData not equal to write value\n");
				error = ERR_PROG_ERROR;
			}
			FLASH_CMD_RESET (dev, addr);
			done = 1;
			break;
		}
		/*  spin delay */
		udelay (10);
	}


	/*  error update */
	if (!done) {
		printf ("_flash_poll(): Timeout\n");
		error = ERR_TIMOUT;
	}

	/*  Check the data */
	if (!error) {
		/*  Read the Data */
		flashData = GET__U8 (addr);
		if (flashData != data) {
			error = ERR_PROG_ERROR;
			printf ("_flash_poll(): flashData(0x%04x) not equal to data(0x%04x)\n",
				flashData, data);
		}
	}

	return error;
}

/*-----------------------------------------------------------------------
 */
static int _flash_check_protection (flash_info_t * info, int s_first, int s_last)
{
	int sect, prot = 0;

	for (sect = s_first; sect <= s_last; sect++)
		if (info->protect[sect]) {
			printf ("  Flash sector %d protected.\n", sect);
			prot++;
		}
	return prot;
}

static int _detectFlash (FLASH_DEV dev, u32 base, u8 venId, u8 devId)
{

	u32 baseAddr = base | CACHE_DISABLE_MASK;
	u8 vendorId, deviceId;

	/*	printf(__FUNCTION__"(): detecting flash @ 0x%08x\n", base); */

	/* Send auto select command and read manufacturer info */
	FLASH_CMD_SELECT (dev, baseAddr);
	vendorId = GET__U8 (baseAddr);
	FLASH_CMD_RESET (dev, baseAddr);

	/* Send auto select command and read device info */
	FLASH_CMD_SELECT (dev, baseAddr);

	if (dev == FLASH_DEV_U7_2MB) {
		deviceId = GET__U8 (baseAddr + 2);
	} else if (dev == FLASH_DEV_U9_512KB) {
		deviceId = GET__U8 (baseAddr + 1);
	} else {
		return 0;
	}

	FLASH_CMD_RESET (dev, baseAddr);

	/* printf (__FUNCTION__"(): found vendorId 0x%04x, deviceId 0x%04x\n",
		vendorId, deviceId);
	 */

	return (vendorId == venId) && (deviceId == devId);

}

/******************************************************************************
 *
 * Public u-boot interface functions below
 *
 *****************************************************************************/

/***************************************************************************
 *
 * Flash initialization
 *
 * This board has two banks of flash, but the base addresses depend on
 * how the board is jumpered.
 *
 * The two flash types are:
 *
 *   AMD Am29LV160DB (2MB) sectors layout 16KB, 2x8KB, 32KB, 31x64KB
 *
 *   AMD Am29LV040B  (512KB)  sectors: 8x64KB
 *****************************************************************************/

unsigned long flash_init (void)
{
	flash_info_t *info;
	u16 i;
	u32 flashtest;
	s16 amd160 = -1;
	u32 amd160base = 0;

#if CONFIG_SYS_MAX_FLASH_BANKS == 2
	s16 amd040 = -1;
	u32 amd040base = 0;
#endif

	/* configure PHYS_FLASH_1 */
	if (_detectFlash (FLASH_DEV_U7_2MB, PHYS_FLASH_1, 0x1, 0x49)) {
		amd160 = 0;
		amd160base = PHYS_FLASH_1;
#if CONFIG_SYS_MAX_FLASH_BANKS == 1
	}
#else
		if (_detectFlash
		    (FLASH_DEV_U9_512KB, PHYS_FLASH_2, 0x1, 0x4F)) {
			amd040 = 1;
			amd040base = PHYS_FLASH_2;
		} else {
			printf (__FUNCTION__
				"(): Unable to detect PHYS_FLASH_2: 0x%08x\n",
				PHYS_FLASH_2);
		}
	} else if (_detectFlash (FLASH_DEV_U9_512KB, PHYS_FLASH_1, 0x1, 0x4F)) {
		amd040 = 0;
		amd040base = PHYS_FLASH_1;
		if (_detectFlash (FLASH_DEV_U7_2MB, PHYS_FLASH_2, 0x1, 0x49)) {
			amd160 = 1;
			amd160base = PHYS_FLASH_2;
		} else {
			printf (__FUNCTION__
				"(): Unable to detect PHYS_FLASH_2: 0x%08x\n",
				PHYS_FLASH_2);
		}
	}
#endif
	else {
		printf ("flash_init(): Unable to detect PHYS_FLASH_1: 0x%08x\n",
			PHYS_FLASH_1);
	}

	/* Configure AMD Am29LV160DB (2MB) */
	info = &flash_info[amd160];
	info->flash_id = FLASH_DEV_U7_2MB;
	info->sector_count = 35;
	info->size = 2 * 1024 * 1024;	/* 2MB */
	/* 1*16K Boot Block
	   2*8K Parameter Block
	   1*32K Small Main Block */
	info->start[0] = amd160base;
	info->start[1] = amd160base + 0x4000;
	info->start[2] = amd160base + 0x6000;
	info->start[3] = amd160base + 0x8000;
	for (i = 1; i < info->sector_count; i++)
		info->start[3 + i] = amd160base + i * (64 * 1024);

	for (i = 0; i < info->sector_count; i++) {
		/* Write auto select command sequence and query sector protection */
		FLASH_CMD_SELECT (info->flash_id,
				  info->start[i] | CACHE_DISABLE_MASK);
		flashtest =
			GET__U8 (((info->start[i] + 4) | CACHE_DISABLE_MASK));
		FLASH_CMD_RESET (info->flash_id,
				 amd160base | CACHE_DISABLE_MASK);
		info->protect[i] = (flashtest & 0x0001);
	}

	/*
	 * protect monitor and environment sectors in 2MB flash
	 */
	flash_protect (FLAG_PROTECT_SET,
		       amd160base, amd160base + monitor_flash_len - 1, info);

	flash_protect (FLAG_PROTECT_SET,
		       CONFIG_ENV_ADDR, CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, info);

#if CONFIG_SYS_MAX_FLASH_BANKS == 2
	/* Configure AMD Am29LV040B (512KB) */
	info = &flash_info[amd040];
	info->flash_id = FLASH_DEV_U9_512KB;
	info->sector_count = 8;
	info->size = 512 * 1024;	/* 512KB, 8 x 64KB */
	for (i = 0; i < info->sector_count; i++) {
		info->start[i] = amd040base + i * (64 * 1024);
		/* Write auto select command sequence and query sector protection */
		FLASH_CMD_SELECT (info->flash_id,
				  info->start[i] | CACHE_DISABLE_MASK);
		flashtest =
			GET__U8 (((info->start[i] + 2) | CACHE_DISABLE_MASK));
		FLASH_CMD_RESET (info->flash_id,
				 amd040base | CACHE_DISABLE_MASK);
		info->protect[i] = (flashtest & 0x0001);
	}
#endif

	return flash_info[0].size
#if CONFIG_SYS_MAX_FLASH_BANKS == 2
		+ flash_info[1].size
#endif
		;
}

void flash_print_info (flash_info_t * info)
{
	int i;

	if (info->flash_id == FLASH_DEV_U7_2MB) {
		printf ("AMD Am29LV160DB (2MB) 16KB,2x8KB,32KB,31x64KB\n");
	} else if (info->flash_id == FLASH_DEV_U9_512KB) {
		printf ("AMD Am29LV040B	 (512KB) 8x64KB\n");
	} else {
		printf ("Unknown flash_id ...\n");
		return;
	}

	printf ("  Size: %ld KB in %d Sectors\n",
		info->size >> 10, info->sector_count);
	printf ("  Sector Start Addresses:");
	for (i = 0; i < info->sector_count; i++) {
		if ((i % 4) == 0)
			printf ("\n   ");
		printf (" S%02d @ 0x%08lX%s", i,
			info->start[i], info->protect[i] ? " !" : "  ");
	}
	printf ("\n");
}

int flash_erase (flash_info_t * info, int s_first, int s_last)
{
	u16 i, error = 0;

	printf ("\n");

	/* check flash protection bits */
	if (_flash_check_protection (info, s_first, s_last)) {
		printf ("  Flash erase aborted due to protected sectors\n");
		return ERR_PROTECTED;
	}

	if ((s_first < info->sector_count) && (s_first <= s_last)) {
		for (i = s_first; i <= s_last && !error; i++) {
			printf ("  Erasing Sector %d @ 0x%08lx ... ", i,
				info->start[i]);
			/* bypass the cache to access the flash memory */
			FLASH_CMD_ERASE_SEC (info->flash_id,
					     (info->
					      start[0] | CACHE_DISABLE_MASK),
					     (info->
					      start[i] | CACHE_DISABLE_MASK));
			/* look for sector to become 0xFF after erase */
			error = _flash_poll (info->flash_id,
					     info->
					     start[i] | CACHE_DISABLE_MASK,
					     0xFF, CONFIG_SYS_FLASH_ERASE_TOUT);
			FLASH_CMD_RESET (info->flash_id,
					 (info->
					  start[0] | CACHE_DISABLE_MASK));
			printf ("done\n");
			if (error) {
				break;
			}
		}
	} else
		error = ERR_INVAL;

	return error;
}

int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
	u16 error = 0, i;
	u32 n;
	u8 *bp, *bps;

	/*  Write Setup */
	/* bypass the cache to access the flash memory */
	FLASH_CMD_UNLOCK_BYPASS (info->flash_id,
				 (info->start[0] | CACHE_DISABLE_MASK));

	/*  Write the Data to Flash */

	bp = (u8 *) (addr | CACHE_DISABLE_MASK);
	bps = (u8 *) src;

	for (n = 0; n < cnt && !error; n++, bp++, bps++) {

		if (!(n % (cnt / 15))) {
			printf (".");
		}

		/*  write the flash command for flash memory */
		*bp = 0xA0;

		/*  Write the data */
		*bp = *bps;

		/*  Check if the write is done */
		for (i = 0; i < 0xff; i++);
		error = _flash_poll (info->flash_id, (u32) bp, *bps,
				     CONFIG_SYS_FLASH_WRITE_TOUT);
		if (error) {
			return error;
		}
	}

	/*  Reset the Flash Mode to read */
	FLASH_CMD_BYPASS_RESET (info->flash_id, info->start[0]);

	printf (" ");

	return error;
}
