/* $NetBSD: tx39.c,v 1.1 1999/11/20 19:56:31 uch Exp $ */ /* * Copyright (c) 1999, by UCHIYAMA Yasushi * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. The name of the developer may NOT be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include "opt_tx39_debug.h" #include "fb.h" #include "cckbd.h" #include #include #include #include /* cpu_id */ #include /* bootinfo */ #include /* platform */ #include #include #include /* cpu_model */ #include #include #include #include #include #ifdef TX391X #include #endif #include #include #include #ifndef CONSPEED #define CONSPEED TTYDEF_SPEED #endif #if NFB > 0 #include #include #include #endif #if NCCKBD > 0 #include #endif extern unsigned nullclkread __P((void)); extern unsigned (*clkread) __P((void)); struct tx_chipset_tag tx_chipset; #ifdef TX39_DEBUG u_int32_t tx39debugflag; #endif void tx_init __P((void)); int tx39icu_intr __P((u_int32_t, u_int32_t, u_int32_t, u_int32_t)); int tx39_find_dram __P((u_int32_t, u_int32_t)); /* TX39-specific initialization vector */ void tx_os_init __P((void)); void tx_bus_reset __P((void)); void tx_cons_init __P((void)); void tx_device_register __P((struct device *, void *)); void tx_fb_init __P((caddr_t*)); int tx_mem_init __P((caddr_t)); int tx_intr __P((u_int32_t mask, u_int32_t pc, u_int32_t statusReg, u_int32_t causeReg)); void tx_init() { tx_chipset_tag_t tc; int model, rev; tc = tx_conf_get_tag(); /* * Platform Specific Function Hooks */ platform.os_init = tx_os_init; platform.bus_reset = tx_bus_reset; platform.cons_init = tx_cons_init; platform.device_register = tx_device_register; platform.fb_init = tx_fb_init; platform.mem_init = tx_mem_init; model = (cpu_id.cpu.cp_majrev << 4)| cpu_id.cpu.cp_minrev; switch (model) { default: /* Unknown TOSHIBA TX39-series */ sprintf(cpu_model, "Unknown TOSHIBA TX39-series %x.%x", cpu_id.cpu.cp_majrev, cpu_id.cpu.cp_minrev); break; case TMPR3912: sprintf(cpu_model, "TOSHIBA TMPR3912"); cpuspeed = 50; /* XXX Should calibrate XXX */ break; case TMPR3922: rev = tx_conf_read(tc, TX3922_REVISION_REG); sprintf(cpu_model, "TOSHIBA TMPR3922 rev. %x.%x", (rev >> 4) & 0xf, rev & 0xf); cpuspeed = 100; /* XXX Should calibrate XXX */ break; } } void tx_os_init() { /* * Set up interrupt handling and I/O addresses. */ mips_hardware_intr = tx39icu_intr; splvec.splbio = MIPS_SPL_2_4; splvec.splnet = MIPS_SPL_2_4; splvec.spltty = MIPS_SPL_2_4; splvec.splimp = MIPS_SPL_2_4; splvec.splclock = MIPS_SPL_2_4; splvec.splstatclock = MIPS_SPL_2_4; /* no high resolution timer circuit; possibly never called */ clkread = nullclkread; } void tx_fb_init(kernend) caddr_t *kernend; { #ifdef TX391X tx_chipset_tag_t tc; u_int32_t fb_start, fb_addr, fb_size, fb_line_bytes; /* Initialize to access TX39 configuration register */ tc = tx_conf_get_tag(); fb_start = MIPS_KSEG0_TO_PHYS(*kernend); tx3912video_init(tc, fb_start, bootinfo->fb_width, bootinfo->fb_height, &fb_addr, &fb_size, &fb_line_bytes); /* Set bootinfo for bicons */ bootinfo->fb_line_bytes = fb_line_bytes; bootinfo->fb_addr = (unsigned char*)MIPS_PHYS_TO_KSEG1(fb_addr); /* Skip V-RAM area */ *kernend += fb_size; #endif /* TX391X */ #ifdef TX392X /* * Plum V-RAM isn't accessible until pmap_bootstrap, * at this time, bicons is disabled. */ bootinfo->fb_addr = 0; #endif /* TX392X */ } int tx_mem_init(kernend) caddr_t kernend; /* kseg0 */ { u_int32_t startaddr, endaddr; int npage, xpage, kpage; startaddr = MIPS_PHYS_TO_KSEG1( (btoc((u_int32_t)kernend - MIPS_KSEG0_START)) << PGSHIFT); endaddr = MIPS_PHYS_TO_KSEG1(TX39_SYSADDR_DRAMBANK0CS1 + TX39_SYSADDR_DRAMBANK_LEN); kpage = btoc(MIPS_KSEG1_TO_PHYS(startaddr)); /* D-RAM bank0 */ npage = tx39_find_dram(startaddr, endaddr); printf("DRAM bank0: %d pages (%dMByte) reserved %d pages\n", npage + 1, ((npage + 1) * NBPG) / 0x100000, kpage + 1); npage -= kpage; /* exclude kernel area */ /* Clear DRAM area */ memset((void*)startaddr, 0, npage * NBPG); /* D-RAM bank1 XXX find only. not usable yet */ startaddr = MIPS_PHYS_TO_KSEG1(TX39_SYSADDR_DRAMBANK1CS1); endaddr = MIPS_PHYS_TO_KSEG1(TX39_SYSADDR_DRAMBANK1CS1 + TX39_SYSADDR_DRAMBANK_LEN); xpage = tx39_find_dram(startaddr, endaddr); printf("DRAM bank1: %d pages (%dMByte) ...but not usable yet\n", xpage + 1, ((xpage + 1) * NBPG) / 0x100000); /* Clear currently unused D-RAM area (For reboot Windows CE clearly)*/ memset((void*)startaddr, 0, npage * NBPG); memset((void*)(KERNBASE + 0x400), 0, KERNTEXTOFF - KERNBASE - 0x800); return npage; /* Return bank0's memory only */ } int tx39_find_dram(startaddr, endaddr) u_int32_t startaddr; /* kseg1 */ u_int32_t endaddr; /* kseg1 */ { #define DRAM_MAGIC0 0xac1dcafe #define DRAM_MAGIC1 0x19700220 u_int32_t page; int npage; page = startaddr; ((volatile int *)page)[0] = DRAM_MAGIC0; ((volatile int *)page)[4] = DRAM_MAGIC1; page += NBPG; for (npage = 0; page < endaddr; page += NBPG, npage++) { if ((((volatile int *)page)[0] == DRAM_MAGIC0 && ((volatile int *)page)[4] == DRAM_MAGIC1)) { return npage; } } /* no memory in this bank */ return 0; } void tx_bus_reset() { /* hpcmips port don't use */ } void tx_cons_init() { int slot; #ifdef SERIALCONSSLOT slot = SERIALCONSSLOT; #else slot = TX39_UARTA; #endif if (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) { if(txcom_cnattach(slot, CONSPEED, (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8)) { panic("tx_cons_init: can't attach serial console."); } } #if NFB > 0 if(fb_cnattach(0, 0, 0, 0)) { panic("tx_cons_init: can't init fb console"); } #endif #if NCCKBD > 0 if(cckbd_cnattach(0, 0)) { panic("tx_cons_init: can't init cckbd as console"); } #endif } void tx_device_register(dev, aux) struct device *dev; void *aux; { /* hpcmips port don't use */ } void tx_conf_register_intr(t, intrt) tx_chipset_tag_t t; void *intrt; { if (tx_chipset.tc_intrt) { panic("duplicate intrt"); } if (t != &tx_chipset) { panic("bogus tx_chipset_tag"); } tx_chipset.tc_intrt = intrt; } #ifdef TX39_PREFER_FUNCTION tx_chipset_tag_t tx_conf_get_tag() { return (tx_chipset_tag_t)&tx_chipset; } txreg_t tx_conf_read(t, reg) tx_chipset_tag_t t; int reg; { return *((txreg_t*)(TX39_SYSADDR_CONFIG_REG_KSEG1 + reg)); } void tx_conf_write(t, reg, val) tx_chipset_tag_t t; int reg; txreg_t val; { *((txreg_t*)(TX39_SYSADDR_CONFIG_REG_KSEG1 + reg)) = val; } #endif /* TX39_PREFER_FUNCTION */ int __is_set_print(reg, mask, name) u_int32_t reg; int mask; char *name; { if (reg & mask) { printf("%s ", name); return 1; } return 0; }