/*
 * EBI driver for Atmel chips
 * inspired by the fsl weim bus driver
 *
 * Copyright (C) 2013 Jean-Jacques Hiblot <jjhiblot@traphandler.com>
 *
 * This file is licensed under the terms of the GNU General Public
 * License version 2. This program is licensed "as is" without any
 * warranty of any kind, whether express or implied.
 */

#include <linux/clk.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/atmel-matrix.h>
#include <linux/mfd/syscon/atmel-smc.h>
#include <linux/init.h>
#include <linux/of_device.h>
#include <linux/regmap.h>

struct atmel_ebi_dev_config {
	int cs;
	struct atmel_smc_cs_conf smcconf;
};

struct atmel_ebi;

struct atmel_ebi_dev {
	struct list_head node;
	struct atmel_ebi *ebi;
	u32 mode;
	int numcs;
	struct atmel_ebi_dev_config configs[];
};

struct atmel_ebi_caps {
	unsigned int available_cs;
	unsigned int ebi_csa_offs;
	void (*get_config)(struct atmel_ebi_dev *ebid,
			   struct atmel_ebi_dev_config *conf);
	int (*xlate_config)(struct atmel_ebi_dev *ebid,
			    struct device_node *configs_np,
			    struct atmel_ebi_dev_config *conf);
	void (*apply_config)(struct atmel_ebi_dev *ebid,
			     struct atmel_ebi_dev_config *conf);
};

struct atmel_ebi {
	struct clk *clk;
	struct regmap *matrix;
	struct  {
		struct regmap *regmap;
		struct clk *clk;
		const struct atmel_hsmc_reg_layout *layout;
	} smc;

	struct device *dev;
	const struct atmel_ebi_caps *caps;
	struct list_head devs;
};

struct atmel_smc_timing_xlate {
	const char *name;
	int (*converter)(struct atmel_smc_cs_conf *conf,
			 unsigned int shift, unsigned int nycles);
	unsigned int shift;
};

#define ATMEL_SMC_SETUP_XLATE(nm, pos)	\
	{ .name = nm, .converter = atmel_smc_cs_conf_set_setup, .shift = pos}

#define ATMEL_SMC_PULSE_XLATE(nm, pos)	\
	{ .name = nm, .converter = atmel_smc_cs_conf_set_pulse, .shift = pos}

#define ATMEL_SMC_CYCLE_XLATE(nm, pos)	\
	{ .name = nm, .converter = atmel_smc_cs_conf_set_cycle, .shift = pos}

static void at91sam9_ebi_get_config(struct atmel_ebi_dev *ebid,
				    struct atmel_ebi_dev_config *conf)
{
	atmel_smc_cs_conf_get(ebid->ebi->smc.regmap, conf->cs,
			      &conf->smcconf);
}

static void sama5_ebi_get_config(struct atmel_ebi_dev *ebid,
				 struct atmel_ebi_dev_config *conf)
{
	atmel_hsmc_cs_conf_get(ebid->ebi->smc.regmap, ebid->ebi->smc.layout,
			       conf->cs, &conf->smcconf);
}

static const struct atmel_smc_timing_xlate timings_xlate_table[] = {
	ATMEL_SMC_SETUP_XLATE("atmel,smc-ncs-rd-setup-ns",
			      ATMEL_SMC_NCS_RD_SHIFT),
	ATMEL_SMC_SETUP_XLATE("atmel,smc-ncs-wr-setup-ns",
			      ATMEL_SMC_NCS_WR_SHIFT),
	ATMEL_SMC_SETUP_XLATE("atmel,smc-nrd-setup-ns", ATMEL_SMC_NRD_SHIFT),
	ATMEL_SMC_SETUP_XLATE("atmel,smc-nwe-setup-ns", ATMEL_SMC_NWE_SHIFT),
	ATMEL_SMC_PULSE_XLATE("atmel,smc-ncs-rd-pulse-ns",
			      ATMEL_SMC_NCS_RD_SHIFT),
	ATMEL_SMC_PULSE_XLATE("atmel,smc-ncs-wr-pulse-ns",
			      ATMEL_SMC_NCS_WR_SHIFT),
	ATMEL_SMC_PULSE_XLATE("atmel,smc-nrd-pulse-ns", ATMEL_SMC_NRD_SHIFT),
	ATMEL_SMC_PULSE_XLATE("atmel,smc-nwe-pulse-ns", ATMEL_SMC_NWE_SHIFT),
	ATMEL_SMC_CYCLE_XLATE("atmel,smc-nrd-cycle-ns", ATMEL_SMC_NRD_SHIFT),
	ATMEL_SMC_CYCLE_XLATE("atmel,smc-nwe-cycle-ns", ATMEL_SMC_NWE_SHIFT),
};

static int atmel_ebi_xslate_smc_timings(struct atmel_ebi_dev *ebid,
					struct device_node *np,
					struct atmel_smc_cs_conf *smcconf)
{
	unsigned int clk_rate = clk_get_rate(ebid->ebi->clk);
	unsigned int clk_period_ns = NSEC_PER_SEC / clk_rate;
	bool required = false;
	unsigned int ncycles;
	int ret, i;
	u32 val;

	ret = of_property_read_u32(np, "atmel,smc-tdf-ns", &val);
	if (!ret) {
		required = true;
		ncycles = DIV_ROUND_UP(val, clk_period_ns);
		if (ncycles > ATMEL_SMC_MODE_TDF_MAX) {
			ret = -EINVAL;
			goto out;
		}

		if (ncycles < ATMEL_SMC_MODE_TDF_MIN)
			ncycles = ATMEL_SMC_MODE_TDF_MIN;

		smcconf->mode |= ATMEL_SMC_MODE_TDF(ncycles);
	}

	for (i = 0; i < ARRAY_SIZE(timings_xlate_table); i++) {
		const struct atmel_smc_timing_xlate *xlate;

		xlate = &timings_xlate_table[i];

		ret = of_property_read_u32(np, xlate->name, &val);
		if (ret) {
			if (!required)
				continue;
			else
				break;
		}

		if (!required) {
			ret = -EINVAL;
			break;
		}

		ncycles = DIV_ROUND_UP(val, clk_period_ns);
		ret = xlate->converter(smcconf, xlate->shift, ncycles);
		if (ret)
			goto out;
	}

out:
	if (ret) {
		dev_err(ebid->ebi->dev,
			"missing or invalid timings definition in %pOF",
			np);
		return ret;
	}

	return required;
}

static int atmel_ebi_xslate_smc_config(struct atmel_ebi_dev *ebid,
				       struct device_node *np,
				       struct atmel_ebi_dev_config *conf)
{
	struct atmel_smc_cs_conf *smcconf = &conf->smcconf;
	bool required = false;
	const char *tmp_str;
	u32 tmp;
	int ret;

	ret = of_property_read_u32(np, "atmel,smc-bus-width", &tmp);
	if (!ret) {
		switch (tmp) {
		case 8:
			smcconf->mode |= ATMEL_SMC_MODE_DBW_8;
			break;

		case 16:
			smcconf->mode |= ATMEL_SMC_MODE_DBW_16;
			break;

		case 32:
			smcconf->mode |= ATMEL_SMC_MODE_DBW_32;
			break;

		default:
			return -EINVAL;
		}

		required = true;
	}

	if (of_property_read_bool(np, "atmel,smc-tdf-optimized")) {
		smcconf->mode |= ATMEL_SMC_MODE_TDFMODE_OPTIMIZED;
		required = true;
	}

	tmp_str = NULL;
	of_property_read_string(np, "atmel,smc-byte-access-type", &tmp_str);
	if (tmp_str && !strcmp(tmp_str, "write")) {
		smcconf->mode |= ATMEL_SMC_MODE_BAT_WRITE;
		required = true;
	}

	tmp_str = NULL;
	of_property_read_string(np, "atmel,smc-read-mode", &tmp_str);
	if (tmp_str && !strcmp(tmp_str, "nrd")) {
		smcconf->mode |= ATMEL_SMC_MODE_READMODE_NRD;
		required = true;
	}

	tmp_str = NULL;
	of_property_read_string(np, "atmel,smc-write-mode", &tmp_str);
	if (tmp_str && !strcmp(tmp_str, "nwe")) {
		smcconf->mode |= ATMEL_SMC_MODE_WRITEMODE_NWE;
		required = true;
	}

	tmp_str = NULL;
	of_property_read_string(np, "atmel,smc-exnw-mode", &tmp_str);
	if (tmp_str) {
		if (!strcmp(tmp_str, "frozen"))
			smcconf->mode |= ATMEL_SMC_MODE_EXNWMODE_FROZEN;
		else if (!strcmp(tmp_str, "ready"))
			smcconf->mode |= ATMEL_SMC_MODE_EXNWMODE_READY;
		else if (strcmp(tmp_str, "disabled"))
			return -EINVAL;

		required = true;
	}

	ret = of_property_read_u32(np, "atmel,smc-page-mode", &tmp);
	if (!ret) {
		switch (tmp) {
		case 4:
			smcconf->mode |= ATMEL_SMC_MODE_PS_4;
			break;

		case 8:
			smcconf->mode |= ATMEL_SMC_MODE_PS_8;
			break;

		case 16:
			smcconf->mode |= ATMEL_SMC_MODE_PS_16;
			break;

		case 32:
			smcconf->mode |= ATMEL_SMC_MODE_PS_32;
			break;

		default:
			return -EINVAL;
		}

		smcconf->mode |= ATMEL_SMC_MODE_PMEN;
		required = true;
	}

	ret = atmel_ebi_xslate_smc_timings(ebid, np, &conf->smcconf);
	if (ret < 0)
		return -EINVAL;

	if ((ret > 0 && !required) || (!ret && required)) {
		dev_err(ebid->ebi->dev, "missing atmel,smc- properties in %pOF",
			np);
		return -EINVAL;
	}

	return required;
}

static void at91sam9_ebi_apply_config(struct atmel_ebi_dev *ebid,
				      struct atmel_ebi_dev_config *conf)
{
	atmel_smc_cs_conf_apply(ebid->ebi->smc.regmap, conf->cs,
				&conf->smcconf);
}

static void sama5_ebi_apply_config(struct atmel_ebi_dev *ebid,
				   struct atmel_ebi_dev_config *conf)
{
	atmel_hsmc_cs_conf_apply(ebid->ebi->smc.regmap, ebid->ebi->smc.layout,
				 conf->cs, &conf->smcconf);
}

static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np,
			       int reg_cells)
{
	const struct atmel_ebi_caps *caps = ebi->caps;
	struct atmel_ebi_dev_config conf = { };
	struct device *dev = ebi->dev;
	struct atmel_ebi_dev *ebid;
	unsigned long cslines = 0;
	int ret, numcs = 0, nentries, i;
	bool apply = false;
	u32 cs;

	nentries = of_property_count_elems_of_size(np, "reg",
						   reg_cells * sizeof(u32));
	for (i = 0; i < nentries; i++) {
		ret = of_property_read_u32_index(np, "reg", i * reg_cells,
						 &cs);
		if (ret)
			return ret;

		if (cs >= AT91_MATRIX_EBI_NUM_CS ||
		    !(ebi->caps->available_cs & BIT(cs))) {
			dev_err(dev, "invalid reg property in %pOF\n", np);
			return -EINVAL;
		}

		if (!test_and_set_bit(cs, &cslines))
			numcs++;
	}

	if (!numcs) {
		dev_err(dev, "invalid reg property in %pOF\n", np);
		return -EINVAL;
	}

	ebid = devm_kzalloc(ebi->dev,
			    sizeof(*ebid) + (numcs * sizeof(*ebid->configs)),
			    GFP_KERNEL);
	if (!ebid)
		return -ENOMEM;

	ebid->ebi = ebi;
	ebid->numcs = numcs;

	ret = caps->xlate_config(ebid, np, &conf);
	if (ret < 0)
		return ret;
	else if (ret)
		apply = true;

	i = 0;
	for_each_set_bit(cs, &cslines, AT91_MATRIX_EBI_NUM_CS) {
		ebid->configs[i].cs = cs;

		if (apply) {
			conf.cs = cs;
			caps->apply_config(ebid, &conf);
		}

		caps->get_config(ebid, &ebid->configs[i]);

		/*
		 * Attach the EBI device to the generic SMC logic if at least
		 * one "atmel,smc-" property is present.
		 */
		if (ebi->caps->ebi_csa_offs && apply)
			regmap_update_bits(ebi->matrix,
					   ebi->caps->ebi_csa_offs,
					   BIT(cs), 0);

		i++;
	}

	list_add_tail(&ebid->node, &ebi->devs);

	return 0;
}

static const struct atmel_ebi_caps at91sam9260_ebi_caps = {
	.available_cs = 0xff,
	.ebi_csa_offs = AT91SAM9260_MATRIX_EBICSA,
	.get_config = at91sam9_ebi_get_config,
	.xlate_config = atmel_ebi_xslate_smc_config,
	.apply_config = at91sam9_ebi_apply_config,
};

static const struct atmel_ebi_caps at91sam9261_ebi_caps = {
	.available_cs = 0xff,
	.ebi_csa_offs = AT91SAM9261_MATRIX_EBICSA,
	.get_config = at91sam9_ebi_get_config,
	.xlate_config = atmel_ebi_xslate_smc_config,
	.apply_config = at91sam9_ebi_apply_config,
};

static const struct atmel_ebi_caps at91sam9263_ebi0_caps = {
	.available_cs = 0x3f,
	.ebi_csa_offs = AT91SAM9263_MATRIX_EBI0CSA,
	.get_config = at91sam9_ebi_get_config,
	.xlate_config = atmel_ebi_xslate_smc_config,
	.apply_config = at91sam9_ebi_apply_config,
};

static const struct atmel_ebi_caps at91sam9263_ebi1_caps = {
	.available_cs = 0x7,
	.ebi_csa_offs = AT91SAM9263_MATRIX_EBI1CSA,
	.get_config = at91sam9_ebi_get_config,
	.xlate_config = atmel_ebi_xslate_smc_config,
	.apply_config = at91sam9_ebi_apply_config,
};

static const struct atmel_ebi_caps at91sam9rl_ebi_caps = {
	.available_cs = 0x3f,
	.ebi_csa_offs = AT91SAM9RL_MATRIX_EBICSA,
	.get_config = at91sam9_ebi_get_config,
	.xlate_config = atmel_ebi_xslate_smc_config,
	.apply_config = at91sam9_ebi_apply_config,
};

static const struct atmel_ebi_caps at91sam9g45_ebi_caps = {
	.available_cs = 0x3f,
	.ebi_csa_offs = AT91SAM9G45_MATRIX_EBICSA,
	.get_config = at91sam9_ebi_get_config,
	.xlate_config = atmel_ebi_xslate_smc_config,
	.apply_config = at91sam9_ebi_apply_config,
};

static const struct atmel_ebi_caps at91sam9x5_ebi_caps = {
	.available_cs = 0x3f,
	.ebi_csa_offs = AT91SAM9X5_MATRIX_EBICSA,
	.get_config = at91sam9_ebi_get_config,
	.xlate_config = atmel_ebi_xslate_smc_config,
	.apply_config = at91sam9_ebi_apply_config,
};

static const struct atmel_ebi_caps sama5d3_ebi_caps = {
	.available_cs = 0xf,
	.get_config = sama5_ebi_get_config,
	.xlate_config = atmel_ebi_xslate_smc_config,
	.apply_config = sama5_ebi_apply_config,
};

static const struct of_device_id atmel_ebi_id_table[] = {
	{
		.compatible = "atmel,at91sam9260-ebi",
		.data = &at91sam9260_ebi_caps,
	},
	{
		.compatible = "atmel,at91sam9261-ebi",
		.data = &at91sam9261_ebi_caps,
	},
	{
		.compatible = "atmel,at91sam9263-ebi0",
		.data = &at91sam9263_ebi0_caps,
	},
	{
		.compatible = "atmel,at91sam9263-ebi1",
		.data = &at91sam9263_ebi1_caps,
	},
	{
		.compatible = "atmel,at91sam9rl-ebi",
		.data = &at91sam9rl_ebi_caps,
	},
	{
		.compatible = "atmel,at91sam9g45-ebi",
		.data = &at91sam9g45_ebi_caps,
	},
	{
		.compatible = "atmel,at91sam9x5-ebi",
		.data = &at91sam9x5_ebi_caps,
	},
	{
		.compatible = "atmel,sama5d3-ebi",
		.data = &sama5d3_ebi_caps,
	},
	{ /* sentinel */ }
};

static int atmel_ebi_dev_disable(struct atmel_ebi *ebi, struct device_node *np)
{
	struct device *dev = ebi->dev;
	struct property *newprop;

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

	newprop->name = devm_kstrdup(dev, "status", GFP_KERNEL);
	if (!newprop->name)
		return -ENOMEM;

	newprop->value = devm_kstrdup(dev, "disabled", GFP_KERNEL);
	if (!newprop->value)
		return -ENOMEM;

	newprop->length = sizeof("disabled");

	return of_update_property(np, newprop);
}

static int atmel_ebi_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *child, *np = dev->of_node, *smc_np;
	const struct of_device_id *match;
	struct atmel_ebi *ebi;
	int ret, reg_cells;
	struct clk *clk;
	u32 val;

	match = of_match_device(atmel_ebi_id_table, dev);
	if (!match || !match->data)
		return -EINVAL;

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

	platform_set_drvdata(pdev, ebi);

	INIT_LIST_HEAD(&ebi->devs);
	ebi->caps = match->data;
	ebi->dev = dev;

	clk = devm_clk_get(dev, NULL);
	if (IS_ERR(clk))
		return PTR_ERR(clk);

	ebi->clk = clk;

	smc_np = of_parse_phandle(dev->of_node, "atmel,smc", 0);

	ebi->smc.regmap = syscon_node_to_regmap(smc_np);
	if (IS_ERR(ebi->smc.regmap))
		return PTR_ERR(ebi->smc.regmap);

	ebi->smc.layout = atmel_hsmc_get_reg_layout(smc_np);
	if (IS_ERR(ebi->smc.layout))
		return PTR_ERR(ebi->smc.layout);

	ebi->smc.clk = of_clk_get(smc_np, 0);
	if (IS_ERR(ebi->smc.clk)) {
		if (PTR_ERR(ebi->smc.clk) != -ENOENT)
			return PTR_ERR(ebi->smc.clk);

		ebi->smc.clk = NULL;
	}
	ret = clk_prepare_enable(ebi->smc.clk);
	if (ret)
		return ret;

	/*
	 * The sama5d3 does not provide an EBICSA register and thus does need
	 * to access the matrix registers.
	 */
	if (ebi->caps->ebi_csa_offs) {
		ebi->matrix =
			syscon_regmap_lookup_by_phandle(np, "atmel,matrix");
		if (IS_ERR(ebi->matrix))
			return PTR_ERR(ebi->matrix);
	}

	ret = of_property_read_u32(np, "#address-cells", &val);
	if (ret) {
		dev_err(dev, "missing #address-cells property\n");
		return ret;
	}

	reg_cells = val;

	ret = of_property_read_u32(np, "#size-cells", &val);
	if (ret) {
		dev_err(dev, "missing #address-cells property\n");
		return ret;
	}

	reg_cells += val;

	for_each_available_child_of_node(np, child) {
		if (!of_find_property(child, "reg", NULL))
			continue;

		ret = atmel_ebi_dev_setup(ebi, child, reg_cells);
		if (ret) {
			dev_err(dev, "failed to configure EBI bus for %pOF, disabling the device",
				child);

			ret = atmel_ebi_dev_disable(ebi, child);
			if (ret)
				return ret;
		}
	}

	return of_platform_populate(np, NULL, NULL, dev);
}

static __maybe_unused int atmel_ebi_resume(struct device *dev)
{
	struct atmel_ebi *ebi = dev_get_drvdata(dev);
	struct atmel_ebi_dev *ebid;

	list_for_each_entry(ebid, &ebi->devs, node) {
		int i;

		for (i = 0; i < ebid->numcs; i++)
			ebid->ebi->caps->apply_config(ebid, &ebid->configs[i]);
	}

	return 0;
}

static SIMPLE_DEV_PM_OPS(atmel_ebi_pm_ops, NULL, atmel_ebi_resume);

static struct platform_driver atmel_ebi_driver = {
	.driver = {
		.name = "atmel-ebi",
		.of_match_table	= atmel_ebi_id_table,
		.pm = &atmel_ebi_pm_ops,
	},
};
builtin_platform_driver_probe(atmel_ebi_driver, atmel_ebi_probe);
