/*
 *  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/mtd.h>
#include <linux/platform_device.h>

#include <asm/io.h>
#ifdef CONFIG_40x
#include <asm/ibm405.h>
#else
#include <asm/ibm44x.h>
#endif

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;
	__raw_writel(ccr, ndfc->ndfcbase + NDFC_CCR);
}

static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
	struct ndfc_controller *ndfc = &ndfc_ctrl;

	if (cmd == NAND_CMD_NONE)
		return;

	if (ctrl & NAND_CLE)
		writel(cmd & 0xFF, ndfc->ndfcbase + NDFC_CMD);
	else
		writel(cmd & 0xFF, ndfc->ndfcbase + 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->ecclayout = chip->ecc.layout = mtd->pl_chip->ecclayout;
	mtd->mtd.priv = chip;
	mtd->mtd.owner = THIS_MODULE;
}

static int ndfc_chip_probe(struct platform_device *pdev)
{
	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) {
		/* Add the full device, so complete dumps can be made */
		add_mtd_device(&nandmtd->mtd);
		add_mtd_partitions(&nandmtd->mtd, nc->partitions,
				   nc->nr_partitions);

	} 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 = settings->ndfc_erpn | res->start;

#ifndef CONFIG_PHYS_64BIT
	ndfc->ndfcbase = ioremap((phys_addr_t)phys, res->end - res->start + 1);
#else
	ndfc->ndfcbase = ioremap64(phys, res->end - res->start + 1);
#endif
	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;

	spin_lock_init(&ndfc_ctrl.ndfc_control.lock);
	init_waitqueue_head(&ndfc_ctrl.ndfc_control.wq);

	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");
MODULE_ALIAS("platform:ndfc-chip");
MODULE_ALIAS("platform:ndfc-nand");
