1 /* $NetBSD: tod.c,v 1.6 2002/10/02 16:02:24 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 2001 Matthew Fredette 5 * Copyright (c) 1994 Gordon W. Ross 6 * Copyright (c) 1993 Adam Glass 7 * Copyright (c) 1988 University of Utah. 8 * Copyright (c) 1982, 1990, 1993 9 * The Regents of the University of California. All rights reserved. 10 * 11 * This code is derived from software contributed to Berkeley by 12 * the Systems Programming Group of the University of Utah Computer 13 * Science Department. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 18 * 1. Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in the 22 * documentation and/or other materials provided with the distribution. 23 * 3. All advertising materials mentioning features or use of this software 24 * must display the following acknowledgement: 25 * This product includes software developed by the University of 26 * California, Berkeley and its contributors. 27 * 4. Neither the name of the University nor the names of its contributors 28 * may be used to endorse or promote products derived from this software 29 * without specific prior written permission. 30 * 31 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 32 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 33 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 34 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 35 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 39 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 40 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 41 * SUCH DAMAGE. 42 * 43 * from: Utah Hdr: clock.c 1.18 91/01/21$ 44 * from: @(#)clock.c 8.2 (Berkeley) 1/12/94 45 */ 46 47 /* 48 * Machine-dependent clock routines for the NS mm58167 time-of-day chip. 49 * Written by Matthew Fredette, based on the sun3 clock.c by 50 * Adam Glass and Gordon Ross. 51 */ 52 53 #include <sys/param.h> 54 #include <sys/systm.h> 55 #include <sys/time.h> 56 #include <sys/kernel.h> 57 #include <sys/device.h> 58 59 #include <m68k/asm_single.h> 60 61 #include <machine/autoconf.h> 62 #include <machine/bus.h> 63 #include <machine/cpu.h> 64 65 #include <sun2/sun2/machdep.h> 66 #include <sun2/sun2/tod.h> 67 68 #include <dev/vme/vmereg.h> 69 #include <dev/vme/vmevar.h> 70 71 #include <dev/clock_subr.h> 72 #include <dev/ic/mm58167var.h> 73 74 static todr_chip_handle_t todr_handle; 75 76 static int tod_obio_match __P((struct device *, struct cfdata *, void *args)); 77 static void tod_obio_attach __P((struct device *, struct device *, void *)); 78 static int tod_vme_match __P((struct device *, struct cfdata *, void *args)); 79 static void tod_vme_attach __P((struct device *, struct device *, void *)); 80 static void tod_attach __P((struct mm58167_softc *)); 81 82 CFATTACH_DECL(tod_obio, sizeof(struct mm58167_softc), 83 tod_obio_match, tod_obio_attach, NULL, NULL); 84 85 CFATTACH_DECL(tod_vme, sizeof(struct mm58167_softc), 86 tod_vme_match, tod_vme_attach, NULL, NULL); 87 88 static int 89 tod_obio_match(parent, cf, args) 90 struct device *parent; 91 struct cfdata *cf; 92 void *args; 93 { 94 struct obio_attach_args *oba = args; 95 bus_space_handle_t bh; 96 int matched; 97 98 /* This driver only supports one unit. */ 99 if (cf->cf_unit != 0) 100 return (0); 101 102 /* Make sure there is something there... */ 103 if (bus_space_map(oba->oba_bustag, oba->oba_paddr, MM58167REG_BANK_SZ, 104 0, &bh)) 105 return (0); 106 matched = (bus_space_peek_1(oba->oba_bustag, bh, 0, NULL) == 0); 107 bus_space_unmap(oba->oba_bustag, bh, MM58167REG_BANK_SZ); 108 return (matched); 109 } 110 111 static void 112 tod_obio_attach(parent, self, args) 113 struct device *parent; 114 struct device *self; 115 void *args; 116 { 117 struct obio_attach_args *oba = args; 118 struct mm58167_softc *sc; 119 120 sc = (struct mm58167_softc *) self; 121 122 /* Map the device. */ 123 sc->mm58167_regt = oba->oba_bustag; 124 if (bus_space_map(oba->oba_bustag, oba->oba_paddr, MM58167REG_BANK_SZ, 0, &sc->mm58167_regh)) 125 panic("tod_obio_attach: can't map"); 126 127 tod_attach(sc); 128 } 129 130 static int 131 tod_vme_match(parent, cf, aux) 132 struct device *parent; 133 struct cfdata *cf; 134 void *aux; 135 { 136 struct vme_attach_args *va = aux; 137 vme_chipset_tag_t ct = va->va_vct; 138 vme_am_t mod; 139 vme_addr_t vme_addr; 140 141 /* Make sure there is something there... */ 142 mod = VME_AM_A24 | VME_AM_MBO | VME_AM_SUPER | VME_AM_DATA; 143 vme_addr = va->r[0].offset; 144 145 if (vme_probe(ct, vme_addr, 1, mod, VME_D8, NULL, 0) != 0) 146 return (0); 147 148 return (1); 149 } 150 151 static void 152 tod_vme_attach(parent, self, aux) 153 struct device *parent, *self; 154 void *aux; 155 { 156 struct mm58167_softc *sc; 157 struct vme_attach_args *va = aux; 158 vme_chipset_tag_t ct = va->va_vct; 159 bus_space_tag_t bt; 160 bus_space_handle_t bh; 161 vme_am_t mod; 162 vme_mapresc_t resc; 163 164 sc = (struct mm58167_softc *) self; 165 166 mod = VME_AM_A24 | VME_AM_MBO | VME_AM_SUPER | VME_AM_DATA; 167 168 if (vme_space_map(ct, va->r[0].offset, MM58167REG_BANK_SZ, 169 mod, VME_D8, 0, &bt, &bh, &resc) != 0) 170 panic("tod_vme_attach: can't map"); 171 172 sc->mm58167_regt = bt; 173 sc->mm58167_regh = bh; 174 175 tod_attach(sc); 176 } 177 178 static void 179 tod_attach(sc) 180 struct mm58167_softc *sc; 181 { 182 183 /* Call the IC attach code. */ 184 sc->mm58167_msec_xxx = MM58167REG_MSEC_XXX; 185 sc->mm58167_csec = MM58167REG_CSEC; 186 sc->mm58167_sec = MM58167REG_SEC; 187 sc->mm58167_min = MM58167REG_MIN; 188 sc->mm58167_hour = MM58167REG_HOUR; 189 sc->mm58167_wday = MM58167REG_WDAY; 190 sc->mm58167_day = MM58167REG_DAY; 191 sc->mm58167_mon = MM58167REG_MON; 192 sc->mm58167_status = MM58167REG_STATUS; 193 sc->mm58167_go = MM58167REG_GO; 194 if ((todr_handle = mm58167_attach(sc)) == NULL) 195 panic("tod_attach: can't attach ic"); 196 197 printf("\n"); 198 } 199 200 /* 201 * Machine-dependent clock routines. 202 * 203 * Inittodr initializes the time of day hardware which provides 204 * date functions. 205 * 206 * Resettodr restores the time of day hardware after a time change. 207 */ 208 209 /* 210 * Initialize the time of day register, based on the time base 211 * which is, e.g. from a filesystem. 212 */ 213 void inittodr(fs_time) 214 time_t fs_time; 215 { 216 struct timeval tv; 217 time_t diff, clk_time; 218 time_t long_ago = (5 * SECYR); 219 int clk_bad = 0; 220 221 /* 222 * Sanity check time from file system. 223 * If it is zero,assume filesystem time is just unknown 224 * instead of preposterous. Don't bark. 225 */ 226 if (fs_time < long_ago) { 227 /* 228 * If fs_time is zero, assume filesystem time is just 229 * unknown instead of preposterous. Don't bark. 230 */ 231 if (fs_time != 0) 232 printf("WARNING: preposterous time in file system\n"); 233 /* 1991/07/01 12:00:00 */ 234 fs_time = 21*SECYR + 186*SECDAY + SECDAY/2; 235 } 236 237 todr_gettime(todr_handle, &tv); 238 clk_time = tv.tv_sec; 239 240 /* Sanity check time from clock. */ 241 if (clk_time < long_ago) { 242 printf("WARNING: bad date in battery clock"); 243 clk_bad = 1; 244 clk_time = fs_time; 245 } else { 246 /* Does the clock time jive with the file system? */ 247 diff = clk_time - fs_time; 248 if (diff < 0) 249 diff = -diff; 250 if (diff >= (SECDAY*2)) { 251 printf("WARNING: clock %s %d days", 252 (clk_time < fs_time) ? "lost" : "gained", 253 (int) (diff / SECDAY)); 254 clk_bad = 1; 255 } 256 } 257 if (clk_bad) 258 printf(" -- CHECK AND RESET THE DATE!\n"); 259 time.tv_sec = clk_time; 260 } 261 262 /* 263 * Resettodr restores the time of day hardware after a time change. 264 */ 265 void resettodr() 266 { 267 struct timeval tv; 268 tv = time; 269 todr_settime(todr_handle, &tv); 270 } 271