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