/*
 * JZ4780 NAND driver
 *
 * Copyright (c) 2015 Imagination Technologies
 * Author: Alex Smith <alex.smith@imgtec.com>
 *
 * 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.
 */

#include <linux/delay.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/gpio/consumer.h>
#include <linux/of_mtd.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/jz4780-nemc.h>

#include "jz4780_bch.h"

#define DRV_NAME	"jz4780-nand"

#define OFFSET_DATA	0x00000000
#define OFFSET_CMD	0x00400000
#define OFFSET_ADDR	0x00800000

/* Command delay when there is no R/B pin. */
#define RB_DELAY_US	100

struct jz4780_nand_cs {
	unsigned int bank;
	void __iomem *base;
};

struct jz4780_nand_controller {
	struct device *dev;
	struct jz4780_bch *bch;
	struct nand_hw_control controller;
	unsigned int num_banks;
	struct list_head chips;
	int selected;
	struct jz4780_nand_cs cs[];
};

struct jz4780_nand_chip {
	struct nand_chip chip;
	struct list_head chip_list;

	struct nand_ecclayout ecclayout;

	struct gpio_desc *busy_gpio;
	struct gpio_desc *wp_gpio;
	unsigned int reading: 1;
};

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

static inline struct jz4780_nand_controller *to_jz4780_nand_controller(struct nand_hw_control *ctrl)
{
	return container_of(ctrl, struct jz4780_nand_controller, controller);
}

static void jz4780_nand_select_chip(struct mtd_info *mtd, int chipnr)
{
	struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd);
	struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(nand->chip.controller);
	struct jz4780_nand_cs *cs;

	/* Ensure the currently selected chip is deasserted. */
	if (chipnr == -1 && nfc->selected >= 0) {
		cs = &nfc->cs[nfc->selected];
		jz4780_nemc_assert(nfc->dev, cs->bank, false);
	}

	nfc->selected = chipnr;
}

static void jz4780_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
				 unsigned int ctrl)
{
	struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd);
	struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(nand->chip.controller);
	struct jz4780_nand_cs *cs;

	if (WARN_ON(nfc->selected < 0))
		return;

	cs = &nfc->cs[nfc->selected];

	jz4780_nemc_assert(nfc->dev, cs->bank, ctrl & NAND_NCE);

	if (cmd == NAND_CMD_NONE)
		return;

	if (ctrl & NAND_ALE)
		writeb(cmd, cs->base + OFFSET_ADDR);
	else if (ctrl & NAND_CLE)
		writeb(cmd, cs->base + OFFSET_CMD);
}

static int jz4780_nand_dev_ready(struct mtd_info *mtd)
{
	struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd);

	return !gpiod_get_value_cansleep(nand->busy_gpio);
}

static void jz4780_nand_ecc_hwctl(struct mtd_info *mtd, int mode)
{
	struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd);

	nand->reading = (mode == NAND_ECC_READ);
}

static int jz4780_nand_ecc_calculate(struct mtd_info *mtd, const u8 *dat,
				     u8 *ecc_code)
{
	struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd);
	struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(nand->chip.controller);
	struct jz4780_bch_params params;

	/*
	 * Don't need to generate the ECC when reading, BCH does it for us as
	 * part of decoding/correction.
	 */
	if (nand->reading)
		return 0;

	params.size = nand->chip.ecc.size;
	params.bytes = nand->chip.ecc.bytes;
	params.strength = nand->chip.ecc.strength;

	return jz4780_bch_calculate(nfc->bch, &params, dat, ecc_code);
}

static int jz4780_nand_ecc_correct(struct mtd_info *mtd, u8 *dat,
				   u8 *read_ecc, u8 *calc_ecc)
{
	struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd);
	struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(nand->chip.controller);
	struct jz4780_bch_params params;

	params.size = nand->chip.ecc.size;
	params.bytes = nand->chip.ecc.bytes;
	params.strength = nand->chip.ecc.strength;

	return jz4780_bch_correct(nfc->bch, &params, dat, read_ecc);
}

static int jz4780_nand_init_ecc(struct jz4780_nand_chip *nand, struct device *dev)
{
	struct nand_chip *chip = &nand->chip;
	struct mtd_info *mtd = nand_to_mtd(chip);
	struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(chip->controller);
	struct nand_ecclayout *layout = &nand->ecclayout;
	u32 start, i;

	chip->ecc.bytes = fls((1 + 8) * chip->ecc.size)	*
				(chip->ecc.strength / 8);

	if (nfc->bch && chip->ecc.mode == NAND_ECC_HW) {
		chip->ecc.hwctl = jz4780_nand_ecc_hwctl;
		chip->ecc.calculate = jz4780_nand_ecc_calculate;
		chip->ecc.correct = jz4780_nand_ecc_correct;
	} else if (!nfc->bch && chip->ecc.mode == NAND_ECC_HW) {
		dev_err(dev, "HW BCH selected, but BCH controller not found\n");
		return -ENODEV;
	}

	if (chip->ecc.mode == NAND_ECC_HW_SYNDROME) {
		dev_err(dev, "ECC HW syndrome not supported\n");
		return -EINVAL;
	}

	if (chip->ecc.mode != NAND_ECC_NONE)
		dev_info(dev, "using %s (strength %d, size %d, bytes %d)\n",
			(nfc->bch) ? "hardware BCH" : "software ECC",
			chip->ecc.strength, chip->ecc.size, chip->ecc.bytes);
	else
		dev_info(dev, "not using ECC\n");

	/* The NAND core will generate the ECC layout. */
	if (chip->ecc.mode == NAND_ECC_SOFT || chip->ecc.mode == NAND_ECC_SOFT_BCH)
		return 0;

	/* Generate ECC layout. ECC codes are right aligned in the OOB area. */
	layout->eccbytes = mtd->writesize / chip->ecc.size * chip->ecc.bytes;

	if (layout->eccbytes > mtd->oobsize - 2) {
		dev_err(dev,
			"invalid ECC config: required %d ECC bytes, but only %d are available",
			layout->eccbytes, mtd->oobsize - 2);
		return -EINVAL;
	}

	start = mtd->oobsize - layout->eccbytes;
	for (i = 0; i < layout->eccbytes; i++)
		layout->eccpos[i] = start + i;

	layout->oobfree[0].offset = 2;
	layout->oobfree[0].length = mtd->oobsize - layout->eccbytes - 2;

	chip->ecc.layout = layout;
	return 0;
}

static int jz4780_nand_init_chip(struct platform_device *pdev,
				struct jz4780_nand_controller *nfc,
				struct device_node *np,
				unsigned int chipnr)
{
	struct device *dev = &pdev->dev;
	struct jz4780_nand_chip *nand;
	struct jz4780_nand_cs *cs;
	struct resource *res;
	struct nand_chip *chip;
	struct mtd_info *mtd;
	const __be32 *reg;
	int ret = 0;

	cs = &nfc->cs[chipnr];

	reg = of_get_property(np, "reg", NULL);
	if (!reg)
		return -EINVAL;

	cs->bank = be32_to_cpu(*reg);

	jz4780_nemc_set_type(nfc->dev, cs->bank, JZ4780_NEMC_BANK_NAND);

	res = platform_get_resource(pdev, IORESOURCE_MEM, chipnr);
	cs->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(cs->base))
		return PTR_ERR(cs->base);

	nand = devm_kzalloc(dev, sizeof(*nand), GFP_KERNEL);
	if (!nand)
		return -ENOMEM;

	nand->busy_gpio = devm_gpiod_get_optional(dev, "rb", GPIOD_IN);

	if (IS_ERR(nand->busy_gpio)) {
		ret = PTR_ERR(nand->busy_gpio);
		dev_err(dev, "failed to request busy GPIO: %d\n", ret);
		return ret;
	} else if (nand->busy_gpio) {
		nand->chip.dev_ready = jz4780_nand_dev_ready;
	}

	nand->wp_gpio = devm_gpiod_get_optional(dev, "wp", GPIOD_OUT_LOW);

	if (IS_ERR(nand->wp_gpio)) {
		ret = PTR_ERR(nand->wp_gpio);
		dev_err(dev, "failed to request WP GPIO: %d\n", ret);
		return ret;
	}

	chip = &nand->chip;
	mtd = nand_to_mtd(chip);
	mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s.%d", dev_name(dev),
				   cs->bank);
	if (!mtd->name)
		return -ENOMEM;
	mtd->dev.parent = dev;

	chip->IO_ADDR_R = cs->base + OFFSET_DATA;
	chip->IO_ADDR_W = cs->base + OFFSET_DATA;
	chip->chip_delay = RB_DELAY_US;
	chip->options = NAND_NO_SUBPAGE_WRITE;
	chip->select_chip = jz4780_nand_select_chip;
	chip->cmd_ctrl = jz4780_nand_cmd_ctrl;
	chip->ecc.mode = NAND_ECC_HW;
	chip->controller = &nfc->controller;
	nand_set_flash_node(chip, np);

	ret = nand_scan_ident(mtd, 1, NULL);
	if (ret)
		return ret;

	ret = jz4780_nand_init_ecc(nand, dev);
	if (ret)
		return ret;

	ret = nand_scan_tail(mtd);
	if (ret)
		return ret;

	ret = mtd_device_register(mtd, NULL, 0);
	if (ret) {
		nand_release(mtd);
		return ret;
	}

	list_add_tail(&nand->chip_list, &nfc->chips);

	return 0;
}

static void jz4780_nand_cleanup_chips(struct jz4780_nand_controller *nfc)
{
	struct jz4780_nand_chip *chip;

	while (!list_empty(&nfc->chips)) {
		chip = list_first_entry(&nfc->chips, struct jz4780_nand_chip, chip_list);
		nand_release(nand_to_mtd(&chip->chip));
		list_del(&chip->chip_list);
	}
}

static int jz4780_nand_init_chips(struct jz4780_nand_controller *nfc,
				  struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np;
	int i = 0;
	int ret;
	int num_chips = of_get_child_count(dev->of_node);

	if (num_chips > nfc->num_banks) {
		dev_err(dev, "found %d chips but only %d banks\n", num_chips, nfc->num_banks);
		return -EINVAL;
	}

	for_each_child_of_node(dev->of_node, np) {
		ret = jz4780_nand_init_chip(pdev, nfc, np, i);
		if (ret) {
			jz4780_nand_cleanup_chips(nfc);
			return ret;
		}

		i++;
	}

	return 0;
}

static int jz4780_nand_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	unsigned int num_banks;
	struct jz4780_nand_controller *nfc;
	int ret;

	num_banks = jz4780_nemc_num_banks(dev);
	if (num_banks == 0) {
		dev_err(dev, "no banks found\n");
		return -ENODEV;
	}

	nfc = devm_kzalloc(dev, sizeof(*nfc) + (sizeof(nfc->cs[0]) * num_banks), GFP_KERNEL);
	if (!nfc)
		return -ENOMEM;

	/*
	 * Check for BCH HW before we call nand_scan_ident, to prevent us from
	 * having to call it again if the BCH driver returns -EPROBE_DEFER.
	 */
	nfc->bch = of_jz4780_bch_get(dev->of_node);
	if (IS_ERR(nfc->bch))
		return PTR_ERR(nfc->bch);

	nfc->dev = dev;
	nfc->num_banks = num_banks;

	spin_lock_init(&nfc->controller.lock);
	INIT_LIST_HEAD(&nfc->chips);
	init_waitqueue_head(&nfc->controller.wq);

	ret = jz4780_nand_init_chips(nfc, pdev);
	if (ret) {
		if (nfc->bch)
			jz4780_bch_release(nfc->bch);
		return ret;
	}

	platform_set_drvdata(pdev, nfc);
	return 0;
}

static int jz4780_nand_remove(struct platform_device *pdev)
{
	struct jz4780_nand_controller *nfc = platform_get_drvdata(pdev);

	if (nfc->bch)
		jz4780_bch_release(nfc->bch);

	jz4780_nand_cleanup_chips(nfc);

	return 0;
}

static const struct of_device_id jz4780_nand_dt_match[] = {
	{ .compatible = "ingenic,jz4780-nand" },
	{},
};
MODULE_DEVICE_TABLE(of, jz4780_nand_dt_match);

static struct platform_driver jz4780_nand_driver = {
	.probe		= jz4780_nand_probe,
	.remove		= jz4780_nand_remove,
	.driver	= {
		.name	= DRV_NAME,
		.of_match_table = of_match_ptr(jz4780_nand_dt_match),
	},
};
module_platform_driver(jz4780_nand_driver);

MODULE_AUTHOR("Alex Smith <alex@alex-smith.me.uk>");
MODULE_AUTHOR("Harvey Hunt <harvey.hunt@imgtec.com>");
MODULE_DESCRIPTION("Ingenic JZ4780 NAND driver");
MODULE_LICENSE("GPL v2");
