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