1 /* $NetBSD: gumstix_machdep.c,v 1.51 2016/03/31 14:33:17 kiyohara Exp $ */ 2 /* 3 * Copyright (C) 2005, 2006, 2007 WIDE Project and SOUM Corporation. 4 * All rights reserved. 5 * 6 * Written by Takashi Kiyohara and Susumu Miki for WIDE Project and SOUM 7 * Corporation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the project nor the name of SOUM Corporation 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT and SOUM CORPORATION ``AS IS'' 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT AND SOUM CORPORATION 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 /* 34 * Copyright (c) 2002, 2003, 2004, 2005 Genetec Corporation. 35 * All rights reserved. 36 * 37 * Written by Hiroyuki Bessho for Genetec Corporation. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 3. The name of Genetec Corporation may not be used to endorse or 48 * promote products derived from this software without specific prior 49 * written permission. 50 * 51 * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND 52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 53 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 54 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION 55 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 56 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 57 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 58 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 59 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 61 * POSSIBILITY OF SUCH DAMAGE. 62 * 63 * Machine dependent functions for kernel setup for Genetec G4250EBX 64 * evaluation board. 65 * 66 * Based on iq80310_machhdep.c 67 */ 68 /* 69 * Copyright (c) 2001 Wasabi Systems, Inc. 70 * All rights reserved. 71 * 72 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 73 * 74 * Redistribution and use in source and binary forms, with or without 75 * modification, are permitted provided that the following conditions 76 * are met: 77 * 1. Redistributions of source code must retain the above copyright 78 * notice, this list of conditions and the following disclaimer. 79 * 2. Redistributions in binary form must reproduce the above copyright 80 * notice, this list of conditions and the following disclaimer in the 81 * documentation and/or other materials provided with the distribution. 82 * 3. All advertising materials mentioning features or use of this software 83 * must display the following acknowledgement: 84 * This product includes software developed for the NetBSD Project by 85 * Wasabi Systems, Inc. 86 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 87 * or promote products derived from this software without specific prior 88 * written permission. 89 * 90 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 91 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 92 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 93 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 94 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 95 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 96 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 97 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 98 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 99 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 100 * POSSIBILITY OF SUCH DAMAGE. 101 */ 102 103 /* 104 * Copyright (c) 1997,1998 Mark Brinicombe. 105 * Copyright (c) 1997,1998 Causality Limited. 106 * All rights reserved. 107 * 108 * Redistribution and use in source and binary forms, with or without 109 * modification, are permitted provided that the following conditions 110 * are met: 111 * 1. Redistributions of source code must retain the above copyright 112 * notice, this list of conditions and the following disclaimer. 113 * 2. Redistributions in binary form must reproduce the above copyright 114 * notice, this list of conditions and the following disclaimer in the 115 * documentation and/or other materials provided with the distribution. 116 * 3. All advertising materials mentioning features or use of this software 117 * must display the following acknowledgement: 118 * This product includes software developed by Mark Brinicombe 119 * for the NetBSD Project. 120 * 4. The name of the company nor the name of the author may be used to 121 * endorse or promote products derived from this software without specific 122 * prior written permission. 123 * 124 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 125 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 126 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 127 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 128 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 129 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 130 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 131 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 132 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 133 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 134 * SUCH DAMAGE. 135 * 136 * Machine dependent functions for kernel setup for Intel IQ80310 evaluation 137 * boards using RedBoot firmware. 138 */ 139 140 #include "opt_evbarm_boardtype.h" 141 #include "opt_cputypes.h" 142 #include "opt_gumstix.h" 143 #ifdef OVERO 144 #include "opt_omap.h" 145 #include "prcm.h" 146 #endif 147 #include "opt_kgdb.h" 148 #include "opt_pmap_debug.h" 149 #include "opt_com.h" 150 151 #include <sys/param.h> 152 #include <sys/conf.h> 153 #include <sys/device.h> 154 #include <sys/exec.h> 155 #include <sys/kernel.h> 156 #include <sys/proc.h> 157 #include <sys/reboot.h> 158 #include <sys/systm.h> 159 #include <sys/termios.h> 160 #include <sys/bus.h> 161 #include <sys/cpu.h> 162 163 #include <uvm/uvm_extern.h> 164 165 #include <machine/autoconf.h> 166 #include <machine/bootconfig.h> 167 #include <arm/locore.h> 168 169 #include <arm/arm32/machdep.h> 170 #ifdef OVERO 171 #include <arm/omap/omap2_gpmcreg.h> 172 #include <arm/omap/omap2_obiovar.h> 173 #include <arm/omap/omap2_prcm.h> 174 #include <arm/omap/omap2_reg.h> 175 #include <arm/omap/omap_var.h> 176 #include <arm/omap/omap_com.h> 177 #endif 178 #include <arm/xscale/pxa2x0reg.h> 179 #include <arm/xscale/pxa2x0var.h> 180 #include <arm/xscale/pxa2x0_gpio.h> 181 #include <evbarm/gumstix/gumstixreg.h> 182 #include <evbarm/gumstix/gumstixvar.h> 183 184 #include <dev/cons.h> 185 186 #ifdef KGDB 187 #include <sys/kgdb.h> 188 #endif 189 190 /* 191 * The range 0xc1000000 - 0xcfffffff is available for kernel VM space 192 * Core-logic registers and I/O mappings occupy 0xfd000000 - 0xffffffff 193 */ 194 #ifndef KERNEL_VM_BASE 195 #define KERNEL_VM_BASE 0xc1000000 196 #endif 197 #define KERNEL_VM_SIZE 0x0f000000 198 199 BootConfig bootconfig; /* Boot config storage */ 200 static char bootargs[MAX_BOOT_STRING]; 201 const size_t bootargs_len = sizeof(bootargs) - 1; /* without nul */ 202 char *boot_args = NULL; 203 204 uint32_t system_serial_high; 205 uint32_t system_serial_low; 206 207 /* Prototypes */ 208 #if defined(GUMSTIX) 209 static void read_system_serial(void); 210 #elif defined(OVERO) 211 static void overo_reset(void); 212 static void find_cpu_clock(void); 213 #endif 214 static void process_kernel_args(int, char *[]); 215 static void process_kernel_args_liner(char *); 216 #ifdef KGDB 217 static void kgdb_port_init(void); 218 #endif 219 static void gumstix_device_register(device_t, void *); 220 221 bs_protos(bs_notimpl); 222 223 #include "com.h" 224 #if NCOM > 0 225 #include <dev/ic/comreg.h> 226 #include <dev/ic/comvar.h> 227 #endif 228 229 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 230 #include "lcd.h" 231 #endif 232 233 #ifndef CONSPEED 234 #define CONSPEED B115200 /* It's a setting of the default of u-boot */ 235 #endif 236 #ifndef CONMODE 237 #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */ 238 #endif 239 240 int comcnspeed = CONSPEED; 241 int comcnmode = CONMODE; 242 243 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 244 static char console[16]; 245 #endif 246 247 extern void gxio_config_pin(void); 248 extern void gxio_config_expansion(char *); 249 250 251 static inline pd_entry_t * 252 read_ttb(void) 253 { 254 long ttb; 255 256 __asm volatile("mrc p15, 0, %0, c2, c0, 0" : "=r" (ttb)); 257 258 return (pd_entry_t *)(ttb & ~((1<<14)-1)); 259 } 260 261 /* 262 * Static device mappings. These peripheral registers are mapped at 263 * fixed virtual addresses very early in initarm() so that we can use 264 * them while booting the kernel, and stay at the same address 265 * throughout whole kernel's life time. 266 * 267 * We use this table twice; once with bootstrap page table, and once 268 * with kernel's page table which we build up in initarm(). 269 * 270 * Since we map these registers into the bootstrap page table using 271 * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map 272 * registers segment-aligned and segment-rounded in order to avoid 273 * using the 2nd page tables. 274 */ 275 276 #define _A(a) ((a) & ~L1_S_OFFSET) 277 #define _S(s) (((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1)) 278 279 static const struct pmap_devmap gumstix_devmap[] = { 280 #if defined(GUMSTIX) 281 { 282 GUMSTIX_GPIO_VBASE, 283 _A(PXA2X0_GPIO_BASE), 284 _S(PXA250_GPIO_SIZE), 285 VM_PROT_READ | VM_PROT_WRITE, 286 PTE_NOCACHE, 287 }, 288 { 289 GUMSTIX_CLKMAN_VBASE, 290 _A(PXA2X0_CLKMAN_BASE), 291 _S(PXA2X0_CLKMAN_SIZE), 292 VM_PROT_READ | VM_PROT_WRITE, 293 PTE_NOCACHE, 294 }, 295 { 296 GUMSTIX_INTCTL_VBASE, 297 _A(PXA2X0_INTCTL_BASE), 298 _S(PXA2X0_INTCTL_SIZE), 299 VM_PROT_READ | VM_PROT_WRITE, 300 PTE_NOCACHE, 301 }, 302 { 303 GUMSTIX_FFUART_VBASE, 304 _A(PXA2X0_FFUART_BASE), 305 _S(4 * COM_NPORTS), 306 VM_PROT_READ | VM_PROT_WRITE, 307 PTE_NOCACHE, 308 }, 309 { 310 GUMSTIX_STUART_VBASE, 311 _A(PXA2X0_STUART_BASE), 312 _S(4 * COM_NPORTS), 313 VM_PROT_READ | VM_PROT_WRITE, 314 PTE_NOCACHE, 315 }, 316 { 317 GUMSTIX_BTUART_VBASE, 318 _A(PXA2X0_BTUART_BASE), 319 _S(4 * COM_NPORTS), 320 VM_PROT_READ | VM_PROT_WRITE, 321 PTE_NOCACHE, 322 }, 323 { 324 GUMSTIX_HWUART_VBASE, 325 _A(PXA2X0_HWUART_BASE), 326 _S(4 * COM_NPORTS), 327 VM_PROT_READ | VM_PROT_WRITE, 328 PTE_NOCACHE, 329 }, 330 { 331 GUMSTIX_LCDC_VBASE, 332 _A(PXA2X0_LCDC_BASE), 333 _S(4 * COM_NPORTS), 334 VM_PROT_READ | VM_PROT_WRITE, 335 PTE_NOCACHE, 336 }, 337 #elif defined(OVERO) 338 { 339 OVERO_L4_CORE_VBASE, 340 _A(OMAP3530_L4_CORE_BASE), 341 _S(L1_S_SIZE), /* No need 16MB. Use only first 1MB */ 342 VM_PROT_READ | VM_PROT_WRITE, 343 PTE_NOCACHE 344 }, 345 { 346 OVERO_L4_PERIPHERAL_VBASE, 347 _A(OMAP3530_L4_PERIPHERAL_BASE), 348 _S(OMAP3530_L4_PERIPHERAL_SIZE), 349 VM_PROT_READ | VM_PROT_WRITE, 350 PTE_NOCACHE 351 }, 352 { 353 OVERO_GPMC_VBASE, 354 _A(GPMC_BASE), 355 _S(GPMC_SIZE), 356 VM_PROT_READ | VM_PROT_WRITE, 357 PTE_NOCACHE 358 }, 359 #endif 360 { 0, 0, 0, 0, 0 } 361 }; 362 363 #undef _A 364 #undef _S 365 366 367 /* 368 * u_int initarm(...) 369 * 370 * Initial entry point on startup. This gets called before main() is 371 * entered. 372 * It should be responsible for setting up everything that must be 373 * in place when main is called. 374 * This includes 375 * Taking a copy of the boot configuration structure. 376 * Initialising the physical console so characters can be printed. 377 * Setting up page tables for the kernel 378 * Relocating the kernel to the bottom of physical memory 379 */ 380 u_int 381 initarm(void *arg) 382 { 383 extern char KERNEL_BASE_phys[]; 384 extern uint32_t *u_boot_args[]; 385 extern uint32_t ram_size; 386 enum { r0 = 0, r1 = 1, r2 = 2, r3 = 3 }; /* args from u-boot */ 387 388 /* 389 * We mapped PA == VA in gumstix_start.S. 390 * Also mapped SDRAM to KERNEL_BASE first 64Mbyte only with cachable. 391 * 392 * Gumstix (basix, connex, verdex, verdex-pro): 393 * Physical Address Range Description 394 * ----------------------- ---------------------------------- 395 * 0x00000000 - 0x00ffffff flash Memory (16MB or 4MB) 396 * 0x40000000 - 0x480fffff Processor Registers 397 * 0xa0000000 - 0xa3ffffff SDRAM Bank 0 (64MB or 128MB) 398 * 0xc0000000 - 0xc3ffffff KERNEL_BASE 399 * 400 * Overo: 401 * Physical Address Range Description 402 * ----------------------- ---------------------------------- 403 * 0x80000000 - 0x8fffffff SDRAM Bank 0 (256MB or 512MB) 404 * 0x80000000 - 0x83ffffff KERNEL_BASE 405 */ 406 407 #if defined(GUMSTIX) 408 cpu_reset_address = NULL; 409 #elif defined(OVERO) 410 cpu_reset_address = overo_reset; 411 412 find_cpu_clock(); // find our CPU speed. 413 #endif 414 415 /* 416 * Heads up ... Setup the CPU / MMU / TLB functions 417 */ 418 if (set_cpufuncs()) 419 panic("cpu not recognized!"); 420 421 /* map some peripheral registers at static I/O area */ 422 pmap_devmap_bootstrap((vaddr_t)read_ttb(), gumstix_devmap); 423 424 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 425 /* start 32.768kHz OSC */ 426 ioreg_write(GUMSTIX_CLKMAN_VBASE + CLKMAN_OSCC, OSCC_OON); 427 428 /* Get ready for splfoo() */ 429 pxa2x0_intr_bootstrap(GUMSTIX_INTCTL_VBASE); 430 431 /* setup GPIO for {FF,ST,HW}UART. */ 432 pxa2x0_gpio_bootstrap(GUMSTIX_GPIO_VBASE); 433 434 pxa2x0_clkman_bootstrap(GUMSTIX_CLKMAN_VBASE); 435 #elif defined(CPU_CORTEX) 436 cortex_pmc_ccnt_init(); 437 #endif 438 439 cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); 440 441 /* configure GPIOs. */ 442 gxio_config_pin(); 443 444 445 #ifndef GUMSTIX_NETBSD_ARGS_CONSOLE 446 consinit(); 447 #endif 448 #ifdef KGDB 449 kgdb_port_init(); 450 #endif 451 452 /* 453 * Examine the boot args string for options we need to know about 454 * now. 455 */ 456 #if defined(GUMSTIX) 457 #define SDRAM_START 0xa0000000UL 458 #elif defined(OVERO) 459 #define SDRAM_START 0x80000000UL 460 #endif 461 if (((uint32_t)u_boot_args[r0] & 0xf0000000) != SDRAM_START) 462 /* Maybe r0 is 'argc'. We are booted by command 'go'. */ 463 process_kernel_args((int)u_boot_args[r0], 464 (char **)u_boot_args[r1]); 465 else 466 /* 467 * Maybe r3 is 'boot args string' of 'bootm'. This string is 468 * linely. 469 */ 470 process_kernel_args_liner((char *)u_boot_args[r3]); 471 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 472 consinit(); 473 #endif 474 475 /* Talk to the user */ 476 #define BDSTR(s) _BDSTR(s) 477 #define _BDSTR(s) #s 478 printf("\nNetBSD/evbarm (" BDSTR(EVBARM_BOARDTYPE) ") booting ...\n"); 479 480 /* Read system serial */ 481 #if defined(GUMSTIX) 482 read_system_serial(); 483 #endif 484 485 #ifdef VERBOSE_INIT_ARM 486 printf("initarm: Configuring system ...\n"); 487 #endif 488 489 /* Fake bootconfig structure for the benefit of pmap.c */ 490 /* XXX must make the memory description h/w independent */ 491 bootconfig.dramblocks = 1; 492 bootconfig.dram[0].address = SDRAM_START; 493 bootconfig.dram[0].pages = ram_size / PAGE_SIZE; 494 495 KASSERT(ram_size <= KERNEL_VM_BASE - KERNEL_BASE); 496 497 arm32_bootmem_init(bootconfig.dram[0].address, ram_size, 498 (uintptr_t) KERNEL_BASE_phys); 499 arm32_kernel_vm_init(KERNEL_VM_BASE, 500 #if defined(CPU_XSCALE_PXA250) || defined(CPU_XSCALE_PXA270) 501 ARM_VECTORS_LOW, 502 #elif defined(CPU_CORTEXA8) 503 ARM_VECTORS_HIGH, 504 #endif 505 0, gumstix_devmap, true); 506 507 evbarm_device_register = gumstix_device_register; 508 509 return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0); 510 } 511 512 #if defined(GUMSTIX) 513 static void 514 read_system_serial(void) 515 { 516 #define GUMSTIX_SYSTEM_SERIAL_ADDR 0 517 #define GUMSTIX_SYSTEM_SERIAL_SIZE 8 518 #define FLASH_OFFSET_INTEL_PROTECTION 0x81 519 #define FLASH_OFFSET_USER_PROTECTION 0x85 520 #define FLASH_CMD_READ_ID 0x90 521 #define FLASH_CMD_RESET 0xff 522 int i; 523 char system_serial[GUMSTIX_SYSTEM_SERIAL_SIZE], *src; 524 char x; 525 526 src = (char *)(FLASH_OFFSET_USER_PROTECTION * 2 /*word*/); 527 *(volatile uint16_t *)0 = FLASH_CMD_READ_ID; 528 memcpy(system_serial, 529 src + GUMSTIX_SYSTEM_SERIAL_ADDR, sizeof (system_serial)); 530 *(volatile uint16_t *)0 = FLASH_CMD_RESET; 531 532 for (i = 1, x = system_serial[0]; i < sizeof (system_serial); i++) 533 x &= system_serial[i]; 534 if (x == 0xff) { 535 src = (char *)(FLASH_OFFSET_INTEL_PROTECTION * 2 /*word*/); 536 *(volatile uint16_t *)0 = FLASH_CMD_READ_ID; 537 memcpy(system_serial, 538 src + GUMSTIX_SYSTEM_SERIAL_ADDR, sizeof (system_serial)); 539 *(volatile uint16_t *)0 = FLASH_CMD_RESET; 540 541 /* 542 * XXXX: Don't need ??? 543 * gumstix_serial_hash(system_serial); 544 */ 545 } 546 system_serial_high = system_serial[0] << 24 | system_serial[1] << 16 | 547 system_serial[2] << 8 | system_serial[3]; 548 system_serial_low = system_serial[4] << 24 | system_serial[5] << 16 | 549 system_serial[6] << 8 | system_serial[7]; 550 551 printf("system serial: 0x"); 552 for (i = 0; i < sizeof (system_serial); i++) 553 printf("%02x", system_serial[i]); 554 printf("\n"); 555 } 556 557 #elif defined(OVERO) 558 559 static void 560 overo_reset(void) 561 { 562 563 #if NPRCM > 0 564 prcm_cold_reset(); 565 #endif 566 } 567 568 static void 569 find_cpu_clock(void) 570 { 571 const vaddr_t prm_base = OMAP2_PRM_BASE; 572 const vaddr_t cm_base = OMAP2_CM_BASE; 573 const uint32_t prm_clksel = 574 *(volatile uint32_t *)(prm_base + PLL_MOD + OMAP3_PRM_CLKSEL); 575 static const uint32_t prm_clksel_freqs[] = OMAP3_PRM_CLKSEL_FREQS; 576 const uint32_t sys_clk = 577 prm_clksel_freqs[__SHIFTOUT(prm_clksel, OMAP3_PRM_CLKSEL_CLKIN)]; 578 const uint32_t dpll1 = 579 *(volatile uint32_t *)(cm_base + OMAP3_CM_CLKSEL1_PLL_MPU); 580 const uint32_t dpll2 = 581 *(volatile uint32_t *)(cm_base + OMAP3_CM_CLKSEL2_PLL_MPU); 582 const uint32_t m = 583 __SHIFTOUT(dpll1, OMAP3_CM_CLKSEL1_PLL_MPU_DPLL_MULT); 584 const uint32_t n = __SHIFTOUT(dpll1, OMAP3_CM_CLKSEL1_PLL_MPU_DPLL_DIV); 585 const uint32_t m2 = 586 __SHIFTOUT(dpll2, OMAP3_CM_CLKSEL2_PLL_MPU_DPLL_CLKOUT_DIV); 587 588 /* 589 * MPU_CLK supplies ARM_FCLK which is twice the CPU frequency. 590 */ 591 curcpu()->ci_data.cpu_cc_freq = 592 ((sys_clk * m) / ((n + 1) * m2 * 2)) * OMAP3_PRM_CLKSEL_MULT; 593 omap_sys_clk = sys_clk * OMAP3_PRM_CLKSEL_MULT; 594 } 595 #endif 596 597 #ifdef GUMSTIX_NETBSD_ARGS_BUSHEADER 598 static const char busheader_name[] = "busheader="; 599 #endif 600 #if defined(GUMSTIX_NETBSD_ARGS_BUSHEADER) || \ 601 defined(GUMSTIX_NETBSD_ARGS_EXPANSION) 602 static const char expansion_name[] = "expansion="; 603 #endif 604 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 605 static const char console_name[] = "console="; 606 #endif 607 static void 608 process_kernel_args(int argc, char *argv[]) 609 { 610 int gxio_configured = 0, i, j; 611 612 boothowto = 0; 613 614 for (i = 1, j = 0; i < argc; i++) { 615 #ifdef GUMSTIX_NETBSD_ARGS_BUSHEADER 616 if (!strncmp(argv[i], busheader_name, strlen(busheader_name))) { 617 /* Configure for GPIOs of busheader side */ 618 gxio_config_expansion(argv[i] + strlen(busheader_name)); 619 gxio_configured = 1; 620 continue; 621 } 622 #endif 623 #if defined(GUMSTIX_NETBSD_ARGS_BUSHEADER) || \ 624 defined(GUMSTIX_NETBSD_ARGS_EXPANSION) 625 if (!strncmp(argv[i], expansion_name, strlen(expansion_name))) { 626 /* Configure expansion */ 627 gxio_config_expansion(argv[i] + strlen(expansion_name)); 628 gxio_configured = 1; 629 continue; 630 } 631 #endif 632 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 633 if (!strncmp(argv[i], console_name, strlen(console_name))) { 634 strncpy(console, argv[i] + strlen(console_name), 635 sizeof(console)); 636 consinit(); 637 } 638 #endif 639 if (j == bootargs_len) { 640 *(bootargs + j) = '\0'; 641 continue; 642 } 643 if (j != 0) 644 *(bootargs + j++) = ' '; 645 strncpy(bootargs + j, argv[i], bootargs_len - j); 646 bootargs[bootargs_len] = '\0'; 647 j += strlen(argv[i]); 648 } 649 boot_args = bootargs; 650 651 parse_mi_bootargs(boot_args); 652 653 if (!gxio_configured) 654 gxio_config_expansion(NULL); 655 } 656 657 static void 658 process_kernel_args_liner(char *args) 659 { 660 int i = 0; 661 char *p = NULL; 662 663 boothowto = 0; 664 665 strncpy(bootargs, args, sizeof(bootargs)); 666 #if defined(GUMSTIX_NETBSD_ARGS_BUSHEADER) || \ 667 defined(GUMSTIX_NETBSD_ARGS_EXPANSION) 668 { 669 char *q; 670 671 if ((p = strstr(bootargs, expansion_name))) 672 q = p + strlen(expansion_name); 673 #ifdef GUMSTIX_NETBSD_ARGS_BUSHEADER 674 else if ((p = strstr(bootargs, busheader_name))) 675 q = p + strlen(busheader_name); 676 #endif 677 if (p) { 678 char expansion[256], c; 679 680 i = 0; 681 do { 682 c = *(q + i); 683 if (c == ' ') 684 c = '\0'; 685 expansion[i++] = c; 686 } while (c != '\0' && i < sizeof(expansion)); 687 gxio_config_expansion(expansion); 688 strcpy(p, q + i); 689 } 690 } 691 #endif 692 if (p == NULL) 693 gxio_config_expansion(NULL); 694 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 695 p = strstr(bootargs, console_name); 696 if (p != NULL) { 697 char c; 698 699 i = 0; 700 do { 701 c = *(p + strlen(console_name) + i); 702 if (c == ' ') 703 c = '\0'; 704 console[i++] = c; 705 } while (c != '\0' && i < sizeof(console)); 706 consinit(); 707 strcpy(p, p + strlen(console_name) + i); 708 } 709 #endif 710 boot_args = bootargs; 711 712 parse_mi_bootargs(boot_args); 713 } 714 715 #ifdef KGDB 716 #ifndef KGDB_DEVNAME 717 #define KGDB_DEVNAME "ffuart" 718 #endif 719 const char kgdb_devname[] = KGDB_DEVNAME; 720 721 #ifndef KGDB_DEVRATE 722 #define KGDB_DEVRATE CONSPEED 723 #endif 724 int kgdb_devrate = KGDB_DEVRATE; 725 726 #if (NCOM > 0) 727 #ifndef KGDB_DEVMODE 728 #define KGDB_DEVMODE CONMODE 729 #endif 730 int comkgdbmode = KGDB_DEVMODE; 731 #endif /* NCOM */ 732 733 #endif /* KGDB */ 734 735 736 void 737 consinit(void) 738 { 739 static int consinit_called = 0; 740 741 if (consinit_called != 0) 742 return; 743 744 consinit_called = 1; 745 746 #if NCOM > 0 747 748 #ifdef GUMSTIX_NETBSD_ARGS_CONSOLE 749 /* Maybe passed Linux's bootargs 'console=ttyS?,<speed>...' */ 750 if (strncmp(console, "ttyS", 4) == 0 && console[5] == ',') { 751 int i; 752 753 comcnspeed = 0; 754 for (i = 6; i < strlen(console) && isdigit(console[i]); i++) 755 comcnspeed = comcnspeed * 10 + (console[i] - '0'); 756 } 757 #endif 758 759 #if defined(GUMSTIX) 760 761 #ifdef FFUARTCONSOLE 762 #ifdef KGDB 763 if (strcmp(kgdb_devname, "ffuart") == 0){ 764 /* port is reserved for kgdb */ 765 } else 766 #endif 767 #if defined(GUMSTIX_NETBSD_ARGS_CONSOLE) 768 if (console[0] == '\0' || strcasecmp(console, "ffuart") == 0 || 769 strncmp(console, "ttyS0,", 6) == 0) 770 #endif 771 { 772 int rv; 773 774 rv = comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_FFUART_BASE, 775 comcnspeed, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comcnmode); 776 if (rv == 0) { 777 pxa2x0_clkman_config(CKEN_FFUART, 1); 778 return; 779 } 780 } 781 #endif /* FFUARTCONSOLE */ 782 783 #ifdef STUARTCONSOLE 784 #ifdef KGDB 785 if (strcmp(kgdb_devname, "stuart") == 0) { 786 /* port is reserved for kgdb */ 787 } else 788 #endif 789 #if defined(GUMSTIX_NETBSD_ARGS_CONSOLE) 790 if (console[0] == '\0' || strcasecmp(console, "stuart") == 0) 791 #endif 792 { 793 int rv; 794 795 rv = comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_STUART_BASE, 796 comcnspeed, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comcnmode); 797 if (rv == 0) { 798 pxa2x0_clkman_config(CKEN_STUART, 1); 799 return; 800 } 801 } 802 #endif /* STUARTCONSOLE */ 803 804 #ifdef BTUARTCONSOLE 805 #ifdef KGDB 806 if (strcmp(kgdb_devname, "btuart") == 0) { 807 /* port is reserved for kgdb */ 808 } else 809 #endif 810 #if defined(GUMSTIX_NETBSD_ARGS_CONSOLE) 811 if (console[0] == '\0' || strcasecmp(console, "btuart") == 0) 812 #endif 813 { 814 int rv; 815 816 rv = comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_BTUART_BASE, 817 comcnspeed, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comcnmode); 818 if (rv == 0) { 819 pxa2x0_clkman_config(CKEN_BTUART, 1); 820 return; 821 } 822 } 823 #endif /* BTUARTCONSOLE */ 824 825 #ifdef HWUARTCONSOLE 826 #ifdef KGDB 827 if (strcmp(kgdb_devname, "hwuart") == 0) { 828 /* port is reserved for kgdb */ 829 } else 830 #endif 831 #if defined(GUMSTIX_NETBSD_ARGS_CONSOLE) 832 if (console[0] == '\0' || strcasecmp(console, "hwuart") == 0) 833 #endif 834 { 835 rv = comcnattach(&pxa2x0_a4x_bs_tag, PXA2X0_HWUART_BASE, 836 comcnspeed, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comcnmode); 837 if (rv == 0) { 838 pxa2x0_clkman_config(CKEN_HWUART, 1); 839 return; 840 } 841 } 842 #endif /* HWUARTCONSOLE */ 843 844 #elif defined(OVERO) 845 846 if (comcnattach(&omap_a4x_bs_tag, 0x49020000, comcnspeed, 847 OMAP_COM_FREQ, COM_TYPE_NORMAL, comcnmode) == 0) 848 return; 849 850 #endif /* GUMSTIX or OVERO */ 851 852 #endif /* NCOM */ 853 854 #if NLCD > 0 855 #if defined(GUMSTIX_NETBSD_ARGS_CONSOLE) 856 if (console[0] == '\0' || strcasecmp(console, "lcd") == 0) 857 #endif 858 { 859 gxlcd_cnattach(); 860 } 861 #endif 862 } 863 864 #ifdef KGDB 865 static void 866 kgdb_port_init(void) 867 { 868 #if (NCOM > 0) && defined(COM_PXA2X0) 869 paddr_t paddr = 0; 870 int cken = 0; 871 872 if (0 == strcmp(kgdb_devname, "ffuart")) { 873 paddr = PXA2X0_FFUART_BASE; 874 cken = CKEN_FFUART; 875 } else if (0 == strcmp(kgdb_devname, "stuart")) { 876 paddr = PXA2X0_STUART_BASE; 877 cken = CKEN_STUART; 878 } else if (0 == strcmp(kgdb_devname, "btuart")) { 879 paddr = PXA2X0_BTUART_BASE; 880 cken = CKEN_BTUART; 881 } else if (0 == strcmp(kgdb_devname, "hwuart")) { 882 paddr = PXA2X0_HWUART_BASE; 883 cken = CKEN_HWUART; 884 } 885 886 if (paddr && 887 0 == com_kgdb_attach(&pxa2x0_a4x_bs_tag, paddr, 888 kgdb_devrate, PXA2X0_COM_FREQ, COM_TYPE_PXA2x0, comkgdbmode)) { 889 890 pxa2x0_clkman_config(cken, 1); 891 } 892 893 #endif 894 } 895 #endif 896 897 static void 898 gumstix_device_register(device_t dev, void *aux) 899 { 900 prop_dictionary_t dict = device_properties(dev); 901 902 if (device_is_a(dev, "ehci")) { 903 prop_dictionary_set_uint16(dict, "nports", 2); 904 prop_dictionary_set_bool(dict, "phy-reset", true); 905 prop_dictionary_set_cstring(dict, "port0-mode", "none"); 906 prop_dictionary_set_int16(dict, "port0-gpio", -1); 907 prop_dictionary_set_cstring(dict, "port1-mode", "phy"); 908 prop_dictionary_set_int16(dict, "port1-gpio", 183); 909 prop_dictionary_set_bool(dict, "port1-gpioval", true); 910 prop_dictionary_set_uint16(dict, "dpll5-m", 443); 911 prop_dictionary_set_uint16(dict, "dpll5-n", 11); 912 prop_dictionary_set_uint16(dict, "dpll5-m2", 4); 913 } 914 if (device_is_a(dev, "ohci")) { 915 if (prop_dictionary_set_bool(dict, 916 "Ganged-power-mask-on-port1", 1) == false) { 917 printf("WARNING: unable to set power-mask for port1" 918 " property for %s\n", device_xname(dev)); 919 } 920 if (prop_dictionary_set_bool(dict, 921 "Ganged-power-mask-on-port2", 1) == false) { 922 printf("WARNING: unable to set power-mask for port2" 923 " property for %s\n", device_xname(dev)); 924 } 925 if (prop_dictionary_set_bool(dict, 926 "Ganged-power-mask-on-port3", 1) == false) { 927 printf("WARNING: unable to set power-mask for port3" 928 " property for %s\n", device_xname(dev)); 929 } 930 } 931 if (device_is_a(dev, "omapmputmr")) { 932 #ifdef OVERO 933 struct obio_attach_args *obio = aux; 934 int en; 935 936 switch (obio->obio_addr) { 937 case 0x49032000: /* GPTIMER2 */ 938 case 0x49034000: /* GPTIMER3 */ 939 case 0x49036000: /* GPTIMER4 */ 940 case 0x49038000: /* GPTIMER5 */ 941 case 0x4903a000: /* GPTIMER6 */ 942 case 0x4903c000: /* GPTIMER7 */ 943 case 0x4903e000: /* GPTIMER8 */ 944 case 0x49040000: /* GPTIMER9 */ 945 /* Ensure enable PRCM.CM_[FI]CLKEN_PER[3:10]. */ 946 en = 1 << (((obio->obio_addr >> 13) & 0x3f) - 0x16); 947 ioreg_write(OVERO_L4_CORE_VBASE + 0x5000, 948 ioreg_read(OVERO_L4_CORE_VBASE + 0x5000) | en); 949 ioreg_write(OVERO_L4_CORE_VBASE + 0x5010, 950 ioreg_read(OVERO_L4_CORE_VBASE + 0x5010) | en); 951 break; 952 } 953 #endif 954 } 955 } 956