Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/nvidia Use PLL LFSR as rnd source.
details: https://anonhg.NetBSD.org/src/rev/48c2a9565f4e
branches: trunk
changeset: 808698:48c2a9565f4e
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Sat May 30 11:10:24 2015 +0000
description:
Use PLL LFSR as rnd source.
diffstat:
sys/arch/arm/nvidia/tegra_car.c | 79 +++++++++++++++++++++++++++++++++++++-
sys/arch/arm/nvidia/tegra_carreg.h | 5 +-
2 files changed, 81 insertions(+), 3 deletions(-)
diffs (143 lines):
diff -r df701e959a62 -r 48c2a9565f4e sys/arch/arm/nvidia/tegra_car.c
--- a/sys/arch/arm/nvidia/tegra_car.c Sat May 30 06:41:08 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_car.c Sat May 30 11:10:24 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_car.c,v 1.19 2015/05/20 00:05:53 jmcneill Exp $ */
+/* $NetBSD: tegra_car.c,v 1.20 2015/05/30 11:10:24 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
#include "locators.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tegra_car.c,v 1.19 2015/05/20 00:05:53 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tegra_car.c,v 1.20 2015/05/30 11:10:24 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -37,6 +37,8 @@
#include <sys/intr.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/rndpool.h>
+#include <sys/rndsource.h>
#include <arm/nvidia/tegra_reg.h>
#include <arm/nvidia/tegra_carreg.h>
@@ -50,9 +52,18 @@
device_t sc_dev;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh;
+
+ kmutex_t sc_intr_lock;
+ kmutex_t sc_rnd_lock;
+ u_int sc_bytes_wanted;
+ void *sc_sih;
+ krndsource_t sc_rndsource;
};
static void tegra_car_init(struct tegra_car_softc *);
+static void tegra_car_rnd_attach(device_t);
+static void tegra_car_rnd_intr(void *);
+static void tegra_car_rnd_callback(size_t, void *);
static struct tegra_car_softc *pmc_softc = NULL;
@@ -91,6 +102,8 @@
aprint_verbose_dev(self, "PLLU = %u Hz\n", tegra_car_pllu_rate());
aprint_verbose_dev(self, "PLLP0 = %u Hz\n", tegra_car_pllp0_rate());
aprint_verbose_dev(self, "PLLD2 = %u Hz\n", tegra_car_plld2_rate());
+
+ config_interrupts(self, tegra_car_rnd_attach);
}
static void
@@ -108,6 +121,68 @@
}
static void
+tegra_car_rnd_attach(device_t self)
+{
+ struct tegra_car_softc * const sc = device_private(self);
+
+ mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SERIAL);
+ mutex_init(&sc->sc_rnd_lock, MUTEX_DEFAULT, IPL_SERIAL);
+ sc->sc_bytes_wanted = 0;
+ sc->sc_sih = softint_establish(SOFTINT_SERIAL|SOFTINT_MPSAFE,
+ tegra_car_rnd_intr, sc);
+ if (sc->sc_sih == NULL) {
+ aprint_error_dev(sc->sc_dev, "couldn't establish softint\n");
+ return;
+ }
+
+ rndsource_setcb(&sc->sc_rndsource, tegra_car_rnd_callback, sc);
+ rnd_attach_source(&sc->sc_rndsource, device_xname(sc->sc_dev),
+ RND_TYPE_RNG, RND_FLAG_COLLECT_VALUE|RND_FLAG_HASCB);
+}
+
+static void
+tegra_car_rnd_intr(void *priv)
+{
+ struct tegra_car_softc * const sc = priv;
+ uint16_t buf[512];
+ uint32_t cnt;
+
+ mutex_enter(&sc->sc_intr_lock);
+ while (sc->sc_bytes_wanted) {
+ const u_int nbytes = MIN(sc->sc_bytes_wanted, 1024);
+ for (cnt = 0; cnt < sc->sc_bytes_wanted / 2; cnt++) {
+ buf[cnt] = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
+ CAR_PLL_LFSR_REG) & 0xffff;
+ }
+ mutex_exit(&sc->sc_intr_lock);
+ mutex_enter(&sc->sc_rnd_lock);
+ rnd_add_data(&sc->sc_rndsource, buf, nbytes, nbytes * NBBY);
+ mutex_exit(&sc->sc_rnd_lock);
+ mutex_enter(&sc->sc_intr_lock);
+ sc->sc_bytes_wanted -= MIN(sc->sc_bytes_wanted, nbytes);
+ }
+ explicit_memset(buf, 0, sizeof(buf));
+ mutex_exit(&sc->sc_intr_lock);
+}
+
+static void
+tegra_car_rnd_callback(size_t bytes_wanted, void *priv)
+{
+ struct tegra_car_softc * const sc = priv;
+
+ mutex_enter(&sc->sc_intr_lock);
+ if (sc->sc_bytes_wanted == 0) {
+ softint_schedule(sc->sc_sih);
+ }
+ if (bytes_wanted > (UINT_MAX - sc->sc_bytes_wanted)) {
+ sc->sc_bytes_wanted = UINT_MAX;
+ } else {
+ sc->sc_bytes_wanted += bytes_wanted;
+ }
+ mutex_exit(&sc->sc_intr_lock);
+}
+
+static void
tegra_car_get_bs(bus_space_tag_t *pbst, bus_space_handle_t *pbsh)
{
if (pmc_softc) {
diff -r df701e959a62 -r 48c2a9565f4e sys/arch/arm/nvidia/tegra_carreg.h
--- a/sys/arch/arm/nvidia/tegra_carreg.h Sat May 30 06:41:08 2015 +0000
+++ b/sys/arch/arm/nvidia/tegra_carreg.h Sat May 30 11:10:24 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tegra_carreg.h,v 1.16 2015/05/18 20:36:42 jmcneill Exp $ */
+/* $NetBSD: tegra_carreg.h,v 1.17 2015/05/30 11:10:24 jmcneill Exp $ */
/*-
* Copyright (c) 2015 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -33,6 +33,9 @@
#define CAR_CLK_OUT_ENB_H_REG 0x14
#define CAR_CLK_OUT_ENB_U_REG 0x18
+#define CAR_PLL_LFSR_REG 0x54
+#define CAR_PLL_LFSR_RND __BITS(15,0)
+
#define CAR_PLLP_BASE_REG 0xa0
#define CAR_PLLP_BASE_BYPASS __BIT(31)
#define CAR_PLLP_BASE_ENABLE __BIT(30)
Home |
Main Index |
Thread Index |
Old Index