hw-rng-rockchip.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-3-08 GuEe-GUI the first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #define DBG_TAG "rng.rockchip"
  14. #define DBG_LVL DBG_INFO
  15. #include <rtdbg.h>
  16. #include "rockchip.h"
  17. #define ROCKCHIP_AUTOSUSPEND_DELAY 100
  18. #define ROCKCHIP_POLL_PERIOD_US 100
  19. #define ROCKCHIP_POLL_TIMEOUT_US 50000
  20. #define RK_MAX_RNG_BYTE (32)
  21. /* start of CRYPTO V1 register define */
  22. #define CRYPTO_V1_CTRL 0x0008
  23. #define CRYPTO_V1_RNG_START RT_BIT(8)
  24. #define CRYPTO_V1_RNG_FLUSH RT_BIT(9)
  25. #define CRYPTO_V1_TRNG_CTRL 0x0200
  26. #define CRYPTO_V1_OSC_ENABLE RT_BIT(16)
  27. #define CRYPTO_V1_TRNG_SAMPLE_PERIOD(x) (x)
  28. #define CRYPTO_V1_TRNG_DOUT_0 0x0204
  29. /* end of CRYPTO V1 register define */
  30. /* start of CRYPTO V2 register define */
  31. #define CRYPTO_V2_RNG_DEFAULT_OFFSET 0x0400
  32. #define CRYPTO_V2_RNG_CTL 0x0
  33. #define CRYPTO_V2_RNG_64_BIT_LEN ((0x00) << (4))
  34. #define CRYPTO_V2_RNG_128_BIT_LEN ((0x01) << (4))
  35. #define CRYPTO_V2_RNG_192_BIT_LEN ((0x02) << (4))
  36. #define CRYPTO_V2_RNG_256_BIT_LEN ((0x03) << (4))
  37. #define CRYPTO_V2_RNG_FATESY_SOC_RING ((0x00) << (2))
  38. #define CRYPTO_V2_RNG_SLOWER_SOC_RING_0 ((0x01) << (2))
  39. #define CRYPTO_V2_RNG_SLOWER_SOC_RING_1 ((0x02) << (2))
  40. #define CRYPTO_V2_RNG_SLOWEST_SOC_RING ((0x03) << (2))
  41. #define CRYPTO_V2_RNG_ENABLE RT_BIT(1)
  42. #define CRYPTO_V2_RNG_START RT_BIT(0)
  43. #define CRYPTO_V2_RNG_SAMPLE_CNT 0x0004
  44. #define CRYPTO_V2_RNG_DOUT_0 0x0010
  45. /* end of CRYPTO V2 register define */
  46. /* start of TRNG_V1 register define */
  47. /* TRNG is no longer subordinate to the Crypto module */
  48. #define TRNG_V1_CTRL 0x0000
  49. #define TRNG_V1_CTRL_NOP ((0x00) << (0))
  50. #define TRNG_V1_CTRL_RAND ((0x01) << (0))
  51. #define TRNG_V1_CTRL_SEED ((0x02) << (0))
  52. #define TRNG_V1_STAT 0x0004
  53. #define TRNG_V1_STAT_SEEDED RT_BIT(9)
  54. #define TRNG_V1_STAT_GENERATING RT_BIT(30)
  55. #define TRNG_V1_STAT_RESEEDING RT_BIT(31)
  56. #define TRNG_V1_MODE 0x0008
  57. #define TRNG_V1_MODE_128_BIT ((0x00) << (3))
  58. #define TRNG_V1_MODE_256_BIT ((0x01) << (3))
  59. #define TRNG_V1_IE 0x0010
  60. #define TRNG_V1_IE_GLBL_EN RT_BIT(31)
  61. #define TRNG_V1_IE_SEED_DONE_EN RT_BIT(1)
  62. #define TRNG_V1_IE_RAND_RDY_EN RT_BIT(0)
  63. #define TRNG_V1_ISTAT 0x0014
  64. #define TRNG_V1_ISTAT_RAND_RDY RT_BIT(0)
  65. /* RAND0 ~ RAND7 */
  66. #define TRNG_V1_RAND0 0x0020
  67. #define TRNG_V1_RAND7 0x003C
  68. #define TRNG_V1_AUTO_RQSTS 0x0060
  69. #define TRNG_V1_VERSION 0x00F0
  70. #define TRNG_v1_VERSION_CODE 0x46bc
  71. /* end of TRNG_V1 register define */
  72. struct rockchip_rng;
  73. struct rockchip_rng_soc_data
  74. {
  75. rt_uint32_t default_offset;
  76. rt_err_t (*init)(struct rockchip_rng *rk_rng);
  77. rt_uint32_t (*read)(struct rockchip_rng *rk_rng, void *buf, rt_size_t max, rt_bool_t wait);
  78. };
  79. struct rockchip_rng
  80. {
  81. struct rt_hwcrypto_device parent;
  82. void *regs;
  83. struct rt_clk_array *clk_arr;
  84. struct rt_reset_control *rstc;
  85. const struct rockchip_rng_soc_data *soc_data;
  86. };
  87. #define raw_to_rockchip_rng(raw) rt_container_of(raw, struct rockchip_rng, parent)
  88. static void rockchip_rng_writel(struct rockchip_rng *rk_rng, rt_uint32_t val, int offset)
  89. {
  90. HWREG32(rk_rng->regs + offset) = val;
  91. }
  92. static rt_uint32_t rockchip_rng_readl(struct rockchip_rng *rk_rng, int offset)
  93. {
  94. return HWREG32(rk_rng->regs + offset);
  95. }
  96. static void rockchip_rng_read_regs(struct rockchip_rng *rk_rng, rt_uint32_t offset,
  97. void *buf, rt_size_t size)
  98. {
  99. rt_uint32_t *data = buf;
  100. for (int i = 0; i < size; i += 4, ++offset)
  101. {
  102. data[i] = rt_be32_to_cpu(rockchip_rng_readl(rk_rng, offset));
  103. }
  104. }
  105. static rt_uint32_t rockchip_crypto_v1_read(struct rockchip_rng *rk_rng, void *buf,
  106. rt_size_t max, rt_bool_t wait)
  107. {
  108. rt_tick_t start;
  109. rt_uint32_t res = 0, reg_ctrl = 0;
  110. int timeout = rt_tick_from_millisecond(ROCKCHIP_POLL_TIMEOUT_US / 1000);
  111. /* enable osc_ring to get entropy, sample period is set as 100 */
  112. reg_ctrl = CRYPTO_V1_OSC_ENABLE | CRYPTO_V1_TRNG_SAMPLE_PERIOD(100);
  113. rockchip_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_TRNG_CTRL);
  114. reg_ctrl = HIWORD_UPDATE(CRYPTO_V1_RNG_START, CRYPTO_V1_RNG_START, 0);
  115. rockchip_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_CTRL);
  116. start = rt_tick_get();
  117. while (rockchip_rng_readl(rk_rng, CRYPTO_V1_CTRL) & CRYPTO_V1_RNG_START)
  118. {
  119. rt_hw_us_delay(ROCKCHIP_POLL_PERIOD_US);
  120. if ((rt_tick_get() - start) > timeout)
  121. {
  122. goto _time_out;
  123. }
  124. rt_hw_cpu_relax();
  125. }
  126. res = rt_min_t(rt_size_t, max, RK_MAX_RNG_BYTE);
  127. rockchip_rng_read_regs(rk_rng, CRYPTO_V1_TRNG_DOUT_0, buf, res);
  128. _time_out:
  129. /* close TRNG */
  130. rockchip_rng_writel(rk_rng, HIWORD_UPDATE(0, CRYPTO_V1_RNG_START, 0), CRYPTO_V1_CTRL);
  131. return res;
  132. }
  133. static rt_uint32_t rockchip_crypto_v2_read(struct rockchip_rng *rk_rng, void *buf,
  134. rt_size_t max, rt_bool_t wait)
  135. {
  136. rt_tick_t start;
  137. rt_uint32_t res = 0, reg_ctrl = 0;
  138. int timeout = rt_tick_from_millisecond(ROCKCHIP_POLL_TIMEOUT_US / 1000);
  139. /* enable osc_ring to get entropy, sample period is set as 100 */
  140. rockchip_rng_writel(rk_rng, 100, CRYPTO_V2_RNG_SAMPLE_CNT);
  141. reg_ctrl |= CRYPTO_V2_RNG_256_BIT_LEN;
  142. reg_ctrl |= CRYPTO_V2_RNG_SLOWER_SOC_RING_0;
  143. reg_ctrl |= CRYPTO_V2_RNG_ENABLE;
  144. reg_ctrl |= CRYPTO_V2_RNG_START;
  145. rockchip_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0), CRYPTO_V2_RNG_CTL);
  146. start = rt_tick_get();
  147. while (rockchip_rng_readl(rk_rng, CRYPTO_V2_RNG_CTL) & CRYPTO_V2_RNG_START)
  148. {
  149. rt_hw_us_delay(ROCKCHIP_POLL_PERIOD_US);
  150. if ((rt_tick_get() - start) > timeout)
  151. {
  152. goto _time_out;
  153. }
  154. rt_hw_cpu_relax();
  155. }
  156. res = rt_min_t(rt_size_t, max, RK_MAX_RNG_BYTE);
  157. rockchip_rng_read_regs(rk_rng, CRYPTO_V2_RNG_DOUT_0, buf, res);
  158. _time_out:
  159. /* close TRNG */
  160. rockchip_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), CRYPTO_V2_RNG_CTL);
  161. return res;
  162. }
  163. static rt_err_t rockchip_trng_v1_init(struct rockchip_rng *rk_rng)
  164. {
  165. rt_uint32_t auto_reseed_cnt = 1000;
  166. rt_uint32_t reg_ctrl, status, version;
  167. version = rockchip_rng_readl(rk_rng, TRNG_V1_VERSION);
  168. if (version != TRNG_v1_VERSION_CODE)
  169. {
  170. LOG_E("Wrong trng version, expected = %08x, actual = %08x",
  171. TRNG_V1_VERSION, version);
  172. return -RT_EIO;
  173. }
  174. status = rockchip_rng_readl(rk_rng, TRNG_V1_STAT);
  175. /* TRNG should wait RAND_RDY triggered if it is busy or not seeded */
  176. if (!(status & TRNG_V1_STAT_SEEDED) || (status & TRNG_V1_STAT_GENERATING) ||
  177. (status & TRNG_V1_STAT_RESEEDING))
  178. {
  179. rt_tick_t start;
  180. rt_uint32_t mask = TRNG_V1_STAT_SEEDED | TRNG_V1_STAT_GENERATING |
  181. TRNG_V1_STAT_RESEEDING;
  182. int timeout = rt_tick_from_millisecond(ROCKCHIP_POLL_TIMEOUT_US / 1000);
  183. rt_hw_us_delay(10);
  184. /* wait for GENERATING and RESEEDING flag to clear */
  185. start = rt_tick_get();
  186. while ((rockchip_rng_readl(rk_rng, TRNG_V1_STAT) & mask) != TRNG_V1_STAT_SEEDED)
  187. {
  188. rt_hw_us_delay(ROCKCHIP_POLL_PERIOD_US);
  189. if ((rt_tick_get() - start) > timeout)
  190. {
  191. break;
  192. }
  193. rt_hw_cpu_relax();
  194. }
  195. }
  196. /* clear ISTAT flag because trng may auto reseeding when power on */
  197. reg_ctrl = rockchip_rng_readl(rk_rng, TRNG_V1_ISTAT);
  198. rockchip_rng_writel(rk_rng, reg_ctrl, TRNG_V1_ISTAT);
  199. /* auto reseed after (auto_reseed_cnt * 16) byte rand generate */
  200. rockchip_rng_writel(rk_rng, auto_reseed_cnt, TRNG_V1_AUTO_RQSTS);
  201. return RT_EOK;
  202. }
  203. static rt_uint32_t rockchip_trng_v1_read(struct rockchip_rng *rk_rng, void *buf,
  204. rt_size_t max, rt_bool_t wait)
  205. {
  206. rt_uint32_t res = 0, reg_ctrl = 0;
  207. /* clear ISTAT anyway */
  208. reg_ctrl = rockchip_rng_readl(rk_rng, TRNG_V1_ISTAT);
  209. rockchip_rng_writel(rk_rng, reg_ctrl, TRNG_V1_ISTAT);
  210. /* generate 256bit random */
  211. rockchip_rng_writel(rk_rng, TRNG_V1_MODE_256_BIT, TRNG_V1_MODE);
  212. rockchip_rng_writel(rk_rng, TRNG_V1_CTRL_RAND, TRNG_V1_CTRL);
  213. /*
  214. * Generate2 56 bit random data will cost 1024 clock cycles.
  215. * Estimated at 150M RNG module frequency, it takes 6.7 microseconds.
  216. */
  217. rt_hw_us_delay(10);
  218. reg_ctrl = rockchip_rng_readl(rk_rng, TRNG_V1_ISTAT);
  219. if (!(reg_ctrl & TRNG_V1_ISTAT_RAND_RDY))
  220. {
  221. rt_tick_t start = rt_tick_get();
  222. int timeout = rt_tick_from_millisecond(ROCKCHIP_POLL_TIMEOUT_US / 1000);
  223. /* wait RAND_RDY triggered */
  224. while (!(rockchip_rng_readl(rk_rng, TRNG_V1_ISTAT) & TRNG_V1_ISTAT_RAND_RDY))
  225. {
  226. rt_hw_us_delay(ROCKCHIP_POLL_PERIOD_US);
  227. if ((rt_tick_get() - start) > timeout)
  228. {
  229. goto _time_out;
  230. }
  231. rt_hw_cpu_relax();
  232. }
  233. }
  234. res = rt_min_t(rt_size_t, max, RK_MAX_RNG_BYTE);
  235. rockchip_rng_read_regs(rk_rng, TRNG_V1_RAND0, buf, res);
  236. /* clear all status flag */
  237. rockchip_rng_writel(rk_rng, reg_ctrl, TRNG_V1_ISTAT);
  238. _time_out:
  239. /* close TRNG */
  240. rockchip_rng_writel(rk_rng, TRNG_V1_CTRL_NOP, TRNG_V1_CTRL);
  241. return res;
  242. }
  243. static rt_uint32_t rockchip_rng_read(struct rockchip_rng *rk_rng, void *buf,
  244. rt_size_t max, rt_bool_t wait)
  245. {
  246. rt_uint32_t res;
  247. int read_len = 0;
  248. if (!rk_rng->soc_data->read)
  249. {
  250. return 0;
  251. }
  252. res = 0;
  253. while (max > res)
  254. {
  255. read_len = rk_rng->soc_data->read(rk_rng, buf + res, max - res, wait);
  256. if (read_len < 0)
  257. {
  258. res = read_len;
  259. break;
  260. }
  261. res += read_len;
  262. }
  263. return res;
  264. }
  265. static rt_uint32_t rockchip_rng_rand(struct hwcrypto_rng *ctx)
  266. {
  267. rt_uint32_t rand;
  268. struct rockchip_rng *rk_rng = raw_to_rockchip_rng(ctx->parent.device);
  269. if (rockchip_rng_read(rk_rng, &rand, sizeof(rand), RT_TRUE) != sizeof(rand))
  270. {
  271. return 0;
  272. }
  273. return rand;
  274. }
  275. static const struct hwcrypto_rng_ops rng_ops =
  276. {
  277. .update = rockchip_rng_rand,
  278. };
  279. static rt_err_t rockchip_rng_create(struct rt_hwcrypto_ctx *ctx)
  280. {
  281. rt_err_t res = RT_EOK;
  282. struct hwcrypto_rng *rng;
  283. switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
  284. {
  285. case HWCRYPTO_TYPE_RNG:
  286. ctx->contex = RT_NULL;
  287. rng = rt_container_of(ctx, struct hwcrypto_rng, parent);
  288. rng->ops = &rng_ops;
  289. break;
  290. default:
  291. res = -RT_ENOSYS;
  292. break;
  293. }
  294. return res;
  295. }
  296. static void rockchip_rng_destroy(struct rt_hwcrypto_ctx *ctx)
  297. {
  298. rt_free(ctx->contex);
  299. }
  300. static rt_err_t rockchip_rng_copy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
  301. {
  302. rt_err_t err = RT_EOK;
  303. switch (src->type & HWCRYPTO_MAIN_TYPE_MASK)
  304. {
  305. case HWCRYPTO_TYPE_RNG:
  306. break;
  307. default:
  308. err = -RT_ENOSYS;
  309. break;
  310. }
  311. return err;
  312. }
  313. static void rockchip_rng_reset(struct rt_hwcrypto_ctx *ctx)
  314. {
  315. }
  316. static const struct rt_hwcrypto_ops rockchip_rng_ops =
  317. {
  318. .create = rockchip_rng_create,
  319. .destroy = rockchip_rng_destroy,
  320. .copy = rockchip_rng_copy,
  321. .reset = rockchip_rng_reset,
  322. };
  323. static void rockchip_rng_free(struct rockchip_rng *rk_rng)
  324. {
  325. if (!rk_rng->regs)
  326. {
  327. rt_iounmap(rk_rng->regs);
  328. }
  329. if (!rt_is_err_or_null(rk_rng->rstc))
  330. {
  331. rt_reset_control_assert(rk_rng->rstc);
  332. rt_reset_control_put(rk_rng->rstc);
  333. }
  334. if (!rt_is_err_or_null(rk_rng->clk_arr))
  335. {
  336. rt_clk_array_disable_unprepare(rk_rng->clk_arr);
  337. rt_clk_array_put(rk_rng->clk_arr);
  338. }
  339. rt_free(rk_rng);
  340. }
  341. static rt_err_t rockchip_rng_probe(struct rt_platform_device *pdev)
  342. {
  343. rt_err_t err = RT_EOK;
  344. struct rt_device *dev = &pdev->parent;
  345. struct rockchip_rng *rk_rng = rt_calloc(1, sizeof(*rk_rng));
  346. if (!rk_rng)
  347. {
  348. return -RT_ENOMEM;
  349. }
  350. rk_rng->soc_data = pdev->id->data;
  351. rk_rng->regs = rt_dm_dev_iomap(dev, 0);
  352. if (!rk_rng->regs)
  353. {
  354. err = -RT_EIO;
  355. goto _fail;
  356. }
  357. rk_rng->rstc = rt_reset_control_get_by_name(dev, "reset");
  358. if (rt_is_err(rk_rng->rstc))
  359. {
  360. err = rt_ptr_err(rk_rng->rstc);
  361. goto _fail;
  362. }
  363. if (rk_rng->rstc)
  364. {
  365. rt_reset_control_assert(rk_rng->rstc);
  366. rt_hw_us_delay(10);
  367. rt_reset_control_deassert(rk_rng->rstc);
  368. }
  369. rk_rng->clk_arr = rt_clk_get_array(dev);
  370. if (rt_is_err(rk_rng->clk_arr))
  371. {
  372. err = rt_ptr_err(rk_rng->clk_arr);
  373. goto _fail;
  374. }
  375. rt_clk_array_prepare_enable(rk_rng->clk_arr);
  376. if (rk_rng->soc_data->init)
  377. {
  378. err = rk_rng->soc_data->init(rk_rng);
  379. }
  380. if (err)
  381. {
  382. goto _fail;
  383. }
  384. dev->user_data = rk_rng;
  385. rk_rng->parent.ops = &rockchip_rng_ops;
  386. if ((err = rt_hwcrypto_register(&rk_rng->parent, "hwrng")))
  387. {
  388. goto _fail;
  389. }
  390. return RT_EOK;
  391. _fail:
  392. rockchip_rng_free(rk_rng);
  393. return err;
  394. }
  395. static rt_err_t rockchip_rng_remove(struct rt_platform_device *pdev)
  396. {
  397. struct rockchip_rng *rk_rng = pdev->parent.user_data;
  398. rt_device_unregister(&rk_rng->parent.parent);
  399. rockchip_rng_free(rk_rng);
  400. return RT_EOK;
  401. }
  402. static const struct rockchip_rng_soc_data rk_crypto_v1_soc_data =
  403. {
  404. .default_offset = 0,
  405. .read = rockchip_crypto_v1_read,
  406. };
  407. static const struct rockchip_rng_soc_data rk_crypto_v2_soc_data =
  408. {
  409. .default_offset = CRYPTO_V2_RNG_DEFAULT_OFFSET,
  410. .read = rockchip_crypto_v2_read,
  411. };
  412. static const struct rockchip_rng_soc_data rk_trng_v1_soc_data =
  413. {
  414. .default_offset = 0,
  415. .init = rockchip_trng_v1_init,
  416. .read = rockchip_trng_v1_read,
  417. };
  418. static const struct rt_ofw_node_id rockchip_rng_ofw_ids[] =
  419. {
  420. { .compatible = "rockchip,cryptov1-rng", .data = &rk_crypto_v1_soc_data, },
  421. { .compatible = "rockchip,cryptov2-rng", .data = &rk_crypto_v2_soc_data, },
  422. { .compatible = "rockchip,trngv1", .data = &rk_trng_v1_soc_data, },
  423. { /* sentinel */ }
  424. };
  425. static struct rt_platform_driver rockchip_rng_driver =
  426. {
  427. .name = "rockchip-rng",
  428. .ids = rockchip_rng_ofw_ids,
  429. .probe = rockchip_rng_probe,
  430. .remove = rockchip_rng_remove,
  431. };
  432. RT_PLATFORM_DRIVER_EXPORT(rockchip_rng_driver);