/*
 * U-boot - flash.c Flash driver for PSD4256GV
 *
 * Copyright (c) 2005 blackfin.uclinux.org
 * 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., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#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", CFG_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 < CFG_MAX_FLASH_BANKS; ++i) {
		flash_info[i].flash_id = FLASH_UNKNOWN;
	}

	size_b0 = flash_get_size(CFG_FLASH0_BASE, &flash_info[0], 0);
	size_b1 = flash_get_size(CFG_FLASH0_BASE, &flash_info[1], 1);
	size_b2 = flash_get_size(CFG_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,CFG_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 ");
		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;

	ret = write_data(addr, cnt, 1, (int *) src);
	if(ret == FLASH_FAIL)
		return ERR_NOT_ERASED;
	return FLASH_SUCCESS;
}


int write_data(long lStart, long lCount, long lStride, int *pnData)
{
	long i = 0;
	int j = 0;
	unsigned long ulOffset = lStart - CFG_FLASH_BASE;
	int d;
	int iShift = 0;
	int iNumWords = 2;
	int nLeftover = lCount % 4;
	int nSector = 0;

	for (i = 0; (i < lCount / 4) && (i < BUFFER_SIZE); i++) {
		for (iShift = 0, j = 0; (j < iNumWords);
			j++, ulOffset += (lStride * 2)) {
			if ((ulOffset >= INVALIDLOCNSTART)
			&& (ulOffset < INVALIDLOCNEND)) {
				printf("Invalid locations, Try writing to another location \n");
				return FLASH_FAIL;
			}
			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);
			if(write_flash(ulOffset, (pnData[i] >> iShift)) < 0) {
				printf("Error programming the flash \n");
				return FLASH_FAIL;
			}
			iShift += 16;
		}
	}
	if (nLeftover > 0) {
		if ((ulOffset >= INVALIDLOCNSTART)
			&& (ulOffset < INVALIDLOCNEND))
				return FLASH_FAIL;
		get_sector_number(ulOffset, &nSector);
		read_flash(ulOffset,&d);
		if(d != 0xffff) {
			printf("Flash already programmed. Please erase to reprogram \n");
			printf("uloffset = 0x%x \t d = 0x%x\n",ulOffset,d);
			return FLASH_FAIL;
		}
		unlock_flash(ulOffset);
		if(write_flash(ulOffset, pnData[i]) < 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 = (CFG_FLASH_BASE + nOffset);
	asm("ssync;");
	*(unsigned volatile short *) addr = nValue;
	asm("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 = (CFG_FLASH_BASE + nOffset);

	if (nOffset != 0x2)
		reset_flash();
	asm("ssync;");
	nValue = *(volatile unsigned short *) addr;
	asm("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 - CFG_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;
	}
}
