xref: /netbsd-src/sys/arch/mvme68k/dev/clock_pcc.c (revision 76dfffe33547c37f8bdd446e3e4ab0f3c16cea4b)
1 /*	$NetBSD: clock_pcc.c,v 1.2 1996/09/12 05:10:46 thorpej Exp $	*/
2 
3 /*-
4  * Copyright (c) 1996 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
30  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38 
39 /*
40  * Glue for the Peripheral Channel Controller timers and the
41  * Mostek clock chip found on the MVME-147.
42  */
43 
44 #include <sys/param.h>
45 #include <sys/kernel.h>
46 #include <sys/systm.h>
47 #include <sys/device.h>
48 
49 #include <machine/psl.h>
50 #include <machine/cpu.h>
51 
52 #include <mvme68k/mvme68k/clockreg.h>
53 #include <mvme68k/mvme68k/clockvar.h>
54 
55 #include <mvme68k/dev/pccreg.h>
56 #include <mvme68k/dev/pccvar.h>
57 
58 int	clock_pcc_match __P((struct device *, void *, void *));
59 void	clock_pcc_attach __P((struct device *, struct device *, void *));
60 int	clock_pcc_profintr __P((void *));
61 int	clock_pcc_statintr __P((void *));
62 void	clock_pcc_initclocks __P((int, int));
63 void	clock_pcc_shutdown __P((void *));
64 
65 u_char	clock_pcc_lvl;
66 
67 struct cfattach clock_pcc_ca = {
68 	sizeof(struct device), clock_pcc_match, clock_pcc_attach
69 };
70 
71 int
72 clock_pcc_match(parent, match, aux)
73 	struct device *parent;
74 	void *match, *aux;
75 {
76 	struct cfdata *cf = match;
77 	struct pcc_attach_args *pa = aux;
78 	static int clock_pcc_matched;
79 
80 	/* Only one clock, please. */
81 	if (clock_pcc_matched)
82 		return (0);
83 
84 	if (strcmp(pa->pa_name, clock_cd.cd_name))
85 		return (0);
86 
87 	clock_pcc_matched = 1;
88 	pa->pa_ipl = cf->pcccf_ipl;
89 
90 	return (1);
91 }
92 
93 void
94 clock_pcc_attach(parent, self, aux)
95 	struct device *parent, *self;
96 	void *aux;
97 {
98 	struct pcc_attach_args *pa = aux;
99 	caddr_t nvram, clockregs;
100 
101 	if (pa->pa_ipl != CLOCK_LEVEL)
102 		panic("clock_pcc_attach: wrong interrupt level");
103 
104 	nvram = PCC_VADDR(pa->pa_offset);
105 	clockregs = PCC_VADDR(pa->pa_offset + PCC_RTC_OFF);
106 
107 	/* Do common portions of clock config. */
108 	clock_config(self, clockregs, nvram, MK48T02_SIZE,
109 	    clock_pcc_initclocks);
110 
111 	/* Ensure our interrupts get disabled at shutdown time. */
112 	(void)shutdownhook_establish(clock_pcc_shutdown, NULL);
113 
114 	/* Attach the interrupt handlers. */
115 	pccintr_establish(PCCV_TIMER1, clock_pcc_profintr, pa->pa_ipl, NULL);
116 	pccintr_establish(PCCV_TIMER2, clock_pcc_statintr, pa->pa_ipl, NULL);
117 	clock_pcc_lvl = pa->pa_ipl | PCC_IENABLE | PCC_TIMERACK;
118 }
119 
120 void
121 clock_pcc_initclocks(proftick, stattick)
122 	int proftick, stattick;
123 {
124 
125 	sys_pcc->t1_pload = pcc_timer_us2lim(proftick);
126 	sys_pcc->t1_cr = PCC_TIMERCLEAR;
127 	sys_pcc->t1_cr = PCC_TIMERSTART;
128 	sys_pcc->t1_int = clock_pcc_lvl;
129 
130 	sys_pcc->t2_pload = pcc_timer_us2lim(stattick);
131 	sys_pcc->t2_cr = PCC_TIMERCLEAR;
132 	sys_pcc->t2_cr = PCC_TIMERSTART;
133 	sys_pcc->t2_int = clock_pcc_lvl;
134 }
135 
136 int
137 clock_pcc_profintr(frame)
138 	void *frame;
139 {
140 
141 	sys_pcc->t1_int = clock_pcc_lvl;
142 	hardclock(frame);
143 	clock_profcnt.ev_count++;
144 	return (1);
145 }
146 
147 int
148 clock_pcc_statintr(frame)
149 	void *frame;
150 {
151 
152 	/* Disable the timer interrupt while we handle it. */
153 	sys_pcc->t2_int = 0;
154 
155 	statclock((struct clockframe *)frame);
156 
157 	sys_pcc->t2_pload =
158 	    pcc_timer_us2lim(CLOCK_NEWINT(clock_statvar, clock_statmin));
159 	sys_pcc->t2_cr = PCC_TIMERCLEAR;
160 	sys_pcc->t2_cr = PCC_TIMERSTART;
161 	sys_pcc->t2_int = clock_pcc_lvl;
162 
163 	clock_statcnt.ev_count++;
164 	return (1);
165 }
166 
167 /* ARGSUSED */
168 void
169 clock_pcc_shutdown(arg)
170 	void *arg;
171 {
172 
173 	/* Make sure the timer interrupts are turned off. */
174 	sys_pcc->t1_cr = PCC_TIMERCLEAR;
175 	sys_pcc->t1_int = 0;
176 	sys_pcc->t2_cr = PCC_TIMERCLEAR;
177 	sys_pcc->t2_int = 0;
178 }
179