diff --git a/target/linux/mediatek/filogic/config-6.12 b/target/linux/mediatek/filogic/config-6.12 index a6f4ea3d16..9174ffb222 100644 --- a/target/linux/mediatek/filogic/config-6.12 +++ b/target/linux/mediatek/filogic/config-6.12 @@ -222,7 +222,6 @@ CONFIG_HAS_IOPORT_MAP=y CONFIG_HWMON=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_MTK=y -CONFIG_HW_RANDOM_MTK_V2=y CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y diff --git a/target/linux/mediatek/mt7622/config-6.12 b/target/linux/mediatek/mt7622/config-6.12 index 1b8f94ea67..e6f4918692 100644 --- a/target/linux/mediatek/mt7622/config-6.12 +++ b/target/linux/mediatek/mt7622/config-6.12 @@ -221,7 +221,6 @@ CONFIG_HAS_IOPORT_MAP=y CONFIG_HWMON=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_MTK=y -# CONFIG_HW_RANDOM_MTK_V2 is not set CONFIG_I2C=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_CHARDEV=y diff --git a/target/linux/mediatek/mt7629/config-6.12 b/target/linux/mediatek/mt7629/config-6.12 index f54814b8d2..bf657caf5b 100644 --- a/target/linux/mediatek/mt7629/config-6.12 +++ b/target/linux/mediatek/mt7629/config-6.12 @@ -161,7 +161,6 @@ CONFIG_HOTPLUG_CORE_SYNC_DEAD=y CONFIG_HOTPLUG_CPU=y CONFIG_HW_RANDOM=y CONFIG_HW_RANDOM_MTK=y -# CONFIG_HW_RANDOM_MTK_V2 is not set CONFIG_HZ_FIXED=0 # CONFIG_IDPF is not set CONFIG_INITRAMFS_SOURCE="" diff --git a/target/linux/mediatek/patches-6.12/051-v6.16-hwrng-mtk-Add-struct-device-pointer-to-device-contex.patch b/target/linux/mediatek/patches-6.12/051-v6.16-hwrng-mtk-Add-struct-device-pointer-to-device-contex.patch new file mode 100644 index 0000000000..70c771d2df --- /dev/null +++ b/target/linux/mediatek/patches-6.12/051-v6.16-hwrng-mtk-Add-struct-device-pointer-to-device-contex.patch @@ -0,0 +1,60 @@ +From f9c0c36eefaa8c6ee224634bf9c0b8b4ed87b43a Mon Sep 17 00:00:00 2001 +From: Sakari Ailus +Date: Thu, 10 Apr 2025 18:22:38 +0300 +Subject: [PATCH] hwrng: mtk - Add struct device pointer to device context struct + +Add a struct device pointer field to the device's context struct. This +makes using the unsigned long priv pointer in struct hwrng unnecessary, so +remove that one as well. + +Signed-off-by: Sakari Ailus +Signed-off-by: Herbert Xu +--- + drivers/char/hw_random/mtk-rng.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/char/hw_random/mtk-rng.c ++++ b/drivers/char/hw_random/mtk-rng.c +@@ -36,6 +36,7 @@ struct mtk_rng { + void __iomem *base; + struct clk *clk; + struct hwrng rng; ++ struct device *dev; + }; + + static int mtk_rng_init(struct hwrng *rng) +@@ -85,7 +86,7 @@ static int mtk_rng_read(struct hwrng *rn + struct mtk_rng *priv = to_mtk_rng(rng); + int retval = 0; + +- pm_runtime_get_sync((struct device *)priv->rng.priv); ++ pm_runtime_get_sync(priv->dev); + + while (max >= sizeof(u32)) { + if (!mtk_rng_wait_ready(rng, wait)) +@@ -97,8 +98,8 @@ static int mtk_rng_read(struct hwrng *rn + max -= sizeof(u32); + } + +- pm_runtime_mark_last_busy((struct device *)priv->rng.priv); +- pm_runtime_put_sync_autosuspend((struct device *)priv->rng.priv); ++ pm_runtime_mark_last_busy(priv->dev); ++ pm_runtime_put_sync_autosuspend(priv->dev); + + return retval || !wait ? retval : -EIO; + } +@@ -112,13 +113,13 @@ static int mtk_rng_probe(struct platform + if (!priv) + return -ENOMEM; + ++ priv->dev = &pdev->dev; + priv->rng.name = pdev->name; + #ifndef CONFIG_PM + priv->rng.init = mtk_rng_init; + priv->rng.cleanup = mtk_rng_cleanup; + #endif + priv->rng.read = mtk_rng_read; +- priv->rng.priv = (unsigned long)&pdev->dev; + priv->rng.quality = 900; + + priv->clk = devm_clk_get(&pdev->dev, "rng"); diff --git a/target/linux/mediatek/patches-6.12/320-hwrng-add-driver-for-MediaTek-TRNG-SMC.patch b/target/linux/mediatek/patches-6.12/320-hwrng-add-driver-for-MediaTek-TRNG-SMC.patch deleted file mode 100644 index 3d7ca7c3e2..0000000000 --- a/target/linux/mediatek/patches-6.12/320-hwrng-add-driver-for-MediaTek-TRNG-SMC.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 9837930d6738e9fdc323ad887ace7c236a61d70c Mon Sep 17 00:00:00 2001 -From: Daniel Golle -Date: Wed, 25 Jan 2023 00:27:49 +0000 -Subject: [PATCH] hwrng: add driver for MediaTek TRNG SMC - -Add driver providing kernel-side support for the Random Number -Generator hardware found on Mediatek SoCs which have a driver in ARM -TrustedFirmware-A allowing Linux to read random numbers using a -non-standard vendor-defined Secure Monitor Call. - -Signed-off-by: Daniel Golle ---- - drivers/char/hw_random/Kconfig | 16 +++++++ - drivers/char/hw_random/Makefile | 1 + - drivers/char/hw_random/mtk-rng-v2.c | 74 +++++++++++++++++++++++++++++ - 3 files changed, 91 insertions(+) - create mode 100644 drivers/char/hw_random/mtk-rng-v2.c - ---- a/drivers/char/hw_random/Kconfig -+++ b/drivers/char/hw_random/Kconfig -@@ -452,6 +452,23 @@ config HW_RANDOM_MTK - - If unsure, say Y. - -+config HW_RANDOM_MTK_V2 -+ tristate "Mediatek Random Number Generator support (v2/SMC)" -+ depends on HAVE_ARM_SMCCC -+ depends on HW_RANDOM -+ depends on (ARM64 && ARCH_MEDIATEK) || COMPILE_TEST -+ default y -+ help -+ This driver provides kernel-side support for the Random Number -+ Generator hardware found on Mediatek SoCs which have a driver -+ in ARM TrustedFirmware-A allowing Linux to read using a non- -+ standard vendor-defined Secure Monitor Call. -+ -+ To compile this driver as a module, choose M here. the -+ module will be called mtk-rng-v2. -+ -+ If unsure, say Y. -+ - config HW_RANDOM_S390 - tristate "S390 True Random Number Generator support" - depends on S390 ---- a/drivers/char/hw_random/Makefile -+++ b/drivers/char/hw_random/Makefile -@@ -39,6 +39,7 @@ obj-$(CONFIG_HW_RANDOM_PIC32) += pic32-r - obj-$(CONFIG_HW_RANDOM_MESON) += meson-rng.o - obj-$(CONFIG_HW_RANDOM_CAVIUM) += cavium-rng.o cavium-rng-vf.o - obj-$(CONFIG_HW_RANDOM_MTK) += mtk-rng.o -+obj-$(CONFIG_HW_RANDOM_MTK_V2) += mtk-rng-v2.o - obj-$(CONFIG_HW_RANDOM_S390) += s390-trng.o - obj-$(CONFIG_HW_RANDOM_KEYSTONE) += ks-sa-rng.o - obj-$(CONFIG_HW_RANDOM_OPTEE) += optee-rng.o ---- /dev/null -+++ b/drivers/char/hw_random/mtk-rng-v2.c -@@ -0,0 +1,76 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Driver for Mediatek Hardware Random Number Generator (v2/SMCC) -+ * -+ * Copyright (C) 2023 Daniel Golle -+ * based on patch from Mingming Su -+ */ -+#define MTK_RNG_DEV KBUILD_MODNAME -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MTK_SIP_KERNEL_GET_RND MTK_SIP_SMC_CMD(0x550) -+ -+static int mtk_rng_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait) -+{ -+ struct arm_smccc_res res; -+ int retval = 0; -+ -+ while (max >= sizeof(u32)) { -+ arm_smccc_smc(MTK_SIP_KERNEL_GET_RND, 0, 0, 0, 0, 0, 0, 0, -+ &res); -+ if (res.a0) -+ break; -+ -+ *(u32 *)buf = res.a1; -+ retval += sizeof(u32); -+ buf += sizeof(u32); -+ max -= sizeof(u32); -+ } -+ -+ return retval || !wait ? retval : -EIO; -+} -+ -+static int mtk_rng_v2_probe(struct platform_device *pdev) -+{ -+ struct hwrng *trng; -+ -+ trng = devm_kzalloc(&pdev->dev, sizeof(*trng), GFP_KERNEL); -+ if (!trng) -+ return -ENOMEM; -+ -+ trng->name = pdev->name; -+ trng->read = mtk_rng_v2_read; -+ trng->quality = 900; -+ -+ return devm_hwrng_register(&pdev->dev, trng); -+} -+ -+static const struct of_device_id mtk_rng_v2_match[] = { -+ { .compatible = "mediatek,mt7981-rng" }, -+ { .compatible = "mediatek,mt7987-rng" }, -+ { .compatible = "mediatek,mt7988-rng" }, -+ {}, -+}; -+MODULE_DEVICE_TABLE(of, mtk_rng_v2_match); -+ -+static struct platform_driver mtk_rng_v2_driver = { -+ .probe = mtk_rng_v2_probe, -+ .driver = { -+ .name = KBUILD_MODNAME, -+ .of_match_table = mtk_rng_v2_match, -+ }, -+}; -+module_platform_driver(mtk_rng_v2_driver); -+ -+MODULE_DESCRIPTION("Mediatek Random Number Generator Driver (v2/SMC)"); -+MODULE_AUTHOR("Daniel Golle "); -+MODULE_LICENSE("GPL"); diff --git a/target/linux/mediatek/patches-6.12/320-hwrng-mtk-add-support-for-hw-access-via-SMCC.patch b/target/linux/mediatek/patches-6.12/320-hwrng-mtk-add-support-for-hw-access-via-SMCC.patch new file mode 100644 index 0000000000..9bd9d0ab31 --- /dev/null +++ b/target/linux/mediatek/patches-6.12/320-hwrng-mtk-add-support-for-hw-access-via-SMCC.patch @@ -0,0 +1,212 @@ +From d211e2184d820207d14f5e8f84938c639875bf0d Mon Sep 17 00:00:00 2001 +From: Daniel Golle +Date: Tue, 3 Mar 2026 23:45:46 +0000 +Subject: [PATCH] hwrng: mtk - add support for hw access via SMCC + +Newer versions of ARM TrustedFirmware-A on MediaTek's ARMv8 SoCs no longer +allow accessing the TRNG from outside of the trusted firmware. +Instead, a vendor-defined custom Secure Monitor Call can be used to +acquire random bytes. +Add support for newer SoCs (MT7981, MT7987, MT7988). On MT7986 the best bet +is to test if firmware blocks direct access to the hwrng and if so, expect +the SMCC interface to be usable. + +Signed-off-by: Daniel Golle +--- + drivers/char/hw_random/mtk-rng.c | 128 ++++++++++++++++++++++++++----- + 1 file changed, 107 insertions(+), 21 deletions(-) + +--- a/drivers/char/hw_random/mtk-rng.c ++++ b/drivers/char/hw_random/mtk-rng.c +@@ -3,6 +3,7 @@ + * Driver for Mediatek Hardware Random Number Generator + * + * Copyright (C) 2017 Sean Wang ++ * Copyright (C) 2026 Daniel Golle + */ + #define MTK_RNG_DEV KBUILD_MODNAME + +@@ -17,6 +18,8 @@ + #include + #include + #include ++#include ++#include + + /* Runtime PM autosuspend timeout: */ + #define RNG_AUTOSUSPEND_TIMEOUT 100 +@@ -30,6 +33,11 @@ + + #define RNG_DATA 0x08 + ++/* Driver feature flags */ ++#define MTK_RNG_SMC BIT(0) ++ ++#define MTK_SIP_KERNEL_GET_RND MTK_SIP_SMC_CMD(0x550) ++ + #define to_mtk_rng(p) container_of(p, struct mtk_rng, rng) + + struct mtk_rng { +@@ -37,6 +45,7 @@ struct mtk_rng { + struct clk *clk; + struct hwrng rng; + struct device *dev; ++ unsigned long flags; + }; + + static int mtk_rng_init(struct hwrng *rng) +@@ -104,6 +113,56 @@ static int mtk_rng_read(struct hwrng *rn + return retval || !wait ? retval : -EIO; + } + ++static int mtk_rng_read_smc(struct hwrng *rng, void *buf, size_t max, ++ bool wait) ++{ ++ struct arm_smccc_res res; ++ int retval = 0; ++ ++ while (max >= sizeof(u32)) { ++ arm_smccc_smc(MTK_SIP_KERNEL_GET_RND, 0, 0, 0, 0, 0, 0, 0, ++ &res); ++ if (res.a0) ++ break; ++ ++ *(u32 *)buf = res.a1; ++ retval += sizeof(u32); ++ buf += sizeof(u32); ++ max -= sizeof(u32); ++ } ++ ++ return retval || !wait ? retval : -EIO; ++} ++ ++static bool mtk_rng_hw_accessible(struct mtk_rng *priv) ++{ ++ u32 val; ++ int err; ++ ++ err = clk_prepare_enable(priv->clk); ++ if (err) ++ return false; ++ ++ val = readl(priv->base + RNG_CTRL); ++ val |= RNG_EN; ++ writel(val, priv->base + RNG_CTRL); ++ ++ val = readl(priv->base + RNG_CTRL); ++ ++ if (val & RNG_EN) { ++ /* HW is accessible, clean up: disable RNG and clock */ ++ writel(val & ~RNG_EN, priv->base + RNG_CTRL); ++ clk_disable_unprepare(priv->clk); ++ return true; ++ } ++ ++ /* ++ * If TF-A blocks direct access, the register reads back as 0. ++ * Leave the clock enabled as TF-A's SMC handler needs it. ++ */ ++ return false; ++} ++ + static int mtk_rng_probe(struct platform_device *pdev) + { + int ret; +@@ -115,23 +174,42 @@ static int mtk_rng_probe(struct platform + + priv->dev = &pdev->dev; + priv->rng.name = pdev->name; +-#ifndef CONFIG_PM +- priv->rng.init = mtk_rng_init; +- priv->rng.cleanup = mtk_rng_cleanup; +-#endif +- priv->rng.read = mtk_rng_read; + priv->rng.quality = 900; ++ priv->flags = (unsigned long)device_get_match_data(&pdev->dev); + +- priv->clk = devm_clk_get(&pdev->dev, "rng"); +- if (IS_ERR(priv->clk)) { +- ret = PTR_ERR(priv->clk); +- dev_err(&pdev->dev, "no clock for device: %d\n", ret); +- return ret; ++ if (!(priv->flags & MTK_RNG_SMC)) { ++ priv->clk = devm_clk_get(&pdev->dev, "rng"); ++ if (IS_ERR(priv->clk)) { ++ ret = PTR_ERR(priv->clk); ++ dev_err(&pdev->dev, "no clock for device: %d\n", ret); ++ return ret; ++ } ++ ++ priv->base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(priv->base)) ++ return PTR_ERR(priv->base); ++ ++ if (IS_ENABLED(CONFIG_HAVE_ARM_SMCCC) && ++ of_device_is_compatible(pdev->dev.of_node, ++ "mediatek,mt7986-rng") && ++ !mtk_rng_hw_accessible(priv)) { ++ priv->flags |= MTK_RNG_SMC; ++ dev_info(&pdev->dev, ++ "HW RNG not MMIO accessible, using SMC\n"); ++ } + } + +- priv->base = devm_platform_ioremap_resource(pdev, 0); +- if (IS_ERR(priv->base)) +- return PTR_ERR(priv->base); ++ if (priv->flags & MTK_RNG_SMC) { ++ if (!IS_ENABLED(CONFIG_HAVE_ARM_SMCCC)) ++ return -ENODEV; ++ priv->rng.read = mtk_rng_read_smc; ++ } else { ++#ifndef CONFIG_PM ++ priv->rng.init = mtk_rng_init; ++ priv->rng.cleanup = mtk_rng_cleanup; ++#endif ++ priv->rng.read = mtk_rng_read; ++ } + + ret = devm_hwrng_register(&pdev->dev, &priv->rng); + if (ret) { +@@ -140,12 +218,15 @@ static int mtk_rng_probe(struct platform + return ret; + } + +- dev_set_drvdata(&pdev->dev, priv); +- pm_runtime_set_autosuspend_delay(&pdev->dev, RNG_AUTOSUSPEND_TIMEOUT); +- pm_runtime_use_autosuspend(&pdev->dev); +- ret = devm_pm_runtime_enable(&pdev->dev); +- if (ret) +- return ret; ++ if (!(priv->flags & MTK_RNG_SMC)) { ++ dev_set_drvdata(&pdev->dev, priv); ++ pm_runtime_set_autosuspend_delay(&pdev->dev, ++ RNG_AUTOSUSPEND_TIMEOUT); ++ pm_runtime_use_autosuspend(&pdev->dev); ++ ret = devm_pm_runtime_enable(&pdev->dev); ++ if (ret) ++ return ret; ++ } + + dev_info(&pdev->dev, "registered RNG driver\n"); + +@@ -182,8 +263,12 @@ static const struct dev_pm_ops mtk_rng_p + #endif /* CONFIG_PM */ + + static const struct of_device_id mtk_rng_match[] = { +- { .compatible = "mediatek,mt7986-rng" }, + { .compatible = "mediatek,mt7623-rng" }, ++ { .compatible = "mediatek,mt7622-rng" }, ++ { .compatible = "mediatek,mt7981-rng", .data = (void *)MTK_RNG_SMC }, ++ { .compatible = "mediatek,mt7986-rng" }, ++ { .compatible = "mediatek,mt7987-rng", .data = (void *)MTK_RNG_SMC }, ++ { .compatible = "mediatek,mt7988-rng", .data = (void *)MTK_RNG_SMC }, + {}, + }; + MODULE_DEVICE_TABLE(of, mtk_rng_match); +@@ -201,4 +286,5 @@ module_platform_driver(mtk_rng_driver); + + MODULE_DESCRIPTION("Mediatek Random Number Generator Driver"); + MODULE_AUTHOR("Sean Wang "); ++MODULE_AUTHOR("Daniel Golle "); + MODULE_LICENSE("GPL");