From 1b35d27aa1e08c41ab91a5f3c3e4b69e4745a896 Mon Sep 17 00:00:00 2001 From: Per Fogelstrom Date: Thu, 29 Jan 1998 15:06:24 +0000 Subject: New try with conf --- sys/arch/mips/dev/clock_ds.c | 271 ++++++++++++++++++++++++++++++++++++++++++ sys/arch/mips/dev/clockvar.h | 77 ++++++++++++ sys/arch/mips/dev/ds1386reg.h | 119 +++++++++++++++++++ 3 files changed, 467 insertions(+) create mode 100644 sys/arch/mips/dev/clock_ds.c create mode 100644 sys/arch/mips/dev/clockvar.h create mode 100644 sys/arch/mips/dev/ds1386reg.h (limited to 'sys/arch/mips/dev') 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 +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + + +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, ®s) + 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, ®s); + 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, ®s); + 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); -- cgit v1.2.3