xref: /rk3399_ARM-atf/drivers/brcm/rng.c (revision c82a2bcd38637bcf9a1dbb11dfb9661806dcf7f7)
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 
rng_reset(void)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 
rng_enable(void)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 
rng_init(void)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 
rng_read(uint32_t * p_out,uint32_t * words_read)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