mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 04:13:31 +00:00
120 lines
3.1 KiB
Diff
120 lines
3.1 KiB
Diff
From 4e19cd0a572b6a27b82fef84c30fca69914b7798 Mon Sep 17 00:00:00 2001
|
|
From: Lin Jinhan <troy.lin@rock-chips.com>
|
|
Date: Thu, 23 Jan 2025 22:48:21 +0000
|
|
Subject: [PATCH 9/9] rng: rockchip: Add support for rkrng variant
|
|
|
|
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@rock-chips.com>
|
|
Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
|
|
---
|
|
drivers/rng/rockchip_rng.c | 73 ++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 73 insertions(+)
|
|
|
|
--- 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_t
|
|
.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_
|
|
.compatible = "rockchip,trngv1",
|
|
.data = (ulong)&rk_trngv1_soc_data,
|
|
},
|
|
+ {
|
|
+ .compatible = "rockchip,rkrng",
|
|
+ .data = (ulong)&rkrng_soc_data,
|
|
+ },
|
|
{},
|
|
};
|
|
|