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 <[email protected]>
> ---
>  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 <[email protected]>
> + *
> + */
> +
> +#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
> 

Attachment: signature.asc
Description: PGP signature

Reply via email to