/*
 *
 * Atmel DataFlash probing
 *
 * Copyright (C) 2004-2009, 2015 Freescale Semiconductor, Inc.
 * Haikun Wang (haikun.wang@freescale.com)
 *
 * SPDX-License-Identifier:	GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <spi.h>
#include <spi_flash.h>
#include <div64.h>
#include <linux/err.h>
#include <linux/math64.h>

#include "sf_internal.h"

/* reads can bypass the buffers */
#define OP_READ_CONTINUOUS	0xE8
#define OP_READ_PAGE		0xD2

/* group B requests can run even while status reports "busy" */
#define OP_READ_STATUS		0xD7	/* group B */

/* move data between host and buffer */
#define OP_READ_BUFFER1		0xD4	/* group B */
#define OP_READ_BUFFER2		0xD6	/* group B */
#define OP_WRITE_BUFFER1	0x84	/* group B */
#define OP_WRITE_BUFFER2	0x87	/* group B */

/* erasing flash */
#define OP_ERASE_PAGE		0x81
#define OP_ERASE_BLOCK		0x50

/* move data between buffer and flash */
#define OP_TRANSFER_BUF1	0x53
#define OP_TRANSFER_BUF2	0x55
#define OP_MREAD_BUFFER1	0xD4
#define OP_MREAD_BUFFER2	0xD6
#define OP_MWERASE_BUFFER1	0x83
#define OP_MWERASE_BUFFER2	0x86
#define OP_MWRITE_BUFFER1	0x88	/* sector must be pre-erased */
#define OP_MWRITE_BUFFER2	0x89	/* sector must be pre-erased */

/* write to buffer, then write-erase to flash */
#define OP_PROGRAM_VIA_BUF1	0x82
#define OP_PROGRAM_VIA_BUF2	0x85

/* compare buffer to flash */
#define OP_COMPARE_BUF1		0x60
#define OP_COMPARE_BUF2		0x61

/* read flash to buffer, then write-erase to flash */
#define OP_REWRITE_VIA_BUF1	0x58
#define OP_REWRITE_VIA_BUF2	0x59

/*
 * newer chips report JEDEC manufacturer and device IDs; chip
 * serial number and OTP bits; and per-sector writeprotect.
 */
#define OP_READ_ID		0x9F
#define OP_READ_SECURITY	0x77
#define OP_WRITE_SECURITY_REVC	0x9A
#define OP_WRITE_SECURITY	0x9B	/* revision D */


struct dataflash {
	uint8_t			command[16];
	unsigned short		page_offset;	/* offset in flash address */
};

/*
 * Return the status of the DataFlash device.
 */
static inline int dataflash_status(struct spi_slave *spi)
{
	int ret;
	u8 status;
	/*
	 * NOTE:  at45db321c over 25 MHz wants to write
	 * a dummy byte after the opcode...
	 */
	ret = spi_flash_cmd(spi, OP_READ_STATUS, &status, 1);
	return ret ? -EIO : status;
}

/*
 * Poll the DataFlash device until it is READY.
 * This usually takes 5-20 msec or so; more for sector erase.
 * ready: return > 0
 */
static int dataflash_waitready(struct spi_slave *spi)
{
	int status;
	int timeout = 2 * CONFIG_SYS_HZ;
	int timebase;

	timebase = get_timer(0);
	do {
		status = dataflash_status(spi);
		if (status < 0)
			status = 0;

		if (status & (1 << 7))	/* RDY/nBSY */
			return status;

		mdelay(3);
	} while (get_timer(timebase) < timeout);

	return -ETIME;
}

/*
 * Erase pages of flash.
 */
static int spi_dataflash_erase(struct udevice *dev, u32 offset, size_t len)
{
	struct dataflash	*dataflash;
	struct spi_flash	*spi_flash;
	struct spi_slave	*spi;
	unsigned		blocksize;
	uint8_t			*command;
	uint32_t		rem;
	int			status;

	dataflash = dev_get_priv(dev);
	spi_flash = dev_get_uclass_priv(dev);
	spi = spi_flash->spi;

	blocksize = spi_flash->page_size << 3;

	memset(dataflash->command, 0 , sizeof(dataflash->command));
	command = dataflash->command;

	debug("%s: erase addr=0x%x len 0x%x\n", dev->name, offset, len);

	div_u64_rem(len, spi_flash->page_size, &rem);
	if (rem)
		return -EINVAL;
	div_u64_rem(offset, spi_flash->page_size, &rem);
	if (rem)
		return -EINVAL;

	status = spi_claim_bus(spi);
	if (status) {
		debug("SPI DATAFLASH: unable to claim SPI bus\n");
		return status;
	}

	while (len > 0) {
		unsigned int	pageaddr;
		int		do_block;
		/*
		 * Calculate flash page address; use block erase (for speed) if
		 * we're at a block boundary and need to erase the whole block.
		 */
		pageaddr = div_u64(offset, spi_flash->page_size);
		do_block = (pageaddr & 0x7) == 0 && len >= blocksize;
		pageaddr = pageaddr << dataflash->page_offset;

		command[0] = do_block ? OP_ERASE_BLOCK : OP_ERASE_PAGE;
		command[1] = (uint8_t)(pageaddr >> 16);
		command[2] = (uint8_t)(pageaddr >> 8);
		command[3] = 0;

		debug("%s ERASE %s: (%x) %x %x %x [%d]\n",
		      dev->name, do_block ? "block" : "page",
		      command[0], command[1], command[2], command[3],
		      pageaddr);

		status = spi_flash_cmd_write(spi, command, 4, NULL, 0);
		if (status < 0) {
			debug("%s: erase send command error!\n", dev->name);
			return -EIO;
		}

		status = dataflash_waitready(spi);
		if (status < 0) {
			debug("%s: erase waitready error!\n", dev->name);
			return status;
		}

		if (do_block) {
			offset += blocksize;
			len -= blocksize;
		} else {
			offset += spi_flash->page_size;
			len -= spi_flash->page_size;
		}
	}

	spi_release_bus(spi);

	return 0;
}

/*
 * Read from the DataFlash device.
 *   offset : Start offset in flash device
 *   len    : Amount to read
 *   buf    : Buffer containing the data
 */
static int spi_dataflash_read(struct udevice *dev, u32 offset, size_t len,
			      void *buf)
{
	struct dataflash	*dataflash;
	struct spi_flash	*spi_flash;
	struct spi_slave	*spi;
	unsigned int		addr;
	uint8_t			*command;
	int			status;

	dataflash = dev_get_priv(dev);
	spi_flash = dev_get_uclass_priv(dev);
	spi = spi_flash->spi;

	memset(dataflash->command, 0 , sizeof(dataflash->command));
	command = dataflash->command;

	debug("%s: erase addr=0x%x len 0x%x\n", dev->name, offset, len);
	debug("READ: (%x) %x %x %x\n",
	      command[0], command[1], command[2], command[3]);

	/* Calculate flash page/byte address */
	addr = (((unsigned)offset / spi_flash->page_size)
	       << dataflash->page_offset)
	       + ((unsigned)offset % spi_flash->page_size);

	status = spi_claim_bus(spi);
	if (status) {
		debug("SPI DATAFLASH: unable to claim SPI bus\n");
		return status;
	}

	/*
	 * Continuous read, max clock = f(car) which may be less than
	 * the peak rate available.  Some chips support commands with
	 * fewer "don't care" bytes.  Both buffers stay unchanged.
	 */
	command[0] = OP_READ_CONTINUOUS;
	command[1] = (uint8_t)(addr >> 16);
	command[2] = (uint8_t)(addr >> 8);
	command[3] = (uint8_t)(addr >> 0);

	/* plus 4 "don't care" bytes, command len: 4 + 4 "don't care" bytes */
	status = spi_flash_cmd_read(spi, command, 8, buf, len);

	spi_release_bus(spi);

	return status;
}

/*
 * Write to the DataFlash device.
 *   offset     : Start offset in flash device
 *   len    : Amount to write
 *   buf    : Buffer containing the data
 */
int spi_dataflash_write(struct udevice *dev, u32 offset, size_t len,
			const void *buf)
{
	struct dataflash	*dataflash;
	struct spi_flash	*spi_flash;
	struct spi_slave	*spi;
	uint8_t			*command;
	unsigned int		pageaddr, addr, to, writelen;
	size_t			remaining = len;
	u_char			*writebuf = (u_char *)buf;
	int			status = -EINVAL;

	dataflash = dev_get_priv(dev);
	spi_flash = dev_get_uclass_priv(dev);
	spi = spi_flash->spi;

	memset(dataflash->command, 0 , sizeof(dataflash->command));
	command = dataflash->command;

	debug("%s: write 0x%x..0x%x\n", dev->name, offset, (offset + len));

	pageaddr = ((unsigned)offset / spi_flash->page_size);
	to = ((unsigned)offset % spi_flash->page_size);
	if (to + len > spi_flash->page_size)
		writelen = spi_flash->page_size - to;
	else
		writelen = len;

	status = spi_claim_bus(spi);
	if (status) {
		debug("SPI DATAFLASH: unable to claim SPI bus\n");
		return status;
	}

	while (remaining > 0) {
		debug("write @ %d:%d len=%d\n", pageaddr, to, writelen);

		/*
		 * REVISIT:
		 * (a) each page in a sector must be rewritten at least
		 *     once every 10K sibling erase/program operations.
		 * (b) for pages that are already erased, we could
		 *     use WRITE+MWRITE not PROGRAM for ~30% speedup.
		 * (c) WRITE to buffer could be done while waiting for
		 *     a previous MWRITE/MWERASE to complete ...
		 * (d) error handling here seems to be mostly missing.
		 *
		 * Two persistent bits per page, plus a per-sector counter,
		 * could support (a) and (b) ... we might consider using
		 * the second half of sector zero, which is just one block,
		 * to track that state.  (On AT91, that sector should also
		 * support boot-from-DataFlash.)
		 */

		addr = pageaddr << dataflash->page_offset;

		/* (1) Maybe transfer partial page to Buffer1 */
		if (writelen != spi_flash->page_size) {
			command[0] = OP_TRANSFER_BUF1;
			command[1] = (addr & 0x00FF0000) >> 16;
			command[2] = (addr & 0x0000FF00) >> 8;
			command[3] = 0;

			debug("TRANSFER: (%x) %x %x %x\n",
			      command[0], command[1], command[2], command[3]);

			status = spi_flash_cmd_write(spi, command, 4, NULL, 0);
			if (status < 0) {
				debug("%s: write(<pagesize) command error!\n",
				      dev->name);
				return -EIO;
			}

			status = dataflash_waitready(spi);
			if (status < 0) {
				debug("%s: write(<pagesize) waitready error!\n",
				      dev->name);
				return status;
			}
		}

		/* (2) Program full page via Buffer1 */
		addr += to;
		command[0] = OP_PROGRAM_VIA_BUF1;
		command[1] = (addr & 0x00FF0000) >> 16;
		command[2] = (addr & 0x0000FF00) >> 8;
		command[3] = (addr & 0x000000FF);

		debug("PROGRAM: (%x) %x %x %x\n",
		      command[0], command[1], command[2], command[3]);

		status = spi_flash_cmd_write(spi, command,
					     4, writebuf, writelen);
		if (status < 0) {
			debug("%s: write send command error!\n", dev->name);
			return -EIO;
		}

		status = dataflash_waitready(spi);
		if (status < 0) {
			debug("%s: write waitready error!\n", dev->name);
			return status;
		}

#ifdef CONFIG_SPI_DATAFLASH_WRITE_VERIFY
		/* (3) Compare to Buffer1 */
		addr = pageaddr << dataflash->page_offset;
		command[0] = OP_COMPARE_BUF1;
		command[1] = (addr & 0x00FF0000) >> 16;
		command[2] = (addr & 0x0000FF00) >> 8;
		command[3] = 0;

		debug("COMPARE: (%x) %x %x %x\n",
		      command[0], command[1], command[2], command[3]);

		status = spi_flash_cmd_write(spi, command,
					     4, writebuf, writelen);
		if (status < 0) {
			debug("%s: write(compare) send command error!\n",
			      dev->name);
			return -EIO;
		}

		status = dataflash_waitready(spi);

		/* Check result of the compare operation */
		if (status & (1 << 6)) {
			printf("SPI DataFlash: write compare page %u, err %d\n",
			       pageaddr, status);
			remaining = 0;
			status = -EIO;
			break;
		} else {
			status = 0;
		}

#endif	/* CONFIG_SPI_DATAFLASH_WRITE_VERIFY */
		remaining = remaining - writelen;
		pageaddr++;
		to = 0;
		writebuf += writelen;

		if (remaining > spi_flash->page_size)
			writelen = spi_flash->page_size;
		else
			writelen = remaining;
	}

	spi_release_bus(spi);

	return 0;
}

static int add_dataflash(struct udevice *dev, char *name, int nr_pages,
			     int pagesize, int pageoffset, char revision)
{
	struct spi_flash *spi_flash;
	struct dataflash *dataflash;

	dataflash = dev_get_priv(dev);
	spi_flash = dev_get_uclass_priv(dev);

	dataflash->page_offset = pageoffset;

	spi_flash->name = name;
	spi_flash->page_size = pagesize;
	spi_flash->size = nr_pages * pagesize;
	spi_flash->erase_size = pagesize;

#ifndef CONFIG_SPL_BUILD
	printf("SPI DataFlash: Detected %s with page size ", spi_flash->name);
	print_size(spi_flash->page_size, ", erase size ");
	print_size(spi_flash->erase_size, ", total ");
	print_size(spi_flash->size, "");
	printf(", revision %c", revision);
	puts("\n");
#endif

	return 0;
}

struct flash_info {
	char		*name;

	/*
	 * JEDEC id has a high byte of zero plus three data bytes:
	 * the manufacturer id, then a two byte device id.
	 */
	uint32_t	jedec_id;

	/* The size listed here is what works with OP_ERASE_PAGE. */
	unsigned	nr_pages;
	uint16_t	pagesize;
	uint16_t	pageoffset;

	uint16_t	flags;
#define SUP_POW2PS	0x0002		/* supports 2^N byte pages */
#define IS_POW2PS	0x0001		/* uses 2^N byte pages */
};

static struct flash_info dataflash_data[] = {
	/*
	 * NOTE:  chips with SUP_POW2PS (rev D and up) need two entries,
	 * one with IS_POW2PS and the other without.  The entry with the
	 * non-2^N byte page size can't name exact chip revisions without
	 * losing backwards compatibility for cmdlinepart.
	 *
	 * Those two entries have different name spelling format in order to
	 * show their difference obviously.
	 * The upper case refer to the chip isn't in normal 2^N bytes page-size
	 * mode.
	 * The lower case refer to the chip is in normal 2^N bytes page-size
	 * mode.
	 *
	 * These newer chips also support 128-byte security registers (with
	 * 64 bytes one-time-programmable) and software write-protection.
	 */
	{ "AT45DB011B",  0x1f2200, 512, 264, 9, SUP_POW2PS},
	{ "at45db011d",  0x1f2200, 512, 256, 8, SUP_POW2PS | IS_POW2PS},

	{ "AT45DB021B",  0x1f2300, 1024, 264, 9, SUP_POW2PS},
	{ "at45db021d",  0x1f2300, 1024, 256, 8, SUP_POW2PS | IS_POW2PS},

	{ "AT45DB041x",  0x1f2400, 2048, 264, 9, SUP_POW2PS},
	{ "at45db041d",  0x1f2400, 2048, 256, 8, SUP_POW2PS | IS_POW2PS},

	{ "AT45DB081B",  0x1f2500, 4096, 264, 9, SUP_POW2PS},
	{ "at45db081d",  0x1f2500, 4096, 256, 8, SUP_POW2PS | IS_POW2PS},

	{ "AT45DB161x",  0x1f2600, 4096, 528, 10, SUP_POW2PS},
	{ "at45db161d",  0x1f2600, 4096, 512, 9, SUP_POW2PS | IS_POW2PS},

	{ "AT45DB321x",  0x1f2700, 8192, 528, 10, 0},		/* rev C */

	{ "AT45DB321x",  0x1f2701, 8192, 528, 10, SUP_POW2PS},
	{ "at45db321d",  0x1f2701, 8192, 512, 9, SUP_POW2PS | IS_POW2PS},

	{ "AT45DB642x",  0x1f2800, 8192, 1056, 11, SUP_POW2PS},
	{ "at45db642d",  0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS},
};

static struct flash_info *jedec_probe(struct spi_slave *spi, u8 *id)
{
	int			tmp;
	uint32_t		jedec;
	struct flash_info	*info;
	int status;

	/*
	 * JEDEC also defines an optional "extended device information"
	 * string for after vendor-specific data, after the three bytes
	 * we use here.  Supporting some chips might require using it.
	 *
	 * If the vendor ID isn't Atmel's (0x1f), assume this call failed.
	 * That's not an error; only rev C and newer chips handle it, and
	 * only Atmel sells these chips.
	 */
	if (id[0] != 0x1f)
		return NULL;

	jedec = id[0];
	jedec = jedec << 8;
	jedec |= id[1];
	jedec = jedec << 8;
	jedec |= id[2];

	for (tmp = 0, info = dataflash_data;
			tmp < ARRAY_SIZE(dataflash_data);
			tmp++, info++) {
		if (info->jedec_id == jedec) {
			if (info->flags & SUP_POW2PS) {
				status = dataflash_status(spi);
				if (status < 0) {
					debug("SPI DataFlash: status error %d\n",
					      status);
					return NULL;
				}
				if (status & 0x1) {
					if (info->flags & IS_POW2PS)
						return info;
				} else {
					if (!(info->flags & IS_POW2PS))
						return info;
				}
			} else {
				return info;
			}
		}
	}

	/*
	 * Treat other chips as errors ... we won't know the right page
	 * size (it might be binary) even when we can tell which density
	 * class is involved (legacy chip id scheme).
	 */
	printf("SPI DataFlash: Unsupported flash IDs: ");
	printf("manuf %02x, jedec %04x, ext_jedec %04x\n",
	       id[0], jedec, id[3] << 8 | id[4]);
	return NULL;
}

/*
 * Detect and initialize DataFlash device, using JEDEC IDs on newer chips
 * or else the ID code embedded in the status bits:
 *
 *   Device      Density         ID code          #Pages PageSize  Offset
 *   AT45DB011B  1Mbit   (128K)  xx0011xx (0x0c)    512    264      9
 *   AT45DB021B  2Mbit   (256K)  xx0101xx (0x14)   1024    264      9
 *   AT45DB041B  4Mbit   (512K)  xx0111xx (0x1c)   2048    264      9
 *   AT45DB081B  8Mbit   (1M)    xx1001xx (0x24)   4096    264      9
 *   AT45DB0161B 16Mbit  (2M)    xx1011xx (0x2c)   4096    528     10
 *   AT45DB0321B 32Mbit  (4M)    xx1101xx (0x34)   8192    528     10
 *   AT45DB0642  64Mbit  (8M)    xx111xxx (0x3c)   8192   1056     11
 *   AT45DB1282  128Mbit (16M)   xx0100xx (0x10)  16384   1056     11
 */
static int spi_dataflash_probe(struct udevice *dev)
{
	struct spi_slave *spi = dev_get_parent_priv(dev);
	struct spi_flash *spi_flash;
	struct flash_info *info;
	u8 idcode[5];
	int ret, status = 0;

	spi_flash = dev_get_uclass_priv(dev);
	spi_flash->dev = dev;

	ret = spi_claim_bus(spi);
	if (ret)
		return ret;

	ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode));
	if (ret) {
		printf("SPI DataFlash: Failed to get idcodes\n");
		goto err_read_cmd;
	}

	/*
	 * Try to detect dataflash by JEDEC ID.
	 * If it succeeds we know we have either a C or D part.
	 * D will support power of 2 pagesize option.
	 * Both support the security register, though with different
	 * write procedures.
	 */
	info = jedec_probe(spi, idcode);
	if (info != NULL)
		add_dataflash(dev, info->name, info->nr_pages,
			      info->pagesize, info->pageoffset,
			      (info->flags & SUP_POW2PS) ? 'd' : 'c');
	else {
		/*
		* Older chips support only legacy commands, identifing
		* capacity using bits in the status byte.
		*/
		status = dataflash_status(spi);
		if (status <= 0 || status == 0xff) {
			printf("SPI DataFlash: read status error %d\n", status);
			if (status == 0 || status == 0xff)
				status = -ENODEV;
			goto err_read_cmd;
		}
		/*
		* if there's a device there, assume it's dataflash.
		* board setup should have set spi->max_speed_max to
		* match f(car) for continuous reads, mode 0 or 3.
		*/
		switch (status & 0x3c) {
		case 0x0c:	/* 0 0 1 1 x x */
			status = add_dataflash(dev, "AT45DB011B",
					       512, 264, 9, 0);
			break;
		case 0x14:	/* 0 1 0 1 x x */
			status = add_dataflash(dev, "AT45DB021B",
					       1024, 264, 9, 0);
			break;
		case 0x1c:	/* 0 1 1 1 x x */
			status = add_dataflash(dev, "AT45DB041x",
					       2048, 264, 9, 0);
			break;
		case 0x24:	/* 1 0 0 1 x x */
			status = add_dataflash(dev, "AT45DB081B",
					       4096, 264, 9, 0);
			break;
		case 0x2c:	/* 1 0 1 1 x x */
			status = add_dataflash(dev, "AT45DB161x",
					       4096, 528, 10, 0);
			break;
		case 0x34:	/* 1 1 0 1 x x */
			status = add_dataflash(dev, "AT45DB321x",
					       8192, 528, 10, 0);
			break;
		case 0x38:	/* 1 1 1 x x x */
		case 0x3c:
			status = add_dataflash(dev, "AT45DB642x",
					       8192, 1056, 11, 0);
			break;
		/* obsolete AT45DB1282 not (yet?) supported */
		default:
			dev_info(&spi->dev, "unsupported device (%x)\n",
				 status & 0x3c);
			status = -ENODEV;
			goto err_read_cmd;
		}
	}

	/* Assign spi data */
	spi_flash->spi = spi;
	spi_flash->memory_map = spi->memory_map;
	spi_flash->dual_flash = spi->option;

	spi_release_bus(spi);

	return 0;

err_read_cmd:
	spi_release_bus(spi);

	return status;
}

static const struct dm_spi_flash_ops spi_dataflash_ops = {
	.read = spi_dataflash_read,
	.write = spi_dataflash_write,
	.erase = spi_dataflash_erase,
};

static const struct udevice_id spi_dataflash_ids[] = {
	{ .compatible = "atmel,at45", },
	{ .compatible = "atmel,dataflash", },
	{ }
};

U_BOOT_DRIVER(spi_dataflash) = {
	.name		= "spi_dataflash",
	.id		= UCLASS_SPI_FLASH,
	.of_match	= spi_dataflash_ids,
	.probe		= spi_dataflash_probe,
	.priv_auto_alloc_size = sizeof(struct dataflash),
	.ops		= &spi_dataflash_ops,
};
