/*
 * Copyright © 2009 Nuvoton technology corporation.
 *
 * Wan ZongShun <mcuos.com@gmail.com>
 *
 * 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;version 2 of the License.
 *
 */

#include <linux/slab.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/err.h>

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

#define REG_FMICSR   	0x00
#define REG_SMCSR    	0xa0
#define REG_SMISR    	0xac
#define REG_SMCMD    	0xb0
#define REG_SMADDR   	0xb4
#define REG_SMDATA   	0xb8

#define RESET_FMI	0x01
#define NAND_EN		0x08
#define READYBUSY	(0x01 << 18)

#define SWRST		0x01
#define PSIZE		(0x01 << 3)
#define DMARWEN		(0x03 << 1)
#define BUSWID		(0x01 << 4)
#define ECC4EN		(0x01 << 5)
#define WP		(0x01 << 24)
#define NANDCS		(0x01 << 25)
#define ENDADDR		(0x01 << 31)

#define read_data_reg(dev)		\
	__raw_readl((dev)->reg + REG_SMDATA)

#define write_data_reg(dev, val)	\
	__raw_writel((val), (dev)->reg + REG_SMDATA)

#define write_cmd_reg(dev, val)		\
	__raw_writel((val), (dev)->reg + REG_SMCMD)

#define write_addr_reg(dev, val)	\
	__raw_writel((val), (dev)->reg + REG_SMADDR)

struct nuc900_nand {
	struct nand_chip chip;
	void __iomem *reg;
	struct clk *clk;
	spinlock_t lock;
};

static inline struct nuc900_nand *mtd_to_nuc900(struct mtd_info *mtd)
{
	return container_of(mtd_to_nand(mtd), struct nuc900_nand, chip);
}

static const struct mtd_partition partitions[] = {
	{
	 .name = "NAND FS 0",
	 .offset = 0,
	 .size = 8 * 1024 * 1024
	},
	{
	 .name = "NAND FS 1",
	 .offset = MTDPART_OFS_APPEND,
	 .size = MTDPART_SIZ_FULL
	}
};

static unsigned char nuc900_nand_read_byte(struct nand_chip *chip)
{
	unsigned char ret;
	struct nuc900_nand *nand = mtd_to_nuc900(nand_to_mtd(chip));

	ret = (unsigned char)read_data_reg(nand);

	return ret;
}

static void nuc900_nand_read_buf(struct nand_chip *chip,
				 unsigned char *buf, int len)
{
	int i;
	struct nuc900_nand *nand = mtd_to_nuc900(nand_to_mtd(chip));

	for (i = 0; i < len; i++)
		buf[i] = (unsigned char)read_data_reg(nand);
}

static void nuc900_nand_write_buf(struct nand_chip *chip,
				  const unsigned char *buf, int len)
{
	int i;
	struct nuc900_nand *nand = mtd_to_nuc900(nand_to_mtd(chip));

	for (i = 0; i < len; i++)
		write_data_reg(nand, buf[i]);
}

static int nuc900_check_rb(struct nuc900_nand *nand)
{
	unsigned int val;
	spin_lock(&nand->lock);
	val = __raw_readl(nand->reg + REG_SMISR);
	val &= READYBUSY;
	spin_unlock(&nand->lock);

	return val;
}

static int nuc900_nand_devready(struct nand_chip *chip)
{
	struct nuc900_nand *nand = mtd_to_nuc900(nand_to_mtd(chip));
	int ready;

	ready = (nuc900_check_rb(nand)) ? 1 : 0;
	return ready;
}

static void nuc900_nand_command_lp(struct nand_chip *chip,
				   unsigned int command,
				   int column, int page_addr)
{
	struct mtd_info *mtd = nand_to_mtd(chip);
	struct nuc900_nand *nand = mtd_to_nuc900(mtd);

	if (command == NAND_CMD_READOOB) {
		column += mtd->writesize;
		command = NAND_CMD_READ0;
	}

	write_cmd_reg(nand, command & 0xff);

	if (column != -1 || page_addr != -1) {

		if (column != -1) {
			if (chip->options & NAND_BUSWIDTH_16 &&
					!nand_opcode_8bits(command))
				column >>= 1;
			write_addr_reg(nand, column);
			write_addr_reg(nand, column >> 8 | ENDADDR);
		}
		if (page_addr != -1) {
			write_addr_reg(nand, page_addr);

			if (chip->options & NAND_ROW_ADDR_3) {
				write_addr_reg(nand, page_addr >> 8);
				write_addr_reg(nand, page_addr >> 16 | ENDADDR);
			} else {
				write_addr_reg(nand, page_addr >> 8 | ENDADDR);
			}
		}
	}

	switch (command) {
	case NAND_CMD_CACHEDPROG:
	case NAND_CMD_PAGEPROG:
	case NAND_CMD_ERASE1:
	case NAND_CMD_ERASE2:
	case NAND_CMD_SEQIN:
	case NAND_CMD_RNDIN:
	case NAND_CMD_STATUS:
		return;

	case NAND_CMD_RESET:
		if (chip->legacy.dev_ready)
			break;
		udelay(chip->legacy.chip_delay);

		write_cmd_reg(nand, NAND_CMD_STATUS);
		write_cmd_reg(nand, command);

		while (!nuc900_check_rb(nand))
			;

		return;

	case NAND_CMD_RNDOUT:
		write_cmd_reg(nand, NAND_CMD_RNDOUTSTART);
		return;

	case NAND_CMD_READ0:

		write_cmd_reg(nand, NAND_CMD_READSTART);
	default:

		if (!chip->legacy.dev_ready) {
			udelay(chip->legacy.chip_delay);
			return;
		}
	}

	/* Apply this short delay always to ensure that we do wait tWB in
	 * any case on any machine. */
	ndelay(100);

	while (!chip->legacy.dev_ready(chip))
		;
}


static void nuc900_nand_enable(struct nuc900_nand *nand)
{
	unsigned int val;
	spin_lock(&nand->lock);
	__raw_writel(RESET_FMI, (nand->reg + REG_FMICSR));

	val = __raw_readl(nand->reg + REG_FMICSR);

	if (!(val & NAND_EN))
		__raw_writel(val | NAND_EN, nand->reg + REG_FMICSR);

	val = __raw_readl(nand->reg + REG_SMCSR);

	val &= ~(SWRST|PSIZE|DMARWEN|BUSWID|ECC4EN|NANDCS);
	val |= WP;

	__raw_writel(val, nand->reg + REG_SMCSR);

	spin_unlock(&nand->lock);
}

static int nuc900_nand_probe(struct platform_device *pdev)
{
	struct nuc900_nand *nuc900_nand;
	struct nand_chip *chip;
	struct mtd_info *mtd;
	struct resource *res;

	nuc900_nand = devm_kzalloc(&pdev->dev, sizeof(struct nuc900_nand),
				   GFP_KERNEL);
	if (!nuc900_nand)
		return -ENOMEM;
	chip = &(nuc900_nand->chip);
	mtd = nand_to_mtd(chip);

	mtd->dev.parent		= &pdev->dev;
	spin_lock_init(&nuc900_nand->lock);

	nuc900_nand->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(nuc900_nand->clk))
		return -ENOENT;
	clk_enable(nuc900_nand->clk);

	chip->legacy.cmdfunc	= nuc900_nand_command_lp;
	chip->legacy.dev_ready	= nuc900_nand_devready;
	chip->legacy.read_byte	= nuc900_nand_read_byte;
	chip->legacy.write_buf	= nuc900_nand_write_buf;
	chip->legacy.read_buf	= nuc900_nand_read_buf;
	chip->legacy.chip_delay	= 50;
	chip->options		= 0;
	chip->ecc.mode		= NAND_ECC_SOFT;
	chip->ecc.algo		= NAND_ECC_HAMMING;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	nuc900_nand->reg = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(nuc900_nand->reg))
		return PTR_ERR(nuc900_nand->reg);

	nuc900_nand_enable(nuc900_nand);

	if (nand_scan(chip, 1))
		return -ENXIO;

	mtd_device_register(mtd, partitions, ARRAY_SIZE(partitions));

	platform_set_drvdata(pdev, nuc900_nand);

	return 0;
}

static int nuc900_nand_remove(struct platform_device *pdev)
{
	struct nuc900_nand *nuc900_nand = platform_get_drvdata(pdev);

	nand_release(&nuc900_nand->chip);
	clk_disable(nuc900_nand->clk);

	return 0;
}

static struct platform_driver nuc900_nand_driver = {
	.probe		= nuc900_nand_probe,
	.remove		= nuc900_nand_remove,
	.driver		= {
		.name	= "nuc900-fmi",
	},
};

module_platform_driver(nuc900_nand_driver);

MODULE_AUTHOR("Wan ZongShun <mcuos.com@gmail.com>");
MODULE_DESCRIPTION("w90p910/NUC9xx nand driver!");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:nuc900-fmi");
