Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sgimips/hpc Add dpclock driver (and minimal hpc1 go...



details:   https://anonhg.NetBSD.org/src/rev/50b08f8d5e1b
branches:  trunk
changeset: 555572:50b08f8d5e1b
user:      sekiya <sekiya%NetBSD.org@localhost>
date:      Sat Nov 22 03:58:51 2003 +0000

description:
Add dpclock driver (and minimal hpc1 goo) for ip20.  Code originally
from Steve Rumble, with modifications by myself.

diffstat:

 sys/arch/sgimips/hpc/dpclock_hpc.c |  198 +++++++++++++++++++++++++++++++++++++
 1 files changed, 198 insertions(+), 0 deletions(-)

diffs (202 lines):

diff -r 9be66fc0161b -r 50b08f8d5e1b sys/arch/sgimips/hpc/dpclock_hpc.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/sgimips/hpc/dpclock_hpc.c        Sat Nov 22 03:58:51 2003 +0000
@@ -0,0 +1,198 @@
+/*     $NetBSD: dpclock_hpc.c,v 1.1 2003/11/22 03:58:52 sekiya Exp $   */
+
+/*
+ * Copyright (c) 2001 Erik Reid
+ * Copyright (c) 2001 Rafal K. Boni
+ * Copyright (c) 2001 Christopher Sekiya
+ * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Portions of this code are derived from software contributed to The
+ * NetBSD Foundation by Jason R. Thorpe of the Numerical Aerospace
+ * Simulation Facility, NASA Ames Research Center.
+ *
+ * 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.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+#include <machine/sysconf.h>
+#include <machine/machtype.h>
+
+#include <dev/clock_subr.h>
+#include <sgimips/hpc/dp8573areg.h>
+
+#include <sgimips/hpc/hpcvar.h>
+#include <sgimips/sgimips/clockvar.h>
+
+struct dpclock_softc {
+       struct device sc_dev;
+
+       /* RTC registers */
+       bus_space_tag_t         sc_rtct;
+       bus_space_handle_t      sc_rtch;
+};
+
+static void    dpclock_init(struct device *);
+static int     dpclock_match(struct device *, struct cfdata *, void *);
+static void    dpclock_attach(struct device *, struct device *, void *);
+static void    dpclock_get(struct device *, struct clock_ymdhms *);
+static void    dpclock_set(struct device *, struct clock_ymdhms *);
+
+const struct clockfns dpclock_clockfns = {
+       dpclock_init, dpclock_get, dpclock_set,
+};
+
+CFATTACH_DECL(dpclock, sizeof(struct dpclock_softc),
+    dpclock_match, dpclock_attach, NULL, NULL);
+
+static int
+dpclock_match(struct device *parent, struct cfdata *cf, void *aux)
+{
+       struct hpc_attach_args *ha = aux;
+
+       if (strcmp(ha->ha_name, cf->cf_name) == 0)
+               return (1);
+
+       return (0);
+}
+
+static void
+dpclock_attach(struct device *parent, struct device *self, void *aux)
+{
+       struct dpclock_softc *sc = (void *)self;
+       struct hpc_attach_args *haa = aux;
+       int err;
+
+       printf("\n");
+
+       sc->sc_rtct = haa->ha_st;
+       if ((err = bus_space_subregion(haa->ha_st, haa->ha_sh,
+                                      haa->ha_devoff, 0x1ffff,
+                                      &sc->sc_rtch)) != 0) {
+               printf(": unable to map RTC registers, error = %d\n", err);
+               return;
+       }
+
+       clockattach(&sc->sc_dev, &dpclock_clockfns);
+}
+
+static void
+dpclock_init(struct device *dev)
+{
+}
+
+/*
+ * Get the time of day, based on the clock's value and/or the base value.
+ */
+static void
+dpclock_get(struct device *dev, struct clock_ymdhms * dt)
+{
+       struct dpclock_softc *sc = (struct dpclock_softc *)dev;
+       int s;
+       u_int8_t i, j;
+       u_int8_t regs[32];
+
+       s = splhigh();
+       i = bus_space_read_1(sc->sc_rtct, sc->sc_rtch, DP8573A_TIMESAVE_CTL);
+       j = i | DP8573A_TIMESAVE_CTL_EN; 
+       bus_space_write_1(sc->sc_rtct, sc->sc_rtch, DP8573A_TIMESAVE_CTL, j);
+       bus_space_write_1(sc->sc_rtct, sc->sc_rtch, DP8573A_TIMESAVE_CTL, i);
+       splx(s);
+
+       for (i = 0; i < 32; i++)
+               regs[i] = bus_space_read_1(sc->sc_rtct, sc->sc_rtch, i);
+
+       dt->dt_sec = FROMBCD(regs[DP8573A_SAVE_SEC]);
+       dt->dt_min = FROMBCD(regs[DP8573A_SAVE_MIN]);
+
+       if (regs[DP8573A_RT_MODE] & DP8573A_RT_MODE_1224) {
+               dt->dt_hour = FROMBCD(regs[DP8573A_SAVE_HOUR] &
+                                               DP8573A_HOUR_12HR_MASK) +
+                   ((regs[DP8573A_SAVE_HOUR] & DP8573A_RT_MODE_1224) ? 0 : 12);
+
+               /*
+                * In AM/PM mode, hour range is 01-12, so adding in 12 hours
+                * for PM gives us 01-24, whereas we want 00-23, so map hour
+                * 24 to hour 0.
+                */
+
+               if (dt->dt_hour == 24)
+                       dt->dt_hour = 0;
+       } else {
+               dt->dt_hour = FROMBCD(regs[DP8573A_SAVE_HOUR] &
+                                                       DP8573A_HOUR_24HR_MASK);
+       }
+
+       dt->dt_wday = FROMBCD(regs[DP8573A_DOW]);       /* Not from time saved */
+       dt->dt_day = FROMBCD(regs[DP8573A_SAVE_DOM]);
+       dt->dt_mon = FROMBCD(regs[DP8573A_SAVE_MONTH]);
+       dt->dt_year = FROM_IRIX_YEAR(FROMBCD(regs[DP8573A_YEAR]));
+}
+
+/*
+ * Reset the TODR based on the time value.
+ */
+static void
+dpclock_set(struct device *dev, struct clock_ymdhms * dt)
+{
+       struct dpclock_softc *sc = (struct dpclock_softc *)dev;
+       int s;
+       u_int8_t i, j;
+       u_int8_t regs[32];
+
+       s = splhigh();
+       i = bus_space_read_1(sc->sc_rtct, sc->sc_rtch, DP8573A_TIMESAVE_CTL);
+       j = i | DP8573A_TIMESAVE_CTL_EN; 
+       bus_space_write_1(sc->sc_rtct, sc->sc_rtch, DP8573A_TIMESAVE_CTL, j);
+       bus_space_write_1(sc->sc_rtct, sc->sc_rtch, DP8573A_TIMESAVE_CTL, i);
+       splx(s);
+
+       for (i = 0; i < 32; i++)
+               regs[i] = bus_space_read_1(sc->sc_rtct, sc->sc_rtch, i);
+
+       regs[DP8573A_SUBSECOND] = 0;
+       regs[DP8573A_SECOND] = TOBCD(dt->dt_sec);
+       regs[DP8573A_MINUTE] = TOBCD(dt->dt_min);
+       regs[DP8573A_HOUR] = TOBCD(dt->dt_hour) & DP8573A_HOUR_24HR_MASK;
+       regs[DP8573A_DOW] = TOBCD(dt->dt_wday);
+       regs[DP8573A_DOM] = TOBCD(dt->dt_day);
+       regs[DP8573A_MONTH] = TOBCD(dt->dt_mon);
+       regs[DP8573A_YEAR] = TOBCD(TO_IRIX_YEAR(dt->dt_year));
+
+       s = splhigh();
+       i = bus_space_read_1(sc->sc_rtct, sc->sc_rtch, DP8573A_RT_MODE);
+       j = i & ~DP8573A_RT_MODE_CLKSS;
+       bus_space_write_1(sc->sc_rtct, sc->sc_rtch, DP8573A_RT_MODE, j);
+
+       for (i = 0; i < 10; i++)
+               bus_space_write_1(sc->sc_rtct, sc->sc_rtch, DP8573A_COUNTERS +i,
+                                                   regs[DP8573A_COUNTERS + i]);
+       
+       bus_space_write_1(sc->sc_rtct, sc->sc_rtch, DP8573A_RT_MODE, i);
+       splx(s);
+}



Home | Main Index | Thread Index | Old Index