blob: 7c09a7102b0f8580cf980ddde4963f8be58ca208 [file] [log] [blame]
developerb0e74f92021-12-17 21:07:00 +08001From ae5611b1b7a857edb3d9c8e900b550c76f7c236e Mon Sep 17 00:00:00 2001
2From: "Mingming.Su" <Mingming.Su@mediatek.com>
3Date: Fri, 17 Dec 2021 20:27:34 +0800
4Subject: [PATCH] Add trngv2 driver support
5
6---
7 drivers/char/hw_random/mtk-rng.c | 105 +++++++++++++++++++++++--------
8 1 file changed, 78 insertions(+), 27 deletions(-)
9
10diff --git a/drivers/char/hw_random/mtk-rng.c b/drivers/char/hw_random/mtk-rng.c
11index a8bd06da7..75fca4cef 100644
12--- a/drivers/char/hw_random/mtk-rng.c
13+++ b/drivers/char/hw_random/mtk-rng.c
14@@ -6,6 +6,7 @@
15 */
16 #define MTK_RNG_DEV KBUILD_MODNAME
17
18+#include <linux/arm-smccc.h>
19 #include <linux/clk.h>
20 #include <linux/delay.h>
21 #include <linux/err.h>
22@@ -15,8 +16,12 @@
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/of.h>
26+#include <linux/of_device.h>
27 #include <linux/platform_device.h>
28 #include <linux/pm_runtime.h>
29+#include <linux/soc/mediatek/mtk_sip_svc.h>
30+
31+#define MTK_SIP_KERNEL_GET_RND MTK_SIP_SMC_CMD(0x550)
32
33 /* Runtime PM autosuspend timeout: */
34 #define RNG_AUTOSUSPEND_TIMEOUT 100
35@@ -32,10 +37,15 @@
36
37 #define to_mtk_rng(p) container_of(p, struct mtk_rng, rng)
38
39+struct mtk_rng_of_data{
40+ unsigned int rng_version;
41+};
42+
43 struct mtk_rng {
44 void __iomem *base;
45 struct clk *clk;
46 struct hwrng rng;
47+ const struct mtk_rng_of_data *soc;
48 };
49
50 static int mtk_rng_init(struct hwrng *rng)
51@@ -103,41 +113,74 @@ static int mtk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
52 return retval || !wait ? retval : -EIO;
53 }
54
55+static int mtk_rngv2_read(struct hwrng *rng, void *buf, size_t max, bool wait)
56+{
57+ struct arm_smccc_res res;
58+ int retval = 0;
59+
60+ while (max >= sizeof(u32)) {
61+ arm_smccc_smc(MTK_SIP_KERNEL_GET_RND, 0, 0, 0, 0, 0, 0, 0,
62+ &res);
63+ if (res.a0)
64+ break;
65+
66+ *(u32 *)buf = res.a1;
67+ retval += sizeof(u32);
68+ buf += sizeof(u32);
69+ max -= sizeof(u32);
70+ }
71+
72+ return retval || !wait ? retval : -EIO;
73+}
74+
75 static int mtk_rng_probe(struct platform_device *pdev)
76 {
77 struct resource *res;
78 int ret;
79 struct mtk_rng *priv;
80
81- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
82- if (!res) {
83- dev_err(&pdev->dev, "no iomem resource\n");
84- return -ENXIO;
85- }
86-
87 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
88 if (!priv)
89 return -ENOMEM;
90
91- priv->rng.name = pdev->name;
92+ priv->soc = of_device_get_match_data(&pdev->dev);
93+ if (priv->soc->rng_version == 1) {
94+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
95+ if (!res) {
96+ dev_err(&pdev->dev, "no iomem resource\n");
97+ return -ENXIO;
98+ }
99+
100+ priv->base = devm_ioremap_resource(&pdev->dev, res);
101+ if (IS_ERR(priv->base))
102+ return PTR_ERR(priv->base);
103+
104+ priv->clk = devm_clk_get(&pdev->dev, "rng");
105+ if (IS_ERR(priv->clk)) {
106+ ret = PTR_ERR(priv->clk);
107+ dev_err(&pdev->dev, "no clock for device: %d\n", ret);
108+ return ret;
109+ }
110+
111 #ifndef CONFIG_PM
112- priv->rng.init = mtk_rng_init;
113- priv->rng.cleanup = mtk_rng_cleanup;
114+ priv->rng.init = mtk_rng_init;
115+ priv->rng.cleanup = mtk_rng_cleanup;
116 #endif
117- priv->rng.read = mtk_rng_read;
118+ priv->rng.read = mtk_rng_read;
119+
120+ pm_runtime_set_autosuspend_delay(&pdev->dev,
121+ RNG_AUTOSUSPEND_TIMEOUT);
122+ pm_runtime_use_autosuspend(&pdev->dev);
123+ pm_runtime_enable(&pdev->dev);
124+ } else {
125+ priv->rng.read = mtk_rngv2_read;
126+ }
127+
128+ priv->rng.name = pdev->name;
129 priv->rng.priv = (unsigned long)&pdev->dev;
130 priv->rng.quality = 900;
131
132- priv->clk = devm_clk_get(&pdev->dev, "rng");
133- if (IS_ERR(priv->clk)) {
134- ret = PTR_ERR(priv->clk);
135- dev_err(&pdev->dev, "no clock for device: %d\n", ret);
136- return ret;
137- }
138-
139- priv->base = devm_ioremap_resource(&pdev->dev, res);
140- if (IS_ERR(priv->base))
141- return PTR_ERR(priv->base);
142+ dev_set_drvdata(&pdev->dev, priv);
143
144 ret = devm_hwrng_register(&pdev->dev, &priv->rng);
145 if (ret) {
146@@ -146,11 +189,6 @@ static int mtk_rng_probe(struct platform_device *pdev)
147 return ret;
148 }
149
150- dev_set_drvdata(&pdev->dev, priv);
151- pm_runtime_set_autosuspend_delay(&pdev->dev, RNG_AUTOSUSPEND_TIMEOUT);
152- pm_runtime_use_autosuspend(&pdev->dev);
153- pm_runtime_enable(&pdev->dev);
154-
155 dev_info(&pdev->dev, "registered RNG driver\n");
156
157 return 0;
158@@ -185,9 +223,22 @@ static const struct dev_pm_ops mtk_rng_pm_ops = {
159 #define MTK_RNG_PM_OPS NULL
160 #endif /* CONFIG_PM */
161
162+static const struct mtk_rng_of_data mt7981_rng_data = {
163+ .rng_version = 2,
164+};
165+
166+static const struct mtk_rng_of_data mt7986_rng_data = {
167+ .rng_version = 1,
168+};
169+
170+static const struct mtk_rng_of_data mt7623_rng_data = {
171+ .rng_version = 1,
172+};
173+
174 static const struct of_device_id mtk_rng_match[] = {
175- { .compatible = "mediatek,mt7986-rng" },
176- { .compatible = "mediatek,mt7623-rng" },
177+ { .compatible = "mediatek,mt7981-rng", .data = &mt7981_rng_data },
178+ { .compatible = "mediatek,mt7986-rng", .data = &mt7986_rng_data },
179+ { .compatible = "mediatek,mt7623-rng", .data = &mt7623_rng_data },
180 {},
181 };
182 MODULE_DEVICE_TABLE(of, mtk_rng_match);
183--
1842.18.0
185