xref: /linux/drivers/char/hw_random/omap-rng.c (revision 3bdab16c55f57a24245c97d707241dd9b48d1a91)
1 /*
2  * omap-rng.c - RNG driver for TI OMAP CPU family
3  *
4  * Author: Deepak Saxena <dsaxena@plexity.net>
5  *
6  * Copyright 2005 (c) MontaVista Software, Inc.
7  *
8  * Mostly based on original driver:
9  *
10  * Copyright (C) 2005 Nokia Corporation
11  * Author: Juha Yrjölä <juha.yrjola@nokia.com>
12  *
13  * This file is licensed under  the terms of the GNU General Public
14  * License version 2. This program is licensed "as is" without any
15  * warranty of any kind, whether express or implied.
16  */
17 
18 #include <linux/module.h>
19 #include <linux/init.h>
20 #include <linux/random.h>
21 #include <linux/err.h>
22 #include <linux/platform_device.h>
23 #include <linux/hw_random.h>
24 #include <linux/delay.h>
25 #include <linux/slab.h>
26 #include <linux/pm_runtime.h>
27 #include <linux/of.h>
28 #include <linux/of_device.h>
29 #include <linux/of_address.h>
30 #include <linux/interrupt.h>
31 #include <linux/clk.h>
32 
33 #include <asm/io.h>
34 
35 #define RNG_REG_STATUS_RDY			(1 << 0)
36 
37 #define RNG_REG_INTACK_RDY_MASK			(1 << 0)
38 #define RNG_REG_INTACK_SHUTDOWN_OFLO_MASK	(1 << 1)
39 #define RNG_SHUTDOWN_OFLO_MASK			(1 << 1)
40 
41 #define RNG_CONTROL_STARTUP_CYCLES_SHIFT	16
42 #define RNG_CONTROL_STARTUP_CYCLES_MASK		(0xffff << 16)
43 #define RNG_CONTROL_ENABLE_TRNG_SHIFT		10
44 #define RNG_CONTROL_ENABLE_TRNG_MASK		(1 << 10)
45 
46 #define RNG_CONFIG_MAX_REFIL_CYCLES_SHIFT	16
47 #define RNG_CONFIG_MAX_REFIL_CYCLES_MASK	(0xffff << 16)
48 #define RNG_CONFIG_MIN_REFIL_CYCLES_SHIFT	0
49 #define RNG_CONFIG_MIN_REFIL_CYCLES_MASK	(0xff << 0)
50 
51 #define RNG_CONTROL_STARTUP_CYCLES		0xff
52 #define RNG_CONFIG_MIN_REFIL_CYCLES		0x21
53 #define RNG_CONFIG_MAX_REFIL_CYCLES		0x22
54 
55 #define RNG_ALARMCNT_ALARM_TH_SHIFT		0x0
56 #define RNG_ALARMCNT_ALARM_TH_MASK		(0xff << 0)
57 #define RNG_ALARMCNT_SHUTDOWN_TH_SHIFT		16
58 #define RNG_ALARMCNT_SHUTDOWN_TH_MASK		(0x1f << 16)
59 #define RNG_ALARM_THRESHOLD			0xff
60 #define RNG_SHUTDOWN_THRESHOLD			0x4
61 
62 #define RNG_REG_FROENABLE_MASK			0xffffff
63 #define RNG_REG_FRODETUNE_MASK			0xffffff
64 
65 #define OMAP2_RNG_OUTPUT_SIZE			0x4
66 #define OMAP4_RNG_OUTPUT_SIZE			0x8
67 #define EIP76_RNG_OUTPUT_SIZE			0x10
68 
69 enum {
70 	RNG_OUTPUT_0_REG = 0,
71 	RNG_OUTPUT_1_REG,
72 	RNG_OUTPUT_2_REG,
73 	RNG_OUTPUT_3_REG,
74 	RNG_STATUS_REG,
75 	RNG_INTMASK_REG,
76 	RNG_INTACK_REG,
77 	RNG_CONTROL_REG,
78 	RNG_CONFIG_REG,
79 	RNG_ALARMCNT_REG,
80 	RNG_FROENABLE_REG,
81 	RNG_FRODETUNE_REG,
82 	RNG_ALARMMASK_REG,
83 	RNG_ALARMSTOP_REG,
84 	RNG_REV_REG,
85 	RNG_SYSCONFIG_REG,
86 };
87 
88 static const u16 reg_map_omap2[] = {
89 	[RNG_OUTPUT_0_REG]	= 0x0,
90 	[RNG_STATUS_REG]	= 0x4,
91 	[RNG_CONFIG_REG]	= 0x28,
92 	[RNG_REV_REG]		= 0x3c,
93 	[RNG_SYSCONFIG_REG]	= 0x40,
94 };
95 
96 static const u16 reg_map_omap4[] = {
97 	[RNG_OUTPUT_0_REG]	= 0x0,
98 	[RNG_OUTPUT_1_REG]	= 0x4,
99 	[RNG_STATUS_REG]	= 0x8,
100 	[RNG_INTMASK_REG]	= 0xc,
101 	[RNG_INTACK_REG]	= 0x10,
102 	[RNG_CONTROL_REG]	= 0x14,
103 	[RNG_CONFIG_REG]	= 0x18,
104 	[RNG_ALARMCNT_REG]	= 0x1c,
105 	[RNG_FROENABLE_REG]	= 0x20,
106 	[RNG_FRODETUNE_REG]	= 0x24,
107 	[RNG_ALARMMASK_REG]	= 0x28,
108 	[RNG_ALARMSTOP_REG]	= 0x2c,
109 	[RNG_REV_REG]		= 0x1FE0,
110 	[RNG_SYSCONFIG_REG]	= 0x1FE4,
111 };
112 
113 static const u16 reg_map_eip76[] = {
114 	[RNG_OUTPUT_0_REG]	= 0x0,
115 	[RNG_OUTPUT_1_REG]	= 0x4,
116 	[RNG_OUTPUT_2_REG]	= 0x8,
117 	[RNG_OUTPUT_3_REG]	= 0xc,
118 	[RNG_STATUS_REG]	= 0x10,
119 	[RNG_INTACK_REG]	= 0x10,
120 	[RNG_CONTROL_REG]	= 0x14,
121 	[RNG_CONFIG_REG]	= 0x18,
122 	[RNG_ALARMCNT_REG]	= 0x1c,
123 	[RNG_FROENABLE_REG]	= 0x20,
124 	[RNG_FRODETUNE_REG]	= 0x24,
125 	[RNG_ALARMMASK_REG]	= 0x28,
126 	[RNG_ALARMSTOP_REG]	= 0x2c,
127 	[RNG_REV_REG]		= 0x7c,
128 };
129 
130 struct omap_rng_dev;
131 /**
132  * struct omap_rng_pdata - RNG IP block-specific data
133  * @regs: Pointer to the register offsets structure.
134  * @data_size: No. of bytes in RNG output.
135  * @data_present: Callback to determine if data is available.
136  * @init: Callback for IP specific initialization sequence.
137  * @cleanup: Callback for IP specific cleanup sequence.
138  */
139 struct omap_rng_pdata {
140 	u16	*regs;
141 	u32	data_size;
142 	u32	(*data_present)(struct omap_rng_dev *priv);
143 	int	(*init)(struct omap_rng_dev *priv);
144 	void	(*cleanup)(struct omap_rng_dev *priv);
145 };
146 
147 struct omap_rng_dev {
148 	void __iomem			*base;
149 	struct device			*dev;
150 	const struct omap_rng_pdata	*pdata;
151 	struct hwrng rng;
152 	struct clk 			*clk;
153 	struct clk			*clk_reg;
154 };
155 
156 static inline u32 omap_rng_read(struct omap_rng_dev *priv, u16 reg)
157 {
158 	return __raw_readl(priv->base + priv->pdata->regs[reg]);
159 }
160 
161 static inline void omap_rng_write(struct omap_rng_dev *priv, u16 reg,
162 				      u32 val)
163 {
164 	__raw_writel(val, priv->base + priv->pdata->regs[reg]);
165 }
166 
167 
168 static int omap_rng_do_read(struct hwrng *rng, void *data, size_t max,
169 			    bool wait)
170 {
171 	struct omap_rng_dev *priv;
172 	int i, present;
173 
174 	priv = (struct omap_rng_dev *)rng->priv;
175 
176 	if (max < priv->pdata->data_size)
177 		return 0;
178 
179 	for (i = 0; i < 20; i++) {
180 		present = priv->pdata->data_present(priv);
181 		if (present || !wait)
182 			break;
183 
184 		udelay(10);
185 	}
186 	if (!present)
187 		return 0;
188 
189 	memcpy_fromio(data, priv->base + priv->pdata->regs[RNG_OUTPUT_0_REG],
190 		      priv->pdata->data_size);
191 
192 	if (priv->pdata->regs[RNG_INTACK_REG])
193 		omap_rng_write(priv, RNG_INTACK_REG, RNG_REG_INTACK_RDY_MASK);
194 
195 	return priv->pdata->data_size;
196 }
197 
198 static int omap_rng_init(struct hwrng *rng)
199 {
200 	struct omap_rng_dev *priv;
201 
202 	priv = (struct omap_rng_dev *)rng->priv;
203 	return priv->pdata->init(priv);
204 }
205 
206 static void omap_rng_cleanup(struct hwrng *rng)
207 {
208 	struct omap_rng_dev *priv;
209 
210 	priv = (struct omap_rng_dev *)rng->priv;
211 	priv->pdata->cleanup(priv);
212 }
213 
214 
215 static inline u32 omap2_rng_data_present(struct omap_rng_dev *priv)
216 {
217 	return omap_rng_read(priv, RNG_STATUS_REG) ? 0 : 1;
218 }
219 
220 static int omap2_rng_init(struct omap_rng_dev *priv)
221 {
222 	omap_rng_write(priv, RNG_SYSCONFIG_REG, 0x1);
223 	return 0;
224 }
225 
226 static void omap2_rng_cleanup(struct omap_rng_dev *priv)
227 {
228 	omap_rng_write(priv, RNG_SYSCONFIG_REG, 0x0);
229 }
230 
231 static struct omap_rng_pdata omap2_rng_pdata = {
232 	.regs		= (u16 *)reg_map_omap2,
233 	.data_size	= OMAP2_RNG_OUTPUT_SIZE,
234 	.data_present	= omap2_rng_data_present,
235 	.init		= omap2_rng_init,
236 	.cleanup	= omap2_rng_cleanup,
237 };
238 
239 #if defined(CONFIG_OF)
240 static inline u32 omap4_rng_data_present(struct omap_rng_dev *priv)
241 {
242 	return omap_rng_read(priv, RNG_STATUS_REG) & RNG_REG_STATUS_RDY;
243 }
244 
245 static int eip76_rng_init(struct omap_rng_dev *priv)
246 {
247 	u32 val;
248 
249 	/* Return if RNG is already running. */
250 	if (omap_rng_read(priv, RNG_CONTROL_REG) & RNG_CONTROL_ENABLE_TRNG_MASK)
251 		return 0;
252 
253 	/*  Number of 512 bit blocks of raw Noise Source output data that must
254 	 *  be processed by either the Conditioning Function or the
255 	 *  SP 800-90 DRBG ‘BC_DF’ functionality to yield a ‘full entropy’
256 	 *  output value.
257 	 */
258 	val = 0x5 << RNG_CONFIG_MIN_REFIL_CYCLES_SHIFT;
259 
260 	/* Number of FRO samples that are XOR-ed together into one bit to be
261 	 * shifted into the main shift register
262 	 */
263 	val |= RNG_CONFIG_MAX_REFIL_CYCLES << RNG_CONFIG_MAX_REFIL_CYCLES_SHIFT;
264 	omap_rng_write(priv, RNG_CONFIG_REG, val);
265 
266 	/* Enable all available FROs */
267 	omap_rng_write(priv, RNG_FRODETUNE_REG, 0x0);
268 	omap_rng_write(priv, RNG_FROENABLE_REG, RNG_REG_FROENABLE_MASK);
269 
270 	/* Enable TRNG */
271 	val = RNG_CONTROL_ENABLE_TRNG_MASK;
272 	omap_rng_write(priv, RNG_CONTROL_REG, val);
273 
274 	return 0;
275 }
276 
277 static int omap4_rng_init(struct omap_rng_dev *priv)
278 {
279 	u32 val;
280 
281 	/* Return if RNG is already running. */
282 	if (omap_rng_read(priv, RNG_CONTROL_REG) & RNG_CONTROL_ENABLE_TRNG_MASK)
283 		return 0;
284 
285 	val = RNG_CONFIG_MIN_REFIL_CYCLES << RNG_CONFIG_MIN_REFIL_CYCLES_SHIFT;
286 	val |= RNG_CONFIG_MAX_REFIL_CYCLES << RNG_CONFIG_MAX_REFIL_CYCLES_SHIFT;
287 	omap_rng_write(priv, RNG_CONFIG_REG, val);
288 
289 	omap_rng_write(priv, RNG_FRODETUNE_REG, 0x0);
290 	omap_rng_write(priv, RNG_FROENABLE_REG, RNG_REG_FROENABLE_MASK);
291 	val = RNG_ALARM_THRESHOLD << RNG_ALARMCNT_ALARM_TH_SHIFT;
292 	val |= RNG_SHUTDOWN_THRESHOLD << RNG_ALARMCNT_SHUTDOWN_TH_SHIFT;
293 	omap_rng_write(priv, RNG_ALARMCNT_REG, val);
294 
295 	val = RNG_CONTROL_STARTUP_CYCLES << RNG_CONTROL_STARTUP_CYCLES_SHIFT;
296 	val |= RNG_CONTROL_ENABLE_TRNG_MASK;
297 	omap_rng_write(priv, RNG_CONTROL_REG, val);
298 
299 	return 0;
300 }
301 
302 static void omap4_rng_cleanup(struct omap_rng_dev *priv)
303 {
304 	int val;
305 
306 	val = omap_rng_read(priv, RNG_CONTROL_REG);
307 	val &= ~RNG_CONTROL_ENABLE_TRNG_MASK;
308 	omap_rng_write(priv, RNG_CONTROL_REG, val);
309 }
310 
311 static irqreturn_t omap4_rng_irq(int irq, void *dev_id)
312 {
313 	struct omap_rng_dev *priv = dev_id;
314 	u32 fro_detune, fro_enable;
315 
316 	/*
317 	 * Interrupt raised by a fro shutdown threshold, do the following:
318 	 * 1. Clear the alarm events.
319 	 * 2. De tune the FROs which are shutdown.
320 	 * 3. Re enable the shutdown FROs.
321 	 */
322 	omap_rng_write(priv, RNG_ALARMMASK_REG, 0x0);
323 	omap_rng_write(priv, RNG_ALARMSTOP_REG, 0x0);
324 
325 	fro_enable = omap_rng_read(priv, RNG_FROENABLE_REG);
326 	fro_detune = ~fro_enable & RNG_REG_FRODETUNE_MASK;
327 	fro_detune = fro_detune | omap_rng_read(priv, RNG_FRODETUNE_REG);
328 	fro_enable = RNG_REG_FROENABLE_MASK;
329 
330 	omap_rng_write(priv, RNG_FRODETUNE_REG, fro_detune);
331 	omap_rng_write(priv, RNG_FROENABLE_REG, fro_enable);
332 
333 	omap_rng_write(priv, RNG_INTACK_REG, RNG_REG_INTACK_SHUTDOWN_OFLO_MASK);
334 
335 	return IRQ_HANDLED;
336 }
337 
338 static struct omap_rng_pdata omap4_rng_pdata = {
339 	.regs		= (u16 *)reg_map_omap4,
340 	.data_size	= OMAP4_RNG_OUTPUT_SIZE,
341 	.data_present	= omap4_rng_data_present,
342 	.init		= omap4_rng_init,
343 	.cleanup	= omap4_rng_cleanup,
344 };
345 
346 static struct omap_rng_pdata eip76_rng_pdata = {
347 	.regs		= (u16 *)reg_map_eip76,
348 	.data_size	= EIP76_RNG_OUTPUT_SIZE,
349 	.data_present	= omap4_rng_data_present,
350 	.init		= eip76_rng_init,
351 	.cleanup	= omap4_rng_cleanup,
352 };
353 
354 static const struct of_device_id omap_rng_of_match[] = {
355 		{
356 			.compatible	= "ti,omap2-rng",
357 			.data		= &omap2_rng_pdata,
358 		},
359 		{
360 			.compatible	= "ti,omap4-rng",
361 			.data		= &omap4_rng_pdata,
362 		},
363 		{
364 			.compatible	= "inside-secure,safexcel-eip76",
365 			.data		= &eip76_rng_pdata,
366 		},
367 		{},
368 };
369 MODULE_DEVICE_TABLE(of, omap_rng_of_match);
370 
371 static int of_get_omap_rng_device_details(struct omap_rng_dev *priv,
372 					  struct platform_device *pdev)
373 {
374 	const struct of_device_id *match;
375 	struct device *dev = &pdev->dev;
376 	int irq, err;
377 
378 	match = of_match_device(of_match_ptr(omap_rng_of_match), dev);
379 	if (!match) {
380 		dev_err(dev, "no compatible OF match\n");
381 		return -EINVAL;
382 	}
383 	priv->pdata = match->data;
384 
385 	if (of_device_is_compatible(dev->of_node, "ti,omap4-rng") ||
386 	    of_device_is_compatible(dev->of_node, "inside-secure,safexcel-eip76")) {
387 		irq = platform_get_irq(pdev, 0);
388 		if (irq < 0) {
389 			dev_err(dev, "%s: error getting IRQ resource - %d\n",
390 				__func__, irq);
391 			return irq;
392 		}
393 
394 		err = devm_request_irq(dev, irq, omap4_rng_irq,
395 				       IRQF_TRIGGER_NONE, dev_name(dev), priv);
396 		if (err) {
397 			dev_err(dev, "unable to request irq %d, err = %d\n",
398 				irq, err);
399 			return err;
400 		}
401 
402 		/*
403 		 * On OMAP4, enabling the shutdown_oflo interrupt is
404 		 * done in the interrupt mask register. There is no
405 		 * such register on EIP76, and it's enabled by the
406 		 * same bit in the control register
407 		 */
408 		if (priv->pdata->regs[RNG_INTMASK_REG])
409 			omap_rng_write(priv, RNG_INTMASK_REG,
410 				       RNG_SHUTDOWN_OFLO_MASK);
411 		else
412 			omap_rng_write(priv, RNG_CONTROL_REG,
413 				       RNG_SHUTDOWN_OFLO_MASK);
414 	}
415 	return 0;
416 }
417 #else
418 static int of_get_omap_rng_device_details(struct omap_rng_dev *omap_rng,
419 					  struct platform_device *pdev)
420 {
421 	return -EINVAL;
422 }
423 #endif
424 
425 static int get_omap_rng_device_details(struct omap_rng_dev *omap_rng)
426 {
427 	/* Only OMAP2/3 can be non-DT */
428 	omap_rng->pdata = &omap2_rng_pdata;
429 	return 0;
430 }
431 
432 static int omap_rng_probe(struct platform_device *pdev)
433 {
434 	struct omap_rng_dev *priv;
435 	struct resource *res;
436 	struct device *dev = &pdev->dev;
437 	int ret;
438 
439 	priv = devm_kzalloc(dev, sizeof(struct omap_rng_dev), GFP_KERNEL);
440 	if (!priv)
441 		return -ENOMEM;
442 
443 	priv->rng.read = omap_rng_do_read;
444 	priv->rng.init = omap_rng_init;
445 	priv->rng.cleanup = omap_rng_cleanup;
446 	priv->rng.quality = 900;
447 
448 	priv->rng.priv = (unsigned long)priv;
449 	platform_set_drvdata(pdev, priv);
450 	priv->dev = dev;
451 
452 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
453 	priv->base = devm_ioremap_resource(dev, res);
454 	if (IS_ERR(priv->base)) {
455 		ret = PTR_ERR(priv->base);
456 		goto err_ioremap;
457 	}
458 
459 	priv->rng.name = devm_kstrdup(dev, dev_name(dev), GFP_KERNEL);
460 	if (!priv->rng.name) {
461 		ret = -ENOMEM;
462 		goto err_ioremap;
463 	}
464 
465 	pm_runtime_enable(&pdev->dev);
466 	ret = pm_runtime_get_sync(&pdev->dev);
467 	if (ret < 0) {
468 		dev_err(&pdev->dev, "Failed to runtime_get device: %d\n", ret);
469 		pm_runtime_put_noidle(&pdev->dev);
470 		goto err_ioremap;
471 	}
472 
473 	priv->clk = devm_clk_get(&pdev->dev, NULL);
474 	if (IS_ERR(priv->clk) && PTR_ERR(priv->clk) == -EPROBE_DEFER)
475 		return -EPROBE_DEFER;
476 	if (!IS_ERR(priv->clk)) {
477 		ret = clk_prepare_enable(priv->clk);
478 		if (ret) {
479 			dev_err(&pdev->dev,
480 				"Unable to enable the clk: %d\n", ret);
481 			goto err_register;
482 		}
483 	}
484 
485 	priv->clk_reg = devm_clk_get(&pdev->dev, "reg");
486 	if (IS_ERR(priv->clk_reg) && PTR_ERR(priv->clk_reg) == -EPROBE_DEFER)
487 		return -EPROBE_DEFER;
488 	if (!IS_ERR(priv->clk_reg)) {
489 		ret = clk_prepare_enable(priv->clk_reg);
490 		if (ret) {
491 			dev_err(&pdev->dev,
492 				"Unable to enable the register clk: %d\n",
493 				ret);
494 			goto err_register;
495 		}
496 	}
497 
498 	ret = (dev->of_node) ? of_get_omap_rng_device_details(priv, pdev) :
499 				get_omap_rng_device_details(priv);
500 	if (ret)
501 		goto err_register;
502 
503 	ret = hwrng_register(&priv->rng);
504 	if (ret)
505 		goto err_register;
506 
507 	dev_info(&pdev->dev, "Random Number Generator ver. %02x\n",
508 		 omap_rng_read(priv, RNG_REV_REG));
509 
510 	return 0;
511 
512 err_register:
513 	priv->base = NULL;
514 	pm_runtime_put_sync(&pdev->dev);
515 	pm_runtime_disable(&pdev->dev);
516 
517 	clk_disable_unprepare(priv->clk_reg);
518 	clk_disable_unprepare(priv->clk);
519 err_ioremap:
520 	dev_err(dev, "initialization failed.\n");
521 	return ret;
522 }
523 
524 static int omap_rng_remove(struct platform_device *pdev)
525 {
526 	struct omap_rng_dev *priv = platform_get_drvdata(pdev);
527 
528 	hwrng_unregister(&priv->rng);
529 
530 	priv->pdata->cleanup(priv);
531 
532 	pm_runtime_put_sync(&pdev->dev);
533 	pm_runtime_disable(&pdev->dev);
534 
535 	clk_disable_unprepare(priv->clk);
536 	clk_disable_unprepare(priv->clk_reg);
537 
538 	return 0;
539 }
540 
541 static int __maybe_unused omap_rng_suspend(struct device *dev)
542 {
543 	struct omap_rng_dev *priv = dev_get_drvdata(dev);
544 
545 	priv->pdata->cleanup(priv);
546 	pm_runtime_put_sync(dev);
547 
548 	return 0;
549 }
550 
551 static int __maybe_unused omap_rng_resume(struct device *dev)
552 {
553 	struct omap_rng_dev *priv = dev_get_drvdata(dev);
554 	int ret;
555 
556 	ret = pm_runtime_get_sync(dev);
557 	if (ret < 0) {
558 		dev_err(dev, "Failed to runtime_get device: %d\n", ret);
559 		pm_runtime_put_noidle(dev);
560 		return ret;
561 	}
562 
563 	priv->pdata->init(priv);
564 
565 	return 0;
566 }
567 
568 static SIMPLE_DEV_PM_OPS(omap_rng_pm, omap_rng_suspend, omap_rng_resume);
569 
570 static struct platform_driver omap_rng_driver = {
571 	.driver = {
572 		.name		= "omap_rng",
573 		.pm		= &omap_rng_pm,
574 		.of_match_table = of_match_ptr(omap_rng_of_match),
575 	},
576 	.probe		= omap_rng_probe,
577 	.remove		= omap_rng_remove,
578 };
579 
580 module_platform_driver(omap_rng_driver);
581 MODULE_ALIAS("platform:omap_rng");
582 MODULE_AUTHOR("Deepak Saxena (and others)");
583 MODULE_LICENSE("GPL");
584