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