drivers/rng: add Amlogic hardware RNG driver
Add support for the hardware random number generator of Amlogic SOCs. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> Reviewed-by: Sughosh Ganu <sughosh.ganu@linaro.org>
This commit is contained in:
		
							parent
							
								
									c312c4b4dc
								
							
						
					
					
						commit
						bc40eb278b
					
				|  | @ -8,6 +8,14 @@ config DM_RNG | |||
| 
 | ||||
| if DM_RNG | ||||
| 
 | ||||
| config RNG_MESON | ||||
| 	bool "Amlogic Meson Random Number Generator support" | ||||
| 	depends on ARCH_MESON | ||||
| 	default y | ||||
| 	help | ||||
| 	  Enable support for hardware random number generator | ||||
| 	  of Amlogic Meson SoCs. | ||||
| 
 | ||||
| config RNG_SANDBOX | ||||
| 	bool "Sandbox random number generator" | ||||
| 	depends on SANDBOX | ||||
|  |  | |||
|  | @ -4,5 +4,6 @@ | |||
| #
 | ||||
| 
 | ||||
| obj-$(CONFIG_DM_RNG) += rng-uclass.o | ||||
| obj-$(CONFIG_RNG_MESON) += meson-rng.o | ||||
| obj-$(CONFIG_RNG_SANDBOX) += sandbox_rng.o | ||||
| obj-$(CONFIG_RNG_STM32MP1) += stm32mp1_rng.o | ||||
|  |  | |||
|  | @ -0,0 +1,120 @@ | |||
| // SPDX-License-Identifier: GPL-2.0-or-later
 | ||||
| /*
 | ||||
|  * Copyright 2020, Heinrich Schuchardt <xypron.glpk@gmx.de> | ||||
|  * | ||||
|  * Driver for Amlogic hardware random number generator | ||||
|  */ | ||||
| 
 | ||||
| #include <common.h> | ||||
| #include <clk.h> | ||||
| #include <dm.h> | ||||
| #include <rng.h> | ||||
| #include <asm/io.h> | ||||
| 
 | ||||
| struct meson_rng_platdata { | ||||
| 	fdt_addr_t base; | ||||
| 	struct clk clk; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * meson_rng_read() - fill buffer with random bytes | ||||
|  * | ||||
|  * @buffer:	buffer to receive data | ||||
|  * @size:	size of buffer | ||||
|  * | ||||
|  * Return:	0 | ||||
|  */ | ||||
| static int meson_rng_read(struct udevice *dev, void *data, size_t len) | ||||
| { | ||||
| 	struct meson_rng_platdata *pdata = dev_get_platdata(dev); | ||||
| 	char *buffer = (char *)data; | ||||
| 
 | ||||
| 	while (len) { | ||||
| 		u32 rand = readl(pdata->base); | ||||
| 		size_t step; | ||||
| 
 | ||||
| 		if (len >= 4) | ||||
| 			step = 4; | ||||
| 		else | ||||
| 			step = len; | ||||
| 		memcpy(buffer, &rand, step); | ||||
| 		buffer += step; | ||||
| 		len -= step; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * meson_rng_probe() - probe rng device | ||||
|  * | ||||
|  * @dev:	device | ||||
|  * Return:	0 if ok | ||||
|  */ | ||||
| static int meson_rng_probe(struct udevice *dev) | ||||
| { | ||||
| 	struct meson_rng_platdata *pdata = dev_get_platdata(dev); | ||||
| 	int err; | ||||
| 
 | ||||
| 	err = clk_enable(&pdata->clk); | ||||
| 	if (err) | ||||
| 		return err; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * meson_rng_remove() - deinitialize rng device | ||||
|  * | ||||
|  * @dev:	device | ||||
|  * Return:	0 if ok | ||||
|  */ | ||||
| static int meson_rng_remove(struct udevice *dev) | ||||
| { | ||||
| 	struct meson_rng_platdata *pdata = dev_get_platdata(dev); | ||||
| 
 | ||||
| 	return clk_disable(&pdata->clk); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * meson_rng_ofdata_to_platdata() - transfer device tree data to plaform data | ||||
|  * | ||||
|  * @dev:	device | ||||
|  * Return:	0 if ok | ||||
|  */ | ||||
| static int meson_rng_ofdata_to_platdata(struct udevice *dev) | ||||
| { | ||||
| 	struct meson_rng_platdata *pdata = dev_get_platdata(dev); | ||||
| 	int err; | ||||
| 
 | ||||
| 	pdata->base = dev_read_addr(dev); | ||||
| 	if (!pdata->base) | ||||
| 		return -ENODEV; | ||||
| 
 | ||||
| 	err = clk_get_by_name(dev, "core", &pdata->clk); | ||||
| 	if (err) | ||||
| 		return err; | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static const struct dm_rng_ops meson_rng_ops = { | ||||
| 	.read = meson_rng_read, | ||||
| }; | ||||
| 
 | ||||
| static const struct udevice_id meson_rng_match[] = { | ||||
| 	{ | ||||
| 		.compatible = "amlogic,meson-rng", | ||||
| 	}, | ||||
| 	{}, | ||||
| }; | ||||
| 
 | ||||
| U_BOOT_DRIVER(meson_rng) = { | ||||
| 	.name = "meson-rng", | ||||
| 	.id = UCLASS_RNG, | ||||
| 	.of_match = meson_rng_match, | ||||
| 	.ops = &meson_rng_ops, | ||||
| 	.probe = meson_rng_probe, | ||||
| 	.remove = meson_rng_remove, | ||||
| 	.platdata_auto_alloc_size = sizeof(struct meson_rng_platdata), | ||||
| 	.ofdata_to_platdata = meson_rng_ofdata_to_platdata, | ||||
| }; | ||||
		Loading…
	
		Reference in New Issue