1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2019, Linaro Limited
6 #define LOG_CATEGORY UCLASS_RNG
14 #include <linux/bitops.h>
15 #include <linux/delay.h>
16 #include <linux/iopoll.h>
17 #include <linux/kernel.h>
20 #define RNG_CR_RNGEN BIT(2)
21 #define RNG_CR_CED BIT(5)
22 #define RNG_CR_CONFIG1 GENMASK(11, 8)
23 #define RNG_CR_NISTC BIT(12)
24 #define RNG_CR_CONFIG2 GENMASK(15, 13)
25 #define RNG_CR_CLKDIV_SHIFT 16
26 #define RNG_CR_CLKDIV GENMASK(19, 16)
27 #define RNG_CR_CONFIG3 GENMASK(25, 20)
28 #define RNG_CR_CONDRST BIT(30)
29 #define RNG_CR_ENTROPY_SRC_MASK (RNG_CR_CONFIG1 | RNG_CR_NISTC | RNG_CR_CONFIG2 | RNG_CR_CONFIG3)
30 #define RNG_CR_CONFIG_MASK (RNG_CR_ENTROPY_SRC_MASK | RNG_CR_CED | RNG_CR_CLKDIV)
33 #define RNG_SR_SEIS BIT(6)
34 #define RNG_SR_CEIS BIT(5)
35 #define RNG_SR_SECS BIT(2)
36 #define RNG_SR_DRDY BIT(0)
41 #define RNG_NSCR_MASK GENMASK(17, 0)
45 #define RNG_NB_RECOVER_TRIES 3
48 * struct stm32_rng_data - RNG compat data
50 * @max_clock_rate: Max RNG clock frequency, in Hertz
51 * @cr: Entropy source configuration
52 * @nscr: Noice sources control configuration
53 * @htcr: Health tests configuration
54 * @has_cond_reset: True if conditionnal reset is supported
57 struct stm32_rng_data
{
65 struct stm32_rng_plat
{
69 const struct stm32_rng_data
*data
;
74 * Extracts from the STM32 RNG specification when RNG supports CONDRST.
76 * When a noise source (or seed) error occurs, the RNG stops generating
77 * random numbers and sets to “1” both SEIS and SECS bits to indicate
78 * that a seed error occurred. (...)
80 * 1. Software reset by writing CONDRST at 1 and at 0 (see bitfield
81 * description for details). This step is needed only if SECS is set.
82 * Indeed, when SEIS is set and SECS is cleared it means RNG performed
83 * the reset automatically (auto-reset).
84 * 2. If SECS was set in step 1 (no auto-reset) wait for CONDRST
85 * to be cleared in the RNG_CR register, then confirm that SEIS is
86 * cleared in the RNG_SR register. Otherwise just clear SEIS bit in
87 * the RNG_SR register.
88 * 3. If SECS was set in step 1 (no auto-reset) wait for SECS to be
89 * cleared by RNG. The random number generation is now back to normal.
91 static int stm32_rng_conceal_seed_error_cond_reset(struct stm32_rng_plat
*pdata
)
93 u32 sr
= readl_relaxed(pdata
->base
+ RNG_SR
);
94 u32 cr
= readl_relaxed(pdata
->base
+ RNG_CR
);
97 if (sr
& RNG_SR_SECS
) {
98 /* Conceal by resetting the subsystem (step 1.) */
99 writel_relaxed(cr
| RNG_CR_CONDRST
, pdata
->base
+ RNG_CR
);
100 writel_relaxed(cr
& ~RNG_CR_CONDRST
, pdata
->base
+ RNG_CR
);
102 /* RNG auto-reset (step 2.) */
103 writel_relaxed(sr
& ~RNG_SR_SEIS
, pdata
->base
+ RNG_SR
);
107 err
= readl_relaxed_poll_timeout(pdata
->base
+ RNG_SR
, sr
, !(sr
& RNG_CR_CONDRST
), 100000);
109 log_err("%s: timeout %x\n", __func__
, sr
);
113 /* Check SEIS is cleared (step 2.) */
114 if (readl_relaxed(pdata
->base
+ RNG_SR
) & RNG_SR_SEIS
)
117 err
= readl_relaxed_poll_timeout(pdata
->base
+ RNG_SR
, sr
, !(sr
& RNG_SR_SECS
), 100000);
119 log_err("%s: timeout %x\n", __func__
, sr
);
127 * Extracts from the STM32 RNG specification, when CONDRST is not supported
129 * When a noise source (or seed) error occurs, the RNG stops generating
130 * random numbers and sets to “1” both SEIS and SECS bits to indicate
131 * that a seed error occurred. (...)
133 * The following sequence shall be used to fully recover from a seed
134 * error after the RNG initialization:
135 * 1. Clear the SEIS bit by writing it to “0”.
136 * 2. Read out 12 words from the RNG_DR register, and discard each of
137 * them in order to clean the pipeline.
138 * 3. Confirm that SEIS is still cleared. Random number generation is
141 static int stm32_rng_conceal_seed_error_sw_reset(struct stm32_rng_plat
*pdata
)
144 u32 sr
= readl_relaxed(pdata
->base
+ RNG_SR
);
146 writel_relaxed(sr
& ~RNG_SR_SEIS
, pdata
->base
+ RNG_SR
);
148 for (i
= 12; i
!= 0; i
--)
149 (void)readl_relaxed(pdata
->base
+ RNG_DR
);
151 if (readl_relaxed(pdata
->base
+ RNG_SR
) & RNG_SR_SEIS
)
157 static int stm32_rng_conceal_seed_error(struct stm32_rng_plat
*pdata
)
159 log_debug("Concealing RNG seed error\n");
161 if (pdata
->data
->has_cond_reset
)
162 return stm32_rng_conceal_seed_error_cond_reset(pdata
);
164 return stm32_rng_conceal_seed_error_sw_reset(pdata
);
167 static int stm32_rng_read(struct udevice
*dev
, void *data
, size_t len
)
172 struct stm32_rng_plat
*pdata
= dev_get_plat(dev
);
176 retval
= readl_poll_timeout(pdata
->base
+ RNG_SR
, sr
,
179 log_err("%s: Timeout RNG no data", __func__
);
183 if (sr
!= RNG_SR_DRDY
) {
184 if (sr
& RNG_SR_SEIS
) {
185 retval
= stm32_rng_conceal_seed_error(pdata
);
187 if (retval
|| tries
> RNG_NB_RECOVER_TRIES
) {
188 log_err("%s: Couldn't recover from seed error", __func__
);
189 return -ENOTRECOVERABLE
;
196 if (sr
& RNG_SR_CEIS
) {
197 log_info("RNG clock too slow");
198 writel_relaxed(0, pdata
->base
+ RNG_SR
);
203 * Once the DRDY bit is set, the RNG_DR register can
204 * be read up to four consecutive times.
206 reg
= readl(pdata
->base
+ RNG_DR
);
207 /* Late seed error case: DR being 0 is an error status */
209 retval
= stm32_rng_conceal_seed_error(pdata
);
212 if (retval
|| tries
> RNG_NB_RECOVER_TRIES
) {
213 log_err("%s: Couldn't recover from seed error", __func__
);
214 return -ENOTRECOVERABLE
;
221 increment
= min(len
, sizeof(u32
));
222 memcpy(data
, ®
, increment
);
232 static uint
stm32_rng_clock_freq_restrain(struct stm32_rng_plat
*pdata
)
234 ulong clock_rate
= 0;
237 clock_rate
= clk_get_rate(&pdata
->clk
);
240 * Get the exponent to apply on the CLKDIV field in RNG_CR register.
241 * No need to handle the case when clock-div > 0xF as it is physically
244 while ((clock_rate
>> clock_div
) > pdata
->data
->max_clock_rate
)
247 log_debug("RNG clk rate : %lu\n", clk_get_rate(&pdata
->clk
) >> clock_div
);
252 static int stm32_rng_init(struct stm32_rng_plat
*pdata
)
257 err
= clk_enable(&pdata
->clk
);
261 cr
= readl(pdata
->base
+ RNG_CR
);
264 * Keep default RNG configuration if none was specified, that is when conf.cr is set to 0.
266 if (pdata
->data
->has_cond_reset
&& pdata
->data
->cr
) {
267 uint clock_div
= stm32_rng_clock_freq_restrain(pdata
);
269 cr
&= ~RNG_CR_CONFIG_MASK
;
270 cr
|= RNG_CR_CONDRST
| (pdata
->data
->cr
& RNG_CR_ENTROPY_SRC_MASK
) |
271 (clock_div
<< RNG_CR_CLKDIV_SHIFT
);
276 writel(cr
, pdata
->base
+ RNG_CR
);
278 /* Health tests and noise control registers */
279 writel_relaxed(pdata
->data
->htcr
, pdata
->base
+ RNG_HTCR
);
280 writel_relaxed(pdata
->data
->nscr
& RNG_NSCR_MASK
, pdata
->base
+ RNG_NSCR
);
282 cr
&= ~RNG_CR_CONDRST
;
284 writel(cr
, pdata
->base
+ RNG_CR
);
285 err
= readl_poll_timeout(pdata
->base
+ RNG_CR
, cr
,
286 (!(cr
& RNG_CR_CONDRST
)), 10000);
288 log_err("%s: Timeout!", __func__
);
292 if (pdata
->data
->has_cond_reset
)
293 cr
|= RNG_CR_CONDRST
;
300 writel(cr
, pdata
->base
+ RNG_CR
);
302 if (pdata
->data
->has_cond_reset
)
303 cr
&= ~RNG_CR_CONDRST
;
307 writel(cr
, pdata
->base
+ RNG_CR
);
310 /* clear error indicators */
311 writel(0, pdata
->base
+ RNG_SR
);
313 err
= readl_poll_timeout(pdata
->base
+ RNG_SR
, sr
,
314 sr
& RNG_SR_DRDY
, 10000);
316 log_err("%s: Timeout!", __func__
);
321 static int stm32_rng_cleanup(struct stm32_rng_plat
*pdata
)
323 writel(0, pdata
->base
+ RNG_CR
);
325 return clk_disable(&pdata
->clk
);
328 static int stm32_rng_probe(struct udevice
*dev
)
330 struct stm32_rng_plat
*pdata
= dev_get_plat(dev
);
332 pdata
->data
= (struct stm32_rng_data
*)dev_get_driver_data(dev
);
334 reset_assert(&pdata
->rst
);
336 reset_deassert(&pdata
->rst
);
338 return stm32_rng_init(pdata
);
341 static int stm32_rng_remove(struct udevice
*dev
)
343 struct stm32_rng_plat
*pdata
= dev_get_plat(dev
);
345 return stm32_rng_cleanup(pdata
);
348 static int stm32_rng_of_to_plat(struct udevice
*dev
)
350 struct stm32_rng_plat
*pdata
= dev_get_plat(dev
);
353 pdata
->base
= dev_read_addr(dev
);
357 err
= clk_get_by_index(dev
, 0, &pdata
->clk
);
361 err
= reset_get_by_index(dev
, 0, &pdata
->rst
);
365 pdata
->ced
= dev_read_bool(dev
, "clock-error-detect");
370 static const struct dm_rng_ops stm32_rng_ops
= {
371 .read
= stm32_rng_read
,
374 static const struct stm32_rng_data stm32mp13_rng_data
= {
375 .has_cond_reset
= true,
376 .max_clock_rate
= 48000000,
382 static const struct stm32_rng_data stm32_rng_data
= {
383 .has_cond_reset
= false,
384 .max_clock_rate
= 3000000,
391 static const struct udevice_id stm32_rng_match
[] = {
392 {.compatible
= "st,stm32mp13-rng", .data
= (ulong
)&stm32mp13_rng_data
},
393 {.compatible
= "st,stm32-rng", .data
= (ulong
)&stm32_rng_data
},
397 U_BOOT_DRIVER(stm32_rng
) = {
400 .of_match
= stm32_rng_match
,
401 .ops
= &stm32_rng_ops
,
402 .probe
= stm32_rng_probe
,
403 .remove
= stm32_rng_remove
,
404 .plat_auto
= sizeof(struct stm32_rng_plat
),
405 .of_to_plat
= stm32_rng_of_to_plat
,