[PATCH v1] drivers: rng: add check status bit feature

Alexey Romanov AVRomanov at sberdevices.ru
Fri Jun 23 12:53:43 CEST 2023


Hello!

On Thu, Jun 22, 2023 at 06:18:28PM +0200, neil.armstrong at linaro.org wrote:
> Hi,
> 
> On 21/06/2023 12:24, Alexey Romanov wrote:
> > For some Amlogic SOC's, the mechanism for obtain a random number
> > has been changed. For example, S4 now uses a status bit wait algo.
> 
> Thanks for the change, but could you add this first in Linux with the
> associated bindings update and DT changes then port it to U-boot ?
> 
> Thanks,
> Neil
> 
> > 
> > Signed-off-by: Alexey Romanov <avromanov at sberdevices.ru>
> > ---
> >   drivers/rng/meson-rng.c | 73 +++++++++++++++++++++++++++++++++++++----
> >   1 file changed, 67 insertions(+), 6 deletions(-)
> > 
> > diff --git a/drivers/rng/meson-rng.c b/drivers/rng/meson-rng.c
> > index e0a1e8c7e04..3bf2eb9cf87 100644
> > --- a/drivers/rng/meson-rng.c
> > +++ b/drivers/rng/meson-rng.c
> > @@ -11,36 +11,82 @@
> >   #include <rng.h>
> >   #include <asm/io.h>
> > +struct meson_rng_data {
> > +	bool check_status_bit;
> > +};
> > +
> >   struct meson_rng_plat {
> >   	fdt_addr_t base;
> >   	struct clk clk;
> > +	struct meson_rng_data *data;
> >   };
> > +#define RETRY_CNT 100
> > +#define RNG_OUT_OFFSET 0x08
> > +
> > +#define SEED_READY_STS_BIT 0
> > +#define RUN_BIT 31
> > +
> > +static int meson_rng_wait_status(struct meson_rng_plat *pdata, int bit)
> > +{
> > +	u32 status;
> > +	u32 cnt = 0;
> > +
> > +	pr_debug("Poll status of bit: %d\n", bit);
> > +
> > +	do {
> > +		status = readl(pdata->base) & BIT(bit);
> > +	} while (status && (cnt++ < RETRY_CNT));
> > +
> > +	if (cnt == RETRY_CNT) {
> > +		pr_err("Can't get random number, try again");
> > +		return -EBUSY;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >   /**
> >    * meson_rng_read() - fill buffer with random bytes
> >    *
> >    * @buffer:	buffer to receive data
> >    * @size:	size of buffer
> >    *
> > - * Return:	0
> > + * Return:	0 on success or -errno in failure
> >    */
> >   static int meson_rng_read(struct udevice *dev, void *data, size_t len)
> >   {
> >   	struct meson_rng_plat *pdata = dev_get_plat(dev);
> > +	struct meson_rng_data *rng_data = pdata->data;
> >   	char *buffer = (char *)data;
> > +	int err;
> >   	while (len) {
> > -		u32 rand = readl(pdata->base);
> > +		u32 rand;
> >   		size_t step;
> > -		if (len >= 4)
> > -			step = 4;
> > -		else
> > -			step = len;
> > +		if (rng_data->check_status_bit) {
> > +			writel(readl(pdata->base) | BIT(SEED_READY_STS_BIT), pdata->base);
> > +
> > +			err = meson_rng_wait_status(pdata, SEED_READY_STS_BIT);
> > +			if (err)
> > +				return err;
> > +
> > +			err = meson_rng_wait_status(pdata, RUN_BIT);
> > +			if (err)
> > +				return err;
> > +
> > +			rand = readl(pdata->base + RNG_OUT_OFFSET);
> > +		} else {
> > +			rand = readl(pdata->base);
> > +		}
> > +
> > +		step = min_t(u32, len, 4);
> >   		memcpy(buffer, &rand, step);
> >   		buffer += step;
> >   		len -= step;
> >   	}
> > +
> >   	return 0;
> >   }
> > @@ -90,6 +136,8 @@ static int meson_rng_of_to_plat(struct udevice *dev)
> >   	if (!pdata->base)
> >   		return -ENODEV;
> > +	pdata->data = (struct meson_rng_data *)dev_get_driver_data(dev);
> > +
> >   	/* Get optional "core" clock */
> >   	err = clk_get_by_name_optional(dev, "core", &pdata->clk);
> >   	if (err)
> > @@ -102,9 +150,22 @@ static const struct dm_rng_ops meson_rng_ops = {
> >   	.read = meson_rng_read,
> >   };
> > +static const struct meson_rng_data meson_rng_data = {
> > +	.check_status_bit = false,
> > +};
> > +
> > +static const struct meson_rng_data meson_rng_data_s4 = {
> > +	.check_status_bit = true,
> > +};
> > +
> >   static const struct udevice_id meson_rng_match[] = {
> >   	{
> >   		.compatible = "amlogic,meson-rng",
> > +		.data = (ulong)&meson_rng_data,
> > +	},
> > +	{
> > +		.compatible = "amlogic,meson-rng-s4",
> > +		.data = (ulong)&meson_rng_data_s4,
> >   	},
> >   	{},
> >   };
> 

Sure, I will prepare patches and send them in LKML next week.

-- 
Thank you,
Alexey


More information about the U-Boot mailing list