mxc-rnga.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * RNG driver for Freescale RNGA
  4. *
  5. * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
  6. * Author: Alan Carvalho de Assis <[email protected]>
  7. */
  8. /*
  9. *
  10. * This driver is based on other RNG drivers.
  11. */
  12. #include <linux/clk.h>
  13. #include <linux/delay.h>
  14. #include <linux/hw_random.h>
  15. #include <linux/io.h>
  16. #include <linux/module.h>
  17. #include <linux/of.h>
  18. #include <linux/platform_device.h>
  19. /* RNGA Registers */
  20. #define RNGA_CONTROL 0x00
  21. #define RNGA_STATUS 0x04
  22. #define RNGA_ENTROPY 0x08
  23. #define RNGA_OUTPUT_FIFO 0x0c
  24. #define RNGA_MODE 0x10
  25. #define RNGA_VERIFICATION_CONTROL 0x14
  26. #define RNGA_OSC_CONTROL_COUNTER 0x18
  27. #define RNGA_OSC1_COUNTER 0x1c
  28. #define RNGA_OSC2_COUNTER 0x20
  29. #define RNGA_OSC_COUNTER_STATUS 0x24
  30. /* RNGA Registers Range */
  31. #define RNG_ADDR_RANGE 0x28
  32. /* RNGA Control Register */
  33. #define RNGA_CONTROL_SLEEP 0x00000010
  34. #define RNGA_CONTROL_CLEAR_INT 0x00000008
  35. #define RNGA_CONTROL_MASK_INTS 0x00000004
  36. #define RNGA_CONTROL_HIGH_ASSURANCE 0x00000002
  37. #define RNGA_CONTROL_GO 0x00000001
  38. #define RNGA_STATUS_LEVEL_MASK 0x0000ff00
  39. /* RNGA Status Register */
  40. #define RNGA_STATUS_OSC_DEAD 0x80000000
  41. #define RNGA_STATUS_SLEEP 0x00000010
  42. #define RNGA_STATUS_ERROR_INT 0x00000008
  43. #define RNGA_STATUS_FIFO_UNDERFLOW 0x00000004
  44. #define RNGA_STATUS_LAST_READ_STATUS 0x00000002
  45. #define RNGA_STATUS_SECURITY_VIOLATION 0x00000001
  46. struct mxc_rng {
  47. struct device *dev;
  48. struct hwrng rng;
  49. void __iomem *mem;
  50. struct clk *clk;
  51. };
  52. static int mxc_rnga_data_present(struct hwrng *rng, int wait)
  53. {
  54. int i;
  55. struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng);
  56. for (i = 0; i < 20; i++) {
  57. /* how many random numbers are in FIFO? [0-16] */
  58. int level = (__raw_readl(mxc_rng->mem + RNGA_STATUS) &
  59. RNGA_STATUS_LEVEL_MASK) >> 8;
  60. if (level || !wait)
  61. return !!level;
  62. udelay(10);
  63. }
  64. return 0;
  65. }
  66. static int mxc_rnga_data_read(struct hwrng *rng, u32 * data)
  67. {
  68. int err;
  69. u32 ctrl;
  70. struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng);
  71. /* retrieve a random number from FIFO */
  72. *data = __raw_readl(mxc_rng->mem + RNGA_OUTPUT_FIFO);
  73. /* some error while reading this random number? */
  74. err = __raw_readl(mxc_rng->mem + RNGA_STATUS) & RNGA_STATUS_ERROR_INT;
  75. /* if error: clear error interrupt, but doesn't return random number */
  76. if (err) {
  77. dev_dbg(mxc_rng->dev, "Error while reading random number!\n");
  78. ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL);
  79. __raw_writel(ctrl | RNGA_CONTROL_CLEAR_INT,
  80. mxc_rng->mem + RNGA_CONTROL);
  81. return 0;
  82. } else
  83. return 4;
  84. }
  85. static int mxc_rnga_init(struct hwrng *rng)
  86. {
  87. u32 ctrl, osc;
  88. struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng);
  89. /* wake up */
  90. ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL);
  91. __raw_writel(ctrl & ~RNGA_CONTROL_SLEEP, mxc_rng->mem + RNGA_CONTROL);
  92. /* verify if oscillator is working */
  93. osc = __raw_readl(mxc_rng->mem + RNGA_STATUS);
  94. if (osc & RNGA_STATUS_OSC_DEAD) {
  95. dev_err(mxc_rng->dev, "RNGA Oscillator is dead!\n");
  96. return -ENODEV;
  97. }
  98. /* go running */
  99. ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL);
  100. __raw_writel(ctrl | RNGA_CONTROL_GO, mxc_rng->mem + RNGA_CONTROL);
  101. return 0;
  102. }
  103. static void mxc_rnga_cleanup(struct hwrng *rng)
  104. {
  105. u32 ctrl;
  106. struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng);
  107. ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL);
  108. /* stop rnga */
  109. __raw_writel(ctrl & ~RNGA_CONTROL_GO, mxc_rng->mem + RNGA_CONTROL);
  110. }
  111. static int __init mxc_rnga_probe(struct platform_device *pdev)
  112. {
  113. int err;
  114. struct mxc_rng *mxc_rng;
  115. mxc_rng = devm_kzalloc(&pdev->dev, sizeof(*mxc_rng), GFP_KERNEL);
  116. if (!mxc_rng)
  117. return -ENOMEM;
  118. mxc_rng->dev = &pdev->dev;
  119. mxc_rng->rng.name = "mxc-rnga";
  120. mxc_rng->rng.init = mxc_rnga_init;
  121. mxc_rng->rng.cleanup = mxc_rnga_cleanup;
  122. mxc_rng->rng.data_present = mxc_rnga_data_present;
  123. mxc_rng->rng.data_read = mxc_rnga_data_read;
  124. mxc_rng->clk = devm_clk_get(&pdev->dev, NULL);
  125. if (IS_ERR(mxc_rng->clk)) {
  126. dev_err(&pdev->dev, "Could not get rng_clk!\n");
  127. return PTR_ERR(mxc_rng->clk);
  128. }
  129. err = clk_prepare_enable(mxc_rng->clk);
  130. if (err)
  131. return err;
  132. mxc_rng->mem = devm_platform_ioremap_resource(pdev, 0);
  133. if (IS_ERR(mxc_rng->mem)) {
  134. err = PTR_ERR(mxc_rng->mem);
  135. goto err_ioremap;
  136. }
  137. err = hwrng_register(&mxc_rng->rng);
  138. if (err) {
  139. dev_err(&pdev->dev, "MXC RNGA registering failed (%d)\n", err);
  140. goto err_ioremap;
  141. }
  142. return 0;
  143. err_ioremap:
  144. clk_disable_unprepare(mxc_rng->clk);
  145. return err;
  146. }
  147. static int __exit mxc_rnga_remove(struct platform_device *pdev)
  148. {
  149. struct mxc_rng *mxc_rng = platform_get_drvdata(pdev);
  150. hwrng_unregister(&mxc_rng->rng);
  151. clk_disable_unprepare(mxc_rng->clk);
  152. return 0;
  153. }
  154. static const struct of_device_id mxc_rnga_of_match[] = {
  155. { .compatible = "fsl,imx21-rnga", },
  156. { .compatible = "fsl,imx31-rnga", },
  157. { /* sentinel */ },
  158. };
  159. MODULE_DEVICE_TABLE(of, mxc_rnga_of_match);
  160. static struct platform_driver mxc_rnga_driver = {
  161. .driver = {
  162. .name = "mxc_rnga",
  163. .of_match_table = mxc_rnga_of_match,
  164. },
  165. .remove = __exit_p(mxc_rnga_remove),
  166. };
  167. module_platform_driver_probe(mxc_rnga_driver, mxc_rnga_probe);
  168. MODULE_AUTHOR("Freescale Semiconductor, Inc.");
  169. MODULE_DESCRIPTION("H/W RNGA driver for i.MX");
  170. MODULE_LICENSE("GPL");