/*
 * LowLevel function for ATMEL DataFlash support
 * Author : Hamid Ikdoumi (Atmel)
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */
#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 found[CONFIG_SYS_MAX_DATAFLASH_BANKS];
	unsigned char protected;

	AT91F_SpiInit ();

	for (i = 0; i < CONFIG_SYS_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*/
		dataflash_info[i].end_address =
				(dataflash_info[i].Device.pages_number *
				dataflash_info[i].Device.pages_size) - 1;

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