The vendor TF-A blobs for RK3562 leave the TRNG and RK RNG clocks gated when returning to U-Boot proper.
Try to enable clocks while reading or otherwise accessing TRNG/RKRNG regs to ensure random data can successfully be read on affected SoCs. This is not expected to have any impact on SoCs using a clock driver with unimplemented enable/disable ops. Signed-off-by: Jonas Karlman <[email protected]> --- drivers/rng/rockchip_rng.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/rng/rockchip_rng.c b/drivers/rng/rockchip_rng.c index 178a76c09347..b674d270d8ac 100644 --- a/drivers/rng/rockchip_rng.c +++ b/drivers/rng/rockchip_rng.c @@ -3,6 +3,7 @@ * Copyright (c) 2020 Fuzhou Rockchip Electronics Co., Ltd */ +#include <clk.h> #include <dm.h> #include <rng.h> #include <asm/arch-rockchip/hardware.h> @@ -103,6 +104,7 @@ struct rk_rng_soc_data { struct rk_rng_plat { fdt_addr_t base; + struct clk_bulk clks; struct rk_rng_soc_data *soc_data; }; @@ -296,7 +298,7 @@ static int rockchip_rng_read(struct udevice *dev, void *data, size_t len) { unsigned char *buf = data; unsigned int i; - int ret = -EIO; + int ret; struct rk_rng_plat *pdata = dev_get_priv(dev); @@ -306,6 +308,10 @@ static int rockchip_rng_read(struct udevice *dev, void *data, size_t len) if (!pdata->soc_data || !pdata->soc_data->rk_rng_read) return -EINVAL; + ret = clk_enable_bulk(&pdata->clks); + if (ret && ret != -ENOENT) + return ret; + for (i = 0; i < len / RK_HW_RNG_MAX; i++, buf += RK_HW_RNG_MAX) { ret = pdata->soc_data->rk_rng_read(dev, buf, RK_HW_RNG_MAX); if (ret) @@ -317,6 +323,7 @@ static int rockchip_rng_read(struct udevice *dev, void *data, size_t len) len % RK_HW_RNG_MAX); exit: + clk_disable_bulk(&pdata->clks); return ret; } @@ -336,12 +343,22 @@ static int rockchip_rng_of_to_plat(struct udevice *dev) static int rockchip_rng_probe(struct udevice *dev) { struct rk_rng_plat *pdata = dev_get_priv(dev); - int ret = 0; + int ret; + + ret = clk_get_bulk(dev, &pdata->clks); + if (ret && ret != -ENOENT && ret != -ENOSYS) + return ret; pdata->soc_data = (struct rk_rng_soc_data *)dev_get_driver_data(dev); - if (pdata->soc_data->rk_rng_init) + if (pdata->soc_data->rk_rng_init) { + ret = clk_enable_bulk(&pdata->clks); + if (ret && ret != -ENOENT) + return ret; + ret = pdata->soc_data->rk_rng_init(dev); + clk_disable_bulk(&pdata->clks); + } return ret; } -- 2.55.0
