123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- // 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_plat {
- 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_plat *pdata = dev_get_plat(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_plat *pdata = dev_get_plat(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_plat *pdata = dev_get_plat(dev);
- return clk_disable(&pdata->clk);
- }
- /**
- * meson_rng_of_to_plat() - transfer device tree data to plaform data
- *
- * @dev: device
- * Return: 0 if ok
- */
- static int meson_rng_of_to_plat(struct udevice *dev)
- {
- struct meson_rng_plat *pdata = dev_get_plat(dev);
- int err;
- pdata->base = dev_read_addr(dev);
- if (!pdata->base)
- return -ENODEV;
- /* Get optional "core" clock */
- err = clk_get_by_name(dev, "core", &pdata->clk);
- if (err && err != -ENODATA)
- 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,
- .plat_auto = sizeof(struct meson_rng_plat),
- .of_to_plat = meson_rng_of_to_plat,
- };
|