From 2ab581efc1b9a2c37628ab094402990dd8eeb93f Mon Sep 17 00:00:00 2001 From: Tomas Marek Date: Mon, 26 Sep 2022 12:08:31 +0200 Subject: [PATCH] hwrng: stm32: add support for TRNG clock selection Add support for STM32 TRNG clock frequency specification. The clock frequency could be specified using "clock-frequency" attribute in DTS. The higher clock frequency could increase TRNG throughput. --- .../devicetree/bindings/rng/st,stm32-rng.yaml | 3 +++ arch/arm/boot/dts/st/stm32mp151-cc100.dtsi | 1 + drivers/char/hw_random/stm32-rng.c | 20 +++++++++++++++++++ drivers/clk/clk-stm32mp1.c | 5 ++++- 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/rng/st,stm32-rng.yaml b/Documentation/devicetree/bindings/rng/st,stm32-rng.yaml index 187b172d0cca..5e87f9e5642f 100644 --- a/Documentation/devicetree/bindings/rng/st,stm32-rng.yaml +++ b/Documentation/devicetree/bindings/rng/st,stm32-rng.yaml @@ -30,6 +30,9 @@ properties: type: boolean description: If set enable the clock detection management + clock-frequency: + description: Specify TRNG SRC clock frequency. + required: - compatible - reg diff --git a/arch/arm/boot/dts/st/stm32mp151-cc100.dtsi b/arch/arm/boot/dts/st/stm32mp151-cc100.dtsi index f061eb0a64f0..369d9822f886 100644 --- a/arch/arm/boot/dts/st/stm32mp151-cc100.dtsi +++ b/arch/arm/boot/dts/st/stm32mp151-cc100.dtsi @@ -548,6 +548,7 @@ &rng1 { status = "okay"; + clock-frequency = <48000000>; }; &rtc { diff --git a/drivers/char/hw_random/stm32-rng.c b/drivers/char/hw_random/stm32-rng.c index efb6a9f9a11b..a49c0765d5bb 100644 --- a/drivers/char/hw_random/stm32-rng.c +++ b/drivers/char/hw_random/stm32-rng.c @@ -28,6 +28,8 @@ #define RNG_DR 0x08 +#define MAX_RNG_SRC_CLK_FREQ 48000000 + struct stm32_rng_private { struct hwrng rng; void __iomem *base; @@ -119,6 +121,7 @@ static int stm32_rng_probe(struct platform_device *ofdev) struct device_node *np = ofdev->dev.of_node; struct stm32_rng_private *priv; struct resource res; + u32 clock_rate; int err; priv = devm_kzalloc(dev, sizeof(struct stm32_rng_private), GFP_KERNEL); @@ -146,6 +149,23 @@ static int stm32_rng_probe(struct platform_device *ofdev) priv->ced = of_property_read_bool(np, "clock-error-detect"); + if (!of_property_read_u32(dev->of_node, "clock-frequency", &clock_rate)) { + if (clock_rate > MAX_RNG_SRC_CLK_FREQ) { + dev_err(dev, "cannot set clock rate: %d\n", err); + return -EINVAL; + } + + dev_info(dev, "set clock rate %d\n", clock_rate); + err = clk_set_rate(priv->clk, clock_rate); + if (err) { + dev_err(dev, "cannot set clock rate: %d\n", err); + return err; + } + } else { + clock_rate = clk_get_rate(priv->clk); + dev_info(dev, "use default clock rate %d\n", clock_rate); + } + dev_set_drvdata(dev, priv); priv->rng.name = dev_driver_string(dev); diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c index 939779f66867..90dda4688288 100644 --- a/drivers/clk/clk-stm32mp1.c +++ b/drivers/clk/clk-stm32mp1.c @@ -1996,7 +1996,10 @@ static const struct clock_config stm32mp1_clock_cfg[] = { KCLK(SDMMC3_K, "sdmmc3_k", sdmmc3_src, 0, G_SDMMC3, M_SDMMC3), KCLK(FMC_K, "fmc_k", fmc_src, 0, G_FMC, M_FMC), KCLK(QSPI_K, "qspi_k", qspi_src, 0, G_QSPI, M_QSPI), - KCLK(RNG1_K, "rng1_k", rng_src, 0, G_RNG1, M_RNG1), + COMPOSITE(RNG1_K, "rng1_k", rng_src, CLK_OPS_PARENT_ENABLE,\ + _MGATE_MP1(G_RNG1),\ + _MMUX(M_RNG1),\ + _NO_DIV), KCLK(RNG2_K, "rng2_k", rng_src, 0, G_RNG2, M_RNG2), KCLK(USBPHY_K, "usbphy_k", usbphy_src, 0, G_USBPHY, M_USBPHY), KCLK(STGEN_K, "stgen_k", stgen_src, CLK_IS_CRITICAL, G_STGEN, M_STGEN),