/* LowLevel function for ATMEL DataFlash support
 * Author : Hamid Ikdoumi (Atmel)
 *
 * 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 <config.h>
#include <asm/hardware.h>
#include <dataflash.h>

static AT91S_DataFlash DataFlashInst;

extern void AT91F_SpiInit (void);
extern int AT91F_DataflashProbe (int i, AT91PS_DataflashDesc pDesc);
extern int AT91F_DataFlashRead (AT91PS_DataFlash pDataFlash,
				unsigned long addr,
				unsigned long size, char *buffer);
extern int AT91F_DataFlashWrite( AT91PS_DataFlash pDataFlash,
				unsigned char *src,
				int dest,
				int size );

int AT91F_DataflashInit (void)
{
	int i, j;
	int dfcode;
	int part;
	int last_part;
	int found[CFG_MAX_DATAFLASH_BANKS];
	unsigned char protected;

	AT91F_SpiInit ();

	for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
		found[i] = 0;
		dataflash_info[i].Desc.state = IDLE;
		dataflash_info[i].id = 0;
		dataflash_info[i].Device.pages_number = 0;
		dfcode = AT91F_DataflashProbe (cs[i].cs,
				&dataflash_info[i].Desc);

		switch (dfcode) {
		case AT45DB021:
			dataflash_info[i].Device.pages_number = 1024;
			dataflash_info[i].Device.pages_size = 264;
			dataflash_info[i].Device.page_offset = 9;
			dataflash_info[i].Device.byte_mask = 0x300;
			dataflash_info[i].Device.cs = cs[i].cs;
			dataflash_info[i].Desc.DataFlash_state = IDLE;
			dataflash_info[i].logical_address = cs[i].addr;
			dataflash_info[i].id = dfcode;
			found[i] += dfcode;;
			break;

		case AT45DB081:
			dataflash_info[i].Device.pages_number = 4096;
			dataflash_info[i].Device.pages_size = 264;
			dataflash_info[i].Device.page_offset = 9;
			dataflash_info[i].Device.byte_mask = 0x300;
			dataflash_info[i].Device.cs = cs[i].cs;
			dataflash_info[i].Desc.DataFlash_state = IDLE;
			dataflash_info[i].logical_address = cs[i].addr;
			dataflash_info[i].id = dfcode;
			found[i] += dfcode;;
			break;

		case AT45DB161:
			dataflash_info[i].Device.pages_number = 4096;
			dataflash_info[i].Device.pages_size = 528;
			dataflash_info[i].Device.page_offset = 10;
			dataflash_info[i].Device.byte_mask = 0x300;
			dataflash_info[i].Device.cs = cs[i].cs;
			dataflash_info[i].Desc.DataFlash_state = IDLE;
			dataflash_info[i].logical_address = cs[i].addr;
			dataflash_info[i].id = dfcode;
			found[i] += dfcode;;
			break;

		case AT45DB321:
			dataflash_info[i].Device.pages_number = 8192;
			dataflash_info[i].Device.pages_size = 528;
			dataflash_info[i].Device.page_offset = 10;
			dataflash_info[i].Device.byte_mask = 0x300;
			dataflash_info[i].Device.cs = cs[i].cs;
			dataflash_info[i].Desc.DataFlash_state = IDLE;
			dataflash_info[i].logical_address = cs[i].addr;
			dataflash_info[i].id = dfcode;
			found[i] += dfcode;;
			break;

		case AT45DB642:
			dataflash_info[i].Device.pages_number = 8192;
			dataflash_info[i].Device.pages_size = 1056;
			dataflash_info[i].Device.page_offset = 11;
			dataflash_info[i].Device.byte_mask = 0x700;
			dataflash_info[i].Device.cs = cs[i].cs;
			dataflash_info[i].Desc.DataFlash_state = IDLE;
			dataflash_info[i].logical_address = cs[i].addr;
			dataflash_info[i].id = dfcode;
			found[i] += dfcode;;
			break;

		case AT45DB128:
			dataflash_info[i].Device.pages_number = 16384;
			dataflash_info[i].Device.pages_size = 1056;
			dataflash_info[i].Device.page_offset = 11;
			dataflash_info[i].Device.byte_mask = 0x700;
			dataflash_info[i].Device.cs = cs[i].cs;
			dataflash_info[i].Desc.DataFlash_state = IDLE;
			dataflash_info[i].logical_address = cs[i].addr;
			dataflash_info[i].id = dfcode;
			found[i] += dfcode;;
			break;

		default:
			dfcode = 0;
			break;
		}
		/* set the last area end to the dataflash size*/
		area_list[NB_DATAFLASH_AREA -1].end =
				(dataflash_info[i].Device.pages_number *
				dataflash_info[i].Device.pages_size)-1;

		part = 0;
		last_part = 0;
		/* set the area addresses */
		for(j = 0; j<NB_DATAFLASH_AREA; j++) {
			if(found[i]!=0) {
				dataflash_info[i].Device.area_list[j].start =
					area_list[part].start +
					dataflash_info[i].logical_address;
				if(area_list[part].end == 0xffffffff) {
					dataflash_info[i].Device.area_list[j].end =
						dataflash_info[i].end_address +
						dataflash_info	[i].logical_address;
					last_part = 1;
				} else {
					dataflash_info[i].Device.area_list[j].end =
						area_list[part].end +
						dataflash_info[i].logical_address;
				}
				protected = area_list[part].protected;
				/* Set the environment according to the label...*/
				if(protected == FLAG_PROTECT_INVALID) {
					dataflash_info[i].Device.area_list[j].protected =
						FLAG_PROTECT_INVALID;
				} else {
					dataflash_info[i].Device.area_list[j].protected =
						protected;
				}
				strcpy((char*)(dataflash_info[i].Device.area_list[j].label),
						(const char *)area_list[part].label);
			}
			part++;
		}
	}
	return found[0];
}

void AT91F_DataflashSetEnv (void)
{
	int i, j;
	int part;
	unsigned char env;
	unsigned char s[32];	/* Will fit a long int in hex */
	unsigned long start;

	for (i = 0, part= 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
		for(j = 0; j<NB_DATAFLASH_AREA; j++) {
			env = area_list[part].setenv;
			/* Set the environment according to the label...*/
			if((env & FLAG_SETENV) == FLAG_SETENV) {
				start =
				dataflash_info[i].Device.area_list[j].start;
				sprintf((char*) s,"%lX",start);
				setenv((char*) area_list[part].label,(char*) s);
			}
			part++;
		}
	}
}

void dataflash_print_info (void)
{
	int i, j;

	for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
		if (dataflash_info[i].id != 0) {
			printf("DataFlash:");
			switch (dataflash_info[i].id) {
			case AT45DB021:
				printf("AT45DB021\n");
				break;
			case AT45DB161:
				printf("AT45DB161\n");
				break;

			case AT45DB321:
				printf("AT45DB321\n");
				break;

			case AT45DB642:
				printf("AT45DB642\n");
				break;
			case AT45DB128:
				printf("AT45DB128\n");
				break;
			}

			printf("Nb pages: %6d\n"
				"Page Size: %6d\n"
				"Size=%8d bytes\n"
				"Logical address: 0x%08X\n",
				(unsigned int) dataflash_info[i].Device.pages_number,
				(unsigned int) dataflash_info[i].Device.pages_size,
				(unsigned int) dataflash_info[i].Device.pages_number *
				dataflash_info[i].Device.pages_size,
				(unsigned int) dataflash_info[i].logical_address);
			for (j=0; j< NB_DATAFLASH_AREA; j++) {
				switch(dataflash_info[i].Device.area_list[j].protected) {
				case	FLAG_PROTECT_SET:
				case	FLAG_PROTECT_CLEAR:
					printf("Area %i:\t%08lX to %08lX %s", j,
						dataflash_info[i].Device.area_list[j].start,
						dataflash_info[i].Device.area_list[j].end,
						(dataflash_info[i].Device.area_list[j].protected==FLAG_PROTECT_SET) ? "(RO)" : "    ");
						printf(" %s\n",	dataflash_info[i].Device.area_list[j].label);
					break;
				case	FLAG_PROTECT_INVALID:
					break;
				}
			}
		}
	}
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_DataflashSelect				     */
/* Object              : Select the correct device			     */
/*---------------------------------------------------------------------------*/
AT91PS_DataFlash AT91F_DataflashSelect (AT91PS_DataFlash pFlash,
				unsigned long *addr)
{
	char addr_valid = 0;
	int i;

	for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++)
		if ( dataflash_info[i].id
			&& ((((int) *addr) & 0xFF000000) ==
			dataflash_info[i].logical_address)) {
			addr_valid = 1;
			break;
		}
	if (!addr_valid) {
		pFlash = (AT91PS_DataFlash) 0;
		return pFlash;
	}
	pFlash->pDataFlashDesc = &(dataflash_info[i].Desc);
	pFlash->pDevice = &(dataflash_info[i].Device);
	*addr -= dataflash_info[i].logical_address;
	return (pFlash);
}

/*---------------------------------------------------------------------------*/
/* Function Name       : addr_dataflash					     */
/* Object              : Test if address is valid			     */
/*---------------------------------------------------------------------------*/
int addr_dataflash (unsigned long addr)
{
	int addr_valid = 0;
	int i;

	for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
		if ((((int) addr) & 0xFF000000) ==
			dataflash_info[i].logical_address) {
			addr_valid = 1;
			break;
		}
	}

	return addr_valid;
}

/*---------------------------------------------------------------------------*/
/* Function Name       : size_dataflash					     */
/* Object              : Test if address is valid regarding the size	     */
/*---------------------------------------------------------------------------*/
int size_dataflash (AT91PS_DataFlash pdataFlash, unsigned long addr,
			unsigned long size)
{
	/* is outside the dataflash */
	if (((int)addr & 0x0FFFFFFF) > (pdataFlash->pDevice->pages_size *
		pdataFlash->pDevice->pages_number)) return 0;
	/* is too large for the dataflash */
	if (size > ((pdataFlash->pDevice->pages_size *
		pdataFlash->pDevice->pages_number) -
		((int)addr & 0x0FFFFFFF))) return 0;

	return 1;
}

/*---------------------------------------------------------------------------*/
/* Function Name       : prot_dataflash					     */
/* Object              : Test if destination area is protected		     */
/*---------------------------------------------------------------------------*/
int prot_dataflash (AT91PS_DataFlash pdataFlash, unsigned long addr)
{
	int area;

	/* find area */
	for (area=0; area < NB_DATAFLASH_AREA; area++) {
		if ((addr >= pdataFlash->pDevice->area_list[area].start) &&
			(addr < pdataFlash->pDevice->area_list[area].end))
			break;
	}
	if (area == NB_DATAFLASH_AREA)
		return -1;

	/*test protection value*/
	if (pdataFlash->pDevice->area_list[area].protected == FLAG_PROTECT_SET)
		return 0;
	if (pdataFlash->pDevice->area_list[area].protected == FLAG_PROTECT_INVALID)
		return 0;

	return 1;
}

/*--------------------------------------------------------------------------*/
/* Function Name       : dataflash_real_protect				    */
/* Object              : protect/unprotect area				    */
/*--------------------------------------------------------------------------*/
int dataflash_real_protect (int flag, unsigned long start_addr,
				unsigned long end_addr)
{
	int i,j, area1, area2, addr_valid = 0;

	/* find dataflash */
	for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
		if ((((int) start_addr) & 0xF0000000) ==
			dataflash_info[i].logical_address) {
				addr_valid = 1;
				break;
		}
	}
	if (!addr_valid) {
		return -1;
	}
	/* find start area */
	for (area1=0; area1 < NB_DATAFLASH_AREA; area1++) {
		if (start_addr == dataflash_info[i].Device.area_list[area1].start)
			break;
	}
	if (area1 == NB_DATAFLASH_AREA) return -1;
	/* find end area */
	for (area2=0; area2 < NB_DATAFLASH_AREA; area2++) {
		if (end_addr == dataflash_info[i].Device.area_list[area2].end)
			break;
	}
	if (area2 == NB_DATAFLASH_AREA)
		return -1;

	/*set protection value*/
	for(j = area1; j < area2+1 ; j++)
		if(dataflash_info[i].Device.area_list[j].protected
				!= FLAG_PROTECT_INVALID) {
			if (flag == 0) {
				dataflash_info[i].Device.area_list[j].protected
					= FLAG_PROTECT_CLEAR;
			} else {
				dataflash_info[i].Device.area_list[j].protected
					= FLAG_PROTECT_SET;
			}
		}

	return (area2-area1+1);
}

/*---------------------------------------------------------------------------*/
/* Function Name       : read_dataflash					     */
/* Object              : dataflash memory read				     */
/*---------------------------------------------------------------------------*/
int read_dataflash (unsigned long addr, unsigned long size, char *result)
{
	unsigned long AddrToRead = addr;
	AT91PS_DataFlash pFlash = &DataFlashInst;

	pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead);

	if (pFlash == 0)
		return ERR_UNKNOWN_FLASH_TYPE;

	if (size_dataflash(pFlash,addr,size) == 0)
		return ERR_INVAL;

	return (AT91F_DataFlashRead (pFlash, AddrToRead, size, result));
}

/*---------------------------------------------------------------------------*/
/* Function Name       : write_dataflash				     */
/* Object              : write a block in dataflash			     */
/*---------------------------------------------------------------------------*/
int write_dataflash (unsigned long addr_dest, unsigned long addr_src,
			unsigned long size)
{
	unsigned long AddrToWrite = addr_dest;
	AT91PS_DataFlash pFlash = &DataFlashInst;

	pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite);

	if (pFlash == 0)
		return ERR_UNKNOWN_FLASH_TYPE;

	if (size_dataflash(pFlash,addr_dest,size) == 0)
		return ERR_INVAL;

	if (prot_dataflash(pFlash,addr_dest) == 0)
		return ERR_PROTECTED;

	if (AddrToWrite == -1)
		return -1;

	return AT91F_DataFlashWrite (pFlash, (uchar *)addr_src,
						AddrToWrite, size);
}

void dataflash_perror (int err)
{
	switch (err) {
	case ERR_OK:
		break;
	case ERR_TIMOUT:
		printf("Timeout writing to DataFlash\n");
		break;
	case ERR_PROTECTED:
		printf("Can't write to protected/invalid DataFlash sectors\n");
		break;
	case ERR_INVAL:
		printf("Outside available DataFlash\n");
		break;
	case ERR_UNKNOWN_FLASH_TYPE:
		printf("Unknown Type of DataFlash\n");
		break;
	case ERR_PROG_ERROR:
		printf("General DataFlash Programming Error\n");
		break;
	default:
		printf("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err);
		break;
	}
}
