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