xref: /netbsd/sys/arch/sun2/sun2/tod.c (revision c4a72b64)
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