xref: /netbsd-src/sys/arch/shark/shark/hat.c (revision ed79218b1ecd87f6e43864a73379b6ec66834b31)
1 /*	$NetBSD: hat.c,v 1.7 2021/04/30 02:11:37 thorpej Exp $	*/
2 
3 /*
4  * Copyright 1997
5  * Digital Equipment Corporation. All rights reserved.
6  *
7  * This software is furnished under license and may be used and
8  * copied only in accordance with the following terms and conditions.
9  * Subject to these conditions, you may download, copy, install,
10  * use, modify and distribute this software in source and/or binary
11  * form. No title or ownership is transferred hereby.
12  *
13  * 1) Any source code used, modified or distributed must reproduce
14  *    and retain this copyright notice and list of conditions as
15  *    they appear in the source file.
16  *
17  * 2) No right is granted to use any trade name, trademark, or logo of
18  *    Digital Equipment Corporation. Neither the "Digital Equipment
19  *    Corporation" name nor any trademark or logo of Digital Equipment
20  *    Corporation may be used to endorse or promote products derived
21  *    from this software without the prior written permission of
22  *    Digital Equipment Corporation.
23  *
24  * 3) This software is provided "AS-IS" and any express or implied
25  *    warranties, including but not limited to, any implied warranties
26  *    of merchantability, fitness for a particular purpose, or
27  *    non-infringement are disclaimed. In no event shall DIGITAL be
28  *    liable for any damages whatsoever, and in particular, DIGITAL
29  *    shall not be liable for special, indirect, consequential, or
30  *    incidental damages or damages for lost profits, loss of
31  *    revenue or loss of use, whether such damages arise in contract,
32  *    negligence, tort, under statute, in equity, at law or otherwise,
33  *    even if advised of the possibility of such damage.
34  */
35 
36 /*
37  * hat.c
38  *
39  * implementation of high-availability timer on SHARK
40  *
41  * Created      : 19/05/97
42  */
43 
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: hat.c,v 1.7 2021/04/30 02:11:37 thorpej Exp $");
46 
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/time.h>
50 #include <sys/kernel.h>
51 #include <sys/device.h>
52 
53 #include <arm/fiq.h>
54 
55 #include <machine/cpu.h>
56 #include <machine/intr.h>
57 #include <machine/pio.h>
58 #include <arm/cpufunc.h>
59 
60 #include <dev/ic/i8253reg.h>
61 
62 #include <dev/isa/isareg.h>
63 #include <dev/isa/isavar.h>
64 
65 #include "isadma.h"
66 
67 #include <shark/shark/shark_fiq.h>
68 #include <shark/shark/sequoia.h>
69 #include <shark/shark/hat.h>
70 
71 static int hatOn = 0;
72 
73 /* interface to high-availability timer */
74 
75 static void hatClkCount(int);
76 static void hatEnableSWTCH(void);
77 
78 static void (*hatWedgeFn)(int);
79 
80 extern struct fiqregs shark_fiqregs;
81 
82 int
hatClkOff(void)83 hatClkOff(void)
84 {
85 	u_int16_t    seqReg;
86 
87 	if (!hatOn) return -1;
88 	hatOn = 0;
89 	hatWedgeFn = NULL;
90 
91 	sequoiaLock();
92 
93         /* disable the SWTCH pin */
94 
95 	sequoiaRead(PMC_PMCMCR2_REG, &seqReg);
96         sequoiaWrite(PMC_PMCMCR2_REG, seqReg  | (PMCMCR2_M_SWTCHEN));
97 
98 	sequoiaUnlock();
99 
100         /* turn off timer 2 */
101         outb(ATSR_REG1_REG,
102 	     inb(ATSR_REG1_REG) & ~((REG1_M_TMR2EN) | (REG1_M_SPKREN)));
103 
104 	fiq_getregs(&shark_fiqregs);
105 
106 	/* get rid of the C routine and stack */
107 	shark_fiqregs.fr_r9  = 0;
108 	shark_fiqregs.fr_r13 = 0;
109 
110 	fiq_setregs(&shark_fiqregs);
111 #if (NISADMA > 0)
112 	isa_dmathaw(&isa_chipset_tag);		/* XXX */
113 #endif
114 
115 	return 0;
116 }
117 
118 int
hatClkOn(int count,void (* hatFn)(int),int arg,unsigned char * stack,void (* wedgeFn)(int))119 hatClkOn(int count, void (*hatFn)(int), int arg,
120 	 unsigned char *stack, void (*wedgeFn)(int))
121 {
122 	u_int16_t    seqReg;
123 
124 	if (hatOn)
125 		return -1;
126 
127 	hatWedgeFn = wedgeFn;
128 
129 #if (NISADMA > 0)
130 	isa_dmafreeze(&isa_chipset_tag);	/* XXX */
131 #endif
132 
133 	fiq_getregs(&shark_fiqregs);
134 
135 	/* set the C routine and stack */
136 	shark_fiqregs.fr_r9  = (u_int)hatFn;
137 	shark_fiqregs.fr_r10 = (u_int)arg;
138 	shark_fiqregs.fr_r13 = (u_int)stack;
139 
140 	fiq_setregs(&shark_fiqregs);
141 
142 	sequoiaLock();
143 
144 	/* no debounce on SWTCH */
145 	sequoiaRead(PMC_DBCR_REG, &seqReg);
146 	sequoiaWrite(PMC_DBCR_REG, seqReg | DBCR_M_DBDIS0);
147 
148 	hatEnableSWTCH(); /* enable the SWTCH -> PMI logic */
149 
150         /* turn on timer 2 */
151         outb(ATSR_REG1_REG,
152 	     inb(ATSR_REG1_REG) | (REG1_M_TMR2EN) | (REG1_M_SPKREN));
153 
154 	/* start timer 2 running */
155 	hatClkCount(count);
156 
157         /* enable the SWTCH pin */
158 	sequoiaRead(PMC_PMCMCR2_REG, &seqReg);
159         sequoiaWrite(PMC_PMCMCR2_REG, seqReg | (PMCMCR2_M_SWTCHEN));
160 
161 	sequoiaUnlock();
162 
163 	hatOn = 1;
164 	return 0;
165 }
166 
167 
168 int
hatClkAdjust(int count)169 hatClkAdjust(int count)
170 {
171 	if (!hatOn)
172 		return -1;
173 
174 	hatClkCount(count);
175 	sequoiaLock();
176 	hatEnableSWTCH();
177 	sequoiaUnlock();
178 
179 	return 0;
180 }
181 
182 static void
hatEnableSWTCH(void)183 hatEnableSWTCH(void)
184 {
185 	u_int16_t    seqReg;
186 
187 	KASSERT(sequoiaIsLocked());
188 
189 	/* SWTCH input causes PMI, not automatic switch to standby mode! */
190 	/* clearing bit 9 is bad news.  seems to enable PMI from secondary
191 	   activity timeout! */
192 	/* first setting, then clearing this bit seems to unwedge the edge
193 	   detect logic in the sequoia */
194 
195 	sequoiaRead(PMC_PMIMCR_REG, &seqReg);
196 	sequoiaWrite(PMC_PMIMCR_REG, seqReg |  (PMIMCR_M_IMSKSWSTBY));
197 	sequoiaWrite(PMC_PMIMCR_REG, seqReg & ~(PMIMCR_M_IMSKSWSTBY));
198 }
199 
200 void
hatUnwedge(void)201 hatUnwedge(void)
202 {
203 	static int   lastFiqsHappened = -1;
204 	extern int   fiqs_happened;
205 
206 	if (!hatOn)
207 		return;
208 
209 	if (lastFiqsHappened == fiqs_happened) {
210 		sequoiaLock();
211 		hatEnableSWTCH();
212 		sequoiaUnlock();
213 		if (hatWedgeFn)
214 			(*hatWedgeFn)(fiqs_happened);
215 	} else {
216 		lastFiqsHappened = fiqs_happened;
217 	}
218 }
219 
220 static void
hatClkCount(int count)221 hatClkCount(int count)
222 {
223         u_int savedints;
224 
225         savedints = disable_interrupts(I32_bit);
226 
227 	outb(TIMER_MODE, TIMER_SEL2|TIMER_RATEGEN|TIMER_16BIT);
228 	outb(TIMER_CNTR2, count % 256);
229 	outb(TIMER_CNTR2, count / 256);
230 
231 	restore_interrupts(savedints);
232 }
233