1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3 * Copyright (c) 2018-2024, STMicroelectronics
4 */
5
6 #include <assert.h>
7 #include <drivers/clk.h>
8 #include <drivers/clk_dt.h>
9 #include <drivers/rstctrl.h>
10 #include <io.h>
11 #include <kernel/delay.h>
12 #include <kernel/dt.h>
13 #include <kernel/dt_driver.h>
14 #include <kernel/boot.h>
15 #include <kernel/panic.h>
16 #include <kernel/pm.h>
17 #include <kernel/thread.h>
18 #include <libfdt.h>
19 #include <mm/core_memprot.h>
20 #include <rng_support.h>
21 #include <stdbool.h>
22 #include <stm32_util.h>
23 #include <string.h>
24 #include <tee/tee_cryp_utl.h>
25
26 #define RNG_CR U(0x00)
27 #define RNG_SR U(0x04)
28 #define RNG_DR U(0x08)
29 #define RNG_NSCR U(0x0C)
30 #define RNG_HTCR U(0x10)
31 #define RNG_VERR U(0x3F4)
32
33 #define RNG_CR_RNGEN BIT(2)
34 #define RNG_CR_IE BIT(3)
35 #define RNG_CR_CED BIT(5)
36 #define RNG_CR_CONFIG1 GENMASK_32(11, 8)
37 #define RNG_CR_NISTC BIT(12)
38 #define RNG_CR_POWER_OPTIM BIT(13)
39 #define RNG_CR_CONFIG2 GENMASK_32(15, 13)
40 #define RNG_CR_CLKDIV GENMASK_32(19, 16)
41 #define RNG_CR_CLKDIV_SHIFT U(16)
42 #define RNG_CR_CONFIG3 GENMASK_32(25, 20)
43 #define RNG_CR_CONDRST BIT(30)
44 #define RNG_CR_ENTROPY_SRC_MASK (RNG_CR_CONFIG1 | RNG_CR_NISTC | \
45 RNG_CR_CONFIG2 | RNG_CR_CONFIG3)
46
47 #define RNG_SR_DRDY BIT(0)
48 #define RNG_SR_CECS BIT(1)
49 #define RNG_SR_SECS BIT(2)
50 #define RNG_SR_CEIS BIT(5)
51 #define RNG_SR_SEIS BIT(6)
52
53 #define RNG_NSCR_MASK GENMASK_32(17, 0)
54
55 #define RNG_VERR_MINOR_MASK GENMASK_32(3, 0)
56 #define RNG_VERR_MAJOR_MASK GENMASK_32(7, 4)
57 #define RNG_VERR_MAJOR_SHIFT U(4)
58
59 #if TRACE_LEVEL > TRACE_DEBUG
60 #define RNG_READY_TIMEOUT_US U(100000)
61 #else
62 #define RNG_READY_TIMEOUT_US U(10000)
63 #endif
64 #define RNG_RESET_TIMEOUT_US U(1000)
65
66 #define RNG_FIFO_BYTE_DEPTH U(16)
67
68 #define RNG_CONFIG_MASK (RNG_CR_ENTROPY_SRC_MASK | RNG_CR_CED | \
69 RNG_CR_CLKDIV)
70
71 struct stm32_rng_driver_data {
72 unsigned long max_noise_clk_freq;
73 unsigned long nb_clock;
74 uint32_t cr;
75 uint32_t nscr;
76 uint32_t htcr;
77 bool has_power_optim;
78 bool has_cond_reset;
79 };
80
81 struct stm32_rng_instance {
82 struct io_pa_va base;
83 struct clk *clock;
84 struct clk *bus_clock;
85 struct rstctrl *rstctrl;
86 const struct stm32_rng_driver_data *ddata;
87 unsigned int lock;
88 uint64_t error_to_ref;
89 uint32_t pm_cr;
90 uint32_t pm_health;
91 uint32_t pm_noise_ctrl;
92 uint32_t health_test_conf;
93 uint32_t noise_ctrl_conf;
94 uint32_t rng_config;
95 bool clock_error;
96 bool error_conceal;
97 };
98
99 /* Expect at most a single RNG instance */
100 static struct stm32_rng_instance *stm32_rng;
101
get_base(void)102 static vaddr_t get_base(void)
103 {
104 assert(stm32_rng);
105
106 return io_pa_or_va(&stm32_rng->base, 1);
107 }
108
109 /*
110 * Extracts from the STM32 RNG specification when RNG supports CONDRST.
111 *
112 * When a noise source (or seed) error occurs, the RNG stops generating
113 * random numbers and sets to “1” both SEIS and SECS bits to indicate
114 * that a seed error occurred. (...)
115 *
116 * 1. Software reset by writing CONDRST at 1 and at 0 (see bitfield
117 * description for details). This step is needed only if SECS is set.
118 * Indeed, when SEIS is set and SECS is cleared it means RNG performed
119 * the reset automatically (auto-reset).
120 * 2. If SECS was set in step 1 (no auto-reset) wait for CONDRST
121 * to be cleared in the RNG_CR register, then confirm that SEIS is
122 * cleared in the RNG_SR register. Otherwise just clear SEIS bit in
123 * the RNG_SR register.
124 * 3. If SECS was set in step 1 (no auto-reset) wait for SECS to be
125 * cleared by RNG. The random number generation is now back to normal.
126 */
conceal_seed_error_cond_reset(void)127 static void conceal_seed_error_cond_reset(void)
128 {
129 struct stm32_rng_instance *dev = stm32_rng;
130 vaddr_t rng_base = get_base();
131
132 if (!dev->error_conceal) {
133 uint32_t sr = io_read32(rng_base + RNG_SR);
134
135 if (sr & RNG_SR_SECS) {
136 /* Conceal by resetting the subsystem (step 1.) */
137 io_setbits32(rng_base + RNG_CR, RNG_CR_CONDRST);
138 io_clrbits32(rng_base + RNG_CR, RNG_CR_CONDRST);
139
140 /* Arm timeout for error_conceal sequence */
141 dev->error_to_ref =
142 timeout_init_us(RNG_READY_TIMEOUT_US);
143 dev->error_conceal = true;
144 } else {
145 /* RNG auto-reset (step 2.) */
146 io_clrbits32(rng_base + RNG_SR, RNG_SR_SEIS);
147 }
148 } else {
149 /* Measure time before possible reschedule */
150 bool timed_out = timeout_elapsed(dev->error_to_ref);
151
152 /* Wait CONDRST is cleared (step 2.) */
153 if (io_read32(rng_base + RNG_CR) & RNG_CR_CONDRST) {
154 if (timed_out)
155 panic();
156
157 /* Wait subsystem reset cycle completes */
158 return;
159 }
160
161 /* Check SEIS is cleared (step 2.) */
162 if (io_read32(rng_base + RNG_SR) & RNG_SR_SEIS)
163 panic();
164
165 /* Wait SECS is cleared (step 3.) */
166 if (io_read32(rng_base + RNG_SR) & RNG_SR_SECS) {
167 if (timed_out)
168 panic();
169
170 /* Wait subsystem reset cycle completes */
171 return;
172 }
173
174 dev->error_conceal = false;
175 }
176 }
177
178 /*
179 * Extracts from the STM32 RNG specification, when CONDRST is not supported
180 *
181 * When a noise source (or seed) error occurs, the RNG stops generating
182 * random numbers and sets to “1” both SEIS and SECS bits to indicate
183 * that a seed error occurred. (...)
184 *
185 * The following sequence shall be used to fully recover from a seed
186 * error after the RNG initialization:
187 * 1. Clear the SEIS bit by writing it to “0”.
188 * 2. Read out 12 words from the RNG_DR register, and discard each of
189 * them in order to clean the pipeline.
190 * 3. Confirm that SEIS is still cleared. Random number generation is
191 * back to normal.
192 */
conceal_seed_error_sw_reset(void)193 static void conceal_seed_error_sw_reset(void)
194 {
195 vaddr_t rng_base = get_base();
196 size_t i = 0;
197
198 io_clrbits32(rng_base + RNG_SR, RNG_SR_SEIS);
199
200 for (i = 12; i != 0; i--)
201 (void)io_read32(rng_base + RNG_DR);
202
203 if (io_read32(rng_base + RNG_SR) & RNG_SR_SEIS)
204 panic("RNG noise");
205 }
206
conceal_seed_error(void)207 static void conceal_seed_error(void)
208 {
209 if (stm32_rng->ddata->has_cond_reset)
210 conceal_seed_error_cond_reset();
211 else
212 conceal_seed_error_sw_reset();
213 }
214
read_available(vaddr_t rng_base,uint8_t * out,size_t * size)215 static TEE_Result read_available(vaddr_t rng_base, uint8_t *out, size_t *size)
216 {
217 struct stm32_rng_instance *dev = stm32_rng;
218 uint8_t *buf = NULL;
219 size_t req_size = 0;
220 size_t len = 0;
221
222 if (dev->error_conceal || io_read32(rng_base + RNG_SR) & RNG_SR_SEIS)
223 conceal_seed_error();
224
225 if (!(io_read32(rng_base + RNG_SR) & RNG_SR_DRDY)) {
226 FMSG("RNG not ready");
227 return TEE_ERROR_NO_DATA;
228 }
229
230 if (io_read32(rng_base + RNG_SR) & RNG_SR_SEIS) {
231 FMSG("RNG noise error");
232 return TEE_ERROR_NO_DATA;
233 }
234
235 buf = out;
236 req_size = MIN(RNG_FIFO_BYTE_DEPTH, *size);
237 len = req_size;
238
239 /* RNG is ready: read up to 4 32bit words */
240 while (len) {
241 uint32_t data32 = 0;
242 size_t sz = MIN(len, sizeof(uint32_t));
243
244 if (!(io_read32(rng_base + RNG_SR) & RNG_SR_DRDY))
245 break;
246 data32 = io_read32(rng_base + RNG_DR);
247
248 /* Late seed error case: DR being 0 is an error status */
249 if (!data32) {
250 conceal_seed_error();
251 return TEE_ERROR_NO_DATA;
252 }
253
254 memcpy(buf, &data32, sz);
255 buf += sz;
256 len -= sz;
257 }
258
259 *size = req_size - len;
260
261 return TEE_SUCCESS;
262 }
263
stm32_rng_clock_freq_restrain(void)264 static uint32_t stm32_rng_clock_freq_restrain(void)
265 {
266 struct stm32_rng_instance *dev = stm32_rng;
267 unsigned long clock_rate = 0;
268 uint32_t clock_div = 0;
269
270 clock_rate = clk_get_rate(dev->clock);
271
272 /*
273 * Get the exponent to apply on the CLKDIV field in RNG_CR register
274 * No need to handle the case when clock-div > 0xF as it is physically
275 * impossible
276 */
277 while ((clock_rate >> clock_div) > dev->ddata->max_noise_clk_freq)
278 clock_div++;
279
280 DMSG("RNG clk rate : %lu", clk_get_rate(dev->clock) >> clock_div);
281
282 return clock_div;
283 }
284
enable_rng_clock(void)285 static TEE_Result enable_rng_clock(void)
286 {
287 TEE_Result res = clk_enable(stm32_rng->clock);
288
289 if (!res && stm32_rng->bus_clock) {
290 res = clk_enable(stm32_rng->bus_clock);
291 if (res)
292 clk_disable(stm32_rng->clock);
293 }
294
295 return res;
296 }
297
disable_rng_clock(void)298 static void disable_rng_clock(void)
299 {
300 clk_disable(stm32_rng->clock);
301 if (stm32_rng->bus_clock)
302 clk_disable(stm32_rng->bus_clock);
303 }
304
stm32_rng_init(void)305 static TEE_Result stm32_rng_init(void)
306 {
307 TEE_Result res = TEE_ERROR_GENERIC;
308 vaddr_t rng_base = get_base();
309 uint32_t cr_ced_mask = 0;
310 uint32_t value = 0;
311
312 res = enable_rng_clock();
313 if (res)
314 return res;
315
316 if (stm32_rng->rstctrl &&
317 rstctrl_assert_to(stm32_rng->rstctrl, RNG_RESET_TIMEOUT_US)) {
318 res = TEE_ERROR_GENERIC;
319 goto out;
320 }
321
322 if (stm32_rng->rstctrl &&
323 rstctrl_deassert_to(stm32_rng->rstctrl, RNG_RESET_TIMEOUT_US)) {
324 res = TEE_ERROR_GENERIC;
325 goto out;
326 }
327
328 if (!stm32_rng->clock_error)
329 cr_ced_mask = RNG_CR_CED;
330
331 /* Clean error indications */
332 io_write32(rng_base + RNG_SR, 0);
333
334 if (stm32_rng->ddata->has_cond_reset) {
335 uint32_t clock_div = stm32_rng_clock_freq_restrain();
336
337 /*
338 * Keep default RNG configuration if none was specified.
339 * 0 is an invalid value as it disables all entropy sources.
340 */
341 if (!stm32_rng->rng_config)
342 stm32_rng->rng_config = io_read32(rng_base + RNG_CR) &
343 RNG_CR_ENTROPY_SRC_MASK;
344
345 /*
346 * Configuration must be set in the same access that sets
347 * RNG_CR_CONDRST bit. Otherwise, the configuration setting is
348 * not taken into account. CONFIGLOCK bit is always cleared at
349 * this stage.
350 */
351 io_clrsetbits32(rng_base + RNG_CR, RNG_CONFIG_MASK,
352 stm32_rng->rng_config | RNG_CR_CONDRST |
353 cr_ced_mask |
354 SHIFT_U32(clock_div, RNG_CR_CLKDIV_SHIFT));
355
356 /*
357 * Write health test and noise source control configuration
358 * according to current RNG entropy source configuration
359 */
360 if (stm32_rng->noise_ctrl_conf)
361 io_write32(rng_base + RNG_NSCR,
362 stm32_rng->noise_ctrl_conf);
363
364 if (stm32_rng->health_test_conf)
365 io_write32(rng_base + RNG_HTCR,
366 stm32_rng->health_test_conf);
367
368 io_clrsetbits32(rng_base + RNG_CR, RNG_CR_CONDRST,
369 RNG_CR_RNGEN);
370
371 if (IO_READ32_POLL_TIMEOUT(rng_base + RNG_CR, value,
372 !(value & RNG_CR_CONDRST), 0,
373 RNG_READY_TIMEOUT_US))
374 panic();
375
376 DMSG("RNG control register %#"PRIx32,
377 io_read32(rng_base + RNG_CR));
378 DMSG("RNG noise source control register %#"PRIx32,
379 io_read32(rng_base + RNG_NSCR));
380 DMSG("RNG health test register %#"PRIx32,
381 io_read32(rng_base + RNG_HTCR));
382 } else {
383 io_setbits32(rng_base + RNG_CR, RNG_CR_RNGEN | cr_ced_mask);
384 }
385
386 if (IO_READ32_POLL_TIMEOUT(rng_base + RNG_SR, value,
387 value & RNG_SR_DRDY, 0,
388 RNG_READY_TIMEOUT_US))
389 return TEE_ERROR_GENERIC;
390
391 res = TEE_SUCCESS;
392
393 out:
394 disable_rng_clock();
395
396 return res;
397 }
398
stm32_rng_read(uint8_t * out,size_t size)399 static TEE_Result stm32_rng_read(uint8_t *out, size_t size)
400 {
401 TEE_Result rc = TEE_ERROR_GENERIC;
402 bool burst_timeout = false;
403 uint64_t timeout_ref = 0;
404 uint32_t exceptions = 0;
405 uint8_t *out_ptr = out;
406 vaddr_t rng_base = 0;
407 size_t out_size = 0;
408
409 if (!stm32_rng) {
410 DMSG("No RNG");
411 return TEE_ERROR_NOT_SUPPORTED;
412 }
413
414 rc = enable_rng_clock();
415 if (rc)
416 return rc;
417
418 rng_base = get_base();
419
420 /* Arm timeout */
421 timeout_ref = timeout_init_us(RNG_READY_TIMEOUT_US);
422 burst_timeout = false;
423
424 while (out_size < size) {
425 /* Read by chunks of the size the RNG FIFO depth */
426 size_t sz = size - out_size;
427
428 exceptions = may_spin_lock(&stm32_rng->lock);
429
430 rc = read_available(rng_base, out_ptr, &sz);
431
432 /* Raise timeout only if we failed to get some samples */
433 assert(!rc || rc == TEE_ERROR_NO_DATA);
434 if (rc)
435 burst_timeout = timeout_elapsed(timeout_ref);
436
437 may_spin_unlock(&stm32_rng->lock, exceptions);
438
439 if (burst_timeout) {
440 rc = TEE_ERROR_GENERIC;
441 goto out;
442 }
443
444 if (!rc) {
445 out_size += sz;
446 out_ptr += sz;
447 /* Re-arm timeout */
448 timeout_ref = timeout_init_us(RNG_READY_TIMEOUT_US);
449 burst_timeout = false;
450 }
451 }
452
453 out:
454 assert(!rc || rc == TEE_ERROR_GENERIC);
455 disable_rng_clock();
456
457 return rc;
458 }
459
460 #ifdef CFG_WITH_SOFTWARE_PRNG
461 /* Override weak plat_rng_init with platform handler to attempt to seed PRNG */
plat_rng_init(void)462 void plat_rng_init(void)
463 {
464 uint8_t seed[RNG_FIFO_BYTE_DEPTH] = { };
465
466 if (!stm32_rng) {
467 __plat_rng_init();
468 DMSG("PRNG seeded without RNG");
469 return;
470 }
471
472 if (stm32_rng_read(seed, sizeof(seed)))
473 panic();
474
475 if (crypto_rng_init(seed, sizeof(seed)))
476 panic();
477
478 DMSG("PRNG seeded with RNG");
479 }
480 #else
hw_get_random_bytes(void * out,size_t size)481 TEE_Result hw_get_random_bytes(void *out, size_t size)
482 {
483 return stm32_rng_read(out, size);
484 }
485
plat_rng_init(void)486 void plat_rng_init(void)
487 {
488 }
489 #endif
490
stm32_rng_pm_resume(void)491 static TEE_Result stm32_rng_pm_resume(void)
492 {
493 vaddr_t base = get_base();
494
495 /* Clean error indications */
496 io_write32(base + RNG_SR, 0);
497
498 if (stm32_rng->ddata->has_cond_reset) {
499 uint64_t timeout_ref = 0;
500
501 /*
502 * Configuration must be set in the same access that sets
503 * RNG_CR_CONDRST bit. Otherwise, the configuration setting is
504 * not taken into account. CONFIGLOCK bit is always cleared in
505 * this configuration.
506 */
507 io_write32(base + RNG_CR, stm32_rng->pm_cr | RNG_CR_CONDRST);
508
509 /* Restore health test and noise control configuration */
510 io_write32(base + RNG_NSCR, stm32_rng->pm_noise_ctrl);
511 io_write32(base + RNG_HTCR, stm32_rng->pm_health);
512
513 io_clrsetbits32(base + RNG_CR, RNG_CR_CONDRST, RNG_CR_RNGEN);
514
515 timeout_ref = timeout_init_us(RNG_READY_TIMEOUT_US);
516 while (io_read32(base + RNG_CR) & RNG_CR_CONDRST)
517 if (timeout_elapsed(timeout_ref))
518 break;
519 if (io_read32(base + RNG_CR) & RNG_CR_CONDRST)
520 panic();
521 } else {
522 io_write32(base + RNG_CR, RNG_CR_RNGEN | stm32_rng->pm_cr);
523 }
524
525 return TEE_SUCCESS;
526 }
527
stm32_rng_pm_suspend(void)528 static TEE_Result stm32_rng_pm_suspend(void)
529 {
530 vaddr_t rng_base = get_base();
531
532 stm32_rng->pm_cr = io_read32(rng_base + RNG_CR);
533
534 if (stm32_rng->ddata->has_cond_reset) {
535 stm32_rng->pm_health = io_read32(rng_base + RNG_HTCR);
536 stm32_rng->pm_noise_ctrl = io_read32(rng_base + RNG_NSCR);
537 }
538
539 if (stm32_rng->ddata->has_power_optim) {
540 uint64_t timeout_ref = 0;
541
542 /*
543 * As per reference manual, it is recommended to set
544 * RNG_CONFIG2[bit0] when RNG power consumption is critical.
545 */
546 io_setbits32(rng_base + RNG_CR, RNG_CR_POWER_OPTIM |
547 RNG_CR_CONDRST);
548 io_clrbits32(rng_base + RNG_CR, RNG_CR_CONDRST);
549
550 timeout_ref = timeout_init_us(RNG_READY_TIMEOUT_US);
551 while (io_read32(rng_base + RNG_CR) & RNG_CR_CONDRST)
552 if (timeout_elapsed(timeout_ref))
553 break;
554 if (io_read32(rng_base + RNG_CR) & RNG_CR_CONDRST)
555 panic();
556 } else {
557 io_clrbits32(rng_base + RNG_CR, RNG_CR_RNGEN);
558 }
559
560 return TEE_SUCCESS;
561 }
562
563 static TEE_Result
stm32_rng_pm(enum pm_op op,unsigned int pm_hint __unused,const struct pm_callback_handle * pm_handle __unused)564 stm32_rng_pm(enum pm_op op, unsigned int pm_hint __unused,
565 const struct pm_callback_handle *pm_handle __unused)
566 {
567 TEE_Result res = TEE_ERROR_GENERIC;
568
569 assert(stm32_rng && (op == PM_OP_SUSPEND || op == PM_OP_RESUME));
570
571 res = enable_rng_clock();
572 if (res)
573 return res;
574
575 if (op == PM_OP_RESUME)
576 res = stm32_rng_pm_resume();
577 else
578 res = stm32_rng_pm_suspend();
579
580 disable_rng_clock();
581
582 return res;
583 }
584 DECLARE_KEEP_PAGER(stm32_rng_pm);
585
stm32_rng_parse_fdt(const void * fdt,int node)586 static TEE_Result stm32_rng_parse_fdt(const void *fdt, int node)
587 {
588 TEE_Result res = TEE_ERROR_GENERIC;
589 struct dt_node_info dt_rng = { };
590
591 fdt_fill_device_info(fdt, &dt_rng, node);
592 if (dt_rng.reg == DT_INFO_INVALID_REG)
593 return TEE_ERROR_BAD_PARAMETERS;
594
595 stm32_rng->base.pa = dt_rng.reg;
596 stm32_rng->base.va = io_pa_or_va_secure(&stm32_rng->base,
597 dt_rng.reg_size);
598 assert(stm32_rng->base.va);
599
600 res = rstctrl_dt_get_by_index(fdt, node, 0, &stm32_rng->rstctrl);
601 if (res != TEE_SUCCESS && res != TEE_ERROR_ITEM_NOT_FOUND)
602 return res;
603
604 if (stm32_rng->ddata->nb_clock > 1) {
605 res = clk_dt_get_by_name(fdt, node, "rng_clk",
606 &stm32_rng->clock);
607 if (res)
608 return res;
609
610 res = clk_dt_get_by_name(fdt, node, "rng_hclk",
611 &stm32_rng->bus_clock);
612 if (res)
613 return res;
614 } else {
615 res = clk_dt_get_by_index(fdt, node, 0, &stm32_rng->clock);
616 if (res)
617 return res;
618 }
619
620 if (fdt_getprop(fdt, node, "clock-error-detect", NULL))
621 stm32_rng->clock_error = true;
622
623 stm32_rng->rng_config = stm32_rng->ddata->cr;
624 if (stm32_rng->rng_config & ~RNG_CR_ENTROPY_SRC_MASK)
625 panic("Incorrect entropy source configuration");
626 stm32_rng->health_test_conf = stm32_rng->ddata->htcr;
627 stm32_rng->noise_ctrl_conf = stm32_rng->ddata->nscr;
628 if (stm32_rng->noise_ctrl_conf & ~RNG_NSCR_MASK)
629 panic("Incorrect noise source control configuration");
630
631 return TEE_SUCCESS;
632 }
633
stm32_rng_probe(const void * fdt,int offs,const void * compat_data)634 static TEE_Result stm32_rng_probe(const void *fdt, int offs,
635 const void *compat_data)
636 {
637 unsigned int __maybe_unused version = 0;
638 TEE_Result res = TEE_ERROR_GENERIC;
639
640 /* Expect a single RNG instance */
641 assert(!stm32_rng);
642
643 stm32_rng = calloc(1, sizeof(*stm32_rng));
644 if (!stm32_rng)
645 panic();
646
647 stm32_rng->ddata = compat_data;
648 assert(stm32_rng->ddata);
649
650 res = stm32_rng_parse_fdt(fdt, offs);
651 if (res)
652 goto err;
653
654 res = enable_rng_clock();
655 if (res)
656 goto err;
657
658 version = io_read32(get_base() + RNG_VERR);
659 DMSG("RNG version Major %u, Minor %u",
660 (version & RNG_VERR_MAJOR_MASK) >> RNG_VERR_MAJOR_SHIFT,
661 version & RNG_VERR_MINOR_MASK);
662
663 disable_rng_clock();
664
665 res = stm32_rng_init();
666 if (res)
667 goto err;
668
669 /* Power management implementation expects both or none are set */
670 assert(stm32_rng->ddata->has_power_optim ==
671 stm32_rng->ddata->has_cond_reset);
672
673 if (!IS_ENABLED(CFG_WITH_SOFTWARE_PRNG))
674 register_pm_core_service_cb(stm32_rng_pm, &stm32_rng,
675 "rng-service");
676
677 return TEE_SUCCESS;
678
679 err:
680 free(stm32_rng);
681 stm32_rng = NULL;
682
683 return res;
684 }
685
686 static const struct stm32_rng_driver_data mp13_data[] = {
687 {
688 .max_noise_clk_freq = U(48000000),
689 .nb_clock = 1,
690 .has_cond_reset = true,
691 .has_power_optim = true,
692 .cr = 0x00F00D00,
693 .nscr = 0x2B5BB,
694 .htcr = 0x969D,
695 },
696 };
697
698 static const struct stm32_rng_driver_data mp15_data[] = {
699 {
700 .max_noise_clk_freq = U(48000000),
701 .nb_clock = 1,
702 .has_cond_reset = false,
703 .has_power_optim = false,
704 },
705 };
706 DECLARE_KEEP_PAGER(mp15_data);
707
708 static const struct stm32_rng_driver_data mp25_data[] = {
709 {
710 .max_noise_clk_freq = U(48000000),
711 .nb_clock = 2,
712 .has_cond_reset = true,
713 .has_power_optim = true,
714 .cr = 0x00F00D00,
715 .nscr = 0x2B5BB,
716 .htcr = 0x969D,
717 },
718 };
719
720 static const struct dt_device_match rng_match_table[] = {
721 { .compatible = "st,stm32-rng", .compat_data = &mp15_data },
722 { .compatible = "st,stm32mp13-rng", .compat_data = &mp13_data },
723 { .compatible = "st,stm32mp25-rng", .compat_data = &mp25_data },
724 { }
725 };
726
727 DEFINE_DT_DRIVER(stm32_rng_dt_driver) = {
728 .name = "stm32_rng",
729 .match_table = rng_match_table,
730 .probe = stm32_rng_probe,
731 };
732
stm32_rng_release(void)733 static TEE_Result stm32_rng_release(void)
734 {
735 if (stm32_rng && IS_ENABLED(CFG_WITH_SOFTWARE_PRNG)) {
736 DMSG("Release RNG driver");
737 free(stm32_rng);
738 stm32_rng = NULL;
739 }
740
741 return TEE_SUCCESS;
742 }
743
744 release_init_resource(stm32_rng_release);
745