/*
 * 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 <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) {
#ifdef DEBUG
		printf("Device ID of the Flash is %x\n", id);
#endif
		FlagDev = 0;
	}
	info->flash_id = id;

	switch (bank_flag) {
	case 0:
		for (i = PriFlashABegin; i < SecFlashABegin; i++)
			info->start[i] = (baseaddr + (i * AFP_SectorSize1));
		info->size = 0x200000;
		info->sector_count = 32;
		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_b0, size_b1, size_b2;
	int i;

	size_b0 = size_b1 = size_b2 = 0;
#ifdef DEBUG
	printf("Flash Memory Start 0x%x\n", CONFIG_SYS_FLASH_BASE);
	printf("Memory Map for the Flash\n");
	printf("0x20000000 - 0x200FFFFF Flash A Primary (1MB)\n");
	printf("0x20100000 - 0x201FFFFF Flash B Primary (1MB)\n");
	printf("0x20200000 - 0x2020FFFF Flash A Secondary (64KB)\n");
	printf("0x20280000 - 0x2028FFFF Flash B Secondary (64KB)\n");
	printf("Please type command flinfo for information on Sectors \n");
#endif
	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
		flash_info[i].flash_id = FLASH_UNKNOWN;
	}

	size_b0 = flash_get_size(CONFIG_SYS_FLASH0_BASE, &flash_info[0], 0);
	size_b1 = flash_get_size(CONFIG_SYS_FLASH0_BASE, &flash_info[1], 1);
	size_b2 = flash_get_size(CONFIG_SYS_FLASH0_BASE, &flash_info[2], 2);

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

	(void)flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_FLASH0_BASE,
			    (flash_info[0].start[2] - 1), &flash_info[0]);

	return (size_b0 + size_b1 + size_b2);
}

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 FLASH_PSD4256GV:
		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 (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, info->start[i]) < 0) {
					printf("Error Sector erasing \n");
					return FLASH_FAIL;
				}
			}
		}
	}
	return FLASH_SUCCESS;
}

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

int write_data(long lStart, long lCount, uchar * pnData)
{
	long i = 0;
	unsigned long ulOffset = lStart - CONFIG_SYS_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 read_data(long ulStart, long lCount, long lStride, int *pnData)
{
	long i = 0;
	int j = 0;
	long ulOffset = ulStart;
	int iShift = 0;
	int iNumWords = 2;
	int nLeftover = lCount % 4;
	int nHi, nLow;
	int nSector = 0;

	for (i = 0; (i < lCount / 4) && (i < BUFFER_SIZE); i++) {
		for (iShift = 0, j = 0; j < iNumWords; j += 2) {
			if ((ulOffset >= INVALIDLOCNSTART)
			    && (ulOffset < INVALIDLOCNEND))
				return FLASH_FAIL;

			get_sector_number(ulOffset, &nSector);
			read_flash(ulOffset, &nLow);
			ulOffset += (lStride * 2);
			read_flash(ulOffset, &nHi);
			ulOffset += (lStride * 2);
			pnData[i] = (nHi << 16) | nLow;
		}
	}
	if (nLeftover > 0) {
		if ((ulOffset >= INVALIDLOCNSTART)
		    && (ulOffset < INVALIDLOCNEND))
			return FLASH_FAIL;

		get_sector_number(ulOffset, &nSector);
		read_flash(ulOffset, &pnData[i]);
	}
	return FLASH_SUCCESS;
}

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

	addr = (CONFIG_SYS_FLASH_BASE + nOffset);
	SSYNC();
	*(unsigned volatile short *)addr = nValue;
	SSYNC();
	if (poll_toggle_bit(nOffset) < 0)
		return FLASH_FAIL;
	return FLASH_SUCCESS;
}

int read_flash(long nOffset, int *pnValue)
{
	int nValue = 0x0;
	long addr = (CONFIG_SYS_FLASH_BASE + nOffset);

	if (nOffset != 0x2)
		reset_flash();
	SSYNC();
	nValue = *(volatile unsigned short *)addr;
	SSYNC();
	*pnValue = nValue;
	return TRUE;
}

int poll_toggle_bit(long lOffset)
{
	unsigned int u1, u2;
	unsigned long timeout = 0xFFFFFFFF;
	volatile unsigned long *FB =
	    (volatile unsigned long *)(0x20000000 + lOffset);
	while (1) {
		if (timeout < 0)
			break;
		u1 = *(volatile unsigned short *)FB;
		u2 = *(volatile unsigned short *)FB;
		if ((u1 & 0x0040) == (u2 & 0x0040))
			return FLASH_SUCCESS;
		if ((u2 & 0x0020) == 0x0000)
			continue;
		u1 = *(volatile unsigned short *)FB;
		if ((u2 & 0x0040) == (u1 & 0x0040))
			return FLASH_SUCCESS;
		else {
			reset_flash();
			return FLASH_FAIL;
		}
		timeout--;
	}
	printf("Time out occured \n");
	if (timeout < 0)
		return FLASH_FAIL;
}

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;

	write_flash(SecFlashAOff + WRITESEQ1, WRITEDATA1);
	write_flash(SecFlashAOff + WRITESEQ2, WRITEDATA2);
	write_flash(SecFlashAOff + WRITESEQ3, WRITEDATA3);
	write_flash(SecFlashAOff + WRITESEQ4, WRITEDATA4);
	write_flash(SecFlashAOff + WRITESEQ5, WRITEDATA5);
	write_flash(SecFlashAOff + WRITESEQ6, WRITEDATA6);

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

	write_flash(PriFlashBOff + WRITESEQ1, WRITEDATA1);
	write_flash(PriFlashBOff + WRITESEQ2, WRITEDATA2);
	write_flash(PriFlashBOff + WRITESEQ3, WRITEDATA3);
	write_flash(PriFlashBOff + WRITESEQ4, WRITEDATA4);
	write_flash(PriFlashBOff + WRITESEQ5, WRITEDATA5);
	write_flash(PriFlashBOff + WRITESEQ6, WRITEDATA6);

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

	write_flash(SecFlashBOff + WRITESEQ1, WRITEDATA1);
	write_flash(SecFlashBOff + WRITESEQ2, WRITEDATA2);
	write_flash(SecFlashBOff + WRITESEQ3, WRITEDATA3);
	write_flash(SecFlashBOff + WRITESEQ4, WRITEDATA4);
	write_flash(SecFlashBOff + WRITESEQ5, WRITEDATA5);
	write_flash(SecFlashBOff + WRITESEQ6, WRITEDATA6);

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

	return FLASH_SUCCESS;
}

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

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

	ulSectorOff = (address - CONFIG_SYS_FLASH_BASE);

	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;

	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(0x0002, &dev_id);
	dev_id &= 0x00FF;

	reset_flash();

	return dev_id;
}

void get_sector_number(long ulOffset, int *pnSector)
{
	int nSector = 0;

	if (ulOffset >= SecFlashAOff) {
		if ((ulOffset < SecFlashASec1Off)
		    && (ulOffset < SecFlashASec2Off)) {
			nSector = SECT32;
		} else if ((ulOffset >= SecFlashASec2Off)
			   && (ulOffset < SecFlashASec3Off)) {
			nSector = SECT33;
		} else if ((ulOffset >= SecFlashASec3Off)
			   && (ulOffset < SecFlashASec4Off)) {
			nSector = SECT34;
		} else if ((ulOffset >= SecFlashASec4Off)
			   && (ulOffset < SecFlashAEndOff)) {
			nSector = SECT35;
		}
	} else if (ulOffset >= SecFlashBOff) {
		if ((ulOffset < SecFlashBSec1Off)
		    && (ulOffset < SecFlashBSec2Off)) {
			nSector = SECT36;
		}
		if ((ulOffset < SecFlashBSec2Off)
		    && (ulOffset < SecFlashBSec3Off)) {
			nSector = SECT37;
		}
		if ((ulOffset < SecFlashBSec3Off)
		    && (ulOffset < SecFlashBSec4Off)) {
			nSector = SECT38;
		}
		if ((ulOffset < SecFlashBSec4Off)
		    && (ulOffset < SecFlashBEndOff)) {
			nSector = SECT39;
		}
	} else if ((ulOffset >= PriFlashAOff) && (ulOffset < SecFlashAOff)) {
		nSector = ulOffset & 0xffff0000;
		nSector = ulOffset >> 16;
		nSector = nSector & 0x000ff;
	}

	if ((nSector >= 0) && (nSector < AFP_NumSectors)) {
		*pnSector = nSector;
	}
}
