xref: /linux/drivers/char/hw_random/mtk-rng.c (revision bba2c3615bd6cfee7456d1130f2e6b01b3f4e9ba)
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