Module Name: src Committed By: matt Date: Thu Jun 5 03:48:32 UTC 2014
Modified Files: src/sys/arch/arm/allwinner: awin_tmr.c awin_var.h Log Message: Start to flesh out the A10 timer code. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/allwinner/awin_tmr.c cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/allwinner/awin_var.h 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/allwinner/awin_tmr.c diff -u src/sys/arch/arm/allwinner/awin_tmr.c:1.2 src/sys/arch/arm/allwinner/awin_tmr.c:1.3 --- src/sys/arch/arm/allwinner/awin_tmr.c:1.2 Thu Feb 20 21:48:38 2014 +++ src/sys/arch/arm/allwinner/awin_tmr.c Thu Jun 5 03:48:32 2014 @@ -31,12 +31,13 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: awin_tmr.c,v 1.2 2014/02/20 21:48:38 matt Exp $"); +__KERNEL_RCSID(1, "$NetBSD: awin_tmr.c,v 1.3 2014/06/05 03:48:32 matt Exp $"); #include <sys/param.h> #include <sys/bus.h> #include <sys/device.h> #include <sys/intr.h> +#include <sys/kernel.h> #include <sys/systm.h> #include <arm/allwinner/awin_reg.h> @@ -50,11 +51,31 @@ struct awin_tmr_softc { bus_space_tag_t sc_bst; bus_space_handle_t sc_bsh; bus_dma_tag_t sc_dmat; + void *sc_ih; + /* register mirrors */ + uint32_t sc_intv_value; + uint32_t sc_ctrl; }; -CFATTACH_DECL_NEW(awin_tmr, sizeof(struct awin_tmr_softc), +static int awin_tmr_intr(void *); + +static struct awin_tmr_softc awin_tmr_softc; + +CFATTACH_DECL_NEW(awin_tmr, 0, awin_tmr_match, awin_tmr_attach, NULL, NULL); +static inline uint32_t +awin_tmr_read(struct awin_tmr_softc *sc, bus_size_t off) +{ + return bus_space_read_4(sc->sc_bst, sc->sc_bsh, off); +} + +static inline void +awin_tmr_write(struct awin_tmr_softc *sc, bus_size_t off, uint32_t val) +{ + return bus_space_write_4(sc->sc_bst, sc->sc_bsh, off, val); +} + static int awin_tmr_match(device_t parent, cfdata_t cf, void *aux) { @@ -62,6 +83,9 @@ awin_tmr_match(device_t parent, cfdata_t const struct awin_locators * const loc = &aio->aio_loc; const int port = cf->cf_loc[AWINIOCF_PORT]; + if (awin_tmr_softc.sc_dev != NULL) + return 0; + if (strcmp(cf->cf_name, loc->loc_name) || (port != AWINIOCF_PORT_DEFAULT && port != loc->loc_port)) return 0; @@ -74,11 +98,12 @@ awin_tmr_match(device_t parent, cfdata_t static void awin_tmr_attach(device_t parent, device_t self, void *aux) { - struct awin_tmr_softc * const sc = device_private(self); + struct awin_tmr_softc * const sc = &awin_tmr_softc; struct awinio_attach_args * const aio = aux; const struct awin_locators * const loc = &aio->aio_loc; sc->sc_dev = self; + self->dv_private = sc; sc->sc_bst = aio->aio_core_bst; sc->sc_dmat = aio->aio_dmat; @@ -87,4 +112,45 @@ awin_tmr_attach(device_t parent, device_ aprint_naive("\n"); aprint_normal("\n"); + + awin_tmr_write(sc, AWIN_TMR_IRQ_EN_REG, 0); + + sc->sc_ih = intr_establish(loc->loc_intr, IPL_SCHED, + IST_LEVEL | IST_MPSAFE, awin_tmr_intr, NULL); + if (sc->sc_ih != NULL) { + aprint_normal_dev(self, "interrupting on irq %d\n", + loc->loc_intr); + } + + sc->sc_intv_value = AWIN_REF_FREQ / hz; +} + +int +awin_tmr_intr(void *arg) +{ + struct awin_tmr_softc * const sc = &awin_tmr_softc; + struct clockframe * const cf = arg; + + /* clear interrupt pending */ + const uint32_t sts = awin_tmr_read(sc, AWIN_TMR_IRQ_STA_REG); + awin_tmr_write(sc, AWIN_TMR_IRQ_STA_REG, sts); + + int32_t now = 0 - awin_tmr_read(sc, AWIN_TMR0_CUR_VALUE_REG); + int32_t slop = now % sc->sc_intv_value; + awin_tmr_write(sc, AWIN_TMR0_INTV_VALUE_REG, + sc->sc_intv_value - slop); + awin_tmr_write(sc, AWIN_TMR0_CTRL_REG, + sc->sc_ctrl | AWIN_TMR_CTRL_RELOAD); + + hardclock(cf); + for (; now > sc->sc_intv_value; now -= sc->sc_intv_value) { + hardclock(cf); + } + + return 1; +} + +void +awin_tmr_cpu_init(struct cpu_info *ci) +{ } Index: src/sys/arch/arm/allwinner/awin_var.h diff -u src/sys/arch/arm/allwinner/awin_var.h:1.9 src/sys/arch/arm/allwinner/awin_var.h:1.10 --- src/sys/arch/arm/allwinner/awin_var.h:1.9 Wed Feb 26 00:19:01 2014 +++ src/sys/arch/arm/allwinner/awin_var.h Thu Jun 5 03:48:32 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: awin_var.h,v 1.9 2014/02/26 00:19:01 matt Exp $ */ +/* $NetBSD: awin_var.h,v 1.10 2014/06/05 03:48:32 matt Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. * All rights reserved. @@ -91,6 +91,7 @@ void awin_gpio_pinset_release(const stru bool awin_gpio_pin_reserve(const char *, struct awin_gpio_pindata *); void awin_wdog_reset(void); +void awin_tmr_cpu_init(struct cpu_info *); static inline void awin_gpio_pindata_write(const struct awin_gpio_pindata *pd, int value)