/*
 *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
 *  JZ4740 SoC NAND controller driver
 *
 *  This program is free software; you can redistribute it and/or modify it
 *  under  the terms of the GNU General  Public License as published by the
 *  Free Software Foundation;  either version 2 of the License, or (at your
 *  option) any later version.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>

#include <linux/gpio.h>

#include <asm/mach-jz4740/gpio.h>
#include <asm/mach-jz4740/jz4740_nand.h>

#define JZ_REG_NAND_CTRL	0x50
#define JZ_REG_NAND_ECC_CTRL	0x100
#define JZ_REG_NAND_DATA	0x104
#define JZ_REG_NAND_PAR0	0x108
#define JZ_REG_NAND_PAR1	0x10C
#define JZ_REG_NAND_PAR2	0x110
#define JZ_REG_NAND_IRQ_STAT	0x114
#define JZ_REG_NAND_IRQ_CTRL	0x118
#define JZ_REG_NAND_ERR(x)	(0x11C + ((x) << 2))

#define JZ_NAND_ECC_CTRL_PAR_READY	BIT(4)
#define JZ_NAND_ECC_CTRL_ENCODING	BIT(3)
#define JZ_NAND_ECC_CTRL_RS		BIT(2)
#define JZ_NAND_ECC_CTRL_RESET		BIT(1)
#define JZ_NAND_ECC_CTRL_ENABLE		BIT(0)

#define JZ_NAND_STATUS_ERR_COUNT	(BIT(31) | BIT(30) | BIT(29))
#define JZ_NAND_STATUS_PAD_FINISH	BIT(4)
#define JZ_NAND_STATUS_DEC_FINISH	BIT(3)
#define JZ_NAND_STATUS_ENC_FINISH	BIT(2)
#define JZ_NAND_STATUS_UNCOR_ERROR	BIT(1)
#define JZ_NAND_STATUS_ERROR		BIT(0)

#define JZ_NAND_CTRL_ENABLE_CHIP(x) BIT((x) << 1)
#define JZ_NAND_CTRL_ASSERT_CHIP(x) BIT(((x) << 1) + 1)
#define JZ_NAND_CTRL_ASSERT_CHIP_MASK 0xaa

#define JZ_NAND_MEM_CMD_OFFSET 0x08000
#define JZ_NAND_MEM_ADDR_OFFSET 0x10000

struct jz_nand {
	struct mtd_info mtd;
	struct nand_chip chip;
	void __iomem *base;
	struct resource *mem;

	unsigned char banks[JZ_NAND_NUM_BANKS];
	void __iomem *bank_base[JZ_NAND_NUM_BANKS];
	struct resource *bank_mem[JZ_NAND_NUM_BANKS];

	int selected_bank;

	struct gpio_desc *busy_gpio;
	bool is_reading;
};

static inline struct jz_nand *mtd_to_jz_nand(struct mtd_info *mtd)
{
	return container_of(mtd, struct jz_nand, mtd);
}

static void jz_nand_select_chip(struct mtd_info *mtd, int chipnr)
{
	struct jz_nand *nand = mtd_to_jz_nand(mtd);
	struct nand_chip *chip = mtd->priv;
	uint32_t ctrl;
	int banknr;

	ctrl = readl(nand->base + JZ_REG_NAND_CTRL);
	ctrl &= ~JZ_NAND_CTRL_ASSERT_CHIP_MASK;

	if (chipnr == -1) {
		banknr = -1;
	} else {
		banknr = nand->banks[chipnr] - 1;
		chip->IO_ADDR_R = nand->bank_base[banknr];
		chip->IO_ADDR_W = nand->bank_base[banknr];
	}
	writel(ctrl, nand->base + JZ_REG_NAND_CTRL);

	nand->selected_bank = banknr;
}

static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl)
{
	struct jz_nand *nand = mtd_to_jz_nand(mtd);
	struct nand_chip *chip = mtd->priv;
	uint32_t reg;
	void __iomem *bank_base = nand->bank_base[nand->selected_bank];

	BUG_ON(nand->selected_bank < 0);

	if (ctrl & NAND_CTRL_CHANGE) {
		BUG_ON((ctrl & NAND_ALE) && (ctrl & NAND_CLE));
		if (ctrl & NAND_ALE)
			bank_base += JZ_NAND_MEM_ADDR_OFFSET;
		else if (ctrl & NAND_CLE)
			bank_base += JZ_NAND_MEM_CMD_OFFSET;
		chip->IO_ADDR_W = bank_base;

		reg = readl(nand->base + JZ_REG_NAND_CTRL);
		if (ctrl & NAND_NCE)
			reg |= JZ_NAND_CTRL_ASSERT_CHIP(nand->selected_bank);
		else
			reg &= ~JZ_NAND_CTRL_ASSERT_CHIP(nand->selected_bank);
		writel(reg, nand->base + JZ_REG_NAND_CTRL);
	}
	if (dat != NAND_CMD_NONE)
		writeb(dat, chip->IO_ADDR_W);
}

static int jz_nand_dev_ready(struct mtd_info *mtd)
{
	struct jz_nand *nand = mtd_to_jz_nand(mtd);
	return gpiod_get_value_cansleep(nand->busy_gpio);
}

static void jz_nand_hwctl(struct mtd_info *mtd, int mode)
{
	struct jz_nand *nand = mtd_to_jz_nand(mtd);
	uint32_t reg;

	writel(0, nand->base + JZ_REG_NAND_IRQ_STAT);
	reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL);

	reg |= JZ_NAND_ECC_CTRL_RESET;
	reg |= JZ_NAND_ECC_CTRL_ENABLE;
	reg |= JZ_NAND_ECC_CTRL_RS;

	switch (mode) {
	case NAND_ECC_READ:
		reg &= ~JZ_NAND_ECC_CTRL_ENCODING;
		nand->is_reading = true;
		break;
	case NAND_ECC_WRITE:
		reg |= JZ_NAND_ECC_CTRL_ENCODING;
		nand->is_reading = false;
		break;
	default:
		break;
	}

	writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL);
}

static int jz_nand_calculate_ecc_rs(struct mtd_info *mtd, const uint8_t *dat,
	uint8_t *ecc_code)
{
	struct jz_nand *nand = mtd_to_jz_nand(mtd);
	uint32_t reg, status;
	int i;
	unsigned int timeout = 1000;
	static uint8_t empty_block_ecc[] = {0xcd, 0x9d, 0x90, 0x58, 0xf4,
						0x8b, 0xff, 0xb7, 0x6f};

	if (nand->is_reading)
		return 0;

	do {
		status = readl(nand->base + JZ_REG_NAND_IRQ_STAT);
	} while (!(status & JZ_NAND_STATUS_ENC_FINISH) && --timeout);

	if (timeout == 0)
	    return -1;

	reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL);
	reg &= ~JZ_NAND_ECC_CTRL_ENABLE;
	writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL);

	for (i = 0; i < 9; ++i)
		ecc_code[i] = readb(nand->base + JZ_REG_NAND_PAR0 + i);

	/* If the written data is completly 0xff, we also want to write 0xff as
	 * ecc, otherwise we will get in trouble when doing subpage writes. */
	if (memcmp(ecc_code, empty_block_ecc, 9) == 0)
		memset(ecc_code, 0xff, 9);

	return 0;
}

static void jz_nand_correct_data(uint8_t *dat, int index, int mask)
{
	int offset = index & 0x7;
	uint16_t data;

	index += (index >> 3);

	data = dat[index];
	data |= dat[index+1] << 8;

	mask ^= (data >> offset) & 0x1ff;
	data &= ~(0x1ff << offset);
	data |= (mask << offset);

	dat[index] = data & 0xff;
	dat[index+1] = (data >> 8) & 0xff;
}

static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat,
	uint8_t *read_ecc, uint8_t *calc_ecc)
{
	struct jz_nand *nand = mtd_to_jz_nand(mtd);
	int i, error_count, index;
	uint32_t reg, status, error;
	uint32_t t;
	unsigned int timeout = 1000;

	t = read_ecc[0];

	if (t == 0xff) {
		for (i = 1; i < 9; ++i)
			t &= read_ecc[i];

		t &= dat[0];
		t &= dat[nand->chip.ecc.size / 2];
		t &= dat[nand->chip.ecc.size - 1];

		if (t == 0xff) {
			for (i = 1; i < nand->chip.ecc.size - 1; ++i)
				t &= dat[i];
			if (t == 0xff)
				return 0;
		}
	}

	for (i = 0; i < 9; ++i)
		writeb(read_ecc[i], nand->base + JZ_REG_NAND_PAR0 + i);

	reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL);
	reg |= JZ_NAND_ECC_CTRL_PAR_READY;
	writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL);

	do {
		status = readl(nand->base + JZ_REG_NAND_IRQ_STAT);
	} while (!(status & JZ_NAND_STATUS_DEC_FINISH) && --timeout);

	if (timeout == 0)
	    return -1;

	reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL);
	reg &= ~JZ_NAND_ECC_CTRL_ENABLE;
	writel(reg, nand->base + JZ_REG_NAND_ECC_CTRL);

	if (status & JZ_NAND_STATUS_ERROR) {
		if (status & JZ_NAND_STATUS_UNCOR_ERROR)
			return -1;

		error_count = (status & JZ_NAND_STATUS_ERR_COUNT) >> 29;

		for (i = 0; i < error_count; ++i) {
			error = readl(nand->base + JZ_REG_NAND_ERR(i));
			index = ((error >> 16) & 0x1ff) - 1;
			if (index >= 0 && index < 512)
				jz_nand_correct_data(dat, index, error & 0x1ff);
		}

		return error_count;
	}

	return 0;
}

static int jz_nand_ioremap_resource(struct platform_device *pdev,
	const char *name, struct resource **res, void *__iomem *base)
{
	int ret;

	*res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
	if (!*res) {
		dev_err(&pdev->dev, "Failed to get platform %s memory\n", name);
		ret = -ENXIO;
		goto err;
	}

	*res = request_mem_region((*res)->start, resource_size(*res),
				pdev->name);
	if (!*res) {
		dev_err(&pdev->dev, "Failed to request %s memory region\n", name);
		ret = -EBUSY;
		goto err;
	}

	*base = ioremap((*res)->start, resource_size(*res));
	if (!*base) {
		dev_err(&pdev->dev, "Failed to ioremap %s memory region\n", name);
		ret = -EBUSY;
		goto err_release_mem;
	}

	return 0;

err_release_mem:
	release_mem_region((*res)->start, resource_size(*res));
err:
	*res = NULL;
	*base = NULL;
	return ret;
}

static inline void jz_nand_iounmap_resource(struct resource *res,
					    void __iomem *base)
{
	iounmap(base);
	release_mem_region(res->start, resource_size(res));
}

static int jz_nand_detect_bank(struct platform_device *pdev,
			       struct jz_nand *nand, unsigned char bank,
			       size_t chipnr, uint8_t *nand_maf_id,
			       uint8_t *nand_dev_id)
{
	int ret;
	int gpio;
	char gpio_name[9];
	char res_name[6];
	uint32_t ctrl;
	struct mtd_info *mtd = &nand->mtd;
	struct nand_chip *chip = &nand->chip;

	/* Request GPIO port. */
	gpio = JZ_GPIO_MEM_CS0 + bank - 1;
	sprintf(gpio_name, "NAND CS%d", bank);
	ret = gpio_request(gpio, gpio_name);
	if (ret) {
		dev_warn(&pdev->dev,
			"Failed to request %s gpio %d: %d\n",
			gpio_name, gpio, ret);
		goto notfound_gpio;
	}

	/* Request I/O resource. */
	sprintf(res_name, "bank%d", bank);
	ret = jz_nand_ioremap_resource(pdev, res_name,
					&nand->bank_mem[bank - 1],
					&nand->bank_base[bank - 1]);
	if (ret)
		goto notfound_resource;

	/* Enable chip in bank. */
	jz_gpio_set_function(gpio, JZ_GPIO_FUNC_MEM_CS0);
	ctrl = readl(nand->base + JZ_REG_NAND_CTRL);
	ctrl |= JZ_NAND_CTRL_ENABLE_CHIP(bank - 1);
	writel(ctrl, nand->base + JZ_REG_NAND_CTRL);

	if (chipnr == 0) {
		/* Detect first chip. */
		ret = nand_scan_ident(mtd, 1, NULL);
		if (ret)
			goto notfound_id;

		/* Retrieve the IDs from the first chip. */
		chip->select_chip(mtd, 0);
		chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
		chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
		*nand_maf_id = chip->read_byte(mtd);
		*nand_dev_id = chip->read_byte(mtd);
	} else {
		/* Detect additional chip. */
		chip->select_chip(mtd, chipnr);
		chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
		chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
		if (*nand_maf_id != chip->read_byte(mtd)
		 || *nand_dev_id != chip->read_byte(mtd)) {
			ret = -ENODEV;
			goto notfound_id;
		}

		/* Update size of the MTD. */
		chip->numchips++;
		mtd->size += chip->chipsize;
	}

	dev_info(&pdev->dev, "Found chip %i on bank %i\n", chipnr, bank);
	return 0;

notfound_id:
	dev_info(&pdev->dev, "No chip found on bank %i\n", bank);
	ctrl &= ~(JZ_NAND_CTRL_ENABLE_CHIP(bank - 1));
	writel(ctrl, nand->base + JZ_REG_NAND_CTRL);
	jz_gpio_set_function(gpio, JZ_GPIO_FUNC_NONE);
	jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
				 nand->bank_base[bank - 1]);
notfound_resource:
	gpio_free(gpio);
notfound_gpio:
	return ret;
}

static int jz_nand_probe(struct platform_device *pdev)
{
	int ret;
	struct jz_nand *nand;
	struct nand_chip *chip;
	struct mtd_info *mtd;
	struct jz_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
	size_t chipnr, bank_idx;
	uint8_t nand_maf_id = 0, nand_dev_id = 0;

	nand = kzalloc(sizeof(*nand), GFP_KERNEL);
	if (!nand)
		return -ENOMEM;

	ret = jz_nand_ioremap_resource(pdev, "mmio", &nand->mem, &nand->base);
	if (ret)
		goto err_free;

	nand->busy_gpio = devm_gpiod_get_optional(&pdev->dev, "busy", GPIOD_IN);
	if (IS_ERR(nand->busy_gpio)) {
		ret = PTR_ERR(nand->busy_gpio);
		dev_err(&pdev->dev, "Failed to request busy gpio %d\n",
		    ret);
		goto err_iounmap_mmio;
	}

	mtd		= &nand->mtd;
	chip		= &nand->chip;
	mtd->priv	= chip;
	mtd->dev.parent = &pdev->dev;
	mtd->name	= "jz4740-nand";

	chip->ecc.hwctl		= jz_nand_hwctl;
	chip->ecc.calculate	= jz_nand_calculate_ecc_rs;
	chip->ecc.correct	= jz_nand_correct_ecc_rs;
	chip->ecc.mode		= NAND_ECC_HW_OOB_FIRST;
	chip->ecc.size		= 512;
	chip->ecc.bytes		= 9;
	chip->ecc.strength	= 4;

	if (pdata)
		chip->ecc.layout = pdata->ecc_layout;

	chip->chip_delay = 50;
	chip->cmd_ctrl = jz_nand_cmd_ctrl;
	chip->select_chip = jz_nand_select_chip;

	if (nand->busy_gpio)
		chip->dev_ready = jz_nand_dev_ready;

	platform_set_drvdata(pdev, nand);

	/* We are going to autodetect NAND chips in the banks specified in the
	 * platform data. Although nand_scan_ident() can detect multiple chips,
	 * it requires those chips to be numbered consecuitively, which is not
	 * always the case for external memory banks. And a fixed chip-to-bank
	 * mapping is not practical either, since for example Dingoo units
	 * produced at different times have NAND chips in different banks.
	 */
	chipnr = 0;
	for (bank_idx = 0; bank_idx < JZ_NAND_NUM_BANKS; bank_idx++) {
		unsigned char bank;

		/* If there is no platform data, look for NAND in bank 1,
		 * which is the most likely bank since it is the only one
		 * that can be booted from.
		 */
		bank = pdata ? pdata->banks[bank_idx] : bank_idx ^ 1;
		if (bank == 0)
			break;
		if (bank > JZ_NAND_NUM_BANKS) {
			dev_warn(&pdev->dev,
				"Skipping non-existing bank: %d\n", bank);
			continue;
		}
		/* The detection routine will directly or indirectly call
		 * jz_nand_select_chip(), so nand->banks has to contain the
		 * bank we're checking.
		 */
		nand->banks[chipnr] = bank;
		if (jz_nand_detect_bank(pdev, nand, bank, chipnr,
					&nand_maf_id, &nand_dev_id) == 0)
			chipnr++;
		else
			nand->banks[chipnr] = 0;
	}
	if (chipnr == 0) {
		dev_err(&pdev->dev, "No NAND chips found\n");
		goto err_iounmap_mmio;
	}

	if (pdata && pdata->ident_callback) {
		pdata->ident_callback(pdev, chip, &pdata->partitions,
					&pdata->num_partitions);
	}

	ret = nand_scan_tail(mtd);
	if (ret) {
		dev_err(&pdev->dev,  "Failed to scan NAND\n");
		goto err_unclaim_banks;
	}

	ret = mtd_device_parse_register(mtd, NULL, NULL,
					pdata ? pdata->partitions : NULL,
					pdata ? pdata->num_partitions : 0);

	if (ret) {
		dev_err(&pdev->dev, "Failed to add mtd device\n");
		goto err_nand_release;
	}

	dev_info(&pdev->dev, "Successfully registered JZ4740 NAND driver\n");

	return 0;

err_nand_release:
	nand_release(mtd);
err_unclaim_banks:
	while (chipnr--) {
		unsigned char bank = nand->banks[chipnr];
		gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
		jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
					 nand->bank_base[bank - 1]);
	}
	writel(0, nand->base + JZ_REG_NAND_CTRL);
err_iounmap_mmio:
	jz_nand_iounmap_resource(nand->mem, nand->base);
err_free:
	kfree(nand);
	return ret;
}

static int jz_nand_remove(struct platform_device *pdev)
{
	struct jz_nand *nand = platform_get_drvdata(pdev);
	size_t i;

	nand_release(&nand->mtd);

	/* Deassert and disable all chips */
	writel(0, nand->base + JZ_REG_NAND_CTRL);

	for (i = 0; i < JZ_NAND_NUM_BANKS; ++i) {
		unsigned char bank = nand->banks[i];
		if (bank != 0) {
			jz_nand_iounmap_resource(nand->bank_mem[bank - 1],
						 nand->bank_base[bank - 1]);
			gpio_free(JZ_GPIO_MEM_CS0 + bank - 1);
		}
	}

	jz_nand_iounmap_resource(nand->mem, nand->base);

	kfree(nand);

	return 0;
}

static struct platform_driver jz_nand_driver = {
	.probe = jz_nand_probe,
	.remove = jz_nand_remove,
	.driver = {
		.name = "jz4740-nand",
	},
};

module_platform_driver(jz_nand_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
MODULE_DESCRIPTION("NAND controller driver for JZ4740 SoC");
MODULE_ALIAS("platform:jz4740-nand");
