1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Driver for Mediatek Hardware Random Number Generator 4 * 5 * Copyright (C) 2017 Sean Wang <sean.wang@mediatek.com> 6 * Copyright (C) 2026 Daniel Golle <daniel@makrotopia.org> 7 */ 8 #define MTK_RNG_DEV KBUILD_MODNAME 9 10 #include <linux/arm-smccc.h> 11 #include <linux/clk.h> 12 #include <linux/delay.h> 13 #include <linux/err.h> 14 #include <linux/hw_random.h> 15 #include <linux/io.h> 16 #include <linux/iopoll.h> 17 #include <linux/kernel.h> 18 #include <linux/module.h> 19 #include <linux/of.h> 20 #include <linux/platform_device.h> 21 #include <linux/pm_runtime.h> 22 #include <linux/soc/mediatek/mtk_sip_svc.h> 23 24 /* Runtime PM autosuspend timeout: */ 25 #define RNG_AUTOSUSPEND_TIMEOUT 100 26 27 #define USEC_POLL 2 28 #define TIMEOUT_POLL 60 29 30 #define RNG_CTRL 0x00 31 #define RNG_EN BIT(0) 32 #define RNG_READY BIT(31) 33 34 #define RNG_DATA 0x08 35 36 /* Driver feature flags */ 37 #define MTK_RNG_SMC BIT(0) 38 39 #define MTK_SIP_KERNEL_GET_RND MTK_SIP_SMC_CMD(0x550) 40 41 #define to_mtk_rng(p) container_of(p, struct mtk_rng, rng) 42 43 struct mtk_rng { 44 void __iomem *base; 45 struct clk *clk; 46 struct hwrng rng; 47 struct device *dev; 48 unsigned long flags; 49 }; 50 51 static int mtk_rng_init(struct hwrng *rng) 52 { 53 struct mtk_rng *priv = to_mtk_rng(rng); 54 u32 val; 55 int err; 56 57 err = clk_prepare_enable(priv->clk); 58 if (err) 59 return err; 60 61 val = readl(priv->base + RNG_CTRL); 62 val |= RNG_EN; 63 writel(val, priv->base + RNG_CTRL); 64 65 return 0; 66 } 67 68 static void mtk_rng_cleanup(struct hwrng *rng) 69 { 70 struct mtk_rng *priv = to_mtk_rng(rng); 71 u32 val; 72 73 val = readl(priv->base + RNG_CTRL); 74 val &= ~RNG_EN; 75 writel(val, priv->base + RNG_CTRL); 76 77 clk_disable_unprepare(priv->clk); 78 } 79 80 static bool mtk_rng_wait_ready(struct hwrng *rng, bool wait) 81 { 82 struct mtk_rng *priv = to_mtk_rng(rng); 83 int ready; 84 85 ready = readl(priv->base + RNG_CTRL) & RNG_READY; 86 if (!ready && wait) 87 readl_poll_timeout_atomic(priv->base + RNG_CTRL, ready, 88 ready & RNG_READY, USEC_POLL, 89 TIMEOUT_POLL); 90 return !!(ready & RNG_READY); 91 } 92 93 static int mtk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) 94 { 95 struct mtk_rng *priv = to_mtk_rng(rng); 96 int retval = 0; 97 98 pm_runtime_get_sync(priv->dev); 99 100 while (max >= sizeof(u32)) { 101 if (!mtk_rng_wait_ready(rng, wait)) 102 break; 103 104 *(u32 *)buf = readl(priv->base + RNG_DATA); 105 retval += sizeof(u32); 106 buf += sizeof(u32); 107 max -= sizeof(u32); 108 } 109 110 pm_runtime_put_sync_autosuspend(priv->dev); 111 112 return retval || !wait ? retval : -EIO; 113 } 114 115 static int mtk_rng_read_smc(struct hwrng *rng, void *buf, size_t max, 116 bool wait) 117 { 118 struct arm_smccc_res res; 119 int retval = 0; 120 121 while (max >= sizeof(u32)) { 122 arm_smccc_smc(MTK_SIP_KERNEL_GET_RND, 0, 0, 0, 0, 0, 0, 0, 123 &res); 124 if (res.a0) 125 break; 126 127 *(u32 *)buf = res.a1; 128 retval += sizeof(u32); 129 buf += sizeof(u32); 130 max -= sizeof(u32); 131 } 132 133 return retval || !wait ? retval : -EIO; 134 } 135 136 static bool mtk_rng_hw_accessible(struct mtk_rng *priv) 137 { 138 u32 val; 139 int err; 140 141 err = clk_prepare_enable(priv->clk); 142 if (err) 143 return false; 144 145 val = readl(priv->base + RNG_CTRL); 146 val |= RNG_EN; 147 writel(val, priv->base + RNG_CTRL); 148 149 val = readl(priv->base + RNG_CTRL); 150 151 if (val & RNG_EN) { 152 /* HW is accessible, clean up: disable RNG and clock */ 153 writel(val & ~RNG_EN, priv->base + RNG_CTRL); 154 clk_disable_unprepare(priv->clk); 155 return true; 156 } 157 158 /* 159 * If TF-A blocks direct access, the register reads back as 0. 160 * Leave the clock enabled as TF-A needs it. 161 */ 162 return false; 163 } 164 165 static int mtk_rng_probe(struct platform_device *pdev) 166 { 167 int ret; 168 struct mtk_rng *priv; 169 170 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 171 if (!priv) 172 return -ENOMEM; 173 174 priv->dev = &pdev->dev; 175 priv->rng.name = pdev->name; 176 priv->rng.quality = 900; 177 priv->flags = (unsigned long)device_get_match_data(&pdev->dev); 178 179 if (!(priv->flags & MTK_RNG_SMC)) { 180 priv->clk = devm_clk_get(&pdev->dev, "rng"); 181 if (IS_ERR(priv->clk)) { 182 ret = PTR_ERR(priv->clk); 183 dev_err(&pdev->dev, "no clock for device: %d\n", ret); 184 return ret; 185 } 186 187 priv->base = devm_platform_ioremap_resource(pdev, 0); 188 if (IS_ERR(priv->base)) 189 return PTR_ERR(priv->base); 190 191 if (IS_ENABLED(CONFIG_HAVE_ARM_SMCCC) && 192 of_device_is_compatible(pdev->dev.of_node, 193 "mediatek,mt7986-rng") && 194 !mtk_rng_hw_accessible(priv)) { 195 priv->flags |= MTK_RNG_SMC; 196 dev_info(&pdev->dev, 197 "HW RNG not MMIO accessible, using SMC\n"); 198 } 199 } 200 201 if (priv->flags & MTK_RNG_SMC) { 202 if (!IS_ENABLED(CONFIG_HAVE_ARM_SMCCC)) 203 return -ENODEV; 204 priv->rng.read = mtk_rng_read_smc; 205 } else { 206 #ifndef CONFIG_PM 207 priv->rng.init = mtk_rng_init; 208 priv->rng.cleanup = mtk_rng_cleanup; 209 #endif 210 priv->rng.read = mtk_rng_read; 211 } 212 213 ret = devm_hwrng_register(&pdev->dev, &priv->rng); 214 if (ret) { 215 dev_err(&pdev->dev, "failed to register rng device: %d\n", 216 ret); 217 return ret; 218 } 219 220 if (!(priv->flags & MTK_RNG_SMC)) { 221 dev_set_drvdata(&pdev->dev, priv); 222 pm_runtime_set_autosuspend_delay(&pdev->dev, 223 RNG_AUTOSUSPEND_TIMEOUT); 224 pm_runtime_use_autosuspend(&pdev->dev); 225 ret = devm_pm_runtime_enable(&pdev->dev); 226 if (ret) 227 return ret; 228 } 229 230 dev_info(&pdev->dev, "registered RNG driver\n"); 231 232 return 0; 233 } 234 235 #ifdef CONFIG_PM 236 static int mtk_rng_runtime_suspend(struct device *dev) 237 { 238 struct mtk_rng *priv = dev_get_drvdata(dev); 239 240 mtk_rng_cleanup(&priv->rng); 241 242 return 0; 243 } 244 245 static int mtk_rng_runtime_resume(struct device *dev) 246 { 247 struct mtk_rng *priv = dev_get_drvdata(dev); 248 249 return mtk_rng_init(&priv->rng); 250 } 251 252 static const struct dev_pm_ops mtk_rng_pm_ops = { 253 SET_RUNTIME_PM_OPS(mtk_rng_runtime_suspend, 254 mtk_rng_runtime_resume, NULL) 255 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 256 pm_runtime_force_resume) 257 }; 258 259 #define MTK_RNG_PM_OPS (&mtk_rng_pm_ops) 260 #else /* CONFIG_PM */ 261 #define MTK_RNG_PM_OPS NULL 262 #endif /* CONFIG_PM */ 263 264 static const struct of_device_id mtk_rng_match[] = { 265 { .compatible = "mediatek,mt7623-rng" }, 266 { .compatible = "mediatek,mt7981-rng", .data = (void *)MTK_RNG_SMC }, 267 { .compatible = "mediatek,mt7986-rng" }, 268 { .compatible = "mediatek,mt7987-rng", .data = (void *)MTK_RNG_SMC }, 269 { .compatible = "mediatek,mt7988-rng", .data = (void *)MTK_RNG_SMC }, 270 {}, 271 }; 272 MODULE_DEVICE_TABLE(of, mtk_rng_match); 273 274 static struct platform_driver mtk_rng_driver = { 275 .probe = mtk_rng_probe, 276 .driver = { 277 .name = MTK_RNG_DEV, 278 .pm = MTK_RNG_PM_OPS, 279 .of_match_table = mtk_rng_match, 280 }, 281 }; 282 283 module_platform_driver(mtk_rng_driver); 284 285 MODULE_DESCRIPTION("Mediatek Random Number Generator Driver"); 286 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); 287 MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>"); 288 MODULE_LICENSE("GPL"); 289