Module Name: src Committed By: jmcneill Date: Fri Apr 3 14:02:06 UTC 2015
Modified Files: src/sys/arch/arm/amlogic: amlogic_board.c amlogic_crureg.h amlogic_rng.c Log Message: Use a callback (with ugly lock dance from bcm2835_rng) instead of callout. Make sure the ring oscillator is enabled as well. To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/sys/arch/arm/amlogic/amlogic_board.c cvs rdiff -u -r1.7 -r1.8 src/sys/arch/arm/amlogic/amlogic_crureg.h cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/amlogic/amlogic_rng.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/amlogic/amlogic_board.c diff -u src/sys/arch/arm/amlogic/amlogic_board.c:1.10 src/sys/arch/arm/amlogic/amlogic_board.c:1.11 --- src/sys/arch/arm/amlogic/amlogic_board.c:1.10 Sun Mar 29 22:49:44 2015 +++ src/sys/arch/arm/amlogic/amlogic_board.c Fri Apr 3 14:02:06 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: amlogic_board.c,v 1.10 2015/03/29 22:49:44 jmcneill Exp $ */ +/* $NetBSD: amlogic_board.c,v 1.11 2015/04/03 14:02:06 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -29,7 +29,7 @@ #include "opt_amlogic.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: amlogic_board.c,v 1.10 2015/03/29 22:49:44 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: amlogic_board.c,v 1.11 2015/04/03 14:02:06 jmcneill Exp $"); #define _ARM32_BUS_DMA_PRIVATE #include <sys/param.h> @@ -191,10 +191,10 @@ amlogic_eth_init(void) void amlogic_rng_init(void) { - CBUS_WRITE(EE_CLK_GATING0_REG, - CBUS_READ(EE_CLK_GATING0_REG) | EE_CLK_GATING0_RNG); - CBUS_WRITE(EE_CLK_GATING3_REG, - CBUS_READ(EE_CLK_GATING3_REG) | EE_CLK_GATING3_RNG); + CBUS_SET_CLEAR(EE_CLK_GATING0_REG, EE_CLK_GATING0_RNG, 0); + CBUS_SET_CLEAR(EE_CLK_GATING3_REG, EE_CLK_GATING3_RNG, 0); + CBUS_SET_CLEAR(AM_RING_OSC_REG, + AM_RING_OSC_ENABLE | AM_RING_OSC_HF_MODE, 0); } void Index: src/sys/arch/arm/amlogic/amlogic_crureg.h diff -u src/sys/arch/arm/amlogic/amlogic_crureg.h:1.7 src/sys/arch/arm/amlogic/amlogic_crureg.h:1.8 --- src/sys/arch/arm/amlogic/amlogic_crureg.h:1.7 Sun Mar 8 12:44:55 2015 +++ src/sys/arch/arm/amlogic/amlogic_crureg.h Fri Apr 3 14:02:06 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: amlogic_crureg.h,v 1.7 2015/03/08 12:44:55 jmcneill Exp $ */ +/* $NetBSD: amlogic_crureg.h,v 1.8 2015/04/03 14:02:06 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -107,6 +107,11 @@ #define PAD_PULL_UP_EN_5_REG CBUS_REG(0x204d) #define PAD_PULL_UP_EN_6_REG CBUS_REG(0x204e) +#define AM_RING_OSC_REG CBUS_REG(0x207f) + +#define AM_RING_OSC_ENABLE __BIT(0) +#define AM_RING_OSC_HF_MODE __BIT(1) + #define PREI_USB_PHY_A_CFG_REG CBUS_REG(0x2200) #define PREI_USB_PHY_A_CTRL_REG CBUS_REG(0x2201) #define PREI_USB_PHY_A_ADP_BC_REG CBUS_REG(0x2203) Index: src/sys/arch/arm/amlogic/amlogic_rng.c diff -u src/sys/arch/arm/amlogic/amlogic_rng.c:1.1 src/sys/arch/arm/amlogic/amlogic_rng.c:1.2 --- src/sys/arch/arm/amlogic/amlogic_rng.c:1.1 Sat Mar 7 21:34:25 2015 +++ src/sys/arch/arm/amlogic/amlogic_rng.c Fri Apr 3 14:02:06 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: amlogic_rng.c,v 1.1 2015/03/07 21:34:25 jmcneill Exp $ */ +/* $NetBSD: amlogic_rng.c,v 1.2 2015/04/03 14:02:06 jmcneill Exp $ */ /*- * Copyright (c) 2015 Jared D. McNeill <jmcne...@invisible.ca> @@ -29,7 +29,7 @@ #include "locators.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: amlogic_rng.c,v 1.1 2015/03/07 21:34:25 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: amlogic_rng.c,v 1.2 2015/04/03 14:02:06 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -43,10 +43,14 @@ __KERNEL_RCSID(0, "$NetBSD: amlogic_rng. #include <arm/amlogic/amlogic_reg.h> #include <arm/amlogic/amlogic_var.h> +struct amlogic_rng_softc; + static int amlogic_rng_match(device_t, cfdata_t, void *); static void amlogic_rng_attach(device_t, device_t, void *); -static void amlogic_rng_callout(void *); +static void amlogic_rng_get(struct amlogic_rng_softc *); +static void amlogic_rng_get_intr(void *); +static void amlogic_rng_get_cb(size_t, void *); struct amlogic_rng_softc { device_t sc_dev; @@ -55,9 +59,11 @@ struct amlogic_rng_softc { void * sc_sih; - callout_t sc_tick; krndsource_t sc_rndsource; size_t sc_bytes_wanted; + + kmutex_t sc_intr_lock; + kmutex_t sc_rnd_lock; }; CFATTACH_DECL_NEW(amlogic_rng, sizeof(struct amlogic_rng_softc), @@ -81,31 +87,69 @@ amlogic_rng_attach(device_t parent, devi bus_space_subregion(aio->aio_core_bst, aio->aio_bsh, loc->loc_offset, loc->loc_size, &sc->sc_bsh); - callout_init(&sc->sc_tick, CALLOUT_MPSAFE); - callout_setfunc(&sc->sc_tick, amlogic_rng_callout, sc); - + mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SERIAL); + mutex_init(&sc->sc_rnd_lock, MUTEX_DEFAULT, IPL_SERIAL); + amlogic_rng_init(); aprint_naive("\n"); aprint_normal("\n"); + sc->sc_sih = softint_establish(SOFTINT_SERIAL|SOFTINT_MPSAFE, + amlogic_rng_get_intr, sc); + if (sc->sc_sih == NULL) { + aprint_error_dev(self, "couldn't establish softint\n"); + return; + } + + rndsource_setcb(&sc->sc_rndsource, amlogic_rng_get_cb, sc); rnd_attach_source(&sc->sc_rndsource, device_xname(self), RND_TYPE_RNG, - RND_FLAG_COLLECT_VALUE); + RND_FLAG_COLLECT_VALUE|RND_FLAG_HASCB); - amlogic_rng_callout(sc); + amlogic_rng_get_cb(RND_POOLBITS / NBBY, sc); } static void -amlogic_rng_callout(void *priv) +amlogic_rng_get(struct amlogic_rng_softc *sc) { - struct amlogic_rng_softc * const sc = priv; uint32_t data[2]; - bus_space_read_region_4(sc->sc_bst, sc->sc_bsh, 0, data, 2); - rnd_add_data(&sc->sc_rndsource, data, sizeof(data), - sizeof(data) * NBBY); - + mutex_spin_enter(&sc->sc_intr_lock); + while (sc->sc_bytes_wanted) { + bus_space_read_region_4(sc->sc_bst, sc->sc_bsh, 0, data, 2); + mutex_spin_exit(&sc->sc_intr_lock); + mutex_spin_enter(&sc->sc_rnd_lock); + rnd_add_data(&sc->sc_rndsource, data, sizeof(data), + sizeof(data) * NBBY); + mutex_spin_exit(&sc->sc_rnd_lock); + mutex_spin_enter(&sc->sc_intr_lock); + sc->sc_bytes_wanted -= MIN(sc->sc_bytes_wanted, sizeof(data)); + } explicit_memset(data, 0, sizeof(data)); + mutex_spin_exit(&sc->sc_intr_lock); +} + +static void +amlogic_rng_get_cb(size_t bytes_wanted, void *priv) +{ + struct amlogic_rng_softc * const sc = priv; + + mutex_spin_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_spin_exit(&sc->sc_intr_lock); +} + +static void +amlogic_rng_get_intr(void *priv) +{ + struct amlogic_rng_softc * const sc = priv; - callout_schedule(&sc->sc_tick, 1); + amlogic_rng_get(sc); }