xref: /netbsd/sys/arch/shark/shark/hat.c (revision bf9ec67e)
1 /*	$NetBSD: hat.c,v 1.1 2002/02/10 01:58:03 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 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/time.h>
46 #include <sys/kernel.h>
47 #include <sys/device.h>
48 
49 #include <arm/fiq.h>
50 
51 #include <machine/cpu.h>
52 #include <machine/intr.h>
53 #include <machine/pio.h>
54 #include <arm/cpufunc.h>
55 
56 #include <dev/ic/i8253reg.h>
57 
58 #include <dev/isa/isareg.h>
59 #include <dev/isa/isavar.h>
60 
61 #include <shark/shark/shark_fiq.h>
62 #include <shark/shark/sequoia.h>
63 
64 static int hatOn = 0;
65 
66 /* interface to high-availability timer */
67 
68 static void hatClkCount(int count);
69 static void hatEnableSWTCH();
70 
71 static void (*hatWedgeFn)(int);
72 
73 extern struct fiqregs shark_fiqregs;
74 
75 int hatClkOff(void)
76 {
77 	u_int16_t    seqReg;
78 
79 	if (!hatOn) return -1;
80 	hatOn = 0;
81 	hatWedgeFn = NULL;
82 
83         /* disable the SWTCH pin */
84 
85 	sequoiaRead(PMC_PMCMCR2_REG, &seqReg);
86         sequoiaWrite(PMC_PMCMCR2_REG, seqReg  | (PMCMCR2_M_SWTCHEN));
87 
88         /* turn off timer 2 */
89         outb(ATSR_REG1_REG,
90 	     inb(ATSR_REG1_REG) & ~((REG1_M_TMR2EN) | (REG1_M_SPKREN)));
91 
92 	fiq_getregs(&shark_fiqregs);
93 
94 	/* get rid of the C routine and stack */
95 	shark_fiqregs.fr_r9  = 0;
96 	shark_fiqregs.fr_r13 = 0;
97 
98 	fiq_setregs(&shark_fiqregs);
99 	isa_dmathaw(&isa_chipset_tag);		/* XXX */
100 
101 	return 0;
102 }
103 
104 
105 int hatClkOn(int count, void (*hatFn)(int), int arg,
106 	     unsigned char *stack, void (*wedgeFn)(int))
107 {
108 	u_int16_t    seqReg;
109 
110 	if (hatOn) return -1;
111 
112 	hatWedgeFn = wedgeFn;
113 
114 	isa_dmafreeze(&isa_chipset_tag);	/* XXX */
115 
116 	fiq_getregs(&shark_fiqregs);
117 
118 	/* set the C routine and stack */
119 	shark_fiqregs.fr_r9  = (u_int)hatFn;
120 	shark_fiqregs.fr_r10 = (u_int)arg;
121 	shark_fiqregs.fr_r13 = (u_int)stack;
122 
123 	fiq_setregs(&shark_fiqregs);
124 
125 	/* no debounce on SWTCH */
126 	sequoiaRead(PMC_DBCR_REG, &seqReg);
127 	sequoiaWrite(PMC_DBCR_REG, seqReg | DBCR_M_DBDIS0);
128 
129 	hatEnableSWTCH(); /* enable the SWTCH -> PMI logic */
130 
131         /* turn on timer 2 */
132         outb(ATSR_REG1_REG,
133 	     inb(ATSR_REG1_REG) | (REG1_M_TMR2EN) | (REG1_M_SPKREN));
134 
135 	/* start timer 2 running */
136 	hatClkCount(count);
137 
138         /* enable the SWTCH pin */
139 	sequoiaRead(PMC_PMCMCR2_REG, &seqReg);
140         sequoiaWrite(PMC_PMCMCR2_REG, seqReg | (PMCMCR2_M_SWTCHEN));
141 
142 	hatOn = 1;
143 	return 0;
144 }
145 
146 
147 int hatClkAdjust(int count)
148 {
149 	if (!hatOn) return -1;
150 
151 	hatClkCount(count);
152 	hatEnableSWTCH();
153 
154 	return 0;
155 }
156 
157 static void
158 hatEnableSWTCH()
159 {
160     u_int16_t    seqReg;
161 
162     /* SWTCH input causes PMI, not automatic switch to standby mode! */
163     /* clearing bit 9 is bad news.  seems to enable PMI from secondary
164        activity timeout! */
165     /* first setting, then clearing this bit seems to unwedge the edge
166        detect logic in the sequoia */
167 
168     sequoiaRead(PMC_PMIMCR_REG, &seqReg);
169     sequoiaWrite(PMC_PMIMCR_REG, seqReg |  (PMIMCR_M_IMSKSWSTBY));
170     sequoiaWrite(PMC_PMIMCR_REG, seqReg & ~(PMIMCR_M_IMSKSWSTBY));
171 }
172 
173 void hatUnwedge()
174 {
175   static int   lastFiqsHappened = -1;
176   extern int   fiqs_happened;
177 
178   if (!hatOn) return;
179 
180   if (lastFiqsHappened == fiqs_happened) {
181     hatEnableSWTCH();
182     if (hatWedgeFn) (*hatWedgeFn)(fiqs_happened);
183   } else {
184     lastFiqsHappened = fiqs_happened;
185   }
186 }
187 
188 static void hatClkCount(int count)
189 {
190         u_int savedints;
191 
192         savedints = disable_interrupts(I32_bit);
193 
194 	outb(TIMER_MODE, TIMER_SEL2|TIMER_RATEGEN|TIMER_16BIT);
195 	outb(TIMER_CNTR2, count % 256);
196 	outb(TIMER_CNTR2, count / 256);
197 
198 	restore_interrupts(savedints);
199 }
200 
201