// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) 2015, Daniel Thompson
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/hw_random.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/reset.h>
#include <linux/slab.h>

#define RNG_CR			0x00
#define RNG_CR_RNGEN		BIT(2)
#define RNG_CR_CED		BIT(5)
#define RNG_CR_CONFIG1		GENMASK(11, 8)
#define RNG_CR_NISTC		BIT(12)
#define RNG_CR_CONFIG2		GENMASK(15, 13)
#define RNG_CR_CLKDIV_SHIFT	16
#define RNG_CR_CLKDIV		GENMASK(19, 16)
#define RNG_CR_CONFIG3		GENMASK(25, 20)
#define RNG_CR_CONDRST		BIT(30)
#define RNG_CR_CONFLOCK		BIT(31)
#define RNG_CR_ENTROPY_SRC_MASK	(RNG_CR_CONFIG1 | RNG_CR_NISTC | RNG_CR_CONFIG2 | RNG_CR_CONFIG3)
#define RNG_CR_CONFIG_MASK	(RNG_CR_ENTROPY_SRC_MASK | RNG_CR_CED | RNG_CR_CLKDIV)

#define RNG_SR			0x04
#define RNG_SR_DRDY		BIT(0)
#define RNG_SR_CECS		BIT(1)
#define RNG_SR_SECS		BIT(2)
#define RNG_SR_CEIS		BIT(5)
#define RNG_SR_SEIS		BIT(6)

#define RNG_DR			0x08

#define RNG_NSCR		0x0C
#define RNG_NSCR_MASK		GENMASK(17, 0)

#define RNG_HTCR		0x10

#define RNG_NB_RECOVER_TRIES	3

struct stm32_rng_data {
	uint	max_clock_rate;
	u32	cr;
	u32	nscr;
	u32	htcr;
	bool	has_cond_reset;
};

/**
 * struct stm32_rng_config - RNG configuration data
 *
 * @cr:			RNG configuration. 0 means default hardware RNG configuration
 * @nscr:		Noise sources control configuration.
 * @htcr:		Health tests configuration.
 */
struct stm32_rng_config {
	u32 cr;
	u32 nscr;
	u32 htcr;
};

struct stm32_rng_private {
	struct hwrng rng;
	struct device *dev;
	void __iomem *base;
	struct clk *clk;
	struct reset_control *rst;
	struct stm32_rng_config pm_conf;
	const struct stm32_rng_data *data;
	bool ced;
	bool lock_conf;
};

/*
 * Extracts from the STM32 RNG specification when RNG supports CONDRST.
 *
 * When a noise source (or seed) error occurs, the RNG stops generating
 * random numbers and sets to “1” both SEIS and SECS bits to indicate
 * that a seed error occurred. (...)
 *
 * 1. Software reset by writing CONDRST at 1 and at 0 (see bitfield
 * description for details). This step is needed only if SECS is set.
 * Indeed, when SEIS is set and SECS is cleared it means RNG performed
 * the reset automatically (auto-reset).
 * 2. If SECS was set in step 1 (no auto-reset) wait for CONDRST
 * to be cleared in the RNG_CR register, then confirm that SEIS is
 * cleared in the RNG_SR register. Otherwise just clear SEIS bit in
 * the RNG_SR register.
 * 3. If SECS was set in step 1 (no auto-reset) wait for SECS to be
 * cleared by RNG. The random number generation is now back to normal.
 */
static int stm32_rng_conceal_seed_error_cond_reset(struct stm32_rng_private *priv)
{
	struct device *dev = priv->dev;
	u32 sr = readl_relaxed(priv->base + RNG_SR);
	u32 cr = readl_relaxed(priv->base + RNG_CR);
	int err;

	if (sr & RNG_SR_SECS) {
		/* Conceal by resetting the subsystem (step 1.) */
		writel_relaxed(cr | RNG_CR_CONDRST, priv->base + RNG_CR);
		writel_relaxed(cr & ~RNG_CR_CONDRST, priv->base + RNG_CR);
	} else {
		/* RNG auto-reset (step 2.) */
		writel_relaxed(sr & ~RNG_SR_SEIS, priv->base + RNG_SR);
		goto end;
	}

	err = readl_relaxed_poll_timeout_atomic(priv->base + RNG_CR, cr, !(cr & RNG_CR_CONDRST), 10,
						100000);
	if (err) {
		dev_err(dev, "%s: timeout %x\n", __func__, sr);
		return err;
	}

	/* Check SEIS is cleared (step 2.) */
	if (readl_relaxed(priv->base + RNG_SR) & RNG_SR_SEIS)
		return -EINVAL;

	err = readl_relaxed_poll_timeout_atomic(priv->base + RNG_SR, sr, !(sr & RNG_SR_SECS), 10,
						100000);
	if (err) {
		dev_err(dev, "%s: timeout %x\n", __func__, sr);
		return err;
	}

end:
	return 0;
}

/*
 * Extracts from the STM32 RNG specification, when CONDRST is not supported
 *
 * When a noise source (or seed) error occurs, the RNG stops generating
 * random numbers and sets to “1” both SEIS and SECS bits to indicate
 * that a seed error occurred. (...)
 *
 * The following sequence shall be used to fully recover from a seed
 * error after the RNG initialization:
 * 1. Clear the SEIS bit by writing it to “0”.
 * 2. Read out 12 words from the RNG_DR register, and discard each of
 * them in order to clean the pipeline.
 * 3. Confirm that SEIS is still cleared. Random number generation is
 * back to normal.
 */
static int stm32_rng_conceal_seed_error_sw_reset(struct stm32_rng_private *priv)
{
	unsigned int i = 0;
	u32 sr = readl_relaxed(priv->base + RNG_SR);

	writel_relaxed(sr & ~RNG_SR_SEIS, priv->base + RNG_SR);

	for (i = 12; i != 0; i--)
		(void)readl_relaxed(priv->base + RNG_DR);

	if (readl_relaxed(priv->base + RNG_SR) & RNG_SR_SEIS)
		return -EINVAL;

	return 0;
}

static int stm32_rng_conceal_seed_error(struct hwrng *rng)
{
	struct stm32_rng_private *priv = container_of(rng, struct stm32_rng_private, rng);

	dev_dbg(priv->dev, "Concealing seed error\n");

	if (priv->data->has_cond_reset)
		return stm32_rng_conceal_seed_error_cond_reset(priv);
	else
		return stm32_rng_conceal_seed_error_sw_reset(priv);
};


static int stm32_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
{
	struct stm32_rng_private *priv = container_of(rng, struct stm32_rng_private, rng);
	unsigned int i = 0;
	int retval = 0, err = 0;
	u32 sr;

	retval = pm_runtime_resume_and_get(priv->dev);
	if (retval)
		return retval;

	if (readl_relaxed(priv->base + RNG_SR) & RNG_SR_SEIS)
		stm32_rng_conceal_seed_error(rng);

	while (max >= sizeof(u32)) {
		sr = readl_relaxed(priv->base + RNG_SR);
		/*
		 * Manage timeout which is based on timer and take
		 * care of initial delay time when enabling the RNG.
		 */
		if (!sr && wait) {
			err = readl_relaxed_poll_timeout_atomic(priv->base
								   + RNG_SR,
								   sr, sr,
								   10, 50000);
			if (err) {
				dev_err(priv->dev, "%s: timeout %x!\n", __func__, sr);
				break;
			}
		} else if (!sr) {
			/* The FIFO is being filled up */
			break;
		}

		if (sr != RNG_SR_DRDY) {
			if (sr & RNG_SR_SEIS) {
				err = stm32_rng_conceal_seed_error(rng);
				i++;
				if (err && i > RNG_NB_RECOVER_TRIES) {
					dev_err(priv->dev, "Couldn't recover from seed error\n");
					retval = -ENOTRECOVERABLE;
					goto exit_rpm;
				}

				continue;
			}

			if (WARN_ONCE((sr & RNG_SR_CEIS), "RNG clock too slow - %x\n", sr))
				writel_relaxed(0, priv->base + RNG_SR);
		}

		/* Late seed error case: DR being 0 is an error status */
		*(u32 *)data = readl_relaxed(priv->base + RNG_DR);
		if (!*(u32 *)data) {
			err = stm32_rng_conceal_seed_error(rng);
			i++;
			if (err && i > RNG_NB_RECOVER_TRIES) {
				dev_err(priv->dev, "Couldn't recover from seed error");
				retval = -ENOTRECOVERABLE;
				goto exit_rpm;
			}

			continue;
		}

		i = 0;
		retval += sizeof(u32);
		data += sizeof(u32);
		max -= sizeof(u32);
	}

exit_rpm:
	pm_runtime_mark_last_busy(priv->dev);
	pm_runtime_put_sync_autosuspend(priv->dev);

	return retval || !wait ? retval : -EIO;
}

static uint stm32_rng_clock_freq_restrain(struct hwrng *rng)
{
	struct stm32_rng_private *priv =
	    container_of(rng, struct stm32_rng_private, rng);
	unsigned long clock_rate = 0;
	uint clock_div = 0;

	clock_rate = clk_get_rate(priv->clk);

	/*
	 * Get the exponent to apply on the CLKDIV field in RNG_CR register
	 * No need to handle the case when clock-div > 0xF as it is physically
	 * impossible
	 */
	while ((clock_rate >> clock_div) > priv->data->max_clock_rate)
		clock_div++;

	pr_debug("RNG clk rate : %lu\n", clk_get_rate(priv->clk) >> clock_div);

	return clock_div;
}

static int stm32_rng_init(struct hwrng *rng)
{
	struct stm32_rng_private *priv =
	    container_of(rng, struct stm32_rng_private, rng);
	int err;
	u32 reg;

	err = clk_prepare_enable(priv->clk);
	if (err)
		return err;

	/* clear error indicators */
	writel_relaxed(0, priv->base + RNG_SR);

	reg = readl_relaxed(priv->base + RNG_CR);

	/*
	 * Keep default RNG configuration if none was specified.
	 * 0 is an invalid value as it disables all entropy sources.
	 */
	if (priv->data->has_cond_reset && priv->data->cr) {
		uint clock_div = stm32_rng_clock_freq_restrain(rng);

		reg &= ~RNG_CR_CONFIG_MASK;
		reg |= RNG_CR_CONDRST | (priv->data->cr & RNG_CR_ENTROPY_SRC_MASK) |
		       (clock_div << RNG_CR_CLKDIV_SHIFT);
		if (priv->ced)
			reg &= ~RNG_CR_CED;
		else
			reg |= RNG_CR_CED;
		writel_relaxed(reg, priv->base + RNG_CR);

		/* Health tests and noise control registers */
		writel_relaxed(priv->data->htcr, priv->base + RNG_HTCR);
		writel_relaxed(priv->data->nscr & RNG_NSCR_MASK, priv->base + RNG_NSCR);

		reg &= ~RNG_CR_CONDRST;
		reg |= RNG_CR_RNGEN;
		if (priv->lock_conf)
			reg |= RNG_CR_CONFLOCK;

		writel_relaxed(reg, priv->base + RNG_CR);

		err = readl_relaxed_poll_timeout_atomic(priv->base + RNG_CR, reg,
							(!(reg & RNG_CR_CONDRST)),
							10, 50000);
		if (err) {
			clk_disable_unprepare(priv->clk);
			dev_err(priv->dev, "%s: timeout %x!\n", __func__, reg);
			return -EINVAL;
		}
	} else {
		/* Handle all RNG versions by checking if conditional reset should be set */
		if (priv->data->has_cond_reset)
			reg |= RNG_CR_CONDRST;

		if (priv->ced)
			reg &= ~RNG_CR_CED;
		else
			reg |= RNG_CR_CED;

		writel_relaxed(reg, priv->base + RNG_CR);

		if (priv->data->has_cond_reset)
			reg &= ~RNG_CR_CONDRST;

		reg |= RNG_CR_RNGEN;

		writel_relaxed(reg, priv->base + RNG_CR);
	}

	err = readl_relaxed_poll_timeout_atomic(priv->base + RNG_SR, reg,
						reg & RNG_SR_DRDY,
						10, 100000);
	if (err || (reg & ~RNG_SR_DRDY)) {
		clk_disable_unprepare(priv->clk);
		dev_err(priv->dev, "%s: timeout:%x SR: %x!\n", __func__, err, reg);
		return -EINVAL;
	}

	clk_disable_unprepare(priv->clk);

	return 0;
}

static void stm32_rng_remove(struct platform_device *ofdev)
{
	pm_runtime_disable(&ofdev->dev);
}

static int __maybe_unused stm32_rng_runtime_suspend(struct device *dev)
{
	struct stm32_rng_private *priv = dev_get_drvdata(dev);
	u32 reg;

	reg = readl_relaxed(priv->base + RNG_CR);
	reg &= ~RNG_CR_RNGEN;
	writel_relaxed(reg, priv->base + RNG_CR);
	clk_disable_unprepare(priv->clk);

	return 0;
}

static int __maybe_unused stm32_rng_suspend(struct device *dev)
{
	struct stm32_rng_private *priv = dev_get_drvdata(dev);
	int err;

	err = clk_prepare_enable(priv->clk);
	if (err)
		return err;

	if (priv->data->has_cond_reset) {
		priv->pm_conf.nscr = readl_relaxed(priv->base + RNG_NSCR);
		priv->pm_conf.htcr = readl_relaxed(priv->base + RNG_HTCR);
	}

	/* Do not save that RNG is enabled as it will be handled at resume */
	priv->pm_conf.cr = readl_relaxed(priv->base + RNG_CR) & ~RNG_CR_RNGEN;

	writel_relaxed(priv->pm_conf.cr, priv->base + RNG_CR);

	clk_disable_unprepare(priv->clk);

	return 0;
}

static int __maybe_unused stm32_rng_runtime_resume(struct device *dev)
{
	struct stm32_rng_private *priv = dev_get_drvdata(dev);
	int err;
	u32 reg;

	err = clk_prepare_enable(priv->clk);
	if (err)
		return err;

	/* Clean error indications */
	writel_relaxed(0, priv->base + RNG_SR);

	reg = readl_relaxed(priv->base + RNG_CR);
	reg |= RNG_CR_RNGEN;
	writel_relaxed(reg, priv->base + RNG_CR);

	return 0;
}

static int __maybe_unused stm32_rng_resume(struct device *dev)
{
	struct stm32_rng_private *priv = dev_get_drvdata(dev);
	int err;
	u32 reg;

	err = clk_prepare_enable(priv->clk);
	if (err)
		return err;

	/* Clean error indications */
	writel_relaxed(0, priv->base + RNG_SR);

	if (priv->data->has_cond_reset) {
		/*
		 * Correct configuration in bits [29:4] must be set in the same
		 * access that set RNG_CR_CONDRST bit. Else config setting is
		 * not taken into account. CONFIGLOCK bit must also be unset but
		 * it is not handled at the moment.
		 */
		writel_relaxed(priv->pm_conf.cr | RNG_CR_CONDRST, priv->base + RNG_CR);

		writel_relaxed(priv->pm_conf.nscr, priv->base + RNG_NSCR);
		writel_relaxed(priv->pm_conf.htcr, priv->base + RNG_HTCR);

		reg = readl_relaxed(priv->base + RNG_CR);
		reg |= RNG_CR_RNGEN;
		reg &= ~RNG_CR_CONDRST;
		writel_relaxed(reg, priv->base + RNG_CR);

		err = readl_relaxed_poll_timeout_atomic(priv->base + RNG_CR, reg,
							reg & ~RNG_CR_CONDRST, 10, 100000);

		if (err) {
			clk_disable_unprepare(priv->clk);
			dev_err(priv->dev, "%s: timeout:%x CR: %x!\n", __func__, err, reg);
			return -EINVAL;
		}
	} else {
		reg = priv->pm_conf.cr;
		reg |= RNG_CR_RNGEN;
		writel_relaxed(reg, priv->base + RNG_CR);
	}

	clk_disable_unprepare(priv->clk);

	return 0;
}

static const struct dev_pm_ops __maybe_unused stm32_rng_pm_ops = {
	SET_RUNTIME_PM_OPS(stm32_rng_runtime_suspend,
			   stm32_rng_runtime_resume, NULL)
	SET_SYSTEM_SLEEP_PM_OPS(stm32_rng_suspend,
				stm32_rng_resume)
};

static const struct stm32_rng_data stm32mp13_rng_data = {
	.has_cond_reset = true,
	.max_clock_rate = 48000000,
	.cr = 0x00F00D00,
	.nscr = 0x2B5BB,
	.htcr = 0x969D,
};

static const struct stm32_rng_data stm32_rng_data = {
	.has_cond_reset = false,
	.max_clock_rate = 3000000,
};

static const struct of_device_id stm32_rng_match[] = {
	{
		.compatible = "st,stm32mp13-rng",
		.data = &stm32mp13_rng_data,
	},
	{
		.compatible = "st,stm32-rng",
		.data = &stm32_rng_data,
	},
	{},
};
MODULE_DEVICE_TABLE(of, stm32_rng_match);

static int stm32_rng_probe(struct platform_device *ofdev)
{
	struct device *dev = &ofdev->dev;
	struct device_node *np = ofdev->dev.of_node;
	struct stm32_rng_private *priv;
	struct resource *res;

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

	priv->base = devm_platform_get_and_ioremap_resource(ofdev, 0, &res);
	if (IS_ERR(priv->base))
		return PTR_ERR(priv->base);

	priv->clk = devm_clk_get(&ofdev->dev, NULL);
	if (IS_ERR(priv->clk))
		return PTR_ERR(priv->clk);

	priv->rst = devm_reset_control_get(&ofdev->dev, NULL);
	if (!IS_ERR(priv->rst)) {
		reset_control_assert(priv->rst);
		udelay(2);
		reset_control_deassert(priv->rst);
	}

	priv->ced = of_property_read_bool(np, "clock-error-detect");
	priv->lock_conf = of_property_read_bool(np, "st,rng-lock-conf");
	priv->dev = dev;

	priv->data = of_device_get_match_data(dev);
	if (!priv->data)
		return -ENODEV;

	dev_set_drvdata(dev, priv);

	priv->rng.name = dev_driver_string(dev);
	priv->rng.init = stm32_rng_init;
	priv->rng.read = stm32_rng_read;
	priv->rng.quality = 900;

	pm_runtime_set_autosuspend_delay(dev, 100);
	pm_runtime_use_autosuspend(dev);
	pm_runtime_enable(dev);

	return devm_hwrng_register(dev, &priv->rng);
}

static struct platform_driver stm32_rng_driver = {
	.driver = {
		.name = "stm32-rng",
		.pm = pm_ptr(&stm32_rng_pm_ops),
		.of_match_table = stm32_rng_match,
	},
	.probe = stm32_rng_probe,
	.remove_new = stm32_rng_remove,
};

module_platform_driver(stm32_rng_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Daniel Thompson <daniel.thompson@linaro.org>");
MODULE_DESCRIPTION("STMicroelectronics STM32 RNG device driver");
