summaryrefslogtreecommitdiff
path: root/sys/arch/mips/dev
diff options
context:
space:
mode:
authorPer Fogelstrom <pefo@cvs.openbsd.org>1998-01-29 15:06:24 +0000
committerPer Fogelstrom <pefo@cvs.openbsd.org>1998-01-29 15:06:24 +0000
commit1b35d27aa1e08c41ab91a5f3c3e4b69e4745a896 (patch)
tree25cc408ac82101632aabed2b09e4173082894fae /sys/arch/mips/dev
parent82368fc5f594f861ddefcd447fab0577315ce67e (diff)
New try with conf
Diffstat (limited to 'sys/arch/mips/dev')
-rw-r--r--sys/arch/mips/dev/clock_ds.c271
-rw-r--r--sys/arch/mips/dev/clockvar.h77
-rw-r--r--sys/arch/mips/dev/ds1386reg.h119
3 files changed, 467 insertions, 0 deletions
diff --git a/sys/arch/mips/dev/clock_ds.c b/sys/arch/mips/dev/clock_ds.c
new file mode 100644
index 00000000000..61e6c042ea3
--- /dev/null
+++ b/sys/arch/mips/dev/clock_ds.c
@@ -0,0 +1,271 @@
+/* $OpenBSD: clock_ds.c,v 1.1 1998/01/29 15:06:17 pefo Exp $ */
+
+/*
+ * Copyright (c) 1997 Per Fogelstrom
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed under OpenBSD by
+ * Per Fogelstrom.
+ * 4. 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/autoconf.h>
+#include <machine/pio.h>
+#include <machine/cpu.h>
+
+#include <mips/dev/clockvar.h>
+#include <mips/archtype.h>
+#include <mips/dev/ds1386reg.h>
+
+
+void md_clk_attach __P((struct device *, struct device *, void *));
+static void dsclk_init __P((struct clock_softc *));
+static void dsclk_get __P((struct clock_softc *, time_t, struct tod_time *));
+static void dsclk_set __P((struct clock_softc *, struct tod_time *));
+
+struct dsclkdata {
+ void (*ds_write) __P((struct clock_softc *, u_int, u_int));
+ u_int (*ds_read) __P((struct clock_softc *, u_int));
+ void *ds_addr;
+};
+
+#define ds1386_write(sc, reg, datum) \
+ (*((struct dsclkdata *)sc->sc_data)->ds_write)(sc, reg, datum)
+#define ds1386_read(sc, reg) \
+ (*((struct dsclkdata *)sc->sc_data)->ds_read)(sc, reg)
+
+#ifdef hkmips
+static void ds_write_laguna __P((struct clock_softc *, u_int, u_int));
+static u_int ds_read_laguna __P((struct clock_softc *, u_int));
+static struct dsclkdata dsclkdata_laguna = {
+ ds_write_laguna,
+ ds_read_laguna,
+ (void *)NULL
+};
+static u_char ethaddr[8];
+#endif
+
+#ifdef sgi
+u_int32_t cpu_counter_interval; /* Number of counter ticks/tick */
+u_int32_t cpu_counter_last; /* Last compare value loaded */
+
+static void ds_write_sgi_indy __P((struct clock_softc *, u_int, u_int));
+static u_int ds_read_sgi_indy __P((struct clock_softc *, u_int));
+static struct dsclkdata dsclkdata_sgi_indy = {
+ ds_write_sgi_indy,
+ ds_read_sgi_indy,
+ (void *)NULL
+};
+#endif
+
+void
+md_clk_attach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct clock_softc *sc;
+ struct confargs *ca;
+
+ sc = (struct clock_softc *)self;
+ ca = aux;
+
+ printf(": DS1[234]86 or compatible");
+
+ sc->sc_init = dsclk_init;
+ sc->sc_get = dsclk_get;
+ sc->sc_set = dsclk_set;
+
+ switch (system_type) {
+
+#ifdef hkmips
+ case LAGUNA:
+ /*
+ * XXX should really allocate a new one and copy, or
+ * something. unlikely we'll have more than one...
+ */
+ sc->sc_data = &dsclkdata_laguna;
+ dsclkdata_laguna.ds_addr = BUS_CVTADDR(ca);
+
+ ethaddr[0] = ds_read_laguna(sc, DS_ETHERADR+0);
+ ethaddr[1] = ds_read_laguna(sc, DS_ETHERADR+1);
+ ethaddr[2] = ds_read_laguna(sc, DS_ETHERADR+2);
+ ethaddr[3] = ds_read_laguna(sc, DS_ETHERADR+3);
+ ethaddr[4] = ds_read_laguna(sc, DS_ETHERADR+4);
+ ethaddr[5] = ds_read_laguna(sc, DS_ETHERADR+5);
+ break;
+#endif
+
+#ifdef sgi
+ case SGI_INDY:
+ sc->sc_data = &dsclkdata_sgi_indy;
+ dsclkdata_sgi_indy.ds_addr = BUS_CVTADDR(ca);
+ break;
+#endif
+ default:
+ printf("\n");
+ panic("don't know how to set up for other system types.");
+ }
+
+ /* Turn interrupts off, just in case. */
+ ds1386_write(sc, DS_REGC, DS_REGC_TE);
+}
+
+/*
+ * Clock initialization.
+ *
+ * INDY's use the CPU timer register to generate the
+ * system ticker. This due to a rumour that the 8254
+ * has a bug that makes it unusable. Well who knows...
+ */
+static void
+dsclk_init (sc)
+ struct clock_softc *sc ;
+{
+#ifdef sgi
+ /* XXX get cpu frquency! */
+ cpu_counter_interval = 50000000 / hz;
+ cpu_counter_last = R4K_GetCOUNT();
+ cpu_counter_last += cpu_counter_interval;
+ R4K_SetCOMPARE(cpu_counter_last);
+#endif
+}
+
+/*
+ * Get the clock device idea of the time of day.
+ */
+static void
+dsclk_get(sc, base, ct)
+ struct clock_softc *sc;
+ time_t base;
+ struct tod_time *ct;
+{
+ ds_todregs regs;
+ int s;
+
+ s = splclock();
+ DS1386_GETTOD(sc, &regs)
+ splx(s);
+
+#define hex_to_bin(x,m) (((x) & m & 0xf) + (((x) & m) >> 4) * 10)
+ ct->sec = hex_to_bin(regs[DS_SEC], 0x7f);
+ ct->min = hex_to_bin(regs[DS_MIN], 0x7f);
+ ct->hour = hex_to_bin(regs[DS_HOUR], 0x3f);
+ ct->dow = hex_to_bin(regs[DS_DOW], 0x07);
+ ct->day = hex_to_bin(regs[DS_DOM], 0x3f);
+ ct->mon = hex_to_bin(regs[DS_MONTH], 0x1f);
+ ct->year = hex_to_bin(regs[DS_YEAR], 0xff);
+
+printf("%d:%d:%d-%d-%d-%d\n", ct->hour, ct->min, ct->sec, ct->year, ct->mon, ct->day);
+}
+
+/*
+ * Reset the clock device to the current time value.
+ */
+static void
+dsclk_set(sc, ct)
+ struct clock_softc *sc;
+ struct tod_time *ct;
+{
+ ds_todregs regs;
+ int s;
+
+ s = splclock();
+ DS1386_GETTOD(sc, &regs);
+ splx(s);
+
+#define bin_to_hex(x,m) ((((x) / 10 << 4) + (x) % 10) & m)
+ regs[DS_SEC_100] = 0x00;
+ regs[DS_SEC] = bin_to_hex(ct->sec, 0x7f);
+ regs[DS_MIN] = bin_to_hex(ct->min, 0x7f);
+ regs[DS_HOUR] = bin_to_hex(ct->hour, 0x3f);
+ regs[DS_DOW] = bin_to_hex(ct->dow, 0x07);
+ regs[DS_DOM] = bin_to_hex(ct->day, 0x3f);
+ regs[DS_MONTH] = bin_to_hex(ct->mon, 0x1f);
+ regs[DS_YEAR] = bin_to_hex(ct->year, 0xff);
+
+ s = splclock();
+ DS1386_PUTTOD(sc, &regs);
+ splx(s);
+}
+
+
+/*
+ * Clock register acces routines for different clock chips
+ */
+
+#ifdef hkmips
+static void
+ds_write_laguna(sc, reg, datum)
+ struct clock_softc *sc;
+ u_int reg, datum;
+{
+ int i,brc1;
+
+ brc1 = inb(LAGUNA_BRC1_REG);
+ outb(LAGUNA_BRC1_REG, brc1 | LAGUNA_BRC1_ENRTCWR);
+ outb(((struct dsclkdata *)sc->sc_data)->ds_addr + (reg * 4), datum);
+}
+
+static u_int
+ds_read_laguna(sc, reg)
+ struct clock_softc *sc;
+ u_int reg;
+{
+ int i;
+
+ i = inb(((struct dsclkdata *)sc->sc_data)->ds_addr + (reg * 4));
+ i &= 0xff;
+ return(i);
+}
+#endif
+
+#ifdef sgi
+static void
+ds_write_sgi_indy(sc, reg, datum)
+ struct clock_softc *sc;
+ u_int reg, datum;
+{
+ outb(((struct dsclkdata *)sc->sc_data)->ds_addr + (reg * 4), datum);
+}
+
+static u_int
+ds_read_sgi_indy(sc, reg)
+ struct clock_softc *sc;
+ u_int reg;
+{
+ int i;
+
+ i = inb(((struct dsclkdata *)sc->sc_data)->ds_addr + (reg * 4));
+ i &= 0xff;
+ return(i);
+}
+#endif
diff --git a/sys/arch/mips/dev/clockvar.h b/sys/arch/mips/dev/clockvar.h
new file mode 100644
index 00000000000..f5420f436ac
--- /dev/null
+++ b/sys/arch/mips/dev/clockvar.h
@@ -0,0 +1,77 @@
+/* $OpenBSD: clockvar.h,v 1.1 1998/01/29 15:06:19 pefo Exp $ */
+/* $NetBSD: clockvar.h,v 1.1 1995/06/28 02:44:59 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ * Adopted for r4400: Per Fogelstrom
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * Definitions for "cpu-independent" clock handling for the mips arc arch.
+ */
+
+/*
+ * clocktime structure:
+ *
+ * structure passed to TOY clocks when setting them. broken out this
+ * way, so that the time_t -> field conversion can be shared.
+ */
+struct tod_time {
+ int year; /* year - 1900 */
+ int mon; /* month (1 - 12) */
+ int day; /* day (1 - 31) */
+ int hour; /* hour (0 - 23) */
+ int min; /* minute (0 - 59) */
+ int sec; /* second (0 - 59) */
+ int dow; /* day of week (0 - 6; 0 = Sunday) */
+};
+
+/*
+ * clockdesc structure:
+ *
+ * provides clock-specific functions to do necessary operations.
+ */
+struct clock_softc {
+ struct device sc_dev;
+
+ /*
+ * The functions that all types of clock provide.
+ */
+ void (*sc_attach) __P((struct device *, struct device *, void *));
+ void (*sc_init) __P((struct clock_softc *));
+ void (*sc_get) __P((struct clock_softc *, time_t, struct tod_time *));
+ void (*sc_set) __P((struct clock_softc *, struct tod_time *));
+
+ /*
+ * Private storage for particular clock types.
+ */
+ void *sc_data;
+
+ /*
+ * Has the time been initialized?
+ */
+ int sc_initted;
+};
diff --git a/sys/arch/mips/dev/ds1386reg.h b/sys/arch/mips/dev/ds1386reg.h
new file mode 100644
index 00000000000..362ac80e7d5
--- /dev/null
+++ b/sys/arch/mips/dev/ds1386reg.h
@@ -0,0 +1,119 @@
+/* $NetBSD: ds1386reg.h,v 1.1 1995/05/04 19:31:18 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * Definitions for the Dallas Semiconductor DS1386 Real Time Clock.
+ *
+ */
+
+/*
+ * The registers, and the bits within each register.
+ */
+
+#define DS_SEC_100 0x0 /* Time of year: hundreds seconds (0-99) */
+#define DS_SEC 0x1 /* Time of year: seconds (0-59) */
+#define DS_MIN 0x2 /* Time of year: minutes (0-59) */
+#define DS_HOUR 0x4 /* Time of year: hour (see above) */
+#define DS_DOW 0x6 /* Time of year: day of week (1-7) */
+#define DS_DOM 0x8 /* Time of year: day of month (1-31) */
+#define DS_MONTH 0x9 /* Time of year: month (1-12) */
+#define DS_YEAR 0xa /* Time of year: year in century (0-99) */
+#define DS_AMIN 0x3 /* Alarm: minutes */
+#define DS_AHOUR 0x5 /* Alarm: hour */
+#define DS_ADOW 0x7 /* Alarm: day */
+
+
+
+#define DS_HOUR_12 0x40 /* 12-hour mode. In DS_HOUR reg */
+#define DS_EOSC 0x80 /* Enable TOD osc if 0. In DS_MONTH reg. */
+
+#define DS_REGC 0xb /* Control register */
+
+#define DS_REGC_TE 0x80 /* Transfer enable bit. 0 freezes regs */
+#define DS_REGC_IPSW 0x40 /* Interrupt routing bit */
+#define DS_REGC_WAM 0x08 /* Watchdog alarm int enab. 1 enables */
+#define DS_REGC_TDM 0x04 /* Time Of Day alarm int enab. 1 enables */
+#define DS_REGC_WAF 0x02 /* Watchdog alarm int status */
+#define DS_REGC_TDF 0x01 /* Time Of Day alarm int status */
+
+
+#define DS_NTODREGS 0xb /* 10 of those regs are for TOD and alarm */
+
+#define DS_NVRAM_START 0xe /* start of NVRAM: offset 14 */
+#define DS_NVRAM_SIZE (0x8000-0xe) /* 32k of NVRAM */
+
+/*
+ * Special NVRAM locations.
+ */
+#define DS_ETHERADR 0x115 /* Ethernet address */
+
+/*
+ * RTC register/NVRAM read and write functions -- machine-dependent.
+ * Appropriately manipulate RTC registers to get/put data values.
+ */
+u_int ds1386_read __P((void *sc, u_int reg));
+void ds1386_write __P((void *sc, u_int reg, u_int datum));
+
+/*
+ * A collection of TOD/Alarm registers.
+ */
+typedef u_int ds_todregs[DS_NTODREGS];
+
+/*
+ * Get all of the TOD/Alarm registers
+ * Must be called at splhigh(), and with the RTC properly set up.
+ */
+#define DS1386_GETTOD(sc, regs) \
+ do { \
+ int i; \
+ \
+ /* wait for update; spin loop */ \
+ i = ds1386_read(sc, DS_SEC_100); \
+ while (ds1386_read(sc, DS_SEC_100) == i) \
+ ; \
+ \
+ /* read all of the tod/alarm regs */ \
+ for (i = 0; i < DS_NTODREGS; i++) \
+ (*regs)[i] = ds1386_read(sc, i); \
+ } while (0);
+
+/*
+ * Set all of the TOD/Alarm registers
+ * Must be called at splhigh(), and with the RTC properly set up.
+ */
+#define DS1386_PUTTOD(sc, regs) \
+ do { \
+ int i; \
+ \
+ /* stop updates while setting */ \
+ ds1386_write(sc, DS_MONTH, DS_EOSC); \
+ \
+ /* write all of the tod/alarm regs */ \
+ for (i = 0; i < DS_NTODREGS; i++) \
+ ds1386_write(sc, i, (*regs)[i]); \
+ \
+ } while (0);