public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [PATCH v3 0/7] rng: stm32: support STM32MP13x platforms
@ 2023-09-19 15:27 Gatien Chevallier
  2023-09-19 15:27 ` [PATCH v3 1/7] rng: stm32: rename STM32 RNG driver Gatien Chevallier
                   ` (6 more replies)
  0 siblings, 7 replies; 22+ messages in thread
From: Gatien Chevallier @ 2023-09-19 15:27 UTC (permalink / raw)
  To: u-boot
  Cc: Patrick Delaunay, Patrice Chotard, Sughosh Ganu,
	Heinrich Schuchardt, uboot-stm32, Gatien Chevallier

This is the cover letter for patchset [1].
First, do not restrain the STM32 RNG driver to the MPU series.

The STM32MP13x platforms have a RNG hardware block that supports
customization, a conditional reset sequences that allows to
recover from certain situations and a configuration locking
mechanism.

This series adds support for the mentionned features. Note that
the hardware RNG can and should be managed in the secure world
for this platform, hence the rng not being default enabled on
the STM32MP135F-DK board.

[1] http://patchwork.ozlabs.org/project/uboot/list/?series=372119&state=*

Changes in V2:
	- Added this cover letter
	- Added ARCH_STM32 as a dependency for RNG_STM32
	- Added review tags

Changes in V3:
	- Added Patrick's tag to [PATCH 1/7]

Gatien Chevallier (7):
  rng: stm32: rename STM32 RNG driver
  configs: default activate CONFIG_RNG_STM32 for STM32MP13x platforms
  rng: stm32: Implement configurable RNG clock error detection
  rng: stm32: add RNG clock frequency restraint
  rng: stm32: add error concealment sequence
  rng: stm32: Implement custom RNG configuration support
  ARM: dts: stm32: add RNG node for STM32MP13x platforms

 MAINTAINERS                         |   2 +-
 arch/arm/dts/stm32mp131.dtsi        |   8 +
 configs/stm32mp13_defconfig         |   1 +
 configs/stm32mp15_basic_defconfig   |   2 +-
 configs/stm32mp15_defconfig         |   2 +-
 configs/stm32mp15_trusted_defconfig |   2 +-
 drivers/rng/Kconfig                 |   8 +-
 drivers/rng/Makefile                |   2 +-
 drivers/rng/stm32_rng.c             | 408 ++++++++++++++++++++++++++++
 drivers/rng/stm32mp1_rng.c          | 198 --------------
 10 files changed, 426 insertions(+), 207 deletions(-)
 create mode 100644 drivers/rng/stm32_rng.c
 delete mode 100644 drivers/rng/stm32mp1_rng.c

-- 
2.25.1


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH v3 1/7] rng: stm32: rename STM32 RNG driver
  2023-09-19 15:27 [PATCH v3 0/7] rng: stm32: support STM32MP13x platforms Gatien Chevallier
@ 2023-09-19 15:27 ` Gatien Chevallier
  2023-09-27  6:52   ` Patrice CHOTARD
  2023-09-19 15:27 ` [PATCH v3 2/7] configs: default activate CONFIG_RNG_STM32 for STM32MP13x platforms Gatien Chevallier
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 22+ messages in thread
From: Gatien Chevallier @ 2023-09-19 15:27 UTC (permalink / raw)
  To: u-boot
  Cc: Patrick Delaunay, Patrice Chotard, Sughosh Ganu,
	Heinrich Schuchardt, uboot-stm32, Gatien Chevallier,
	Grzegorz Szymaszek

Rename the RNG driver as it is usable by other STM32 platforms
than the STM32MP1x ones. Rename CONFIG_RNG_STM32MP1 to
CONFIG_RNG_STM32

Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
Reviewed-by: Grzegorz Szymaszek <gszymaszek@short.pl>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---

Changes in V2:
	- Added ARCH_STM32 in the "depends on" section of the
	  RNG_STM32 configuration field.
	- Added Grzegorz's tag and discarded Patrick's and
	  Heinrich's as there's a modification

Changes in V2:
	- Added Patrick's tag. Discarded Heinrich's as patch's
	  content has changed.
	 
 MAINTAINERS                                 | 2 +-
 configs/stm32mp15_basic_defconfig           | 2 +-
 configs/stm32mp15_defconfig                 | 2 +-
 configs/stm32mp15_trusted_defconfig         | 2 +-
 drivers/rng/Kconfig                         | 8 ++++----
 drivers/rng/Makefile                        | 2 +-
 drivers/rng/{stm32mp1_rng.c => stm32_rng.c} | 0
 7 files changed, 9 insertions(+), 9 deletions(-)
 rename drivers/rng/{stm32mp1_rng.c => stm32_rng.c} (100%)

diff --git a/MAINTAINERS b/MAINTAINERS
index 0a10a436bc..a3bffa63d5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -621,7 +621,7 @@ F:	drivers/ram/stm32mp1/
 F:	drivers/remoteproc/stm32_copro.c
 F:	drivers/reset/stm32-reset.c
 F:	drivers/rng/optee_rng.c
-F:	drivers/rng/stm32mp1_rng.c
+F:	drivers/rng/stm32_rng.c
 F:	drivers/rtc/stm32_rtc.c
 F:	drivers/serial/serial_stm32.*
 F:	drivers/spi/stm32_qspi.c
diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig
index 9ea5aaa714..29b869cf34 100644
--- a/configs/stm32mp15_basic_defconfig
+++ b/configs/stm32mp15_basic_defconfig
@@ -150,7 +150,7 @@ CONFIG_DM_REGULATOR_STM32_VREFBUF=y
 CONFIG_DM_REGULATOR_STPMIC1=y
 CONFIG_REMOTEPROC_STM32_COPRO=y
 CONFIG_DM_RNG=y
-CONFIG_RNG_STM32MP1=y
+CONFIG_RNG_STM32=y
 CONFIG_DM_RTC=y
 CONFIG_RTC_STM32=y
 CONFIG_SERIAL_RX_BUFFER=y
diff --git a/configs/stm32mp15_defconfig b/configs/stm32mp15_defconfig
index 4d0a81f8a8..b061a83f9d 100644
--- a/configs/stm32mp15_defconfig
+++ b/configs/stm32mp15_defconfig
@@ -123,7 +123,7 @@ CONFIG_DM_REGULATOR_SCMI=y
 CONFIG_REMOTEPROC_STM32_COPRO=y
 CONFIG_RESET_SCMI=y
 CONFIG_DM_RNG=y
-CONFIG_RNG_STM32MP1=y
+CONFIG_RNG_STM32=y
 CONFIG_DM_RTC=y
 CONFIG_RTC_STM32=y
 CONFIG_SERIAL_RX_BUFFER=y
diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig
index 0a7d862485..b51eefe652 100644
--- a/configs/stm32mp15_trusted_defconfig
+++ b/configs/stm32mp15_trusted_defconfig
@@ -123,7 +123,7 @@ CONFIG_DM_REGULATOR_STPMIC1=y
 CONFIG_REMOTEPROC_STM32_COPRO=y
 CONFIG_RESET_SCMI=y
 CONFIG_DM_RNG=y
-CONFIG_RNG_STM32MP1=y
+CONFIG_RNG_STM32=y
 CONFIG_DM_RTC=y
 CONFIG_RTC_STM32=y
 CONFIG_SERIAL_RX_BUFFER=y
diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig
index 5deb5db5b7..24666bff98 100644
--- a/drivers/rng/Kconfig
+++ b/drivers/rng/Kconfig
@@ -48,11 +48,11 @@ config RNG_OPTEE
 	  accessible to normal world but reserved and used by the OP-TEE
 	  to avoid the weakness of a software PRNG.
 
-config RNG_STM32MP1
-	bool "Enable random number generator for STM32MP1"
-	depends on ARCH_STM32MP
+config RNG_STM32
+	bool "Enable random number generator for STM32"
+	depends on ARCH_STM32 || ARCH_STM32MP
 	help
-	  Enable STM32MP1 rng driver.
+	  Enable STM32 rng driver.
 
 config RNG_ROCKCHIP
 	bool "Enable random number generator for rockchip crypto rng"
diff --git a/drivers/rng/Makefile b/drivers/rng/Makefile
index 78f61051ac..192f911e15 100644
--- a/drivers/rng/Makefile
+++ b/drivers/rng/Makefile
@@ -9,7 +9,7 @@ obj-$(CONFIG_RNG_SANDBOX) += sandbox_rng.o
 obj-$(CONFIG_RNG_MSM) += msm_rng.o
 obj-$(CONFIG_RNG_NPCM) += npcm_rng.o
 obj-$(CONFIG_RNG_OPTEE) += optee_rng.o
-obj-$(CONFIG_RNG_STM32MP1) += stm32mp1_rng.o
+obj-$(CONFIG_RNG_STM32) += stm32_rng.o
 obj-$(CONFIG_RNG_ROCKCHIP) += rockchip_rng.o
 obj-$(CONFIG_RNG_IPROC200) += iproc_rng200.o
 obj-$(CONFIG_RNG_SMCCC_TRNG) += smccc_trng.o
diff --git a/drivers/rng/stm32mp1_rng.c b/drivers/rng/stm32_rng.c
similarity index 100%
rename from drivers/rng/stm32mp1_rng.c
rename to drivers/rng/stm32_rng.c
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 2/7] configs: default activate CONFIG_RNG_STM32 for STM32MP13x platforms
  2023-09-19 15:27 [PATCH v3 0/7] rng: stm32: support STM32MP13x platforms Gatien Chevallier
  2023-09-19 15:27 ` [PATCH v3 1/7] rng: stm32: rename STM32 RNG driver Gatien Chevallier
@ 2023-09-19 15:27 ` Gatien Chevallier
  2023-09-27  6:53   ` Patrice CHOTARD
  2023-09-19 15:27 ` [PATCH v3 3/7] rng: stm32: Implement configurable RNG clock error detection Gatien Chevallier
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 22+ messages in thread
From: Gatien Chevallier @ 2023-09-19 15:27 UTC (permalink / raw)
  To: u-boot
  Cc: Patrick Delaunay, Patrice Chotard, Sughosh Ganu,
	Heinrich Schuchardt, uboot-stm32, Gatien Chevallier

Default embed this configuration. If OP-TEE PTA RNG is exposed, it means
that the RNG is managed by the secure world. Therefore, the RNG node
should be disabled in the device tree as an access would be denied
by the hardware firewall.

Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---
Changes in V2:
	- Added Patrick's tag

 configs/stm32mp13_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/stm32mp13_defconfig b/configs/stm32mp13_defconfig
index 82b62744f6..4a899c85de 100644
--- a/configs/stm32mp13_defconfig
+++ b/configs/stm32mp13_defconfig
@@ -65,6 +65,7 @@ CONFIG_DM_REGULATOR_GPIO=y
 CONFIG_DM_REGULATOR_SCMI=y
 CONFIG_RESET_SCMI=y
 CONFIG_DM_RNG=y
+CONFIG_RNG_STM32=y
 CONFIG_DM_RTC=y
 CONFIG_RTC_STM32=y
 CONFIG_SERIAL_RX_BUFFER=y
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 3/7] rng: stm32: Implement configurable RNG clock error detection
  2023-09-19 15:27 [PATCH v3 0/7] rng: stm32: support STM32MP13x platforms Gatien Chevallier
  2023-09-19 15:27 ` [PATCH v3 1/7] rng: stm32: rename STM32 RNG driver Gatien Chevallier
  2023-09-19 15:27 ` [PATCH v3 2/7] configs: default activate CONFIG_RNG_STM32 for STM32MP13x platforms Gatien Chevallier
@ 2023-09-19 15:27 ` Gatien Chevallier
  2023-09-27  6:56   ` Patrice CHOTARD
  2023-09-19 15:27 ` [PATCH v3 4/7] rng: stm32: add RNG clock frequency restraint Gatien Chevallier
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 22+ messages in thread
From: Gatien Chevallier @ 2023-09-19 15:27 UTC (permalink / raw)
  To: u-boot
  Cc: Patrick Delaunay, Patrice Chotard, Sughosh Ganu,
	Heinrich Schuchardt, uboot-stm32, Gatien Chevallier

RNG clock error detection is now enabled if the "clock-error-detect"
property is set in the device tree.

Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---
Changes in V2:
	- Added Patrick's tag

 drivers/rng/stm32_rng.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/rng/stm32_rng.c b/drivers/rng/stm32_rng.c
index 89da78c6c8..ada5d92214 100644
--- a/drivers/rng/stm32_rng.c
+++ b/drivers/rng/stm32_rng.c
@@ -40,6 +40,7 @@ struct stm32_rng_plat {
 	struct clk clk;
 	struct reset_ctl rst;
 	const struct stm32_rng_data *data;
+	bool ced;
 };
 
 static int stm32_rng_read(struct udevice *dev, void *data, size_t len)
@@ -97,25 +98,34 @@ static int stm32_rng_init(struct stm32_rng_plat *pdata)
 
 	cr = readl(pdata->base + RNG_CR);
 
-	/* Disable CED */
-	cr |= RNG_CR_CED;
 	if (pdata->data->has_cond_reset) {
 		cr |= RNG_CR_CONDRST;
+		if (pdata->ced)
+			cr &= ~RNG_CR_CED;
+		else
+			cr |= RNG_CR_CED;
 		writel(cr, pdata->base + RNG_CR);
 		cr &= ~RNG_CR_CONDRST;
+		cr |= RNG_CR_RNGEN;
 		writel(cr, pdata->base + RNG_CR);
 		err = readl_poll_timeout(pdata->base + RNG_CR, cr,
 					 (!(cr & RNG_CR_CONDRST)), 10000);
 		if (err)
 			return err;
+	} else {
+		if (pdata->ced)
+			cr &= ~RNG_CR_CED;
+		else
+			cr |= RNG_CR_CED;
+
+		cr |= RNG_CR_RNGEN;
+
+		writel(cr, pdata->base + RNG_CR);
 	}
 
 	/* clear error indicators */
 	writel(0, pdata->base + RNG_SR);
 
-	cr |= RNG_CR_RNGEN;
-	writel(cr, pdata->base + RNG_CR);
-
 	err = readl_poll_timeout(pdata->base + RNG_SR, sr,
 				 sr & RNG_SR_DRDY, 10000);
 	return err;
@@ -165,6 +175,8 @@ static int stm32_rng_of_to_plat(struct udevice *dev)
 	if (err)
 		return err;
 
+	pdata->ced = dev_read_bool(dev, "clock-error-detect");
+
 	return 0;
 }
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 4/7] rng: stm32: add RNG clock frequency restraint
  2023-09-19 15:27 [PATCH v3 0/7] rng: stm32: support STM32MP13x platforms Gatien Chevallier
                   ` (2 preceding siblings ...)
  2023-09-19 15:27 ` [PATCH v3 3/7] rng: stm32: Implement configurable RNG clock error detection Gatien Chevallier
@ 2023-09-19 15:27 ` Gatien Chevallier
  2023-09-27  6:56   ` Patrice CHOTARD
  2023-09-19 15:27 ` [PATCH v3 5/7] rng: stm32: add error concealment sequence Gatien Chevallier
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 22+ messages in thread
From: Gatien Chevallier @ 2023-09-19 15:27 UTC (permalink / raw)
  To: u-boot
  Cc: Patrick Delaunay, Patrice Chotard, Sughosh Ganu,
	Heinrich Schuchardt, uboot-stm32, Gatien Chevallier

In order to ensure a good RNG quality and compatibility with
certified RNG configuration, add RNG clock frequency restraint.

Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---
Changes in V2:
	- Added Patrick's tag

 drivers/rng/stm32_rng.c | 43 ++++++++++++++++++++++++++++++++++++-----
 1 file changed, 38 insertions(+), 5 deletions(-)

diff --git a/drivers/rng/stm32_rng.c b/drivers/rng/stm32_rng.c
index ada5d92214..f943acd7d2 100644
--- a/drivers/rng/stm32_rng.c
+++ b/drivers/rng/stm32_rng.c
@@ -18,10 +18,11 @@
 #include <linux/iopoll.h>
 #include <linux/kernel.h>
 
-#define RNG_CR		0x00
-#define RNG_CR_RNGEN	BIT(2)
-#define RNG_CR_CED	BIT(5)
-#define RNG_CR_CONDRST	BIT(30)
+#define RNG_CR			0x00
+#define RNG_CR_RNGEN		BIT(2)
+#define RNG_CR_CED		BIT(5)
+#define RNG_CR_CLKDIV_SHIFT	16
+#define RNG_CR_CONDRST		BIT(30)
 
 #define RNG_SR		0x04
 #define RNG_SR_SEIS	BIT(6)
@@ -31,7 +32,15 @@
 
 #define RNG_DR		0x08
 
+/*
+ * struct stm32_rng_data - RNG compat data
+ *
+ * @max_clock_rate:	Max RNG clock frequency, in Hertz
+ * @has_cond_reset:	True if conditionnal reset is supported
+ *
+ */
 struct stm32_rng_data {
+	uint max_clock_rate;
 	bool has_cond_reset;
 };
 
@@ -87,6 +96,26 @@ static int stm32_rng_read(struct udevice *dev, void *data, size_t len)
 	return 0;
 }
 
+static uint stm32_rng_clock_freq_restrain(struct stm32_rng_plat *pdata)
+{
+	ulong clock_rate = 0;
+	uint clock_div = 0;
+
+	clock_rate = clk_get_rate(&pdata->clk);
+
+	/*
+	 * Get the exponent to apply on the CLKDIV field in RNG_CR register.
+	 * No need to handle the case when clock-div > 0xF as it is physically
+	 * impossible.
+	 */
+	while ((clock_rate >> clock_div) > pdata->data->max_clock_rate)
+		clock_div++;
+
+	log_debug("RNG clk rate : %lu\n", clk_get_rate(&pdata->clk) >> clock_div);
+
+	return clock_div;
+}
+
 static int stm32_rng_init(struct stm32_rng_plat *pdata)
 {
 	int err;
@@ -99,7 +128,9 @@ static int stm32_rng_init(struct stm32_rng_plat *pdata)
 	cr = readl(pdata->base + RNG_CR);
 
 	if (pdata->data->has_cond_reset) {
-		cr |= RNG_CR_CONDRST;
+		uint clock_div = stm32_rng_clock_freq_restrain(pdata);
+
+		cr |= RNG_CR_CONDRST | (clock_div << RNG_CR_CLKDIV_SHIFT);
 		if (pdata->ced)
 			cr &= ~RNG_CR_CED;
 		else
@@ -186,10 +217,12 @@ static const struct dm_rng_ops stm32_rng_ops = {
 
 static const struct stm32_rng_data stm32mp13_rng_data = {
 	.has_cond_reset = true,
+	.max_clock_rate = 48000000,
 };
 
 static const struct stm32_rng_data stm32_rng_data = {
 	.has_cond_reset = false,
+	.max_clock_rate = 3000000,
 };
 
 static const struct udevice_id stm32_rng_match[] = {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 5/7] rng: stm32: add error concealment sequence
  2023-09-19 15:27 [PATCH v3 0/7] rng: stm32: support STM32MP13x platforms Gatien Chevallier
                   ` (3 preceding siblings ...)
  2023-09-19 15:27 ` [PATCH v3 4/7] rng: stm32: add RNG clock frequency restraint Gatien Chevallier
@ 2023-09-19 15:27 ` Gatien Chevallier
  2023-09-27  6:57   ` Patrice CHOTARD
  2023-09-19 15:27 ` [PATCH v3 6/7] rng: stm32: Implement custom RNG configuration support Gatien Chevallier
  2023-09-19 15:27 ` [PATCH v3 7/7] ARM: dts: stm32: add RNG node for STM32MP13x platforms Gatien Chevallier
  6 siblings, 1 reply; 22+ messages in thread
From: Gatien Chevallier @ 2023-09-19 15:27 UTC (permalink / raw)
  To: u-boot
  Cc: Patrick Delaunay, Patrice Chotard, Sughosh Ganu,
	Heinrich Schuchardt, uboot-stm32, Gatien Chevallier

Seed errors can occur when using the hardware RNG. Implement the
sequences to handle them. This avoids irrecoverable RNG state.

Try to conceal seed errors when possible. If, despite the error
concealing tries, a seed error is still present, then return an error.

A clock error does not compromise the hardware block and data can
still be read from RNG_DR. Just warn that the RNG clock is too slow
and clear RNG_SR.

Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---
Changes in V2:
	- Added Patrick's tag

 drivers/rng/stm32_rng.c | 163 ++++++++++++++++++++++++++++++++++------
 1 file changed, 140 insertions(+), 23 deletions(-)

diff --git a/drivers/rng/stm32_rng.c b/drivers/rng/stm32_rng.c
index f943acd7d2..b1a790b217 100644
--- a/drivers/rng/stm32_rng.c
+++ b/drivers/rng/stm32_rng.c
@@ -32,6 +32,8 @@
 
 #define RNG_DR		0x08
 
+#define RNG_NB_RECOVER_TRIES	3
+
 /*
  * struct stm32_rng_data - RNG compat data
  *
@@ -52,45 +54,160 @@ struct stm32_rng_plat {
 	bool ced;
 };
 
+/*
+ * Extracts from the STM32 RNG specification when RNG supports CONDRST.
+ *
+ * When a noise source (or seed) error occurs, the RNG stops generating
+ * random numbers and sets to “1” both SEIS and SECS bits to indicate
+ * that a seed error occurred. (...)
+ *
+ * 1. Software reset by writing CONDRST at 1 and at 0 (see bitfield
+ * description for details). This step is needed only if SECS is set.
+ * Indeed, when SEIS is set and SECS is cleared it means RNG performed
+ * the reset automatically (auto-reset).
+ * 2. If SECS was set in step 1 (no auto-reset) wait for CONDRST
+ * to be cleared in the RNG_CR register, then confirm that SEIS is
+ * cleared in the RNG_SR register. Otherwise just clear SEIS bit in
+ * the RNG_SR register.
+ * 3. If SECS was set in step 1 (no auto-reset) wait for SECS to be
+ * cleared by RNG. The random number generation is now back to normal.
+ */
+static int stm32_rng_conceal_seed_error_cond_reset(struct stm32_rng_plat *pdata)
+{
+	u32 sr = readl_relaxed(pdata->base + RNG_SR);
+	u32 cr = readl_relaxed(pdata->base + RNG_CR);
+	int err;
+
+	if (sr & RNG_SR_SECS) {
+		/* Conceal by resetting the subsystem (step 1.) */
+		writel_relaxed(cr | RNG_CR_CONDRST, pdata->base + RNG_CR);
+		writel_relaxed(cr & ~RNG_CR_CONDRST, pdata->base + RNG_CR);
+	} else {
+		/* RNG auto-reset (step 2.) */
+		writel_relaxed(sr & ~RNG_SR_SEIS, pdata->base + RNG_SR);
+		return 0;
+	}
+
+	err = readl_relaxed_poll_timeout(pdata->base + RNG_SR, sr, !(sr & RNG_CR_CONDRST), 100000);
+	if (err) {
+		log_err("%s: timeout %x\n", __func__, sr);
+		return err;
+	}
+
+	/* Check SEIS is cleared (step 2.) */
+	if (readl_relaxed(pdata->base + RNG_SR) & RNG_SR_SEIS)
+		return -EINVAL;
+
+	err = readl_relaxed_poll_timeout(pdata->base + RNG_SR, sr, !(sr & RNG_SR_SECS), 100000);
+	if (err) {
+		log_err("%s: timeout %x\n", __func__, sr);
+		return err;
+	}
+
+	return 0;
+}
+
+/*
+ * Extracts from the STM32 RNG specification, when CONDRST is not supported
+ *
+ * When a noise source (or seed) error occurs, the RNG stops generating
+ * random numbers and sets to “1” both SEIS and SECS bits to indicate
+ * that a seed error occurred. (...)
+ *
+ * The following sequence shall be used to fully recover from a seed
+ * error after the RNG initialization:
+ * 1. Clear the SEIS bit by writing it to “0”.
+ * 2. Read out 12 words from the RNG_DR register, and discard each of
+ * them in order to clean the pipeline.
+ * 3. Confirm that SEIS is still cleared. Random number generation is
+ * back to normal.
+ */
+static int stm32_rng_conceal_seed_error_sw_reset(struct stm32_rng_plat *pdata)
+{
+	uint i = 0;
+	u32 sr = readl_relaxed(pdata->base + RNG_SR);
+
+	writel_relaxed(sr & ~RNG_SR_SEIS, pdata->base + RNG_SR);
+
+	for (i = 12; i != 0; i--)
+		(void)readl_relaxed(pdata->base + RNG_DR);
+
+	if (readl_relaxed(pdata->base + RNG_SR) & RNG_SR_SEIS)
+		return -EINVAL;
+
+	return 0;
+}
+
+static int stm32_rng_conceal_seed_error(struct stm32_rng_plat *pdata)
+{
+	log_debug("Concealing RNG seed error\n");
+
+	if (pdata->data->has_cond_reset)
+		return stm32_rng_conceal_seed_error_cond_reset(pdata);
+	else
+		return stm32_rng_conceal_seed_error_sw_reset(pdata);
+};
+
 static int stm32_rng_read(struct udevice *dev, void *data, size_t len)
 {
-	int retval, i;
-	u32 sr, count, reg;
+	int retval;
+	u32 sr, reg;
 	size_t increment;
 	struct stm32_rng_plat *pdata = dev_get_plat(dev);
+	uint tries = 0;
 
 	while (len > 0) {
 		retval = readl_poll_timeout(pdata->base + RNG_SR, sr,
-					    sr & RNG_SR_DRDY, 10000);
-		if (retval)
+					    sr, 10000);
+		if (retval) {
+			log_err("%s: Timeout RNG no data",  __func__);
 			return retval;
+		}
 
-		if (sr & (RNG_SR_SEIS | RNG_SR_SECS)) {
-			/* As per SoC TRM */
-			clrbits_le32(pdata->base + RNG_SR, RNG_SR_SEIS);
-			for (i = 0; i < 12; i++)
-				readl(pdata->base + RNG_DR);
-			if (readl(pdata->base + RNG_SR) & RNG_SR_SEIS) {
-				log_err("RNG Noise");
-				return -EIO;
+		if (sr != RNG_SR_DRDY) {
+			if (sr & RNG_SR_SEIS) {
+				retval = stm32_rng_conceal_seed_error(pdata);
+				tries++;
+				if (retval || tries > RNG_NB_RECOVER_TRIES) {
+					log_err("%s: Couldn't recover from seed error",  __func__);
+					return -ENOTRECOVERABLE;
+				}
+
+				/* Start again */
+				continue;
+			}
+
+			if (sr & RNG_SR_CEIS) {
+				log_info("RNG clock too slow");
+				writel_relaxed(0, pdata->base + RNG_SR);
 			}
-			/* start again */
-			continue;
 		}
 
 		/*
 		 * Once the DRDY bit is set, the RNG_DR register can
-		 * be read four consecutive times.
+		 * be read up to four consecutive times.
 		 */
-		count = 4;
-		while (len && count) {
-			reg = readl(pdata->base + RNG_DR);
-			memcpy(data, &reg, min(len, sizeof(u32)));
-			increment = min(len, sizeof(u32));
-			data += increment;
-			len -= increment;
-			count--;
+		reg = readl(pdata->base + RNG_DR);
+		/* Late seed error case: DR being 0 is an error status */
+		if (!reg) {
+			retval = stm32_rng_conceal_seed_error(pdata);
+			tries++;
+
+			if (retval || tries > RNG_NB_RECOVER_TRIES) {
+				log_err("%s: Couldn't recover from seed error",  __func__);
+				return -ENOTRECOVERABLE;
+			}
+
+			/* Start again */
+			continue;
 		}
+
+		increment = min(len, sizeof(u32));
+		memcpy(data, &reg, increment);
+		data += increment;
+		len -= increment;
+
+		tries = 0;
 	}
 
 	return 0;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 6/7] rng: stm32: Implement custom RNG configuration support
  2023-09-19 15:27 [PATCH v3 0/7] rng: stm32: support STM32MP13x platforms Gatien Chevallier
                   ` (4 preceding siblings ...)
  2023-09-19 15:27 ` [PATCH v3 5/7] rng: stm32: add error concealment sequence Gatien Chevallier
@ 2023-09-19 15:27 ` Gatien Chevallier
  2023-09-27  7:11   ` Patrice CHOTARD
  2023-09-19 15:27 ` [PATCH v3 7/7] ARM: dts: stm32: add RNG node for STM32MP13x platforms Gatien Chevallier
  6 siblings, 1 reply; 22+ messages in thread
From: Gatien Chevallier @ 2023-09-19 15:27 UTC (permalink / raw)
  To: u-boot
  Cc: Patrick Delaunay, Patrice Chotard, Sughosh Ganu,
	Heinrich Schuchardt, uboot-stm32, Gatien Chevallier

STM32 RNG configuration should best fit the requirements of the
platform. Therefore, put a platform-specific RNG configuration
field in the platform data. Default RNG configuration for STM32MP13
is the NIST certified configuration [1].

While there, fix and the RNG init sequence to support all RNG
versions.

[1] https://csrc.nist.gov/projects/cryptographic-module-validation-program/entropy-validations/certificate/53

Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---
Changes in V2:
	- Added Patrick's tag

 drivers/rng/stm32_rng.c | 54 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 51 insertions(+), 3 deletions(-)

diff --git a/drivers/rng/stm32_rng.c b/drivers/rng/stm32_rng.c
index b1a790b217..c397b4d95c 100644
--- a/drivers/rng/stm32_rng.c
+++ b/drivers/rng/stm32_rng.c
@@ -21,8 +21,15 @@
 #define RNG_CR			0x00
 #define RNG_CR_RNGEN		BIT(2)
 #define RNG_CR_CED		BIT(5)
+#define RNG_CR_CONFIG1		GENMASK(11, 8)
+#define RNG_CR_NISTC		BIT(12)
+#define RNG_CR_CONFIG2		GENMASK(15, 13)
 #define RNG_CR_CLKDIV_SHIFT	16
+#define RNG_CR_CLKDIV		GENMASK(19, 16)
+#define RNG_CR_CONFIG3		GENMASK(25, 20)
 #define RNG_CR_CONDRST		BIT(30)
+#define RNG_CR_ENTROPY_SRC_MASK	(RNG_CR_CONFIG1 | RNG_CR_NISTC | RNG_CR_CONFIG2 | RNG_CR_CONFIG3)
+#define RNG_CR_CONFIG_MASK	(RNG_CR_ENTROPY_SRC_MASK | RNG_CR_CED | RNG_CR_CLKDIV)
 
 #define RNG_SR		0x04
 #define RNG_SR_SEIS	BIT(6)
@@ -32,17 +39,28 @@
 
 #define RNG_DR		0x08
 
+#define RNG_NSCR		0x0C
+#define RNG_NSCR_MASK		GENMASK(17, 0)
+
+#define RNG_HTCR	0x10
+
 #define RNG_NB_RECOVER_TRIES	3
 
 /*
  * struct stm32_rng_data - RNG compat data
  *
  * @max_clock_rate:	Max RNG clock frequency, in Hertz
+ * @cr:			Entropy source configuration
+ * @nscr:		Noice sources control configuration
+ * @htcr:		Health tests configuration
  * @has_cond_reset:	True if conditionnal reset is supported
  *
  */
 struct stm32_rng_data {
 	uint max_clock_rate;
+	u32 cr;
+	u32 nscr;
+	u32 htcr;
 	bool has_cond_reset;
 };
 
@@ -244,28 +262,48 @@ static int stm32_rng_init(struct stm32_rng_plat *pdata)
 
 	cr = readl(pdata->base + RNG_CR);
 
-	if (pdata->data->has_cond_reset) {
+	/*
+	 * Keep default RNG configuration if none was specified, that is when conf.cr is set to 0.
+	 */
+	if (pdata->data->has_cond_reset && pdata->data->cr) {
 		uint clock_div = stm32_rng_clock_freq_restrain(pdata);
 
-		cr |= RNG_CR_CONDRST | (clock_div << RNG_CR_CLKDIV_SHIFT);
+		cr &= ~RNG_CR_CONFIG_MASK;
+		cr |= RNG_CR_CONDRST | (pdata->data->cr & RNG_CR_ENTROPY_SRC_MASK) |
+		      (clock_div << RNG_CR_CLKDIV_SHIFT);
 		if (pdata->ced)
 			cr &= ~RNG_CR_CED;
 		else
 			cr |= RNG_CR_CED;
 		writel(cr, pdata->base + RNG_CR);
+
+		/* Health tests and noise control registers */
+		writel_relaxed(pdata->data->htcr, pdata->base + RNG_HTCR);
+		writel_relaxed(pdata->data->nscr & RNG_NSCR_MASK, pdata->base + RNG_NSCR);
+
 		cr &= ~RNG_CR_CONDRST;
 		cr |= RNG_CR_RNGEN;
 		writel(cr, pdata->base + RNG_CR);
 		err = readl_poll_timeout(pdata->base + RNG_CR, cr,
 					 (!(cr & RNG_CR_CONDRST)), 10000);
-		if (err)
+		if (err) {
+			log_err("%s: Timeout!",  __func__);
 			return err;
+		}
 	} else {
+		if (pdata->data->has_cond_reset)
+			cr |= RNG_CR_CONDRST;
+
 		if (pdata->ced)
 			cr &= ~RNG_CR_CED;
 		else
 			cr |= RNG_CR_CED;
 
+		writel(cr, pdata->base + RNG_CR);
+
+		if (pdata->data->has_cond_reset)
+			cr &= ~RNG_CR_CONDRST;
+
 		cr |= RNG_CR_RNGEN;
 
 		writel(cr, pdata->base + RNG_CR);
@@ -276,6 +314,9 @@ static int stm32_rng_init(struct stm32_rng_plat *pdata)
 
 	err = readl_poll_timeout(pdata->base + RNG_SR, sr,
 				 sr & RNG_SR_DRDY, 10000);
+	if (err)
+		log_err("%s: Timeout!",  __func__);
+
 	return err;
 }
 
@@ -335,11 +376,18 @@ static const struct dm_rng_ops stm32_rng_ops = {
 static const struct stm32_rng_data stm32mp13_rng_data = {
 	.has_cond_reset = true,
 	.max_clock_rate = 48000000,
+	.htcr = 0x969D,
+	.nscr = 0x2B5BB,
+	.cr = 0xF00D00,
 };
 
 static const struct stm32_rng_data stm32_rng_data = {
 	.has_cond_reset = false,
 	.max_clock_rate = 3000000,
+	/* Not supported */
+	.htcr = 0,
+	.nscr = 0,
+	.cr = 0,
 };
 
 static const struct udevice_id stm32_rng_match[] = {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH v3 7/7] ARM: dts: stm32: add RNG node for STM32MP13x platforms
  2023-09-19 15:27 [PATCH v3 0/7] rng: stm32: support STM32MP13x platforms Gatien Chevallier
                   ` (5 preceding siblings ...)
  2023-09-19 15:27 ` [PATCH v3 6/7] rng: stm32: Implement custom RNG configuration support Gatien Chevallier
@ 2023-09-19 15:27 ` Gatien Chevallier
  2023-09-27  7:11   ` Patrice CHOTARD
  6 siblings, 1 reply; 22+ messages in thread
From: Gatien Chevallier @ 2023-09-19 15:27 UTC (permalink / raw)
  To: u-boot
  Cc: Patrick Delaunay, Patrice Chotard, Sughosh Ganu,
	Heinrich Schuchardt, uboot-stm32, Gatien Chevallier

Add RNG node for STM32MP13x platforms.

Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
---
Changes in V2:
	- Added Patrick's tag

 arch/arm/dts/stm32mp131.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/dts/stm32mp131.dtsi b/arch/arm/dts/stm32mp131.dtsi
index d23bbc3639..bd7285053d 100644
--- a/arch/arm/dts/stm32mp131.dtsi
+++ b/arch/arm/dts/stm32mp131.dtsi
@@ -1208,6 +1208,14 @@
 			};
 		};
 
+		rng: rng@54004000 {
+			compatible = "st,stm32mp13-rng";
+			reg = <0x54004000 0x400>;
+			clocks = <&rcc RNG1_K>;
+			resets = <&rcc RNG1_R>;
+			status = "disabled";
+		};
+
 		mdma: dma-controller@58000000 {
 			compatible = "st,stm32h7-mdma";
 			reg = <0x58000000 0x1000>;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH v3 1/7] rng: stm32: rename STM32 RNG driver
  2023-09-19 15:27 ` [PATCH v3 1/7] rng: stm32: rename STM32 RNG driver Gatien Chevallier
@ 2023-09-27  6:52   ` Patrice CHOTARD
  2023-09-27  7:25     ` Patrice CHOTARD
  0 siblings, 1 reply; 22+ messages in thread
From: Patrice CHOTARD @ 2023-09-27  6:52 UTC (permalink / raw)
  To: Gatien Chevallier, u-boot
  Cc: Patrick Delaunay, Sughosh Ganu, Heinrich Schuchardt, uboot-stm32,
	Grzegorz Szymaszek



On 9/19/23 17:27, Gatien Chevallier wrote:
> Rename the RNG driver as it is usable by other STM32 platforms
> than the STM32MP1x ones. Rename CONFIG_RNG_STM32MP1 to
> CONFIG_RNG_STM32
> 
> Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
> Reviewed-by: Grzegorz Szymaszek <gszymaszek@short.pl>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> ---
> 
> Changes in V2:
> 	- Added ARCH_STM32 in the "depends on" section of the
> 	  RNG_STM32 configuration field.
> 	- Added Grzegorz's tag and discarded Patrick's and
> 	  Heinrich's as there's a modification
> 
> Changes in V2:
> 	- Added Patrick's tag. Discarded Heinrich's as patch's
> 	  content has changed.
> 	 
>  MAINTAINERS                                 | 2 +-
>  configs/stm32mp15_basic_defconfig           | 2 +-
>  configs/stm32mp15_defconfig                 | 2 +-
>  configs/stm32mp15_trusted_defconfig         | 2 +-
>  drivers/rng/Kconfig                         | 8 ++++----
>  drivers/rng/Makefile                        | 2 +-
>  drivers/rng/{stm32mp1_rng.c => stm32_rng.c} | 0
>  7 files changed, 9 insertions(+), 9 deletions(-)
>  rename drivers/rng/{stm32mp1_rng.c => stm32_rng.c} (100%)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 0a10a436bc..a3bffa63d5 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -621,7 +621,7 @@ F:	drivers/ram/stm32mp1/
>  F:	drivers/remoteproc/stm32_copro.c
>  F:	drivers/reset/stm32-reset.c
>  F:	drivers/rng/optee_rng.c
> -F:	drivers/rng/stm32mp1_rng.c
> +F:	drivers/rng/stm32_rng.c
>  F:	drivers/rtc/stm32_rtc.c
>  F:	drivers/serial/serial_stm32.*
>  F:	drivers/spi/stm32_qspi.c
> diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig
> index 9ea5aaa714..29b869cf34 100644
> --- a/configs/stm32mp15_basic_defconfig
> +++ b/configs/stm32mp15_basic_defconfig
> @@ -150,7 +150,7 @@ CONFIG_DM_REGULATOR_STM32_VREFBUF=y
>  CONFIG_DM_REGULATOR_STPMIC1=y
>  CONFIG_REMOTEPROC_STM32_COPRO=y
>  CONFIG_DM_RNG=y
> -CONFIG_RNG_STM32MP1=y
> +CONFIG_RNG_STM32=y
>  CONFIG_DM_RTC=y
>  CONFIG_RTC_STM32=y
>  CONFIG_SERIAL_RX_BUFFER=y
> diff --git a/configs/stm32mp15_defconfig b/configs/stm32mp15_defconfig
> index 4d0a81f8a8..b061a83f9d 100644
> --- a/configs/stm32mp15_defconfig
> +++ b/configs/stm32mp15_defconfig
> @@ -123,7 +123,7 @@ CONFIG_DM_REGULATOR_SCMI=y
>  CONFIG_REMOTEPROC_STM32_COPRO=y
>  CONFIG_RESET_SCMI=y
>  CONFIG_DM_RNG=y
> -CONFIG_RNG_STM32MP1=y
> +CONFIG_RNG_STM32=y
>  CONFIG_DM_RTC=y
>  CONFIG_RTC_STM32=y
>  CONFIG_SERIAL_RX_BUFFER=y
> diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig
> index 0a7d862485..b51eefe652 100644
> --- a/configs/stm32mp15_trusted_defconfig
> +++ b/configs/stm32mp15_trusted_defconfig
> @@ -123,7 +123,7 @@ CONFIG_DM_REGULATOR_STPMIC1=y
>  CONFIG_REMOTEPROC_STM32_COPRO=y
>  CONFIG_RESET_SCMI=y
>  CONFIG_DM_RNG=y
> -CONFIG_RNG_STM32MP1=y
> +CONFIG_RNG_STM32=y
>  CONFIG_DM_RTC=y
>  CONFIG_RTC_STM32=y
>  CONFIG_SERIAL_RX_BUFFER=y
> diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig
> index 5deb5db5b7..24666bff98 100644
> --- a/drivers/rng/Kconfig
> +++ b/drivers/rng/Kconfig
> @@ -48,11 +48,11 @@ config RNG_OPTEE
>  	  accessible to normal world but reserved and used by the OP-TEE
>  	  to avoid the weakness of a software PRNG.
>  
> -config RNG_STM32MP1
> -	bool "Enable random number generator for STM32MP1"
> -	depends on ARCH_STM32MP
> +config RNG_STM32
> +	bool "Enable random number generator for STM32"
> +	depends on ARCH_STM32 || ARCH_STM32MP
>  	help
> -	  Enable STM32MP1 rng driver.
> +	  Enable STM32 rng driver.
>  
>  config RNG_ROCKCHIP
>  	bool "Enable random number generator for rockchip crypto rng"
> diff --git a/drivers/rng/Makefile b/drivers/rng/Makefile
> index 78f61051ac..192f911e15 100644
> --- a/drivers/rng/Makefile
> +++ b/drivers/rng/Makefile
> @@ -9,7 +9,7 @@ obj-$(CONFIG_RNG_SANDBOX) += sandbox_rng.o
>  obj-$(CONFIG_RNG_MSM) += msm_rng.o
>  obj-$(CONFIG_RNG_NPCM) += npcm_rng.o
>  obj-$(CONFIG_RNG_OPTEE) += optee_rng.o
> -obj-$(CONFIG_RNG_STM32MP1) += stm32mp1_rng.o
> +obj-$(CONFIG_RNG_STM32) += stm32_rng.o
>  obj-$(CONFIG_RNG_ROCKCHIP) += rockchip_rng.o
>  obj-$(CONFIG_RNG_IPROC200) += iproc_rng200.o
>  obj-$(CONFIG_RNG_SMCCC_TRNG) += smccc_trng.o
> diff --git a/drivers/rng/stm32mp1_rng.c b/drivers/rng/stm32_rng.c
> similarity index 100%
> rename from drivers/rng/stm32mp1_rng.c
> rename to drivers/rng/stm32_rng.c

Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>

Thanks
Patrice

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v3 2/7] configs: default activate CONFIG_RNG_STM32 for STM32MP13x platforms
  2023-09-19 15:27 ` [PATCH v3 2/7] configs: default activate CONFIG_RNG_STM32 for STM32MP13x platforms Gatien Chevallier
@ 2023-09-27  6:53   ` Patrice CHOTARD
  2023-09-27  7:26     ` [Uboot-stm32] " Patrice CHOTARD
  0 siblings, 1 reply; 22+ messages in thread
From: Patrice CHOTARD @ 2023-09-27  6:53 UTC (permalink / raw)
  To: Gatien Chevallier, u-boot
  Cc: Patrick Delaunay, Sughosh Ganu, Heinrich Schuchardt, uboot-stm32



On 9/19/23 17:27, Gatien Chevallier wrote:
> Default embed this configuration. If OP-TEE PTA RNG is exposed, it means
> that the RNG is managed by the secure world. Therefore, the RNG node
> should be disabled in the device tree as an access would be denied
> by the hardware firewall.
> 
> Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> ---
> Changes in V2:
> 	- Added Patrick's tag
> 
>  configs/stm32mp13_defconfig | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/configs/stm32mp13_defconfig b/configs/stm32mp13_defconfig
> index 82b62744f6..4a899c85de 100644
> --- a/configs/stm32mp13_defconfig
> +++ b/configs/stm32mp13_defconfig
> @@ -65,6 +65,7 @@ CONFIG_DM_REGULATOR_GPIO=y
>  CONFIG_DM_REGULATOR_SCMI=y
>  CONFIG_RESET_SCMI=y
>  CONFIG_DM_RNG=y
> +CONFIG_RNG_STM32=y
>  CONFIG_DM_RTC=y
>  CONFIG_RTC_STM32=y
>  CONFIG_SERIAL_RX_BUFFER=y
Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>

Thanks
Patrice

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v3 3/7] rng: stm32: Implement configurable RNG clock error detection
  2023-09-19 15:27 ` [PATCH v3 3/7] rng: stm32: Implement configurable RNG clock error detection Gatien Chevallier
@ 2023-09-27  6:56   ` Patrice CHOTARD
  2023-09-27  7:26     ` [Uboot-stm32] " Patrice CHOTARD
  0 siblings, 1 reply; 22+ messages in thread
From: Patrice CHOTARD @ 2023-09-27  6:56 UTC (permalink / raw)
  To: Gatien Chevallier, u-boot
  Cc: Patrick Delaunay, Sughosh Ganu, Heinrich Schuchardt, uboot-stm32



On 9/19/23 17:27, Gatien Chevallier wrote:
> RNG clock error detection is now enabled if the "clock-error-detect"
> property is set in the device tree.
> 
> Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> ---
> Changes in V2:
> 	- Added Patrick's tag
> 
>  drivers/rng/stm32_rng.c | 22 +++++++++++++++++-----
>  1 file changed, 17 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/rng/stm32_rng.c b/drivers/rng/stm32_rng.c
> index 89da78c6c8..ada5d92214 100644
> --- a/drivers/rng/stm32_rng.c
> +++ b/drivers/rng/stm32_rng.c
> @@ -40,6 +40,7 @@ struct stm32_rng_plat {
>  	struct clk clk;
>  	struct reset_ctl rst;
>  	const struct stm32_rng_data *data;
> +	bool ced;
>  };
>  
>  static int stm32_rng_read(struct udevice *dev, void *data, size_t len)
> @@ -97,25 +98,34 @@ static int stm32_rng_init(struct stm32_rng_plat *pdata)
>  
>  	cr = readl(pdata->base + RNG_CR);
>  
> -	/* Disable CED */
> -	cr |= RNG_CR_CED;
>  	if (pdata->data->has_cond_reset) {
>  		cr |= RNG_CR_CONDRST;
> +		if (pdata->ced)
> +			cr &= ~RNG_CR_CED;
> +		else
> +			cr |= RNG_CR_CED;
>  		writel(cr, pdata->base + RNG_CR);
>  		cr &= ~RNG_CR_CONDRST;
> +		cr |= RNG_CR_RNGEN;
>  		writel(cr, pdata->base + RNG_CR);
>  		err = readl_poll_timeout(pdata->base + RNG_CR, cr,
>  					 (!(cr & RNG_CR_CONDRST)), 10000);
>  		if (err)
>  			return err;
> +	} else {
> +		if (pdata->ced)
> +			cr &= ~RNG_CR_CED;
> +		else
> +			cr |= RNG_CR_CED;
> +
> +		cr |= RNG_CR_RNGEN;
> +
> +		writel(cr, pdata->base + RNG_CR);
>  	}
>  
>  	/* clear error indicators */
>  	writel(0, pdata->base + RNG_SR);
>  
> -	cr |= RNG_CR_RNGEN;
> -	writel(cr, pdata->base + RNG_CR);
> -
>  	err = readl_poll_timeout(pdata->base + RNG_SR, sr,
>  				 sr & RNG_SR_DRDY, 10000);
>  	return err;
> @@ -165,6 +175,8 @@ static int stm32_rng_of_to_plat(struct udevice *dev)
>  	if (err)
>  		return err;
>  
> +	pdata->ced = dev_read_bool(dev, "clock-error-detect");
> +
>  	return 0;
>  }
>  
Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>

Thanks
Patrice

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v3 4/7] rng: stm32: add RNG clock frequency restraint
  2023-09-19 15:27 ` [PATCH v3 4/7] rng: stm32: add RNG clock frequency restraint Gatien Chevallier
@ 2023-09-27  6:56   ` Patrice CHOTARD
  2023-09-27  7:26     ` Patrice CHOTARD
  0 siblings, 1 reply; 22+ messages in thread
From: Patrice CHOTARD @ 2023-09-27  6:56 UTC (permalink / raw)
  To: Gatien Chevallier, u-boot
  Cc: Patrick Delaunay, Sughosh Ganu, Heinrich Schuchardt, uboot-stm32



On 9/19/23 17:27, Gatien Chevallier wrote:
> In order to ensure a good RNG quality and compatibility with
> certified RNG configuration, add RNG clock frequency restraint.
> 
> Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> ---
> Changes in V2:
> 	- Added Patrick's tag
> 
>  drivers/rng/stm32_rng.c | 43 ++++++++++++++++++++++++++++++++++++-----
>  1 file changed, 38 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/rng/stm32_rng.c b/drivers/rng/stm32_rng.c
> index ada5d92214..f943acd7d2 100644
> --- a/drivers/rng/stm32_rng.c
> +++ b/drivers/rng/stm32_rng.c
> @@ -18,10 +18,11 @@
>  #include <linux/iopoll.h>
>  #include <linux/kernel.h>
>  
> -#define RNG_CR		0x00
> -#define RNG_CR_RNGEN	BIT(2)
> -#define RNG_CR_CED	BIT(5)
> -#define RNG_CR_CONDRST	BIT(30)
> +#define RNG_CR			0x00
> +#define RNG_CR_RNGEN		BIT(2)
> +#define RNG_CR_CED		BIT(5)
> +#define RNG_CR_CLKDIV_SHIFT	16
> +#define RNG_CR_CONDRST		BIT(30)
>  
>  #define RNG_SR		0x04
>  #define RNG_SR_SEIS	BIT(6)
> @@ -31,7 +32,15 @@
>  
>  #define RNG_DR		0x08
>  
> +/*
> + * struct stm32_rng_data - RNG compat data
> + *
> + * @max_clock_rate:	Max RNG clock frequency, in Hertz
> + * @has_cond_reset:	True if conditionnal reset is supported
> + *
> + */
>  struct stm32_rng_data {
> +	uint max_clock_rate;
>  	bool has_cond_reset;
>  };
>  
> @@ -87,6 +96,26 @@ static int stm32_rng_read(struct udevice *dev, void *data, size_t len)
>  	return 0;
>  }
>  
> +static uint stm32_rng_clock_freq_restrain(struct stm32_rng_plat *pdata)
> +{
> +	ulong clock_rate = 0;
> +	uint clock_div = 0;
> +
> +	clock_rate = clk_get_rate(&pdata->clk);
> +
> +	/*
> +	 * Get the exponent to apply on the CLKDIV field in RNG_CR register.
> +	 * No need to handle the case when clock-div > 0xF as it is physically
> +	 * impossible.
> +	 */
> +	while ((clock_rate >> clock_div) > pdata->data->max_clock_rate)
> +		clock_div++;
> +
> +	log_debug("RNG clk rate : %lu\n", clk_get_rate(&pdata->clk) >> clock_div);
> +
> +	return clock_div;
> +}
> +
>  static int stm32_rng_init(struct stm32_rng_plat *pdata)
>  {
>  	int err;
> @@ -99,7 +128,9 @@ static int stm32_rng_init(struct stm32_rng_plat *pdata)
>  	cr = readl(pdata->base + RNG_CR);
>  
>  	if (pdata->data->has_cond_reset) {
> -		cr |= RNG_CR_CONDRST;
> +		uint clock_div = stm32_rng_clock_freq_restrain(pdata);
> +
> +		cr |= RNG_CR_CONDRST | (clock_div << RNG_CR_CLKDIV_SHIFT);
>  		if (pdata->ced)
>  			cr &= ~RNG_CR_CED;
>  		else
> @@ -186,10 +217,12 @@ static const struct dm_rng_ops stm32_rng_ops = {
>  
>  static const struct stm32_rng_data stm32mp13_rng_data = {
>  	.has_cond_reset = true,
> +	.max_clock_rate = 48000000,
>  };
>  
>  static const struct stm32_rng_data stm32_rng_data = {
>  	.has_cond_reset = false,
> +	.max_clock_rate = 3000000,
>  };
>  
>  static const struct udevice_id stm32_rng_match[] = {

Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>

Thanks
Patrice

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v3 5/7] rng: stm32: add error concealment sequence
  2023-09-19 15:27 ` [PATCH v3 5/7] rng: stm32: add error concealment sequence Gatien Chevallier
@ 2023-09-27  6:57   ` Patrice CHOTARD
  2023-09-27  7:26     ` Patrice CHOTARD
  0 siblings, 1 reply; 22+ messages in thread
From: Patrice CHOTARD @ 2023-09-27  6:57 UTC (permalink / raw)
  To: Gatien Chevallier, u-boot
  Cc: Patrick Delaunay, Sughosh Ganu, Heinrich Schuchardt, uboot-stm32



On 9/19/23 17:27, Gatien Chevallier wrote:
> Seed errors can occur when using the hardware RNG. Implement the
> sequences to handle them. This avoids irrecoverable RNG state.
> 
> Try to conceal seed errors when possible. If, despite the error
> concealing tries, a seed error is still present, then return an error.
> 
> A clock error does not compromise the hardware block and data can
> still be read from RNG_DR. Just warn that the RNG clock is too slow
> and clear RNG_SR.
> 
> Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> ---
> Changes in V2:
> 	- Added Patrick's tag
> 
>  drivers/rng/stm32_rng.c | 163 ++++++++++++++++++++++++++++++++++------
>  1 file changed, 140 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/rng/stm32_rng.c b/drivers/rng/stm32_rng.c
> index f943acd7d2..b1a790b217 100644
> --- a/drivers/rng/stm32_rng.c
> +++ b/drivers/rng/stm32_rng.c
> @@ -32,6 +32,8 @@
>  
>  #define RNG_DR		0x08
>  
> +#define RNG_NB_RECOVER_TRIES	3
> +
>  /*
>   * struct stm32_rng_data - RNG compat data
>   *
> @@ -52,45 +54,160 @@ struct stm32_rng_plat {
>  	bool ced;
>  };
>  
> +/*
> + * Extracts from the STM32 RNG specification when RNG supports CONDRST.
> + *
> + * When a noise source (or seed) error occurs, the RNG stops generating
> + * random numbers and sets to “1” both SEIS and SECS bits to indicate
> + * that a seed error occurred. (...)
> + *
> + * 1. Software reset by writing CONDRST at 1 and at 0 (see bitfield
> + * description for details). This step is needed only if SECS is set.
> + * Indeed, when SEIS is set and SECS is cleared it means RNG performed
> + * the reset automatically (auto-reset).
> + * 2. If SECS was set in step 1 (no auto-reset) wait for CONDRST
> + * to be cleared in the RNG_CR register, then confirm that SEIS is
> + * cleared in the RNG_SR register. Otherwise just clear SEIS bit in
> + * the RNG_SR register.
> + * 3. If SECS was set in step 1 (no auto-reset) wait for SECS to be
> + * cleared by RNG. The random number generation is now back to normal.
> + */
> +static int stm32_rng_conceal_seed_error_cond_reset(struct stm32_rng_plat *pdata)
> +{
> +	u32 sr = readl_relaxed(pdata->base + RNG_SR);
> +	u32 cr = readl_relaxed(pdata->base + RNG_CR);
> +	int err;
> +
> +	if (sr & RNG_SR_SECS) {
> +		/* Conceal by resetting the subsystem (step 1.) */
> +		writel_relaxed(cr | RNG_CR_CONDRST, pdata->base + RNG_CR);
> +		writel_relaxed(cr & ~RNG_CR_CONDRST, pdata->base + RNG_CR);
> +	} else {
> +		/* RNG auto-reset (step 2.) */
> +		writel_relaxed(sr & ~RNG_SR_SEIS, pdata->base + RNG_SR);
> +		return 0;
> +	}
> +
> +	err = readl_relaxed_poll_timeout(pdata->base + RNG_SR, sr, !(sr & RNG_CR_CONDRST), 100000);
> +	if (err) {
> +		log_err("%s: timeout %x\n", __func__, sr);
> +		return err;
> +	}
> +
> +	/* Check SEIS is cleared (step 2.) */
> +	if (readl_relaxed(pdata->base + RNG_SR) & RNG_SR_SEIS)
> +		return -EINVAL;
> +
> +	err = readl_relaxed_poll_timeout(pdata->base + RNG_SR, sr, !(sr & RNG_SR_SECS), 100000);
> +	if (err) {
> +		log_err("%s: timeout %x\n", __func__, sr);
> +		return err;
> +	}
> +
> +	return 0;
> +}
> +
> +/*
> + * Extracts from the STM32 RNG specification, when CONDRST is not supported
> + *
> + * When a noise source (or seed) error occurs, the RNG stops generating
> + * random numbers and sets to “1” both SEIS and SECS bits to indicate
> + * that a seed error occurred. (...)
> + *
> + * The following sequence shall be used to fully recover from a seed
> + * error after the RNG initialization:
> + * 1. Clear the SEIS bit by writing it to “0”.
> + * 2. Read out 12 words from the RNG_DR register, and discard each of
> + * them in order to clean the pipeline.
> + * 3. Confirm that SEIS is still cleared. Random number generation is
> + * back to normal.
> + */
> +static int stm32_rng_conceal_seed_error_sw_reset(struct stm32_rng_plat *pdata)
> +{
> +	uint i = 0;
> +	u32 sr = readl_relaxed(pdata->base + RNG_SR);
> +
> +	writel_relaxed(sr & ~RNG_SR_SEIS, pdata->base + RNG_SR);
> +
> +	for (i = 12; i != 0; i--)
> +		(void)readl_relaxed(pdata->base + RNG_DR);
> +
> +	if (readl_relaxed(pdata->base + RNG_SR) & RNG_SR_SEIS)
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static int stm32_rng_conceal_seed_error(struct stm32_rng_plat *pdata)
> +{
> +	log_debug("Concealing RNG seed error\n");
> +
> +	if (pdata->data->has_cond_reset)
> +		return stm32_rng_conceal_seed_error_cond_reset(pdata);
> +	else
> +		return stm32_rng_conceal_seed_error_sw_reset(pdata);
> +};
> +
>  static int stm32_rng_read(struct udevice *dev, void *data, size_t len)
>  {
> -	int retval, i;
> -	u32 sr, count, reg;
> +	int retval;
> +	u32 sr, reg;
>  	size_t increment;
>  	struct stm32_rng_plat *pdata = dev_get_plat(dev);
> +	uint tries = 0;
>  
>  	while (len > 0) {
>  		retval = readl_poll_timeout(pdata->base + RNG_SR, sr,
> -					    sr & RNG_SR_DRDY, 10000);
> -		if (retval)
> +					    sr, 10000);
> +		if (retval) {
> +			log_err("%s: Timeout RNG no data",  __func__);
>  			return retval;
> +		}
>  
> -		if (sr & (RNG_SR_SEIS | RNG_SR_SECS)) {
> -			/* As per SoC TRM */
> -			clrbits_le32(pdata->base + RNG_SR, RNG_SR_SEIS);
> -			for (i = 0; i < 12; i++)
> -				readl(pdata->base + RNG_DR);
> -			if (readl(pdata->base + RNG_SR) & RNG_SR_SEIS) {
> -				log_err("RNG Noise");
> -				return -EIO;
> +		if (sr != RNG_SR_DRDY) {
> +			if (sr & RNG_SR_SEIS) {
> +				retval = stm32_rng_conceal_seed_error(pdata);
> +				tries++;
> +				if (retval || tries > RNG_NB_RECOVER_TRIES) {
> +					log_err("%s: Couldn't recover from seed error",  __func__);
> +					return -ENOTRECOVERABLE;
> +				}
> +
> +				/* Start again */
> +				continue;
> +			}
> +
> +			if (sr & RNG_SR_CEIS) {
> +				log_info("RNG clock too slow");
> +				writel_relaxed(0, pdata->base + RNG_SR);
>  			}
> -			/* start again */
> -			continue;
>  		}
>  
>  		/*
>  		 * Once the DRDY bit is set, the RNG_DR register can
> -		 * be read four consecutive times.
> +		 * be read up to four consecutive times.
>  		 */
> -		count = 4;
> -		while (len && count) {
> -			reg = readl(pdata->base + RNG_DR);
> -			memcpy(data, &reg, min(len, sizeof(u32)));
> -			increment = min(len, sizeof(u32));
> -			data += increment;
> -			len -= increment;
> -			count--;
> +		reg = readl(pdata->base + RNG_DR);
> +		/* Late seed error case: DR being 0 is an error status */
> +		if (!reg) {
> +			retval = stm32_rng_conceal_seed_error(pdata);
> +			tries++;
> +
> +			if (retval || tries > RNG_NB_RECOVER_TRIES) {
> +				log_err("%s: Couldn't recover from seed error",  __func__);
> +				return -ENOTRECOVERABLE;
> +			}
> +
> +			/* Start again */
> +			continue;
>  		}
> +
> +		increment = min(len, sizeof(u32));
> +		memcpy(data, &reg, increment);
> +		data += increment;
> +		len -= increment;
> +
> +		tries = 0;
>  	}
>  
>  	return 0;

Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>

Thanks
Patrice

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v3 6/7] rng: stm32: Implement custom RNG configuration support
  2023-09-19 15:27 ` [PATCH v3 6/7] rng: stm32: Implement custom RNG configuration support Gatien Chevallier
@ 2023-09-27  7:11   ` Patrice CHOTARD
  2023-09-27  7:27     ` [Uboot-stm32] " Patrice CHOTARD
  0 siblings, 1 reply; 22+ messages in thread
From: Patrice CHOTARD @ 2023-09-27  7:11 UTC (permalink / raw)
  To: Gatien Chevallier, u-boot
  Cc: Patrick Delaunay, Sughosh Ganu, Heinrich Schuchardt, uboot-stm32



On 9/19/23 17:27, Gatien Chevallier wrote:
> STM32 RNG configuration should best fit the requirements of the
> platform. Therefore, put a platform-specific RNG configuration
> field in the platform data. Default RNG configuration for STM32MP13
> is the NIST certified configuration [1].
> 
> While there, fix and the RNG init sequence to support all RNG
> versions.
> 
> [1] https://csrc.nist.gov/projects/cryptographic-module-validation-program/entropy-validations/certificate/53
> 
> Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> ---
> Changes in V2:
> 	- Added Patrick's tag
> 
>  drivers/rng/stm32_rng.c | 54 ++++++++++++++++++++++++++++++++++++++---
>  1 file changed, 51 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/rng/stm32_rng.c b/drivers/rng/stm32_rng.c
> index b1a790b217..c397b4d95c 100644
> --- a/drivers/rng/stm32_rng.c
> +++ b/drivers/rng/stm32_rng.c
> @@ -21,8 +21,15 @@
>  #define RNG_CR			0x00
>  #define RNG_CR_RNGEN		BIT(2)
>  #define RNG_CR_CED		BIT(5)
> +#define RNG_CR_CONFIG1		GENMASK(11, 8)
> +#define RNG_CR_NISTC		BIT(12)
> +#define RNG_CR_CONFIG2		GENMASK(15, 13)
>  #define RNG_CR_CLKDIV_SHIFT	16
> +#define RNG_CR_CLKDIV		GENMASK(19, 16)
> +#define RNG_CR_CONFIG3		GENMASK(25, 20)
>  #define RNG_CR_CONDRST		BIT(30)
> +#define RNG_CR_ENTROPY_SRC_MASK	(RNG_CR_CONFIG1 | RNG_CR_NISTC | RNG_CR_CONFIG2 | RNG_CR_CONFIG3)
> +#define RNG_CR_CONFIG_MASK	(RNG_CR_ENTROPY_SRC_MASK | RNG_CR_CED | RNG_CR_CLKDIV)
>  
>  #define RNG_SR		0x04
>  #define RNG_SR_SEIS	BIT(6)
> @@ -32,17 +39,28 @@
>  
>  #define RNG_DR		0x08
>  
> +#define RNG_NSCR		0x0C
> +#define RNG_NSCR_MASK		GENMASK(17, 0)
> +
> +#define RNG_HTCR	0x10
> +
>  #define RNG_NB_RECOVER_TRIES	3
>  
>  /*
>   * struct stm32_rng_data - RNG compat data
>   *
>   * @max_clock_rate:	Max RNG clock frequency, in Hertz
> + * @cr:			Entropy source configuration
> + * @nscr:		Noice sources control configuration
> + * @htcr:		Health tests configuration
>   * @has_cond_reset:	True if conditionnal reset is supported
>   *
>   */
>  struct stm32_rng_data {
>  	uint max_clock_rate;
> +	u32 cr;
> +	u32 nscr;
> +	u32 htcr;
>  	bool has_cond_reset;
>  };
>  
> @@ -244,28 +262,48 @@ static int stm32_rng_init(struct stm32_rng_plat *pdata)
>  
>  	cr = readl(pdata->base + RNG_CR);
>  
> -	if (pdata->data->has_cond_reset) {
> +	/*
> +	 * Keep default RNG configuration if none was specified, that is when conf.cr is set to 0.
> +	 */
> +	if (pdata->data->has_cond_reset && pdata->data->cr) {
>  		uint clock_div = stm32_rng_clock_freq_restrain(pdata);
>  
> -		cr |= RNG_CR_CONDRST | (clock_div << RNG_CR_CLKDIV_SHIFT);
> +		cr &= ~RNG_CR_CONFIG_MASK;
> +		cr |= RNG_CR_CONDRST | (pdata->data->cr & RNG_CR_ENTROPY_SRC_MASK) |
> +		      (clock_div << RNG_CR_CLKDIV_SHIFT);
>  		if (pdata->ced)
>  			cr &= ~RNG_CR_CED;
>  		else
>  			cr |= RNG_CR_CED;
>  		writel(cr, pdata->base + RNG_CR);
> +
> +		/* Health tests and noise control registers */
> +		writel_relaxed(pdata->data->htcr, pdata->base + RNG_HTCR);
> +		writel_relaxed(pdata->data->nscr & RNG_NSCR_MASK, pdata->base + RNG_NSCR);
> +
>  		cr &= ~RNG_CR_CONDRST;
>  		cr |= RNG_CR_RNGEN;
>  		writel(cr, pdata->base + RNG_CR);
>  		err = readl_poll_timeout(pdata->base + RNG_CR, cr,
>  					 (!(cr & RNG_CR_CONDRST)), 10000);
> -		if (err)
> +		if (err) {
> +			log_err("%s: Timeout!",  __func__);
>  			return err;
> +		}
>  	} else {
> +		if (pdata->data->has_cond_reset)
> +			cr |= RNG_CR_CONDRST;
> +
>  		if (pdata->ced)
>  			cr &= ~RNG_CR_CED;
>  		else
>  			cr |= RNG_CR_CED;
>  
> +		writel(cr, pdata->base + RNG_CR);
> +
> +		if (pdata->data->has_cond_reset)
> +			cr &= ~RNG_CR_CONDRST;
> +
>  		cr |= RNG_CR_RNGEN;
>  
>  		writel(cr, pdata->base + RNG_CR);
> @@ -276,6 +314,9 @@ static int stm32_rng_init(struct stm32_rng_plat *pdata)
>  
>  	err = readl_poll_timeout(pdata->base + RNG_SR, sr,
>  				 sr & RNG_SR_DRDY, 10000);
> +	if (err)
> +		log_err("%s: Timeout!",  __func__);
> +
>  	return err;
>  }
>  
> @@ -335,11 +376,18 @@ static const struct dm_rng_ops stm32_rng_ops = {
>  static const struct stm32_rng_data stm32mp13_rng_data = {
>  	.has_cond_reset = true,
>  	.max_clock_rate = 48000000,
> +	.htcr = 0x969D,
> +	.nscr = 0x2B5BB,
> +	.cr = 0xF00D00,
>  };
>  
>  static const struct stm32_rng_data stm32_rng_data = {
>  	.has_cond_reset = false,
>  	.max_clock_rate = 3000000,
> +	/* Not supported */
> +	.htcr = 0,
> +	.nscr = 0,
> +	.cr = 0,
>  };
>  
>  static const struct udevice_id stm32_rng_match[] = {
Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>

Thanks
Patrice

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v3 7/7] ARM: dts: stm32: add RNG node for STM32MP13x platforms
  2023-09-19 15:27 ` [PATCH v3 7/7] ARM: dts: stm32: add RNG node for STM32MP13x platforms Gatien Chevallier
@ 2023-09-27  7:11   ` Patrice CHOTARD
  2023-09-27  7:27     ` Patrice CHOTARD
  0 siblings, 1 reply; 22+ messages in thread
From: Patrice CHOTARD @ 2023-09-27  7:11 UTC (permalink / raw)
  To: Gatien Chevallier, u-boot
  Cc: Patrick Delaunay, Sughosh Ganu, Heinrich Schuchardt, uboot-stm32



On 9/19/23 17:27, Gatien Chevallier wrote:
> Add RNG node for STM32MP13x platforms.
> 
> Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
> ---
> Changes in V2:
> 	- Added Patrick's tag
> 
>  arch/arm/dts/stm32mp131.dtsi | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/arch/arm/dts/stm32mp131.dtsi b/arch/arm/dts/stm32mp131.dtsi
> index d23bbc3639..bd7285053d 100644
> --- a/arch/arm/dts/stm32mp131.dtsi
> +++ b/arch/arm/dts/stm32mp131.dtsi
> @@ -1208,6 +1208,14 @@
>  			};
>  		};
>  
> +		rng: rng@54004000 {
> +			compatible = "st,stm32mp13-rng";
> +			reg = <0x54004000 0x400>;
> +			clocks = <&rcc RNG1_K>;
> +			resets = <&rcc RNG1_R>;
> +			status = "disabled";
> +		};
> +
>  		mdma: dma-controller@58000000 {
>  			compatible = "st,stm32h7-mdma";
>  			reg = <0x58000000 0x1000>;
Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>

Thanks
Patrice

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v3 1/7] rng: stm32: rename STM32 RNG driver
  2023-09-27  6:52   ` Patrice CHOTARD
@ 2023-09-27  7:25     ` Patrice CHOTARD
  0 siblings, 0 replies; 22+ messages in thread
From: Patrice CHOTARD @ 2023-09-27  7:25 UTC (permalink / raw)
  To: Gatien Chevallier, u-boot
  Cc: Patrick Delaunay, Sughosh Ganu, Heinrich Schuchardt, uboot-stm32,
	Grzegorz Szymaszek



On 9/27/23 08:52, Patrice CHOTARD wrote:
> 
> 
> On 9/19/23 17:27, Gatien Chevallier wrote:
>> Rename the RNG driver as it is usable by other STM32 platforms
>> than the STM32MP1x ones. Rename CONFIG_RNG_STM32MP1 to
>> CONFIG_RNG_STM32
>>
>> Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
>> Reviewed-by: Grzegorz Szymaszek <gszymaszek@short.pl>
>> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
>> ---
>>
>> Changes in V2:
>> 	- Added ARCH_STM32 in the "depends on" section of the
>> 	  RNG_STM32 configuration field.
>> 	- Added Grzegorz's tag and discarded Patrick's and
>> 	  Heinrich's as there's a modification
>>
>> Changes in V2:
>> 	- Added Patrick's tag. Discarded Heinrich's as patch's
>> 	  content has changed.
>> 	 
>>  MAINTAINERS                                 | 2 +-
>>  configs/stm32mp15_basic_defconfig           | 2 +-
>>  configs/stm32mp15_defconfig                 | 2 +-
>>  configs/stm32mp15_trusted_defconfig         | 2 +-
>>  drivers/rng/Kconfig                         | 8 ++++----
>>  drivers/rng/Makefile                        | 2 +-
>>  drivers/rng/{stm32mp1_rng.c => stm32_rng.c} | 0
>>  7 files changed, 9 insertions(+), 9 deletions(-)
>>  rename drivers/rng/{stm32mp1_rng.c => stm32_rng.c} (100%)
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 0a10a436bc..a3bffa63d5 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -621,7 +621,7 @@ F:	drivers/ram/stm32mp1/
>>  F:	drivers/remoteproc/stm32_copro.c
>>  F:	drivers/reset/stm32-reset.c
>>  F:	drivers/rng/optee_rng.c
>> -F:	drivers/rng/stm32mp1_rng.c
>> +F:	drivers/rng/stm32_rng.c
>>  F:	drivers/rtc/stm32_rtc.c
>>  F:	drivers/serial/serial_stm32.*
>>  F:	drivers/spi/stm32_qspi.c
>> diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig
>> index 9ea5aaa714..29b869cf34 100644
>> --- a/configs/stm32mp15_basic_defconfig
>> +++ b/configs/stm32mp15_basic_defconfig
>> @@ -150,7 +150,7 @@ CONFIG_DM_REGULATOR_STM32_VREFBUF=y
>>  CONFIG_DM_REGULATOR_STPMIC1=y
>>  CONFIG_REMOTEPROC_STM32_COPRO=y
>>  CONFIG_DM_RNG=y
>> -CONFIG_RNG_STM32MP1=y
>> +CONFIG_RNG_STM32=y
>>  CONFIG_DM_RTC=y
>>  CONFIG_RTC_STM32=y
>>  CONFIG_SERIAL_RX_BUFFER=y
>> diff --git a/configs/stm32mp15_defconfig b/configs/stm32mp15_defconfig
>> index 4d0a81f8a8..b061a83f9d 100644
>> --- a/configs/stm32mp15_defconfig
>> +++ b/configs/stm32mp15_defconfig
>> @@ -123,7 +123,7 @@ CONFIG_DM_REGULATOR_SCMI=y
>>  CONFIG_REMOTEPROC_STM32_COPRO=y
>>  CONFIG_RESET_SCMI=y
>>  CONFIG_DM_RNG=y
>> -CONFIG_RNG_STM32MP1=y
>> +CONFIG_RNG_STM32=y
>>  CONFIG_DM_RTC=y
>>  CONFIG_RTC_STM32=y
>>  CONFIG_SERIAL_RX_BUFFER=y
>> diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig
>> index 0a7d862485..b51eefe652 100644
>> --- a/configs/stm32mp15_trusted_defconfig
>> +++ b/configs/stm32mp15_trusted_defconfig
>> @@ -123,7 +123,7 @@ CONFIG_DM_REGULATOR_STPMIC1=y
>>  CONFIG_REMOTEPROC_STM32_COPRO=y
>>  CONFIG_RESET_SCMI=y
>>  CONFIG_DM_RNG=y
>> -CONFIG_RNG_STM32MP1=y
>> +CONFIG_RNG_STM32=y
>>  CONFIG_DM_RTC=y
>>  CONFIG_RTC_STM32=y
>>  CONFIG_SERIAL_RX_BUFFER=y
>> diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig
>> index 5deb5db5b7..24666bff98 100644
>> --- a/drivers/rng/Kconfig
>> +++ b/drivers/rng/Kconfig
>> @@ -48,11 +48,11 @@ config RNG_OPTEE
>>  	  accessible to normal world but reserved and used by the OP-TEE
>>  	  to avoid the weakness of a software PRNG.
>>  
>> -config RNG_STM32MP1
>> -	bool "Enable random number generator for STM32MP1"
>> -	depends on ARCH_STM32MP
>> +config RNG_STM32
>> +	bool "Enable random number generator for STM32"
>> +	depends on ARCH_STM32 || ARCH_STM32MP
>>  	help
>> -	  Enable STM32MP1 rng driver.
>> +	  Enable STM32 rng driver.
>>  
>>  config RNG_ROCKCHIP
>>  	bool "Enable random number generator for rockchip crypto rng"
>> diff --git a/drivers/rng/Makefile b/drivers/rng/Makefile
>> index 78f61051ac..192f911e15 100644
>> --- a/drivers/rng/Makefile
>> +++ b/drivers/rng/Makefile
>> @@ -9,7 +9,7 @@ obj-$(CONFIG_RNG_SANDBOX) += sandbox_rng.o
>>  obj-$(CONFIG_RNG_MSM) += msm_rng.o
>>  obj-$(CONFIG_RNG_NPCM) += npcm_rng.o
>>  obj-$(CONFIG_RNG_OPTEE) += optee_rng.o
>> -obj-$(CONFIG_RNG_STM32MP1) += stm32mp1_rng.o
>> +obj-$(CONFIG_RNG_STM32) += stm32_rng.o
>>  obj-$(CONFIG_RNG_ROCKCHIP) += rockchip_rng.o
>>  obj-$(CONFIG_RNG_IPROC200) += iproc_rng200.o
>>  obj-$(CONFIG_RNG_SMCCC_TRNG) += smccc_trng.o
>> diff --git a/drivers/rng/stm32mp1_rng.c b/drivers/rng/stm32_rng.c
>> similarity index 100%
>> rename from drivers/rng/stm32mp1_rng.c
>> rename to drivers/rng/stm32_rng.c
> 
> Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
> 
> Thanks
> Patrice
Apply on stm32/next

Patrice

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Uboot-stm32] [PATCH v3 2/7] configs: default activate CONFIG_RNG_STM32 for STM32MP13x platforms
  2023-09-27  6:53   ` Patrice CHOTARD
@ 2023-09-27  7:26     ` Patrice CHOTARD
  0 siblings, 0 replies; 22+ messages in thread
From: Patrice CHOTARD @ 2023-09-27  7:26 UTC (permalink / raw)
  To: Gatien Chevallier, u-boot
  Cc: Patrick Delaunay, Heinrich Schuchardt, uboot-stm32, Sughosh Ganu



On 9/27/23 08:53, Patrice CHOTARD wrote:
> 
> 
> On 9/19/23 17:27, Gatien Chevallier wrote:
>> Default embed this configuration. If OP-TEE PTA RNG is exposed, it means
>> that the RNG is managed by the secure world. Therefore, the RNG node
>> should be disabled in the device tree as an access would be denied
>> by the hardware firewall.
>>
>> Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
>> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
>> ---
>> Changes in V2:
>> 	- Added Patrick's tag
>>
>>  configs/stm32mp13_defconfig | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/configs/stm32mp13_defconfig b/configs/stm32mp13_defconfig
>> index 82b62744f6..4a899c85de 100644
>> --- a/configs/stm32mp13_defconfig
>> +++ b/configs/stm32mp13_defconfig
>> @@ -65,6 +65,7 @@ CONFIG_DM_REGULATOR_GPIO=y
>>  CONFIG_DM_REGULATOR_SCMI=y
>>  CONFIG_RESET_SCMI=y
>>  CONFIG_DM_RNG=y
>> +CONFIG_RNG_STM32=y
>>  CONFIG_DM_RTC=y
>>  CONFIG_RTC_STM32=y
>>  CONFIG_SERIAL_RX_BUFFER=y
> Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
> 
> Thanks
> Patrice
> _______________________________________________
> Uboot-stm32 mailing list
> Uboot-stm32@st-md-mailman.stormreply.com
> https://st-md-mailman.stormreply.com/mailman/listinfo/uboot-stm32
Apply on stm32/next

Patrice

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Uboot-stm32] [PATCH v3 3/7] rng: stm32: Implement configurable RNG clock error detection
  2023-09-27  6:56   ` Patrice CHOTARD
@ 2023-09-27  7:26     ` Patrice CHOTARD
  0 siblings, 0 replies; 22+ messages in thread
From: Patrice CHOTARD @ 2023-09-27  7:26 UTC (permalink / raw)
  To: Gatien Chevallier, u-boot
  Cc: Patrick Delaunay, Heinrich Schuchardt, uboot-stm32, Sughosh Ganu



On 9/27/23 08:56, Patrice CHOTARD wrote:
> 
> 
> On 9/19/23 17:27, Gatien Chevallier wrote:
>> RNG clock error detection is now enabled if the "clock-error-detect"
>> property is set in the device tree.
>>
>> Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
>> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
>> ---
>> Changes in V2:
>> 	- Added Patrick's tag
>>
>>  drivers/rng/stm32_rng.c | 22 +++++++++++++++++-----
>>  1 file changed, 17 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/rng/stm32_rng.c b/drivers/rng/stm32_rng.c
>> index 89da78c6c8..ada5d92214 100644
>> --- a/drivers/rng/stm32_rng.c
>> +++ b/drivers/rng/stm32_rng.c
>> @@ -40,6 +40,7 @@ struct stm32_rng_plat {
>>  	struct clk clk;
>>  	struct reset_ctl rst;
>>  	const struct stm32_rng_data *data;
>> +	bool ced;
>>  };
>>  
>>  static int stm32_rng_read(struct udevice *dev, void *data, size_t len)
>> @@ -97,25 +98,34 @@ static int stm32_rng_init(struct stm32_rng_plat *pdata)
>>  
>>  	cr = readl(pdata->base + RNG_CR);
>>  
>> -	/* Disable CED */
>> -	cr |= RNG_CR_CED;
>>  	if (pdata->data->has_cond_reset) {
>>  		cr |= RNG_CR_CONDRST;
>> +		if (pdata->ced)
>> +			cr &= ~RNG_CR_CED;
>> +		else
>> +			cr |= RNG_CR_CED;
>>  		writel(cr, pdata->base + RNG_CR);
>>  		cr &= ~RNG_CR_CONDRST;
>> +		cr |= RNG_CR_RNGEN;
>>  		writel(cr, pdata->base + RNG_CR);
>>  		err = readl_poll_timeout(pdata->base + RNG_CR, cr,
>>  					 (!(cr & RNG_CR_CONDRST)), 10000);
>>  		if (err)
>>  			return err;
>> +	} else {
>> +		if (pdata->ced)
>> +			cr &= ~RNG_CR_CED;
>> +		else
>> +			cr |= RNG_CR_CED;
>> +
>> +		cr |= RNG_CR_RNGEN;
>> +
>> +		writel(cr, pdata->base + RNG_CR);
>>  	}
>>  
>>  	/* clear error indicators */
>>  	writel(0, pdata->base + RNG_SR);
>>  
>> -	cr |= RNG_CR_RNGEN;
>> -	writel(cr, pdata->base + RNG_CR);
>> -
>>  	err = readl_poll_timeout(pdata->base + RNG_SR, sr,
>>  				 sr & RNG_SR_DRDY, 10000);
>>  	return err;
>> @@ -165,6 +175,8 @@ static int stm32_rng_of_to_plat(struct udevice *dev)
>>  	if (err)
>>  		return err;
>>  
>> +	pdata->ced = dev_read_bool(dev, "clock-error-detect");
>> +
>>  	return 0;
>>  }
>>  
> Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
> 
> Thanks
> Patrice
> _______________________________________________
> Uboot-stm32 mailing list
> Uboot-stm32@st-md-mailman.stormreply.com
> https://st-md-mailman.stormreply.com/mailman/listinfo/uboot-stm32
Apply on stm32/next

Patrice

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v3 4/7] rng: stm32: add RNG clock frequency restraint
  2023-09-27  6:56   ` Patrice CHOTARD
@ 2023-09-27  7:26     ` Patrice CHOTARD
  0 siblings, 0 replies; 22+ messages in thread
From: Patrice CHOTARD @ 2023-09-27  7:26 UTC (permalink / raw)
  To: Gatien Chevallier, u-boot
  Cc: Patrick Delaunay, Sughosh Ganu, Heinrich Schuchardt, uboot-stm32



On 9/27/23 08:56, Patrice CHOTARD wrote:
> 
> 
> On 9/19/23 17:27, Gatien Chevallier wrote:
>> In order to ensure a good RNG quality and compatibility with
>> certified RNG configuration, add RNG clock frequency restraint.
>>
>> Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
>> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
>> ---
>> Changes in V2:
>> 	- Added Patrick's tag
>>
>>  drivers/rng/stm32_rng.c | 43 ++++++++++++++++++++++++++++++++++++-----
>>  1 file changed, 38 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/rng/stm32_rng.c b/drivers/rng/stm32_rng.c
>> index ada5d92214..f943acd7d2 100644
>> --- a/drivers/rng/stm32_rng.c
>> +++ b/drivers/rng/stm32_rng.c
>> @@ -18,10 +18,11 @@
>>  #include <linux/iopoll.h>
>>  #include <linux/kernel.h>
>>  
>> -#define RNG_CR		0x00
>> -#define RNG_CR_RNGEN	BIT(2)
>> -#define RNG_CR_CED	BIT(5)
>> -#define RNG_CR_CONDRST	BIT(30)
>> +#define RNG_CR			0x00
>> +#define RNG_CR_RNGEN		BIT(2)
>> +#define RNG_CR_CED		BIT(5)
>> +#define RNG_CR_CLKDIV_SHIFT	16
>> +#define RNG_CR_CONDRST		BIT(30)
>>  
>>  #define RNG_SR		0x04
>>  #define RNG_SR_SEIS	BIT(6)
>> @@ -31,7 +32,15 @@
>>  
>>  #define RNG_DR		0x08
>>  
>> +/*
>> + * struct stm32_rng_data - RNG compat data
>> + *
>> + * @max_clock_rate:	Max RNG clock frequency, in Hertz
>> + * @has_cond_reset:	True if conditionnal reset is supported
>> + *
>> + */
>>  struct stm32_rng_data {
>> +	uint max_clock_rate;
>>  	bool has_cond_reset;
>>  };
>>  
>> @@ -87,6 +96,26 @@ static int stm32_rng_read(struct udevice *dev, void *data, size_t len)
>>  	return 0;
>>  }
>>  
>> +static uint stm32_rng_clock_freq_restrain(struct stm32_rng_plat *pdata)
>> +{
>> +	ulong clock_rate = 0;
>> +	uint clock_div = 0;
>> +
>> +	clock_rate = clk_get_rate(&pdata->clk);
>> +
>> +	/*
>> +	 * Get the exponent to apply on the CLKDIV field in RNG_CR register.
>> +	 * No need to handle the case when clock-div > 0xF as it is physically
>> +	 * impossible.
>> +	 */
>> +	while ((clock_rate >> clock_div) > pdata->data->max_clock_rate)
>> +		clock_div++;
>> +
>> +	log_debug("RNG clk rate : %lu\n", clk_get_rate(&pdata->clk) >> clock_div);
>> +
>> +	return clock_div;
>> +}
>> +
>>  static int stm32_rng_init(struct stm32_rng_plat *pdata)
>>  {
>>  	int err;
>> @@ -99,7 +128,9 @@ static int stm32_rng_init(struct stm32_rng_plat *pdata)
>>  	cr = readl(pdata->base + RNG_CR);
>>  
>>  	if (pdata->data->has_cond_reset) {
>> -		cr |= RNG_CR_CONDRST;
>> +		uint clock_div = stm32_rng_clock_freq_restrain(pdata);
>> +
>> +		cr |= RNG_CR_CONDRST | (clock_div << RNG_CR_CLKDIV_SHIFT);
>>  		if (pdata->ced)
>>  			cr &= ~RNG_CR_CED;
>>  		else
>> @@ -186,10 +217,12 @@ static const struct dm_rng_ops stm32_rng_ops = {
>>  
>>  static const struct stm32_rng_data stm32mp13_rng_data = {
>>  	.has_cond_reset = true,
>> +	.max_clock_rate = 48000000,
>>  };
>>  
>>  static const struct stm32_rng_data stm32_rng_data = {
>>  	.has_cond_reset = false,
>> +	.max_clock_rate = 3000000,
>>  };
>>  
>>  static const struct udevice_id stm32_rng_match[] = {
> 
> Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
> 
> Thanks
> Patrice
Apply on stm32/next

Patrice

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v3 5/7] rng: stm32: add error concealment sequence
  2023-09-27  6:57   ` Patrice CHOTARD
@ 2023-09-27  7:26     ` Patrice CHOTARD
  0 siblings, 0 replies; 22+ messages in thread
From: Patrice CHOTARD @ 2023-09-27  7:26 UTC (permalink / raw)
  To: Gatien Chevallier, u-boot
  Cc: Patrick Delaunay, Sughosh Ganu, Heinrich Schuchardt, uboot-stm32



On 9/27/23 08:57, Patrice CHOTARD wrote:
> 
> 
> On 9/19/23 17:27, Gatien Chevallier wrote:
>> Seed errors can occur when using the hardware RNG. Implement the
>> sequences to handle them. This avoids irrecoverable RNG state.
>>
>> Try to conceal seed errors when possible. If, despite the error
>> concealing tries, a seed error is still present, then return an error.
>>
>> A clock error does not compromise the hardware block and data can
>> still be read from RNG_DR. Just warn that the RNG clock is too slow
>> and clear RNG_SR.
>>
>> Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
>> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
>> ---
>> Changes in V2:
>> 	- Added Patrick's tag
>>
>>  drivers/rng/stm32_rng.c | 163 ++++++++++++++++++++++++++++++++++------
>>  1 file changed, 140 insertions(+), 23 deletions(-)
>>
>> diff --git a/drivers/rng/stm32_rng.c b/drivers/rng/stm32_rng.c
>> index f943acd7d2..b1a790b217 100644
>> --- a/drivers/rng/stm32_rng.c
>> +++ b/drivers/rng/stm32_rng.c
>> @@ -32,6 +32,8 @@
>>  
>>  #define RNG_DR		0x08
>>  
>> +#define RNG_NB_RECOVER_TRIES	3
>> +
>>  /*
>>   * struct stm32_rng_data - RNG compat data
>>   *
>> @@ -52,45 +54,160 @@ struct stm32_rng_plat {
>>  	bool ced;
>>  };
>>  
>> +/*
>> + * Extracts from the STM32 RNG specification when RNG supports CONDRST.
>> + *
>> + * When a noise source (or seed) error occurs, the RNG stops generating
>> + * random numbers and sets to “1” both SEIS and SECS bits to indicate
>> + * that a seed error occurred. (...)
>> + *
>> + * 1. Software reset by writing CONDRST at 1 and at 0 (see bitfield
>> + * description for details). This step is needed only if SECS is set.
>> + * Indeed, when SEIS is set and SECS is cleared it means RNG performed
>> + * the reset automatically (auto-reset).
>> + * 2. If SECS was set in step 1 (no auto-reset) wait for CONDRST
>> + * to be cleared in the RNG_CR register, then confirm that SEIS is
>> + * cleared in the RNG_SR register. Otherwise just clear SEIS bit in
>> + * the RNG_SR register.
>> + * 3. If SECS was set in step 1 (no auto-reset) wait for SECS to be
>> + * cleared by RNG. The random number generation is now back to normal.
>> + */
>> +static int stm32_rng_conceal_seed_error_cond_reset(struct stm32_rng_plat *pdata)
>> +{
>> +	u32 sr = readl_relaxed(pdata->base + RNG_SR);
>> +	u32 cr = readl_relaxed(pdata->base + RNG_CR);
>> +	int err;
>> +
>> +	if (sr & RNG_SR_SECS) {
>> +		/* Conceal by resetting the subsystem (step 1.) */
>> +		writel_relaxed(cr | RNG_CR_CONDRST, pdata->base + RNG_CR);
>> +		writel_relaxed(cr & ~RNG_CR_CONDRST, pdata->base + RNG_CR);
>> +	} else {
>> +		/* RNG auto-reset (step 2.) */
>> +		writel_relaxed(sr & ~RNG_SR_SEIS, pdata->base + RNG_SR);
>> +		return 0;
>> +	}
>> +
>> +	err = readl_relaxed_poll_timeout(pdata->base + RNG_SR, sr, !(sr & RNG_CR_CONDRST), 100000);
>> +	if (err) {
>> +		log_err("%s: timeout %x\n", __func__, sr);
>> +		return err;
>> +	}
>> +
>> +	/* Check SEIS is cleared (step 2.) */
>> +	if (readl_relaxed(pdata->base + RNG_SR) & RNG_SR_SEIS)
>> +		return -EINVAL;
>> +
>> +	err = readl_relaxed_poll_timeout(pdata->base + RNG_SR, sr, !(sr & RNG_SR_SECS), 100000);
>> +	if (err) {
>> +		log_err("%s: timeout %x\n", __func__, sr);
>> +		return err;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +/*
>> + * Extracts from the STM32 RNG specification, when CONDRST is not supported
>> + *
>> + * When a noise source (or seed) error occurs, the RNG stops generating
>> + * random numbers and sets to “1” both SEIS and SECS bits to indicate
>> + * that a seed error occurred. (...)
>> + *
>> + * The following sequence shall be used to fully recover from a seed
>> + * error after the RNG initialization:
>> + * 1. Clear the SEIS bit by writing it to “0”.
>> + * 2. Read out 12 words from the RNG_DR register, and discard each of
>> + * them in order to clean the pipeline.
>> + * 3. Confirm that SEIS is still cleared. Random number generation is
>> + * back to normal.
>> + */
>> +static int stm32_rng_conceal_seed_error_sw_reset(struct stm32_rng_plat *pdata)
>> +{
>> +	uint i = 0;
>> +	u32 sr = readl_relaxed(pdata->base + RNG_SR);
>> +
>> +	writel_relaxed(sr & ~RNG_SR_SEIS, pdata->base + RNG_SR);
>> +
>> +	for (i = 12; i != 0; i--)
>> +		(void)readl_relaxed(pdata->base + RNG_DR);
>> +
>> +	if (readl_relaxed(pdata->base + RNG_SR) & RNG_SR_SEIS)
>> +		return -EINVAL;
>> +
>> +	return 0;
>> +}
>> +
>> +static int stm32_rng_conceal_seed_error(struct stm32_rng_plat *pdata)
>> +{
>> +	log_debug("Concealing RNG seed error\n");
>> +
>> +	if (pdata->data->has_cond_reset)
>> +		return stm32_rng_conceal_seed_error_cond_reset(pdata);
>> +	else
>> +		return stm32_rng_conceal_seed_error_sw_reset(pdata);
>> +};
>> +
>>  static int stm32_rng_read(struct udevice *dev, void *data, size_t len)
>>  {
>> -	int retval, i;
>> -	u32 sr, count, reg;
>> +	int retval;
>> +	u32 sr, reg;
>>  	size_t increment;
>>  	struct stm32_rng_plat *pdata = dev_get_plat(dev);
>> +	uint tries = 0;
>>  
>>  	while (len > 0) {
>>  		retval = readl_poll_timeout(pdata->base + RNG_SR, sr,
>> -					    sr & RNG_SR_DRDY, 10000);
>> -		if (retval)
>> +					    sr, 10000);
>> +		if (retval) {
>> +			log_err("%s: Timeout RNG no data",  __func__);
>>  			return retval;
>> +		}
>>  
>> -		if (sr & (RNG_SR_SEIS | RNG_SR_SECS)) {
>> -			/* As per SoC TRM */
>> -			clrbits_le32(pdata->base + RNG_SR, RNG_SR_SEIS);
>> -			for (i = 0; i < 12; i++)
>> -				readl(pdata->base + RNG_DR);
>> -			if (readl(pdata->base + RNG_SR) & RNG_SR_SEIS) {
>> -				log_err("RNG Noise");
>> -				return -EIO;
>> +		if (sr != RNG_SR_DRDY) {
>> +			if (sr & RNG_SR_SEIS) {
>> +				retval = stm32_rng_conceal_seed_error(pdata);
>> +				tries++;
>> +				if (retval || tries > RNG_NB_RECOVER_TRIES) {
>> +					log_err("%s: Couldn't recover from seed error",  __func__);
>> +					return -ENOTRECOVERABLE;
>> +				}
>> +
>> +				/* Start again */
>> +				continue;
>> +			}
>> +
>> +			if (sr & RNG_SR_CEIS) {
>> +				log_info("RNG clock too slow");
>> +				writel_relaxed(0, pdata->base + RNG_SR);
>>  			}
>> -			/* start again */
>> -			continue;
>>  		}
>>  
>>  		/*
>>  		 * Once the DRDY bit is set, the RNG_DR register can
>> -		 * be read four consecutive times.
>> +		 * be read up to four consecutive times.
>>  		 */
>> -		count = 4;
>> -		while (len && count) {
>> -			reg = readl(pdata->base + RNG_DR);
>> -			memcpy(data, &reg, min(len, sizeof(u32)));
>> -			increment = min(len, sizeof(u32));
>> -			data += increment;
>> -			len -= increment;
>> -			count--;
>> +		reg = readl(pdata->base + RNG_DR);
>> +		/* Late seed error case: DR being 0 is an error status */
>> +		if (!reg) {
>> +			retval = stm32_rng_conceal_seed_error(pdata);
>> +			tries++;
>> +
>> +			if (retval || tries > RNG_NB_RECOVER_TRIES) {
>> +				log_err("%s: Couldn't recover from seed error",  __func__);
>> +				return -ENOTRECOVERABLE;
>> +			}
>> +
>> +			/* Start again */
>> +			continue;
>>  		}
>> +
>> +		increment = min(len, sizeof(u32));
>> +		memcpy(data, &reg, increment);
>> +		data += increment;
>> +		len -= increment;
>> +
>> +		tries = 0;
>>  	}
>>  
>>  	return 0;
> 
> Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
> 
> Thanks
> Patrice
Apply on stm32/next

Patrice

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [Uboot-stm32] [PATCH v3 6/7] rng: stm32: Implement custom RNG configuration support
  2023-09-27  7:11   ` Patrice CHOTARD
@ 2023-09-27  7:27     ` Patrice CHOTARD
  0 siblings, 0 replies; 22+ messages in thread
From: Patrice CHOTARD @ 2023-09-27  7:27 UTC (permalink / raw)
  To: Gatien Chevallier, u-boot
  Cc: Patrick Delaunay, Heinrich Schuchardt, uboot-stm32, Sughosh Ganu



On 9/27/23 09:11, Patrice CHOTARD wrote:
> 
> 
> On 9/19/23 17:27, Gatien Chevallier wrote:
>> STM32 RNG configuration should best fit the requirements of the
>> platform. Therefore, put a platform-specific RNG configuration
>> field in the platform data. Default RNG configuration for STM32MP13
>> is the NIST certified configuration [1].
>>
>> While there, fix and the RNG init sequence to support all RNG
>> versions.
>>
>> [1] https://csrc.nist.gov/projects/cryptographic-module-validation-program/entropy-validations/certificate/53
>>
>> Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
>> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
>> ---
>> Changes in V2:
>> 	- Added Patrick's tag
>>
>>  drivers/rng/stm32_rng.c | 54 ++++++++++++++++++++++++++++++++++++++---
>>  1 file changed, 51 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/rng/stm32_rng.c b/drivers/rng/stm32_rng.c
>> index b1a790b217..c397b4d95c 100644
>> --- a/drivers/rng/stm32_rng.c
>> +++ b/drivers/rng/stm32_rng.c
>> @@ -21,8 +21,15 @@
>>  #define RNG_CR			0x00
>>  #define RNG_CR_RNGEN		BIT(2)
>>  #define RNG_CR_CED		BIT(5)
>> +#define RNG_CR_CONFIG1		GENMASK(11, 8)
>> +#define RNG_CR_NISTC		BIT(12)
>> +#define RNG_CR_CONFIG2		GENMASK(15, 13)
>>  #define RNG_CR_CLKDIV_SHIFT	16
>> +#define RNG_CR_CLKDIV		GENMASK(19, 16)
>> +#define RNG_CR_CONFIG3		GENMASK(25, 20)
>>  #define RNG_CR_CONDRST		BIT(30)
>> +#define RNG_CR_ENTROPY_SRC_MASK	(RNG_CR_CONFIG1 | RNG_CR_NISTC | RNG_CR_CONFIG2 | RNG_CR_CONFIG3)
>> +#define RNG_CR_CONFIG_MASK	(RNG_CR_ENTROPY_SRC_MASK | RNG_CR_CED | RNG_CR_CLKDIV)
>>  
>>  #define RNG_SR		0x04
>>  #define RNG_SR_SEIS	BIT(6)
>> @@ -32,17 +39,28 @@
>>  
>>  #define RNG_DR		0x08
>>  
>> +#define RNG_NSCR		0x0C
>> +#define RNG_NSCR_MASK		GENMASK(17, 0)
>> +
>> +#define RNG_HTCR	0x10
>> +
>>  #define RNG_NB_RECOVER_TRIES	3
>>  
>>  /*
>>   * struct stm32_rng_data - RNG compat data
>>   *
>>   * @max_clock_rate:	Max RNG clock frequency, in Hertz
>> + * @cr:			Entropy source configuration
>> + * @nscr:		Noice sources control configuration
>> + * @htcr:		Health tests configuration
>>   * @has_cond_reset:	True if conditionnal reset is supported
>>   *
>>   */
>>  struct stm32_rng_data {
>>  	uint max_clock_rate;
>> +	u32 cr;
>> +	u32 nscr;
>> +	u32 htcr;
>>  	bool has_cond_reset;
>>  };
>>  
>> @@ -244,28 +262,48 @@ static int stm32_rng_init(struct stm32_rng_plat *pdata)
>>  
>>  	cr = readl(pdata->base + RNG_CR);
>>  
>> -	if (pdata->data->has_cond_reset) {
>> +	/*
>> +	 * Keep default RNG configuration if none was specified, that is when conf.cr is set to 0.
>> +	 */
>> +	if (pdata->data->has_cond_reset && pdata->data->cr) {
>>  		uint clock_div = stm32_rng_clock_freq_restrain(pdata);
>>  
>> -		cr |= RNG_CR_CONDRST | (clock_div << RNG_CR_CLKDIV_SHIFT);
>> +		cr &= ~RNG_CR_CONFIG_MASK;
>> +		cr |= RNG_CR_CONDRST | (pdata->data->cr & RNG_CR_ENTROPY_SRC_MASK) |
>> +		      (clock_div << RNG_CR_CLKDIV_SHIFT);
>>  		if (pdata->ced)
>>  			cr &= ~RNG_CR_CED;
>>  		else
>>  			cr |= RNG_CR_CED;
>>  		writel(cr, pdata->base + RNG_CR);
>> +
>> +		/* Health tests and noise control registers */
>> +		writel_relaxed(pdata->data->htcr, pdata->base + RNG_HTCR);
>> +		writel_relaxed(pdata->data->nscr & RNG_NSCR_MASK, pdata->base + RNG_NSCR);
>> +
>>  		cr &= ~RNG_CR_CONDRST;
>>  		cr |= RNG_CR_RNGEN;
>>  		writel(cr, pdata->base + RNG_CR);
>>  		err = readl_poll_timeout(pdata->base + RNG_CR, cr,
>>  					 (!(cr & RNG_CR_CONDRST)), 10000);
>> -		if (err)
>> +		if (err) {
>> +			log_err("%s: Timeout!",  __func__);
>>  			return err;
>> +		}
>>  	} else {
>> +		if (pdata->data->has_cond_reset)
>> +			cr |= RNG_CR_CONDRST;
>> +
>>  		if (pdata->ced)
>>  			cr &= ~RNG_CR_CED;
>>  		else
>>  			cr |= RNG_CR_CED;
>>  
>> +		writel(cr, pdata->base + RNG_CR);
>> +
>> +		if (pdata->data->has_cond_reset)
>> +			cr &= ~RNG_CR_CONDRST;
>> +
>>  		cr |= RNG_CR_RNGEN;
>>  
>>  		writel(cr, pdata->base + RNG_CR);
>> @@ -276,6 +314,9 @@ static int stm32_rng_init(struct stm32_rng_plat *pdata)
>>  
>>  	err = readl_poll_timeout(pdata->base + RNG_SR, sr,
>>  				 sr & RNG_SR_DRDY, 10000);
>> +	if (err)
>> +		log_err("%s: Timeout!",  __func__);
>> +
>>  	return err;
>>  }
>>  
>> @@ -335,11 +376,18 @@ static const struct dm_rng_ops stm32_rng_ops = {
>>  static const struct stm32_rng_data stm32mp13_rng_data = {
>>  	.has_cond_reset = true,
>>  	.max_clock_rate = 48000000,
>> +	.htcr = 0x969D,
>> +	.nscr = 0x2B5BB,
>> +	.cr = 0xF00D00,
>>  };
>>  
>>  static const struct stm32_rng_data stm32_rng_data = {
>>  	.has_cond_reset = false,
>>  	.max_clock_rate = 3000000,
>> +	/* Not supported */
>> +	.htcr = 0,
>> +	.nscr = 0,
>> +	.cr = 0,
>>  };
>>  
>>  static const struct udevice_id stm32_rng_match[] = {
> Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
> 
> Thanks
> Patrice
> _______________________________________________
> Uboot-stm32 mailing list
> Uboot-stm32@st-md-mailman.stormreply.com
> https://st-md-mailman.stormreply.com/mailman/listinfo/uboot-stm32
Apply on stm32/next

Patrice

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH v3 7/7] ARM: dts: stm32: add RNG node for STM32MP13x platforms
  2023-09-27  7:11   ` Patrice CHOTARD
@ 2023-09-27  7:27     ` Patrice CHOTARD
  0 siblings, 0 replies; 22+ messages in thread
From: Patrice CHOTARD @ 2023-09-27  7:27 UTC (permalink / raw)
  To: Gatien Chevallier, u-boot
  Cc: Patrick Delaunay, Sughosh Ganu, Heinrich Schuchardt, uboot-stm32



On 9/27/23 09:11, Patrice CHOTARD wrote:
> 
> 
> On 9/19/23 17:27, Gatien Chevallier wrote:
>> Add RNG node for STM32MP13x platforms.
>>
>> Signed-off-by: Gatien Chevallier <gatien.chevallier@foss.st.com>
>> Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
>> ---
>> Changes in V2:
>> 	- Added Patrick's tag
>>
>>  arch/arm/dts/stm32mp131.dtsi | 8 ++++++++
>>  1 file changed, 8 insertions(+)
>>
>> diff --git a/arch/arm/dts/stm32mp131.dtsi b/arch/arm/dts/stm32mp131.dtsi
>> index d23bbc3639..bd7285053d 100644
>> --- a/arch/arm/dts/stm32mp131.dtsi
>> +++ b/arch/arm/dts/stm32mp131.dtsi
>> @@ -1208,6 +1208,14 @@
>>  			};
>>  		};
>>  
>> +		rng: rng@54004000 {
>> +			compatible = "st,stm32mp13-rng";
>> +			reg = <0x54004000 0x400>;
>> +			clocks = <&rcc RNG1_K>;
>> +			resets = <&rcc RNG1_R>;
>> +			status = "disabled";
>> +		};
>> +
>>  		mdma: dma-controller@58000000 {
>>  			compatible = "st,stm32h7-mdma";
>>  			reg = <0x58000000 0x1000>;
> Reviewed-by: Patrice Chotard <patrice.chotard@foss.st.com>
> 
> Thanks
> Patrice
Apply on stm32/next

Patrice

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2023-09-27  7:27 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-19 15:27 [PATCH v3 0/7] rng: stm32: support STM32MP13x platforms Gatien Chevallier
2023-09-19 15:27 ` [PATCH v3 1/7] rng: stm32: rename STM32 RNG driver Gatien Chevallier
2023-09-27  6:52   ` Patrice CHOTARD
2023-09-27  7:25     ` Patrice CHOTARD
2023-09-19 15:27 ` [PATCH v3 2/7] configs: default activate CONFIG_RNG_STM32 for STM32MP13x platforms Gatien Chevallier
2023-09-27  6:53   ` Patrice CHOTARD
2023-09-27  7:26     ` [Uboot-stm32] " Patrice CHOTARD
2023-09-19 15:27 ` [PATCH v3 3/7] rng: stm32: Implement configurable RNG clock error detection Gatien Chevallier
2023-09-27  6:56   ` Patrice CHOTARD
2023-09-27  7:26     ` [Uboot-stm32] " Patrice CHOTARD
2023-09-19 15:27 ` [PATCH v3 4/7] rng: stm32: add RNG clock frequency restraint Gatien Chevallier
2023-09-27  6:56   ` Patrice CHOTARD
2023-09-27  7:26     ` Patrice CHOTARD
2023-09-19 15:27 ` [PATCH v3 5/7] rng: stm32: add error concealment sequence Gatien Chevallier
2023-09-27  6:57   ` Patrice CHOTARD
2023-09-27  7:26     ` Patrice CHOTARD
2023-09-19 15:27 ` [PATCH v3 6/7] rng: stm32: Implement custom RNG configuration support Gatien Chevallier
2023-09-27  7:11   ` Patrice CHOTARD
2023-09-27  7:27     ` [Uboot-stm32] " Patrice CHOTARD
2023-09-19 15:27 ` [PATCH v3 7/7] ARM: dts: stm32: add RNG node for STM32MP13x platforms Gatien Chevallier
2023-09-27  7:11   ` Patrice CHOTARD
2023-09-27  7:27     ` Patrice CHOTARD

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox