.. | .. |
---|
87 | 87 | #define TRNG_v1_VERSION_CODE 0x46bc |
---|
88 | 88 | /* end of TRNG_V1 register define */ |
---|
89 | 89 | |
---|
| 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 | + |
---|
90 | 111 | struct rk_rng_soc_data { |
---|
91 | 112 | u32 default_offset; |
---|
92 | 113 | |
---|
.. | .. |
---|
178 | 199 | *(u32 *)(buf + i) = be32_to_cpu(rk_rng_readl(rng, offset + i)); |
---|
179 | 200 | } |
---|
180 | 201 | |
---|
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) |
---|
182 | 203 | { |
---|
183 | 204 | int ret = 0; |
---|
184 | 205 | u32 reg_ctrl = 0; |
---|
.. | .. |
---|
192 | 213 | |
---|
193 | 214 | rk_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_CTRL); |
---|
194 | 215 | |
---|
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 | + |
---|
199 | 222 | if (ret < 0) |
---|
200 | 223 | goto out; |
---|
201 | 224 | |
---|
.. | .. |
---|
211 | 234 | return ret; |
---|
212 | 235 | } |
---|
213 | 236 | |
---|
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) |
---|
215 | 238 | { |
---|
216 | 239 | int ret = 0; |
---|
217 | 240 | u32 reg_ctrl = 0; |
---|
.. | .. |
---|
228 | 251 | rk_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0), |
---|
229 | 252 | CRYPTO_V2_RNG_CTL); |
---|
230 | 253 | |
---|
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); |
---|
235 | 259 | if (ret < 0) |
---|
236 | 260 | goto out; |
---|
237 | 261 | |
---|
.. | .. |
---|
246 | 270 | return ret; |
---|
247 | 271 | } |
---|
248 | 272 | |
---|
249 | | -static int rk_trng_v1_init(struct hwrng *rng) |
---|
| 273 | +static int trng_v1_init(struct hwrng *rng) |
---|
250 | 274 | { |
---|
251 | 275 | int ret; |
---|
252 | 276 | uint32_t auto_reseed_cnt = 1000; |
---|
253 | 277 | uint32_t reg_ctrl, status, version; |
---|
254 | 278 | 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 | | - } |
---|
261 | 279 | |
---|
262 | 280 | version = rk_rng_readl(rk_rng, TRNG_V1_VERSION); |
---|
263 | 281 | if (version != TRNG_v1_VERSION_CODE) { |
---|
.. | .. |
---|
281 | 299 | udelay(10); |
---|
282 | 300 | |
---|
283 | 301 | /* 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); |
---|
288 | 307 | } |
---|
289 | 308 | |
---|
290 | 309 | /* clear ISTAT flag because trng may auto reseeding when power on */ |
---|
.. | .. |
---|
296 | 315 | |
---|
297 | 316 | ret = 0; |
---|
298 | 317 | exit: |
---|
299 | | - pm_runtime_mark_last_busy(rk_rng->dev); |
---|
300 | | - pm_runtime_put_sync_autosuspend(rk_rng->dev); |
---|
301 | 318 | |
---|
302 | 319 | return ret; |
---|
303 | 320 | } |
---|
304 | 321 | |
---|
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) |
---|
306 | 323 | { |
---|
307 | 324 | int ret = 0; |
---|
308 | 325 | u32 reg_ctrl = 0; |
---|
.. | .. |
---|
324 | 341 | reg_ctrl = rk_rng_readl(rk_rng, TRNG_V1_ISTAT); |
---|
325 | 342 | if (!(reg_ctrl & TRNG_V1_ISTAT_RAND_RDY)) { |
---|
326 | 343 | /* 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); |
---|
331 | 349 | if (ret < 0) |
---|
332 | 350 | goto out; |
---|
333 | 351 | } |
---|
.. | .. |
---|
345 | 363 | return ret; |
---|
346 | 364 | } |
---|
347 | 365 | |
---|
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 = { |
---|
349 | 411 | .default_offset = 0, |
---|
350 | 412 | |
---|
351 | | - .rk_rng_read = rk_crypto_v1_read, |
---|
| 413 | + .rk_rng_read = crypto_v1_read, |
---|
352 | 414 | }; |
---|
353 | 415 | |
---|
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 = { |
---|
355 | 417 | .default_offset = CRYPTO_V2_RNG_DEFAULT_OFFSET, |
---|
356 | 418 | |
---|
357 | | - .rk_rng_read = rk_crypto_v2_read, |
---|
| 419 | + .rk_rng_read = crypto_v2_read, |
---|
358 | 420 | }; |
---|
359 | 421 | |
---|
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 = { |
---|
361 | 423 | .default_offset = 0, |
---|
362 | 424 | |
---|
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, |
---|
365 | 434 | }; |
---|
366 | 435 | |
---|
367 | 436 | static const struct of_device_id rk_rng_dt_match[] = { |
---|
368 | 437 | { |
---|
369 | 438 | .compatible = "rockchip,cryptov1-rng", |
---|
370 | | - .data = (void *)&rk_crypto_v1_soc_data, |
---|
| 439 | + .data = (void *)&crypto_v1_soc_data, |
---|
371 | 440 | }, |
---|
372 | 441 | { |
---|
373 | 442 | .compatible = "rockchip,cryptov2-rng", |
---|
374 | | - .data = (void *)&rk_crypto_v2_soc_data, |
---|
| 443 | + .data = (void *)&crypto_v2_soc_data, |
---|
375 | 444 | }, |
---|
376 | 445 | { |
---|
377 | 446 | .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, |
---|
379 | 452 | }, |
---|
380 | 453 | { }, |
---|
381 | 454 | }; |
---|
.. | .. |
---|
445 | 518 | } |
---|
446 | 519 | |
---|
447 | 520 | /* 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 | + |
---|
449 | 524 | ret = rk_rng->soc_data->rk_rng_init(&rk_rng->rng); |
---|
450 | 525 | |
---|
| 526 | + pm_runtime_mark_last_busy(rk_rng->dev); |
---|
| 527 | + pm_runtime_put_sync_autosuspend(rk_rng->dev); |
---|
| 528 | + } |
---|
| 529 | + |
---|
451 | 530 | return ret; |
---|
452 | 531 | } |
---|
453 | 532 | |
---|