tx39clock.c revision 1.1 1 /* $NetBSD: tx39clock.c,v 1.1 1999/11/20 19:56:33 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 /*
94 * Enable periodic timer
95 * but interrupt don't arise yet. see clock_init().
96 */
97 reg = tx_conf_read(tc, TX39_TIMERCONTROL_REG);
98 reg |= TX39_TIMERCONTROL_ENPERTIMER;
99 tx_conf_write(tc, TX39_TIMERCONTROL_REG, reg);
100
101 /* Set counter */
102 #if 0
103 {
104 int cnt = 0xffff; /* XXX the most slower. */
105 reg = tx_conf_read(tc, TX39_TIMERPERIODIC_REG);
106 reg = TX39_TIMERPERIODIC_PERVAL_SET(reg, cnt);
107 tx_conf_write(tc, TX39_TIMERPERIODIC_REG, reg);
108 }
109 #endif
110 clockattach(self, &clockfns);
111
112 tx39clock_dump(tc);
113 }
114
115 /*
116 * RTC and ALARM
117 * RTCINT ... INTR5 bit 31 (roll over)
118 * ALARMINT ... INTR5 bit 30
119 * PERINT ... INTR5 bit 29
120 */
121 void
122 tx39timer_freeze(tc)
123 tx_chipset_tag_t tc;
124 {
125 txreg_t reg;
126
127 reg = tx_conf_read(tc, TX39_TIMERCONTROL_REG);
128 /* Freeze RTC */
129 reg |= TX39_TIMERCONTROL_FREEZEPRE; /* Upper 8bit */
130 reg |= TX39_TIMERCONTROL_FREEZERTC; /* Lower 32bit */
131 /* Freeze periodic timer */
132 reg |= TX39_TIMERCONTROL_FREEZETIMER;
133 reg &= ~TX39_TIMERCONTROL_ENPERTIMER;
134 tx_conf_write(tc, TX39_TIMERCONTROL_REG, reg);
135 }
136
137 void
138 tx39timer_rtcreset(tc)
139 tx_chipset_tag_t tc;
140 {
141 txreg_t reg;
142
143 reg = tx_conf_read(tc, TX39_TIMERCONTROL_REG);
144 /* Reset counter and stop */
145 reg |= TX39_TIMERCONTROL_RTCCLR;
146 tx_conf_write(tc, TX39_TIMERCONTROL_REG, reg);
147 /* Count again */
148 reg &= ~TX39_TIMERCONTROL_RTCCLR;
149 tx_conf_write(tc, TX39_TIMERCONTROL_REG, reg);
150 }
151
152 void
153 clock_init(dev)
154 struct device *dev;
155 {
156 tx_chipset_tag_t tc;
157 txreg_t reg;
158
159 tc = tx_conf_get_tag();
160 /* Enable periodic timer */
161 reg = tx_conf_read(tc, TX39_INTRENABLE6_REG);
162 reg |= TX39_INTRPRI13_TIMER_PERIODIC_BIT;
163 tx_conf_write(tc, TX39_INTRENABLE6_REG, reg);
164
165 }
166
167 void
168 clock_get(dev, base, ct)
169 struct device *dev;
170 time_t base;
171 struct clocktime *ct;
172 {
173 tx_chipset_tag_t tc;
174 txreg_t reghi, reglo, oreghi, oreglo;
175 int i;
176
177 tc = tx_conf_get_tag();
178 i = 10;
179 do {
180 reghi = tx_conf_read(tc, TX39_TIMERRTCHI_REG);
181 reglo = tx_conf_read(tc, TX39_TIMERRTCLO_REG);
182 oreghi = tx_conf_read(tc, TX39_TIMERRTCHI_REG);
183 oreglo = tx_conf_read(tc, TX39_TIMERRTCLO_REG);
184 } while ((reghi != oreghi || reglo != oreglo) && (--i > 0));
185 if (i < 0) {
186 panic("RTC timer read error.\n");
187 }
188 /* XXX not coded yet */
189 }
190
191 void
192 clock_set(dev, ct)
193 struct device *dev;
194 struct clocktime *ct;
195 {
196 /* XXX not coded yet */
197 }
198
199 void
200 tx39clock_dump(tc)
201 tx_chipset_tag_t tc;
202 {
203 txreg_t reg;
204
205 reg = tx_conf_read(tc, TX39_CLOCKCTRL_REG);
206 printf(" ");
207 ISSETPRINT(reg, CHIM);
208 #ifdef TX391X
209 ISSETPRINT(reg, VID);
210 ISSETPRINT(reg, MBUS);
211 #endif /* TX391X */
212 #ifdef TX392X
213 ISSETPRINT(reg, IRDA);
214 #endif /* TX392X */
215 ISSETPRINT(reg, SPI);
216 ISSETPRINT(reg, TIMER);
217 ISSETPRINT(reg, FASTTIMER);
218 #ifdef TX392X
219 ISSETPRINT(reg, C48MOUT);
220 #endif /* TX392X */
221 ISSETPRINT(reg, SIBM);
222 ISSETPRINT(reg, CSER);
223 ISSETPRINT(reg, IR);
224 ISSETPRINT(reg, UARTA);
225 ISSETPRINT(reg, UARTB);
226 printf("\n");
227 }
228
229
230
231
232