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