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 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 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 7216b6c0f6SSandeep Tripathy static TEE_Result bcm_hwrng_init(void) 7316b6c0f6SSandeep Tripathy { 74*c2e4eb43SAnton Rybakov bcm_hwrng_base = (vaddr_t)phys_to_virt(HWRNG_BASE, MEM_AREA_IO_SEC, 75*c2e4eb43SAnton Rybakov HWRNG_END - HWRNG_BASE); 7616b6c0f6SSandeep Tripathy 7716b6c0f6SSandeep Tripathy bcm_hwrng_reset(); 7816b6c0f6SSandeep Tripathy 7916b6c0f6SSandeep Tripathy DMSG("bcm_hwrng init done\n"); 8016b6c0f6SSandeep Tripathy return TEE_SUCCESS; 8116b6c0f6SSandeep Tripathy } 8216b6c0f6SSandeep Tripathy 8316b6c0f6SSandeep Tripathy driver_init(bcm_hwrng_init); 84