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)