1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2019, Linaro Limited
4  */
5 
6 #define LOG_CATEGORY UCLASS_RNG
7 
8 #include <clk.h>
9 #include <dm.h>
10 #include <log.h>
11 #include <reset.h>
12 #include <rng.h>
13 #include <asm/io.h>
14 #include <linux/bitops.h>
15 #include <linux/delay.h>
16 #include <linux/iopoll.h>
17 #include <linux/kernel.h>
18 
19 #define RNG_CR			0x00
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)
31 
32 #define RNG_SR		0x04
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)
37 
38 #define RNG_DR		0x08
39 
40 #define RNG_NSCR		0x0C
41 #define RNG_NSCR_MASK		GENMASK(17, 0)
42 
43 #define RNG_HTCR	0x10
44 
45 #define RNG_NB_RECOVER_TRIES	3
46 
47 /*
48  * struct stm32_rng_data - RNG compat data
49  *
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
55  *
56  */
57 struct stm32_rng_data {
58 	uint max_clock_rate;
59 	u32 cr;
60 	u32 nscr;
61 	u32 htcr;
62 	bool has_cond_reset;
63 };
64 
65 struct stm32_rng_plat {
66 	fdt_addr_t base;
67 	struct clk clk;
68 	struct reset_ctl rst;
69 	const struct stm32_rng_data *data;
70 	bool ced;
71 };
72 
73 /*
74  * Extracts from the STM32 RNG specification when RNG supports CONDRST.
75  *
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. (...)
79  *
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.
90  */
stm32_rng_conceal_seed_error_cond_reset(struct stm32_rng_plat * pdata)91 static int stm32_rng_conceal_seed_error_cond_reset(struct stm32_rng_plat *pdata)
92 {
93 	u32 sr = readl_relaxed(pdata->base + RNG_SR);
94 	u32 cr = readl_relaxed(pdata->base + RNG_CR);
95 	int err;
96 
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);
101 	} else {
102 		/* RNG auto-reset (step 2.) */
103 		writel_relaxed(sr & ~RNG_SR_SEIS, pdata->base + RNG_SR);
104 		return 0;
105 	}
106 
107 	err = readl_relaxed_poll_timeout(pdata->base + RNG_SR, sr, !(sr & RNG_CR_CONDRST), 100000);
108 	if (err) {
109 		log_err("%s: timeout %x\n", __func__, sr);
110 		return err;
111 	}
112 
113 	/* Check SEIS is cleared (step 2.) */
114 	if (readl_relaxed(pdata->base + RNG_SR) & RNG_SR_SEIS)
115 		return -EINVAL;
116 
117 	err = readl_relaxed_poll_timeout(pdata->base + RNG_SR, sr, !(sr & RNG_SR_SECS), 100000);
118 	if (err) {
119 		log_err("%s: timeout %x\n", __func__, sr);
120 		return err;
121 	}
122 
123 	return 0;
124 }
125 
126 /*
127  * Extracts from the STM32 RNG specification, when CONDRST is not supported
128  *
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. (...)
132  *
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
139  * back to normal.
140  */
stm32_rng_conceal_seed_error_sw_reset(struct stm32_rng_plat * pdata)141 static int stm32_rng_conceal_seed_error_sw_reset(struct stm32_rng_plat *pdata)
142 {
143 	uint i = 0;
144 	u32 sr = readl_relaxed(pdata->base + RNG_SR);
145 
146 	writel_relaxed(sr & ~RNG_SR_SEIS, pdata->base + RNG_SR);
147 
148 	for (i = 12; i != 0; i--)
149 		(void)readl_relaxed(pdata->base + RNG_DR);
150 
151 	if (readl_relaxed(pdata->base + RNG_SR) & RNG_SR_SEIS)
152 		return -EINVAL;
153 
154 	return 0;
155 }
156 
stm32_rng_conceal_seed_error(struct stm32_rng_plat * pdata)157 static int stm32_rng_conceal_seed_error(struct stm32_rng_plat *pdata)
158 {
159 	log_debug("Concealing RNG seed error\n");
160 
161 	if (pdata->data->has_cond_reset)
162 		return stm32_rng_conceal_seed_error_cond_reset(pdata);
163 	else
164 		return stm32_rng_conceal_seed_error_sw_reset(pdata);
165 };
166 
stm32_rng_read(struct udevice * dev,void * data,size_t len)167 static int stm32_rng_read(struct udevice *dev, void *data, size_t len)
168 {
169 	int retval;
170 	u32 sr, reg;
171 	size_t increment;
172 	struct stm32_rng_plat *pdata = dev_get_plat(dev);
173 	uint tries = 0;
174 
175 	while (len > 0) {
176 		retval = readl_poll_timeout(pdata->base + RNG_SR, sr,
177 					    sr, 10000);
178 		if (retval) {
179 			log_err("%s: Timeout RNG no data",  __func__);
180 			return retval;
181 		}
182 
183 		if (sr != RNG_SR_DRDY) {
184 			if (sr & RNG_SR_SEIS) {
185 				retval = stm32_rng_conceal_seed_error(pdata);
186 				tries++;
187 				if (retval || tries > RNG_NB_RECOVER_TRIES) {
188 					log_err("%s: Couldn't recover from seed error",  __func__);
189 					return -ENOTRECOVERABLE;
190 				}
191 
192 				/* Start again */
193 				continue;
194 			}
195 
196 			if (sr & RNG_SR_CEIS) {
197 				log_info("RNG clock too slow");
198 				writel_relaxed(0, pdata->base + RNG_SR);
199 			}
200 		}
201 
202 		/*
203 		 * Once the DRDY bit is set, the RNG_DR register can
204 		 * be read up to four consecutive times.
205 		 */
206 		reg = readl(pdata->base + RNG_DR);
207 		/* Late seed error case: DR being 0 is an error status */
208 		if (!reg) {
209 			retval = stm32_rng_conceal_seed_error(pdata);
210 			tries++;
211 
212 			if (retval || tries > RNG_NB_RECOVER_TRIES) {
213 				log_err("%s: Couldn't recover from seed error",  __func__);
214 				return -ENOTRECOVERABLE;
215 			}
216 
217 			/* Start again */
218 			continue;
219 		}
220 
221 		increment = min(len, sizeof(u32));
222 		memcpy(data, &reg, increment);
223 		data += increment;
224 		len -= increment;
225 
226 		tries = 0;
227 	}
228 
229 	return 0;
230 }
231 
stm32_rng_clock_freq_restrain(struct stm32_rng_plat * pdata)232 static uint stm32_rng_clock_freq_restrain(struct stm32_rng_plat *pdata)
233 {
234 	ulong clock_rate = 0;
235 	uint clock_div = 0;
236 
237 	clock_rate = clk_get_rate(&pdata->clk);
238 
239 	/*
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
242 	 * impossible.
243 	 */
244 	while ((clock_rate >> clock_div) > pdata->data->max_clock_rate)
245 		clock_div++;
246 
247 	log_debug("RNG clk rate : %lu\n", clk_get_rate(&pdata->clk) >> clock_div);
248 
249 	return clock_div;
250 }
251 
stm32_rng_init(struct stm32_rng_plat * pdata)252 static int stm32_rng_init(struct stm32_rng_plat *pdata)
253 {
254 	int err;
255 	u32 cr, sr;
256 
257 	err = clk_enable(&pdata->clk);
258 	if (err)
259 		return err;
260 
261 	cr = readl(pdata->base + RNG_CR);
262 
263 	/*
264 	 * Keep default RNG configuration if none was specified, that is when conf.cr is set to 0.
265 	 */
266 	if (pdata->data->has_cond_reset && pdata->data->cr) {
267 		uint clock_div = stm32_rng_clock_freq_restrain(pdata);
268 
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);
272 		if (pdata->ced)
273 			cr &= ~RNG_CR_CED;
274 		else
275 			cr |= RNG_CR_CED;
276 		writel(cr, pdata->base + RNG_CR);
277 
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);
281 
282 		cr &= ~RNG_CR_CONDRST;
283 		cr |= RNG_CR_RNGEN;
284 		writel(cr, pdata->base + RNG_CR);
285 		err = readl_poll_timeout(pdata->base + RNG_CR, cr,
286 					 (!(cr & RNG_CR_CONDRST)), 10000);
287 		if (err) {
288 			log_err("%s: Timeout!",  __func__);
289 			return err;
290 		}
291 	} else {
292 		if (pdata->data->has_cond_reset)
293 			cr |= RNG_CR_CONDRST;
294 
295 		if (pdata->ced)
296 			cr &= ~RNG_CR_CED;
297 		else
298 			cr |= RNG_CR_CED;
299 
300 		writel(cr, pdata->base + RNG_CR);
301 
302 		if (pdata->data->has_cond_reset)
303 			cr &= ~RNG_CR_CONDRST;
304 
305 		cr |= RNG_CR_RNGEN;
306 
307 		writel(cr, pdata->base + RNG_CR);
308 	}
309 
310 	/* clear error indicators */
311 	writel(0, pdata->base + RNG_SR);
312 
313 	err = readl_poll_timeout(pdata->base + RNG_SR, sr,
314 				 sr & RNG_SR_DRDY, 10000);
315 	if (err)
316 		log_err("%s: Timeout!",  __func__);
317 
318 	return err;
319 }
320 
stm32_rng_cleanup(struct stm32_rng_plat * pdata)321 static int stm32_rng_cleanup(struct stm32_rng_plat *pdata)
322 {
323 	writel(0, pdata->base + RNG_CR);
324 
325 	return clk_disable(&pdata->clk);
326 }
327 
stm32_rng_probe(struct udevice * dev)328 static int stm32_rng_probe(struct udevice *dev)
329 {
330 	struct stm32_rng_plat *pdata = dev_get_plat(dev);
331 
332 	pdata->data = (struct stm32_rng_data *)dev_get_driver_data(dev);
333 
334 	reset_assert(&pdata->rst);
335 	udelay(20);
336 	reset_deassert(&pdata->rst);
337 
338 	return stm32_rng_init(pdata);
339 }
340 
stm32_rng_remove(struct udevice * dev)341 static int stm32_rng_remove(struct udevice *dev)
342 {
343 	struct stm32_rng_plat *pdata = dev_get_plat(dev);
344 
345 	return stm32_rng_cleanup(pdata);
346 }
347 
stm32_rng_of_to_plat(struct udevice * dev)348 static int stm32_rng_of_to_plat(struct udevice *dev)
349 {
350 	struct stm32_rng_plat *pdata = dev_get_plat(dev);
351 	int err;
352 
353 	pdata->base = dev_read_addr(dev);
354 	if (!pdata->base)
355 		return -ENOMEM;
356 
357 	err = clk_get_by_index(dev, 0, &pdata->clk);
358 	if (err)
359 		return err;
360 
361 	err = reset_get_by_index(dev, 0, &pdata->rst);
362 	if (err)
363 		return err;
364 
365 	pdata->ced = dev_read_bool(dev, "clock-error-detect");
366 
367 	return 0;
368 }
369 
370 static const struct dm_rng_ops stm32_rng_ops = {
371 	.read = stm32_rng_read,
372 };
373 
374 static const struct stm32_rng_data stm32mp13_rng_data = {
375 	.has_cond_reset = true,
376 	.max_clock_rate = 48000000,
377 	.htcr = 0x969D,
378 	.nscr = 0x2B5BB,
379 	.cr = 0xF00D00,
380 };
381 
382 static const struct stm32_rng_data stm32_rng_data = {
383 	.has_cond_reset = false,
384 	.max_clock_rate = 3000000,
385 	/* Not supported */
386 	.htcr = 0,
387 	.nscr = 0,
388 	.cr = 0,
389 };
390 
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},
394 	{},
395 };
396 
397 U_BOOT_DRIVER(stm32_rng) = {
398 	.name = "stm32-rng",
399 	.id = UCLASS_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,
406 };
407