[PATCH 09/13] rng: rockchip: Add support for rkrng variant

Jonas Karlman jonas at kwiboo.se
Thu Jan 23 23:48:21 CET 2025


From: Lin Jinhan <troy.lin at rock-chips.com>

Add support for rkrng variant, used by e.g. RK3528 and RK3576.

Imported from vendor U-Boot linux-6.1-stan-rkr5 tag with minor
adjustments for mainline.

Signed-off-by: Lin Jinhan <troy.lin at rock-chips.com>
Signed-off-by: Jonas Karlman <jonas at kwiboo.se>
---
 drivers/rng/rockchip_rng.c | 73 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/drivers/rng/rockchip_rng.c b/drivers/rng/rockchip_rng.c
index 2426648fbd57..0e3b95b5540e 100644
--- a/drivers/rng/rockchip_rng.c
+++ b/drivers/rng/rockchip_rng.c
@@ -70,6 +70,27 @@
 #define TRNG_v1_VERSION_CODE			0x46BC
 /* end of TRNG V1 register define */
 
+/* start of RKRNG register define */
+#define RKRNG_CTRL				0x0010
+#define RKRNG_CTRL_INST_REQ			BIT(0)
+#define RKRNG_CTRL_RESEED_REQ			BIT(1)
+#define RKRNG_CTRL_TEST_REQ			BIT(2)
+#define RKRNG_CTRL_SW_DRNG_REQ			BIT(3)
+#define RKRNG_CTRL_SW_TRNG_REQ			BIT(4)
+
+#define RKRNG_STATE				0x0014
+#define RKRNG_STATE_INST_ACK			BIT(0)
+#define RKRNG_STATE_RESEED_ACK			BIT(1)
+#define RKRNG_STATE_TEST_ACK			BIT(2)
+#define RKRNG_STATE_SW_DRNG_ACK			BIT(3)
+#define RKRNG_STATE_SW_TRNG_ACK			BIT(4)
+
+/* DRNG_DATA_0 ~ DNG_DATA_7 */
+#define RKRNG_DRNG_DATA_0			0x0070
+#define RKRNG_DRNG_DATA_7			0x008C
+
+/* end of RKRNG register define */
+
 #define RK_RNG_TIME_OUT	50000  /* max 50ms */
 
 #define trng_write(pdata, pos, val)	writel(val, (pdata)->base + (pos))
@@ -228,6 +249,49 @@ exit:
 	return retval;
 }
 
+static int rkrng_init(struct udevice *dev)
+{
+	struct rk_rng_plat *pdata = dev_get_priv(dev);
+	u32 reg = 0;
+
+	rk_clrreg(pdata->base + RKRNG_CTRL, 0xffff);
+
+	reg = trng_read(pdata, RKRNG_STATE);
+	trng_write(pdata, RKRNG_STATE, reg);
+
+	return 0;
+}
+
+static int rkrng_rng_read(struct udevice *dev, void *data, size_t len)
+{
+	struct rk_rng_plat *pdata = dev_get_priv(dev);
+	u32 reg = 0;
+	int retval;
+
+	if (len > RK_HW_RNG_MAX)
+		return -EINVAL;
+
+	reg = RKRNG_CTRL_SW_DRNG_REQ;
+
+	rk_clrsetreg(pdata->base + RKRNG_CTRL, 0xffff, reg);
+
+	retval = readl_poll_timeout(pdata->base + RKRNG_STATE, reg,
+				    (reg & RKRNG_STATE_SW_DRNG_ACK),
+				    RK_RNG_TIME_OUT);
+	if (retval)
+		goto exit;
+
+	trng_write(pdata, RKRNG_STATE, reg);
+
+	rk_rng_read_regs(pdata->base + RKRNG_DRNG_DATA_0, data, len);
+
+exit:
+	/* close TRNG */
+	rk_clrreg(pdata->base + RKRNG_CTRL, 0xffff);
+
+	return retval;
+}
+
 static int rockchip_rng_read(struct udevice *dev, void *data, size_t len)
 {
 	unsigned char *buf = data;
@@ -295,6 +359,11 @@ static const struct rk_rng_soc_data rk_trngv1_soc_data = {
 	.rk_rng_read = rk_trngv1_rng_read,
 };
 
+static const struct rk_rng_soc_data rkrng_soc_data = {
+	.rk_rng_init = rkrng_init,
+	.rk_rng_read = rkrng_rng_read,
+};
+
 static const struct dm_rng_ops rockchip_rng_ops = {
 	.read = rockchip_rng_read,
 };
@@ -320,6 +389,10 @@ static const struct udevice_id rockchip_rng_match[] = {
 		.compatible = "rockchip,trngv1",
 		.data = (ulong)&rk_trngv1_soc_data,
 	},
+	{
+		.compatible = "rockchip,rkrng",
+		.data = (ulong)&rkrng_soc_data,
+	},
 	{},
 };
 
-- 
2.48.1



More information about the U-Boot mailing list