// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2021 Linaro Ltd.
 * Author: Sam Protsenko <semen.protsenko@linaro.org>
 *
 * Samsung Exynos USI driver (Universal Serial Interface).
 */

#include <linux/clk.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

#include <dt-bindings/soc/samsung,exynos-usi.h>

/* USIv2: System Register: SW_CONF register bits */
#define USI_V2_SW_CONF_NONE	0x0
#define USI_V2_SW_CONF_UART	BIT(0)
#define USI_V2_SW_CONF_SPI	BIT(1)
#define USI_V2_SW_CONF_I2C	BIT(2)
#define USI_V2_SW_CONF_MASK	(USI_V2_SW_CONF_UART | USI_V2_SW_CONF_SPI | \
				 USI_V2_SW_CONF_I2C)

/* USIv2: USI register offsets */
#define USI_CON			0x04
#define USI_OPTION		0x08

/* USIv2: USI register bits */
#define USI_CON_RESET		BIT(0)
#define USI_OPTION_CLKREQ_ON	BIT(1)
#define USI_OPTION_CLKSTOP_ON	BIT(2)

enum exynos_usi_ver {
	USI_VER2 = 2,
};

struct exynos_usi_variant {
	enum exynos_usi_ver ver;	/* USI IP-core version */
	unsigned int sw_conf_mask;	/* SW_CONF mask for all protocols */
	size_t min_mode;		/* first index in exynos_usi_modes[] */
	size_t max_mode;		/* last index in exynos_usi_modes[] */
	size_t num_clks;		/* number of clocks to assert */
	const char * const *clk_names;	/* clock names to assert */
};

struct exynos_usi {
	struct device *dev;
	void __iomem *regs;		/* USI register map */
	struct clk_bulk_data *clks;	/* USI clocks */

	size_t mode;			/* current USI SW_CONF mode index */
	bool clkreq_on;			/* always provide clock to IP */

	/* System Register */
	struct regmap *sysreg;		/* System Register map */
	unsigned int sw_conf;		/* SW_CONF register offset in sysreg */

	const struct exynos_usi_variant *data;
};

struct exynos_usi_mode {
	const char *name;		/* mode name */
	unsigned int val;		/* mode register value */
};

static const struct exynos_usi_mode exynos_usi_modes[] = {
	[USI_V2_NONE] =	{ .name = "none", .val = USI_V2_SW_CONF_NONE },
	[USI_V2_UART] =	{ .name = "uart", .val = USI_V2_SW_CONF_UART },
	[USI_V2_SPI] =	{ .name = "spi",  .val = USI_V2_SW_CONF_SPI },
	[USI_V2_I2C] =	{ .name = "i2c",  .val = USI_V2_SW_CONF_I2C },
};

static const char * const exynos850_usi_clk_names[] = { "pclk", "ipclk" };
static const struct exynos_usi_variant exynos850_usi_data = {
	.ver		= USI_VER2,
	.sw_conf_mask	= USI_V2_SW_CONF_MASK,
	.min_mode	= USI_V2_NONE,
	.max_mode	= USI_V2_I2C,
	.num_clks	= ARRAY_SIZE(exynos850_usi_clk_names),
	.clk_names	= exynos850_usi_clk_names,
};

static const struct of_device_id exynos_usi_dt_match[] = {
	{
		.compatible = "samsung,exynos850-usi",
		.data = &exynos850_usi_data,
	},
	{ } /* sentinel */
};
MODULE_DEVICE_TABLE(of, exynos_usi_dt_match);

/**
 * exynos_usi_set_sw_conf - Set USI block configuration mode
 * @usi: USI driver object
 * @mode: Mode index
 *
 * Select underlying serial protocol (UART/SPI/I2C) in USI IP-core.
 *
 * Return: 0 on success, or negative error code on failure.
 */
static int exynos_usi_set_sw_conf(struct exynos_usi *usi, size_t mode)
{
	unsigned int val;
	int ret;

	if (mode < usi->data->min_mode || mode > usi->data->max_mode)
		return -EINVAL;

	val = exynos_usi_modes[mode].val;
	ret = regmap_update_bits(usi->sysreg, usi->sw_conf,
				 usi->data->sw_conf_mask, val);
	if (ret)
		return ret;

	usi->mode = mode;
	dev_dbg(usi->dev, "protocol: %s\n", exynos_usi_modes[usi->mode].name);

	return 0;
}

/**
 * exynos_usi_enable - Initialize USI block
 * @usi: USI driver object
 *
 * USI IP-core start state is "reset" (on startup and after CPU resume). This
 * routine enables the USI block by clearing the reset flag. It also configures
 * HWACG behavior (needed e.g. for UART Rx). It should be performed before
 * underlying protocol becomes functional.
 *
 * Return: 0 on success, or negative error code on failure.
 */
static int exynos_usi_enable(const struct exynos_usi *usi)
{
	u32 val;
	int ret;

	ret = clk_bulk_prepare_enable(usi->data->num_clks, usi->clks);
	if (ret)
		return ret;

	/* Enable USI block */
	val = readl(usi->regs + USI_CON);
	val &= ~USI_CON_RESET;
	writel(val, usi->regs + USI_CON);
	udelay(1);

	/* Continuously provide the clock to USI IP w/o gating */
	if (usi->clkreq_on) {
		val = readl(usi->regs + USI_OPTION);
		val &= ~USI_OPTION_CLKSTOP_ON;
		val |= USI_OPTION_CLKREQ_ON;
		writel(val, usi->regs + USI_OPTION);
	}

	clk_bulk_disable_unprepare(usi->data->num_clks, usi->clks);

	return ret;
}

static int exynos_usi_configure(struct exynos_usi *usi)
{
	int ret;

	ret = exynos_usi_set_sw_conf(usi, usi->mode);
	if (ret)
		return ret;

	if (usi->data->ver == USI_VER2)
		return exynos_usi_enable(usi);

	return 0;
}

static int exynos_usi_parse_dt(struct device_node *np, struct exynos_usi *usi)
{
	int ret;
	u32 mode;

	ret = of_property_read_u32(np, "samsung,mode", &mode);
	if (ret)
		return ret;
	if (mode < usi->data->min_mode || mode > usi->data->max_mode)
		return -EINVAL;
	usi->mode = mode;

	usi->sysreg = syscon_regmap_lookup_by_phandle(np, "samsung,sysreg");
	if (IS_ERR(usi->sysreg))
		return PTR_ERR(usi->sysreg);

	ret = of_property_read_u32_index(np, "samsung,sysreg", 1,
					 &usi->sw_conf);
	if (ret)
		return ret;

	usi->clkreq_on = of_property_read_bool(np, "samsung,clkreq-on");

	return 0;
}

static int exynos_usi_get_clocks(struct exynos_usi *usi)
{
	const size_t num = usi->data->num_clks;
	struct device *dev = usi->dev;
	size_t i;

	if (num == 0)
		return 0;

	usi->clks = devm_kcalloc(dev, num, sizeof(*usi->clks), GFP_KERNEL);
	if (!usi->clks)
		return -ENOMEM;

	for (i = 0; i < num; ++i)
		usi->clks[i].id = usi->data->clk_names[i];

	return devm_clk_bulk_get(dev, num, usi->clks);
}

static int exynos_usi_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct exynos_usi *usi;
	int ret;

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

	usi->dev = dev;
	platform_set_drvdata(pdev, usi);

	usi->data = of_device_get_match_data(dev);
	if (!usi->data)
		return -EINVAL;

	ret = exynos_usi_parse_dt(np, usi);
	if (ret)
		return ret;

	ret = exynos_usi_get_clocks(usi);
	if (ret)
		return ret;

	if (usi->data->ver == USI_VER2) {
		usi->regs = devm_platform_ioremap_resource(pdev, 0);
		if (IS_ERR(usi->regs))
			return PTR_ERR(usi->regs);
	}

	ret = exynos_usi_configure(usi);
	if (ret)
		return ret;

	/* Make it possible to embed protocol nodes into USI np */
	return of_platform_populate(np, NULL, NULL, dev);
}

static int __maybe_unused exynos_usi_resume_noirq(struct device *dev)
{
	struct exynos_usi *usi = dev_get_drvdata(dev);

	return exynos_usi_configure(usi);
}

static const struct dev_pm_ops exynos_usi_pm = {
	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(NULL, exynos_usi_resume_noirq)
};

static struct platform_driver exynos_usi_driver = {
	.driver = {
		.name		= "exynos-usi",
		.pm		= &exynos_usi_pm,
		.of_match_table	= exynos_usi_dt_match,
	},
	.probe = exynos_usi_probe,
};
module_platform_driver(exynos_usi_driver);

MODULE_DESCRIPTION("Samsung USI driver");
MODULE_AUTHOR("Sam Protsenko <semen.protsenko@linaro.org>");
MODULE_LICENSE("GPL");
