exynos-trng.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * RNG driver for Exynos TRNGs
  4. *
  5. * Author: Łukasz Stelmach <l.stelmach@samsung.com>
  6. *
  7. * Copyright 2017 (c) Samsung Electronics Software, Inc.
  8. *
  9. * Based on the Exynos PRNG driver drivers/crypto/exynos-rng by
  10. * Krzysztof Kozłowski <krzk@kernel.org>
  11. */
  12. #include <linux/arm-smccc.h>
  13. #include <linux/clk.h>
  14. #include <linux/crypto.h>
  15. #include <linux/delay.h>
  16. #include <linux/err.h>
  17. #include <linux/hw_random.h>
  18. #include <linux/io.h>
  19. #include <linux/iopoll.h>
  20. #include <linux/kernel.h>
  21. #include <linux/module.h>
  22. #include <linux/mod_devicetable.h>
  23. #include <linux/platform_device.h>
  24. #include <linux/pm_runtime.h>
  25. #include <linux/property.h>
  26. #define EXYNOS_TRNG_CLKDIV 0x0
  27. #define EXYNOS_TRNG_CTRL 0x20
  28. #define EXYNOS_TRNG_CTRL_RNGEN BIT(31)
  29. #define EXYNOS_TRNG_POST_CTRL 0x30
  30. #define EXYNOS_TRNG_ONLINE_CTRL 0x40
  31. #define EXYNOS_TRNG_ONLINE_STAT 0x44
  32. #define EXYNOS_TRNG_ONLINE_MAXCHI2 0x48
  33. #define EXYNOS_TRNG_FIFO_CTRL 0x50
  34. #define EXYNOS_TRNG_FIFO_0 0x80
  35. #define EXYNOS_TRNG_FIFO_1 0x84
  36. #define EXYNOS_TRNG_FIFO_2 0x88
  37. #define EXYNOS_TRNG_FIFO_3 0x8c
  38. #define EXYNOS_TRNG_FIFO_4 0x90
  39. #define EXYNOS_TRNG_FIFO_5 0x94
  40. #define EXYNOS_TRNG_FIFO_6 0x98
  41. #define EXYNOS_TRNG_FIFO_7 0x9c
  42. #define EXYNOS_TRNG_FIFO_LEN 8
  43. #define EXYNOS_TRNG_CLOCK_RATE 500000
  44. /* Driver feature flags */
  45. #define EXYNOS_SMC BIT(0)
  46. #define EXYNOS_SMC_CALL_VAL(func_num) \
  47. ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
  48. ARM_SMCCC_SMC_32, \
  49. ARM_SMCCC_OWNER_SIP, \
  50. func_num)
  51. /* SMC command for DTRNG access */
  52. #define SMC_CMD_RANDOM EXYNOS_SMC_CALL_VAL(0x1012)
  53. /* SMC_CMD_RANDOM: arguments */
  54. #define HWRNG_INIT 0x0
  55. #define HWRNG_EXIT 0x1
  56. #define HWRNG_GET_DATA 0x2
  57. #define HWRNG_RESUME 0x3
  58. /* SMC_CMD_RANDOM: return values */
  59. #define HWRNG_RET_OK 0x0
  60. #define HWRNG_RET_RETRY_ERROR 0x2
  61. #define HWRNG_MAX_TRIES 100
  62. struct exynos_trng_dev {
  63. struct device *dev;
  64. void __iomem *mem;
  65. struct clk *clk; /* operating clock */
  66. struct clk *pclk; /* bus clock */
  67. struct hwrng rng;
  68. unsigned long flags;
  69. };
  70. static int exynos_trng_do_read_reg(struct hwrng *rng, void *data, size_t max,
  71. bool wait)
  72. {
  73. struct exynos_trng_dev *trng = (struct exynos_trng_dev *)rng->priv;
  74. int val;
  75. max = min_t(size_t, max, (EXYNOS_TRNG_FIFO_LEN * 4));
  76. writel_relaxed(max * 8, trng->mem + EXYNOS_TRNG_FIFO_CTRL);
  77. val = readl_poll_timeout(trng->mem + EXYNOS_TRNG_FIFO_CTRL, val,
  78. val == 0, 200, 1000000);
  79. if (val < 0)
  80. return val;
  81. memcpy_fromio(data, trng->mem + EXYNOS_TRNG_FIFO_0, max);
  82. return max;
  83. }
  84. static int exynos_trng_do_read_smc(struct hwrng *rng, void *data, size_t max,
  85. bool wait)
  86. {
  87. struct arm_smccc_res res;
  88. unsigned int copied = 0;
  89. u32 *buf = data;
  90. int tries = 0;
  91. while (copied < max) {
  92. arm_smccc_smc(SMC_CMD_RANDOM, HWRNG_GET_DATA, 0, 0, 0, 0, 0, 0,
  93. &res);
  94. switch (res.a0) {
  95. case HWRNG_RET_OK:
  96. *buf++ = res.a2;
  97. *buf++ = res.a3;
  98. copied += 8;
  99. tries = 0;
  100. break;
  101. case HWRNG_RET_RETRY_ERROR:
  102. if (!wait)
  103. return copied;
  104. if (++tries >= HWRNG_MAX_TRIES)
  105. return copied;
  106. cond_resched();
  107. break;
  108. default:
  109. return -EIO;
  110. }
  111. }
  112. return copied;
  113. }
  114. static int exynos_trng_init_reg(struct hwrng *rng)
  115. {
  116. struct exynos_trng_dev *trng = (struct exynos_trng_dev *)rng->priv;
  117. unsigned long sss_rate;
  118. u32 val;
  119. sss_rate = clk_get_rate(trng->clk);
  120. /*
  121. * For most TRNG circuits the clock frequency of under 500 kHz
  122. * is safe.
  123. */
  124. val = sss_rate / (EXYNOS_TRNG_CLOCK_RATE * 2);
  125. if (val > 0x7fff) {
  126. dev_err(trng->dev, "clock divider too large: %d\n", val);
  127. return -ERANGE;
  128. }
  129. val = val << 1;
  130. writel_relaxed(val, trng->mem + EXYNOS_TRNG_CLKDIV);
  131. /* Enable the generator. */
  132. val = EXYNOS_TRNG_CTRL_RNGEN;
  133. writel_relaxed(val, trng->mem + EXYNOS_TRNG_CTRL);
  134. /*
  135. * Disable post-processing. /dev/hwrng is supposed to deliver
  136. * unprocessed data.
  137. */
  138. writel_relaxed(0, trng->mem + EXYNOS_TRNG_POST_CTRL);
  139. return 0;
  140. }
  141. static int exynos_trng_init_smc(struct hwrng *rng)
  142. {
  143. struct exynos_trng_dev *trng = (struct exynos_trng_dev *)rng->priv;
  144. struct arm_smccc_res res;
  145. int ret = 0;
  146. arm_smccc_smc(SMC_CMD_RANDOM, HWRNG_INIT, 0, 0, 0, 0, 0, 0, &res);
  147. if (res.a0 != HWRNG_RET_OK) {
  148. dev_err(trng->dev, "SMC command for TRNG init failed (%d)\n",
  149. (int)res.a0);
  150. ret = -EIO;
  151. }
  152. if ((int)res.a0 == -1)
  153. dev_info(trng->dev, "Make sure LDFW is loaded by your BL\n");
  154. return ret;
  155. }
  156. static int exynos_trng_probe(struct platform_device *pdev)
  157. {
  158. struct exynos_trng_dev *trng;
  159. int ret = -ENOMEM;
  160. trng = devm_kzalloc(&pdev->dev, sizeof(*trng), GFP_KERNEL);
  161. if (!trng)
  162. return ret;
  163. platform_set_drvdata(pdev, trng);
  164. trng->dev = &pdev->dev;
  165. trng->flags = (unsigned long)device_get_match_data(&pdev->dev);
  166. trng->rng.name = devm_kstrdup(&pdev->dev, dev_name(&pdev->dev),
  167. GFP_KERNEL);
  168. if (!trng->rng.name)
  169. return ret;
  170. trng->rng.priv = (unsigned long)trng;
  171. if (trng->flags & EXYNOS_SMC) {
  172. trng->rng.init = exynos_trng_init_smc;
  173. trng->rng.read = exynos_trng_do_read_smc;
  174. } else {
  175. trng->rng.init = exynos_trng_init_reg;
  176. trng->rng.read = exynos_trng_do_read_reg;
  177. trng->mem = devm_platform_ioremap_resource(pdev, 0);
  178. if (IS_ERR(trng->mem))
  179. return PTR_ERR(trng->mem);
  180. }
  181. pm_runtime_enable(&pdev->dev);
  182. ret = pm_runtime_resume_and_get(&pdev->dev);
  183. if (ret < 0) {
  184. dev_err(&pdev->dev, "Could not get runtime PM.\n");
  185. goto err_pm_get;
  186. }
  187. trng->clk = devm_clk_get_enabled(&pdev->dev, "secss");
  188. if (IS_ERR(trng->clk)) {
  189. ret = dev_err_probe(&pdev->dev, PTR_ERR(trng->clk),
  190. "Could not get clock\n");
  191. goto err_clock;
  192. }
  193. trng->pclk = devm_clk_get_optional_enabled(&pdev->dev, "pclk");
  194. if (IS_ERR(trng->pclk)) {
  195. ret = dev_err_probe(&pdev->dev, PTR_ERR(trng->pclk),
  196. "Could not get pclk\n");
  197. goto err_clock;
  198. }
  199. ret = devm_hwrng_register(&pdev->dev, &trng->rng);
  200. if (ret) {
  201. dev_err(&pdev->dev, "Could not register hwrng device.\n");
  202. goto err_clock;
  203. }
  204. dev_info(&pdev->dev, "Exynos True Random Number Generator.\n");
  205. return 0;
  206. err_clock:
  207. pm_runtime_put_noidle(&pdev->dev);
  208. err_pm_get:
  209. pm_runtime_disable(&pdev->dev);
  210. return ret;
  211. }
  212. static void exynos_trng_remove(struct platform_device *pdev)
  213. {
  214. struct exynos_trng_dev *trng = platform_get_drvdata(pdev);
  215. if (trng->flags & EXYNOS_SMC) {
  216. struct arm_smccc_res res;
  217. arm_smccc_smc(SMC_CMD_RANDOM, HWRNG_EXIT, 0, 0, 0, 0, 0, 0,
  218. &res);
  219. }
  220. pm_runtime_put_sync(&pdev->dev);
  221. pm_runtime_disable(&pdev->dev);
  222. }
  223. static int exynos_trng_suspend(struct device *dev)
  224. {
  225. struct exynos_trng_dev *trng = dev_get_drvdata(dev);
  226. struct arm_smccc_res res;
  227. if (trng->flags & EXYNOS_SMC) {
  228. arm_smccc_smc(SMC_CMD_RANDOM, HWRNG_EXIT, 0, 0, 0, 0, 0, 0,
  229. &res);
  230. if (res.a0 != HWRNG_RET_OK)
  231. return -EIO;
  232. }
  233. pm_runtime_put_sync(dev);
  234. return 0;
  235. }
  236. static int exynos_trng_resume(struct device *dev)
  237. {
  238. struct exynos_trng_dev *trng = dev_get_drvdata(dev);
  239. int ret;
  240. ret = pm_runtime_resume_and_get(dev);
  241. if (ret < 0) {
  242. dev_err(dev, "Could not get runtime PM.\n");
  243. return ret;
  244. }
  245. if (trng->flags & EXYNOS_SMC) {
  246. struct arm_smccc_res res;
  247. arm_smccc_smc(SMC_CMD_RANDOM, HWRNG_RESUME, 0, 0, 0, 0, 0, 0,
  248. &res);
  249. if (res.a0 != HWRNG_RET_OK)
  250. return -EIO;
  251. arm_smccc_smc(SMC_CMD_RANDOM, HWRNG_INIT, 0, 0, 0, 0, 0, 0,
  252. &res);
  253. if (res.a0 != HWRNG_RET_OK)
  254. return -EIO;
  255. }
  256. return 0;
  257. }
  258. static DEFINE_SIMPLE_DEV_PM_OPS(exynos_trng_pm_ops, exynos_trng_suspend,
  259. exynos_trng_resume);
  260. static const struct of_device_id exynos_trng_dt_match[] = {
  261. {
  262. .compatible = "samsung,exynos5250-trng",
  263. }, {
  264. .compatible = "samsung,exynos850-trng",
  265. .data = (void *)EXYNOS_SMC,
  266. },
  267. { },
  268. };
  269. MODULE_DEVICE_TABLE(of, exynos_trng_dt_match);
  270. static struct platform_driver exynos_trng_driver = {
  271. .driver = {
  272. .name = "exynos-trng",
  273. .pm = pm_sleep_ptr(&exynos_trng_pm_ops),
  274. .of_match_table = exynos_trng_dt_match,
  275. },
  276. .probe = exynos_trng_probe,
  277. .remove_new = exynos_trng_remove,
  278. };
  279. module_platform_driver(exynos_trng_driver);
  280. MODULE_AUTHOR("Łukasz Stelmach");
  281. MODULE_DESCRIPTION("H/W TRNG driver for Exynos chips");
  282. MODULE_LICENSE("GPL v2");