/*
 *  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/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 jz_nand_platform_data *pdata;
	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 gpio_get_value_cansleep(nand->pdata->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 = pdev->dev.platform_data;
	size_t chipnr, bank_idx;
	uint8_t nand_maf_id = 0, nand_dev_id = 0;

	nand = kzalloc(sizeof(*nand), GFP_KERNEL);
	if (!nand) {
		dev_err(&pdev->dev, "Failed to allocate device structure.\n");
		return -ENOMEM;
	}

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

	if (pdata && gpio_is_valid(pdata->busy_gpio)) {
		ret = gpio_request(pdata->busy_gpio, "NAND busy pin");
		if (ret) {
			dev_err(&pdev->dev,
				"Failed to request busy gpio %d: %d\n",
				pdata->busy_gpio, ret);
			goto err_iounmap_mmio;
		}
	}

	mtd		= &nand->mtd;
	chip		= &nand->chip;
	mtd->priv	= chip;
	mtd->owner	= THIS_MODULE;
	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 (pdata && gpio_is_valid(pdata->busy_gpio))
		chip->dev_ready = jz_nand_dev_ready;

	nand->pdata = pdata;
	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_gpio_busy;
	}

	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_gpio_busy:
	if (pdata && gpio_is_valid(pdata->busy_gpio))
		gpio_free(pdata->busy_gpio);
	platform_set_drvdata(pdev, NULL);
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);
	struct jz_nand_platform_data *pdata = pdev->dev.platform_data;
	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);
		}
	}
	if (pdata && gpio_is_valid(pdata->busy_gpio))
		gpio_free(pdata->busy_gpio);

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

	platform_set_drvdata(pdev, NULL);
	kfree(nand);

	return 0;
}

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

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