tx39.c revision 1.12 1 1.12 uch /* $NetBSD: tx39.c,v 1.12 2000/01/16 21:47:00 uch Exp $ */
2 1.1 uch
3 1.1 uch /*
4 1.9 uch * Copyright (c) 1999, 2000, by UCHIYAMA Yasushi
5 1.1 uch * All rights reserved.
6 1.1 uch *
7 1.1 uch * Redistribution and use in source and binary forms, with or without
8 1.1 uch * modification, are permitted provided that the following conditions
9 1.1 uch * are met:
10 1.1 uch * 1. Redistributions of source code must retain the above copyright
11 1.1 uch * notice, this list of conditions and the following disclaimer.
12 1.1 uch * 2. The name of the developer may NOT be used to endorse or promote products
13 1.1 uch * derived from this software without specific prior written permission.
14 1.1 uch *
15 1.1 uch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 1.1 uch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 1.1 uch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 1.1 uch * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 1.1 uch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 1.1 uch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 1.1 uch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 1.1 uch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 1.1 uch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 1.1 uch * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 1.1 uch * SUCH DAMAGE.
26 1.1 uch *
27 1.1 uch */
28 1.1 uch
29 1.1 uch #include "opt_tx39_debug.h"
30 1.5 uch #include "m38813c.h"
31 1.6 uch #include "tc5165buf.h"
32 1.1 uch
33 1.1 uch #include <sys/param.h>
34 1.1 uch #include <sys/systm.h>
35 1.1 uch #include <sys/device.h>
36 1.1 uch
37 1.1 uch #include <machine/locore.h> /* cpu_id */
38 1.1 uch #include <machine/bootinfo.h> /* bootinfo */
39 1.1 uch #include <machine/sysconf.h> /* platform */
40 1.1 uch
41 1.6 uch #include <machine/platid.h>
42 1.6 uch #include <machine/platid_mask.h>
43 1.6 uch
44 1.1 uch #include <machine/bus.h>
45 1.1 uch #include <machine/intr.h>
46 1.1 uch
47 1.1 uch #include <hpcmips/hpcmips/machdep.h> /* cpu_model */
48 1.1 uch
49 1.1 uch #include <hpcmips/tx/tx39biureg.h>
50 1.1 uch #include <hpcmips/tx/tx39reg.h>
51 1.1 uch #include <hpcmips/tx/tx39var.h>
52 1.1 uch #ifdef TX391X
53 1.1 uch #include <hpcmips/tx/tx3912videovar.h>
54 1.1 uch #endif
55 1.1 uch
56 1.1 uch #include <sys/termios.h>
57 1.1 uch #include <sys/ttydefaults.h>
58 1.1 uch #include <hpcmips/tx/tx39uartvar.h>
59 1.1 uch #ifndef CONSPEED
60 1.1 uch #define CONSPEED TTYDEF_SPEED
61 1.1 uch #endif
62 1.1 uch
63 1.5 uch /* console keyboard */
64 1.5 uch #if NM38813C > 0
65 1.5 uch #include <hpcmips/dev/m38813cvar.h>
66 1.1 uch #endif
67 1.6 uch #if NTC5165BUF > 0
68 1.6 uch #include <hpcmips/dev/tc5165bufvar.h>
69 1.6 uch #endif
70 1.1 uch
71 1.1 uch extern unsigned nullclkread __P((void));
72 1.1 uch extern unsigned (*clkread) __P((void));
73 1.1 uch
74 1.1 uch struct tx_chipset_tag tx_chipset;
75 1.1 uch
76 1.1 uch #ifdef TX39_DEBUG
77 1.1 uch u_int32_t tx39debugflag;
78 1.1 uch #endif
79 1.1 uch
80 1.1 uch void tx_init __P((void));
81 1.1 uch int tx39icu_intr __P((u_int32_t, u_int32_t, u_int32_t, u_int32_t));
82 1.1 uch int tx39_find_dram __P((u_int32_t, u_int32_t));
83 1.8 uch void tx39clock_cpuspeed __P((int*, int*));
84 1.1 uch
85 1.1 uch /* TX39-specific initialization vector */
86 1.1 uch void tx_os_init __P((void));
87 1.1 uch void tx_bus_reset __P((void));
88 1.1 uch void tx_cons_init __P((void));
89 1.1 uch void tx_device_register __P((struct device *, void *));
90 1.1 uch void tx_fb_init __P((caddr_t*));
91 1.1 uch int tx_mem_init __P((caddr_t));
92 1.2 takemura void tx_reboot __P((int howto, char *bootstr));
93 1.5 uch int tx_intr __P((u_int32_t mask, u_int32_t pc, u_int32_t statusReg,
94 1.5 uch u_int32_t causeReg));
95 1.1 uch
96 1.1 uch void
97 1.1 uch tx_init()
98 1.1 uch {
99 1.1 uch tx_chipset_tag_t tc;
100 1.1 uch int model, rev;
101 1.8 uch int cpuclock;
102 1.1 uch
103 1.1 uch tc = tx_conf_get_tag();
104 1.1 uch /*
105 1.1 uch * Platform Specific Function Hooks
106 1.1 uch */
107 1.1 uch platform.os_init = tx_os_init;
108 1.1 uch platform.bus_reset = tx_bus_reset;
109 1.1 uch platform.cons_init = tx_cons_init;
110 1.1 uch platform.device_register = tx_device_register;
111 1.1 uch platform.fb_init = tx_fb_init;
112 1.1 uch platform.mem_init = tx_mem_init;
113 1.2 takemura platform.reboot = tx_reboot;
114 1.1 uch
115 1.1 uch model = (cpu_id.cpu.cp_majrev << 4)| cpu_id.cpu.cp_minrev;
116 1.1 uch
117 1.1 uch switch (model) {
118 1.1 uch default:
119 1.1 uch /* Unknown TOSHIBA TX39-series */
120 1.1 uch sprintf(cpu_model, "Unknown TOSHIBA TX39-series %x.%x",
121 1.1 uch cpu_id.cpu.cp_majrev, cpu_id.cpu.cp_minrev);
122 1.1 uch break;
123 1.1 uch case TMPR3912:
124 1.8 uch tx39clock_cpuspeed(&cpuclock, &cpuspeed);
125 1.8 uch
126 1.8 uch sprintf(cpu_model, "TOSHIBA TMPR3912 %d.%02d MHz",
127 1.8 uch cpuclock / 1000000, (cpuclock % 1000000) / 10000);
128 1.1 uch break;
129 1.1 uch case TMPR3922:
130 1.8 uch tx39clock_cpuspeed(&cpuclock, &cpuspeed);
131 1.1 uch rev = tx_conf_read(tc, TX3922_REVISION_REG);
132 1.8 uch
133 1.8 uch sprintf(cpu_model, "TOSHIBA TMPR3922 rev. %x.%x "
134 1.8 uch "%d.%02d MHz", (rev >> 4) & 0xf, rev & 0xf,
135 1.8 uch cpuclock / 1000000, (cpuclock % 1000000) / 10000);
136 1.1 uch break;
137 1.1 uch }
138 1.1 uch }
139 1.1 uch
140 1.1 uch void
141 1.1 uch tx_os_init()
142 1.1 uch {
143 1.1 uch /*
144 1.1 uch * Set up interrupt handling and I/O addresses.
145 1.1 uch */
146 1.1 uch mips_hardware_intr = tx39icu_intr;
147 1.1 uch
148 1.1 uch splvec.splbio = MIPS_SPL_2_4;
149 1.1 uch splvec.splnet = MIPS_SPL_2_4;
150 1.1 uch splvec.spltty = MIPS_SPL_2_4;
151 1.1 uch splvec.splimp = MIPS_SPL_2_4;
152 1.1 uch splvec.splclock = MIPS_SPL_2_4;
153 1.1 uch splvec.splstatclock = MIPS_SPL_2_4;
154 1.1 uch
155 1.1 uch /* no high resolution timer circuit; possibly never called */
156 1.1 uch clkread = nullclkread;
157 1.1 uch }
158 1.1 uch
159 1.1 uch void
160 1.1 uch tx_fb_init(kernend)
161 1.1 uch caddr_t *kernend;
162 1.1 uch {
163 1.1 uch #ifdef TX391X
164 1.1 uch tx_chipset_tag_t tc;
165 1.1 uch u_int32_t fb_start, fb_addr, fb_size, fb_line_bytes;
166 1.1 uch
167 1.1 uch /* Initialize to access TX39 configuration register */
168 1.1 uch tc = tx_conf_get_tag();
169 1.1 uch
170 1.1 uch fb_start = MIPS_KSEG0_TO_PHYS(*kernend);
171 1.1 uch tx3912video_init(tc, fb_start, bootinfo->fb_width,
172 1.1 uch bootinfo->fb_height, &fb_addr, &fb_size,
173 1.1 uch &fb_line_bytes);
174 1.1 uch
175 1.7 uch /* Setup bootinfo */
176 1.1 uch bootinfo->fb_line_bytes = fb_line_bytes;
177 1.1 uch bootinfo->fb_addr = (unsigned char*)MIPS_PHYS_TO_KSEG1(fb_addr);
178 1.1 uch
179 1.1 uch /* Skip V-RAM area */
180 1.1 uch *kernend += fb_size;
181 1.1 uch #endif /* TX391X */
182 1.1 uch #ifdef TX392X
183 1.1 uch /*
184 1.1 uch * Plum V-RAM isn't accessible until pmap_bootstrap,
185 1.7 uch * at this time, frame buffer device is disabled.
186 1.1 uch */
187 1.1 uch bootinfo->fb_addr = 0;
188 1.1 uch #endif /* TX392X */
189 1.1 uch }
190 1.1 uch
191 1.1 uch int
192 1.1 uch tx_mem_init(kernend)
193 1.1 uch caddr_t kernend; /* kseg0 */
194 1.1 uch {
195 1.1 uch u_int32_t startaddr, endaddr;
196 1.1 uch int npage, xpage, kpage;
197 1.1 uch
198 1.1 uch startaddr = MIPS_PHYS_TO_KSEG1(
199 1.1 uch (btoc((u_int32_t)kernend - MIPS_KSEG0_START)) << PGSHIFT);
200 1.1 uch endaddr = MIPS_PHYS_TO_KSEG1(TX39_SYSADDR_DRAMBANK0CS1 +
201 1.1 uch TX39_SYSADDR_DRAMBANK_LEN);
202 1.1 uch kpage = btoc(MIPS_KSEG1_TO_PHYS(startaddr));
203 1.5 uch
204 1.1 uch /* D-RAM bank0 */
205 1.1 uch npage = tx39_find_dram(startaddr, endaddr);
206 1.1 uch
207 1.5 uch printf("DRAM bank0: %d pages (%dMByte) reserved %d pages\n",
208 1.5 uch npage + 1, ((npage + 1) * NBPG) / 0x100000, kpage + 1);
209 1.1 uch npage -= kpage; /* exclude kernel area */
210 1.5 uch
211 1.1 uch /* Clear DRAM area */
212 1.1 uch memset((void*)startaddr, 0, npage * NBPG);
213 1.1 uch
214 1.1 uch /* D-RAM bank1 XXX find only. not usable yet */
215 1.1 uch startaddr = MIPS_PHYS_TO_KSEG1(TX39_SYSADDR_DRAMBANK1CS1);
216 1.1 uch endaddr = MIPS_PHYS_TO_KSEG1(TX39_SYSADDR_DRAMBANK1CS1 +
217 1.1 uch TX39_SYSADDR_DRAMBANK_LEN);
218 1.1 uch xpage = tx39_find_dram(startaddr, endaddr);
219 1.1 uch printf("DRAM bank1: %d pages (%dMByte) ...but not usable yet\n",
220 1.1 uch xpage + 1, ((xpage + 1) * NBPG) / 0x100000);
221 1.1 uch
222 1.5 uch /*
223 1.5 uch * Clear currently unused D-RAM area
224 1.5 uch * (For reboot Windows CE clearly)
225 1.5 uch */
226 1.1 uch memset((void*)startaddr, 0, npage * NBPG);
227 1.5 uch memset((void*)(KERNBASE + 0x400), 0,
228 1.5 uch KERNTEXTOFF - KERNBASE - 0x800);
229 1.1 uch
230 1.1 uch return npage; /* Return bank0's memory only */
231 1.2 takemura }
232 1.2 takemura
233 1.2 takemura void
234 1.2 takemura tx_reboot(howto, bootstr)
235 1.2 takemura int howto;
236 1.2 takemura char *bootstr;
237 1.2 takemura {
238 1.2 takemura goto *(u_int32_t *)MIPS_RESET_EXC_VEC;
239 1.1 uch }
240 1.1 uch
241 1.1 uch int
242 1.1 uch tx39_find_dram(startaddr, endaddr)
243 1.1 uch u_int32_t startaddr; /* kseg1 */
244 1.1 uch u_int32_t endaddr; /* kseg1 */
245 1.1 uch {
246 1.1 uch #define DRAM_MAGIC0 0xac1dcafe
247 1.1 uch #define DRAM_MAGIC1 0x19700220
248 1.1 uch u_int32_t page;
249 1.1 uch int npage;
250 1.1 uch
251 1.1 uch page = startaddr;
252 1.1 uch ((volatile int *)page)[0] = DRAM_MAGIC0;
253 1.1 uch ((volatile int *)page)[4] = DRAM_MAGIC1;
254 1.1 uch page += NBPG;
255 1.1 uch for (npage = 0; page < endaddr; page += NBPG, npage++) {
256 1.1 uch if ((((volatile int *)page)[0] == DRAM_MAGIC0 &&
257 1.1 uch ((volatile int *)page)[4] == DRAM_MAGIC1)) {
258 1.1 uch return npage;
259 1.1 uch }
260 1.1 uch }
261 1.1 uch /* no memory in this bank */
262 1.1 uch return 0;
263 1.1 uch }
264 1.1 uch
265 1.1 uch void
266 1.1 uch tx_bus_reset()
267 1.1 uch {
268 1.1 uch /* hpcmips port don't use */
269 1.1 uch }
270 1.1 uch
271 1.1 uch void
272 1.1 uch tx_cons_init()
273 1.1 uch {
274 1.1 uch int slot;
275 1.6 uch #define CONSPLATIDMATCH(p) \
276 1.6 uch platid_match(&platid, &platid_mask_MACH_##p)
277 1.1 uch
278 1.1 uch #ifdef SERIALCONSSLOT
279 1.1 uch slot = SERIALCONSSLOT;
280 1.1 uch #else
281 1.1 uch slot = TX39_UARTA;
282 1.1 uch #endif
283 1.1 uch if (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) {
284 1.1 uch if(txcom_cnattach(slot, CONSPEED,
285 1.5 uch (TTYDEF_CFLAG & ~(CSIZE | PARENB)) |
286 1.5 uch CS8)) {
287 1.1 uch panic("tx_cons_init: can't attach serial console.");
288 1.1 uch }
289 1.5 uch } else {
290 1.6 uch #if NM38813C > 0
291 1.6 uch if(CONSPLATIDMATCH(VICTOR_INTERLINK) &&
292 1.6 uch m38813c_cnattach(TX39_SYSADDR_CARD1)) {
293 1.10 uch goto panic;
294 1.6 uch }
295 1.6 uch #endif
296 1.6 uch #if NTC5165BUF > 0
297 1.10 uch if(CONSPLATIDMATCH(COMPAQ_C) &&
298 1.10 uch tc5165buf_cnattach(TX39_SYSADDR_CS3)) {
299 1.10 uch goto panic;
300 1.10 uch }
301 1.10 uch
302 1.6 uch if(CONSPLATIDMATCH(SHARP_TELIOS) &&
303 1.6 uch tc5165buf_cnattach(TX39_SYSADDR_CS1)) {
304 1.10 uch goto panic;
305 1.10 uch }
306 1.10 uch
307 1.10 uch if(CONSPLATIDMATCH(SHARP_MOBILON) &&
308 1.10 uch tc5165buf_cnattach(TX39_SYSADDR_MCS0)) {
309 1.10 uch goto panic;
310 1.5 uch }
311 1.5 uch #endif
312 1.1 uch }
313 1.10 uch
314 1.10 uch return;
315 1.10 uch panic:
316 1.10 uch panic("tx_cons_init: can't init console");
317 1.10 uch /* NOTREACHED */
318 1.1 uch }
319 1.1 uch
320 1.1 uch void
321 1.1 uch tx_device_register(dev, aux)
322 1.1 uch struct device *dev;
323 1.1 uch void *aux;
324 1.1 uch {
325 1.1 uch /* hpcmips port don't use */
326 1.1 uch }
327 1.1 uch
328 1.1 uch void
329 1.1 uch tx_conf_register_intr(t, intrt)
330 1.1 uch tx_chipset_tag_t t;
331 1.1 uch void *intrt;
332 1.1 uch {
333 1.1 uch if (tx_chipset.tc_intrt) {
334 1.1 uch panic("duplicate intrt");
335 1.1 uch }
336 1.1 uch
337 1.1 uch if (t != &tx_chipset) {
338 1.1 uch panic("bogus tx_chipset_tag");
339 1.1 uch }
340 1.1 uch
341 1.1 uch tx_chipset.tc_intrt = intrt;
342 1.1 uch }
343 1.1 uch
344 1.9 uch void
345 1.9 uch tx_conf_register_power(t, powert)
346 1.9 uch tx_chipset_tag_t t;
347 1.9 uch void *powert;
348 1.9 uch {
349 1.9 uch if (tx_chipset.tc_powert) {
350 1.9 uch panic("duplicate powert");
351 1.9 uch }
352 1.9 uch
353 1.9 uch if (t != &tx_chipset) {
354 1.9 uch panic("bogus tx_chipset_tag");
355 1.9 uch }
356 1.9 uch
357 1.9 uch tx_chipset.tc_powert = powert;
358 1.9 uch }
359 1.9 uch
360 1.9 uch void
361 1.9 uch tx_conf_register_clock(t, clockt)
362 1.9 uch tx_chipset_tag_t t;
363 1.9 uch void *clockt;
364 1.9 uch {
365 1.9 uch if (tx_chipset.tc_clockt) {
366 1.9 uch panic("duplicate clockt");
367 1.9 uch }
368 1.9 uch
369 1.9 uch if (t != &tx_chipset) {
370 1.9 uch panic("bogus tx_chipset_tag");
371 1.9 uch }
372 1.9 uch
373 1.9 uch tx_chipset.tc_clockt = clockt;
374 1.11 uch }
375 1.11 uch
376 1.11 uch void
377 1.11 uch tx_conf_register_sound(t, soundt)
378 1.11 uch tx_chipset_tag_t t;
379 1.11 uch void *soundt;
380 1.11 uch {
381 1.11 uch if (t != &tx_chipset) {
382 1.11 uch panic("bogus tx_chipset_tag");
383 1.11 uch }
384 1.11 uch
385 1.11 uch tx_chipset.tc_soundt = soundt;
386 1.12 uch }
387 1.12 uch
388 1.12 uch void
389 1.12 uch tx_conf_register_ioman(t, iomant)
390 1.12 uch tx_chipset_tag_t t;
391 1.12 uch void *iomant;
392 1.12 uch {
393 1.12 uch if (tx_chipset.tc_iomant) {
394 1.12 uch panic("duplicate iomant");
395 1.12 uch }
396 1.12 uch
397 1.12 uch if (t != &tx_chipset) {
398 1.12 uch panic("bogus tx_chipset_tag");
399 1.12 uch }
400 1.12 uch
401 1.12 uch tx_chipset.tc_iomant = iomant;
402 1.9 uch }
403 1.9 uch
404 1.1 uch #ifdef TX39_PREFER_FUNCTION
405 1.1 uch tx_chipset_tag_t
406 1.1 uch tx_conf_get_tag()
407 1.1 uch {
408 1.1 uch return (tx_chipset_tag_t)&tx_chipset;
409 1.1 uch }
410 1.1 uch
411 1.1 uch txreg_t
412 1.1 uch tx_conf_read(t, reg)
413 1.1 uch tx_chipset_tag_t t;
414 1.1 uch int reg;
415 1.1 uch {
416 1.8 uch return *((volatile txreg_t*)(TX39_SYSADDR_CONFIG_REG_KSEG1 + reg));
417 1.1 uch }
418 1.1 uch
419 1.1 uch void
420 1.1 uch tx_conf_write(t, reg, val)
421 1.1 uch tx_chipset_tag_t t;
422 1.1 uch int reg;
423 1.1 uch txreg_t val;
424 1.1 uch {
425 1.8 uch *((volatile txreg_t*)(TX39_SYSADDR_CONFIG_REG_KSEG1 + reg)) = val;
426 1.1 uch }
427 1.1 uch #endif /* TX39_PREFER_FUNCTION */
428 1.1 uch
429 1.1 uch int
430 1.1 uch __is_set_print(reg, mask, name)
431 1.1 uch u_int32_t reg;
432 1.1 uch int mask;
433 1.1 uch char *name;
434 1.1 uch {
435 1.9 uch const char onoff[2] = "_x";
436 1.9 uch int ret = reg & mask ? 1 : 0;
437 1.9 uch
438 1.9 uch printf("%s[%c] ", name, onoff[ret]);
439 1.9 uch
440 1.9 uch return ret;
441 1.1 uch }
442