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 > --- > 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 > + * > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#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 >