/*
 *  linux/drivers/mtd/onenand/omap2.c
 *
 *  OneNAND driver for OMAP2 / OMAP3
 *
 *  Copyright © 2005-2006 Nokia Corporation
 *
 *  Author: Jarkko Lavinen <jarkko.lavinen@nokia.com> and Juha Yrjölä
 *  IRQ and DMA support written by Timo Teras
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; see the file COPYING. If not, write to the Free Software
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 */

#include <linux/device.h>
#include <linux/module.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/onenand.h>
#include <linux/mtd/partitions.h>
#include <linux/of_device.h>
#include <linux/omap-gpmc.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/gpio/consumer.h>

#include <asm/mach/flash.h>

#define DRIVER_NAME "omap2-onenand"

#define ONENAND_BUFRAM_SIZE	(1024 * 5)

struct omap2_onenand {
	struct platform_device *pdev;
	int gpmc_cs;
	unsigned long phys_base;
	struct gpio_desc *int_gpiod;
	struct mtd_info mtd;
	struct onenand_chip onenand;
	struct completion irq_done;
	struct completion dma_done;
	struct dma_chan *dma_chan;
};

static void omap2_onenand_dma_complete_func(void *completion)
{
	complete(completion);
}

static irqreturn_t omap2_onenand_interrupt(int irq, void *dev_id)
{
	struct omap2_onenand *c = dev_id;

	complete(&c->irq_done);

	return IRQ_HANDLED;
}

static inline unsigned short read_reg(struct omap2_onenand *c, int reg)
{
	return readw(c->onenand.base + reg);
}

static inline void write_reg(struct omap2_onenand *c, unsigned short value,
			     int reg)
{
	writew(value, c->onenand.base + reg);
}

static int omap2_onenand_set_cfg(struct omap2_onenand *c,
				 bool sr, bool sw,
				 int latency, int burst_len)
{
	unsigned short reg = ONENAND_SYS_CFG1_RDY | ONENAND_SYS_CFG1_INT;

	reg |= latency << ONENAND_SYS_CFG1_BRL_SHIFT;

	switch (burst_len) {
	case 0:		/* continuous */
		break;
	case 4:
		reg |= ONENAND_SYS_CFG1_BL_4;
		break;
	case 8:
		reg |= ONENAND_SYS_CFG1_BL_8;
		break;
	case 16:
		reg |= ONENAND_SYS_CFG1_BL_16;
		break;
	case 32:
		reg |= ONENAND_SYS_CFG1_BL_32;
		break;
	default:
		return -EINVAL;
	}

	if (latency > 5)
		reg |= ONENAND_SYS_CFG1_HF;
	if (latency > 7)
		reg |= ONENAND_SYS_CFG1_VHF;
	if (sr)
		reg |= ONENAND_SYS_CFG1_SYNC_READ;
	if (sw)
		reg |= ONENAND_SYS_CFG1_SYNC_WRITE;

	write_reg(c, reg, ONENAND_REG_SYS_CFG1);

	return 0;
}

static int omap2_onenand_get_freq(int ver)
{
	switch ((ver >> 4) & 0xf) {
	case 0:
		return 40;
	case 1:
		return 54;
	case 2:
		return 66;
	case 3:
		return 83;
	case 4:
		return 104;
	}

	return -EINVAL;
}

static void wait_err(char *msg, int state, unsigned int ctrl, unsigned int intr)
{
	printk(KERN_ERR "onenand_wait: %s! state %d ctrl 0x%04x intr 0x%04x\n",
	       msg, state, ctrl, intr);
}

static void wait_warn(char *msg, int state, unsigned int ctrl,
		      unsigned int intr)
{
	printk(KERN_WARNING "onenand_wait: %s! state %d ctrl 0x%04x "
	       "intr 0x%04x\n", msg, state, ctrl, intr);
}

static int omap2_onenand_wait(struct mtd_info *mtd, int state)
{
	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
	struct onenand_chip *this = mtd->priv;
	unsigned int intr = 0;
	unsigned int ctrl, ctrl_mask;
	unsigned long timeout;
	u32 syscfg;

	if (state == FL_RESETING || state == FL_PREPARING_ERASE ||
	    state == FL_VERIFYING_ERASE) {
		int i = 21;
		unsigned int intr_flags = ONENAND_INT_MASTER;

		switch (state) {
		case FL_RESETING:
			intr_flags |= ONENAND_INT_RESET;
			break;
		case FL_PREPARING_ERASE:
			intr_flags |= ONENAND_INT_ERASE;
			break;
		case FL_VERIFYING_ERASE:
			i = 101;
			break;
		}

		while (--i) {
			udelay(1);
			intr = read_reg(c, ONENAND_REG_INTERRUPT);
			if (intr & ONENAND_INT_MASTER)
				break;
		}
		ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
		if (ctrl & ONENAND_CTRL_ERROR) {
			wait_err("controller error", state, ctrl, intr);
			return -EIO;
		}
		if ((intr & intr_flags) == intr_flags)
			return 0;
		/* Continue in wait for interrupt branch */
	}

	if (state != FL_READING) {
		int result;

		/* Turn interrupts on */
		syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
		if (!(syscfg & ONENAND_SYS_CFG1_IOBE)) {
			syscfg |= ONENAND_SYS_CFG1_IOBE;
			write_reg(c, syscfg, ONENAND_REG_SYS_CFG1);
			/* Add a delay to let GPIO settle */
			syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
		}

		reinit_completion(&c->irq_done);
		result = gpiod_get_value(c->int_gpiod);
		if (result < 0) {
			ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
			intr = read_reg(c, ONENAND_REG_INTERRUPT);
			wait_err("gpio error", state, ctrl, intr);
			return result;
		} else if (result == 0) {
			int retry_cnt = 0;
retry:
			if (!wait_for_completion_io_timeout(&c->irq_done,
						msecs_to_jiffies(20))) {
				/* Timeout after 20ms */
				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
				if (ctrl & ONENAND_CTRL_ONGO &&
				    !this->ongoing) {
					/*
					 * The operation seems to be still going
					 * so give it some more time.
					 */
					retry_cnt += 1;
					if (retry_cnt < 3)
						goto retry;
					intr = read_reg(c,
							ONENAND_REG_INTERRUPT);
					wait_err("timeout", state, ctrl, intr);
					return -EIO;
				}
				intr = read_reg(c, ONENAND_REG_INTERRUPT);
				if ((intr & ONENAND_INT_MASTER) == 0)
					wait_warn("timeout", state, ctrl, intr);
			}
		}
	} else {
		int retry_cnt = 0;

		/* Turn interrupts off */
		syscfg = read_reg(c, ONENAND_REG_SYS_CFG1);
		syscfg &= ~ONENAND_SYS_CFG1_IOBE;
		write_reg(c, syscfg, ONENAND_REG_SYS_CFG1);

		timeout = jiffies + msecs_to_jiffies(20);
		while (1) {
			if (time_before(jiffies, timeout)) {
				intr = read_reg(c, ONENAND_REG_INTERRUPT);
				if (intr & ONENAND_INT_MASTER)
					break;
			} else {
				/* Timeout after 20ms */
				ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);
				if (ctrl & ONENAND_CTRL_ONGO) {
					/*
					 * The operation seems to be still going
					 * so give it some more time.
					 */
					retry_cnt += 1;
					if (retry_cnt < 3) {
						timeout = jiffies +
							  msecs_to_jiffies(20);
						continue;
					}
				}
				break;
			}
		}
	}

	intr = read_reg(c, ONENAND_REG_INTERRUPT);
	ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS);

	if (intr & ONENAND_INT_READ) {
		int ecc = read_reg(c, ONENAND_REG_ECC_STATUS);

		if (ecc) {
			unsigned int addr1, addr8;

			addr1 = read_reg(c, ONENAND_REG_START_ADDRESS1);
			addr8 = read_reg(c, ONENAND_REG_START_ADDRESS8);
			if (ecc & ONENAND_ECC_2BIT_ALL) {
				printk(KERN_ERR "onenand_wait: ECC error = "
				       "0x%04x, addr1 %#x, addr8 %#x\n",
				       ecc, addr1, addr8);
				mtd->ecc_stats.failed++;
				return -EBADMSG;
			} else if (ecc & ONENAND_ECC_1BIT_ALL) {
				printk(KERN_NOTICE "onenand_wait: correctable "
				       "ECC error = 0x%04x, addr1 %#x, "
				       "addr8 %#x\n", ecc, addr1, addr8);
				mtd->ecc_stats.corrected++;
			}
		}
	} else if (state == FL_READING) {
		wait_err("timeout", state, ctrl, intr);
		return -EIO;
	}

	if (ctrl & ONENAND_CTRL_ERROR) {
		wait_err("controller error", state, ctrl, intr);
		if (ctrl & ONENAND_CTRL_LOCK)
			printk(KERN_ERR "onenand_wait: "
					"Device is write protected!!!\n");
		return -EIO;
	}

	ctrl_mask = 0xFE9F;
	if (this->ongoing)
		ctrl_mask &= ~0x8000;

	if (ctrl & ctrl_mask)
		wait_warn("unexpected controller status", state, ctrl, intr);

	return 0;
}

static inline int omap2_onenand_bufferram_offset(struct mtd_info *mtd, int area)
{
	struct onenand_chip *this = mtd->priv;

	if (ONENAND_CURRENT_BUFFERRAM(this)) {
		if (area == ONENAND_DATARAM)
			return this->writesize;
		if (area == ONENAND_SPARERAM)
			return mtd->oobsize;
	}

	return 0;
}

static inline int omap2_onenand_dma_transfer(struct omap2_onenand *c,
					     dma_addr_t src, dma_addr_t dst,
					     size_t count)
{
	struct dma_async_tx_descriptor *tx;
	dma_cookie_t cookie;

	tx = dmaengine_prep_dma_memcpy(c->dma_chan, dst, src, count, 0);
	if (!tx) {
		dev_err(&c->pdev->dev, "Failed to prepare DMA memcpy\n");
		return -EIO;
	}

	reinit_completion(&c->dma_done);

	tx->callback = omap2_onenand_dma_complete_func;
	tx->callback_param = &c->dma_done;

	cookie = tx->tx_submit(tx);
	if (dma_submit_error(cookie)) {
		dev_err(&c->pdev->dev, "Failed to do DMA tx_submit\n");
		return -EIO;
	}

	dma_async_issue_pending(c->dma_chan);

	if (!wait_for_completion_io_timeout(&c->dma_done,
					    msecs_to_jiffies(20))) {
		dmaengine_terminate_sync(c->dma_chan);
		return -ETIMEDOUT;
	}

	return 0;
}

static int omap2_onenand_read_bufferram(struct mtd_info *mtd, int area,
					unsigned char *buffer, int offset,
					size_t count)
{
	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
	struct onenand_chip *this = mtd->priv;
	dma_addr_t dma_src, dma_dst;
	int bram_offset;
	void *buf = (void *)buffer;
	size_t xtra;
	int ret;

	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
		goto out_copy;

	/* panic_write() may be in an interrupt context */
	if (in_interrupt() || oops_in_progress)
		goto out_copy;

	if (buf >= high_memory) {
		struct page *p1;

		if (((size_t)buf & PAGE_MASK) !=
		    ((size_t)(buf + count - 1) & PAGE_MASK))
			goto out_copy;
		p1 = vmalloc_to_page(buf);
		if (!p1)
			goto out_copy;
		buf = page_address(p1) + ((size_t)buf & ~PAGE_MASK);
	}

	xtra = count & 3;
	if (xtra) {
		count -= xtra;
		memcpy(buf + count, this->base + bram_offset + count, xtra);
	}

	dma_src = c->phys_base + bram_offset;
	dma_dst = dma_map_single(&c->pdev->dev, buf, count, DMA_FROM_DEVICE);
	if (dma_mapping_error(&c->pdev->dev, dma_dst)) {
		dev_err(&c->pdev->dev,
			"Couldn't DMA map a %d byte buffer\n",
			count);
		goto out_copy;
	}

	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
	dma_unmap_single(&c->pdev->dev, dma_dst, count, DMA_FROM_DEVICE);

	if (ret) {
		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
		goto out_copy;
	}

	return 0;

out_copy:
	memcpy(buf, this->base + bram_offset, count);
	return 0;
}

static int omap2_onenand_write_bufferram(struct mtd_info *mtd, int area,
					 const unsigned char *buffer,
					 int offset, size_t count)
{
	struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
	struct onenand_chip *this = mtd->priv;
	dma_addr_t dma_src, dma_dst;
	int bram_offset;
	void *buf = (void *)buffer;
	int ret;

	bram_offset = omap2_onenand_bufferram_offset(mtd, area) + area + offset;
	if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
		goto out_copy;

	/* panic_write() may be in an interrupt context */
	if (in_interrupt() || oops_in_progress)
		goto out_copy;

	if (buf >= high_memory) {
		struct page *p1;

		if (((size_t)buf & PAGE_MASK) !=
		    ((size_t)(buf + count - 1) & PAGE_MASK))
			goto out_copy;
		p1 = vmalloc_to_page(buf);
		if (!p1)
			goto out_copy;
		buf = page_address(p1) + ((size_t)buf & ~PAGE_MASK);
	}

	dma_src = dma_map_single(&c->pdev->dev, buf, count, DMA_TO_DEVICE);
	dma_dst = c->phys_base + bram_offset;
	if (dma_mapping_error(&c->pdev->dev, dma_src)) {
		dev_err(&c->pdev->dev,
			"Couldn't DMA map a %d byte buffer\n",
			count);
		return -1;
	}

	ret = omap2_onenand_dma_transfer(c, dma_src, dma_dst, count);
	dma_unmap_single(&c->pdev->dev, dma_src, count, DMA_TO_DEVICE);

	if (ret) {
		dev_err(&c->pdev->dev, "timeout waiting for DMA\n");
		goto out_copy;
	}

	return 0;

out_copy:
	memcpy(this->base + bram_offset, buf, count);
	return 0;
}

static void omap2_onenand_shutdown(struct platform_device *pdev)
{
	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);

	/* With certain content in the buffer RAM, the OMAP boot ROM code
	 * can recognize the flash chip incorrectly. Zero it out before
	 * soft reset.
	 */
	memset((__force void *)c->onenand.base, 0, ONENAND_BUFRAM_SIZE);
}

static int omap2_onenand_probe(struct platform_device *pdev)
{
	u32 val;
	dma_cap_mask_t mask;
	int freq, latency, r;
	struct resource *res;
	struct omap2_onenand *c;
	struct gpmc_onenand_info info;
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(dev, "error getting memory resource\n");
		return -EINVAL;
	}

	r = of_property_read_u32(np, "reg", &val);
	if (r) {
		dev_err(dev, "reg not found in DT\n");
		return r;
	}

	c = devm_kzalloc(dev, sizeof(struct omap2_onenand), GFP_KERNEL);
	if (!c)
		return -ENOMEM;

	init_completion(&c->irq_done);
	init_completion(&c->dma_done);
	c->gpmc_cs = val;
	c->phys_base = res->start;

	c->onenand.base = devm_ioremap_resource(dev, res);
	if (IS_ERR(c->onenand.base))
		return PTR_ERR(c->onenand.base);

	c->int_gpiod = devm_gpiod_get_optional(dev, "int", GPIOD_IN);
	if (IS_ERR(c->int_gpiod)) {
		r = PTR_ERR(c->int_gpiod);
		/* Just try again if this happens */
		if (r != -EPROBE_DEFER)
			dev_err(dev, "error getting gpio: %d\n", r);
		return r;
	}

	if (c->int_gpiod) {
		r = devm_request_irq(dev, gpiod_to_irq(c->int_gpiod),
				     omap2_onenand_interrupt,
				     IRQF_TRIGGER_RISING, "onenand", c);
		if (r)
			return r;

		c->onenand.wait = omap2_onenand_wait;
	}

	dma_cap_zero(mask);
	dma_cap_set(DMA_MEMCPY, mask);

	c->dma_chan = dma_request_channel(mask, NULL, NULL);
	if (c->dma_chan) {
		c->onenand.read_bufferram = omap2_onenand_read_bufferram;
		c->onenand.write_bufferram = omap2_onenand_write_bufferram;
	}

	c->pdev = pdev;
	c->mtd.priv = &c->onenand;
	c->mtd.dev.parent = dev;
	mtd_set_of_node(&c->mtd, dev->of_node);

	dev_info(dev, "initializing on CS%d (0x%08lx), va %p, %s mode\n",
		 c->gpmc_cs, c->phys_base, c->onenand.base,
		 c->dma_chan ? "DMA" : "PIO");

	if ((r = onenand_scan(&c->mtd, 1)) < 0)
		goto err_release_dma;

	freq = omap2_onenand_get_freq(c->onenand.version_id);
	if (freq > 0) {
		switch (freq) {
		case 104:
			latency = 7;
			break;
		case 83:
			latency = 6;
			break;
		case 66:
			latency = 5;
			break;
		case 56:
			latency = 4;
			break;
		default:	/* 40 MHz or lower */
			latency = 3;
			break;
		}

		r = gpmc_omap_onenand_set_timings(dev, c->gpmc_cs,
						  freq, latency, &info);
		if (r)
			goto err_release_onenand;

		r = omap2_onenand_set_cfg(c, info.sync_read, info.sync_write,
					  latency, info.burst_len);
		if (r)
			goto err_release_onenand;

		if (info.sync_read || info.sync_write)
			dev_info(dev, "optimized timings for %d MHz\n", freq);
	}

	r = mtd_device_register(&c->mtd, NULL, 0);
	if (r)
		goto err_release_onenand;

	platform_set_drvdata(pdev, c);

	return 0;

err_release_onenand:
	onenand_release(&c->mtd);
err_release_dma:
	if (c->dma_chan)
		dma_release_channel(c->dma_chan);

	return r;
}

static int omap2_onenand_remove(struct platform_device *pdev)
{
	struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);

	onenand_release(&c->mtd);
	if (c->dma_chan)
		dma_release_channel(c->dma_chan);
	omap2_onenand_shutdown(pdev);

	return 0;
}

static const struct of_device_id omap2_onenand_id_table[] = {
	{ .compatible = "ti,omap2-onenand", },
	{},
};
MODULE_DEVICE_TABLE(of, omap2_onenand_id_table);

static struct platform_driver omap2_onenand_driver = {
	.probe		= omap2_onenand_probe,
	.remove		= omap2_onenand_remove,
	.shutdown	= omap2_onenand_shutdown,
	.driver		= {
		.name	= DRIVER_NAME,
		.of_match_table = omap2_onenand_id_table,
	},
};

module_platform_driver(omap2_onenand_driver);

MODULE_ALIAS("platform:" DRIVER_NAME);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jarkko Lavinen <jarkko.lavinen@nokia.com>");
MODULE_DESCRIPTION("Glue layer for OneNAND flash on OMAP2 / OMAP3");
