hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/drivers/char/hw_random/rockchip-rng.c
....@@ -87,6 +87,27 @@
8787 #define TRNG_v1_VERSION_CODE 0x46bc
8888 /* end of TRNG_V1 register define */
8989
90
+/* start of RKRNG register define */
91
+#define RKRNG_CTRL 0x0010
92
+#define RKRNG_CTRL_INST_REQ BIT(0)
93
+#define RKRNG_CTRL_RESEED_REQ BIT(1)
94
+#define RKRNG_CTRL_TEST_REQ BIT(2)
95
+#define RKRNG_CTRL_SW_DRNG_REQ BIT(3)
96
+#define RKRNG_CTRL_SW_TRNG_REQ BIT(4)
97
+
98
+#define RKRNG_STATE 0x0014
99
+#define RKRNG_STATE_INST_ACK BIT(0)
100
+#define RKRNG_STATE_RESEED_ACK BIT(1)
101
+#define RKRNG_STATE_TEST_ACK BIT(2)
102
+#define RKRNG_STATE_SW_DRNG_ACK BIT(3)
103
+#define RKRNG_STATE_SW_TRNG_ACK BIT(4)
104
+
105
+/* DRNG_DATA_0 ~ DNG_DATA_7 */
106
+#define RKRNG_DRNG_DATA_0 0x0070
107
+#define RKRNG_DRNG_DATA_7 0x008C
108
+
109
+/* end of RKRNG register define */
110
+
90111 struct rk_rng_soc_data {
91112 u32 default_offset;
92113
....@@ -178,7 +199,7 @@
178199 *(u32 *)(buf + i) = be32_to_cpu(rk_rng_readl(rng, offset + i));
179200 }
180201
181
-static int rk_crypto_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait)
202
+static int crypto_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait)
182203 {
183204 int ret = 0;
184205 u32 reg_ctrl = 0;
....@@ -192,10 +213,12 @@
192213
193214 rk_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_CTRL);
194215
195
- ret = readl_poll_timeout(rk_rng->mem + CRYPTO_V1_CTRL, reg_ctrl,
196
- !(reg_ctrl & CRYPTO_V1_RNG_START),
197
- ROCKCHIP_POLL_PERIOD_US,
198
- ROCKCHIP_POLL_TIMEOUT_US);
216
+ ret = read_poll_timeout(rk_rng_readl, reg_ctrl,
217
+ !(reg_ctrl & CRYPTO_V1_RNG_START),
218
+ ROCKCHIP_POLL_PERIOD_US,
219
+ ROCKCHIP_POLL_TIMEOUT_US, false,
220
+ rk_rng, CRYPTO_V1_CTRL);
221
+
199222 if (ret < 0)
200223 goto out;
201224
....@@ -211,7 +234,7 @@
211234 return ret;
212235 }
213236
214
-static int rk_crypto_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait)
237
+static int crypto_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait)
215238 {
216239 int ret = 0;
217240 u32 reg_ctrl = 0;
....@@ -228,10 +251,11 @@
228251 rk_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0),
229252 CRYPTO_V2_RNG_CTL);
230253
231
- ret = readl_poll_timeout(rk_rng->mem + CRYPTO_V2_RNG_CTL, reg_ctrl,
232
- !(reg_ctrl & CRYPTO_V2_RNG_START),
233
- ROCKCHIP_POLL_PERIOD_US,
234
- ROCKCHIP_POLL_TIMEOUT_US);
254
+ ret = read_poll_timeout(rk_rng_readl, reg_ctrl,
255
+ !(reg_ctrl & CRYPTO_V2_RNG_START),
256
+ ROCKCHIP_POLL_PERIOD_US,
257
+ ROCKCHIP_POLL_TIMEOUT_US, false,
258
+ rk_rng, CRYPTO_V2_RNG_CTL);
235259 if (ret < 0)
236260 goto out;
237261
....@@ -246,18 +270,12 @@
246270 return ret;
247271 }
248272
249
-static int rk_trng_v1_init(struct hwrng *rng)
273
+static int trng_v1_init(struct hwrng *rng)
250274 {
251275 int ret;
252276 uint32_t auto_reseed_cnt = 1000;
253277 uint32_t reg_ctrl, status, version;
254278 struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
255
-
256
- ret = pm_runtime_get_sync(rk_rng->dev);
257
- if (ret < 0) {
258
- pm_runtime_put_noidle(rk_rng->dev);
259
- return ret;
260
- }
261279
262280 version = rk_rng_readl(rk_rng, TRNG_V1_VERSION);
263281 if (version != TRNG_v1_VERSION_CODE) {
....@@ -281,10 +299,11 @@
281299 udelay(10);
282300
283301 /* wait for GENERATING and RESEEDING flag to clear */
284
- readl_poll_timeout(rk_rng->mem + TRNG_V1_STAT, reg_ctrl,
285
- (reg_ctrl & mask) == TRNG_V1_STAT_SEEDED,
286
- ROCKCHIP_POLL_PERIOD_US,
287
- ROCKCHIP_POLL_TIMEOUT_US);
302
+ read_poll_timeout(rk_rng_readl, reg_ctrl,
303
+ (reg_ctrl & mask) == TRNG_V1_STAT_SEEDED,
304
+ ROCKCHIP_POLL_PERIOD_US,
305
+ ROCKCHIP_POLL_TIMEOUT_US, false,
306
+ rk_rng, TRNG_V1_STAT);
288307 }
289308
290309 /* clear ISTAT flag because trng may auto reseeding when power on */
....@@ -296,13 +315,11 @@
296315
297316 ret = 0;
298317 exit:
299
- pm_runtime_mark_last_busy(rk_rng->dev);
300
- pm_runtime_put_sync_autosuspend(rk_rng->dev);
301318
302319 return ret;
303320 }
304321
305
-static int rk_trng_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait)
322
+static int trng_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait)
306323 {
307324 int ret = 0;
308325 u32 reg_ctrl = 0;
....@@ -324,10 +341,11 @@
324341 reg_ctrl = rk_rng_readl(rk_rng, TRNG_V1_ISTAT);
325342 if (!(reg_ctrl & TRNG_V1_ISTAT_RAND_RDY)) {
326343 /* wait RAND_RDY triggered */
327
- ret = readl_poll_timeout(rk_rng->mem + TRNG_V1_ISTAT, reg_ctrl,
328
- (reg_ctrl & TRNG_V1_ISTAT_RAND_RDY),
329
- ROCKCHIP_POLL_PERIOD_US,
330
- ROCKCHIP_POLL_TIMEOUT_US);
344
+ ret = read_poll_timeout(rk_rng_readl, reg_ctrl,
345
+ (reg_ctrl & TRNG_V1_ISTAT_RAND_RDY),
346
+ ROCKCHIP_POLL_PERIOD_US,
347
+ ROCKCHIP_POLL_TIMEOUT_US, false,
348
+ rk_rng, TRNG_V1_ISTAT);
331349 if (ret < 0)
332350 goto out;
333351 }
....@@ -345,37 +363,92 @@
345363 return ret;
346364 }
347365
348
-static const struct rk_rng_soc_data rk_crypto_v1_soc_data = {
366
+static int rkrng_init(struct hwrng *rng)
367
+{
368
+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
369
+ u32 reg = 0;
370
+
371
+ rk_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), RKRNG_CTRL);
372
+
373
+ reg = rk_rng_readl(rk_rng, RKRNG_STATE);
374
+ rk_rng_writel(rk_rng, reg, RKRNG_STATE);
375
+
376
+ return 0;
377
+}
378
+
379
+static int rkrng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
380
+{
381
+ struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng);
382
+ u32 reg_ctrl = 0;
383
+ int ret;
384
+
385
+ reg_ctrl = RKRNG_CTRL_SW_DRNG_REQ;
386
+
387
+ rk_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0), RKRNG_CTRL);
388
+
389
+ ret = readl_poll_timeout(rk_rng->mem + RKRNG_STATE, reg_ctrl,
390
+ (reg_ctrl & RKRNG_STATE_SW_DRNG_ACK),
391
+ ROCKCHIP_POLL_PERIOD_US,
392
+ ROCKCHIP_POLL_TIMEOUT_US);
393
+
394
+ if (ret)
395
+ goto exit;
396
+
397
+ rk_rng_writel(rk_rng, reg_ctrl, RKRNG_STATE);
398
+
399
+ ret = min_t(size_t, max, RK_MAX_RNG_BYTE);
400
+
401
+ rk_rng_read_regs(rk_rng, RKRNG_DRNG_DATA_0, buf, ret);
402
+
403
+exit:
404
+ /* close TRNG */
405
+ rk_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), RKRNG_CTRL);
406
+
407
+ return ret;
408
+}
409
+
410
+static const struct rk_rng_soc_data crypto_v1_soc_data = {
349411 .default_offset = 0,
350412
351
- .rk_rng_read = rk_crypto_v1_read,
413
+ .rk_rng_read = crypto_v1_read,
352414 };
353415
354
-static const struct rk_rng_soc_data rk_crypto_v2_soc_data = {
416
+static const struct rk_rng_soc_data crypto_v2_soc_data = {
355417 .default_offset = CRYPTO_V2_RNG_DEFAULT_OFFSET,
356418
357
- .rk_rng_read = rk_crypto_v2_read,
419
+ .rk_rng_read = crypto_v2_read,
358420 };
359421
360
-static const struct rk_rng_soc_data rk_trng_v1_soc_data = {
422
+static const struct rk_rng_soc_data trng_v1_soc_data = {
361423 .default_offset = 0,
362424
363
- .rk_rng_init = rk_trng_v1_init,
364
- .rk_rng_read = rk_trng_v1_read,
425
+ .rk_rng_init = trng_v1_init,
426
+ .rk_rng_read = trng_v1_read,
427
+};
428
+
429
+static const struct rk_rng_soc_data rkrng_soc_data = {
430
+ .default_offset = 0,
431
+
432
+ .rk_rng_init = rkrng_init,
433
+ .rk_rng_read = rkrng_read,
365434 };
366435
367436 static const struct of_device_id rk_rng_dt_match[] = {
368437 {
369438 .compatible = "rockchip,cryptov1-rng",
370
- .data = (void *)&rk_crypto_v1_soc_data,
439
+ .data = (void *)&crypto_v1_soc_data,
371440 },
372441 {
373442 .compatible = "rockchip,cryptov2-rng",
374
- .data = (void *)&rk_crypto_v2_soc_data,
443
+ .data = (void *)&crypto_v2_soc_data,
375444 },
376445 {
377446 .compatible = "rockchip,trngv1",
378
- .data = (void *)&rk_trng_v1_soc_data,
447
+ .data = (void *)&trng_v1_soc_data,
448
+ },
449
+ {
450
+ .compatible = "rockchip,rkrng",
451
+ .data = (void *)&rkrng_soc_data,
379452 },
380453 { },
381454 };
....@@ -445,9 +518,15 @@
445518 }
446519
447520 /* for some platform need hardware operation when probe */
448
- if (rk_rng->soc_data->rk_rng_init)
521
+ if (rk_rng->soc_data->rk_rng_init) {
522
+ pm_runtime_get_sync(rk_rng->dev);
523
+
449524 ret = rk_rng->soc_data->rk_rng_init(&rk_rng->rng);
450525
526
+ pm_runtime_mark_last_busy(rk_rng->dev);
527
+ pm_runtime_put_sync_autosuspend(rk_rng->dev);
528
+ }
529
+
451530 return ret;
452531 }
453532