tx39clock.c revision 1.2 1 /* $NetBSD: tx39clock.c,v 1.2 1999/12/07 17:08:10 uch Exp $ */
2
3 /*
4 * Copyright (c) 1999, by UCHIYAMA Yasushi
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. The name of the developer may NOT be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 */
28 #include "opt_tx39_debug.h"
29
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/device.h>
33
34 #include <machine/bus.h>
35 #include <machine/clock_machdep.h>
36 #include <machine/cpu.h>
37
38 #include <hpcmips/tx/tx39var.h>
39 #include <hpcmips/tx/tx39icureg.h> /* XXX */
40 #include <hpcmips/tx/tx39clockreg.h>
41 #include <hpcmips/tx/tx39timerreg.h>
42 #include <dev/dec/clockvar.h>
43
44 #define ISSETPRINT(r, m) __is_set_print(r, TX39_CLOCK_EN##m##CLK, #m)
45
46 void clock_init __P((struct device*));
47 void clock_get __P((struct device*, time_t, struct clocktime*));
48 void clock_set __P((struct device*, struct clocktime*));
49
50 static const struct clockfns clockfns = {
51 clock_init, clock_get, clock_set,
52 };
53
54 int tx39clock_match __P((struct device*, struct cfdata*, void*));
55 void tx39clock_attach __P((struct device*, struct device*, void*));
56 void tx39clock_dump __P((tx_chipset_tag_t));
57
58 void tx39timer_freeze __P((tx_chipset_tag_t));
59 void tx39timer_rtcreset __P((tx_chipset_tag_t));
60
61 struct tx39clock_softc {
62 struct device sc_dev;
63 tx_chipset_tag_t sc_tc;
64 };
65
66 struct cfattach tx39clock_ca = {
67 sizeof(struct tx39clock_softc), tx39clock_match, tx39clock_attach
68 };
69
70 int
71 tx39clock_match(parent, cf, aux)
72 struct device *parent;
73 struct cfdata *cf;
74 void *aux;
75 {
76 return 2; /* 1st attach group of txsim */
77 }
78
79 void
80 tx39clock_attach(parent, self, aux)
81 struct device *parent;
82 struct device *self;
83 void *aux;
84 {
85 struct txsim_attach_args *ta = aux;
86 struct tx39clock_softc *sc = (void*)self;
87 tx_chipset_tag_t tc;
88 txreg_t reg;
89
90 tc = sc->sc_tc = ta->ta_tc;
91
92 /*
93 * Enable periodic timer
94 * but interrupt don't arise yet. see clock_init().
95 */
96 reg = tx_conf_read(tc, TX39_TIMERCONTROL_REG);
97 reg |= TX39_TIMERCONTROL_ENPERTIMER;
98 tx_conf_write(tc, TX39_TIMERCONTROL_REG, reg);
99
100 /* Set counter */
101 #if 0
102 {
103 int cnt = 0xffff; /* XXX the most slower. */
104 reg = tx_conf_read(tc, TX39_TIMERPERIODIC_REG);
105 reg = TX39_TIMERPERIODIC_PERVAL_SET(reg, cnt);
106 tx_conf_write(tc, TX39_TIMERPERIODIC_REG, reg);
107 }
108 #endif
109 clockattach(self, &clockfns);
110
111 #ifdef TX39CLKDEBUG
112 tx39clock_dump(tc);
113 #endif /* TX39CLKDEBUG */
114 }
115
116 /*
117 * RTC and ALARM
118 * RTCINT ... INTR5 bit 31 (roll over)
119 * ALARMINT ... INTR5 bit 30
120 * PERINT ... INTR5 bit 29
121 */
122 void
123 tx39timer_freeze(tc)
124 tx_chipset_tag_t tc;
125 {
126 txreg_t reg;
127
128 reg = tx_conf_read(tc, TX39_TIMERCONTROL_REG);
129 /* Freeze RTC */
130 reg |= TX39_TIMERCONTROL_FREEZEPRE; /* Upper 8bit */
131 reg |= TX39_TIMERCONTROL_FREEZERTC; /* Lower 32bit */
132 /* Freeze periodic timer */
133 reg |= TX39_TIMERCONTROL_FREEZETIMER;
134 reg &= ~TX39_TIMERCONTROL_ENPERTIMER;
135 tx_conf_write(tc, TX39_TIMERCONTROL_REG, reg);
136 }
137
138 void
139 tx39timer_rtcreset(tc)
140 tx_chipset_tag_t tc;
141 {
142 txreg_t reg;
143
144 reg = tx_conf_read(tc, TX39_TIMERCONTROL_REG);
145 /* Reset counter and stop */
146 reg |= TX39_TIMERCONTROL_RTCCLR;
147 tx_conf_write(tc, TX39_TIMERCONTROL_REG, reg);
148 /* Count again */
149 reg &= ~TX39_TIMERCONTROL_RTCCLR;
150 tx_conf_write(tc, TX39_TIMERCONTROL_REG, reg);
151 }
152
153 void
154 clock_init(dev)
155 struct device *dev;
156 {
157 tx_chipset_tag_t tc;
158 txreg_t reg;
159
160 tc = tx_conf_get_tag();
161 /* Enable periodic timer */
162 reg = tx_conf_read(tc, TX39_INTRENABLE6_REG);
163 reg |= TX39_INTRPRI13_TIMER_PERIODIC_BIT;
164 tx_conf_write(tc, TX39_INTRENABLE6_REG, reg);
165
166 }
167
168 void
169 clock_get(dev, base, ct)
170 struct device *dev;
171 time_t base;
172 struct clocktime *ct;
173 {
174 tx_chipset_tag_t tc;
175 txreg_t reghi, reglo, oreghi, oreglo;
176 int i;
177
178 tc = tx_conf_get_tag();
179 i = 10;
180 do {
181 reghi = tx_conf_read(tc, TX39_TIMERRTCHI_REG);
182 reglo = tx_conf_read(tc, TX39_TIMERRTCLO_REG);
183 oreghi = tx_conf_read(tc, TX39_TIMERRTCHI_REG);
184 oreglo = tx_conf_read(tc, TX39_TIMERRTCLO_REG);
185 } while ((reghi != oreghi || reglo != oreglo) && (--i > 0));
186 if (i < 0) {
187 panic("RTC timer read error.\n");
188 }
189 /* XXX not coded yet */
190 }
191
192 void
193 clock_set(dev, ct)
194 struct device *dev;
195 struct clocktime *ct;
196 {
197 /* XXX not coded yet */
198 }
199
200 void
201 tx39clock_dump(tc)
202 tx_chipset_tag_t tc;
203 {
204 txreg_t reg;
205
206 reg = tx_conf_read(tc, TX39_CLOCKCTRL_REG);
207 printf(" ");
208 ISSETPRINT(reg, CHIM);
209 #ifdef TX391X
210 ISSETPRINT(reg, VID);
211 ISSETPRINT(reg, MBUS);
212 #endif /* TX391X */
213 #ifdef TX392X
214 ISSETPRINT(reg, IRDA);
215 #endif /* TX392X */
216 ISSETPRINT(reg, SPI);
217 ISSETPRINT(reg, TIMER);
218 ISSETPRINT(reg, FASTTIMER);
219 #ifdef TX392X
220 ISSETPRINT(reg, C48MOUT);
221 #endif /* TX392X */
222 ISSETPRINT(reg, SIBM);
223 ISSETPRINT(reg, CSER);
224 ISSETPRINT(reg, IR);
225 ISSETPRINT(reg, UARTA);
226 ISSETPRINT(reg, UARTB);
227 printf("\n");
228 }
229
230
231
232
233