All of lore.kernel.org
 help / color / mirror / Atom feed
From: Robert Marko <robert.marko@sartura.hr>
To: u-boot@lists.denx.de
Subject: [PATCH 5/6] rng: Add Qualcomm MSM PRNG driver
Date: Thu,  8 Oct 2020 22:05:13 +0200	[thread overview]
Message-ID: <20201008200514.2256778-6-robert.marko@sartura.hr> (raw)
In-Reply-To: <20201008200514.2256778-1-robert.marko@sartura.hr>

Add support for the hardware pseudo random number generator found in Qualcomm SoC-s.

Signed-off-by: Robert Marko <robert.marko@sartura.hr>
Cc: Luka Perkov <luka.perkov@sartura.hr>
---
 MAINTAINERS           |   1 +
 drivers/rng/Kconfig   |   7 +++
 drivers/rng/Makefile  |   1 +
 drivers/rng/msm_rng.c | 143 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 152 insertions(+)
 create mode 100644 drivers/rng/msm_rng.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 5f1a815c88..8a1bc97443 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -243,6 +243,7 @@ F:	drivers/reset/reset-ipq4019.c
 F:	drivers/phy/phy-qcom-ipq4019-usb.c
 F:	drivers/spi/spi-qup.c
 F:	drivers/net/mdio-ipq4019.c
+F:	drivers/rng/msm_rng.c
 
 ARM MARVELL KIRKWOOD ARMADA-XP ARMADA-38X ARMADA-37XX ARMADA-7K/8K
 M:	Stefan Roese <sr@denx.de>
diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig
index e4b22d79eb..11001c8ae7 100644
--- a/drivers/rng/Kconfig
+++ b/drivers/rng/Kconfig
@@ -24,6 +24,13 @@ config RNG_SANDBOX
 	  Enable random number generator for sandbox. This is an
 	  emulation of a rng device.
 
+config RNG_MSM
+	bool "Qualcomm SoCs Random Number Generator support"
+	depends on DM_RNG
+	help
+	  This driver provides support for the Random Number
+	  Generator hardware found on Qualcomm SoCs.
+
 config RNG_STM32MP1
 	bool "Enable random number generator for STM32MP1"
 	depends on ARCH_STM32MP
diff --git a/drivers/rng/Makefile b/drivers/rng/Makefile
index 44a0003917..8953406882 100644
--- a/drivers/rng/Makefile
+++ b/drivers/rng/Makefile
@@ -6,5 +6,6 @@
 obj-$(CONFIG_DM_RNG) += rng-uclass.o
 obj-$(CONFIG_RNG_MESON) += meson-rng.o
 obj-$(CONFIG_RNG_SANDBOX) += sandbox_rng.o
+obj-$(CONFIG_RNG_MSM) += msm_rng.o
 obj-$(CONFIG_RNG_STM32MP1) += stm32mp1_rng.o
 obj-$(CONFIG_RNG_ROCKCHIP) += rockchip_rng.o
diff --git a/drivers/rng/msm_rng.c b/drivers/rng/msm_rng.c
new file mode 100644
index 0000000000..d51119303a
--- /dev/null
+++ b/drivers/rng/msm_rng.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * PRNG driver for Qualcomm IPQ40xx
+ *
+ * Copyright (c) 2020 Sartura Ltd.
+ *
+ * Author: Robert Marko <robert.marko@sartura.hr>
+ *
+ * Based on Linux driver
+ */
+
+#include <asm/io.h>
+#include <clk.h>
+#include <common.h>
+#include <dm.h>
+#include <linux/bitops.h>
+#include <rng.h>
+
+/* Device specific register offsets */
+#define PRNG_DATA_OUT		0x0000
+#define PRNG_STATUS			0x0004
+#define PRNG_LFSR_CFG		0x0100
+#define PRNG_CONFIG			0x0104
+
+/* Device specific register masks and config values */
+#define PRNG_LFSR_CFG_MASK		0x0000ffff
+#define PRNG_LFSR_CFG_CLOCKS	0x0000dddd
+#define PRNG_CONFIG_HW_ENABLE	BIT(1)
+#define PRNG_STATUS_DATA_AVAIL	BIT(0)
+
+#define MAX_HW_FIFO_DEPTH		16
+#define MAX_HW_FIFO_SIZE		(MAX_HW_FIFO_DEPTH * 4)
+#define WORD_SZ					4
+
+struct msm_rng_priv {
+	phys_addr_t base;
+	struct clk clk;
+};
+
+static int msm_rng_read(struct udevice *dev, void *data, size_t len)
+{
+	struct msm_rng_priv *priv = dev_get_priv(dev);
+	size_t currsize = 0;
+	u32 *retdata = data;
+	size_t maxsize;
+	u32 val;
+
+	/* calculate max size bytes to transfer back to caller */
+	maxsize = min_t(size_t, MAX_HW_FIFO_SIZE, len);
+
+	/* read random data from hardware */
+	do {
+		val = readl_relaxed(priv->base + PRNG_STATUS);
+		if (!(val & PRNG_STATUS_DATA_AVAIL))
+			break;
+
+		val = readl_relaxed(priv->base + PRNG_DATA_OUT);
+		if (!val)
+			break;
+
+		*retdata++ = val;
+		currsize += WORD_SZ;
+
+		/* make sure we stay on 32bit boundary */
+		if ((maxsize - currsize) < WORD_SZ)
+			break;
+	} while (currsize < maxsize);
+
+	return 0;
+}
+
+static int msm_rng_enable(struct msm_rng_priv *priv, int enable)
+{
+	u32 val;
+
+	if (enable) {
+		/* Enable PRNG only if it is not already enabled */
+		val = readl_relaxed(priv->base + PRNG_CONFIG);
+		if (val & PRNG_CONFIG_HW_ENABLE) {
+			val = readl_relaxed(priv->base + PRNG_LFSR_CFG);
+			val &= ~PRNG_LFSR_CFG_MASK;
+			val |= PRNG_LFSR_CFG_CLOCKS;
+			writel(val, priv->base + PRNG_LFSR_CFG);
+
+			val = readl_relaxed(priv->base + PRNG_CONFIG);
+			val |= PRNG_CONFIG_HW_ENABLE;
+			writel(val, priv->base + PRNG_CONFIG);
+		}
+	} else {
+		val = readl_relaxed(priv->base + PRNG_CONFIG);
+		val &= ~PRNG_CONFIG_HW_ENABLE;
+		writel(val, priv->base + PRNG_CONFIG);
+	}
+
+	return 0;
+}
+
+static int msm_rng_probe(struct udevice *dev)
+{
+	struct msm_rng_priv *priv = dev_get_priv(dev);
+
+	int ret;
+
+	priv->base = dev_read_addr(dev);
+	if (priv->base == FDT_ADDR_T_NONE)
+		return -EINVAL;
+
+	ret = clk_get_by_index(dev, 0, &priv->clk);
+	if (ret)
+		return ret;
+
+	ret = clk_enable(&priv->clk);
+	if (ret < 0)
+		return ret;
+
+	return msm_rng_enable(priv, 1);
+}
+
+static int msm_rng_remove(struct udevice *dev)
+{
+	struct msm_rng_priv *priv = dev_get_priv(dev);
+
+	return msm_rng_enable(priv, 0);
+}
+
+static const struct dm_rng_ops msm_rng_ops = {
+	.read = msm_rng_read,
+};
+
+static const struct udevice_id msm_rng_match[] = {
+	{ .compatible = "qcom,prng", },
+	{},
+};
+
+U_BOOT_DRIVER(msm_rng) = {
+	.name = "msm-rng",
+	.id = UCLASS_RNG,
+	.of_match = msm_rng_match,
+	.ops = &msm_rng_ops,
+	.probe = msm_rng_probe,
+	.remove = msm_rng_remove,
+	.priv_auto_alloc_size = sizeof(struct msm_rng_priv),
+};
-- 
2.28.0

  parent reply	other threads:[~2020-10-08 20:05 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-08 20:05 [PATCH 0/6] IPQ40xx: Improve support Robert Marko
2020-10-08 20:05 ` [PATCH 1/6] spi: Add Qualcomm QUP SPI controller driver Robert Marko
2020-10-23  0:28   ` Tom Rini
2020-10-08 20:05 ` [PATCH 2/6] IPQ40xx: Add SPI support Robert Marko
2020-10-23  0:28   ` Tom Rini
2020-10-08 20:05 ` [PATCH 3/6] net: Add IPQ40xx MDIO driver Robert Marko
2020-10-23  0:28   ` Tom Rini
2020-10-08 20:05 ` [PATCH 4/6] IPQ40xx: Add support for MDIO Robert Marko
2020-10-23  0:29   ` Tom Rini
2020-10-08 20:05 ` Robert Marko [this message]
2020-10-23  0:29   ` [PATCH 5/6] rng: Add Qualcomm MSM PRNG driver Tom Rini
2020-12-14 17:22     ` Heinrich Schuchardt
2020-12-14 17:32       ` Robert Marko
2020-10-08 20:05 ` [PATCH 6/6] IPQ40xx: Add PRNG support Robert Marko
2020-10-23  0:29   ` Tom Rini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201008200514.2256778-6-robert.marko@sartura.hr \
    --to=robert.marko@sartura.hr \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.