/*
 * (C) Copyright 2001-2005
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * Flash Routines for Intel devices
 *
 *--------------------------------------------------------------------
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <mpc8xx.h>
#include "cpu87.h"

flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];

/*-----------------------------------------------------------------------
 */
ulong flash_int_get_size (volatile unsigned long *baseaddr,
					  flash_info_t * info)
{
	short i;
	unsigned long flashtest_h, flashtest_l;

	info->sector_count = info->size = 0;
	info->flash_id = FLASH_UNKNOWN;

	/* Write identify command sequence and test FLASH answer
	 */
	baseaddr[0] = 0x00900090;
	baseaddr[1] = 0x00900090;

	flashtest_h = baseaddr[0];	/* manufacturer ID	*/
	flashtest_l = baseaddr[1];

	if (flashtest_h != INTEL_MANUFACT || flashtest_l != INTEL_MANUFACT)
		return (0);		/* no or unknown flash	*/

	flashtest_h = baseaddr[2];	/* device ID	        */
	flashtest_l = baseaddr[3];

	if (flashtest_h != flashtest_l)
		return (0);

	switch (flashtest_h) {
	case INTEL_ID_28F160C3B:
		info->flash_id = FLASH_28F160C3B;
		info->sector_count = 39;
		info->size = 0x00800000;	/* 4 * 2 MB = 8 MB	*/
		break;
	case INTEL_ID_28F160F3B:
		info->flash_id = FLASH_28F160F3B;
		info->sector_count = 39;
		info->size = 0x00800000;	/* 4 * 2 MB = 8 MB      */
		break;
	case INTEL_ID_28F640C3B:
		info->flash_id = FLASH_28F640C3B;
		info->sector_count = 135;
		info->size = 0x02000000;	/* 16 * 2 MB = 32 MB	*/
		break;
	default:
		return (0);			/* no or unknown flash	*/
	}

	info->flash_id |= INTEL_MANUFACT << 16; /* set manufacturer offset */

	if (info->flash_id & FLASH_BTYPE) {
		volatile unsigned long *tmp = baseaddr;

		/* set up sector start adress table (bottom sector type)
		 * AND unlock the sectors (if our chip is 160C3)
		 */
		for (i = 0; i < info->sector_count; i++) {
			if (((info->flash_id & FLASH_TYPEMASK) == FLASH_28F160C3B) ||
			    ((info->flash_id & FLASH_TYPEMASK) == FLASH_28F640C3B)) {
				tmp[0] = 0x00600060;
				tmp[1] = 0x00600060;
				tmp[0] = 0x00D000D0;
				tmp[1] = 0x00D000D0;
			}
			info->start[i] = (uint) tmp;
			tmp += i < 8 ? 0x2000 : 0x10000; /* pointer arith       */
		}
	}

	memset (info->protect, 0, info->sector_count);

	baseaddr[0] = 0x00FF00FF;
	baseaddr[1] = 0x00FF00FF;

	return (info->size);
}

static ulong flash_amd_get_size (vu_char *addr, flash_info_t *info)
{
	short i;
	uchar vendor, devid;
	ulong base = (ulong)addr;

	/* Write auto select command: read Manufacturer ID */
	addr[0x0555] = 0xAA;
	addr[0x02AA] = 0x55;
	addr[0x0555] = 0x90;

	udelay(1000);

	vendor = addr[0];
	devid = addr[1] & 0xff;

	/* only support AMD */
	if (vendor != 0x01) {
		return 0;
	}

	vendor &= 0xf;
	devid &= 0xff;

	if (devid == AMD_ID_F040B) {
		info->flash_id     = vendor << 16 | devid;
		info->sector_count = 8;
		info->size         = info->sector_count * 0x10000;
	}
	else if (devid == AMD_ID_F080B) {
		info->flash_id     = vendor << 16 | devid;
		info->sector_count = 16;
		info->size         = 4 * info->sector_count * 0x10000;
	}
	else if (devid == AMD_ID_F016D) {
		info->flash_id     = vendor << 16 | devid;
		info->sector_count = 32;
		info->size         = 4 * info->sector_count * 0x10000;
	}
	else {
		printf ("## Unknown Flash Type: %02x\n", devid);
		return 0;
	}

	/* check for protected sectors */
	for (i = 0; i < info->sector_count; i++) {
		/* sector base address */
		info->start[i] = base + i * (info->size / info->sector_count);
		/* read sector protection at sector address, (A7 .. A0) = 0x02 */
		/* D0 = 1 if protected */
		addr = (volatile unsigned char *)(info->start[i]);
		info->protect[i] = addr[2] & 1;
	}

	/*
	 * Prevent writes to uninitialized FLASH.
	 */
	if (info->flash_id != FLASH_UNKNOWN) {
		addr = (vu_char *)info->start[0];
		addr[0] = 0xF0; /* reset bank */
	}

	return (info->size);
}


/*-----------------------------------------------------------------------
 */
unsigned long flash_init (void)
{
	unsigned long size_b0 = 0;
	unsigned long size_b1 = 0;
	int i;

	/* Init: no FLASHes known
	 */
	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; ++i) {
		flash_info[i].flash_id = FLASH_UNKNOWN;
	}

	/* Disable flash protection */
	CPU86_BCR |= (CPU86_BCR_FWPT | CPU86_BCR_FWRE);

	/* Static FLASH Bank configuration here (only one bank) */

	size_b0 = flash_int_get_size ((ulong *) CONFIG_SYS_FLASH_BASE, &flash_info[0]);
	size_b1 = flash_amd_get_size ((uchar *) CONFIG_SYS_BOOTROM_BASE, &flash_info[1]);

	if (size_b0 > 0 || size_b1 > 0) {

		printf("(");

		if (size_b0 > 0) {
			puts ("Bank#1 - ");
			print_size (size_b0, (size_b1 > 0) ? ", " : ") ");
		}

		if (size_b1 > 0) {
			puts ("Bank#2 - ");
			print_size (size_b1, ") ");
		}
	}
	else {
		printf ("## No FLASH found.\n");
		return 0;
	}
	/* protect monitor and environment sectors
	 */

#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_BOOTROM_BASE
	if (size_b1) {
		/* If U-Boot is booted from ROM the CONFIG_SYS_MONITOR_BASE > CONFIG_SYS_FLASH_BASE
		 * but we shouldn't protect it.
		 */

		flash_protect  (FLAG_PROTECT_SET,
				CONFIG_SYS_MONITOR_BASE,
				CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1, &flash_info[1]
		);
	}
#else
#if CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE
	flash_protect (FLAG_PROTECT_SET,
		       CONFIG_SYS_MONITOR_BASE,
		       CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1, &flash_info[0]
	);
#endif
#endif

#if defined(CONFIG_ENV_IS_IN_FLASH) && defined(CONFIG_ENV_ADDR)
# ifndef  CONFIG_ENV_SIZE
#  define CONFIG_ENV_SIZE	CONFIG_ENV_SECT_SIZE
# endif
# if CONFIG_ENV_ADDR >= CONFIG_SYS_BOOTROM_BASE
	if (size_b1) {
		flash_protect (FLAG_PROTECT_SET,
				CONFIG_ENV_ADDR,
				CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[1]);
	}
# else
	flash_protect (FLAG_PROTECT_SET,
		       CONFIG_ENV_ADDR,
		       CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
# endif
#endif

	return (size_b0 + size_b1);
}

/*-----------------------------------------------------------------------
 */
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 >> 16) & 0xff) {
	case 0x89:
		printf ("INTEL ");
		break;
	case 0x1:
		printf ("AMD ");
		break;
	default:
		printf ("Unknown Vendor ");
		break;
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
	case FLASH_28F160C3B:
		printf ("28F160C3B (16 Mbit, bottom sector)\n");
		break;
	case FLASH_28F160F3B:
		printf ("28F160F3B (16 Mbit, bottom sector)\n");
		break;
	case FLASH_28F640C3B:
		printf ("28F640C3B (64 M, bottom sector)\n");
		break;
	case AMD_ID_F040B:
		printf ("AM29F040B (4 Mbit)\n");
		break;
	default:
		printf ("Unknown Chip Type\n");
		break;
	}

	if (info->size < 0x100000)
		printf ("  Size: %ld KB in %d Sectors\n",
				info->size >> 10, info->sector_count);
	else
		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)
{
	vu_char *addr = (vu_char *)(info->start[0]);
	int flag, prot, sect, l_sect;
	ulong start, now, last;

	if ((s_first < 0) || (s_first > s_last)) {
		if (info->flash_id == FLASH_UNKNOWN) {
			printf ("- missing\n");
		} else {
			printf ("- no sectors to erase\n");
		}
		return 1;
	}

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

	/* Check the type of erased flash
	 */
	if (info->flash_id >> 16 == 0x1) {
		/* Erase AMD flash
		 */
		l_sect = -1;

		/* Disable interrupts which might cause a timeout here */
		flag = disable_interrupts();

		addr[0x0555] = 0xAA;
		addr[0x02AA] = 0x55;
		addr[0x0555] = 0x80;
		addr[0x0555] = 0xAA;
		addr[0x02AA] = 0x55;

		/* wait at least 80us - let's wait 1 ms */
		udelay (1000);

		/* Start erase on unprotected sectors */
		for (sect = s_first; sect<=s_last; sect++) {
			if (info->protect[sect] == 0) { /* not protected */
				addr = (vu_char *)(info->start[sect]);
				addr[0] = 0x30;
				l_sect = sect;
			}
		}

		/* re-enable interrupts if necessary */
		if (flag)
			enable_interrupts();

		/* wait at least 80us - let's wait 1 ms */
		udelay (1000);

		/*
		 * We wait for the last triggered sector
		 */
		if (l_sect < 0)
			goto AMD_DONE;

		start = get_timer (0);
		last  = start;
		addr = (vu_char *)(info->start[l_sect]);
		while ((addr[0] & 0x80) != 0x80) {
			if ((now = get_timer(start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
				printf ("Timeout\n");
				return 1;
			}
			/* show that we're waiting */
			if ((now - last) > 1000) {      /* every second */
				serial_putc ('.');
				last = now;
			}
		}

AMD_DONE:
		/* reset to read mode */
		addr = (volatile unsigned char *)info->start[0];
		addr[0] = 0xF0;     /* reset bank */

	} else {
		/* Erase Intel flash
		 */

		/* Start erase on unprotected sectors
		 */
		for (sect = s_first; sect <= s_last; sect++) {
			volatile ulong *addr =
				(volatile unsigned long *) info->start[sect];

			start = get_timer (0);
			last = start;
			if (info->protect[sect] == 0) {
			/* Disable interrupts which might cause a timeout here
			 */
				flag = disable_interrupts ();

				/* Erase the block
				 */
				addr[0] = 0x00200020;
				addr[1] = 0x00200020;
				addr[0] = 0x00D000D0;
				addr[1] = 0x00D000D0;

				/* re-enable interrupts if necessary
				 */
				if (flag)
					enable_interrupts ();

				/* wait at least 80us - let's wait 1 ms
				 */
				udelay (1000);

				last = start;
				while ((addr[0] & 0x00800080) != 0x00800080 ||
				   (addr[1] & 0x00800080) != 0x00800080) {
					if ((now = get_timer (start)) > CONFIG_SYS_FLASH_ERASE_TOUT) {
						printf ("Timeout (erase suspended!)\n");
						/* Suspend erase
						 */
						addr[0] = 0x00B000B0;
						addr[1] = 0x00B000B0;
						goto DONE;
					}
					/* show that we're waiting
					 */
					if ((now - last) > 1000) {	/* every second */
						serial_putc ('.');
						last = now;
					}
				}
				if (addr[0] & 0x00220022 || addr[1] & 0x00220022) {
					printf ("*** ERROR: erase failed!\n");
					goto DONE;
				}
			}
			/* Clear status register and reset to read mode
			 */
			addr[0] = 0x00500050;
			addr[1] = 0x00500050;
			addr[0] = 0x00FF00FF;
			addr[1] = 0x00FF00FF;
		}
	}

	printf (" done\n");

DONE:
	return 0;
}

static int write_word (flash_info_t *, volatile unsigned long *, ulong);
static int write_byte (flash_info_t *info, ulong dest, uchar data);

/*-----------------------------------------------------------------------
 * Copy memory to flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
{
	ulong v;
	int i, l, rc, cc = cnt, res = 0;

	if (info->flash_id >> 16 == 0x1) {

		/* Write to AMD 8-bit flash
		 */
		while (cnt > 0) {
			if ((rc = write_byte(info, addr, *src)) != 0) {
				return (rc);
			}
			addr++;
			src++;
			cnt--;
		}

		return (0);
	} else {

		/* Write to Intel 64-bit flash
		 */
		for (v=0; cc > 0; addr += 4, cc -= 4 - l) {
			l = (addr & 3);
			addr &= ~3;

			for (i = 0; i < 4; i++) {
				v = (v << 8) + (i < l || i - l >= cc ?
					*((unsigned char *) addr + i) : *src++);
			}

			if ((res = write_word (info, (volatile unsigned long *) addr, v)) != 0)
				break;
		}
	}

	return (res);
}

/*-----------------------------------------------------------------------
 * Write a word to Flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
static int write_word (flash_info_t * info, volatile unsigned long *addr,
					   ulong data)
{
	int flag, res = 0;
	ulong start;

	/* Check if Flash is (sufficiently) erased
	 */
	if ((*addr & data) != data)
		return (2);

	/* Disable interrupts which might cause a timeout here
	 */
	flag = disable_interrupts ();

	*addr = 0x00400040;
	*addr = data;

	/* re-enable interrupts if necessary
	 */
	if (flag)
		enable_interrupts ();

	start = get_timer (0);
	while ((*addr & 0x00800080) != 0x00800080) {
		if (get_timer (start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
			/* Suspend program
			 */
			*addr = 0x00B000B0;
			res = 1;
			goto OUT;
		}
	}

	if (*addr & 0x00220022) {
		printf ("*** ERROR: program failed!\n");
		res = 1;
	}

OUT:
	/* Clear status register and reset to read mode
	 */
	*addr = 0x00500050;
	*addr = 0x00FF00FF;

	return (res);
}

/*-----------------------------------------------------------------------
 * Write a byte to Flash, returns:
 * 0 - OK
 * 1 - write timeout
 * 2 - Flash not erased
 */
static int write_byte (flash_info_t *info, ulong dest, uchar data)
{
	vu_char *addr = (vu_char *)(info->start[0]);
	ulong start;
	int flag;

	/* Check if Flash is (sufficiently) erased */
	if ((*((vu_char *)dest) & data) != data) {
		return (2);
	}
	/* Disable interrupts which might cause a timeout here */
	flag = disable_interrupts();

	addr[0x0555] = 0xAA;
	addr[0x02AA] = 0x55;
	addr[0x0555] = 0xA0;

	*((vu_char *)dest) = data;

	/* re-enable interrupts if necessary */
	if (flag)
		enable_interrupts();

	/* data polling for D7 */
	start = get_timer (0);
	while ((*((vu_char *)dest) & 0x80) != (data & 0x80)) {
		if (get_timer(start) > CONFIG_SYS_FLASH_WRITE_TOUT) {
			return (1);
		}
	}
	return (0);
}

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