/*
 * (C) Copyright 2002
 * Lineo, Inc. <www.lineo.com>
 * Bernhard Kuhn <bkuhn@lineo.com>
 *
 * (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);


/* Flash Organization Structure */
typedef struct OrgDef
{
	unsigned int sector_number;
	unsigned int sector_size;
} OrgDef;


/* Flash Organizations */
OrgDef OrgAT49BV16x4[] =
{
	{  8,  8*1024 },	/*   8 *  8 kBytes sectors */
	{  2, 32*1024 },	/*   2 * 32 kBytes sectors */
	{ 30, 64*1024 },	/*  30 * 64 kBytes sectors */
};

OrgDef OrgAT49BV16x4A[] =
{
	{  8,  8*1024 },	/*   8 *  8 kBytes sectors */
	{ 31, 64*1024 },	/*  31 * 64 kBytes sectors */
};

OrgDef OrgAT49BV6416[] =
{
	{   8,  8*1024 },	/*   8 *  8 kBytes sectors */
	{ 127, 64*1024 },	/* 127 * 64 kBytes sectors */
};

flash_info_t    flash_info[CONFIG_SYS_MAX_FLASH_BANKS];

/* AT49BV1614A Codes */
#define FLASH_CODE1		0xAA
#define FLASH_CODE2		0x55
#define ID_IN_CODE		0x90
#define ID_OUT_CODE		0xF0


#define CMD_READ_ARRAY		0x00F0
#define CMD_UNLOCK1		0x00AA
#define CMD_UNLOCK2		0x0055
#define CMD_ERASE_SETUP		0x0080
#define CMD_ERASE_CONFIRM	0x0030
#define CMD_PROGRAM		0x00A0
#define CMD_UNLOCK_BYPASS	0x0020
#define CMD_SECTOR_UNLOCK	0x0070

#define MEM_FLASH_ADDR1		(*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00005555<<1)))
#define MEM_FLASH_ADDR2		(*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00002AAA<<1)))

#define BIT_ERASE_DONE		0x0080
#define BIT_RDY_MASK		0x0080
#define BIT_PROGRAM_ERROR	0x0020
#define BIT_TIMEOUT		0x80000000 /* our flag */

#define READY 1
#define ERR   2
#define TMO   4

/*-----------------------------------------------------------------------
 */
void flash_identification (flash_info_t * info)
{
	volatile u16 manuf_code, device_code, add_device_code;

	MEM_FLASH_ADDR1 = FLASH_CODE1;
	MEM_FLASH_ADDR2 = FLASH_CODE2;
	MEM_FLASH_ADDR1 = ID_IN_CODE;

	manuf_code = *(volatile u16 *) CONFIG_SYS_FLASH_BASE;
	device_code = *(volatile u16 *) (CONFIG_SYS_FLASH_BASE + 2);
	add_device_code = *(volatile u16 *) (CONFIG_SYS_FLASH_BASE + (3 << 1));

	MEM_FLASH_ADDR1 = FLASH_CODE1;
	MEM_FLASH_ADDR2 = FLASH_CODE2;
	MEM_FLASH_ADDR1 = ID_OUT_CODE;

	/* Vendor type */
	info->flash_id = ATM_MANUFACT & FLASH_VENDMASK;
	printf ("Atmel: ");

	if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV1614 & FLASH_TYPEMASK)) {

		if ((add_device_code & FLASH_TYPEMASK) ==
			(ATM_ID_BV1614A & FLASH_TYPEMASK)) {
			info->flash_id |= ATM_ID_BV1614A & FLASH_TYPEMASK;
			printf ("AT49BV1614A (16Mbit)\n");
		} else {				/* AT49BV1614 Flash */
			info->flash_id |= ATM_ID_BV1614 & FLASH_TYPEMASK;
			printf ("AT49BV1614 (16Mbit)\n");
		}

	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV6416 & FLASH_TYPEMASK)) {
		info->flash_id |= ATM_ID_BV6416 & FLASH_TYPEMASK;
		printf ("AT49BV6416 (64Mbit)\n");
	}
}

ushort flash_number_sector(OrgDef *pOrgDef, unsigned int nb_blocks)
{
	int i, nb_sectors = 0;

	for (i=0; i<nb_blocks; i++){
		nb_sectors += pOrgDef[i].sector_number;
	}

	return nb_sectors;
}

void flash_unlock_sector(flash_info_t * info, unsigned int sector)
{
	volatile u16 *addr = (volatile u16 *) (info->start[sector]);

	MEM_FLASH_ADDR1 = CMD_UNLOCK1;
	*addr = CMD_SECTOR_UNLOCK;
}


ulong flash_init (void)
{
	int i, j, k;
	unsigned int flash_nb_blocks, sector;
	unsigned int start_address;
	OrgDef *pOrgDef;

	ulong size = 0;

	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
		ulong flashbase = 0;

		flash_identification (&flash_info[i]);

		if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
			(ATM_ID_BV1614 & FLASH_TYPEMASK)) {

			pOrgDef = OrgAT49BV16x4;
			flash_nb_blocks = sizeof (OrgAT49BV16x4) / sizeof (OrgDef);
		} else if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
			(ATM_ID_BV1614A & FLASH_TYPEMASK)){	/* AT49BV1614A Flash */

			pOrgDef = OrgAT49BV16x4A;
			flash_nb_blocks = sizeof (OrgAT49BV16x4A) / sizeof (OrgDef);
		} else if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
			(ATM_ID_BV6416 & FLASH_TYPEMASK)){	/* AT49BV6416 Flash */

			pOrgDef = OrgAT49BV6416;
			flash_nb_blocks = sizeof (OrgAT49BV6416) / sizeof (OrgDef);
		} else {
			flash_nb_blocks = 0;
			pOrgDef = OrgAT49BV16x4;
		}

		flash_info[i].sector_count = flash_number_sector(pOrgDef, flash_nb_blocks);
		memset (flash_info[i].protect, 0, flash_info[i].sector_count);

		if (i == 0)
			flashbase = PHYS_FLASH_1;
		else
			panic ("configured too many flash banks!\n");

		sector = 0;
		start_address = flashbase;
		flash_info[i].size = 0;

		for (j = 0; j < flash_nb_blocks; j++) {
			for (k = 0; k < pOrgDef[j].sector_number; k++) {
				flash_info[i].start[sector++] = start_address;
				start_address += pOrgDef[j].sector_size;
				flash_info[i].size += pOrgDef[j].sector_size;
			}
		}

		size += flash_info[i].size;

		if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
			(ATM_ID_BV6416 & FLASH_TYPEMASK)){	/* AT49BV6416 Flash */

			/* Unlock all sectors at reset */
			for (j=0; j<flash_info[i].sector_count; j++){
				flash_unlock_sector(&flash_info[i], j);
			}
		}
	}

	/* Protect binary boot image */
	flash_protect (FLAG_PROTECT_SET,
		       CONFIG_SYS_FLASH_BASE,
		       CONFIG_SYS_FLASH_BASE + CONFIG_SYS_BOOT_SIZE - 1, &flash_info[0]);

	/* Protect environment variables */
	flash_protect (FLAG_PROTECT_SET,
		       CONFIG_ENV_ADDR,
		       CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);

	/* Protect U-Boot gzipped image */
	flash_protect (FLAG_PROTECT_SET,
		       CONFIG_SYS_U_BOOT_BASE,
		       CONFIG_SYS_U_BOOT_BASE + CONFIG_SYS_U_BOOT_SIZE - 1, &flash_info[0]);

	return size;
}

/*-----------------------------------------------------------------------
 */
void flash_print_info (flash_info_t * info)
{
	int i;

	switch (info->flash_id & FLASH_VENDMASK) {
	case (ATM_MANUFACT & FLASH_VENDMASK):
		printf ("Atmel: ");
		break;
	default:
		printf ("Unknown Vendor ");
		break;
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
	case (ATM_ID_BV1614 & FLASH_TYPEMASK):
		printf ("AT49BV1614 (16Mbit)\n");
		break;
	case (ATM_ID_BV1614A & FLASH_TYPEMASK):
		printf ("AT49BV1614A (16Mbit)\n");
		break;
	case (ATM_ID_BV6416 & FLASH_TYPEMASK):
		printf ("AT49BV6416 (64Mbit)\n");
		break;
	default:
		printf ("Unknown Chip Type\n");
		return;
	}

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

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

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;
	ulong start;

	/* 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) !=
		(ATM_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 */
		start = get_timer(0);

		if (info->protect[sect] == 0) {	/* not protected */
			volatile u16 *addr = (volatile u16 *) (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 = 0;

			do {
				result = *addr;

				/* check timeout */
				if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
					MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
					chip1 = TMO;
					break;
				}

				if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE)
					chip1 = READY;

			} while (!chip1);

			MEM_FLASH_ADDR1 = CMD_READ_ARRAY;

			if (chip1 == 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)
{
	volatile u16 *addr = (volatile u16 *) dest;
	ulong result;
	int rc = ERR_OK;
	int cflag, iflag;
	int chip1;
	ulong start;

	/*
	 * 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_PROGRAM;
	*addr = data;

	/* arm simple, non interrupt dependent timer */
	start = get_timer(0);

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

		/* check timeout */
		if (get_timer(start) > CONFIG_SYS_FLASH_ERASE_TOUT) {
			chip1 = ERR | TMO;
			break;
		}
		if (!chip1 && ((result & 0x80) == (data & 0x80)))
			chip1 = READY;

	} while (!chip1);

	*addr = CMD_READ_ARRAY;

	if (chip1 == 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 wp, data;
	int rc;

	if (addr & 1) {
		printf ("unaligned destination not supported\n");
		return ERR_ALIGN;
	};

	if ((int) src & 1) {
		printf ("unaligned source not supported\n");
		return ERR_ALIGN;
	};

	wp = addr;

	while (cnt >= 2) {
		data = *((volatile u16 *) src);
		if ((rc = write_word (info, wp, data)) != 0) {
			return (rc);
		}
		src += 2;
		wp += 2;
		cnt -= 2;
	}

	if (cnt == 1) {
		data = (*((volatile u8 *) src)) | (*((volatile u8 *) (wp + 1)) <<
										   8);
		if ((rc = write_word (info, wp, data)) != 0) {
			return (rc);
		}
		src += 1;
		wp += 1;
		cnt -= 1;
	};

	return ERR_OK;
}
