diff --git a/target/linux/rockchip/patches-6.6/300-hwrng-add-Rockchip-SoC-hwrng-driver.patch b/target/linux/rockchip/patches-6.6/300-hwrng-add-hwrng-driver-for-Rockchip-RK3568-SoC.patch similarity index 57% rename from target/linux/rockchip/patches-6.6/300-hwrng-add-Rockchip-SoC-hwrng-driver.patch rename to target/linux/rockchip/patches-6.6/300-hwrng-add-hwrng-driver-for-Rockchip-RK3568-SoC.patch index 0be9a7300b0..683d1b1d5e5 100644 --- a/target/linux/rockchip/patches-6.6/300-hwrng-add-Rockchip-SoC-hwrng-driver.patch +++ b/target/linux/rockchip/patches-6.6/300-hwrng-add-hwrng-driver-for-Rockchip-RK3568-SoC.patch @@ -1,56 +1,27 @@ -From patchwork Sat Nov 12 14:10:58 2022 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Aurelien Jarno -X-Patchwork-Id: 13041222 -Return-Path: - -X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on - aws-us-west-2-korg-lkml-1.web.codeaurora.org +From cea47ad1fbd46d3096fcf5c6905db3d12b5da960 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno -To: Olivia Mackall , - Herbert Xu , - Rob Herring , - Krzysztof Kozlowski , - Heiko Stuebner , - Philipp Zabel , - Lin Jinhan -Cc: linux-crypto@vger.kernel.org (open list:HARDWARE RANDOM NUMBER GENERATOR - CORE), - devicetree@vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE - BINDINGS), - linux-arm-kernel@lists.infradead.org (moderated list:ARM/Rockchip SoC - support), - linux-rockchip@lists.infradead.org (open list:ARM/Rockchip SoC support), - linux-kernel@vger.kernel.org (open list), - Aurelien Jarno -Subject: [PATCH v1 2/3] hwrng: add Rockchip SoC hwrng driver -Date: Sat, 12 Nov 2022 15:10:58 +0100 -Message-Id: <20221112141059.3802506-3-aurelien@aurel32.net> -In-Reply-To: <20221112141059.3802506-1-aurelien@aurel32.net> -References: <20221112141059.3802506-1-aurelien@aurel32.net> -MIME-Version: 1.0 -List-Id: +Date: Sun, 21 Jul 2024 01:48:04 +0100 +Subject: [PATCH 2/3] hwrng: add hwrng driver for Rockchip RK3568 SoC Rockchip SoCs used to have a random number generator as part of their crypto device, and support for it has to be added to the corresponding -driver. However newer Rockchip SoCs like the RK356x have an independent +driver. However newer Rockchip SoCs like the RK3568 have an independent True Random Number Generator device. This patch adds a driver for it, greatly inspired from the downstream driver. The TRNG device does not seem to have a signal conditionner and the FIPS 140-2 test returns a lot of failures. They can be reduced by increasing -RK_RNG_SAMPLE_CNT, in a tradeoff between quality and speed. This value -has been adjusted to get ~90% of successes and the quality value has -been set accordingly. +rockchip,sample-count in DT, in a tradeoff between quality and speed. Signed-off-by: Aurelien Jarno +[daniel@makrotpia.org: code style fixes, add DT properties] +Signed-off-by: Daniel Golle +Acked-by: Krzysztof Kozlowski --- drivers/char/hw_random/Kconfig | 14 ++ drivers/char/hw_random/Makefile | 1 + - drivers/char/hw_random/rockchip-rng.c | 251 ++++++++++++++++++++++++++ - 3 files changed, 266 insertions(+) + drivers/char/hw_random/rockchip-rng.c | 230 ++++++++++++++++++++++++++ + 4 files changed, 246 insertions(+) create mode 100644 drivers/char/hw_random/rockchip-rng.c --- a/drivers/char/hw_random/Kconfig @@ -60,18 +31,18 @@ Signed-off-by: Aurelien Jarno The module will be called jh7110-trng. +config HW_RANDOM_ROCKCHIP -+ tristate "Rockchip True Random Number Generator" -+ depends on HW_RANDOM && (ARCH_ROCKCHIP || COMPILE_TEST) -+ depends on HAS_IOMEM -+ default HW_RANDOM -+ help -+ This driver provides kernel-side support for the True Random Number -+ Generator hardware found on some Rockchip SoC like RK3566 or RK3568. ++ tristate "Rockchip True Random Number Generator" ++ depends on HW_RANDOM && (ARCH_ROCKCHIP || COMPILE_TEST) ++ depends on HAS_IOMEM ++ default HW_RANDOM ++ help ++ This driver provides kernel-side support for the True Random Number ++ Generator hardware found on some Rockchip SoC like RK3566 or RK3568. + -+ To compile this driver as a module, choose M here: the -+ module will be called rockchip-rng. ++ To compile this driver as a module, choose M here: the ++ module will be called rockchip-rng. + -+ If unsure, say Y. ++ If unsure, say Y. + endif # HW_RANDOM @@ -86,10 +57,10 @@ Signed-off-by: Aurelien Jarno obj-$(CONFIG_HW_RANDOM_JH7110) += jh7110-trng.o --- /dev/null +++ b/drivers/char/hw_random/rockchip-rng.c -@@ -0,0 +1,251 @@ +@@ -0,0 +1,230 @@ +// SPDX-License-Identifier: GPL-2.0 +/* -+ * rockchip-rng.c True Random Number Generator driver for Rockchip SoCs ++ * rockchip-rng.c True Random Number Generator driver for Rockchip RK3568 SoC + * + * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd. + * Copyright (c) 2022, Aurelien Jarno @@ -103,7 +74,8 @@ Signed-off-by: Aurelien Jarno +#include +#include +#include -+#include ++#include ++#include +#include +#include +#include @@ -113,13 +85,6 @@ Signed-off-by: Aurelien Jarno +#define RK_RNG_POLL_PERIOD_US 100 +#define RK_RNG_POLL_TIMEOUT_US 10000 + -+/* -+ * TRNG collects osc ring output bit every RK_RNG_SAMPLE_CNT time. The value is -+ * a tradeoff between speed and quality and has been adjusted to get a quality -+ * of ~900 (~90% of FIPS 140-2 successes). -+ */ -+#define RK_RNG_SAMPLE_CNT 1000 -+ +/* TRNG registers from RK3568 TRM-Part2, section 5.4.1 */ +#define TRNG_RST_CTL 0x0004 +#define TRNG_RNG_CTL 0x0400 @@ -131,17 +96,11 @@ Signed-off-by: Aurelien Jarno +#define TRNG_RNG_CTL_OSC_RING_SPEED_1 (0x01 << 2) +#define TRNG_RNG_CTL_OSC_RING_SPEED_2 (0x02 << 2) +#define TRNG_RNG_CTL_OSC_RING_SPEED_3 (0x03 << 2) ++#define TRNG_RNG_CTL_MASK GENMASK(15, 0) +#define TRNG_RNG_CTL_ENABLE BIT(1) +#define TRNG_RNG_CTL_START BIT(0) +#define TRNG_RNG_SAMPLE_CNT 0x0404 -+#define TRNG_RNG_DOUT_0 0x0410 -+#define TRNG_RNG_DOUT_1 0x0414 -+#define TRNG_RNG_DOUT_2 0x0418 -+#define TRNG_RNG_DOUT_3 0x041c -+#define TRNG_RNG_DOUT_4 0x0420 -+#define TRNG_RNG_DOUT_5 0x0424 -+#define TRNG_RNG_DOUT_6 0x0428 -+#define TRNG_RNG_DOUT_7 0x042c ++#define TRNG_RNG_DOUT 0x0410 + +struct rk_rng { + struct hwrng rng; @@ -149,18 +108,18 @@ Signed-off-by: Aurelien Jarno + struct reset_control *rst; + int clk_num; + struct clk_bulk_data *clk_bulks; ++ u32 sample_cnt; +}; + -+/* The mask determine the bits that are updated */ ++/* The mask in the upper 16 bits determines the bits that are updated */ +static void rk_rng_write_ctl(struct rk_rng *rng, u32 val, u32 mask) +{ -+ writel_relaxed((mask << 16) | val, rng->base + TRNG_RNG_CTL); ++ writel((mask << 16) | val, rng->base + TRNG_RNG_CTL); +} + +static int rk_rng_init(struct hwrng *rng) +{ + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); -+ u32 reg; + int ret; + + /* start clocks */ @@ -172,13 +131,13 @@ Signed-off-by: Aurelien Jarno + } + + /* set the sample period */ -+ writel(RK_RNG_SAMPLE_CNT, rk_rng->base + TRNG_RNG_SAMPLE_CNT); ++ writel(rk_rng->sample_cnt, rk_rng->base + TRNG_RNG_SAMPLE_CNT); + + /* set osc ring speed and enable it */ -+ reg = TRNG_RNG_CTL_LEN_256_BIT | -+ TRNG_RNG_CTL_OSC_RING_SPEED_0 | -+ TRNG_RNG_CTL_ENABLE; -+ rk_rng_write_ctl(rk_rng, reg, 0xffff); ++ rk_rng_write_ctl(rk_rng, TRNG_RNG_CTL_LEN_256_BIT | ++ TRNG_RNG_CTL_OSC_RING_SPEED_0 | ++ TRNG_RNG_CTL_ENABLE, ++ TRNG_RNG_CTL_MASK); + + return 0; +} @@ -186,11 +145,9 @@ Signed-off-by: Aurelien Jarno +static void rk_rng_cleanup(struct hwrng *rng) +{ + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); -+ u32 reg; + + /* stop TRNG */ -+ reg = 0; -+ rk_rng_write_ctl(rk_rng, reg, 0xffff); ++ rk_rng_write_ctl(rk_rng, 0, TRNG_RNG_CTL_MASK); + + /* stop clocks */ + clk_bulk_disable_unprepare(rk_rng->clk_num, rk_rng->clk_bulks); @@ -199,15 +156,16 @@ Signed-off-by: Aurelien Jarno +static int rk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) +{ + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); ++ size_t to_read = min_t(size_t, max, RK_RNG_MAX_BYTE); + u32 reg; + int ret = 0; -+ int i; + -+ pm_runtime_get_sync((struct device *) rk_rng->rng.priv); ++ ret = pm_runtime_resume_and_get((struct device *) rk_rng->rng.priv); ++ if (ret < 0) ++ return ret; + + /* Start collecting random data */ -+ reg = TRNG_RNG_CTL_START; -+ rk_rng_write_ctl(rk_rng, reg, reg); ++ rk_rng_write_ctl(rk_rng, TRNG_RNG_CTL_START, TRNG_RNG_CTL_START); + + ret = readl_poll_timeout(rk_rng->base + TRNG_RNG_CTL, reg, + !(reg & TRNG_RNG_CTL_START), @@ -216,27 +174,23 @@ Signed-off-by: Aurelien Jarno + if (ret < 0) + goto out; + -+ /* Read random data stored in big endian in the registers */ -+ ret = min_t(size_t, max, RK_RNG_MAX_BYTE); -+ for (i = 0; i < ret; i += 4) { -+ reg = readl_relaxed(rk_rng->base + TRNG_RNG_DOUT_0 + i); -+ *(u32 *)(buf + i) = be32_to_cpu(reg); -+ } -+ ++ /* Read random data stored in the registers */ ++ memcpy_fromio(buf, rk_rng->base + TRNG_RNG_DOUT, to_read); +out: + pm_runtime_mark_last_busy((struct device *) rk_rng->rng.priv); + pm_runtime_put_sync_autosuspend((struct device *) rk_rng->rng.priv); + -+ return ret; ++ return (ret < 0) ? ret : to_read; +} + +static int rk_rng_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rk_rng *rk_rng; ++ u32 quality; + int ret; + -+ rk_rng = devm_kzalloc(dev, sizeof(struct rk_rng), GFP_KERNEL); ++ rk_rng = devm_kzalloc(dev, sizeof(*rk_rng), GFP_KERNEL); + if (!rk_rng) + return -ENOMEM; + @@ -249,11 +203,19 @@ Signed-off-by: Aurelien Jarno + return dev_err_probe(dev, rk_rng->clk_num, + "Failed to get clks property\n"); + -+ rk_rng->rst = devm_reset_control_array_get(&pdev->dev, false, false); ++ rk_rng->rst = devm_reset_control_array_get_exclusive(&pdev->dev); + if (IS_ERR(rk_rng->rst)) + return dev_err_probe(dev, PTR_ERR(rk_rng->rst), + "Failed to get reset property\n"); + ++ ret = of_property_read_u32(dev->of_node, "rockchip,sample-count", &rk_rng->sample_cnt); ++ if (ret) ++ return dev_err_probe(dev, ret, "Failed to get sample-count property\n"); ++ ++ ret = of_property_read_u32(dev->of_node, "quality", &quality); ++ if (ret || quality > 1024) ++ return dev_err_probe(dev, ret, "Failed to get quality property\n"); ++ + reset_control_assert(rk_rng->rst); + udelay(2); + reset_control_deassert(rk_rng->rst); @@ -261,36 +223,26 @@ Signed-off-by: Aurelien Jarno + platform_set_drvdata(pdev, rk_rng); + + rk_rng->rng.name = dev_driver_string(dev); -+#ifndef CONFIG_PM -+ rk_rng->rng.init = rk_rng_init; -+ rk_rng->rng.cleanup = rk_rng_cleanup; -+#endif ++ if (!IS_ENABLED(CONFIG_PM)) { ++ rk_rng->rng.init = rk_rng_init; ++ rk_rng->rng.cleanup = rk_rng_cleanup; ++ } + rk_rng->rng.read = rk_rng_read; + rk_rng->rng.priv = (unsigned long) dev; -+ rk_rng->rng.quality = 900; ++ rk_rng->rng.quality = quality; + + pm_runtime_set_autosuspend_delay(dev, RK_RNG_AUTOSUSPEND_DELAY); + pm_runtime_use_autosuspend(dev); -+ pm_runtime_enable(dev); ++ devm_pm_runtime_enable(dev); + + ret = devm_hwrng_register(dev, &rk_rng->rng); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Failed to register Rockchip hwrng\n"); + -+ dev_info(&pdev->dev, "Registered Rockchip hwrng\n"); -+ + return 0; +} + -+static int rk_rng_remove(struct platform_device *pdev) -+{ -+ pm_runtime_disable(&pdev->dev); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int rk_rng_runtime_suspend(struct device *dev) ++static int __maybe_unused rk_rng_runtime_suspend(struct device *dev) +{ + struct rk_rng *rk_rng = dev_get_drvdata(dev); + @@ -299,13 +251,12 @@ Signed-off-by: Aurelien Jarno + return 0; +} + -+static int rk_rng_runtime_resume(struct device *dev) ++static int __maybe_unused rk_rng_runtime_resume(struct device *dev) +{ + struct rk_rng *rk_rng = dev_get_drvdata(dev); + + return rk_rng_init(&rk_rng->rng); +} -+#endif + +static const struct dev_pm_ops rk_rng_pm_ops = { + SET_RUNTIME_PM_OPS(rk_rng_runtime_suspend, @@ -315,10 +266,8 @@ Signed-off-by: Aurelien Jarno +}; + +static const struct of_device_id rk_rng_dt_match[] = { -+ { -+ .compatible = "rockchip,rk3568-rng", -+ }, -+ {}, ++ { .compatible = "rockchip,rk3568-rng", }, ++ { /* sentinel */ }, +}; + +MODULE_DEVICE_TABLE(of, rk_rng_dt_match); @@ -330,11 +279,12 @@ Signed-off-by: Aurelien Jarno + .of_match_table = rk_rng_dt_match, + }, + .probe = rk_rng_probe, -+ .remove = rk_rng_remove, +}; + +module_platform_driver(rk_rng_driver); + -+MODULE_DESCRIPTION("Rockchip True Random Number Generator driver"); -+MODULE_AUTHOR("Lin Jinhan , Aurelien Jarno "); -+MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("Rockchip RK3568 True Random Number Generator driver"); ++MODULE_AUTHOR("Lin Jinhan "); ++MODULE_AUTHOR("Aurelien Jarno "); ++MODULE_AUTHOR("Daniel Golle "); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK3568.patch b/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK3568.patch new file mode 100644 index 00000000000..c5e1eb44f68 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK3568.patch @@ -0,0 +1,49 @@ +From 756e7d3251ad8f6c72e7bf4c476537a89f673e38 Mon Sep 17 00:00:00 2001 +From: Aurelien Jarno +Date: Sun, 21 Jul 2024 01:48:38 +0100 +Subject: [PATCH 3/3] arm64: dts: rockchip: add DT entry for RNG to RK356x + +Enable the just added Rockchip RNG driver for RK356x SoCs. + +Signed-off-by: Aurelien Jarno +Signed-off-by: Daniel Golle +--- + arch/arm64/boot/dts/rockchip/rk3568.dtsi | 7 +++++++ + arch/arm64/boot/dts/rockchip/rk356x.dtsi | 10 ++++++++++ + 2 files changed, 17 insertions(+) + +--- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi +@@ -257,6 +257,13 @@ + }; + }; + ++&rng { ++ rockchip,sample-count = <1000>; ++ quality = <900>; ++ ++ status = "okay"; ++}; ++ + &usb_host0_xhci { + phys = <&usb2phy0_otg>, <&combphy0 PHY_TYPE_USB3>; + phy-names = "usb2-phy", "usb3-phy"; +--- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi +@@ -1105,6 +1105,16 @@ + status = "disabled"; + }; + ++ rng: rng@fe388000 { ++ compatible = "rockchip,rk3568-rng"; ++ reg = <0x0 0xfe388000 0x0 0x4000>; ++ clocks = <&cru CLK_TRNG_NS>, <&cru HCLK_TRNG_NS>; ++ clock-names = "core", "ahb"; ++ resets = <&cru SRST_TRNG_NS>; ++ reset-names = "reset"; ++ status = "disabled"; ++ }; ++ + i2s0_8ch: i2s@fe400000 { + compatible = "rockchip,rk3568-i2s-tdm"; + reg = <0x0 0xfe400000 0x0 0x1000>; diff --git a/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK356x.patch b/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK356x.patch deleted file mode 100644 index 3e65de7a20f..00000000000 --- a/target/linux/rockchip/patches-6.6/301-arm64-dts-rockchip-add-DT-entry-for-RNG-to-RK356x.patch +++ /dev/null @@ -1,56 +0,0 @@ -From patchwork Sat Nov 12 14:10:59 2022 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Aurelien Jarno -X-Patchwork-Id: 13041221 -From: Aurelien Jarno -To: Olivia Mackall , - Herbert Xu , - Rob Herring , - Krzysztof Kozlowski , - Heiko Stuebner , - Philipp Zabel , - Lin Jinhan -Cc: linux-crypto@vger.kernel.org (open list:HARDWARE RANDOM NUMBER GENERATOR - CORE), - devicetree@vger.kernel.org (open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE - BINDINGS), - linux-arm-kernel@lists.infradead.org (moderated list:ARM/Rockchip SoC - support), - linux-rockchip@lists.infradead.org (open list:ARM/Rockchip SoC support), - linux-kernel@vger.kernel.org (open list), - Aurelien Jarno -Subject: [PATCH v1 3/3] arm64: dts: rockchip: add DT entry for RNG to RK356x -Date: Sat, 12 Nov 2022 15:10:59 +0100 -Message-Id: <20221112141059.3802506-4-aurelien@aurel32.net> -In-Reply-To: <20221112141059.3802506-1-aurelien@aurel32.net> -References: <20221112141059.3802506-1-aurelien@aurel32.net> -MIME-Version: 1.0 -List-Id: - -Enable the just added Rockchip RNG driver for RK356x SoCs. - -Signed-off-by: Aurelien Jarno ---- - arch/arm64/boot/dts/rockchip/rk356x.dtsi | 9 +++++++++ - 1 file changed, 9 insertions(+) - ---- a/arch/arm64/boot/dts/rockchip/rk356x.dtsi -+++ b/arch/arm64/boot/dts/rockchip/rk356x.dtsi -@@ -1848,6 +1848,15 @@ - }; - }; - -+ rng: rng@fe388000 { -+ compatible = "rockchip,rk3568-rng"; -+ reg = <0x0 0xfe388000 0x0 0x4000>; -+ clocks = <&cru CLK_TRNG_NS>, <&cru HCLK_TRNG_NS>; -+ clock-names = "trng_clk", "trng_hclk"; -+ resets = <&cru SRST_TRNG_NS>; -+ reset-names = "reset"; -+ }; -+ - pinctrl: pinctrl { - compatible = "rockchip,rk3568-pinctrl"; - rockchip,grf = <&grf>;