/*
 * U-boot - flash.c Flash driver for PSD4256GV
 *
 * Copyright (c) 2005-2007 Analog Devices Inc.
 * This file is based on BF533EzFlash.c originally written by Analog Devices, Inc.
 *
 * (C) Copyright 2000-2004
 * Wolfgang Denk, DENX Software Engineering, wd@denx.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., 51 Franklin St, Fifth Floor, Boston,
 * MA 02110-1301 USA
 */

#include <malloc.h>
#include <config.h>
#include <asm/io.h>
#include "flash-defines.h"

void flash_reset(void)
{
	reset_flash();
}

unsigned long flash_get_size(ulong baseaddr, flash_info_t * info, int bank_flag)
{
	int id = 0, i = 0;
	static int FlagDev = 1;

	id = get_codes();
	if (FlagDev) {
		FlagDev = 0;
	}
	info->flash_id = id;
	switch (bank_flag) {
	case 0:
		for (i = PriFlashABegin; i < SecFlashABegin; i++)
			info->start[i] = (baseaddr + (i * AFP_SectorSize1));
		for (i = SecFlashABegin; i < NUM_SECTORS; i++)
			info->start[i] =
			    (baseaddr + SecFlashAOff +
			     ((i - SecFlashABegin) * AFP_SectorSize2));
		info->size = 0x400000;
		info->sector_count = NUM_SECTORS;
		break;
	case 1:
		info->start[0] = baseaddr + SecFlashASec1Off;
		info->start[1] = baseaddr + SecFlashASec2Off;
		info->start[2] = baseaddr + SecFlashASec3Off;
		info->start[3] = baseaddr + SecFlashASec4Off;
		info->size = 0x10000;
		info->sector_count = 4;
		break;
	case 2:
		info->start[0] = baseaddr + SecFlashBSec1Off;
		info->start[1] = baseaddr + SecFlashBSec2Off;
		info->start[2] = baseaddr + SecFlashBSec3Off;
		info->start[3] = baseaddr + SecFlashBSec4Off;
		info->size = 0x10000;
		info->sector_count = 4;
		break;
	}
	return (info->size);
}

unsigned long flash_init(void)
{
	unsigned long size_b;
	int i;

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

	size_b = flash_get_size(CFG_FLASH_BASE, &flash_info[0], 0);

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

	/* flash_protect (int flag, ulong from, ulong to, flash_info_t *info) */
	(void)flash_protect(FLAG_PROTECT_SET, CFG_FLASH_BASE,
			    (flash_info[0].start[2] - 1), &flash_info[0]);
#if (BFIN_BOOT_MODE == BF537_BYPASS_BOOT)
	(void)flash_protect(FLAG_PROTECT_SET, 0x203F0000, 0x203FFFFF,
			    &flash_info[0]);
#endif

	return (size_b);
}

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) {
	case (STM_ID_29W320EB & 0xFFFF):
	case (STM_ID_29W320DB & 0xFFFF):
		printf("ST Microelectronics ");
		break;
	default:
		printf("Unknown Vendor: (0x%08X) ", info->flash_id);
		break;
	}
	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 cnt = 0, i;
	int prot, sect;

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

	cnt = s_last - s_first + 1;

#if (BFIN_BOOT_MODE == BF537_BYPASS_BOOT)
	printf("Erasing Flash locations, Please Wait\n");
	for (i = s_first; i <= s_last; i++) {
		if (info->protect[i] == 0) {	/* not protected */
			if (erase_block_flash(i) < 0) {
				printf("Error Sector erasing \n");
				return FLASH_FAIL;
			}
		}
	}
#elif (BFIN_BOOT_MODE == BF537_SPI_MASTER_BOOT)
	if (cnt == FLASH_TOT_SECT) {
		printf("Erasing flash, Please Wait \n");
		if (erase_flash() < 0) {
			printf("Erasing flash failed \n");
			return FLASH_FAIL;
		}
	} else {
		printf("Erasing Flash locations, Please Wait\n");
		for (i = s_first; i <= s_last; i++) {
			if (info->protect[i] == 0) {	/* not protected */
				if (erase_block_flash(i) < 0) {
					printf("Error Sector erasing \n");
					return FLASH_FAIL;
				}
			}
		}
	}
#endif
	printf("\n");
	return FLASH_SUCCESS;
}

int write_buff(flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
	int d;
	if (addr % 2) {
		read_flash(addr - 1 - CFG_FLASH_BASE, &d);
		d = (int)((d & 0x00FF) | (*src++ << 8));
		write_data(addr - 1, 2, (uchar *) & d);
		write_data(addr + 1, cnt - 1, src);
	} else
		write_data(addr, cnt, src);
	return FLASH_SUCCESS;
}

int write_data(long lStart, long lCount, uchar * pnData)
{
	long i = 0;
	unsigned long ulOffset = lStart - CFG_FLASH_BASE;
	int d;
	int nSector = 0;
	int flag = 0;

	if (lCount % 2) {
		flag = 1;
		lCount = lCount - 1;
	}

	for (i = 0; i < lCount - 1; i += 2, ulOffset += 2) {
		get_sector_number(ulOffset, &nSector);
		read_flash(ulOffset, &d);
		if (d != 0xffff) {
			printf
			    ("Flash not erased at offset 0x%x Please erase to reprogram \n",
			     ulOffset);
			return FLASH_FAIL;
		}
		unlock_flash(ulOffset);
		d = (int)(pnData[i] | pnData[i + 1] << 8);
		write_flash(ulOffset, d);
		if (poll_toggle_bit(ulOffset) < 0) {
			printf("Error programming the flash \n");
			return FLASH_FAIL;
		}
		if ((i > 0) && (!(i % AFP_SectorSize2)))
			printf(".");
	}
	if (flag) {
		get_sector_number(ulOffset, &nSector);
		read_flash(ulOffset, &d);
		if (d != 0xffff) {
			printf
			    ("Flash not erased at offset 0x%x Please erase to reprogram \n",
			     ulOffset);
			return FLASH_FAIL;
		}
		unlock_flash(ulOffset);
		d = (int)(pnData[i] | (d & 0xFF00));
		write_flash(ulOffset, d);
		if (poll_toggle_bit(ulOffset) < 0) {
			printf("Error programming the flash \n");
			return FLASH_FAIL;
		}
	}
	return FLASH_SUCCESS;
}

int write_flash(long nOffset, int nValue)
{
	long addr;

	addr = (CFG_FLASH_BASE + nOffset);
	*(unsigned volatile short *)addr = nValue;
	SSYNC();
#if (BFIN_BOOT_MODE == BF537_SPI_MASTER_BOOT)
	if (icache_status())
		udelay(CONFIG_CCLK_HZ / 1000000);
#endif
	return FLASH_SUCCESS;
}

int read_flash(long nOffset, int *pnValue)
{
	unsigned short *pFlashAddr =
	    (unsigned short *)(CFG_FLASH_BASE + nOffset);

	*pnValue = *pFlashAddr;

	return TRUE;
}

int poll_toggle_bit(long lOffset)
{
	unsigned int u1, u2;
	volatile unsigned long *FB =
	    (volatile unsigned long *)(CFG_FLASH_BASE + lOffset);
	while (1) {
		u1 = *(volatile unsigned short *)FB;
		u2 = *(volatile unsigned short *)FB;
		u1 ^= u2;
		if (!(u1 & 0x0040))
			break;
		if (!(u2 & 0x0020))
			continue;
		else {
			u1 = *(volatile unsigned short *)FB;
			u2 = *(volatile unsigned short *)FB;
			u1 ^= u2;
			if (!(u1 & 0x0040))
				break;
			else {
				reset_flash();
				return FLASH_FAIL;
			}
		}
	}
	return FLASH_SUCCESS;
}

void reset_flash(void)
{
	write_flash(WRITESEQ1, RESET_VAL);
	/* Wait for 10 micro seconds */
	udelay(10);
}

int erase_flash(void)
{
	write_flash(WRITESEQ1, WRITEDATA1);
	write_flash(WRITESEQ2, WRITEDATA2);
	write_flash(WRITESEQ3, WRITEDATA3);
	write_flash(WRITESEQ4, WRITEDATA4);
	write_flash(WRITESEQ5, WRITEDATA5);
	write_flash(WRITESEQ6, WRITEDATA6);

	if (poll_toggle_bit(0x0000) < 0)
		return FLASH_FAIL;

	return FLASH_SUCCESS;
}

int erase_block_flash(int nBlock)
{
	long ulSectorOff = 0x0;

	if ((nBlock < 0) || (nBlock > AFP_NumSectors))
		return FALSE;

	/* figure out the offset of the block in flash */
	if ((nBlock >= 0) && (nBlock < SecFlashABegin))
		ulSectorOff = nBlock * AFP_SectorSize1;

	else if ((nBlock >= SecFlashABegin) && (nBlock < NUM_SECTORS))
		ulSectorOff =
		    SecFlashAOff + (nBlock - SecFlashABegin) * AFP_SectorSize2;
	/* no such sector */
	else
		return FLASH_FAIL;

	write_flash((WRITESEQ1 | ulSectorOff), WRITEDATA1);
	write_flash((WRITESEQ2 | ulSectorOff), WRITEDATA2);
	write_flash((WRITESEQ3 | ulSectorOff), WRITEDATA3);
	write_flash((WRITESEQ4 | ulSectorOff), WRITEDATA4);
	write_flash((WRITESEQ5 | ulSectorOff), WRITEDATA5);

	write_flash(ulSectorOff, BlockEraseVal);

	if (poll_toggle_bit(ulSectorOff) < 0)
		return FLASH_FAIL;
	printf(".");

	return FLASH_SUCCESS;
}

void unlock_flash(long ulOffset)
{
	unsigned long ulOffsetAddr = ulOffset;
	ulOffsetAddr &= 0xFFFF0000;

	write_flash((WRITESEQ1 | ulOffsetAddr), UNLOCKDATA1);
	write_flash((WRITESEQ2 | ulOffsetAddr), UNLOCKDATA2);
	write_flash((WRITESEQ3 | ulOffsetAddr), UNLOCKDATA3);
}

int get_codes()
{
	int dev_id = 0;

	write_flash(WRITESEQ1, GETCODEDATA1);
	write_flash(WRITESEQ2, GETCODEDATA2);
	write_flash(WRITESEQ3, GETCODEDATA3);

	read_flash(0x0402, &dev_id);
	dev_id &= 0x0000FFFF;

	reset_flash();

	return dev_id;
}

void get_sector_number(long ulOffset, int *pnSector)
{
	int nSector = 0;
	long lMainEnd = 0x400000;
	long lBootEnd = 0x10000;

	/* sector numbers for the FLASH A boot sectors */
	if (ulOffset < lBootEnd) {
		nSector = (int)ulOffset / AFP_SectorSize1;
	}
	/* sector numbers for the FLASH B boot sectors */
	else if ((ulOffset >= lBootEnd) && (ulOffset < lMainEnd)) {
		nSector = ((ulOffset / (AFP_SectorSize2)) + 7);
	}
	/* if it is a valid sector, set it */
	if ((nSector >= 0) && (nSector < AFP_NumSectors))
		*pnSector = nSector;

}
