xref: /netbsd-src/sys/arch/next68k/next68k/clock.c (revision b5677b36047b601b9addaaa494a58ceae82c2a6c)
1 /*	$NetBSD: clock.c,v 1.11 2006/09/11 15:07:50 gdamore Exp $	*/
2 /*
3  * Copyright (c) 1998 Darrin B. Jewell
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *      This product includes software developed by Darrin B. Jewell
17  * 4. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.11 2006/09/11 15:07:50 gdamore Exp $");
34 
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/tty.h>
39 #include <sys/device.h>
40 
41 #include <machine/psl.h>
42 #include <machine/bus.h>
43 #include <machine/cpu.h>
44 
45 #include <next68k/dev/clockreg.h>
46 #include <next68k/dev/intiovar.h>
47 
48 #include <next68k/next68k/rtc.h>
49 #include <next68k/next68k/isr.h>
50 
51 /* @@@ This is pretty bogus and will need fixing once
52  * things are working better.
53  * -- jewell@mit.edu
54  */
55 
56 /*
57  * Note that the value of delay_divisor is roughly
58  * 2048 / cpuspeed (where cpuspeed is in MHz) on 68020
59  * and 68030 systems.  See clock.c for the delay
60  * calibration algorithm.
61  */
62 int	cpuspeed;		  /* relative cpu speed; XXX skewed on 68040 */
63 int	delay_divisor = 2048/25;  /* delay constant */
64 
65 /*
66  * Calibrate the delay constant.
67  */
68 void
69 next68k_calibrate_delay(void)
70 {
71 	extern int delay_divisor;
72 
73 	/* @@@ write this once we know how to read
74 	 * a real time clock
75 	 */
76 
77 	/*
78 	 * Sanity check the delay_divisor value.  If we totally lost,
79 	 * assume a 25MHz CPU;
80 	 */
81 	if (delay_divisor == 0)
82 		delay_divisor = 2048 / 25;
83 
84 	/* Calculate CPU speed. */
85 	cpuspeed = 2048 / delay_divisor;
86 }
87 
88 int clock_intr(void *);
89 
90 int
91 clock_intr(void *arg)
92 {
93 	volatile struct timer_reg *timer;
94 	int whilecount = 0;
95 
96 	if (!INTR_OCCURRED(NEXT_I_TIMER)) {
97 		return(0);
98 	}
99 
100 	do {
101 		static int in_hardclock = 0;
102 		int s;
103 
104 		timer = (volatile struct timer_reg *)IIOV(NEXT_P_TIMER);
105 		timer->csr |= TIMER_REG_UPDATE;
106 
107 		if (! in_hardclock) {
108 			in_hardclock = 1;
109 			s = splclock ();
110 			hardclock(arg);
111 			splx(s);
112 			in_hardclock = 0;
113 		}
114 		if (whilecount++ > 10)
115 			panic ("whilecount");
116 	} while (INTR_OCCURRED(NEXT_I_TIMER));
117 	return(1);
118 }
119 
120 /*
121  * Set up the real-time and statistics clocks.  Leave stathz 0 only
122  * if no alternative timer is available.
123  *
124  * The frequencies of these clocks must be an even number of microseconds.
125  */
126 void
127 cpu_initclocks(void)
128 {
129 	int s, cnt;
130 	volatile struct timer_reg *timer;
131 
132 	rtc_init();
133 	hz = 100;
134 	s = splclock();
135 	timer = (volatile struct timer_reg *)IIOV(NEXT_P_TIMER);
136 	cnt = 1000000/hz;          /* usec timer */
137 	timer->csr = 0;
138 	timer->msb = (cnt >> 8);
139 	timer->lsb = cnt;
140 	timer->csr = TIMER_REG_ENABLE|TIMER_REG_UPDATE;
141 	isrlink_autovec(clock_intr, NULL, NEXT_I_IPL(NEXT_I_TIMER), 0, NULL);
142 	INTR_ENABLE(NEXT_I_TIMER);
143 	splx(s);
144 }
145 
146 
147 void
148 setstatclockrate(int newhz)
149 {
150 
151 	/* XXX should we do something here? XXX */
152 }
153 
154 /* @@@ update this to use the usec timer
155  * Darrin B Jewell <jewell@mit.edu>  Sun Feb  8 05:01:02 1998
156  * XXX: Well, there is no more microtime.  But if there is a hardware
157  * timer of any sort, it could be added.   ENODOCS.  gdamore.
158  */
159 
160