1 /* $NetBSD: tod.c,v 1.3 2001/06/27 02:59:26 fredette 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 struct cfattach tod_obio_ca = { 83 sizeof(struct mm58167_softc), tod_obio_match, tod_obio_attach 84 }; 85 86 struct cfattach tod_vme_ca = { 87 sizeof(struct mm58167_softc), tod_vme_match, tod_vme_attach 88 }; 89 90 static int 91 tod_obio_match(parent, cf, args) 92 struct device *parent; 93 struct cfdata *cf; 94 void *args; 95 { 96 struct obio_attach_args *oba = args; 97 bus_space_handle_t bh; 98 int matched; 99 100 /* This driver only supports one unit. */ 101 if (cf->cf_unit != 0) 102 return (0); 103 104 /* Make sure there is something there... */ 105 if (bus_space_map(oba->oba_bustag, oba->oba_paddr, MM58167REG_BANK_SZ, 106 0, &bh)) 107 return (0); 108 matched = (bus_space_peek_1(oba->oba_bustag, bh, 0, NULL) == 0); 109 bus_space_unmap(oba->oba_bustag, bh, MM58167REG_BANK_SZ); 110 return (matched); 111 } 112 113 static void 114 tod_obio_attach(parent, self, args) 115 struct device *parent; 116 struct device *self; 117 void *args; 118 { 119 struct obio_attach_args *oba = args; 120 struct mm58167_softc *sc; 121 122 sc = (struct mm58167_softc *) self; 123 124 /* Map the device. */ 125 sc->mm58167_regt = oba->oba_bustag; 126 if (bus_space_map(oba->oba_bustag, oba->oba_paddr, MM58167REG_BANK_SZ, 0, &sc->mm58167_regh)) 127 panic("tod_obio_attach: can't map"); 128 129 tod_attach(sc); 130 } 131 132 static int 133 tod_vme_match(parent, cf, aux) 134 struct device *parent; 135 struct cfdata *cf; 136 void *aux; 137 { 138 struct vme_attach_args *va = aux; 139 vme_chipset_tag_t ct = va->va_vct; 140 vme_am_t mod; 141 vme_addr_t vme_addr; 142 143 /* Make sure there is something there... */ 144 mod = VME_AM_A24 | VME_AM_MBO | VME_AM_SUPER | VME_AM_DATA; 145 vme_addr = va->r[0].offset; 146 147 if (vme_probe(ct, vme_addr, 1, mod, VME_D8, NULL, 0) != 0) 148 return (0); 149 150 return (1); 151 } 152 153 static void 154 tod_vme_attach(parent, self, aux) 155 struct device *parent, *self; 156 void *aux; 157 { 158 struct mm58167_softc *sc; 159 struct vme_attach_args *va = aux; 160 vme_chipset_tag_t ct = va->va_vct; 161 bus_space_tag_t bt; 162 bus_space_handle_t bh; 163 vme_am_t mod; 164 vme_mapresc_t resc; 165 166 sc = (struct mm58167_softc *) self; 167 168 mod = VME_AM_A24 | VME_AM_MBO | VME_AM_SUPER | VME_AM_DATA; 169 170 if (vme_space_map(ct, va->r[0].offset, MM58167REG_BANK_SZ, 171 mod, VME_D8, 0, &bt, &bh, &resc) != 0) 172 panic("tod_vme_attach: can't map"); 173 174 sc->mm58167_regt = bt; 175 sc->mm58167_regh = bh; 176 177 tod_attach(sc); 178 } 179 180 static void 181 tod_attach(sc) 182 struct mm58167_softc *sc; 183 { 184 185 /* Call the IC attach code. */ 186 sc->mm58167_msec_xxx = MM58167REG_MSEC_XXX; 187 sc->mm58167_csec = MM58167REG_CSEC; 188 sc->mm58167_sec = MM58167REG_SEC; 189 sc->mm58167_min = MM58167REG_MIN; 190 sc->mm58167_hour = MM58167REG_HOUR; 191 sc->mm58167_wday = MM58167REG_WDAY; 192 sc->mm58167_day = MM58167REG_DAY; 193 sc->mm58167_mon = MM58167REG_MON; 194 sc->mm58167_status = MM58167REG_STATUS; 195 sc->mm58167_go = MM58167REG_GO; 196 if ((todr_handle = mm58167_attach(sc)) == NULL) 197 panic("tod_attach: can't attach ic"); 198 199 printf("\n"); 200 } 201 202 /* 203 * Machine-dependent clock routines. 204 * 205 * Inittodr initializes the time of day hardware which provides 206 * date functions. 207 * 208 * Resettodr restores the time of day hardware after a time change. 209 */ 210 211 /* 212 * Initialize the time of day register, based on the time base 213 * which is, e.g. from a filesystem. 214 */ 215 void inittodr(fs_time) 216 time_t fs_time; 217 { 218 struct timeval tv; 219 time_t diff, clk_time; 220 time_t long_ago = (5 * SECYR); 221 int clk_bad = 0; 222 223 /* 224 * Sanity check time from file system. 225 * If it is zero,assume filesystem time is just unknown 226 * instead of preposterous. Don't bark. 227 */ 228 if (fs_time < long_ago) { 229 /* 230 * If fs_time is zero, assume filesystem time is just 231 * unknown instead of preposterous. Don't bark. 232 */ 233 if (fs_time != 0) 234 printf("WARNING: preposterous time in file system\n"); 235 /* 1991/07/01 12:00:00 */ 236 fs_time = 21*SECYR + 186*SECDAY + SECDAY/2; 237 } 238 239 todr_gettime(todr_handle, &tv); 240 clk_time = tv.tv_sec; 241 242 /* Sanity check time from clock. */ 243 if (clk_time < long_ago) { 244 printf("WARNING: bad date in battery clock"); 245 clk_bad = 1; 246 clk_time = fs_time; 247 } else { 248 /* Does the clock time jive with the file system? */ 249 diff = clk_time - fs_time; 250 if (diff < 0) 251 diff = -diff; 252 if (diff >= (SECDAY*2)) { 253 printf("WARNING: clock %s %d days", 254 (clk_time < fs_time) ? "lost" : "gained", 255 (int) (diff / SECDAY)); 256 clk_bad = 1; 257 } 258 } 259 if (clk_bad) 260 printf(" -- CHECK AND RESET THE DATE!\n"); 261 time.tv_sec = clk_time; 262 } 263 264 /* 265 * Resettodr restores the time of day hardware after a time change. 266 */ 267 void resettodr() 268 { 269 struct timeval tv; 270 tv = time; 271 todr_settime(todr_handle, &tv); 272 } 273