1 1.45 christos /* $NetBSD: tx39.c,v 1.45 2014/03/26 17:53:36 christos Exp $ */ 2 1.1 uch 3 1.17 uch /*- 4 1.20 uch * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. 5 1.20 uch * All rights reserved. 6 1.20 uch * 7 1.20 uch * This code is derived from software contributed to The NetBSD Foundation 8 1.20 uch * by UCHIYAMA Yasushi. 9 1.1 uch * 10 1.1 uch * Redistribution and use in source and binary forms, with or without 11 1.1 uch * modification, are permitted provided that the following conditions 12 1.1 uch * are met: 13 1.1 uch * 1. Redistributions of source code must retain the above copyright 14 1.1 uch * notice, this list of conditions and the following disclaimer. 15 1.16 uch * 2. Redistributions in binary form must reproduce the above copyright 16 1.16 uch * notice, this list of conditions and the following disclaimer in the 17 1.16 uch * documentation and/or other materials provided with the distribution. 18 1.1 uch * 19 1.20 uch * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.20 uch * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.20 uch * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.20 uch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.20 uch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.20 uch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.20 uch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.20 uch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.20 uch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.20 uch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.20 uch * POSSIBILITY OF SUCH DAMAGE. 30 1.1 uch */ 31 1.33 lukem 32 1.33 lukem #include <sys/cdefs.h> 33 1.45 christos __KERNEL_RCSID(0, "$NetBSD: tx39.c,v 1.45 2014/03/26 17:53:36 christos Exp $"); 34 1.1 uch 35 1.27 uch #include "opt_vr41xx.h" 36 1.27 uch #include "opt_tx39xx.h" 37 1.5 uch #include "m38813c.h" 38 1.6 uch #include "tc5165buf.h" 39 1.1 uch 40 1.1 uch #include <sys/param.h> 41 1.1 uch #include <sys/systm.h> 42 1.42 matt #include <sys/intr.h> 43 1.1 uch 44 1.32 thorpej #include <uvm/uvm_extern.h> 45 1.32 thorpej 46 1.28 uch #include <mips/cache.h> 47 1.43 tsutsui #include <mips/locore.h> 48 1.28 uch 49 1.1 uch #include <machine/bootinfo.h> /* bootinfo */ 50 1.1 uch #include <machine/sysconf.h> /* platform */ 51 1.1 uch 52 1.6 uch #include <machine/platid.h> 53 1.6 uch #include <machine/platid_mask.h> 54 1.6 uch 55 1.1 uch #include <machine/bus.h> 56 1.1 uch 57 1.1 uch #include <hpcmips/tx/tx39biureg.h> 58 1.1 uch #include <hpcmips/tx/tx39reg.h> 59 1.1 uch #include <hpcmips/tx/tx39var.h> 60 1.1 uch #ifdef TX391X 61 1.1 uch #include <hpcmips/tx/tx3912videovar.h> 62 1.1 uch #endif 63 1.1 uch 64 1.1 uch #include <sys/termios.h> 65 1.1 uch #include <sys/ttydefaults.h> 66 1.1 uch #include <hpcmips/tx/tx39uartvar.h> 67 1.1 uch #ifndef CONSPEED 68 1.1 uch #define CONSPEED TTYDEF_SPEED 69 1.1 uch #endif 70 1.1 uch 71 1.5 uch /* console keyboard */ 72 1.5 uch #if NM38813C > 0 73 1.5 uch #include <hpcmips/dev/m38813cvar.h> 74 1.1 uch #endif 75 1.6 uch #if NTC5165BUF > 0 76 1.6 uch #include <hpcmips/dev/tc5165bufvar.h> 77 1.6 uch #endif 78 1.1 uch 79 1.1 uch struct tx_chipset_tag tx_chipset; 80 1.1 uch 81 1.20 uch void tx_init(void); 82 1.27 uch #if defined(VR41XX) && defined(TX39XX) 83 1.27 uch #define TX_INTR tx_intr 84 1.27 uch #else 85 1.27 uch #define TX_INTR cpu_intr /* locore_mips3 directly call this */ 86 1.27 uch #endif 87 1.27 uch 88 1.42 matt extern void TX_INTR(int, vaddr_t, uint32_t); 89 1.27 uch 90 1.26 uch void tx39clock_cpuspeed(int *, int *); 91 1.1 uch 92 1.1 uch /* TX39-specific initialization vector */ 93 1.20 uch void tx_cons_init(void); 94 1.36 christos void tx_fb_init(void **); 95 1.20 uch void tx_mem_init(paddr_t); 96 1.20 uch void tx_find_dram(paddr_t, paddr_t); 97 1.20 uch void tx_reboot(int, char *); 98 1.1 uch 99 1.1 uch void 100 1.40 cegger tx_init(void) 101 1.1 uch { 102 1.1 uch tx_chipset_tag_t tc; 103 1.1 uch int model, rev; 104 1.8 uch int cpuclock; 105 1.1 uch 106 1.1 uch tc = tx_conf_get_tag(); 107 1.1 uch /* 108 1.1 uch * Platform Specific Function Hooks 109 1.1 uch */ 110 1.27 uch platform.cpu_intr = TX_INTR; 111 1.25 uch platform.cpu_idle = NULL; /* not implemented yet */ 112 1.25 uch platform.cons_init = tx_cons_init; 113 1.25 uch platform.fb_init = tx_fb_init; 114 1.25 uch platform.mem_init = tx_mem_init; 115 1.25 uch platform.reboot = tx_reboot; 116 1.27 uch 117 1.1 uch 118 1.42 matt model = MIPS_PRID_REV(mips_options.mips_cpu_id); 119 1.1 uch 120 1.1 uch switch (model) { 121 1.1 uch default: 122 1.23 uch /* Unknown TOSHIBA TX39-series */ 123 1.45 christos cpuname_printf("Unknown TOSHIBA TX39-series %x", model); 124 1.1 uch break; 125 1.1 uch case TMPR3912: 126 1.8 uch tx39clock_cpuspeed(&cpuclock, &cpuspeed); 127 1.8 uch 128 1.45 christos cpuname_printf("TOSHIBA TMPR3912 %d.%02d MHz", 129 1.23 uch cpuclock / 1000000, (cpuclock % 1000000) / 10000); 130 1.20 uch tc->tc_chipset = __TX391X; 131 1.1 uch break; 132 1.1 uch case TMPR3922: 133 1.8 uch tx39clock_cpuspeed(&cpuclock, &cpuspeed); 134 1.1 uch rev = tx_conf_read(tc, TX3922_REVISION_REG); 135 1.8 uch 136 1.45 christos cpuname_printf("TOSHIBA TMPR3922 rev. %x.%x " 137 1.23 uch "%d.%02d MHz", (rev >> 4) & 0xf, rev & 0xf, 138 1.23 uch cpuclock / 1000000, (cpuclock % 1000000) / 10000); 139 1.20 uch tc->tc_chipset = __TX392X; 140 1.1 uch break; 141 1.1 uch } 142 1.1 uch } 143 1.1 uch 144 1.1 uch void 145 1.36 christos tx_fb_init(void **kernend) 146 1.1 uch { 147 1.1 uch #ifdef TX391X 148 1.16 uch paddr_t fb_end; 149 1.1 uch 150 1.16 uch fb_end = MIPS_KSEG0_TO_PHYS(mem_clusters[0].start + 151 1.23 uch mem_clusters[0].size - 1); 152 1.16 uch tx3912video_init(MIPS_KSEG0_TO_PHYS(*kernend), &fb_end); 153 1.16 uch 154 1.1 uch /* Skip V-RAM area */ 155 1.36 christos *kernend = (void *)MIPS_PHYS_TO_KSEG0(fb_end); 156 1.1 uch #endif /* TX391X */ 157 1.1 uch #ifdef TX392X 158 1.1 uch /* 159 1.1 uch * Plum V-RAM isn't accessible until pmap_bootstrap, 160 1.7 uch * at this time, frame buffer device is disabled. 161 1.1 uch */ 162 1.1 uch bootinfo->fb_addr = 0; 163 1.1 uch #endif /* TX392X */ 164 1.1 uch } 165 1.1 uch 166 1.14 shin void 167 1.26 uch tx_mem_init(paddr_t kernend) 168 1.1 uch { 169 1.26 uch 170 1.14 shin mem_clusters[0].start = 0; 171 1.14 shin mem_clusters[0].size = kernend; 172 1.14 shin mem_cluster_cnt = 1; 173 1.14 shin /* search DRAM bank 0 */ 174 1.14 shin tx_find_dram(kernend, 0x02000000); 175 1.1 uch 176 1.14 shin /* search DRAM bank 1 */ 177 1.14 shin tx_find_dram(0x02000000, 0x04000000); 178 1.2 takemura } 179 1.2 takemura 180 1.2 takemura void 181 1.26 uch tx_find_dram(paddr_t start, paddr_t end) 182 1.2 takemura { 183 1.38 he char *page, *startaddr, *endaddr; 184 1.42 matt uint32_t magic0, magic1; 185 1.42 matt #define MAGIC0 (*(volatile uint32_t *)(page + 0)) 186 1.42 matt #define MAGIC1 (*(volatile uint32_t *)(page + 4)) 187 1.14 shin 188 1.38 he startaddr = (char *)MIPS_PHYS_TO_KSEG1(start); 189 1.38 he endaddr = (char *)MIPS_PHYS_TO_KSEG1(end); 190 1.1 uch 191 1.1 uch page = startaddr; 192 1.14 shin if (badaddr(page, 4)) 193 1.14 shin return; 194 1.14 shin 195 1.28 uch do { 196 1.28 uch magic0 = random(); 197 1.28 uch magic1 = random(); 198 1.28 uch } while (MAGIC0 == magic0 || MAGIC0 == magic1); 199 1.28 uch 200 1.28 uch MAGIC0 = magic0; 201 1.28 uch MAGIC1 = magic1; 202 1.14 shin wbflush(); 203 1.14 shin 204 1.28 uch if (MAGIC0 != magic0 || MAGIC1 != magic1) 205 1.14 shin return; 206 1.14 shin 207 1.32 thorpej for (page += PAGE_SIZE; page < endaddr; page += PAGE_SIZE) { 208 1.14 shin if (badaddr(page, 4)) 209 1.14 shin return; 210 1.28 uch if (MAGIC0 == magic0 && 211 1.28 uch MAGIC1 == magic1) { 212 1.17 uch goto memend_found; 213 1.1 uch } 214 1.1 uch } 215 1.14 shin 216 1.17 uch /* check for 32MByte memory */ 217 1.32 thorpej page -= PAGE_SIZE; 218 1.28 uch MAGIC0 = magic0; 219 1.28 uch MAGIC1 = magic1; 220 1.17 uch wbflush(); 221 1.28 uch if (MAGIC0 != magic0 || MAGIC1 != magic1) 222 1.17 uch return; /* no memory in this bank */ 223 1.17 uch 224 1.17 uch memend_found: 225 1.17 uch mem_clusters[mem_cluster_cnt].start = start; 226 1.17 uch mem_clusters[mem_cluster_cnt].size = page - startaddr; 227 1.29 uch 228 1.29 uch /* skip kernel area */ 229 1.29 uch if (mem_cluster_cnt == 1) 230 1.29 uch mem_clusters[mem_cluster_cnt].size -= start; 231 1.29 uch 232 1.17 uch mem_cluster_cnt++; 233 1.28 uch #undef MAGIC0 234 1.28 uch #undef MAGIC1 235 1.14 shin } 236 1.14 shin 237 1.14 shin void 238 1.26 uch tx_reboot(int howto, char *bootstr) 239 1.14 shin { 240 1.26 uch 241 1.42 matt goto *(uint32_t *)MIPS_RESET_EXC_VEC; 242 1.1 uch } 243 1.1 uch 244 1.1 uch void 245 1.40 cegger tx_cons_init(void) 246 1.1 uch { 247 1.1 uch int slot; 248 1.20 uch #define CONSPLATIDMATCH(p) \ 249 1.6 uch platid_match(&platid, &platid_mask_MACH_##p) 250 1.1 uch 251 1.1 uch #ifdef SERIALCONSSLOT 252 1.1 uch slot = SERIALCONSSLOT; 253 1.1 uch #else 254 1.1 uch slot = TX39_UARTA; 255 1.1 uch #endif 256 1.1 uch if (bootinfo->bi_cnuse & BI_CNUSE_SERIAL) { 257 1.23 uch if(txcom_cnattach(slot, CONSPEED, 258 1.23 uch (TTYDEF_CFLAG & ~(CSIZE | PARENB)) | CS8)) { 259 1.1 uch panic("tx_cons_init: can't attach serial console."); 260 1.1 uch } 261 1.5 uch } else { 262 1.6 uch #if NM38813C > 0 263 1.6 uch if(CONSPLATIDMATCH(VICTOR_INTERLINK) && 264 1.23 uch m38813c_cnattach(TX39_SYSADDR_CARD1)) { 265 1.10 uch goto panic; 266 1.6 uch } 267 1.6 uch #endif 268 1.6 uch #if NTC5165BUF > 0 269 1.10 uch if(CONSPLATIDMATCH(COMPAQ_C) && 270 1.23 uch tc5165buf_cnattach(TX39_SYSADDR_CS3)) { 271 1.10 uch goto panic; 272 1.10 uch } 273 1.10 uch 274 1.6 uch if(CONSPLATIDMATCH(SHARP_TELIOS) && 275 1.23 uch tc5165buf_cnattach(TX39_SYSADDR_CS1)) { 276 1.10 uch goto panic; 277 1.10 uch } 278 1.10 uch 279 1.10 uch if(CONSPLATIDMATCH(SHARP_MOBILON) && 280 1.23 uch tc5165buf_cnattach(TX39_SYSADDR_MCS0)) { 281 1.10 uch goto panic; 282 1.5 uch } 283 1.5 uch #endif 284 1.1 uch } 285 1.10 uch 286 1.10 uch return; 287 1.44 shattere #if (NM38813C > 0) || (NTC5165BUF > 0) 288 1.10 uch panic: 289 1.44 shattere #endif 290 1.10 uch panic("tx_cons_init: can't init console"); 291 1.10 uch /* NOTREACHED */ 292 1.1 uch } 293 1.1 uch 294 1.1 uch void 295 1.26 uch tx_conf_register_intr(tx_chipset_tag_t t, void *intrt) 296 1.1 uch { 297 1.26 uch 298 1.20 uch KASSERT(t == &tx_chipset); 299 1.1 uch tx_chipset.tc_intrt = intrt; 300 1.1 uch } 301 1.1 uch 302 1.9 uch void 303 1.26 uch tx_conf_register_power(tx_chipset_tag_t t, void *powert) 304 1.9 uch { 305 1.26 uch 306 1.20 uch KASSERT(t == &tx_chipset); 307 1.9 uch tx_chipset.tc_powert = powert; 308 1.9 uch } 309 1.9 uch 310 1.9 uch void 311 1.26 uch tx_conf_register_clock(tx_chipset_tag_t t, void *clockt) 312 1.9 uch { 313 1.26 uch 314 1.20 uch KASSERT(t == &tx_chipset); 315 1.9 uch tx_chipset.tc_clockt = clockt; 316 1.11 uch } 317 1.11 uch 318 1.11 uch void 319 1.26 uch tx_conf_register_sound(tx_chipset_tag_t t, void *soundt) 320 1.11 uch { 321 1.26 uch 322 1.20 uch KASSERT(t == &tx_chipset); 323 1.11 uch tx_chipset.tc_soundt = soundt; 324 1.18 uch } 325 1.18 uch 326 1.18 uch void 327 1.26 uch tx_conf_register_video(tx_chipset_tag_t t, void *videot) 328 1.18 uch { 329 1.26 uch 330 1.20 uch KASSERT(t == &tx_chipset); 331 1.18 uch tx_chipset.tc_videot = videot; 332 1.1 uch } 333