1*16b6c0f6SSandeep Tripathy // SPDX-License-Identifier: BSD-2-Clause 2*16b6c0f6SSandeep Tripathy /* 3*16b6c0f6SSandeep Tripathy * Copyright 2019 Broadcom. 4*16b6c0f6SSandeep Tripathy */ 5*16b6c0f6SSandeep Tripathy 6*16b6c0f6SSandeep Tripathy #include <drivers/bcm_hwrng.h> 7*16b6c0f6SSandeep Tripathy #include <initcall.h> 8*16b6c0f6SSandeep Tripathy #include <io.h> 9*16b6c0f6SSandeep Tripathy #include <kernel/delay.h> 10*16b6c0f6SSandeep Tripathy #include <mm/core_memprot.h> 11*16b6c0f6SSandeep Tripathy #include <platform_config.h> 12*16b6c0f6SSandeep Tripathy #include <trace.h> 13*16b6c0f6SSandeep Tripathy 14*16b6c0f6SSandeep Tripathy /* Registers */ 15*16b6c0f6SSandeep Tripathy #define RNG_CTRL_OFFSET 0x00 16*16b6c0f6SSandeep Tripathy #define RNG_CTRL_MASK 0x00001fff 17*16b6c0f6SSandeep Tripathy #define RNG_CTRL_DISABLE 0x00000000 18*16b6c0f6SSandeep Tripathy #define RNG_CTRL_ENABLE 0x00000001 19*16b6c0f6SSandeep Tripathy 20*16b6c0f6SSandeep Tripathy #define RNG_SOFT_RESET_OFFSET 0x04 21*16b6c0f6SSandeep Tripathy #define RNG_SOFT_RESET_MASK 0x00000001 22*16b6c0f6SSandeep Tripathy 23*16b6c0f6SSandeep Tripathy #define RNG_FIFO_DATA_OFFSET 0x20 24*16b6c0f6SSandeep Tripathy 25*16b6c0f6SSandeep Tripathy #define RNG_FIFO_COUNT_OFFSET 0x24 26*16b6c0f6SSandeep Tripathy 27*16b6c0f6SSandeep Tripathy #define RNG_FIFO_COUNT_MASK 0x000000ff 28*16b6c0f6SSandeep Tripathy #define RNG_TIMEOUT_US 10000 29*16b6c0f6SSandeep Tripathy 30*16b6c0f6SSandeep Tripathy static vaddr_t bcm_hwrng_base; 31*16b6c0f6SSandeep Tripathy 32*16b6c0f6SSandeep Tripathy static void bcm_hwrng_reset(void) 33*16b6c0f6SSandeep Tripathy { 34*16b6c0f6SSandeep Tripathy /* Disable RBG */ 35*16b6c0f6SSandeep Tripathy io_clrsetbits32(bcm_hwrng_base + RNG_CTRL_OFFSET, 36*16b6c0f6SSandeep Tripathy RNG_CTRL_MASK, RNG_CTRL_DISABLE); 37*16b6c0f6SSandeep Tripathy /* Reset RNG and RBG */ 38*16b6c0f6SSandeep Tripathy io_setbits32(bcm_hwrng_base + 39*16b6c0f6SSandeep Tripathy RNG_SOFT_RESET_OFFSET, RNG_SOFT_RESET_MASK); 40*16b6c0f6SSandeep Tripathy io_clrbits32(bcm_hwrng_base + 41*16b6c0f6SSandeep Tripathy RNG_SOFT_RESET_OFFSET, RNG_SOFT_RESET_MASK); 42*16b6c0f6SSandeep Tripathy /* Enable RBG */ 43*16b6c0f6SSandeep Tripathy io_clrsetbits32(bcm_hwrng_base + RNG_CTRL_OFFSET, 44*16b6c0f6SSandeep Tripathy RNG_CTRL_MASK, RNG_CTRL_ENABLE); 45*16b6c0f6SSandeep Tripathy } 46*16b6c0f6SSandeep Tripathy 47*16b6c0f6SSandeep Tripathy uint32_t bcm_hwrng_read_rng(uint32_t *p_out, uint32_t words_to_read) 48*16b6c0f6SSandeep Tripathy { 49*16b6c0f6SSandeep Tripathy uint32_t available_words = 0; 50*16b6c0f6SSandeep Tripathy uint32_t num_words = 0; 51*16b6c0f6SSandeep Tripathy uint32_t i = 0; 52*16b6c0f6SSandeep Tripathy uint64_t timeout = timeout_init_us(RNG_TIMEOUT_US); 53*16b6c0f6SSandeep Tripathy 54*16b6c0f6SSandeep Tripathy assert(bcm_hwrng_base); 55*16b6c0f6SSandeep Tripathy 56*16b6c0f6SSandeep Tripathy do { 57*16b6c0f6SSandeep Tripathy available_words = io_read32(bcm_hwrng_base + 58*16b6c0f6SSandeep Tripathy RNG_FIFO_COUNT_OFFSET); 59*16b6c0f6SSandeep Tripathy available_words = available_words & RNG_FIFO_COUNT_MASK; 60*16b6c0f6SSandeep Tripathy } while (!available_words && !timeout_elapsed(timeout)); 61*16b6c0f6SSandeep Tripathy 62*16b6c0f6SSandeep Tripathy if ((available_words > 0) && (words_to_read > 0)) { 63*16b6c0f6SSandeep Tripathy num_words = MIN(available_words, words_to_read); 64*16b6c0f6SSandeep Tripathy for (i = 0; i < num_words; i++) 65*16b6c0f6SSandeep Tripathy p_out[i] = io_read32(bcm_hwrng_base + 66*16b6c0f6SSandeep Tripathy RNG_FIFO_DATA_OFFSET); 67*16b6c0f6SSandeep Tripathy } 68*16b6c0f6SSandeep Tripathy 69*16b6c0f6SSandeep Tripathy return num_words; 70*16b6c0f6SSandeep Tripathy } 71*16b6c0f6SSandeep Tripathy 72*16b6c0f6SSandeep Tripathy static TEE_Result bcm_hwrng_init(void) 73*16b6c0f6SSandeep Tripathy { 74*16b6c0f6SSandeep Tripathy bcm_hwrng_base = (vaddr_t)phys_to_virt(HWRNG_BASE, MEM_AREA_IO_SEC); 75*16b6c0f6SSandeep Tripathy 76*16b6c0f6SSandeep Tripathy bcm_hwrng_reset(); 77*16b6c0f6SSandeep Tripathy 78*16b6c0f6SSandeep Tripathy DMSG("bcm_hwrng init done\n"); 79*16b6c0f6SSandeep Tripathy return TEE_SUCCESS; 80*16b6c0f6SSandeep Tripathy } 81*16b6c0f6SSandeep Tripathy 82*16b6c0f6SSandeep Tripathy driver_init(bcm_hwrng_init); 83