diff --git a/root/package/boot/uboot-rockchip/Makefile b/root/package/boot/uboot-rockchip/Makefile index 3309912c..0b6598b4 100644 --- a/root/package/boot/uboot-rockchip/Makefile +++ b/root/package/boot/uboot-rockchip/Makefile @@ -5,8 +5,8 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk -PKG_VERSION:=2020.10 -PKG_RELEASE:=1 +PKG_VERSION:=2020.07 +PKG_RELEASE:=3 PKG_HASH:=0d481bbdc05c0ee74908ec2f56a6daa53166cc6a78a0e4fac2ac5d025770a622 diff --git a/root/target/linux/rockchip/armv8/config-5.4 b/root/target/linux/rockchip/armv8/config-5.4 index d1a3b1c9..e9a97233 100644 --- a/root/target/linux/rockchip/armv8/config-5.4 +++ b/root/target/linux/rockchip/armv8/config-5.4 @@ -117,6 +117,13 @@ CONFIG_CRC_T10DIF=y CONFIG_CROSS_MEMORY_ATTACH=y CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_CRCT10DIF=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEVFREQ_GOV_PASSIVE is not set CONFIG_DEVFREQ_GOV_PERFORMANCE=y diff --git a/root/target/linux/rockchip/files/drivers/char/hw_random/rockchip-rng.c b/root/target/linux/rockchip/files/drivers/char/hw_random/rockchip-rng.c new file mode 100644 index 00000000..718762f9 --- /dev/null +++ b/root/target/linux/rockchip/files/drivers/char/hw_random/rockchip-rng.c @@ -0,0 +1,340 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * rockchip-rng.c Random Number Generator driver for the Rockchip + * + * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd. + * Author: Lin Jinhan + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define _SBF(s, v) ((v) << (s)) +#define HIWORD_UPDATE(val, mask, shift) \ + ((val) << (shift) | (mask) << ((shift) + 16)) + +#define ROCKCHIP_AUTOSUSPEND_DELAY 100 +#define ROCKCHIP_POLL_PERIOD_US 100 +#define ROCKCHIP_POLL_TIMEOUT_US 10000 +#define RK_MAX_RNG_BYTE (32) + +/* start of CRYPTO V1 register define */ +#define CRYPTO_V1_CTRL 0x0008 +#define CRYPTO_V1_RNG_START BIT(8) +#define CRYPTO_V1_RNG_FLUSH BIT(9) + +#define CRYPTO_V1_TRNG_CTRL 0x0200 +#define CRYPTO_V1_OSC_ENABLE BIT(16) +#define CRYPTO_V1_TRNG_SAMPLE_PERIOD(x) (x) + +#define CRYPTO_V1_TRNG_DOUT_0 0x0204 +/* end of CRYPTO V1 register define */ + +/* start of CRYPTO V2 register define */ +#define CRYPTO_V2_RNG_CTL 0x0400 +#define CRYPTO_V2_RNG_64_BIT_LEN _SBF(4, 0x00) +#define CRYPTO_V2_RNG_128_BIT_LEN _SBF(4, 0x01) +#define CRYPTO_V2_RNG_192_BIT_LEN _SBF(4, 0x02) +#define CRYPTO_V2_RNG_256_BIT_LEN _SBF(4, 0x03) +#define CRYPTO_V2_RNG_FATESY_SOC_RING _SBF(2, 0x00) +#define CRYPTO_V2_RNG_SLOWER_SOC_RING_0 _SBF(2, 0x01) +#define CRYPTO_V2_RNG_SLOWER_SOC_RING_1 _SBF(2, 0x02) +#define CRYPTO_V2_RNG_SLOWEST_SOC_RING _SBF(2, 0x03) +#define CRYPTO_V2_RNG_ENABLE BIT(1) +#define CRYPTO_V2_RNG_START BIT(0) +#define CRYPTO_V2_RNG_SAMPLE_CNT 0x0404 +#define CRYPTO_V2_RNG_DOUT_0 0x0410 +/* end of CRYPTO V2 register define */ + +struct rk_rng_soc_data { + const char * const *clks; + int clks_num; + int (*rk_rng_read)(struct hwrng *rng, void *buf, size_t max, bool wait); +}; + +struct rk_rng { + struct device *dev; + struct hwrng rng; + void __iomem *mem; + struct rk_rng_soc_data *soc_data; + u32 clk_num; + struct clk_bulk_data *clk_bulks; +}; + +static const char * const rk_rng_v1_clks[] = { + "hclk_crypto", + "clk_crypto", +}; + +static const char * const rk_rng_v2_clks[] = { + "hclk_crypto", + "aclk_crypto", + "clk_crypto", + "clk_crypto_apk", +}; + +static void rk_rng_writel(struct rk_rng *rng, u32 val, u32 offset) +{ + __raw_writel(val, rng->mem + offset); +} + +static u32 rk_rng_readl(struct rk_rng *rng, u32 offset) +{ + return __raw_readl(rng->mem + offset); +} + +static int rk_rng_init(struct hwrng *rng) +{ + int ret; + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); + + dev_dbg(rk_rng->dev, "clk_bulk_prepare_enable.\n"); + + ret = clk_bulk_prepare_enable(rk_rng->clk_num, rk_rng->clk_bulks); + if (ret < 0) { + dev_err(rk_rng->dev, "failed to enable clks %d\n", ret); + return ret; + } + + return 0; +} + +static void rk_rng_cleanup(struct hwrng *rng) +{ + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); + + dev_dbg(rk_rng->dev, "clk_bulk_disable_unprepare.\n"); + clk_bulk_disable_unprepare(rk_rng->clk_num, rk_rng->clk_bulks); +} + +static void rk_rng_read_regs(struct rk_rng *rng, u32 offset, void *buf, + size_t size) +{ + u32 i; + + for (i = 0; i < size; i += 4) + *(u32 *)(buf + i) = be32_to_cpu(rk_rng_readl(rng, offset + i)); +} + +static int rk_rng_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait) +{ + int ret = 0; + u32 reg_ctrl = 0; + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); + + ret = pm_runtime_get_sync(rk_rng->dev); + if (ret < 0) { + pm_runtime_put_noidle(rk_rng->dev); + return ret; + } + + /* enable osc_ring to get entropy, sample period is set as 100 */ + reg_ctrl = CRYPTO_V1_OSC_ENABLE | CRYPTO_V1_TRNG_SAMPLE_PERIOD(100); + rk_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_TRNG_CTRL); + + reg_ctrl = HIWORD_UPDATE(CRYPTO_V1_RNG_START, CRYPTO_V1_RNG_START, 0); + + rk_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_CTRL); + + ret = readl_poll_timeout(rk_rng->mem + CRYPTO_V1_CTRL, reg_ctrl, + !(reg_ctrl & CRYPTO_V1_RNG_START), + ROCKCHIP_POLL_PERIOD_US, + ROCKCHIP_POLL_TIMEOUT_US); + if (ret < 0) + goto out; + + ret = min_t(size_t, max, RK_MAX_RNG_BYTE); + + rk_rng_read_regs(rk_rng, CRYPTO_V1_TRNG_DOUT_0, buf, ret); + +out: + /* close TRNG */ + rk_rng_writel(rk_rng, HIWORD_UPDATE(0, CRYPTO_V1_RNG_START, 0), + CRYPTO_V1_CTRL); + + pm_runtime_mark_last_busy(rk_rng->dev); + pm_runtime_put_sync_autosuspend(rk_rng->dev); + + return ret; +} + +static int rk_rng_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait) +{ + int ret = 0; + u32 reg_ctrl = 0; + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); + + ret = pm_runtime_get_sync(rk_rng->dev); + if (ret < 0) { + pm_runtime_put_noidle(rk_rng->dev); + return ret; + } + + /* enable osc_ring to get entropy, sample period is set as 100 */ + rk_rng_writel(rk_rng, 100, CRYPTO_V2_RNG_SAMPLE_CNT); + + reg_ctrl |= CRYPTO_V2_RNG_256_BIT_LEN; + reg_ctrl |= CRYPTO_V2_RNG_SLOWER_SOC_RING_0; + reg_ctrl |= CRYPTO_V2_RNG_ENABLE; + reg_ctrl |= CRYPTO_V2_RNG_START; + + rk_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0), + CRYPTO_V2_RNG_CTL); + + ret = readl_poll_timeout(rk_rng->mem + CRYPTO_V2_RNG_CTL, reg_ctrl, + !(reg_ctrl & CRYPTO_V2_RNG_START), + ROCKCHIP_POLL_PERIOD_US, + ROCKCHIP_POLL_TIMEOUT_US); + if (ret < 0) + goto out; + + ret = min_t(size_t, max, RK_MAX_RNG_BYTE); + + rk_rng_read_regs(rk_rng, CRYPTO_V2_RNG_DOUT_0, buf, ret); + +out: + /* close TRNG */ + rk_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), CRYPTO_V2_RNG_CTL); + + pm_runtime_mark_last_busy(rk_rng->dev); + pm_runtime_put_sync_autosuspend(rk_rng->dev); + + return ret; +} + +static const struct rk_rng_soc_data rk_rng_v1_soc_data = { + .clks_num = ARRAY_SIZE(rk_rng_v1_clks), + .clks = rk_rng_v1_clks, + .rk_rng_read = rk_rng_v1_read, +}; + +static const struct rk_rng_soc_data rk_rng_v2_soc_data = { + .clks_num = ARRAY_SIZE(rk_rng_v2_clks), + .clks = rk_rng_v2_clks, + .rk_rng_read = rk_rng_v2_read, +}; + +static const struct of_device_id rk_rng_dt_match[] = { + { + .compatible = "rockchip,cryptov1-rng", + .data = (void *)&rk_rng_v1_soc_data, + }, + { + .compatible = "rockchip,cryptov2-rng", + .data = (void *)&rk_rng_v2_soc_data, + }, + { }, +}; + +MODULE_DEVICE_TABLE(of, rk_rng_dt_match); + +static int rk_rng_probe(struct platform_device *pdev) +{ + int i; + int ret; + struct rk_rng *rk_rng; + struct device_node *np = pdev->dev.of_node; + const struct of_device_id *match; + + dev_dbg(&pdev->dev, "probing...\n"); + rk_rng = devm_kzalloc(&pdev->dev, sizeof(struct rk_rng), GFP_KERNEL); + if (!rk_rng) + return -ENOMEM; + + match = of_match_node(rk_rng_dt_match, np); + rk_rng->soc_data = (struct rk_rng_soc_data *)match->data; + + rk_rng->dev = &pdev->dev; + rk_rng->rng.name = "rockchip"; +#ifndef CONFIG_PM + rk_rng->rng.init = rk_rng_init; + rk_rng->rng.cleanup = rk_rng_cleanup, +#endif + rk_rng->rng.read = rk_rng->soc_data->rk_rng_read; + rk_rng->rng.quality = 999; + + rk_rng->clk_bulks = + devm_kzalloc(&pdev->dev, sizeof(*rk_rng->clk_bulks) * + rk_rng->soc_data->clks_num, GFP_KERNEL); + + rk_rng->clk_num = rk_rng->soc_data->clks_num; + + for (i = 0; i < rk_rng->soc_data->clks_num; i++) + rk_rng->clk_bulks[i].id = rk_rng->soc_data->clks[i]; + + rk_rng->mem = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL); + if (IS_ERR(rk_rng->mem)) + return PTR_ERR(rk_rng->mem); + + ret = devm_clk_bulk_get(&pdev->dev, rk_rng->clk_num, + rk_rng->clk_bulks); + if (ret) { + dev_err(&pdev->dev, "failed to get clks property\n"); + return ret; + } + + platform_set_drvdata(pdev, rk_rng); + + pm_runtime_set_autosuspend_delay(&pdev->dev, + ROCKCHIP_AUTOSUSPEND_DELAY); + pm_runtime_use_autosuspend(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + ret = devm_hwrng_register(&pdev->dev, &rk_rng->rng); + if (ret) { + pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_disable(&pdev->dev); + } + + return ret; +} + +#ifdef CONFIG_PM +static int rk_rng_runtime_suspend(struct device *dev) +{ + struct rk_rng *rk_rng = dev_get_drvdata(dev); + + rk_rng_cleanup(&rk_rng->rng); + + return 0; +} + +static int rk_rng_runtime_resume(struct device *dev) +{ + struct rk_rng *rk_rng = dev_get_drvdata(dev); + + return rk_rng_init(&rk_rng->rng); +} + +static const struct dev_pm_ops rk_rng_pm_ops = { + SET_RUNTIME_PM_OPS(rk_rng_runtime_suspend, + rk_rng_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) +}; + +#endif + +static struct platform_driver rk_rng_driver = { + .driver = { + .name = "rockchip-rng", +#ifdef CONFIG_PM + .pm = &rk_rng_pm_ops, +#endif + .of_match_table = rk_rng_dt_match, + }, + .probe = rk_rng_probe, +}; + +module_platform_driver(rk_rng_driver); + +MODULE_DESCRIPTION("ROCKCHIP H/W Random Number Generator driver"); +MODULE_AUTHOR("Lin Jinhan "); +MODULE_LICENSE("GPL v2"); + diff --git a/root/target/linux/rockchip/patches-5.4/105-char-add-support-for-rockchip-hardware-random-number.patch b/root/target/linux/rockchip/patches-5.4/105-char-add-support-for-rockchip-hardware-random-number.patch index 196cc00a..85f14e61 100644 --- a/root/target/linux/rockchip/patches-5.4/105-char-add-support-for-rockchip-hardware-random-number.patch +++ b/root/target/linux/rockchip/patches-5.4/105-char-add-support-for-rockchip-hardware-random-number.patch @@ -33,349 +33,6 @@ Signed-off-by: wevsty config HW_RANDOM_PIC32 tristate "Microchip PIC32 Random Number Generator support" depends on HW_RANDOM && MACH_PIC32 ---- /dev/null -+++ b/drivers/char/hw_random/rockchip-rng.c -@@ -0,0 +1,340 @@ -+// SPDX-License-Identifier: GPL-2.0 -+/* -+ * rockchip-rng.c Random Number Generator driver for the Rockchip -+ * -+ * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd. -+ * Author: Lin Jinhan -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define _SBF(s, v) ((v) << (s)) -+#define HIWORD_UPDATE(val, mask, shift) \ -+ ((val) << (shift) | (mask) << ((shift) + 16)) -+ -+#define ROCKCHIP_AUTOSUSPEND_DELAY 100 -+#define ROCKCHIP_POLL_PERIOD_US 100 -+#define ROCKCHIP_POLL_TIMEOUT_US 10000 -+#define RK_MAX_RNG_BYTE (32) -+ -+/* start of CRYPTO V1 register define */ -+#define CRYPTO_V1_CTRL 0x0008 -+#define CRYPTO_V1_RNG_START BIT(8) -+#define CRYPTO_V1_RNG_FLUSH BIT(9) -+ -+#define CRYPTO_V1_TRNG_CTRL 0x0200 -+#define CRYPTO_V1_OSC_ENABLE BIT(16) -+#define CRYPTO_V1_TRNG_SAMPLE_PERIOD(x) (x) -+ -+#define CRYPTO_V1_TRNG_DOUT_0 0x0204 -+/* end of CRYPTO V1 register define */ -+ -+/* start of CRYPTO V2 register define */ -+#define CRYPTO_V2_RNG_CTL 0x0400 -+#define CRYPTO_V2_RNG_64_BIT_LEN _SBF(4, 0x00) -+#define CRYPTO_V2_RNG_128_BIT_LEN _SBF(4, 0x01) -+#define CRYPTO_V2_RNG_192_BIT_LEN _SBF(4, 0x02) -+#define CRYPTO_V2_RNG_256_BIT_LEN _SBF(4, 0x03) -+#define CRYPTO_V2_RNG_FATESY_SOC_RING _SBF(2, 0x00) -+#define CRYPTO_V2_RNG_SLOWER_SOC_RING_0 _SBF(2, 0x01) -+#define CRYPTO_V2_RNG_SLOWER_SOC_RING_1 _SBF(2, 0x02) -+#define CRYPTO_V2_RNG_SLOWEST_SOC_RING _SBF(2, 0x03) -+#define CRYPTO_V2_RNG_ENABLE BIT(1) -+#define CRYPTO_V2_RNG_START BIT(0) -+#define CRYPTO_V2_RNG_SAMPLE_CNT 0x0404 -+#define CRYPTO_V2_RNG_DOUT_0 0x0410 -+/* end of CRYPTO V2 register define */ -+ -+struct rk_rng_soc_data { -+ const char * const *clks; -+ int clks_num; -+ int (*rk_rng_read)(struct hwrng *rng, void *buf, size_t max, bool wait); -+}; -+ -+struct rk_rng { -+ struct device *dev; -+ struct hwrng rng; -+ void __iomem *mem; -+ struct rk_rng_soc_data *soc_data; -+ u32 clk_num; -+ struct clk_bulk_data *clk_bulks; -+}; -+ -+static const char * const rk_rng_v1_clks[] = { -+ "hclk_crypto", -+ "clk_crypto", -+}; -+ -+static const char * const rk_rng_v2_clks[] = { -+ "hclk_crypto", -+ "aclk_crypto", -+ "clk_crypto", -+ "clk_crypto_apk", -+}; -+ -+static void rk_rng_writel(struct rk_rng *rng, u32 val, u32 offset) -+{ -+ __raw_writel(val, rng->mem + offset); -+} -+ -+static u32 rk_rng_readl(struct rk_rng *rng, u32 offset) -+{ -+ return __raw_readl(rng->mem + offset); -+} -+ -+static int rk_rng_init(struct hwrng *rng) -+{ -+ int ret; -+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); -+ -+ dev_dbg(rk_rng->dev, "clk_bulk_prepare_enable.\n"); -+ -+ ret = clk_bulk_prepare_enable(rk_rng->clk_num, rk_rng->clk_bulks); -+ if (ret < 0) { -+ dev_err(rk_rng->dev, "failed to enable clks %d\n", ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static void rk_rng_cleanup(struct hwrng *rng) -+{ -+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); -+ -+ dev_dbg(rk_rng->dev, "clk_bulk_disable_unprepare.\n"); -+ clk_bulk_disable_unprepare(rk_rng->clk_num, rk_rng->clk_bulks); -+} -+ -+static void rk_rng_read_regs(struct rk_rng *rng, u32 offset, void *buf, -+ size_t size) -+{ -+ u32 i; -+ -+ for (i = 0; i < size; i += 4) -+ *(u32 *)(buf + i) = be32_to_cpu(rk_rng_readl(rng, offset + i)); -+} -+ -+static int rk_rng_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait) -+{ -+ int ret = 0; -+ u32 reg_ctrl = 0; -+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); -+ -+ ret = pm_runtime_get_sync(rk_rng->dev); -+ if (ret < 0) { -+ pm_runtime_put_noidle(rk_rng->dev); -+ return ret; -+ } -+ -+ /* enable osc_ring to get entropy, sample period is set as 100 */ -+ reg_ctrl = CRYPTO_V1_OSC_ENABLE | CRYPTO_V1_TRNG_SAMPLE_PERIOD(100); -+ rk_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_TRNG_CTRL); -+ -+ reg_ctrl = HIWORD_UPDATE(CRYPTO_V1_RNG_START, CRYPTO_V1_RNG_START, 0); -+ -+ rk_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_CTRL); -+ -+ ret = readl_poll_timeout(rk_rng->mem + CRYPTO_V1_CTRL, reg_ctrl, -+ !(reg_ctrl & CRYPTO_V1_RNG_START), -+ ROCKCHIP_POLL_PERIOD_US, -+ ROCKCHIP_POLL_TIMEOUT_US); -+ if (ret < 0) -+ goto out; -+ -+ ret = min_t(size_t, max, RK_MAX_RNG_BYTE); -+ -+ rk_rng_read_regs(rk_rng, CRYPTO_V1_TRNG_DOUT_0, buf, ret); -+ -+out: -+ /* close TRNG */ -+ rk_rng_writel(rk_rng, HIWORD_UPDATE(0, CRYPTO_V1_RNG_START, 0), -+ CRYPTO_V1_CTRL); -+ -+ pm_runtime_mark_last_busy(rk_rng->dev); -+ pm_runtime_put_sync_autosuspend(rk_rng->dev); -+ -+ return ret; -+} -+ -+static int rk_rng_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait) -+{ -+ int ret = 0; -+ u32 reg_ctrl = 0; -+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); -+ -+ ret = pm_runtime_get_sync(rk_rng->dev); -+ if (ret < 0) { -+ pm_runtime_put_noidle(rk_rng->dev); -+ return ret; -+ } -+ -+ /* enable osc_ring to get entropy, sample period is set as 100 */ -+ rk_rng_writel(rk_rng, 100, CRYPTO_V2_RNG_SAMPLE_CNT); -+ -+ reg_ctrl |= CRYPTO_V2_RNG_256_BIT_LEN; -+ reg_ctrl |= CRYPTO_V2_RNG_SLOWER_SOC_RING_0; -+ reg_ctrl |= CRYPTO_V2_RNG_ENABLE; -+ reg_ctrl |= CRYPTO_V2_RNG_START; -+ -+ rk_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0), -+ CRYPTO_V2_RNG_CTL); -+ -+ ret = readl_poll_timeout(rk_rng->mem + CRYPTO_V2_RNG_CTL, reg_ctrl, -+ !(reg_ctrl & CRYPTO_V2_RNG_START), -+ ROCKCHIP_POLL_PERIOD_US, -+ ROCKCHIP_POLL_TIMEOUT_US); -+ if (ret < 0) -+ goto out; -+ -+ ret = min_t(size_t, max, RK_MAX_RNG_BYTE); -+ -+ rk_rng_read_regs(rk_rng, CRYPTO_V2_RNG_DOUT_0, buf, ret); -+ -+out: -+ /* close TRNG */ -+ rk_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), CRYPTO_V2_RNG_CTL); -+ -+ pm_runtime_mark_last_busy(rk_rng->dev); -+ pm_runtime_put_sync_autosuspend(rk_rng->dev); -+ -+ return ret; -+} -+ -+static const struct rk_rng_soc_data rk_rng_v1_soc_data = { -+ .clks_num = ARRAY_SIZE(rk_rng_v1_clks), -+ .clks = rk_rng_v1_clks, -+ .rk_rng_read = rk_rng_v1_read, -+}; -+ -+static const struct rk_rng_soc_data rk_rng_v2_soc_data = { -+ .clks_num = ARRAY_SIZE(rk_rng_v2_clks), -+ .clks = rk_rng_v2_clks, -+ .rk_rng_read = rk_rng_v2_read, -+}; -+ -+static const struct of_device_id rk_rng_dt_match[] = { -+ { -+ .compatible = "rockchip,cryptov1-rng", -+ .data = (void *)&rk_rng_v1_soc_data, -+ }, -+ { -+ .compatible = "rockchip,cryptov2-rng", -+ .data = (void *)&rk_rng_v2_soc_data, -+ }, -+ { }, -+}; -+ -+MODULE_DEVICE_TABLE(of, rk_rng_dt_match); -+ -+static int rk_rng_probe(struct platform_device *pdev) -+{ -+ int i; -+ int ret; -+ struct rk_rng *rk_rng; -+ struct device_node *np = pdev->dev.of_node; -+ const struct of_device_id *match; -+ -+ dev_dbg(&pdev->dev, "probing...\n"); -+ rk_rng = devm_kzalloc(&pdev->dev, sizeof(struct rk_rng), GFP_KERNEL); -+ if (!rk_rng) -+ return -ENOMEM; -+ -+ match = of_match_node(rk_rng_dt_match, np); -+ rk_rng->soc_data = (struct rk_rng_soc_data *)match->data; -+ -+ rk_rng->dev = &pdev->dev; -+ rk_rng->rng.name = "rockchip"; -+#ifndef CONFIG_PM -+ rk_rng->rng.init = rk_rng_init; -+ rk_rng->rng.cleanup = rk_rng_cleanup, -+#endif -+ rk_rng->rng.read = rk_rng->soc_data->rk_rng_read; -+ rk_rng->rng.quality = 999; -+ -+ rk_rng->clk_bulks = -+ devm_kzalloc(&pdev->dev, sizeof(*rk_rng->clk_bulks) * -+ rk_rng->soc_data->clks_num, GFP_KERNEL); -+ -+ rk_rng->clk_num = rk_rng->soc_data->clks_num; -+ -+ for (i = 0; i < rk_rng->soc_data->clks_num; i++) -+ rk_rng->clk_bulks[i].id = rk_rng->soc_data->clks[i]; -+ -+ rk_rng->mem = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL); -+ if (IS_ERR(rk_rng->mem)) -+ return PTR_ERR(rk_rng->mem); -+ -+ ret = devm_clk_bulk_get(&pdev->dev, rk_rng->clk_num, -+ rk_rng->clk_bulks); -+ if (ret) { -+ dev_err(&pdev->dev, "failed to get clks property\n"); -+ return ret; -+ } -+ -+ platform_set_drvdata(pdev, rk_rng); -+ -+ pm_runtime_set_autosuspend_delay(&pdev->dev, -+ ROCKCHIP_AUTOSUSPEND_DELAY); -+ pm_runtime_use_autosuspend(&pdev->dev); -+ pm_runtime_enable(&pdev->dev); -+ -+ ret = devm_hwrng_register(&pdev->dev, &rk_rng->rng); -+ if (ret) { -+ pm_runtime_dont_use_autosuspend(&pdev->dev); -+ pm_runtime_disable(&pdev->dev); -+ } -+ -+ return ret; -+} -+ -+#ifdef CONFIG_PM -+static int rk_rng_runtime_suspend(struct device *dev) -+{ -+ struct rk_rng *rk_rng = dev_get_drvdata(dev); -+ -+ rk_rng_cleanup(&rk_rng->rng); -+ -+ return 0; -+} -+ -+static int rk_rng_runtime_resume(struct device *dev) -+{ -+ struct rk_rng *rk_rng = dev_get_drvdata(dev); -+ -+ return rk_rng_init(&rk_rng->rng); -+} -+ -+static const struct dev_pm_ops rk_rng_pm_ops = { -+ SET_RUNTIME_PM_OPS(rk_rng_runtime_suspend, -+ rk_rng_runtime_resume, NULL) -+ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, -+ pm_runtime_force_resume) -+}; -+ -+#endif -+ -+static struct platform_driver rk_rng_driver = { -+ .driver = { -+ .name = "rockchip-rng", -+#ifdef CONFIG_PM -+ .pm = &rk_rng_pm_ops, -+#endif -+ .of_match_table = rk_rng_dt_match, -+ }, -+ .probe = rk_rng_probe, -+}; -+ -+module_platform_driver(rk_rng_driver); -+ -+MODULE_DESCRIPTION("ROCKCHIP H/W Random Number Generator driver"); -+MODULE_AUTHOR("Lin Jinhan "); -+MODULE_LICENSE("GPL v2"); -+ --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -32,6 +32,7 @@ obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += diff --git a/root/target/linux/rockchip/patches-5.4/106-arm64-dts-rockchip-add-hardware-random-number-genera.patch b/root/target/linux/rockchip/patches-5.4/106-arm64-dts-rockchip-add-hardware-random-number-genera.patch index aa7c5c39..75e283ab 100644 --- a/root/target/linux/rockchip/patches-5.4/106-arm64-dts-rockchip-add-hardware-random-number-genera.patch +++ b/root/target/linux/rockchip/patches-5.4/106-arm64-dts-rockchip-add-hardware-random-number-genera.patch @@ -42,7 +42,7 @@ Signed-off-by: wevsty + clock-names = "clk_crypto", "hclk_crypto"; + assigned-clocks = <&cru SCLK_CRYPTO1>, <&cru HCLK_S_CRYPTO1>; + assigned-clock-rates = <150000000>, <100000000>; -+ status = "disabled"; ++ status = "okay"; + }; + gpu: gpu@ff9a0000 {