Author: manu
Date: Tue Feb  7 19:28:32 2017
New Revision: 313403
URL: https://svnweb.freebsd.org/changeset/base/313403

Log:
  Rename timer.c to a10_timer.c
  
  Requested by: andrew

Added:
  head/sys/arm/allwinner/a10_timer.c
     - copied unchanged from r313402, head/sys/arm/allwinner/timer.c
Deleted:
  head/sys/arm/allwinner/timer.c
Modified:
  head/sys/arm/allwinner/files.allwinner_up

Copied: head/sys/arm/allwinner/a10_timer.c (from r313402, 
head/sys/arm/allwinner/timer.c)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/arm/allwinner/a10_timer.c  Tue Feb  7 19:28:32 2017        
(r313403, copy of r313402, head/sys/arm/allwinner/timer.c)
@@ -0,0 +1,367 @@
+/*-
+ * Copyright (c) 2012 Ganbold Tsagaankhuu <ganb...@freebsd.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+#include <sys/timeet.h>
+#include <sys/timetc.h>
+#include <sys/watchdog.h>
+#include <machine/bus.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+#include <machine/machdep.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <machine/bus.h>
+
+#include <sys/kdb.h>
+
+#include <arm/allwinner/aw_machdep.h>
+
+/**
+ * Timer registers addr
+ *
+ */
+#define SW_TIMER_IRQ_EN_REG    0x00
+#define SW_TIMER_IRQ_STA_REG   0x04
+#define SW_TIMER0_CTRL_REG     0x10
+#define SW_TIMER0_INT_VALUE_REG        0x14
+#define SW_TIMER0_CUR_VALUE_REG        0x18
+
+#define SW_COUNTER64LO_REG     0xa4
+#define SW_COUNTER64HI_REG     0xa8
+#define CNT64_CTRL_REG         0xa0
+
+#define CNT64_RL_EN            0x02 /* read latch enable */
+
+#define TIMER_ENABLE           (1<<0)
+#define TIMER_AUTORELOAD       (1<<1)
+#define TIMER_OSC24M           (1<<2) /* oscillator = 24mhz */
+#define TIMER_PRESCALAR                (0<<4) /* prescalar = 1 */
+
+#define SYS_TIMER_CLKSRC       24000000 /* clock source */
+
+struct a10_timer_softc {
+       device_t        sc_dev;
+       struct resource *res[2];
+       bus_space_tag_t sc_bst;
+       bus_space_handle_t sc_bsh;
+       void            *sc_ih;         /* interrupt handler */
+       uint32_t        sc_period;
+       uint32_t        timer0_freq;
+       struct eventtimer et;
+};
+
+int a10_timer_get_timerfreq(struct a10_timer_softc *);
+
+#define timer_read_4(sc, reg)  \
+       bus_space_read_4(sc->sc_bst, sc->sc_bsh, reg)
+#define timer_write_4(sc, reg, val)    \
+       bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, val)
+
+static u_int   a10_timer_get_timecount(struct timecounter *);
+static int     a10_timer_timer_start(struct eventtimer *,
+    sbintime_t first, sbintime_t period);
+static int     a10_timer_timer_stop(struct eventtimer *);
+
+static uint64_t timer_read_counter64(void);
+
+static int a10_timer_hardclock(void *);
+static int a10_timer_probe(device_t);
+static int a10_timer_attach(device_t);
+
+static delay_func a10_timer_delay;
+
+static struct timecounter a10_timer_timecounter = {
+       .tc_name           = "a10_timer timer0",
+       .tc_get_timecount  = a10_timer_get_timecount,
+       .tc_counter_mask   = ~0u,
+       .tc_frequency      = 0,
+       .tc_quality        = 1000,
+};
+
+struct a10_timer_softc *a10_timer_sc = NULL;
+
+static struct resource_spec a10_timer_spec[] = {
+       { SYS_RES_MEMORY,       0,      RF_ACTIVE },
+       { SYS_RES_IRQ,          0,      RF_ACTIVE },
+       { -1, 0 }
+};
+
+static uint64_t
+timer_read_counter64(void)
+{
+       uint32_t lo, hi;
+
+       /* Latch counter, wait for it to be ready to read. */
+       timer_write_4(a10_timer_sc, CNT64_CTRL_REG, CNT64_RL_EN);
+       while (timer_read_4(a10_timer_sc, CNT64_CTRL_REG) & CNT64_RL_EN)
+               continue;
+
+       hi = timer_read_4(a10_timer_sc, SW_COUNTER64HI_REG);
+       lo = timer_read_4(a10_timer_sc, SW_COUNTER64LO_REG);
+
+       return (((uint64_t)hi << 32) | lo);
+}
+
+static int
+a10_timer_probe(device_t dev)
+{
+       struct a10_timer_softc *sc;
+       u_int soc_family;
+
+       sc = device_get_softc(dev);
+
+       if (!ofw_bus_is_compatible(dev, "allwinner,sun4i-a10-timer"))
+               return (ENXIO);
+
+       soc_family = allwinner_soc_family();
+       if (soc_family != ALLWINNERSOC_SUN4I &&
+           soc_family != ALLWINNERSOC_SUN5I)
+               return (ENXIO);
+
+       device_set_desc(dev, "Allwinner A10/A20 timer");
+       return (BUS_PROBE_DEFAULT);
+}
+
+static int
+a10_timer_attach(device_t dev)
+{
+       struct a10_timer_softc *sc;
+       int err;
+       uint32_t val;
+
+       sc = device_get_softc(dev);
+
+       if (bus_alloc_resources(dev, a10_timer_spec, sc->res)) {
+               device_printf(dev, "could not allocate resources\n");
+               return (ENXIO);
+       }
+
+       sc->sc_dev = dev;
+       sc->sc_bst = rman_get_bustag(sc->res[0]);
+       sc->sc_bsh = rman_get_bushandle(sc->res[0]);
+
+       /* Setup and enable the timer interrupt */
+       err = bus_setup_intr(dev, sc->res[1], INTR_TYPE_CLK, 
a10_timer_hardclock,
+           NULL, sc, &sc->sc_ih);
+       if (err != 0) {
+               bus_release_resources(dev, a10_timer_spec, sc->res);
+               device_printf(dev, "Unable to setup the clock irq handler, "
+                   "err = %d\n", err);
+               return (ENXIO);
+       }
+
+       /* Set clock source to OSC24M, 16 pre-division */
+       val = timer_read_4(sc, SW_TIMER0_CTRL_REG);
+       val |= TIMER_PRESCALAR | TIMER_OSC24M;
+       timer_write_4(sc, SW_TIMER0_CTRL_REG, val);
+
+       /* Enable timer0 */
+       val = timer_read_4(sc, SW_TIMER_IRQ_EN_REG);
+       val |= TIMER_ENABLE;
+       timer_write_4(sc, SW_TIMER_IRQ_EN_REG, val);
+
+       sc->timer0_freq = SYS_TIMER_CLKSRC;
+
+       /* Set desired frequency in event timer and timecounter */
+       sc->et.et_frequency = sc->timer0_freq;
+       sc->et.et_name = "a10_timer Eventtimer";
+       sc->et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERIODIC;
+       sc->et.et_quality = 1000;
+       sc->et.et_min_period = (0x00000005LLU << 32) / sc->et.et_frequency;
+       sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
+       sc->et.et_start = a10_timer_timer_start;
+       sc->et.et_stop = a10_timer_timer_stop;
+       sc->et.et_priv = sc;
+       et_register(&sc->et);
+
+       if (device_get_unit(dev) == 0) {
+               arm_set_delay(a10_timer_delay, sc);
+               a10_timer_sc = sc;
+       }
+
+       a10_timer_timecounter.tc_frequency = sc->timer0_freq;
+       tc_init(&a10_timer_timecounter);
+
+       if (bootverbose) {
+               device_printf(sc->sc_dev, "clock: hz=%d stathz = %d\n", hz, 
stathz);
+
+               device_printf(sc->sc_dev, "event timer clock frequency %u\n", 
+                   sc->timer0_freq);
+               device_printf(sc->sc_dev, "timecounter clock frequency %lld\n", 
+                   a10_timer_timecounter.tc_frequency);
+       }
+
+       return (0);
+}
+
+static int
+a10_timer_timer_start(struct eventtimer *et, sbintime_t first,
+    sbintime_t period)
+{
+       struct a10_timer_softc *sc;
+       uint32_t count;
+       uint32_t val;
+
+       sc = (struct a10_timer_softc *)et->et_priv;
+
+       if (period != 0)
+               sc->sc_period = ((uint32_t)et->et_frequency * period) >> 32;
+       else
+               sc->sc_period = 0;
+       if (first != 0)
+               count = ((uint32_t)et->et_frequency * first) >> 32;
+       else
+               count = sc->sc_period;
+
+       /* Update timer values */
+       timer_write_4(sc, SW_TIMER0_INT_VALUE_REG, sc->sc_period);
+       timer_write_4(sc, SW_TIMER0_CUR_VALUE_REG, count);
+
+       val = timer_read_4(sc, SW_TIMER0_CTRL_REG);
+       if (period != 0) {
+               /* periodic */
+               val |= TIMER_AUTORELOAD;
+       } else {
+               /* oneshot */
+               val &= ~TIMER_AUTORELOAD;
+       }
+       /* Enable timer0 */
+       val |= TIMER_ENABLE;
+       timer_write_4(sc, SW_TIMER0_CTRL_REG, val);
+
+       return (0);
+}
+
+static int
+a10_timer_timer_stop(struct eventtimer *et)
+{
+       struct a10_timer_softc *sc;
+       uint32_t val;
+
+       sc = (struct a10_timer_softc *)et->et_priv;
+
+       /* Disable timer0 */
+       val = timer_read_4(sc, SW_TIMER0_CTRL_REG);
+       val &= ~TIMER_ENABLE;
+       timer_write_4(sc, SW_TIMER0_CTRL_REG, val);
+
+       sc->sc_period = 0;
+
+       return (0);
+}
+
+int
+a10_timer_get_timerfreq(struct a10_timer_softc *sc)
+{
+       return (sc->timer0_freq);
+}
+
+static int
+a10_timer_hardclock(void *arg)
+{
+       struct a10_timer_softc *sc;
+       uint32_t val;
+
+       sc = (struct a10_timer_softc *)arg;
+
+       /* Clear interrupt pending bit. */
+       timer_write_4(sc, SW_TIMER_IRQ_STA_REG, 0x1);
+
+       val = timer_read_4(sc, SW_TIMER0_CTRL_REG);
+       /*
+        * Disabled autoreload and sc_period > 0 means 
+        * timer_start was called with non NULL first value.
+        * Now we will set periodic timer with the given period 
+        * value.
+        */
+       if ((val & (1<<1)) == 0 && sc->sc_period > 0) {
+               /* Update timer */
+               timer_write_4(sc, SW_TIMER0_CUR_VALUE_REG, sc->sc_period);
+
+               /* Make periodic and enable */
+               val |= TIMER_AUTORELOAD | TIMER_ENABLE;
+               timer_write_4(sc, SW_TIMER0_CTRL_REG, val);
+       }
+
+       if (sc->et.et_active)
+               sc->et.et_event_cb(&sc->et, sc->et.et_arg);
+
+       return (FILTER_HANDLED);
+}
+
+u_int
+a10_timer_get_timecount(struct timecounter *tc)
+{
+
+       if (a10_timer_sc == NULL)
+               return (0);
+
+       return ((u_int)timer_read_counter64());
+}
+
+static device_method_t a10_timer_methods[] = {
+       DEVMETHOD(device_probe,         a10_timer_probe),
+       DEVMETHOD(device_attach,        a10_timer_attach),
+
+       DEVMETHOD_END
+};
+
+static driver_t a10_timer_driver = {
+       "a10_timer",
+       a10_timer_methods,
+       sizeof(struct a10_timer_softc),
+};
+
+static devclass_t a10_timer_devclass;
+
+EARLY_DRIVER_MODULE(a10_timer, simplebus, a10_timer_driver, 
a10_timer_devclass, 0, 0,
+    BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
+
+static void
+a10_timer_delay(int usec, void *arg)
+{
+       struct a10_timer_softc *sc = arg;
+       uint64_t end, now;
+
+       now = timer_read_counter64();
+       end = now + (sc->timer0_freq / 1000000) * (usec + 1);
+
+       while (now < end)
+               now = timer_read_counter64();
+}

Modified: head/sys/arm/allwinner/files.allwinner_up
==============================================================================
--- head/sys/arm/allwinner/files.allwinner_up   Tue Feb  7 19:02:59 2017        
(r313402)
+++ head/sys/arm/allwinner/files.allwinner_up   Tue Feb  7 19:28:32 2017        
(r313403)
@@ -1,3 +1,3 @@
 # $FreeBSD$
 
-arm/allwinner/timer.c                  standard
+arm/allwinner/a10_timer.c              standard
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to