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)

Reply via email to