From 072de836f53be56a70cecf70b43ae43b7ce17376 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 11 Dec 2023 10:08:36 +0000
Subject: [PATCH] mk-rootfs.sh
---
u-boot/drivers/rng/rockchip_rng.c | 143 ++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 126 insertions(+), 17 deletions(-)
diff --git a/u-boot/drivers/rng/rockchip_rng.c b/u-boot/drivers/rng/rockchip_rng.c
index 7287afd..d85cf65 100644
--- a/u-boot/drivers/rng/rockchip_rng.c
+++ b/u-boot/drivers/rng/rockchip_rng.c
@@ -2,13 +2,14 @@
/*
* Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd
*/
+#include <common.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <rng.h>
#include <asm/arch-rockchip/hardware.h>
#include <asm/io.h>
-#include <common.h>
-#include <dm.h>
#include <linux/iopoll.h>
#include <linux/string.h>
-#include <rng.h>
#define RK_HW_RNG_MAX 32
@@ -70,6 +71,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))
@@ -83,7 +105,36 @@
struct rk_rng_platdata {
fdt_addr_t base;
struct rk_rng_soc_data *soc_data;
+ struct clk hclk;
};
+
+static int rk_rng_do_enable_clk(struct udevice *dev, int enable)
+{
+ struct rk_rng_platdata *pdata = dev_get_priv(dev);
+ int ret;
+
+ if (!pdata->hclk.dev)
+ return 0;
+
+ ret = enable ? clk_enable(&pdata->hclk) : clk_disable(&pdata->hclk);
+ if (ret == -ENOSYS || !ret)
+ return 0;
+
+ printf("rk rng: failed to %s clk, ret=%d\n",
+ enable ? "enable" : "disable", ret);
+
+ return ret;
+}
+
+static int rk_rng_enable_clk(struct udevice *dev)
+{
+ return rk_rng_do_enable_clk(dev, 1);
+}
+
+static int rk_rng_disable_clk(struct udevice *dev)
+{
+ return rk_rng_do_enable_clk(dev, 0);
+}
static int rk_rng_read_regs(fdt_addr_t addr, void *buf, size_t size)
{
@@ -106,7 +157,7 @@
return 0;
}
-static int rk_cryptov1_rng_read(struct udevice *dev, void *data, size_t len)
+static int cryptov1_rng_read(struct udevice *dev, void *data, size_t len)
{
struct rk_rng_platdata *pdata = dev_get_priv(dev);
u32 reg = 0;
@@ -137,7 +188,7 @@
return 0;
}
-static int rk_cryptov2_rng_read(struct udevice *dev, void *data, size_t len)
+static int cryptov2_rng_read(struct udevice *dev, void *data, size_t len)
{
struct rk_rng_platdata *pdata = dev_get_priv(dev);
u32 reg = 0;
@@ -171,7 +222,7 @@
return retval;
}
-static int rk_trngv1_init(struct udevice *dev)
+static int trngv1_init(struct udevice *dev)
{
u32 status, version;
u32 auto_reseed_cnt = 1000;
@@ -198,7 +249,7 @@
return 0;
}
-static int rk_trngv1_rng_read(struct udevice *dev, void *data, size_t len)
+static int trngv1_rng_read(struct udevice *dev, void *data, size_t len)
{
struct rk_rng_platdata *pdata = dev_get_priv(dev);
u32 reg = 0;
@@ -224,6 +275,53 @@
exit:
/* close TRNG */
trng_write(pdata, TRNG_V1_CTRL, TRNG_V1_CTRL_NOP);
+
+ return retval;
+}
+
+static int rkrng_init(struct udevice *dev)
+{
+ struct rk_rng_platdata *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_platdata *pdata = dev_get_priv(dev);
+ u32 reg = 0;
+ int retval;
+
+ if (len > RK_HW_RNG_MAX)
+ return -EINVAL;
+
+ rk_rng_enable_clk(dev);
+
+ 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);
+
+ rk_rng_disable_clk(dev);
return retval;
}
@@ -266,6 +364,8 @@
if (!pdata->base)
return -ENOMEM;
+ clk_get_by_index(dev, 0, &pdata->hclk);
+
return 0;
}
@@ -282,17 +382,22 @@
return ret;
}
-static const struct rk_rng_soc_data rk_cryptov1_soc_data = {
- .rk_rng_read = rk_cryptov1_rng_read,
+static const struct rk_rng_soc_data cryptov1_soc_data = {
+ .rk_rng_read = cryptov1_rng_read,
};
-static const struct rk_rng_soc_data rk_cryptov2_soc_data = {
- .rk_rng_read = rk_cryptov2_rng_read,
+static const struct rk_rng_soc_data cryptov2_soc_data = {
+ .rk_rng_read = cryptov2_rng_read,
};
-static const struct rk_rng_soc_data rk_trngv1_soc_data = {
- .rk_rng_init = rk_trngv1_init,
- .rk_rng_read = rk_trngv1_rng_read,
+static const struct rk_rng_soc_data trngv1_soc_data = {
+ .rk_rng_init = trngv1_init,
+ .rk_rng_read = 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 = {
@@ -302,15 +407,19 @@
static const struct udevice_id rockchip_rng_match[] = {
{
.compatible = "rockchip,cryptov1-rng",
- .data = (ulong)&rk_cryptov1_soc_data,
+ .data = (ulong)&cryptov1_soc_data,
},
{
.compatible = "rockchip,cryptov2-rng",
- .data = (ulong)&rk_cryptov2_soc_data,
+ .data = (ulong)&cryptov2_soc_data,
},
{
.compatible = "rockchip,trngv1",
- .data = (ulong)&rk_trngv1_soc_data,
+ .data = (ulong)&trngv1_soc_data,
+ },
+ {
+ .compatible = "rockchip,rkrng",
+ .data = (ulong)&rkrng_soc_data,
},
{},
};
--
Gitblit v1.6.2