/*
 *  drivers/mtd/ndfc.c
 *
 *  Overview:
 *   Platform independend driver for NDFC (NanD Flash Controller)
 *   integrated into EP440 cores
 *
 *  Author: Thomas Gleixner
 *
 *  Copyright 2006 IBM
 *
 *  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.
 *
 */
#include <linux/module.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/ndfc.h>
#include <linux/mtd/ubi.h>
#include <linux/mtd/mtd.h>
#include <linux/platform_device.h>

#include <asm/io.h>
#include <asm/ibm44x.h>

struct ndfc_nand_mtd {
	struct mtd_info			mtd;
	struct nand_chip		chip;
	struct platform_nand_chip	*pl_chip;
};

static struct ndfc_nand_mtd ndfc_mtd[NDFC_MAX_BANKS];

struct ndfc_controller {
	void __iomem		*ndfcbase;
	struct nand_hw_control	ndfc_control;
	atomic_t		childs_active;
};

static struct ndfc_controller ndfc_ctrl;

static void ndfc_select_chip(struct mtd_info *mtd, int chip)
{
	uint32_t ccr;
	struct ndfc_controller *ndfc = &ndfc_ctrl;
	struct nand_chip *nandchip = mtd->priv;
	struct ndfc_nand_mtd *nandmtd = nandchip->priv;
	struct platform_nand_chip *pchip = nandmtd->pl_chip;

	ccr = __raw_readl(ndfc->ndfcbase + NDFC_CCR);
	if (chip >= 0) {
		ccr &= ~NDFC_CCR_BS_MASK;
		ccr |= NDFC_CCR_BS(chip + pchip->chip_offset);
	} else
		ccr |= NDFC_CCR_RESET_CE;
	writel(ccr, ndfc->ndfcbase + NDFC_CCR);
}

static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
	struct nand_chip *chip = mtd->priv;

	if (cmd == NAND_CMD_NONE)
		return;

	if (ctrl & NAND_CLE)
		writel(cmd & 0xFF, chip->IO_ADDR_W + NDFC_CMD);
	else
		writel(cmd & 0xFF, chip->IO_ADDR_W + NDFC_ALE);
}

static int ndfc_ready(struct mtd_info *mtd)
{
	struct ndfc_controller *ndfc = &ndfc_ctrl;

	return __raw_readl(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY;
}

static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode)
{
	uint32_t ccr;
	struct ndfc_controller *ndfc = &ndfc_ctrl;

	ccr = __raw_readl(ndfc->ndfcbase + NDFC_CCR);
	ccr |= NDFC_CCR_RESET_ECC;
	__raw_writel(ccr, ndfc->ndfcbase + NDFC_CCR);
	wmb();
}

static int ndfc_calculate_ecc(struct mtd_info *mtd,
			      const u_char *dat, u_char *ecc_code)
{
	struct ndfc_controller *ndfc = &ndfc_ctrl;
	uint32_t ecc;
	uint8_t *p = (uint8_t *)&ecc;

	wmb();
	ecc = __raw_readl(ndfc->ndfcbase + NDFC_ECC);
	ecc_code[0] = p[1];
	ecc_code[1] = p[2];
	ecc_code[2] = p[3];

	return 0;
}

/*
 * Speedups for buffer read/write/verify
 *
 * NDFC allows 32bit read/write of data. So we can speed up the buffer
 * functions. No further checking, as nand_base will always read/write
 * page aligned.
 */
static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
{
	struct ndfc_controller *ndfc = &ndfc_ctrl;
	uint32_t *p = (uint32_t *) buf;

	for(;len > 0; len -= 4)
		*p++ = __raw_readl(ndfc->ndfcbase + NDFC_DATA);
}

static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
{
	struct ndfc_controller *ndfc = &ndfc_ctrl;
	uint32_t *p = (uint32_t *) buf;

	for(;len > 0; len -= 4)
		__raw_writel(*p++, ndfc->ndfcbase + NDFC_DATA);
}

static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
{
	struct ndfc_controller *ndfc = &ndfc_ctrl;
	uint32_t *p = (uint32_t *) buf;

	for(;len > 0; len -= 4)
		if (*p++ != __raw_readl(ndfc->ndfcbase + NDFC_DATA))
			return -EFAULT;
	return 0;
}

/*
 * Initialize chip structure
 */
static void ndfc_chip_init(struct ndfc_nand_mtd *mtd)
{
	struct ndfc_controller *ndfc = &ndfc_ctrl;
	struct nand_chip *chip = &mtd->chip;

	chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA;
	chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_DATA;
	chip->cmd_ctrl = ndfc_hwcontrol;
	chip->dev_ready = ndfc_ready;
	chip->select_chip = ndfc_select_chip;
	chip->chip_delay = 50;
	chip->priv = mtd;
	chip->options = mtd->pl_chip->options;
	chip->controller = &ndfc->ndfc_control;
	chip->read_buf = ndfc_read_buf;
	chip->write_buf = ndfc_write_buf;
	chip->verify_buf = ndfc_verify_buf;
	chip->ecc.correct = nand_correct_data;
	chip->ecc.hwctl = ndfc_enable_hwecc;
	chip->ecc.calculate = ndfc_calculate_ecc;
	chip->ecc.mode = NAND_ECC_HW;
	chip->ecc.size = 256;
	chip->ecc.bytes = 3;
	chip->autooob = mtd->pl_chip->autooob;
	mtd->mtd.priv = chip;
	mtd->mtd.owner = THIS_MODULE;
}

static int ndfc_chip_probe(struct platform_device *pdev)
{
	int rc;
	struct platform_nand_chip *nc = pdev->dev.platform_data;
	struct ndfc_chip_settings *settings = nc->priv;
	struct ndfc_controller *ndfc = &ndfc_ctrl;
	struct ndfc_nand_mtd *nandmtd;

	if (nc->chip_offset >= NDFC_MAX_BANKS || nc->nr_chips > NDFC_MAX_BANKS)
		return -EINVAL;

	/* Set the bank settings */
	__raw_writel(settings->bank_settings,
		     ndfc->ndfcbase + NDFC_BCFG0 + (nc->chip_offset << 2));

	nandmtd = &ndfc_mtd[pdev->id];
	if (nandmtd->pl_chip)
		return -EBUSY;

	nandmtd->pl_chip = nc;
	ndfc_chip_init(nandmtd);

	/* Scan for chips */
	if (nand_scan(&nandmtd->mtd, nc->nr_chips)) {
		nandmtd->pl_chip = NULL;
		return -ENODEV;
	}

#ifdef CONFIG_MTD_PARTITIONS
	printk("Number of partitions %d\n", nc->nr_partitions);
	if (nc->nr_partitions) {
		struct mtd_info *mtd_ubi;
		nc->partitions[NAND_PARTS_CONTENT_IDX].mtdp = &mtd_ubi;

		add_mtd_device(&nandmtd->mtd); /* for testing */
		add_mtd_partitions(&nandmtd->mtd,
				   nc->partitions,
				   nc->nr_partitions);

		add_mtd_device(mtd_ubi);

	} else
#else
		add_mtd_device(&nandmtd->mtd);
#endif

	atomic_inc(&ndfc->childs_active);
	return 0;
}

static int ndfc_chip_remove(struct platform_device *pdev)
{
	return 0;
}

static int ndfc_nand_probe(struct platform_device *pdev)
{
	struct platform_nand_ctrl *nc = pdev->dev.platform_data;
	struct ndfc_controller_settings *settings = nc->priv;
	struct resource *res = pdev->resource;
	struct ndfc_controller *ndfc = &ndfc_ctrl;
	unsigned long long phys = NDFC_PHYSADDR_OFFS | res->start;

	ndfc->ndfcbase = ioremap64(phys, res->end - res->start + 1);
	if (!ndfc->ndfcbase) {
		printk(KERN_ERR "NDFC: ioremap failed\n");
		return -EIO;
	}

	__raw_writel(settings->ccr_settings, ndfc->ndfcbase + NDFC_CCR);

	spin_lock_init(&ndfc->ndfc_control.lock);
	init_waitqueue_head(&ndfc->ndfc_control.wq);

	platform_set_drvdata(pdev, ndfc);

	printk("NDFC NAND Driver initialized. Chip-Rev: 0x%08x\n",
	       __raw_readl(ndfc->ndfcbase + NDFC_REVID));

	return 0;
}

static int ndfc_nand_remove(struct platform_device *pdev)
{
	struct ndfc_controller *ndfc = platform_get_drvdata(pdev);

	if (atomic_read(&ndfc->childs_active))
		return -EBUSY;

	if (ndfc) {
		platform_set_drvdata(pdev, NULL);
		iounmap(ndfc_ctrl.ndfcbase);
		ndfc_ctrl.ndfcbase = NULL;
	}
	return 0;
}

/* driver device registration */

static struct platform_driver ndfc_chip_driver = {
	.probe		= ndfc_chip_probe,
	.remove		= ndfc_chip_remove,
	.driver		= {
		.name	= "ndfc-chip",
		.owner	= THIS_MODULE,
	},
};

static struct platform_driver ndfc_nand_driver = {
	.probe		= ndfc_nand_probe,
	.remove		= ndfc_nand_remove,
	.driver		= {
		.name	= "ndfc-nand",
		.owner	= THIS_MODULE,
	},
};

static int __init ndfc_nand_init(void)
{
	int ret = platform_driver_register(&ndfc_nand_driver);

	if (!ret)
		ret = platform_driver_register(&ndfc_chip_driver);
	return ret;
}

static void __exit ndfc_nand_exit(void)
{
	platform_driver_unregister(&ndfc_chip_driver);
	platform_driver_unregister(&ndfc_nand_driver);
}

module_init(ndfc_nand_init);
module_exit(ndfc_nand_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
MODULE_DESCRIPTION("Platform driver for NDFC");
