rng.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /*
  2. * Copyright (c) 2017 - 2020, Broadcom
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <common/debug.h>
  7. #include <drivers/delay_timer.h>
  8. #include <lib/mmio.h>
  9. #include <platform_def.h>
  10. #define RNG_CTRL_REG (RNG_BASE_ADDR + 0x00)
  11. #define RNG_CTRL_MASK 0x00001FFF
  12. #define RNG_CTRL_ENABLE 0x00000001
  13. #define RNG_CTRL_DISABLE 0x00000000
  14. #define RNG_SOFT_RESET_REG (RNG_BASE_ADDR + 0x04)
  15. #define RNG_SOFT_RESET_MASK 0x00000001
  16. #define RNG_FIFO_DATA_REG (RNG_BASE_ADDR + 0x20)
  17. #define RNG_FIFO_COUNT_REG (RNG_BASE_ADDR + 0x24)
  18. #define RNG_FIFO_COUNT_MASK 0x000000FF
  19. #define RNG_FIFO_WORDS_MAX 16
  20. #define MAX_WAIT_COUNT_50US 20000
  21. static void rng_reset(void)
  22. {
  23. /* Disable RBG */
  24. mmio_clrbits_32(RNG_CTRL_REG, RNG_CTRL_MASK);
  25. /* Reset RNG and RBG */
  26. mmio_setbits_32(RNG_SOFT_RESET_REG, RNG_SOFT_RESET_MASK);
  27. /* Take all out of reset */
  28. mmio_clrbits_32(RNG_SOFT_RESET_REG, RNG_SOFT_RESET_MASK);
  29. }
  30. static void rng_enable(void)
  31. {
  32. /* Setup RNG. */
  33. mmio_clrsetbits_32(RNG_CTRL_REG, RNG_CTRL_MASK, RNG_CTRL_ENABLE);
  34. }
  35. int rng_init(void)
  36. {
  37. rng_reset();
  38. rng_enable();
  39. return 0;
  40. }
  41. int rng_read(uint32_t *p_out, uint32_t *words_read)
  42. {
  43. uint32_t available_words;
  44. uint32_t i;
  45. uint32_t word_processed = 0;
  46. uint32_t wait_count = MAX_WAIT_COUNT_50US;
  47. if (*words_read == 0) {
  48. ERROR("RNG Parameter: No word requested\n");
  49. return -1;
  50. }
  51. do {
  52. available_words = mmio_read_32(RNG_FIFO_COUNT_REG);
  53. available_words &= RNG_FIFO_COUNT_MASK;
  54. if (available_words != 0) {
  55. available_words = MIN(available_words,
  56. *words_read - word_processed);
  57. for (i = 0; i < available_words; i++)
  58. p_out[word_processed + i] =
  59. mmio_read_32(RNG_FIFO_DATA_REG);
  60. word_processed += available_words;
  61. } else {
  62. udelay(50);
  63. }
  64. if (word_processed == *words_read)
  65. break;
  66. } while (--wait_count);
  67. if (word_processed != *words_read) {
  68. ERROR("RNG Timeout: requested %d word(s) got %d\n",
  69. *words_read, word_processed);
  70. *words_read = word_processed;
  71. return -1;
  72. }
  73. return 0;
  74. }