[PATCH 4/8] rng: add Microchip PolarFire SoC hardware RNG driver
Conor Dooley
conor at kernel.org
Wed Jul 1 11:55:13 CEST 2026
On Thu, Jun 25, 2026 at 01:23:21PM +0100, Jamie Gibbons wrote:
> Add a U-Boot RNG driver for Microchip's PolarFire SoC (MPFS). The
> hardware RNG is accessed indirectly via the MPFS system controller using
> the mailbox interface.
>
> The driver implements the UCLASS_RNG interface, requesting random data
> from the system controller and returning it to the caller.
>
> This allows use of the PolarFire SoC hardware RNG via the
> standard 'rng' command and DM RNG API.
>
> Signed-off-by: Jamie Gibbons <jamie.gibbons at microchip.com>
> ---
> configs/microchip_mpfs_generic_defconfig | 1 +
> drivers/rng/Kconfig | 7 ++
> drivers/rng/Makefile | 1 +
> drivers/rng/mpfs_rng.c | 106 +++++++++++++++++++++++
> 4 files changed, 115 insertions(+)
> create mode 100644 drivers/rng/mpfs_rng.c
>
> diff --git a/configs/microchip_mpfs_generic_defconfig b/configs/microchip_mpfs_generic_defconfig
> index 973ed09fa87..66acaad7e9b 100644
> --- a/configs/microchip_mpfs_generic_defconfig
> +++ b/configs/microchip_mpfs_generic_defconfig
> @@ -30,3 +30,4 @@ CONFIG_ENV_RELOC_GD_ENV_ADDR=y
> CONFIG_BOOTP_SEND_HOSTNAME=y
> CONFIG_DM_MTD=y
> CONFIG_SYSRESET=y
> +CONFIG_DM_RNG=y
Not entirely sure if this change should be in this patch, but turning on
RNG_MPFS seems like a good idea to me, not just DM_RNG?
> diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig
> index 19b2b707677..856ffda2f5e 100644
> --- a/drivers/rng/Kconfig
> +++ b/drivers/rng/Kconfig
> @@ -23,6 +23,13 @@ config RNG_MESON
> Enable support for hardware random number generator
> of Amlogic Meson SoCs.
>
> +config RNG_MPFS
> + tristate "Microchip PolarFire SoC Random Number Generator support"
> + depends on DM_RNG && MPFS_SYSCONTROLLER
> + help
> + Enable support for hardware random number generator
> + of Microchip's PolarFire SoCs.
> +
> config RNG_SANDBOX
> bool "Sandbox random number generator"
> depends on SANDBOX
> diff --git a/drivers/rng/Makefile b/drivers/rng/Makefile
> index 30c58272d41..50622d4705f 100644
> --- a/drivers/rng/Makefile
> +++ b/drivers/rng/Makefile
> @@ -5,6 +5,7 @@
>
> obj-$(CONFIG_$(PHASE_)DM_RNG) += rng-uclass.o
> obj-$(CONFIG_RNG_MESON) += meson-rng.o
> +obj-$(CONFIG_RNG_MPFS) += mpfs_rng.o
> obj-$(CONFIG_RNG_SANDBOX) += sandbox_rng.o
> obj-$(CONFIG_RNG_MSM) += msm_rng.o
> obj-$(CONFIG_RNG_NPCM) += npcm_rng.o
> diff --git a/drivers/rng/mpfs_rng.c b/drivers/rng/mpfs_rng.c
> new file mode 100644
> index 00000000000..61bd520d8a2
> --- /dev/null
> +++ b/drivers/rng/mpfs_rng.c
> @@ -0,0 +1,106 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Microchip's PolarFire SoC (MPFS) System Controller Driver
> + *
> + * Copyright (C) 2026 Microchip Technology Inc. All rights reserved.
> + *
> + * Author: Jamie Gibbons <jamie.gibbons at microchip.com>
> + *
> + */
> +
> +#include <dm.h>
> +#include <dm/device.h>
> +#include <dm/device_compat.h>
> +#include <dm/devres.h>
> +#include <linux/err.h>
> +#include <linux/errno.h>
> +#include <linux/io.h>
> +#include <linux/printk.h>
> +#include <mailbox.h>
> +#include <malloc.h>
> +#include <mpfs-mailbox.h>
> +#include <rng.h>
> +#include <string.h>
> +
> +#define CMD_OPCODE 0x21
> +#define CMD_DATA_SIZE 0U
> +#define CMD_DATA NULL
> +#define MBOX_OFFSET 0U
> +#define RESP_OFFSET 0U
> +#define RNG_RESP_BYTES 32U
> +
> +/**
> + * struct mpfs_rng_priv - Structure representing System Controller data.
> + * @mpfs_syscontroller_priv: System Controller
> + */
> +struct mpfs_rng_priv {
> + struct mpfs_syscontroller_priv *sys_controller;
> +};
> +
> +static int mpfs_rng_read(struct udevice *dev, void *data, size_t len)
> +{
> + struct mpfs_rng_priv *rng_priv = dev_get_priv(dev);
> + u32 response_msg[RNG_RESP_BYTES / sizeof(u32)];
> + size_t count = 0, copy_size;
> + int ret;
> +
> + struct mpfs_mss_response response = {
> + .resp_status = 0U,
> + .resp_msg = (u32*)response_msg,
> + .resp_size = RNG_RESP_BYTES,
> + };
> + struct mpfs_mss_msg msg = {
> + .cmd_opcode = CMD_OPCODE,
> + .cmd_data_size = CMD_DATA_SIZE,
> + .response = &response,
> + .cmd_data = CMD_DATA,
> + .mbox_offset = MBOX_OFFSET,
> + .resp_offset = RESP_OFFSET,
> + };
> +
> + while (count < len) {
> + ret = mpfs_syscontroller_run_service(rng_priv->sys_controller, &msg);
> + if (ret == -EBUSY)
> + return 0;
> + if (ret)
> + return ret;
With patch 7, isn't this redundant because there's no longer any chance
of getting an -EBUSY anymore?
> +
> + ret = mpfs_syscontroller_recv_response(rng_priv->sys_controller, &msg, 1000);
> + if (ret == -EBUSY)
> + return 0;
> + if (ret)
> + return ret;
> +
> + copy_size = (len - count > RNG_RESP_BYTES) ? RNG_RESP_BYTES : (len - count);
> + memcpy((u8 *)data + count, response_msg, copy_size);
> + count += copy_size;
> + }
> +
> + return len;
> +}
> +
> +static int mpfs_rng_probe(struct udevice *dev)
> +{
> + struct mpfs_rng_priv *rng_priv = dev_get_priv(dev);
> +
> + rng_priv->sys_controller = mpfs_syscontroller_get(dev->parent);
> + if (IS_ERR(rng_priv->sys_controller)) {
> + dev_err(dev, "Failed to get system controller\n");
> + return PTR_ERR(rng_priv->sys_controller);
> + }
> +
> + dev_info(dev, "Registered MPFS hwrng\n");
This seems like a development printout that can be dropped?
Cheers,
Conor.
> + return 0;
> +}
> +
> +static const struct dm_rng_ops mpfs_rng_ops = {
> + .read = mpfs_rng_read,
> +};
> +
> +U_BOOT_DRIVER(mpfs_rng) = {
> + .name = "mpfs_rng",
> + .id = UCLASS_RNG,
> + .probe = mpfs_rng_probe,
> + .priv_auto = sizeof(struct mpfs_rng_priv),
> + .ops = &mpfs_rng_ops,
> +};
> --
> 2.43.0
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <https://lists.denx.de/pipermail/u-boot/attachments/20260701/245b05cb/attachment.sig>
More information about the U-Boot
mailing list