Am 29. September 2026 00:43:37 MESZ schrieb Vitaliy Sochnev 
<[email protected]>:
>Port the Linux driver for the True Random Number Generator found on
>Airoha EN7581/AN7581 SoCs to the U-Boot driver model.
>
>The Linux driver waits for an interrupt to learn that the startup
>health test finished. U-Boot has no interrupts, so the TRNG interrupt
>is kept masked and RST_STARTUP_TEST_DONE is polled instead.
>
>U-Boot can then provide /chosen/kaslr-seed, which KASLR requires.
>
>Signed-off-by: Vitaliy Sochnev <[email protected]>
>---
>
>Notes:
>    The first posting on 2026-09-20 was held by list moderation (non-member
>    post) and never reached the list. Resent to the current list address.
>
> drivers/rng/Kconfig      |   7 ++
> drivers/rng/Makefile     |   1 +
> drivers/rng/airoha-rng.c | 136 +++++++++++++++++++++++++++++++++++++++
> 3 files changed, 144 insertions(+)
> create mode 100644 drivers/rng/airoha-rng.c
>
>diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig
>index bacb02630..3f829fccf 100644
>--- a/drivers/rng/Kconfig
>+++ b/drivers/rng/Kconfig
>@@ -140,4 +140,11 @@ config RNG_EXYNOS
>         case the LDFW (Loadable Firmware) has to be loaded first, as it
>         actually implements TRNG SMC calls.
> 
>+config RNG_AIROHA
>+      bool "Airoha True Random Number Generator support"
>+      depends on DM_RNG && ARCH_AIROHA

This DM_RNG duplicates the if condition. Please, remove the redundant 
constraint.

The entries once were alphabetically sorted.

>+      help
>+        Enable support for the True Random Number Generator (TRNG) found
>+        on Airoha EN7581/AN7581 SoCs.
>+
> endif
>diff --git a/drivers/rng/Makefile b/drivers/rng/Makefile
>index 50622d470..c005231b6 100644
>--- a/drivers/rng/Makefile
>+++ b/drivers/rng/Makefile
>@@ -20,3 +20,4 @@ obj-$(CONFIG_TPM_RNG) += tpm_rng.o
> obj-$(CONFIG_RNG_JH7110) += jh7110_rng.o
> obj-$(CONFIG_RNG_TURRIS_RWTM) += turris_rwtm_rng.o
> obj-$(CONFIG_RNG_EXYNOS) += exynos-trng.o
>+obj-$(CONFIG_RNG_AIROHA) += airoha-rng.o

Same here.

Best regards

Heinrich

>diff --git a/drivers/rng/airoha-rng.c b/drivers/rng/airoha-rng.c
>new file mode 100644
>index 000000000..a94161ad2
>--- /dev/null
>+++ b/drivers/rng/airoha-rng.c
>@@ -0,0 +1,136 @@
>+// SPDX-License-Identifier: GPL-2.0
>+/*
>+ * Airoha True Random Number Generator driver
>+ *
>+ * Ported from the Linux driver drivers/char/hw_random/airoha-trng.c
>+ *
>+ * Copyright (C) 2024 Christian Marangi <[email protected]>
>+ */
>+
>+#include <dm.h>
>+#include <rng.h>
>+#include <dm/device_compat.h>
>+#include <asm/io.h>
>+#include <linux/bitfield.h>
>+#include <linux/bitops.h>
>+#include <linux/iopoll.h>
>+#include <linux/string.h>
>+
>+#define TRNG_IP_RDY                   0x800
>+#define   CNT_TRANS                   GENMASK(15, 8)
>+#define   SAMPLE_RDY                  BIT(0)
>+#define TRNG_NS_SEK_AND_DAT_EN                0x804
>+#define   RNG_EN                      BIT(31)
>+#define   RAW_DATA_EN                 BIT(16)
>+#define TRNG_HEALTH_TEST_SW_RST               0x808
>+#define   SW_RST                      BIT(0) /* Active High */
>+#define TRNG_INTR_EN                  0x818
>+#define   INTR_MASK                   BIT(16)
>+#define   RST_STARTUP_INITR_EN                BIT(0)
>+#define TRNG_HEALTH_TEST_STATUS               0x824
>+#define   RST_STARTUP_TEST_DONE               BIT(18)
>+#define   RST_STARTUP_AP_TEST_FAIL    BIT(17)
>+#define   RST_STARTUP_RC_TEST_FAIL    BIT(16)
>+#define   RAW_DATA_VALID              BIT(7)
>+#define TRNG_RAW_DATA_OUT             0x828
>+
>+#define TRNG_CNT_TRANS_VALID          0x80
>+#define TRNG_TIMEOUT_US                       100000
>+
>+struct airoha_trng {
>+      void __iomem *base;
>+};
>+
>+static int airoha_trng_read(struct udevice *dev, void *data, size_t len)
>+{
>+      struct airoha_trng *trng = dev_get_priv(dev);
>+      u8 *buf = data;
>+
>+      while (len) {
>+              size_t step = min(len, sizeof(u32));
>+              u32 status, val;
>+              int ret;
>+
>+              ret = readl_poll_timeout(trng->base + TRNG_HEALTH_TEST_STATUS,
>+                                       status, status & RAW_DATA_VALID,
>+                                       TRNG_TIMEOUT_US);
>+              if (ret) {
>+                      dev_err(dev, "Timeout waiting for TRNG RAW Data 
>valid\n");
>+                      return ret;
>+              }
>+
>+              val = readl(trng->base + TRNG_RAW_DATA_OUT);
>+              memcpy(buf, &val, step);
>+
>+              buf += step;
>+              len -= step;
>+      }
>+
>+      return 0;
>+}
>+
>+static int airoha_trng_probe(struct udevice *dev)
>+{
>+      struct airoha_trng *trng = dev_get_priv(dev);
>+      u32 val;
>+      int ret;
>+
>+      trng->base = dev_read_addr_ptr(dev);
>+      if (!trng->base)
>+              return -EINVAL;
>+
>+      /* No interrupts in U-Boot: keep the TRNG one masked and poll instead */
>+      val = readl(trng->base + TRNG_INTR_EN);
>+      val |= INTR_MASK | RST_STARTUP_INITR_EN;
>+      writel(val, trng->base + TRNG_INTR_EN);
>+
>+      val = readl(trng->base + TRNG_NS_SEK_AND_DAT_EN);
>+      val |= RAW_DATA_EN | RNG_EN;
>+      writel(val, trng->base + TRNG_NS_SEK_AND_DAT_EN);
>+
>+      /* Health Test runs only on the transition out of SW Reset */
>+      writel(SW_RST, trng->base + TRNG_HEALTH_TEST_SW_RST);
>+      writel(0, trng->base + TRNG_HEALTH_TEST_SW_RST);
>+
>+      ret = readl_poll_timeout(trng->base + TRNG_HEALTH_TEST_STATUS, val,
>+                               val & RST_STARTUP_TEST_DONE, TRNG_TIMEOUT_US);
>+      if (ret) {
>+              dev_err(dev, "Timeout waiting for Health Check\n");
>+              return ret;
>+      }
>+
>+      if (val & (RST_STARTUP_AP_TEST_FAIL | RST_STARTUP_RC_TEST_FAIL)) {
>+              dev_err(dev, "Health Check fail: %s test fail\n",
>+                      val & RST_STARTUP_AP_TEST_FAIL ? "AP" : "RC");
>+              return -EIO;
>+      }
>+
>+      ret = readl_poll_timeout(trng->base + TRNG_IP_RDY, val,
>+                               val & SAMPLE_RDY &&
>+                               FIELD_GET(CNT_TRANS, val) == 
>TRNG_CNT_TRANS_VALID,
>+                               TRNG_TIMEOUT_US);
>+      if (ret) {
>+              dev_err(dev, "Timeout waiting for IP ready\n");
>+              return ret;
>+      }
>+
>+      return 0;
>+}
>+
>+static const struct dm_rng_ops airoha_trng_ops = {
>+      .read = airoha_trng_read,
>+};
>+
>+static const struct udevice_id airoha_trng_match[] = {
>+      { .compatible = "airoha,en7581-trng" },
>+      { }
>+};
>+
>+U_BOOT_DRIVER(airoha_trng) = {
>+      .name = "airoha-trng",
>+      .id = UCLASS_RNG,
>+      .of_match = airoha_trng_match,
>+      .ops = &airoha_trng_ops,
>+      .probe = airoha_trng_probe,
>+      .priv_auto = sizeof(struct airoha_trng),
>+};
>
>base-commit: f61f50a79dab97c8a4109ee9c15b90bf6157d4e8

Reply via email to