aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/brcm/rng.c
diff options
context:
space:
mode:
authorAlistair Delva <adelva@google.com>2021-02-16 21:01:22 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-02-16 21:01:22 +0000
commitefb2826bb8160e2d8e0fcec85133a7468484f9fd (patch)
tree37a21c69306801ee7cdda5167a30896c8740155b /drivers/brcm/rng.c
parentb00a71fc312c9781fa6f404dccfb55b062b2ccac (diff)
parentfaa476c0caaa598afa5a6109d17102db5fe35ec6 (diff)
downloadplatform_external_arm-trusted-firmware-efb2826bb8160e2d8e0fcec85133a7468484f9fd.tar.gz
platform_external_arm-trusted-firmware-efb2826bb8160e2d8e0fcec85133a7468484f9fd.tar.bz2
platform_external_arm-trusted-firmware-efb2826bb8160e2d8e0fcec85133a7468484f9fd.zip
Original change: https://android-review.googlesource.com/c/platform/external/arm-trusted-firmware/+/1589611 MUST ONLY BE SUBMITTED BY AUTOMERGER Change-Id: I3a25534ceed4f8e188510641080d8b8ed49b8f62
Diffstat (limited to 'drivers/brcm/rng.c')
-rw-r--r--drivers/brcm/rng.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/drivers/brcm/rng.c b/drivers/brcm/rng.c
new file mode 100644
index 000000000..ee2e6561e
--- /dev/null
+++ b/drivers/brcm/rng.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2017 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <common/debug.h>
+#include <drivers/delay_timer.h>
+#include <lib/mmio.h>
+#include <platform_def.h>
+
+#define RNG_CTRL_REG (RNG_BASE_ADDR + 0x00)
+#define RNG_CTRL_MASK 0x00001FFF
+#define RNG_CTRL_ENABLE 0x00000001
+#define RNG_CTRL_DISABLE 0x00000000
+
+#define RNG_SOFT_RESET_REG (RNG_BASE_ADDR + 0x04)
+#define RNG_SOFT_RESET_MASK 0x00000001
+
+#define RNG_FIFO_DATA_REG (RNG_BASE_ADDR + 0x20)
+
+#define RNG_FIFO_COUNT_REG (RNG_BASE_ADDR + 0x24)
+#define RNG_FIFO_COUNT_MASK 0x000000FF
+
+#define RNG_FIFO_WORDS_MAX 16
+#define MAX_WAIT_COUNT_50US 20000
+
+
+static void rng_reset(void)
+{
+ /* Disable RBG */
+ mmio_clrbits_32(RNG_CTRL_REG, RNG_CTRL_MASK);
+
+ /* Reset RNG and RBG */
+ mmio_setbits_32(RNG_SOFT_RESET_REG, RNG_SOFT_RESET_MASK);
+
+ /* Take all out of reset */
+ mmio_clrbits_32(RNG_SOFT_RESET_REG, RNG_SOFT_RESET_MASK);
+}
+
+static void rng_enable(void)
+{
+ /* Setup RNG. */
+ mmio_clrsetbits_32(RNG_CTRL_REG, RNG_CTRL_MASK, RNG_CTRL_ENABLE);
+}
+
+int rng_init(void)
+{
+ rng_reset();
+
+ rng_enable();
+
+ return 0;
+}
+
+int rng_read(uint32_t *p_out, uint32_t *words_read)
+{
+ uint32_t available_words;
+ uint32_t i;
+ uint32_t word_processed = 0;
+ uint32_t wait_count = MAX_WAIT_COUNT_50US;
+
+ if (*words_read == 0) {
+ ERROR("RNG Parameter: No word requested\n");
+ return -1;
+ }
+
+ do {
+ available_words = mmio_read_32(RNG_FIFO_COUNT_REG);
+ available_words &= RNG_FIFO_COUNT_MASK;
+
+ if (available_words != 0) {
+ available_words = MIN(available_words,
+ *words_read - word_processed);
+
+ for (i = 0; i < available_words; i++)
+ p_out[word_processed + i] =
+ mmio_read_32(RNG_FIFO_DATA_REG);
+ word_processed += available_words;
+ } else {
+ udelay(50);
+ }
+
+ if (word_processed == *words_read)
+ break;
+
+ } while (--wait_count);
+
+ if (word_processed != *words_read) {
+ ERROR("RNG Timeout: requested %d word(s) got %d\n",
+ *words_read, word_processed);
+ *words_read = word_processed;
+ return -1;
+ }
+
+ return 0;
+}