/*
 * Copyright (C) 2015
 * Cristian Birsan <cristian.birsan@microchip.com>
 * Purna Chandra Mandal <purna.mandal@microchip.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <dm.h>
#include <fdt_support.h>
#include <flash.h>
#include <mach/pic32.h>
#include <wait_bit.h>

DECLARE_GLOBAL_DATA_PTR;

/* NVM Controller registers */
struct pic32_reg_nvm {
	struct pic32_reg_atomic ctrl;
	struct pic32_reg_atomic key;
	struct pic32_reg_atomic addr;
	struct pic32_reg_atomic data;
};

/* NVM operations */
#define NVMOP_NOP		0
#define NVMOP_WORD_WRITE	1
#define NVMOP_PAGE_ERASE	4

/* NVM control bits */
#define NVM_WR			BIT(15)
#define NVM_WREN		BIT(14)
#define NVM_WRERR		BIT(13)
#define NVM_LVDERR		BIT(12)

/* NVM programming unlock register */
#define LOCK_KEY		0x0
#define UNLOCK_KEY1		0xaa996655
#define UNLOCK_KEY2		0x556699aa

/*
 * PIC32 flash banks consist of number of pages, each page
 * into number of rows and rows into number of words.
 * Here we will maintain page information instead of sector.
 */
flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
static struct pic32_reg_nvm *nvm_regs_p;

static inline void flash_initiate_operation(u32 nvmop)
{
	/* set operation */
	writel(nvmop, &nvm_regs_p->ctrl.raw);

	/* enable flash write */
	writel(NVM_WREN, &nvm_regs_p->ctrl.set);

	/* unlock sequence */
	writel(LOCK_KEY, &nvm_regs_p->key.raw);
	writel(UNLOCK_KEY1, &nvm_regs_p->key.raw);
	writel(UNLOCK_KEY2, &nvm_regs_p->key.raw);

	/* initiate operation */
	writel(NVM_WR, &nvm_regs_p->ctrl.set);
}

static int flash_wait_till_busy(const char *func, ulong timeout)
{
	int ret = wait_for_bit(__func__, &nvm_regs_p->ctrl.raw,
			       NVM_WR, false, timeout, false);

	return ret ? ERR_TIMOUT : ERR_OK;
}

static inline int flash_complete_operation(void)
{
	u32 tmp;

	tmp = readl(&nvm_regs_p->ctrl.raw);
	if (tmp & NVM_WRERR) {
		printf("Error in Block Erase - Lock Bit may be set!\n");
		flash_initiate_operation(NVMOP_NOP);
		return ERR_PROTECTED;
	}

	if (tmp & NVM_LVDERR) {
		printf("Error in Block Erase - low-vol detected!\n");
		flash_initiate_operation(NVMOP_NOP);
		return ERR_NOT_ERASED;
	}

	/* disable flash write or erase operation */
	writel(NVM_WREN, &nvm_regs_p->ctrl.clr);

	return ERR_OK;
}

/*
 * Erase flash sectors, returns:
 * ERR_OK - OK
 * ERR_INVAL - invalid sector arguments
 * ERR_TIMOUT - write timeout
 * ERR_NOT_ERASED - Flash not erased
 * ERR_UNKNOWN_FLASH_VENDOR - incorrect flash
 */
int flash_erase(flash_info_t *info, int s_first, int s_last)
{
	ulong sect_start, sect_end, flags;
	int prot, sect;
	int rc;

	if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_MCHP) {
		printf("Can't erase unknown flash type %08lx - aborted\n",
		       info->flash_id);
		return ERR_UNKNOWN_FLASH_VENDOR;
	}

	if ((s_first < 0) || (s_first > s_last)) {
		printf("- no sectors to erase\n");
		return ERR_INVAL;
	}

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

	/* erase on unprotected sectors */
	for (sect = s_first; sect <= s_last; sect++) {
		if (info->protect[sect])
			continue;

		/* disable interrupts */
		flags = disable_interrupts();

		/* write destination page address (physical) */
		sect_start = CPHYSADDR(info->start[sect]);
		writel(sect_start, &nvm_regs_p->addr.raw);

		/* page erase */
		flash_initiate_operation(NVMOP_PAGE_ERASE);

		/* wait */
		rc = flash_wait_till_busy(__func__,
					  CONFIG_SYS_FLASH_ERASE_TOUT);

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

		if (rc != ERR_OK)
			return rc;

		rc = flash_complete_operation();
		if (rc != ERR_OK)
			return rc;

		/*
		 * flash content is updated but cache might contain stale
		 * data, so invalidate dcache.
		 */
		sect_end = info->start[sect] + info->size / info->sector_count;
		invalidate_dcache_range(info->start[sect], sect_end);
	}

	printf(" done\n");
	return ERR_OK;
}

int page_erase(flash_info_t *info, int sect)
{
	return 0;
}

/* Write a word to flash */
static int write_word(flash_info_t *info, ulong dest, ulong word)
{
	ulong flags;
	int rc;

	/* read flash to check if it is sufficiently erased */
	if ((readl((void __iomem *)dest) & word) != word) {
		printf("Error, Flash not erased!\n");
		return ERR_NOT_ERASED;
	}

	/* disable interrupts */
	flags = disable_interrupts();

	/* update destination page address (physical) */
	writel(CPHYSADDR(dest), &nvm_regs_p->addr.raw);
	writel(word, &nvm_regs_p->data.raw);

	/* word write */
	flash_initiate_operation(NVMOP_WORD_WRITE);

	/* wait for operation to complete */
	rc = flash_wait_till_busy(__func__, CONFIG_SYS_FLASH_WRITE_TOUT);

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

	if (rc != ERR_OK)
		return rc;

	return flash_complete_operation();
}

/*
 * Copy memory to flash, returns:
 * ERR_OK - OK
 * ERR_TIMOUT - write timeout
 * ERR_NOT_ERASED - Flash not erased
 */
int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
{
	ulong dst, tmp_le, len = cnt;
	int i, l, rc;
	uchar *cp;

	/* get lower word aligned address */
	dst = (addr & ~3);

	/* handle unaligned start bytes */
	l = addr - dst;
	if (l != 0) {
		tmp_le = 0;
		for (i = 0, cp = (uchar *)dst; i < l; ++i, ++cp)
			tmp_le |= *cp << (i * 8);

		for (; (i < 4) && (cnt > 0); ++i, ++src, --cnt, ++cp)
			tmp_le |= *src << (i * 8);

		for (; (cnt == 0) && (i < 4); ++i, ++cp)
			tmp_le |= *cp << (i * 8);

		rc = write_word(info, dst, tmp_le);
		if (rc)
			goto out;

		dst += 4;
	}

	/* handle word aligned part */
	while (cnt >= 4) {
		tmp_le = src[0] | src[1] << 8 | src[2] << 16 | src[3] << 24;
		rc = write_word(info, dst, tmp_le);
		if (rc)
			goto out;
		src += 4;
		dst += 4;
		cnt -= 4;
	}

	if (cnt == 0) {
		rc = ERR_OK;
		goto out;
	}

	/* handle unaligned tail bytes */
	tmp_le = 0;
	for (i = 0, cp = (uchar *)dst; (i < 4) && (cnt > 0); ++i, ++cp) {
		tmp_le |= *src++ << (i * 8);
		--cnt;
	}

	for (; i < 4; ++i, ++cp)
		tmp_le |= *cp << (i * 8);

	rc = write_word(info, dst, tmp_le);
out:
	/*
	 * flash content updated by nvm controller but CPU cache might
	 * have stale data, so invalidate dcache.
	 */
	invalidate_dcache_range(addr, addr + len);

	printf(" done\n");
	return rc;
}

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 & FLASH_VENDMASK) {
	case FLASH_MAN_MCHP:
		printf("Microchip Technology ");
		break;
	default:
		printf("Unknown Vendor ");
		break;
	}

	switch (info->flash_id & FLASH_TYPEMASK) {
	case FLASH_MCHP100T:
		printf("Internal (8 Mbit, 64 x 16k)\n");
		break;
	default:
		printf("Unknown Chip Type\n");
		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");
}

unsigned long flash_init(void)
{
	unsigned long size = 0;
	struct udevice *dev;
	int bank;

	/* probe every MTD device */
	for (uclass_first_device(UCLASS_MTD, &dev); dev;
	     uclass_next_device(&dev)) {
		/* nop */
	}

	/* calc total flash size */
	for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank)
		size += flash_info[bank].size;

	return size;
}

static void pic32_flash_bank_init(flash_info_t *info,
				  ulong base, ulong size)
{
	ulong sect_size;
	int sect;

	/* device & manufacturer code */
	info->flash_id = FLASH_MAN_MCHP | FLASH_MCHP100T;
	info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
	info->size = size;

	/* update sector (i.e page) info */
	sect_size = info->size / info->sector_count;
	for (sect = 0; sect < info->sector_count; sect++) {
		info->start[sect] = base;
		/* protect each sector by default */
		info->protect[sect] = 1;
		base += sect_size;
	}
}

static int pic32_flash_probe(struct udevice *dev)
{
	void *blob = (void *)gd->fdt_blob;
	int node = dev_of_offset(dev);
	const char *list, *end;
	const fdt32_t *cell;
	unsigned long addr, size;
	int parent, addrc, sizec;
	flash_info_t *info;
	int len, idx;

	/*
	 * decode regs. there are multiple reg tuples, and they need to
	 * match with reg-names.
	 */
	parent = fdt_parent_offset(blob, node);
	of_bus_default_count_cells(blob, parent, &addrc, &sizec);
	list = fdt_getprop(blob, node, "reg-names", &len);
	if (!list)
		return -ENOENT;

	end = list + len;
	cell = fdt_getprop(blob, node, "reg", &len);
	if (!cell)
		return -ENOENT;

	for (idx = 0, info = &flash_info[0]; list < end;) {
		addr = fdt_translate_address((void *)blob, node, cell + idx);
		size = fdt_addr_to_cpu(cell[idx + addrc]);
		len = strlen(list);
		if (!strncmp(list, "nvm", len)) {
			/* NVM controller */
			nvm_regs_p = ioremap(addr, size);
		} else if (!strncmp(list, "bank", 4)) {
			/* Flash bank: use kseg0 cached address */
			pic32_flash_bank_init(info, CKSEG0ADDR(addr), size);
			info++;
		}
		idx += addrc + sizec;
		list += len + 1;
	}

	/* disable flash write/erase operations */
	writel(NVM_WREN, &nvm_regs_p->ctrl.clr);

#if (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
	/* monitor protection ON by default */
	flash_protect(FLAG_PROTECT_SET,
		      CONFIG_SYS_MONITOR_BASE,
		      CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
		      &flash_info[0]);
#endif

#ifdef CONFIG_ENV_IS_IN_FLASH
	/* ENV protection ON by default */
	flash_protect(FLAG_PROTECT_SET,
		      CONFIG_ENV_ADDR,
		      CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
		      &flash_info[0]);
#endif
	return 0;
}

static const struct udevice_id pic32_flash_ids[] = {
	{ .compatible = "microchip,pic32mzda-flash" },
	{}
};

U_BOOT_DRIVER(pic32_flash) = {
	.name	= "pic32_flash",
	.id	= UCLASS_MTD,
	.of_match = pic32_flash_ids,
	.probe	= pic32_flash_probe,
};
