/*
 * board/mx1ads/syncflash.c
 *
 * (c) Copyright 2004
 * Techware Information Technology, Inc.
 * http://www.techware.com.tw/
 *
 * Ming-Len Wu <minglen_wu@techware.com.tw>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
/*#include <mc9328.h>*/
#include <asm/arch/imx-regs.h>

typedef unsigned long * p_u32;

/* 4Mx16x2 IAM=0 CSD1 */

flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];	/* info for FLASH chips    */

/*  Following Setting is for CSD1	*/
#define SFCTL			0x00221004
#define reg_SFCTL		__REG(SFCTL)

#define SYNCFLASH_A10		(0x00100000)

#define CMD_NORMAL		(0x81020300)			/* Normal Mode			*/
#define CMD_PREC		(CMD_NORMAL + 0x10000000)	/* Precharge Command		*/
#define CMD_AUTO		(CMD_NORMAL + 0x20000000)	/* Auto Refresh Command		*/
#define CMD_LMR			(CMD_NORMAL + 0x30000000)	/* Load Mode Register Command	*/
#define CMD_LCR			(CMD_NORMAL + 0x60000000)	/* LCR Command			*/
#define CMD_PROGRAM		(CMD_NORMAL + 0x70000000)

#define MODE_REG_VAL		(CONFIG_SYS_FLASH_BASE+0x0008CC00)	/* Cas Latency 3		*/

/* LCR Command */
#define LCR_READSTATUS		(0x0001C000)			/* 0x70				*/
#define LCR_ERASE_CONFIRM	(0x00008000)			/* 0x20				*/
#define LCR_ERASE_NVMODE	(0x0000C000)			/* 0x30				*/
#define LCR_PROG_NVMODE		(0x00028000)			/* 0xA0				*/
#define LCR_SR_CLEAR		(0x00014000)			/* 0x50				*/

/* Get Status register			*/
u32 SF_SR(void) {
	u32 tmp;

	reg_SFCTL	= CMD_PROGRAM;
	tmp		= __REG(CONFIG_SYS_FLASH_BASE);

	reg_SFCTL	= CMD_NORMAL;

	reg_SFCTL	= CMD_LCR;			/* Activate LCR Mode		*/
	__REG(CONFIG_SYS_FLASH_BASE + LCR_SR_CLEAR);

	return tmp;
}

/* check if SyncFlash is ready		*/
u8 SF_Ready(void) {
	u32 tmp;

	tmp	= SF_SR();

	if ((tmp & 0x00800000) && (tmp & 0x001C0000)) {
		printf ("SyncFlash Error code %08x\n",tmp);
	};

	if ((tmp & 0x00000080) && (tmp & 0x0000001C)) {
		printf ("SyncFlash Error code %08x\n",tmp);
	};

	if (tmp == 0x00800080)		/* Test Bit 7 of SR	*/
		return 1;
	else
		return 0;
}

/* Issue the precharge all command		*/
void SF_PrechargeAll(void) {

	/* Set Precharge Command	*/
	reg_SFCTL	= CMD_PREC;
	/* Issue Precharge All Command */
	__REG(CONFIG_SYS_FLASH_BASE + SYNCFLASH_A10);
}

/* set SyncFlash to normal mode			*/
void SF_Normal(void) {

	SF_PrechargeAll();

	reg_SFCTL	= CMD_NORMAL;
}

/* Erase SyncFlash				*/
void SF_Erase(u32 RowAddress) {

	reg_SFCTL	= CMD_NORMAL;
	__REG(RowAddress);

	reg_SFCTL	= CMD_PREC;
	__REG(RowAddress);

	reg_SFCTL	= CMD_LCR;			/* Set LCR mode		*/
	__REG(RowAddress + LCR_ERASE_CONFIRM)	= 0;	/* Issue Erase Setup Command	*/

	reg_SFCTL	= CMD_NORMAL;			/* return to Normal mode	*/
	__REG(RowAddress)	= 0xD0D0D0D0;		/* Confirm			*/

	while(!SF_Ready());
}

void SF_NvmodeErase(void) {
	SF_PrechargeAll();

	reg_SFCTL	= CMD_LCR;			/* Set to LCR mode		*/
	__REG(CONFIG_SYS_FLASH_BASE + LCR_ERASE_NVMODE)  = 0;	/* Issue Erase Nvmode Reg Command */

	reg_SFCTL	= CMD_NORMAL;			/* Return to Normal mode	*/
	__REG(CONFIG_SYS_FLASH_BASE + LCR_ERASE_NVMODE) = 0xC0C0C0C0;	/* Confirm		*/

	while(!SF_Ready());
}

void SF_NvmodeWrite(void) {
	SF_PrechargeAll();

	reg_SFCTL	= CMD_LCR;			/* Set to LCR mode		*/
	__REG(CONFIG_SYS_FLASH_BASE+LCR_PROG_NVMODE) = 0;	/* Issue Program Nvmode reg command */

	reg_SFCTL	= CMD_NORMAL;			/* Return to Normal mode	*/
	__REG(CONFIG_SYS_FLASH_BASE+LCR_PROG_NVMODE) = 0xC0C0C0C0;	/* Confirm not needed	*/
}

/****************************************************************************************/

ulong flash_init(void) {
	int i, j;

/* Turn on CSD1 for negating RESETSF of SyncFLash */

	reg_SFCTL	|= 0x80000000;		/* enable CSD1 for SyncFlash		*/
	udelay(200);

	reg_SFCTL	= CMD_LMR;		/* Set Load Mode Register Command	*/
	__REG(MODE_REG_VAL);	/* Issue Load Mode Register Command	*/

	SF_Normal();

	i = 0;

	flash_info[i].flash_id	=  FLASH_MAN_MT | FLASH_MT28S4M16LC;

	flash_info[i].size	= FLASH_BANK_SIZE;
	flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;

	memset(flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);

	for (j = 0; j < flash_info[i].sector_count; j++) {
		flash_info[i].start[j] = CONFIG_SYS_FLASH_BASE + j * 0x00100000;
	}

	flash_protect(FLAG_PROTECT_SET,
		CONFIG_SYS_FLASH_BASE,
		CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1,
		&flash_info[0]);

	flash_protect(FLAG_PROTECT_SET,
		CONFIG_ENV_ADDR,
		CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1,
		&flash_info[0]);

	return FLASH_BANK_SIZE;
}

void flash_print_info (flash_info_t *info) {

	int i;

	switch (info->flash_id & FLASH_VENDMASK) {
		case (FLASH_MAN_MT & FLASH_VENDMASK):
			printf("Micron: ");
			break;
		default:
			printf("Unknown Vendor ");
			break;
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
		case (FLASH_MT28S4M16LC & FLASH_TYPEMASK):
			printf("2x FLASH_MT28S4M16LC (16MB Total)\n");
			break;
		default:
			printf("Unknown Chip Type\n");
			return;
			break;
	}

	printf("  Size: %ld MB in %d Sectors\n",
		info->size >> 20, info->sector_count);

	printf("  Sector Start Addresses: ");

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

/*-----------------------------------------------------------------------*/

int flash_erase (flash_info_t *info, int s_first, int s_last) {
	int iflag, cflag, prot, sect;
	int rc = ERR_OK;

/* first look for protection bits */

	if (info->flash_id == FLASH_UNKNOWN)
		return ERR_UNKNOWN_FLASH_TYPE;

	if ((s_first < 0) || (s_first > s_last))
		return ERR_INVAL;

	if ((info->flash_id & FLASH_VENDMASK) != (FLASH_MAN_MT & FLASH_VENDMASK))
		return ERR_UNKNOWN_FLASH_VENDOR;

	prot = 0;

	for (sect = s_first; sect <= s_last; ++sect) {
		if (info->protect[sect])
			prot++;
	}

	if (prot) {
		printf("protected!\n");
		return ERR_PROTECTED;
	}
/*
 * Disable interrupts which might cause a timeout
 * here. Remember that our exception vectors are
 * at address 0 in the flash, and we don't want a
 * (ticker) exception to happen while the flash
 * chip is in programming mode.
 */

	cflag = icache_status();
	icache_disable();
	iflag = disable_interrupts();

/* Start erase on unprotected sectors */
	for (sect = s_first; sect <= s_last && !ctrlc(); sect++) {

		printf("Erasing sector %2d ... ", sect);

/* arm simple, non interrupt dependent timer */

		get_timer(0);

		SF_NvmodeErase();
		SF_NvmodeWrite();

		SF_Erase(CONFIG_SYS_FLASH_BASE + (0x0100000 * sect));
		SF_Normal();

		printf("ok.\n");
	}

	if (ctrlc())
		printf("User Interrupt!\n");

	if (iflag)
		enable_interrupts();

	if (cflag)
		icache_enable();

	return rc;
}

/*-----------------------------------------------------------------------
 * Copy memory to flash.
 */

int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt) {
	int i;

	for(i = 0; i < cnt; i += 4) {

		SF_PrechargeAll();

		reg_SFCTL	= CMD_PROGRAM;		/* Enter SyncFlash Program mode */
		__REG(addr + i) = __REG((u32)src  + i);

		while(!SF_Ready());
	}

	SF_Normal();

	return ERR_OK;
}
