/* Driver for ATMEL DataFlash support
 * Author : Hamid Ikdoumi (Atmel)
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <config.h>
#include <common.h>
#include <dataflash.h>

/*
 * spi.c API
 */
extern unsigned int AT91F_SpiWrite(AT91PS_DataflashDesc pDesc);
extern void AT91F_SpiEnable(int cs);

#define AT91C_TIMEOUT_WRDY			200000

/*----------------------------------------------------------------------*/
/* \fn    AT91F_DataFlashSendCommand					*/
/* \brief Generic function to send a command to the dataflash		*/
/*----------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashSendCommand(AT91PS_DataFlash pDataFlash,
						 unsigned char OpCode,
						 unsigned int CmdSize,
						 unsigned int DataflashAddress)
{
	unsigned int adr;

	if ((pDataFlash->pDataFlashDesc->state) != IDLE)
		return DATAFLASH_BUSY;

	/* process the address to obtain page address and byte address */
	adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) <<
		pDataFlash->pDevice->page_offset) +
			(DataflashAddress % (pDataFlash->pDevice->pages_size));

	/* fill the command buffer */
	pDataFlash->pDataFlashDesc->command[0] = OpCode;
	if (pDataFlash->pDevice->pages_number >= 16384) {
		pDataFlash->pDataFlashDesc->command[1] =
			(unsigned char)((adr & 0x0F000000) >> 24);
		pDataFlash->pDataFlashDesc->command[2] =
			(unsigned char)((adr & 0x00FF0000) >> 16);
		pDataFlash->pDataFlashDesc->command[3] =
			(unsigned char)((adr & 0x0000FF00) >> 8);
		pDataFlash->pDataFlashDesc->command[4] =
			(unsigned char)(adr & 0x000000FF);
	} else {
		pDataFlash->pDataFlashDesc->command[1] =
			(unsigned char)((adr & 0x00FF0000) >> 16);
		pDataFlash->pDataFlashDesc->command[2] =
			(unsigned char)((adr & 0x0000FF00) >> 8);
		pDataFlash->pDataFlashDesc->command[3] =
			(unsigned char)(adr & 0x000000FF);
		pDataFlash->pDataFlashDesc->command[4] = 0;
	}
	pDataFlash->pDataFlashDesc->command[5] = 0;
	pDataFlash->pDataFlashDesc->command[6] = 0;
	pDataFlash->pDataFlashDesc->command[7] = 0;

	/* Initialize the SpiData structure for the spi write fuction */
	pDataFlash->pDataFlashDesc->tx_cmd_pt =
		pDataFlash->pDataFlashDesc->command;
	pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize;
	pDataFlash->pDataFlashDesc->rx_cmd_pt =
		pDataFlash->pDataFlashDesc->command;
	pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize;

	/* send the command and read the data */
	return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
}

/*----------------------------------------------------------------------*/
/* \fn    AT91F_DataFlashGetStatus					*/
/* \brief Read the status register of the dataflash			*/
/*----------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
{
	AT91S_DataFlashStatus status;

	/* if a transfert is in progress ==> return 0 */
	if ((pDesc->state) != IDLE)
		return DATAFLASH_BUSY;

	/* first send the read status command (D7H) */
	pDesc->command[0] = DB_STATUS;
	pDesc->command[1] = 0;

	pDesc->DataFlash_state = GET_STATUS;
	pDesc->tx_data_size = 0;	/* Transmit the command */
	/* and receive response */
	pDesc->tx_cmd_pt = pDesc->command;
	pDesc->rx_cmd_pt = pDesc->command;
	pDesc->rx_cmd_size = 2;
	pDesc->tx_cmd_size = 2;
	status = AT91F_SpiWrite(pDesc);

	pDesc->DataFlash_state = *((unsigned char *)(pDesc->rx_cmd_pt) + 1);

	return status;
}

/*----------------------------------------------------------------------*/
/* \fn    AT91F_DataFlashWaitReady					*/
/* \brief wait for dataflash ready (bit7 of the status register == 1)	*/
/*----------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc
						pDataFlashDesc,
						unsigned int timeout)
{
	pDataFlashDesc->DataFlash_state = IDLE;

	do {
		AT91F_DataFlashGetStatus(pDataFlashDesc);
		timeout--;
	} while (((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) &&
		 (timeout > 0));

	if ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
		return DATAFLASH_ERROR;

	return DATAFLASH_OK;
}

/*--------------------------------------------------------------------------*/
/* Function Name       : AT91F_DataFlashContinuousRead			    */
/* Object              : Continuous stream Read			    */
/* Input Parameters    : DataFlash Service				    */
/*						: <src> = dataflash address */
/*                     : <*dataBuffer> = data buffer pointer		    */
/*                     : <sizeToRead> = data buffer size		    */
/* Return value		: State of the dataflash			    */
/*--------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashContinuousRead(
				AT91PS_DataFlash pDataFlash,
				int src,
				unsigned char *dataBuffer,
				int sizeToRead)
{
	AT91S_DataFlashStatus status;
	/* Test the size to read in the device */
	if ((src + sizeToRead) >
			(pDataFlash->pDevice->pages_size *
				(pDataFlash->pDevice->pages_number)))
		return DATAFLASH_MEMORY_OVERFLOW;

	pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
	pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;
	pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
	pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;

	status = AT91F_DataFlashSendCommand(
			pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src);
	/* Send the command to the dataflash */
	return (status);
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_DataFlashPagePgmBuf			     */
/* Object              : Main memory page program thru buffer 1 or buffer 2  */
/* Input Parameters    : DataFlash Service				     */
/*						: <*src> = Source buffer     */
/*                     : <dest> = dataflash destination address		     */
/*                     : <SizeToWrite> = data buffer size		     */
/* Return value		: State of the dataflash			     */
/*---------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashPagePgmBuf(AT91PS_DataFlash pDataFlash,
						unsigned char *src,
						unsigned int dest,
						unsigned int SizeToWrite)
{
	int cmdsize;
	pDataFlash->pDataFlashDesc->tx_data_pt = src;
	pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite;
	pDataFlash->pDataFlashDesc->rx_data_pt = src;
	pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;

	cmdsize = 4;
	/* Send the command to the dataflash */
	if (pDataFlash->pDevice->pages_number >= 16384)
		cmdsize = 5;
	return (AT91F_DataFlashSendCommand(
			pDataFlash, DB_PAGE_PGM_BUF1, cmdsize, dest));
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_MainMemoryToBufferTransfert		     */
/* Object              : Read a page in the SRAM Buffer 1 or 2		     */
/* Input Parameters    : DataFlash Service				     */
/*                     : Page concerned					     */
/*                     :						     */
/* Return value		: State of the dataflash			     */
/*---------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert(
					AT91PS_DataFlash
					pDataFlash,
					unsigned char
					BufferCommand,
					unsigned int page)
{
	int cmdsize;
	/* Test if the buffer command is legal */
	if ((BufferCommand != DB_PAGE_2_BUF1_TRF) &&
			(BufferCommand != DB_PAGE_2_BUF2_TRF)) {
		return DATAFLASH_BAD_COMMAND;
	}

	/* no data to transmit or receive */
	pDataFlash->pDataFlashDesc->tx_data_size = 0;
	cmdsize = 4;
	if (pDataFlash->pDevice->pages_number >= 16384)
		cmdsize = 5;
	return (AT91F_DataFlashSendCommand(
			pDataFlash, BufferCommand, cmdsize,
			page * pDataFlash->pDevice->pages_size));
}

/*-------------------------------------------------------------------------- */
/* Function Name       : AT91F_DataFlashWriteBuffer			     */
/* Object              : Write data to the internal sram buffer 1 or 2	     */
/* Input Parameters    : DataFlash Service				     */
/*			: <BufferCommand> = command to write buffer1 or 2    */
/*                     : <*dataBuffer> = data buffer to write		     */
/*                     : <bufferAddress> = address in the internal buffer    */
/*                     : <SizeToWrite> = data buffer size		     */
/* Return value		: State of the dataflash			     */
/*---------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer(
					AT91PS_DataFlash pDataFlash,
					unsigned char BufferCommand,
					unsigned char *dataBuffer,
					unsigned int bufferAddress,
					int SizeToWrite)
{
	int cmdsize;
	/* Test if the buffer command is legal */
	if ((BufferCommand != DB_BUF1_WRITE) &&
			(BufferCommand != DB_BUF2_WRITE)) {
		return DATAFLASH_BAD_COMMAND;
	}

	/* buffer address must be lower than page size */
	if (bufferAddress > pDataFlash->pDevice->pages_size)
		return DATAFLASH_BAD_ADDRESS;

	if ((pDataFlash->pDataFlashDesc->state) != IDLE)
		return DATAFLASH_BUSY;

	/* Send first Write Command */
	pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
	pDataFlash->pDataFlashDesc->command[1] = 0;
	if (pDataFlash->pDevice->pages_number >= 16384) {
		pDataFlash->pDataFlashDesc->command[2] = 0;
		pDataFlash->pDataFlashDesc->command[3] =
			(unsigned char)(((unsigned int)(bufferAddress &
							pDataFlash->pDevice->
							byte_mask)) >> 8);
		pDataFlash->pDataFlashDesc->command[4] =
			(unsigned char)((unsigned int)bufferAddress & 0x00FF);
		cmdsize = 5;
	} else {
		pDataFlash->pDataFlashDesc->command[2] =
			(unsigned char)(((unsigned int)(bufferAddress &
							pDataFlash->pDevice->
							byte_mask)) >> 8);
		pDataFlash->pDataFlashDesc->command[3] =
			(unsigned char)((unsigned int)bufferAddress & 0x00FF);
		pDataFlash->pDataFlashDesc->command[4] = 0;
		cmdsize = 4;
	}

	pDataFlash->pDataFlashDesc->tx_cmd_pt =
		pDataFlash->pDataFlashDesc->command;
	pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize;
	pDataFlash->pDataFlashDesc->rx_cmd_pt =
		pDataFlash->pDataFlashDesc->command;
	pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize;

	pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
	pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
	pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
	pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite;

	return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_PageErase                                     */
/* Object              : Erase a page					     */
/* Input Parameters    : DataFlash Service				     */
/*                     : Page concerned					     */
/*                     :						     */
/* Return value		: State of the dataflash			     */
/*---------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_PageErase(
					AT91PS_DataFlash pDataFlash,
					unsigned int page)
{
	int cmdsize;
	/* Test if the buffer command is legal */
	/* no data to transmit or receive */
	pDataFlash->pDataFlashDesc->tx_data_size = 0;

	cmdsize = 4;
	if (pDataFlash->pDevice->pages_number >= 16384)
		cmdsize = 5;
	return (AT91F_DataFlashSendCommand(pDataFlash,
				DB_PAGE_ERASE, cmdsize,
				page * pDataFlash->pDevice->pages_size));
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_BlockErase                                    */
/* Object              : Erase a Block					     */
/* Input Parameters    : DataFlash Service				     */
/*                     : Page concerned					     */
/*                     :						     */
/* Return value		: State of the dataflash			     */
/*---------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_BlockErase(
				AT91PS_DataFlash pDataFlash,
				unsigned int block)
{
	int cmdsize;
	/* Test if the buffer command is legal */
	/* no data to transmit or receive */
	pDataFlash->pDataFlashDesc->tx_data_size = 0;
	cmdsize = 4;
	if (pDataFlash->pDevice->pages_number >= 16384)
		cmdsize = 5;
	return (AT91F_DataFlashSendCommand(pDataFlash, DB_BLOCK_ERASE, cmdsize,
					block * 8 *
					pDataFlash->pDevice->pages_size));
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_WriteBufferToMain			     */
/* Object              : Write buffer to the main memory		     */
/* Input Parameters    : DataFlash Service				     */
/*		: <BufferCommand> = command to send to buffer1 or buffer2    */
/*                     : <dest> = main memory address			     */
/* Return value		: State of the dataflash			     */
/*---------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_WriteBufferToMain(AT91PS_DataFlash pDataFlash,
					unsigned char BufferCommand,
					unsigned int dest)
{
	int cmdsize;
	/* Test if the buffer command is correct */
	if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
			(BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
			(BufferCommand != DB_BUF2_PAGE_PGM) &&
			(BufferCommand != DB_BUF2_PAGE_ERASE_PGM))
		return DATAFLASH_BAD_COMMAND;

	/* no data to transmit or receive */
	pDataFlash->pDataFlashDesc->tx_data_size = 0;

	cmdsize = 4;
	if (pDataFlash->pDevice->pages_number >= 16384)
		cmdsize = 5;
	/* Send the command to the dataflash */
	return (AT91F_DataFlashSendCommand(pDataFlash, BufferCommand,
						cmdsize, dest));
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_PartialPageWrite				     */
/* Object              : Erase partielly a page				     */
/* Input Parameters    : <page> = page number				     */
/*			: <AdrInpage> = adr to begin the fading		     */
/*                     : <length> = Number of bytes to erase		     */
/*---------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_PartialPageWrite(AT91PS_DataFlash pDataFlash,
					unsigned char *src,
					unsigned int dest,
					unsigned int size)
{
	unsigned int page;
	unsigned int AdrInPage;

	page = dest / (pDataFlash->pDevice->pages_size);
	AdrInPage = dest % (pDataFlash->pDevice->pages_size);

	/* Read the contents of the page in the Sram Buffer */
	AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
	AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
				 AT91C_TIMEOUT_WRDY);
	/*Update the SRAM buffer */
	AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src,
					AdrInPage, size);

	AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					AT91C_TIMEOUT_WRDY);

	/* Erase page if a 128 Mbits device */
	if (pDataFlash->pDevice->pages_number >= 16384) {
		AT91F_PageErase(pDataFlash, page);
		/* Rewrite the modified Sram Buffer in the main memory */
		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					 AT91C_TIMEOUT_WRDY);
	}

	/* Rewrite the modified Sram Buffer in the main memory */
	return (AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM,
					(page *
					 pDataFlash->pDevice->pages_size)));
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_DataFlashWrite				     */
/* Object              :						     */
/* Input Parameters    : <*src> = Source buffer				     */
/*                     : <dest> = dataflash adress			     */
/*                     : <size> = data buffer size			     */
/*---------------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashWrite(AT91PS_DataFlash pDataFlash,
						unsigned char *src,
						int dest, int size)
{
	unsigned int length;
	unsigned int page;
	unsigned int status;

	AT91F_SpiEnable(pDataFlash->pDevice->cs);

	if ((dest + size) > (pDataFlash->pDevice->pages_size *
			(pDataFlash->pDevice->pages_number)))
		return DATAFLASH_MEMORY_OVERFLOW;

	/* If destination does not fit a page start address */
	if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0) {
		length =
			pDataFlash->pDevice->pages_size -
			(dest % ((unsigned int)(pDataFlash->pDevice->pages_size)));

		if (size < length)
			length = size;

		if (!AT91F_PartialPageWrite(pDataFlash, src, dest, length))
			return DATAFLASH_ERROR;

		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					 AT91C_TIMEOUT_WRDY);

		/* Update size, source and destination pointers */
		size -= length;
		dest += length;
		src += length;
	}

	while ((size - pDataFlash->pDevice->pages_size) >= 0) {
		/* program dataflash page */
		page = (unsigned int)dest / (pDataFlash->pDevice->pages_size);

		status = AT91F_DataFlashWriteBuffer(pDataFlash,
					DB_BUF1_WRITE, src, 0,
					pDataFlash->pDevice->
					pages_size);
		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					 AT91C_TIMEOUT_WRDY);

		status = AT91F_PageErase(pDataFlash, page);
		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					 AT91C_TIMEOUT_WRDY);
		if (!status)
			return DATAFLASH_ERROR;

		status = AT91F_WriteBufferToMain(pDataFlash,
					 DB_BUF1_PAGE_PGM, dest);
		if (!status)
			return DATAFLASH_ERROR;

		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					 AT91C_TIMEOUT_WRDY);

		/* Update size, source and destination pointers */
		size -= pDataFlash->pDevice->pages_size;
		dest += pDataFlash->pDevice->pages_size;
		src += pDataFlash->pDevice->pages_size;
	}

	/* If still some bytes to read */
	if (size > 0) {
		/* program dataflash page */
		if (!AT91F_PartialPageWrite(pDataFlash, src, dest, size))
			return DATAFLASH_ERROR;

		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					 AT91C_TIMEOUT_WRDY);
	}
	return DATAFLASH_OK;
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_DataFlashRead				     */
/* Object              : Read a block in dataflash			     */
/* Input Parameters    :						     */
/* Return value		:						     */
/*---------------------------------------------------------------------------*/
int AT91F_DataFlashRead(AT91PS_DataFlash pDataFlash,
			unsigned long addr, unsigned long size, char *buffer)
{
	unsigned long SizeToRead;

	AT91F_SpiEnable(pDataFlash->pDevice->cs);

	if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
		return -1;

	while (size) {
		SizeToRead = (size < 0x8000) ? size : 0x8000;

		if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc,
					AT91C_TIMEOUT_WRDY) !=
						DATAFLASH_OK)
			return -1;

		if (AT91F_DataFlashContinuousRead(pDataFlash, addr,
						(uchar *) buffer,
						SizeToRead) != DATAFLASH_OK)
			return -1;

		size -= SizeToRead;
		addr += SizeToRead;
		buffer += SizeToRead;
	}

	return DATAFLASH_OK;
}

/*---------------------------------------------------------------------------*/
/* Function Name       : AT91F_DataflashProbe				     */
/* Object              :						     */
/* Input Parameters    :						     */
/* Return value	       : Dataflash status register			     */
/*---------------------------------------------------------------------------*/
int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc)
{
	AT91F_SpiEnable(cs);
	AT91F_DataFlashGetStatus(pDesc);
	return ((pDesc->command[1] == 0xFF) ? 0 : pDesc->command[1] & 0x3C);
}
