Lines Matching +full:rockchip +full:- +full:device
1 // SPDX-License-Identifier: GPL-2.0
3 * rockchip-rng.c True Random Number Generator driver for Rockchip SoCs
5 * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd.
9 * Lin Jinhan <troy.lin@rock-chips.com>
33 * of ~900 (~87.5% of FIPS 140-2 successes).
40 /* TRNG registers from RK3568 TRM-Part2, section 5.4.1 */
59 * The TRNG V1 IP is a stand-alone TRNG implementation (not part of a crypto IP)
60 * and can be found in the Rockchip RK3588 SoC
98 * The RKRNG IP is a stand-alone TRNG implementation (not part of a crypto IP)
99 * and can be found in the Rockchip RK3576, Rockchip RK3562 and Rockchip RK3528
121 static_assert(RK_RNG_MAX_BYTE <= (TRNG_V1_RAND7 + 4 - TRNG_V1_RAND0),
122 "You raised RK_RNG_MAX_BYTE and broke rk3588-rng, congrats.");
130 struct device *dev;
144 writel((mask << 16) | val, rng->base + TRNG_RNG_CTL);
149 writel(val, rng->base + offset);
154 return readl(rng->base + offset);
161 ret = clk_bulk_prepare_enable(rk_rng->clk_num, rk_rng->clk_bulks);
163 dev_err(rk_rng->dev, "Failed to enable clocks: %d\n", ret);
180 writel(RK_RNG_SAMPLE_CNT, rk_rng->base + TRNG_RNG_SAMPLE_CNT);
199 clk_bulk_disable_unprepare(rk_rng->clk_num, rk_rng->clk_bulks);
209 ret = pm_runtime_resume_and_get(rk_rng->dev);
216 ret = readl_poll_timeout(rk_rng->base + TRNG_RNG_CTL, reg,
224 memcpy_fromio(buf, rk_rng->base + TRNG_RNG_DOUT, to_read);
226 pm_runtime_mark_last_busy(rk_rng->dev);
227 pm_runtime_put_sync_autosuspend(rk_rng->dev);
246 ret = pm_runtime_resume_and_get(rk_rng->dev);
253 if (readl_poll_timeout(rk_rng->base + RKRNG_STATE, val,
256 dev_err(rk_rng->dev, "timed out waiting for data\n");
257 ret = -ETIMEDOUT;
263 memcpy_fromio(buf, rk_rng->base + RKRNG_TRNG_DATA0, to_read);
266 pm_runtime_mark_last_busy(rk_rng->dev);
267 pm_runtime_put_sync_autosuspend(rk_rng->dev);
284 dev_err(rk_rng->dev,
287 ret = -EFAULT;
293 if (readl_poll_timeout(rk_rng->base + TRNG_V1_STAT, status,
296 dev_err(rk_rng->dev, "timed out waiting for hwrng to reseed\n");
297 ret = -ETIMEDOUT;
303 * auto-reseeding "on power on"
313 clk_bulk_disable_unprepare(rk_rng->clk_num, rk_rng->clk_bulks);
321 clk_bulk_disable_unprepare(rk_rng->clk_num, rk_rng->clk_bulks);
331 ret = pm_runtime_resume_and_get(rk_rng->dev);
343 ret = readl_poll_timeout_atomic(rk_rng->base + TRNG_V1_ISTAT, reg,
350 memcpy_fromio(buf, rk_rng->base + TRNG_V1_RAND0, to_read);
358 pm_runtime_mark_last_busy(rk_rng->dev);
359 pm_runtime_put_sync_autosuspend(rk_rng->dev);
390 struct device *dev = &pdev->dev;
397 return -ENOMEM;
399 rk_rng->soc_data = of_device_get_match_data(dev);
400 rk_rng->base = devm_platform_ioremap_resource(pdev, 0);
401 if (IS_ERR(rk_rng->base))
402 return PTR_ERR(rk_rng->base);
404 rk_rng->clk_num = devm_clk_bulk_get_all(dev, &rk_rng->clk_bulks);
405 if (rk_rng->clk_num < 0)
406 return dev_err_probe(dev, rk_rng->clk_num,
409 if (rk_rng->soc_data->reset_optional)
425 rk_rng->rng.name = dev_driver_string(dev);
427 rk_rng->rng.init = rk_rng->soc_data->rk_rng_init;
428 rk_rng->rng.cleanup = rk_rng->soc_data->rk_rng_cleanup;
430 rk_rng->rng.read = rk_rng->soc_data->rk_rng_read;
431 rk_rng->dev = dev;
432 rk_rng->rng.quality = rk_rng->soc_data->quality;
440 ret = devm_hwrng_register(dev, &rk_rng->rng);
442 return dev_err_probe(dev, ret, "Failed to register Rockchip hwrng\n");
447 static int __maybe_unused rk_rng_runtime_suspend(struct device *dev)
451 rk_rng->soc_data->rk_rng_cleanup(&rk_rng->rng);
456 static int __maybe_unused rk_rng_runtime_resume(struct device *dev)
460 return rk_rng->soc_data->rk_rng_init(&rk_rng->rng);
471 { .compatible = "rockchip,rk3568-rng", .data = (void *)&rk3568_soc_data },
472 { .compatible = "rockchip,rk3576-rng", .data = (void *)&rk3576_soc_data },
473 { .compatible = "rockchip,rk3588-rng", .data = (void *)&rk3588_soc_data },
481 .name = "rockchip-rng",
490 MODULE_DESCRIPTION("Rockchip True Random Number Generator driver");
491 MODULE_AUTHOR("Lin Jinhan <troy.lin@rock-chips.com>");