hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/char/hw_random/ks-sa-rng.c
....@@ -1,19 +1,11 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Random Number Generator driver for the Keystone SOC
34 *
4
- * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com
5
+ * Copyright (C) 2016 Texas Instruments Incorporated - https://www.ti.com
56 *
67 * Authors: Sandeep Nair
78 * Vitaly Andrianov
8
- *
9
- * This program is free software; you can redistribute it and/or
10
- * modify it under the terms of the GNU General Public License
11
- * version 2 as published by the Free Software Foundation.
12
- *
13
- * This program is distributed in the hope that it will be useful, but
14
- * WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
- * General Public License for more details.
179 */
1810
1911 #include <linux/hw_random.h>
....@@ -29,6 +21,7 @@
2921 #include <linux/of.h>
3022 #include <linux/of_address.h>
3123 #include <linux/delay.h>
24
+#include <linux/timekeeping.h>
3225
3326 #define SA_CMD_STATUS_OFS 0x8
3427
....@@ -92,14 +85,37 @@
9285 struct hwrng rng;
9386 struct clk *clk;
9487 struct regmap *regmap_cfg;
95
- struct trng_regs *reg_rng;
88
+ struct trng_regs __iomem *reg_rng;
89
+ u64 ready_ts;
90
+ unsigned int refill_delay_ns;
9691 };
92
+
93
+static unsigned int cycles_to_ns(unsigned long clk_rate, unsigned int cycles)
94
+{
95
+ return DIV_ROUND_UP_ULL((TRNG_DEF_CLK_DIV_CYCLES + 1) * 1000000000ull *
96
+ cycles, clk_rate);
97
+}
98
+
99
+static unsigned int startup_delay_ns(unsigned long clk_rate)
100
+{
101
+ if (!TRNG_DEF_STARTUP_CYCLES)
102
+ return cycles_to_ns(clk_rate, BIT(24));
103
+ return cycles_to_ns(clk_rate, 256 * TRNG_DEF_STARTUP_CYCLES);
104
+}
105
+
106
+static unsigned int refill_delay_ns(unsigned long clk_rate)
107
+{
108
+ if (!TRNG_DEF_MAX_REFILL_CYCLES)
109
+ return cycles_to_ns(clk_rate, BIT(24));
110
+ return cycles_to_ns(clk_rate, 256 * TRNG_DEF_MAX_REFILL_CYCLES);
111
+}
97112
98113 static int ks_sa_rng_init(struct hwrng *rng)
99114 {
100115 u32 value;
101116 struct device *dev = (struct device *)rng->priv;
102117 struct ks_sa_rng *ks_sa_rng = dev_get_drvdata(dev);
118
+ unsigned long clk_rate = clk_get_rate(ks_sa_rng->clk);
103119
104120 /* Enable RNG module */
105121 regmap_write_bits(ks_sa_rng->regmap_cfg, SA_CMD_STATUS_OFS,
....@@ -128,6 +144,10 @@
128144 value |= TRNG_CNTL_REG_TRNG_ENABLE;
129145 writel(value, &ks_sa_rng->reg_rng->control);
130146
147
+ ks_sa_rng->refill_delay_ns = refill_delay_ns(clk_rate);
148
+ ks_sa_rng->ready_ts = ktime_get_ns() +
149
+ startup_delay_ns(clk_rate);
150
+
131151 return 0;
132152 }
133153
....@@ -152,6 +172,7 @@
152172 data[1] = readl(&ks_sa_rng->reg_rng->output_h);
153173
154174 writel(TRNG_INTACK_REG_READY, &ks_sa_rng->reg_rng->intack);
175
+ ks_sa_rng->ready_ts = ktime_get_ns() + ks_sa_rng->refill_delay_ns;
155176
156177 return sizeof(u32) * 2;
157178 }
....@@ -160,9 +181,18 @@
160181 {
161182 struct device *dev = (struct device *)rng->priv;
162183 struct ks_sa_rng *ks_sa_rng = dev_get_drvdata(dev);
184
+ u64 now = ktime_get_ns();
163185
164186 u32 ready;
165187 int j;
188
+
189
+ if (wait && now < ks_sa_rng->ready_ts) {
190
+ /* Max delay expected here is 81920000 ns */
191
+ unsigned long min_delay =
192
+ DIV_ROUND_UP((u32)(ks_sa_rng->ready_ts - now), 1000);
193
+
194
+ usleep_range(min_delay, min_delay + SA_RNG_DATA_RETRY_DELAY);
195
+ }
166196
167197 for (j = 0; j < SA_MAX_RNG_DATA_RETRIES; j++) {
168198 ready = readl(&ks_sa_rng->reg_rng->status);
....@@ -182,7 +212,6 @@
182212 struct ks_sa_rng *ks_sa_rng;
183213 struct device *dev = &pdev->dev;
184214 int ret;
185
- struct resource *mem;
186215
187216 ks_sa_rng = devm_kzalloc(dev, sizeof(*ks_sa_rng), GFP_KERNEL);
188217 if (!ks_sa_rng)
....@@ -198,8 +227,7 @@
198227 };
199228 ks_sa_rng->rng.priv = (unsigned long)dev;
200229
201
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
202
- ks_sa_rng->reg_rng = devm_ioremap_resource(dev, mem);
230
+ ks_sa_rng->reg_rng = devm_platform_ioremap_resource(pdev, 0);
203231 if (IS_ERR(ks_sa_rng->reg_rng))
204232 return PTR_ERR(ks_sa_rng->reg_rng);
205233