xref: /rk3399_ARM-atf/drivers/qti/crypto/rng.c (revision 1c63cd61495542b0b52e1b6e484c59ce5c26e0d2)
1 /*
2  * Copyright (c) 2020, The Linux Foundation. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #include <stddef.h>
7 
8 #include <drivers/qti/crypto/rng.h>
9 #include <lib/mmio.h>
10 
qti_rng_get_data(uint8_t * out,uint32_t out_len)11 int qti_rng_get_data(uint8_t *out, uint32_t out_len)
12 {
13 	uint32_t tmp_rndm = 0;
14 	uint32_t bytes_left = out_len;
15 	int i = 0;
16 
17 	if (NULL == out || 0 == out_len) {
18 		return -1;
19 	}
20 
21 	/*
22 	 * RNG HW initialized at previous boot image.
23 	 * RNG clocks are expected to be ON.
24 	 */
25 
26 	do {
27 		/* There is no data to read */
28 		if ((mmio_read_32(SEC_PRNG_STATUS) &
29 		     SEC_PRNG_STATUS_DATA_AVAIL_BMSK) == 0) {
30 			continue;
31 		}
32 
33 		while ((tmp_rndm = mmio_read_32(SEC_PRNG_DATA_OUT)) == 0) {
34 			;
35 		}
36 
37 		for (i = 0; i < 4; i++) {
38 			*out = (uint8_t) (tmp_rndm >> (8 * i));
39 
40 			out++;
41 			bytes_left--;
42 
43 			if (bytes_left == 0) {
44 				break;
45 			}
46 		}
47 
48 	} while (bytes_left != 0);
49 
50 	return 0;
51 }
52