From b22da3d8526a935aa31e086e63f60ff3246cb61c Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 07:24:11 +0000
Subject: [PATCH] add stmac read mac form eeprom

---
 kernel/drivers/char/hw_random/rockchip-rng.c |  157 +++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 118 insertions(+), 39 deletions(-)

diff --git a/kernel/drivers/char/hw_random/rockchip-rng.c b/kernel/drivers/char/hw_random/rockchip-rng.c
index 08ad081..f7a3a7f 100644
--- a/kernel/drivers/char/hw_random/rockchip-rng.c
+++ b/kernel/drivers/char/hw_random/rockchip-rng.c
@@ -87,6 +87,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 */
+
 struct rk_rng_soc_data {
 	u32 default_offset;
 
@@ -178,7 +199,7 @@
 		*(u32 *)(buf + i) = be32_to_cpu(rk_rng_readl(rng, offset + i));
 }
 
-static int rk_crypto_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+static int crypto_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait)
 {
 	int ret = 0;
 	u32 reg_ctrl = 0;
@@ -192,10 +213,12 @@
 
 	rk_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_CTRL);
 
-	ret = readl_poll_timeout(rk_rng->mem + CRYPTO_V1_CTRL, reg_ctrl,
-				 !(reg_ctrl & CRYPTO_V1_RNG_START),
-				 ROCKCHIP_POLL_PERIOD_US,
-				 ROCKCHIP_POLL_TIMEOUT_US);
+	ret = read_poll_timeout(rk_rng_readl, reg_ctrl,
+				!(reg_ctrl & CRYPTO_V1_RNG_START),
+				ROCKCHIP_POLL_PERIOD_US,
+				ROCKCHIP_POLL_TIMEOUT_US, false,
+				rk_rng, CRYPTO_V1_CTRL);
+
 	if (ret < 0)
 		goto out;
 
@@ -211,7 +234,7 @@
 	return ret;
 }
 
-static int rk_crypto_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+static int crypto_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait)
 {
 	int ret = 0;
 	u32 reg_ctrl = 0;
@@ -228,10 +251,11 @@
 	rk_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0),
 		      CRYPTO_V2_RNG_CTL);
 
-	ret = readl_poll_timeout(rk_rng->mem + CRYPTO_V2_RNG_CTL, reg_ctrl,
-				 !(reg_ctrl & CRYPTO_V2_RNG_START),
-				 ROCKCHIP_POLL_PERIOD_US,
-				 ROCKCHIP_POLL_TIMEOUT_US);
+	ret = read_poll_timeout(rk_rng_readl, reg_ctrl,
+				!(reg_ctrl & CRYPTO_V2_RNG_START),
+				ROCKCHIP_POLL_PERIOD_US,
+				ROCKCHIP_POLL_TIMEOUT_US, false,
+				rk_rng, CRYPTO_V2_RNG_CTL);
 	if (ret < 0)
 		goto out;
 
@@ -246,18 +270,12 @@
 	return ret;
 }
 
-static int rk_trng_v1_init(struct hwrng *rng)
+static int trng_v1_init(struct hwrng *rng)
 {
 	int ret;
 	uint32_t auto_reseed_cnt = 1000;
 	uint32_t reg_ctrl, status, version;
 	struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
-
-	ret = pm_runtime_get_sync(rk_rng->dev);
-	if (ret < 0) {
-		pm_runtime_put_noidle(rk_rng->dev);
-		return ret;
-	}
 
 	version = rk_rng_readl(rk_rng, TRNG_V1_VERSION);
 	if (version != TRNG_v1_VERSION_CODE) {
@@ -281,10 +299,11 @@
 		udelay(10);
 
 		/* wait for GENERATING and RESEEDING flag to clear */
-		readl_poll_timeout(rk_rng->mem + TRNG_V1_STAT, reg_ctrl,
-				   (reg_ctrl & mask) == TRNG_V1_STAT_SEEDED,
-				   ROCKCHIP_POLL_PERIOD_US,
-				   ROCKCHIP_POLL_TIMEOUT_US);
+		read_poll_timeout(rk_rng_readl, reg_ctrl,
+				  (reg_ctrl & mask) == TRNG_V1_STAT_SEEDED,
+				  ROCKCHIP_POLL_PERIOD_US,
+				  ROCKCHIP_POLL_TIMEOUT_US, false,
+				  rk_rng, TRNG_V1_STAT);
 	}
 
 	/* clear ISTAT flag because trng may auto reseeding when power on */
@@ -296,13 +315,11 @@
 
 	ret = 0;
 exit:
-	pm_runtime_mark_last_busy(rk_rng->dev);
-	pm_runtime_put_sync_autosuspend(rk_rng->dev);
 
 	return ret;
 }
 
-static int rk_trng_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+static int trng_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait)
 {
 	int ret = 0;
 	u32 reg_ctrl = 0;
@@ -324,10 +341,11 @@
 	reg_ctrl = rk_rng_readl(rk_rng, TRNG_V1_ISTAT);
 	if (!(reg_ctrl & TRNG_V1_ISTAT_RAND_RDY)) {
 		/* wait RAND_RDY triggered */
-		ret = readl_poll_timeout(rk_rng->mem + TRNG_V1_ISTAT, reg_ctrl,
-					 (reg_ctrl & TRNG_V1_ISTAT_RAND_RDY),
-					 ROCKCHIP_POLL_PERIOD_US,
-					 ROCKCHIP_POLL_TIMEOUT_US);
+		ret = read_poll_timeout(rk_rng_readl, reg_ctrl,
+					(reg_ctrl & TRNG_V1_ISTAT_RAND_RDY),
+					ROCKCHIP_POLL_PERIOD_US,
+					ROCKCHIP_POLL_TIMEOUT_US, false,
+					rk_rng, TRNG_V1_ISTAT);
 		if (ret < 0)
 			goto out;
 	}
@@ -345,37 +363,92 @@
 	return ret;
 }
 
-static const struct rk_rng_soc_data rk_crypto_v1_soc_data = {
+static int rkrng_init(struct hwrng *rng)
+{
+	struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
+	u32 reg = 0;
+
+	rk_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), RKRNG_CTRL);
+
+	reg = rk_rng_readl(rk_rng, RKRNG_STATE);
+	rk_rng_writel(rk_rng, reg, RKRNG_STATE);
+
+	return 0;
+}
+
+static int rkrng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
+{
+	struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
+	u32 reg_ctrl = 0;
+	int ret;
+
+	reg_ctrl = RKRNG_CTRL_SW_DRNG_REQ;
+
+	rk_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0), RKRNG_CTRL);
+
+	ret = readl_poll_timeout(rk_rng->mem + RKRNG_STATE, reg_ctrl,
+				 (reg_ctrl & RKRNG_STATE_SW_DRNG_ACK),
+				 ROCKCHIP_POLL_PERIOD_US,
+				 ROCKCHIP_POLL_TIMEOUT_US);
+
+	if (ret)
+		goto exit;
+
+	rk_rng_writel(rk_rng, reg_ctrl, RKRNG_STATE);
+
+	ret = min_t(size_t, max, RK_MAX_RNG_BYTE);
+
+	rk_rng_read_regs(rk_rng, RKRNG_DRNG_DATA_0, buf, ret);
+
+exit:
+	/* close TRNG */
+	rk_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), RKRNG_CTRL);
+
+	return ret;
+}
+
+static const struct rk_rng_soc_data crypto_v1_soc_data = {
 	.default_offset = 0,
 
-	.rk_rng_read = rk_crypto_v1_read,
+	.rk_rng_read = crypto_v1_read,
 };
 
-static const struct rk_rng_soc_data rk_crypto_v2_soc_data = {
+static const struct rk_rng_soc_data crypto_v2_soc_data = {
 	.default_offset = CRYPTO_V2_RNG_DEFAULT_OFFSET,
 
-	.rk_rng_read = rk_crypto_v2_read,
+	.rk_rng_read = crypto_v2_read,
 };
 
-static const struct rk_rng_soc_data rk_trng_v1_soc_data = {
+static const struct rk_rng_soc_data trng_v1_soc_data = {
 	.default_offset = 0,
 
-	.rk_rng_init = rk_trng_v1_init,
-	.rk_rng_read = rk_trng_v1_read,
+	.rk_rng_init = trng_v1_init,
+	.rk_rng_read = trng_v1_read,
+};
+
+static const struct rk_rng_soc_data rkrng_soc_data = {
+	.default_offset = 0,
+
+	.rk_rng_init = rkrng_init,
+	.rk_rng_read = rkrng_read,
 };
 
 static const struct of_device_id rk_rng_dt_match[] = {
 	{
 		.compatible = "rockchip,cryptov1-rng",
-		.data = (void *)&rk_crypto_v1_soc_data,
+		.data = (void *)&crypto_v1_soc_data,
 	},
 	{
 		.compatible = "rockchip,cryptov2-rng",
-		.data = (void *)&rk_crypto_v2_soc_data,
+		.data = (void *)&crypto_v2_soc_data,
 	},
 	{
 		.compatible = "rockchip,trngv1",
-		.data = (void *)&rk_trng_v1_soc_data,
+		.data = (void *)&trng_v1_soc_data,
+	},
+		{
+		.compatible = "rockchip,rkrng",
+		.data = (void *)&rkrng_soc_data,
 	},
 	{ },
 };
@@ -445,9 +518,15 @@
 	}
 
 	/* for some platform need hardware operation when probe */
-	if (rk_rng->soc_data->rk_rng_init)
+	if (rk_rng->soc_data->rk_rng_init) {
+		pm_runtime_get_sync(rk_rng->dev);
+
 		ret = rk_rng->soc_data->rk_rng_init(&rk_rng->rng);
 
+		pm_runtime_mark_last_busy(rk_rng->dev);
+		pm_runtime_put_sync_autosuspend(rk_rng->dev);
+	}
+
 	return ret;
 }
 

--
Gitblit v1.6.2