/*
* Copyright (C) 2015 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*/
/*
 * DESCRIPTION: The Broadcom iProc RNG200 Driver
 */

#include <linux/hw_random.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/delay.h>

/* Registers */
#define RNG_CTRL_OFFSET					0x00
#define RNG_CTRL_RNG_RBGEN_MASK				0x00001FFF
#define RNG_CTRL_RNG_RBGEN_ENABLE			0x00000001

#define RNG_SOFT_RESET_OFFSET				0x04
#define RNG_SOFT_RESET					0x00000001

#define RBG_SOFT_RESET_OFFSET				0x08
#define RBG_SOFT_RESET					0x00000001

#define RNG_INT_STATUS_OFFSET				0x18
#define RNG_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK	0x80000000
#define RNG_INT_STATUS_STARTUP_TRANSITIONS_MET_IRQ_MASK	0x00020000
#define RNG_INT_STATUS_NIST_FAIL_IRQ_MASK		0x00000020
#define RNG_INT_STATUS_TOTAL_BITS_COUNT_IRQ_MASK	0x00000001

#define RNG_FIFO_DATA_OFFSET				0x20

#define RNG_FIFO_COUNT_OFFSET				0x24
#define RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK		0x000000FF

struct iproc_rng200_dev {
	struct hwrng rng;
	void __iomem *base;
};

#define to_rng_priv(rng)	container_of(rng, struct iproc_rng200_dev, rng)

static void iproc_rng200_enable_set(void __iomem *rng_base, bool enable)
{
	u32 val;

	val = ioread32(rng_base + RNG_CTRL_OFFSET);
	val &= ~RNG_CTRL_RNG_RBGEN_MASK;

	if (enable)
		val |= RNG_CTRL_RNG_RBGEN_ENABLE;

	iowrite32(val, rng_base + RNG_CTRL_OFFSET);
}

static void iproc_rng200_restart(void __iomem *rng_base)
{
	uint32_t val;

	iproc_rng200_enable_set(rng_base, false);

	/* Clear all interrupt status */
	iowrite32(0xFFFFFFFFUL, rng_base + RNG_INT_STATUS_OFFSET);

	/* Reset RNG and RBG */
	val = ioread32(rng_base + RBG_SOFT_RESET_OFFSET);
	val |= RBG_SOFT_RESET;
	iowrite32(val, rng_base + RBG_SOFT_RESET_OFFSET);

	val = ioread32(rng_base + RNG_SOFT_RESET_OFFSET);
	val |= RNG_SOFT_RESET;
	iowrite32(val, rng_base + RNG_SOFT_RESET_OFFSET);

	val = ioread32(rng_base + RNG_SOFT_RESET_OFFSET);
	val &= ~RNG_SOFT_RESET;
	iowrite32(val, rng_base + RNG_SOFT_RESET_OFFSET);

	val = ioread32(rng_base + RBG_SOFT_RESET_OFFSET);
	val &= ~RBG_SOFT_RESET;
	iowrite32(val, rng_base + RBG_SOFT_RESET_OFFSET);

	iproc_rng200_enable_set(rng_base, true);
}

static int iproc_rng200_read(struct hwrng *rng, void *buf, size_t max,
			     bool wait)
{
	struct iproc_rng200_dev *priv = to_rng_priv(rng);
	uint32_t num_remaining = max;
	uint32_t status;

	#define MAX_RESETS_PER_READ	1
	uint32_t num_resets = 0;

	#define MAX_IDLE_TIME	(1 * HZ)
	unsigned long idle_endtime = jiffies + MAX_IDLE_TIME;

	while ((num_remaining > 0) && time_before(jiffies, idle_endtime)) {

		/* Is RNG sane? If not, reset it. */
		status = ioread32(priv->base + RNG_INT_STATUS_OFFSET);
		if ((status & (RNG_INT_STATUS_MASTER_FAIL_LOCKOUT_IRQ_MASK |
			RNG_INT_STATUS_NIST_FAIL_IRQ_MASK)) != 0) {

			if (num_resets >= MAX_RESETS_PER_READ)
				return max - num_remaining;

			iproc_rng200_restart(priv->base);
			num_resets++;
		}

		/* Are there any random numbers available? */
		if ((ioread32(priv->base + RNG_FIFO_COUNT_OFFSET) &
				RNG_FIFO_COUNT_RNG_FIFO_COUNT_MASK) > 0) {

			if (num_remaining >= sizeof(uint32_t)) {
				/* Buffer has room to store entire word */
				*(uint32_t *)buf = ioread32(priv->base +
							RNG_FIFO_DATA_OFFSET);
				buf += sizeof(uint32_t);
				num_remaining -= sizeof(uint32_t);
			} else {
				/* Buffer can only store partial word */
				uint32_t rnd_number = ioread32(priv->base +
							RNG_FIFO_DATA_OFFSET);
				memcpy(buf, &rnd_number, num_remaining);
				buf += num_remaining;
				num_remaining = 0;
			}

			/* Reset the IDLE timeout */
			idle_endtime = jiffies + MAX_IDLE_TIME;
		} else {
			if (!wait)
				/* Cannot wait, return immediately */
				return max - num_remaining;

			/* Can wait, give others chance to run */
			usleep_range(min(num_remaining * 10, 500U), 500);
		}
	}

	return max - num_remaining;
}

static int iproc_rng200_init(struct hwrng *rng)
{
	struct iproc_rng200_dev *priv = to_rng_priv(rng);

	iproc_rng200_enable_set(priv->base, true);

	return 0;
}

static void iproc_rng200_cleanup(struct hwrng *rng)
{
	struct iproc_rng200_dev *priv = to_rng_priv(rng);

	iproc_rng200_enable_set(priv->base, false);
}

static int iproc_rng200_probe(struct platform_device *pdev)
{
	struct iproc_rng200_dev *priv;
	struct device *dev = &pdev->dev;
	int ret;

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

	/* Map peripheral */
	priv->base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(priv->base)) {
		dev_err(dev, "failed to remap rng regs\n");
		return PTR_ERR(priv->base);
	}

	priv->rng.name = "iproc-rng200";
	priv->rng.read = iproc_rng200_read;
	priv->rng.init = iproc_rng200_init;
	priv->rng.cleanup = iproc_rng200_cleanup;

	/* Register driver */
	ret = devm_hwrng_register(dev, &priv->rng);
	if (ret) {
		dev_err(dev, "hwrng registration failed\n");
		return ret;
	}

	dev_info(dev, "hwrng registered\n");

	return 0;
}

static const struct of_device_id iproc_rng200_of_match[] = {
	{ .compatible = "brcm,bcm2711-rng200", },
	{ .compatible = "brcm,bcm7211-rng200", },
	{ .compatible = "brcm,bcm7278-rng200", },
	{ .compatible = "brcm,iproc-rng200", },
	{},
};
MODULE_DEVICE_TABLE(of, iproc_rng200_of_match);

static struct platform_driver iproc_rng200_driver = {
	.driver = {
		.name		= "iproc-rng200",
		.of_match_table = iproc_rng200_of_match,
	},
	.probe		= iproc_rng200_probe,
};
module_platform_driver(iproc_rng200_driver);

MODULE_AUTHOR("Broadcom");
MODULE_DESCRIPTION("iProc RNG200 Random Number Generator driver");
MODULE_LICENSE("GPL v2");
