116b6c0f6SSandeep Tripathy // SPDX-License-Identifier: BSD-2-Clause
216b6c0f6SSandeep Tripathy /*
316b6c0f6SSandeep Tripathy * Copyright 2019 Broadcom.
416b6c0f6SSandeep Tripathy */
516b6c0f6SSandeep Tripathy
616b6c0f6SSandeep Tripathy #include <drivers/bcm_hwrng.h>
716b6c0f6SSandeep Tripathy #include <initcall.h>
816b6c0f6SSandeep Tripathy #include <io.h>
916b6c0f6SSandeep Tripathy #include <kernel/delay.h>
1016b6c0f6SSandeep Tripathy #include <mm/core_memprot.h>
1116b6c0f6SSandeep Tripathy #include <platform_config.h>
1216b6c0f6SSandeep Tripathy #include <trace.h>
1316b6c0f6SSandeep Tripathy
1416b6c0f6SSandeep Tripathy /* Registers */
1516b6c0f6SSandeep Tripathy #define RNG_CTRL_OFFSET 0x00
1616b6c0f6SSandeep Tripathy #define RNG_CTRL_MASK 0x00001fff
1716b6c0f6SSandeep Tripathy #define RNG_CTRL_DISABLE 0x00000000
1816b6c0f6SSandeep Tripathy #define RNG_CTRL_ENABLE 0x00000001
1916b6c0f6SSandeep Tripathy
2016b6c0f6SSandeep Tripathy #define RNG_SOFT_RESET_OFFSET 0x04
2116b6c0f6SSandeep Tripathy #define RNG_SOFT_RESET_MASK 0x00000001
2216b6c0f6SSandeep Tripathy
2316b6c0f6SSandeep Tripathy #define RNG_FIFO_DATA_OFFSET 0x20
2416b6c0f6SSandeep Tripathy
2516b6c0f6SSandeep Tripathy #define RNG_FIFO_COUNT_OFFSET 0x24
2616b6c0f6SSandeep Tripathy
2716b6c0f6SSandeep Tripathy #define RNG_FIFO_COUNT_MASK 0x000000ff
2816b6c0f6SSandeep Tripathy #define RNG_TIMEOUT_US 10000
2916b6c0f6SSandeep Tripathy
3016b6c0f6SSandeep Tripathy static vaddr_t bcm_hwrng_base;
3116b6c0f6SSandeep Tripathy
bcm_hwrng_reset(void)3216b6c0f6SSandeep Tripathy static void bcm_hwrng_reset(void)
3316b6c0f6SSandeep Tripathy {
3416b6c0f6SSandeep Tripathy /* Disable RBG */
3516b6c0f6SSandeep Tripathy io_clrsetbits32(bcm_hwrng_base + RNG_CTRL_OFFSET,
3616b6c0f6SSandeep Tripathy RNG_CTRL_MASK, RNG_CTRL_DISABLE);
3716b6c0f6SSandeep Tripathy /* Reset RNG and RBG */
3816b6c0f6SSandeep Tripathy io_setbits32(bcm_hwrng_base +
3916b6c0f6SSandeep Tripathy RNG_SOFT_RESET_OFFSET, RNG_SOFT_RESET_MASK);
4016b6c0f6SSandeep Tripathy io_clrbits32(bcm_hwrng_base +
4116b6c0f6SSandeep Tripathy RNG_SOFT_RESET_OFFSET, RNG_SOFT_RESET_MASK);
4216b6c0f6SSandeep Tripathy /* Enable RBG */
4316b6c0f6SSandeep Tripathy io_clrsetbits32(bcm_hwrng_base + RNG_CTRL_OFFSET,
4416b6c0f6SSandeep Tripathy RNG_CTRL_MASK, RNG_CTRL_ENABLE);
4516b6c0f6SSandeep Tripathy }
4616b6c0f6SSandeep Tripathy
bcm_hwrng_read_rng(uint32_t * p_out,uint32_t words_to_read)4716b6c0f6SSandeep Tripathy uint32_t bcm_hwrng_read_rng(uint32_t *p_out, uint32_t words_to_read)
4816b6c0f6SSandeep Tripathy {
4916b6c0f6SSandeep Tripathy uint32_t available_words = 0;
5016b6c0f6SSandeep Tripathy uint32_t num_words = 0;
5116b6c0f6SSandeep Tripathy uint32_t i = 0;
5216b6c0f6SSandeep Tripathy uint64_t timeout = timeout_init_us(RNG_TIMEOUT_US);
5316b6c0f6SSandeep Tripathy
5416b6c0f6SSandeep Tripathy assert(bcm_hwrng_base);
5516b6c0f6SSandeep Tripathy
5616b6c0f6SSandeep Tripathy do {
5716b6c0f6SSandeep Tripathy available_words = io_read32(bcm_hwrng_base +
5816b6c0f6SSandeep Tripathy RNG_FIFO_COUNT_OFFSET);
5916b6c0f6SSandeep Tripathy available_words = available_words & RNG_FIFO_COUNT_MASK;
6016b6c0f6SSandeep Tripathy } while (!available_words && !timeout_elapsed(timeout));
6116b6c0f6SSandeep Tripathy
6216b6c0f6SSandeep Tripathy if ((available_words > 0) && (words_to_read > 0)) {
6316b6c0f6SSandeep Tripathy num_words = MIN(available_words, words_to_read);
6416b6c0f6SSandeep Tripathy for (i = 0; i < num_words; i++)
6516b6c0f6SSandeep Tripathy p_out[i] = io_read32(bcm_hwrng_base +
6616b6c0f6SSandeep Tripathy RNG_FIFO_DATA_OFFSET);
6716b6c0f6SSandeep Tripathy }
6816b6c0f6SSandeep Tripathy
6916b6c0f6SSandeep Tripathy return num_words;
7016b6c0f6SSandeep Tripathy }
7116b6c0f6SSandeep Tripathy
bcm_hwrng_init(void)7216b6c0f6SSandeep Tripathy static TEE_Result bcm_hwrng_init(void)
7316b6c0f6SSandeep Tripathy {
74c2e4eb43SAnton Rybakov bcm_hwrng_base = (vaddr_t)phys_to_virt(HWRNG_BASE, MEM_AREA_IO_SEC,
75c2e4eb43SAnton Rybakov HWRNG_END - HWRNG_BASE);
7616b6c0f6SSandeep Tripathy
7716b6c0f6SSandeep Tripathy bcm_hwrng_reset();
7816b6c0f6SSandeep Tripathy
79*bce2f88aSVincent Mailhol DMSG("bcm_hwrng init done");
8016b6c0f6SSandeep Tripathy return TEE_SUCCESS;
8116b6c0f6SSandeep Tripathy }
8216b6c0f6SSandeep Tripathy
8316b6c0f6SSandeep Tripathy driver_init(bcm_hwrng_init);
84