Home | History | Annotate | Line # | Download | only in beagle
beagle_machdep.c revision 1.60
      1 /*	$NetBSD: beagle_machdep.c,v 1.59 2014/07/20 23:08:43 bouyer Exp $ */
      2 
      3 /*
      4  * Machine dependent functions for kernel setup for TI OSK5912 board.
      5  * Based on lubbock_machdep.c which in turn was based on iq80310_machhdep.c
      6  *
      7  * Copyright (c) 2002, 2003, 2005  Genetec Corporation.  All rights reserved.
      8  * Written by Hiroyuki Bessho for Genetec Corporation.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. The name of Genetec Corporation may not be used to endorse or
     19  *    promote products derived from this software without specific prior
     20  *    written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
     23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
     26  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     32  * POSSIBILITY OF SUCH DAMAGE.
     33  *
     34  * Copyright (c) 2001 Wasabi Systems, Inc.
     35  * All rights reserved.
     36  *
     37  * Written by Jason R. Thorpe for Wasabi Systems, Inc.
     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. All advertising materials mentioning features or use of this software
     48  *    must display the following acknowledgement:
     49  *	This product includes software developed for the NetBSD Project by
     50  *	Wasabi Systems, Inc.
     51  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
     52  *    or promote products derived from this software without specific prior
     53  *    written permission.
     54  *
     55  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
     56  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     57  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     58  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
     59  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     60  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     61  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     62  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     63  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     64  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     65  * POSSIBILITY OF SUCH DAMAGE.
     66  *
     67  * Copyright (c) 1997,1998 Mark Brinicombe.
     68  * Copyright (c) 1997,1998 Causality Limited.
     69  * All rights reserved.
     70  *
     71  * Redistribution and use in source and binary forms, with or without
     72  * modification, are permitted provided that the following conditions
     73  * are met:
     74  * 1. Redistributions of source code must retain the above copyright
     75  *    notice, this list of conditions and the following disclaimer.
     76  * 2. Redistributions in binary form must reproduce the above copyright
     77  *    notice, this list of conditions and the following disclaimer in the
     78  *    documentation and/or other materials provided with the distribution.
     79  * 3. All advertising materials mentioning features or use of this software
     80  *    must display the following acknowledgement:
     81  *	This product includes software developed by Mark Brinicombe
     82  *	for the NetBSD Project.
     83  * 4. The name of the company nor the name of the author may be used to
     84  *    endorse or promote products derived from this software without specific
     85  *    prior written permission.
     86  *
     87  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     88  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     89  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     90  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
     91  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     92  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     93  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     94  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     95  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     96  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     97  * SUCH DAMAGE.
     98  *
     99  * Copyright (c) 2007 Microsoft
    100  * All rights reserved.
    101  *
    102  * Redistribution and use in source and binary forms, with or without
    103  * modification, are permitted provided that the following conditions
    104  * are met:
    105  * 1. Redistributions of source code must retain the above copyright
    106  *    notice, this list of conditions and the following disclaimer.
    107  * 2. Redistributions in binary form must reproduce the above copyright
    108  *    notice, this list of conditions and the following disclaimer in the
    109  *    documentation and/or other materials provided with the distribution.
    110  * 3. All advertising materials mentioning features or use of this software
    111  *    must display the following acknowledgement:
    112  *	This product includes software developed by Microsoft
    113  *
    114  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
    115  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    116  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    117  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT,
    118  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    119  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    120  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    121  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    122  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    123  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    124  * SUCH DAMAGE.
    125  */
    126 
    127 #include <sys/cdefs.h>
    128 __KERNEL_RCSID(0, "$NetBSD: beagle_machdep.c,v 1.59 2014/07/20 23:08:43 bouyer Exp $");
    129 
    130 #include "opt_machdep.h"
    131 #include "opt_ddb.h"
    132 #include "opt_kgdb.h"
    133 #include "opt_ipkdb.h"
    134 #include "opt_md.h"
    135 #include "opt_com.h"
    136 #include "opt_omap.h"
    137 
    138 #include "com.h"
    139 #include "omapwdt32k.h"
    140 #include "prcm.h"
    141 #include "sdhc.h"
    142 #include "ukbd.h"
    143 #include "arml2cc.h"
    144 
    145 #include <sys/param.h>
    146 #include <sys/systm.h>
    147 #include <sys/bus.h>
    148 #include <sys/cpu.h>
    149 #include <sys/device.h>
    150 #include <sys/exec.h>
    151 #include <sys/kernel.h>
    152 #include <sys/ksyms.h>
    153 #include <sys/msgbuf.h>
    154 #include <sys/proc.h>
    155 #include <sys/reboot.h>
    156 #include <sys/termios.h>
    157 #include <sys/gpio.h>
    158 
    159 #include <uvm/uvm_extern.h>
    160 
    161 #include <sys/conf.h>
    162 #include <dev/cons.h>
    163 #include <dev/md.h>
    164 
    165 #include <machine/db_machdep.h>
    166 #include <ddb/db_sym.h>
    167 #include <ddb/db_extern.h>
    168 #ifdef KGDB
    169 #include <sys/kgdb.h>
    170 #endif
    171 
    172 #include <machine/bootconfig.h>
    173 #include <arm/armreg.h>
    174 #include <arm/undefined.h>
    175 
    176 #include <arm/arm32/machdep.h>
    177 #include <arm/mainbus/mainbus.h>
    178 
    179 #include <dev/ic/ns16550reg.h>
    180 #include <dev/ic/comreg.h>
    181 
    182 #include <arm/omap/omap_com.h>
    183 #include <arm/omap/omap_var.h>
    184 #include <arm/omap/omap_wdtvar.h>
    185 #include <arm/omap/omap2_prcm.h>
    186 #include <arm/omap/omap2_gpio.h>
    187 #ifdef TI_AM335X
    188 # if NPRCM == 0
    189 #  error no prcm device configured.
    190 # endif
    191 # include <arm/omap/am335x_prcm.h>
    192 # include <dev/i2c/tps65217pmicvar.h>
    193 # if NSDHC > 0
    194 #  include <arm/omap/omap2_obiovar.h>
    195 #  include <arm/omap/omap3_sdmmcreg.h>
    196 # endif
    197 #endif
    198 
    199 #ifdef CPU_CORTEXA9
    200 #include <arm/cortex/pl310_reg.h>
    201 #include <arm/cortex/scu_reg.h>
    202 
    203 #include <arm/cortex/a9tmr_var.h>
    204 #include <arm/cortex/pl310_var.h>
    205 #endif
    206 
    207 #if defined(CPU_CORTEXA7) || defined(CPU_CORTEXA15)
    208 #include <arm/cortex/gtmr_var.h>
    209 #endif
    210 
    211 #include <evbarm/include/autoconf.h>
    212 #include <evbarm/beagle/beagle.h>
    213 
    214 #include <dev/i2c/i2cvar.h>
    215 #include <dev/i2c/ddcreg.h>
    216 
    217 #include <dev/usb/ukbdvar.h>
    218 
    219 BootConfig bootconfig;		/* Boot config storage */
    220 static char bootargs[MAX_BOOT_STRING];
    221 char *boot_args = NULL;
    222 char *boot_file = NULL;
    223 
    224 static uint8_t beagle_edid[128];	/* EDID storage */
    225 
    226 u_int uboot_args[4] = { 0 };	/* filled in by beagle_start.S (not in bss) */
    227 
    228 /* Same things, but for the free (unused by the kernel) memory. */
    229 
    230 extern char KERNEL_BASE_phys[];
    231 extern char _end[];
    232 
    233 #if NCOM > 0
    234 int use_fb_console = false;
    235 #else
    236 int use_fb_console = true;
    237 #endif
    238 
    239 #ifdef CPU_CORTEXA15
    240 uint32_t omap5_cnt_frq;
    241 #endif
    242 #if defined(TI_AM335X)
    243 device_t pmic_dev = NULL;
    244 #endif
    245 
    246 /*
    247  * Macros to translate between physical and virtual for a subset of the
    248  * kernel address space.  *Not* for general use.
    249  */
    250 #define KERNEL_BASE_PHYS ((paddr_t)KERNEL_BASE_phys)
    251 #define	OMAP_L4_CORE_VOFFSET	(OMAP_L4_CORE_VBASE - OMAP_L4_CORE_BASE)
    252 
    253 /* Prototypes */
    254 
    255 void consinit(void);
    256 #ifdef KGDB
    257 static void kgdb_port_init(void);
    258 #endif
    259 
    260 static void init_clocks(void);
    261 static void beagle_device_register(device_t, void *);
    262 static void beagle_reset(void);
    263 #if defined(OMAP_3XXX) || defined(TI_DM37XX)
    264 static void omap3_cpu_clk(void);
    265 #endif
    266 #if defined(OMAP_4XXX) || defined(OMAP_5XXX)
    267 static void omap4_cpu_clk(void);
    268 #endif
    269 #if defined(OMAP_4XXX) || defined(OMAP_5XXX) || defined(TI_AM335X)
    270 static psize_t emif_memprobe(void);
    271 #endif
    272 
    273 #if defined(OMAP_3XXX)
    274 static psize_t omap3_memprobe(void);
    275 #endif
    276 
    277 bs_protos(bs_notimpl);
    278 
    279 #if NCOM > 0
    280 #include <dev/ic/comreg.h>
    281 #include <dev/ic/comvar.h>
    282 #endif
    283 
    284 /*
    285  * Static device mappings. These peripheral registers are mapped at
    286  * fixed virtual addresses very early in initarm() so that we can use
    287  * them while booting the kernel, and stay at the same address
    288  * throughout whole kernel's life time.
    289  *
    290  * We use this table twice; once with bootstrap page table, and once
    291  * with kernel's page table which we build up in initarm().
    292  *
    293  * Since we map these registers into the bootstrap page table using
    294  * pmap_devmap_bootstrap() which calls pmap_map_chunk(), we map
    295  * registers segment-aligned and segment-rounded in order to avoid
    296  * using the 2nd page tables.
    297  */
    298 
    299 #define	_A(a)	((a) & ~L1_S_OFFSET)
    300 #define	_S(s)	(((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1))
    301 
    302 static const struct pmap_devmap devmap[] = {
    303 	{
    304 		/*
    305 		 * Map the first 1MB of L4 Core area
    306 		 * this gets us the ICU, I2C, USB, GPT[10-11], MMC, McSPI
    307 		 * UART[12], clock manager, sDMA, ...
    308 		 */
    309 		.pd_va = _A(OMAP_L4_CORE_VBASE),
    310 		.pd_pa = _A(OMAP_L4_CORE_BASE),
    311 		.pd_size = _S(OMAP_L4_CORE_SIZE),
    312 		.pd_prot = VM_PROT_READ|VM_PROT_WRITE,
    313 		.pd_cache = PTE_NOCACHE
    314 	},
    315 	{
    316 		/*
    317 		 * Map the all 1MB of the L4 Core area
    318 		 * this gets us the console UART3, GPT[2-9], WDT1,
    319 		 * and GPIO[2-6].
    320 		 */
    321 		.pd_va = _A(OMAP_L4_PERIPHERAL_VBASE),
    322 		.pd_pa = _A(OMAP_L4_PERIPHERAL_BASE),
    323 		.pd_size = _S(OMAP_L4_PERIPHERAL_SIZE),
    324 		.pd_prot = VM_PROT_READ|VM_PROT_WRITE,
    325 		.pd_cache = PTE_NOCACHE
    326 	},
    327 #if defined(OMAP_L4_WAKEUP_BASE) && defined(OMAP_L4_WAKEUP_VBASE)
    328 	{
    329 		/*
    330 		 * Map all 256KB of the L4 Wakeup area
    331 		 * this gets us GPIO1, WDT2, GPT1, 32K and power/reset regs
    332 		 */
    333 		.pd_va = _A(OMAP_L4_WAKEUP_VBASE),
    334 		.pd_pa = _A(OMAP_L4_WAKEUP_BASE),
    335 		.pd_size = _S(OMAP_L4_WAKEUP_SIZE),
    336 		.pd_prot = VM_PROT_READ|VM_PROT_WRITE,
    337 		.pd_cache = PTE_NOCACHE
    338 	},
    339 #endif
    340 #ifdef OMAP_L4_FAST_BASE
    341 	{
    342 		/*
    343 		 * Map all of the L4 Fast area
    344 		 * this gets us GPIO1, WDT2, GPT1, 32K and power/reset regs
    345 		 */
    346 		.pd_va = _A(OMAP_L4_FAST_VBASE),
    347 		.pd_pa = _A(OMAP_L4_FAST_BASE),
    348 		.pd_size = _S(OMAP_L4_FAST_SIZE),
    349 		.pd_prot = VM_PROT_READ|VM_PROT_WRITE,
    350 		.pd_cache = PTE_NOCACHE
    351 	},
    352 #endif
    353 #ifdef OMAP_EMIF1_BASE
    354 	{
    355 		/*
    356 		 * Map all of the L4 EMIF1 area
    357 		 */
    358 		.pd_va = _A(OMAP_EMIF1_VBASE),
    359 		.pd_pa = _A(OMAP_EMIF1_BASE),
    360 		.pd_size = _S(OMAP_EMIF1_SIZE),
    361 		.pd_prot = VM_PROT_READ|VM_PROT_WRITE,
    362 		.pd_cache = PTE_NOCACHE
    363 	},
    364 #endif
    365 #ifdef OMAP_EMIF2_BASE
    366 	{
    367 		/*
    368 		 * Map all of the L4 EMIF2 area
    369 		 */
    370 		.pd_va = _A(OMAP_EMIF2_VBASE),
    371 		.pd_pa = _A(OMAP_EMIF2_BASE),
    372 		.pd_size = _S(OMAP_EMIF2_SIZE),
    373 		.pd_prot = VM_PROT_READ|VM_PROT_WRITE,
    374 		.pd_cache = PTE_NOCACHE
    375 	},
    376 #endif
    377 #ifdef OMAP_L4_ABE_BASE
    378 	{
    379 		/*
    380 		 * Map all of the L4 Fast area
    381 		 * this gets us GPIO1, WDT2, GPT1, 32K and power/reset regs
    382 		 */
    383 		.pd_va = _A(OMAP_L4_ABE_VBASE),
    384 		.pd_pa = _A(OMAP_L4_ABE_BASE),
    385 		.pd_size = _S(OMAP_L4_ABE_SIZE),
    386 		.pd_prot = VM_PROT_READ|VM_PROT_WRITE,
    387 		.pd_cache = PTE_NOCACHE
    388 	},
    389 #endif
    390 #ifdef OMAP_SDRC_BASE
    391 	{
    392 		/*
    393 		 * Map SDRAM Controller (SDRC) registers
    394 		 */
    395 		.pd_va = _A(OMAP_SDRC_VBASE),
    396 		.pd_pa = _A(OMAP_SDRC_BASE),
    397 		.pd_size = _S(OMAP_SDRC_SIZE),
    398 		.pd_prot = VM_PROT_READ|VM_PROT_WRITE,
    399 		.pd_cache = PTE_NOCACHE,
    400 	},
    401 #endif
    402 	{0}
    403 };
    404 
    405 #undef	_A
    406 #undef	_S
    407 
    408 #ifdef DDB
    409 static void
    410 beagle_db_trap(int where)
    411 {
    412 #if NOMAPWDT32K > 0
    413 	static int oldwatchdogstate;
    414 
    415 	if (where) {
    416 		oldwatchdogstate = omapwdt32k_enable(0);
    417 	} else {
    418 		omapwdt32k_enable(oldwatchdogstate);
    419 	}
    420 #endif
    421 }
    422 #endif
    423 
    424 void beagle_putchar(char c);
    425 void
    426 beagle_putchar(char c)
    427 {
    428 #if NCOM > 0
    429 	volatile uint32_t *com0addr = (volatile uint32_t *)CONSADDR_VA;
    430 	int timo = 150000;
    431 
    432 	while ((com0addr[com_lsr] & LSR_TXRDY) == 0) {
    433 		if (--timo == 0)
    434 			break;
    435 	}
    436 
    437 	com0addr[com_data] = c;
    438 
    439 	while ((com0addr[com_lsr] & LSR_TXRDY) == 0) {
    440 		if (--timo == 0)
    441 			break;
    442 	}
    443 #endif
    444 }
    445 
    446 /*
    447  * u_int initarm(...)
    448  *
    449  * Initial entry point on startup. This gets called before main() is
    450  * entered.
    451  * It should be responsible for setting up everything that must be
    452  * in place when main is called.
    453  * This includes
    454  *   Taking a copy of the boot configuration structure.
    455  *   Initialising the physical console so characters can be printed.
    456  *   Setting up page tables for the kernel
    457  *   Relocating the kernel to the bottom of physical memory
    458  */
    459 u_int
    460 initarm(void *arg)
    461 {
    462 	psize_t ram_size = 0;
    463 	char *ptr;
    464 
    465 #if 1
    466 	beagle_putchar('d');
    467 #endif
    468 
    469 	/*
    470 	 * When we enter here, we are using a temporary first level
    471 	 * translation table with section entries in it to cover the OBIO
    472 	 * peripherals and SDRAM.  The temporary first level translation table
    473 	 * is at the end of SDRAM.
    474 	 */
    475 #if defined(OMAP_3XXX) || defined(TI_DM37XX)
    476 	omap3_cpu_clk();		// find our CPU speed.
    477 #endif
    478 #if defined(OMAP_4XXX) || defined(OMAP_5XXX)
    479 	omap4_cpu_clk();		// find our CPU speed.
    480 #endif
    481 #if defined(TI_AM335X)
    482 	prcm_bootstrap(OMAP2_CM_BASE + OMAP_L4_CORE_VOFFSET);
    483 	// find our reference clock.
    484 	am335x_sys_clk(TI_AM335X_CTLMOD_BASE + OMAP_L4_CORE_VOFFSET);
    485 	am335x_cpu_clk();		// find our CPU speed.
    486 #endif
    487 	/* Heads up ... Setup the CPU / MMU / TLB functions. */
    488 	if (set_cpufuncs())
    489 		panic("cpu not recognized!");
    490 
    491 	init_clocks();
    492 
    493 	/* The console is going to try to map things.  Give pmap a devmap. */
    494 	pmap_devmap_register(devmap);
    495 	consinit();
    496 #ifdef CPU_CORTEXA15
    497 #ifdef MULTIPROCESSOR
    498 	arm_cpu_max = 1 + __SHIFTOUT(armreg_l2ctrl_read(), L2CTRL_NUMCPU);
    499 #endif
    500 #endif
    501 #if defined(OMAP_4XXX)
    502 #if NARML2CC > 0
    503 	/*
    504 	 * Probe the PL310 L2CC
    505 	 */
    506 	const bus_space_handle_t pl310_bh = OMAP4_L2CC_BASE
    507 	    + OMAP_L4_PERIPHERAL_VBASE - OMAP_L4_PERIPHERAL_BASE;
    508 	arml2cc_init(&omap_bs_tag, pl310_bh, 0);
    509 	beagle_putchar('l');
    510 #endif
    511 #ifdef MULTIPROCESSOR
    512 	const bus_space_handle_t scu_bh = OMAP4_SCU_BASE
    513 	    + OMAP_L4_PERIPHERAL_VBASE - OMAP_L4_PERIPHERAL_BASE;
    514 	uint32_t scu_cfg = bus_space_read_4(&omap_bs_tag, scu_bh, SCU_CFG);
    515 	arm_cpu_max = 1 + (scu_cfg & SCU_CFG_CPUMAX);
    516 	beagle_putchar('s');
    517 #endif
    518 #endif /* OMAP_4XXX */
    519 #if defined(TI_AM335X) && defined(VERBOSE_INIT_ARM)
    520 	am335x_cpu_clk();		// find our CPU speed.
    521 #endif
    522 #if 1
    523 	beagle_putchar('h');
    524 #endif
    525 	printf("\nuboot arg = %#x, %#x, %#x, %#x\n",
    526 	    uboot_args[0], uboot_args[1], uboot_args[2], uboot_args[3]);
    527 
    528 
    529 #ifdef KGDB
    530 	kgdb_port_init();
    531 #endif
    532 
    533 	cpu_reset_address = beagle_reset;
    534 
    535 #ifdef VERBOSE_INIT_ARM
    536 	/* Talk to the user */
    537 	printf("\nNetBSD/evbarm (beagle) booting ...\n");
    538 #endif
    539 
    540 #ifdef BOOT_ARGS
    541 	char mi_bootargs[] = BOOT_ARGS;
    542 	parse_mi_bootargs(mi_bootargs);
    543 #endif
    544 
    545 #ifdef VERBOSE_INIT_ARM
    546 	printf("initarm: Configuring system ...\n");
    547 #endif
    548 
    549 #if !defined(CPU_CORTEXA8)
    550 	printf("initarm: cbar=%#x\n", armreg_cbar_read());
    551 #endif
    552 
    553 	/*
    554 	 * Set up the variables that define the availability of physical
    555 	 * memory.
    556 	 */
    557 #if defined(OMAP_3XXX)
    558 	ram_size = omap3_memprobe();
    559 #endif
    560 #if defined(OMAP_4XXX) || defined(OMAP_5XXX) || defined(TI_AM335X)
    561 	ram_size = emif_memprobe();
    562 #endif
    563 
    564 #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
    565 	if (ram_size > KERNEL_VM_BASE - KERNEL_BASE) {
    566 		printf("%s: dropping RAM size from %luMB to %uMB\n",
    567 		    __func__, (unsigned long) (ram_size >> 20),
    568 		    (KERNEL_VM_BASE - KERNEL_BASE) >> 20);
    569 		ram_size = KERNEL_VM_BASE - KERNEL_BASE;
    570 	}
    571 #endif
    572 
    573 	/*
    574 	 * If MEMSIZE specified less than what we really have, limit ourselves
    575 	 * to that.
    576 	 */
    577 #ifdef MEMSIZE
    578 	if (ram_size == 0 || ram_size > (unsigned)MEMSIZE * 1024 * 1024)
    579 		ram_size = (unsigned)MEMSIZE * 1024 * 1024;
    580 #else
    581 	KASSERTMSG(ram_size > 0, "RAM size unknown and MEMSIZE undefined");
    582 #endif
    583 
    584 	/* Fake bootconfig structure for the benefit of pmap.c. */
    585 	bootconfig.dramblocks = 1;
    586 	bootconfig.dram[0].address = KERNEL_BASE_PHYS & -0x400000;
    587 	bootconfig.dram[0].pages = ram_size / PAGE_SIZE;
    588 
    589 #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
    590 	const bool mapallmem_p = true;
    591 	KASSERT(ram_size <= KERNEL_VM_BASE - KERNEL_BASE);
    592 #else
    593 	const bool mapallmem_p = false;
    594 #endif
    595 	KASSERT((armreg_pfr1_read() & ARM_PFR1_SEC_MASK) != 0);
    596 
    597 	arm32_bootmem_init(bootconfig.dram[0].address, ram_size,
    598 	    KERNEL_BASE_PHYS);
    599 	arm32_kernel_vm_init(KERNEL_VM_BASE, ARM_VECTORS_LOW, 0, devmap,
    600 	    mapallmem_p);
    601 
    602 #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
    603 	/* "bootargs" env variable is passed as 4th argument to kernel */
    604 	if (uboot_args[3] - 0x80000000 < ram_size) {
    605 		strlcpy(bootargs, (char *)uboot_args[3], sizeof(bootargs));
    606 	}
    607 #endif
    608 	boot_args = bootargs;
    609 	parse_mi_bootargs(boot_args);
    610 
    611 	/* we've a specific device_register routine */
    612 	evbarm_device_register = beagle_device_register;
    613 
    614 	db_trap_callback = beagle_db_trap;
    615 
    616 	if (get_bootconf_option(boot_args, "console",
    617 		    BOOTOPT_TYPE_STRING, &ptr) && strncmp(ptr, "fb", 2) == 0) {
    618 		use_fb_console = true;
    619 	}
    620 
    621 	return initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, NULL, 0);
    622 
    623 }
    624 
    625 static void
    626 init_clocks(void)
    627 {
    628 #ifdef NOTYET
    629 	static volatile uint32_t * const clksel_reg = (volatile uint32_t *) (OMAP3530_L4_WAKEUP_VBASE + OMAP2_CM_BASE + OMAP2_CM_CLKSEL_MPU - OMAP3530_L4_WAKEUP_BASE);
    630 	uint32_t v;
    631 	beagle_putchar('E');
    632 	v = *clksel_reg;
    633 	beagle_putchar('F');
    634 	if (v != OMAP3530_CM_CLKSEL_MPU_FULLSPEED) {
    635 		printf("Changed CPU speed from half (%d) ", v);
    636 		*clksel_reg = OMAP3530_CM_CLKSEL_MPU_FULLSPEED;
    637 		printf("to full speed.\n");
    638 	}
    639 	beagle_putchar('G');
    640 #endif
    641 }
    642 
    643 #if NCOM > 0
    644 #ifndef CONSADDR
    645 #error Specify the address of the console UART with the CONSADDR option.
    646 #endif
    647 #ifndef CONSPEED
    648 #define CONSPEED 115200
    649 #endif
    650 #ifndef CONMODE
    651 #define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
    652 #endif
    653 
    654 static const bus_addr_t consaddr = CONSADDR;
    655 static const int conspeed = CONSPEED;
    656 static const int conmode = CONMODE;
    657 #endif
    658 
    659 void
    660 consinit(void)
    661 {
    662 #if NCOM > 0
    663 	bus_space_handle_t bh;
    664 #endif
    665 	static int consinit_called = 0;
    666 
    667 	if (consinit_called != 0)
    668 		return;
    669 
    670 	consinit_called = 1;
    671 
    672 	beagle_putchar('e');
    673 
    674 #if NCOM > 0
    675 	if (bus_space_map(&omap_a4x_bs_tag, consaddr, OMAP_COM_SIZE, 0, &bh))
    676 		panic("Serial console can not be mapped.");
    677 
    678 	if (comcnattach(&omap_a4x_bs_tag, consaddr, conspeed,
    679 			OMAP_COM_FREQ, COM_TYPE_NORMAL, conmode))
    680 		panic("Serial console can not be initialized.");
    681 
    682 	bus_space_unmap(&omap_a4x_bs_tag, bh, OMAP_COM_SIZE);
    683 #endif
    684 
    685 #if NUKBD > 0
    686 	ukbd_cnattach();	/* allow USB keyboard to become console */
    687 #endif
    688 
    689 	beagle_putchar('f');
    690 	beagle_putchar('g');
    691 }
    692 
    693 void
    694 beagle_reset(void)
    695 {
    696 #if defined(OMAP_4XXX)
    697 	*(volatile uint32_t *)(OMAP_L4_CORE_VBASE + (OMAP_L4_WAKEUP_BASE - OMAP_L4_CORE_BASE) + OMAP4_PRM_RSTCTRL) = OMAP4_PRM_RSTCTRL_WARM;
    698 #elif defined(OMAP_5XXX)
    699 	*(volatile uint32_t *)(OMAP_L4_CORE_VBASE + (OMAP_L4_WAKEUP_BASE - OMAP_L4_CORE_BASE) + OMAP5_PRM_RSTCTRL) = OMAP4_PRM_RSTCTRL_COLD;
    700 #elif defined(OMAP_5XXX)
    701 #elif defined(TI_AM335X)
    702 	*(volatile uint32_t *)(OMAP_L4_CORE_VBASE + (OMAP2_CM_BASE - OMAP_L4_CORE_BASE) + AM335X_PRCM_PRM_DEVICE + PRM_RSTCTRL) = RST_GLOBAL_WARM_SW;
    703 #else
    704 #if NPRCM > 0
    705 	prcm_cold_reset();
    706 #endif
    707 #if NOMAPWDT32K > 0
    708 	omapwdt32k_reboot();
    709 #endif
    710 #endif
    711 }
    712 
    713 #ifdef KGDB
    714 #ifndef KGDB_DEVADDR
    715 #error Specify the address of the kgdb UART with the KGDB_DEVADDR option.
    716 #endif
    717 #ifndef KGDB_DEVRATE
    718 #define KGDB_DEVRATE 115200
    719 #endif
    720 
    721 #ifndef KGDB_DEVMODE
    722 #define KGDB_DEVMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
    723 #endif
    724 static const vaddr_t comkgdbaddr = KGDB_DEVADDR;
    725 static const int comkgdbspeed = KGDB_DEVRATE;
    726 static const int comkgdbmode = KGDB_DEVMODE;
    727 
    728 void
    729 static kgdb_port_init(void)
    730 {
    731 	static int kgdbsinit_called = 0;
    732 
    733 	if (kgdbsinit_called != 0)
    734 		return;
    735 
    736 	kgdbsinit_called = 1;
    737 
    738 	bus_space_handle_t bh;
    739 	if (bus_space_map(&omap_a4x_bs_tag, comkgdbaddr, OMAP_COM_SIZE, 0, &bh))
    740 		panic("kgdb port can not be mapped.");
    741 
    742 	if (com_kgdb_attach(&omap_a4x_bs_tag, comkgdbaddr, comkgdbspeed,
    743 			OMAP_COM_FREQ, COM_TYPE_NORMAL, comkgdbmode))
    744 		panic("KGDB uart can not be initialized.");
    745 
    746 	bus_space_unmap(&omap_a4x_bs_tag, bh, OMAP_COM_SIZE);
    747 }
    748 #endif
    749 
    750 #if defined(OMAP_3XXX) || defined(TI_DM37XX)
    751 void
    752 omap3_cpu_clk(void)
    753 {
    754 	const vaddr_t prm_base = OMAP2_PRM_BASE + OMAP_L4_CORE_VOFFSET;
    755 	const uint32_t prm_clksel = *(volatile uint32_t *)(prm_base + PLL_MOD + OMAP3_PRM_CLKSEL);
    756 	static const uint32_t prm_clksel_freqs[] = OMAP3_PRM_CLKSEL_FREQS;
    757 	const uint32_t sys_clk = prm_clksel_freqs[__SHIFTOUT(prm_clksel, OMAP3_PRM_CLKSEL_CLKIN)];
    758 	const vaddr_t cm_base = OMAP2_CM_BASE - OMAP_L4_CORE_BASE + OMAP_L4_CORE_VBASE;
    759 	const uint32_t dpll1 = *(volatile uint32_t *)(cm_base + OMAP3_CM_CLKSEL1_PLL_MPU);
    760 	const uint32_t dpll2 = *(volatile uint32_t *)(cm_base + OMAP3_CM_CLKSEL2_PLL_MPU);
    761 	const uint32_t m = __SHIFTOUT(dpll1, OMAP3_CM_CLKSEL1_PLL_MPU_DPLL_MULT);
    762 	const uint32_t n = __SHIFTOUT(dpll1, OMAP3_CM_CLKSEL1_PLL_MPU_DPLL_DIV);
    763 	const uint32_t m2 = __SHIFTOUT(dpll2, OMAP3_CM_CLKSEL2_PLL_MPU_DPLL_CLKOUT_DIV);
    764 
    765 	/*
    766 	 * MPU_CLK supplies ARM_FCLK which is twice the CPU frequency.
    767 	 */
    768 	curcpu()->ci_data.cpu_cc_freq = ((sys_clk * m) / ((n + 1) * m2 * 2)) * OMAP3_PRM_CLKSEL_MULT;
    769 	omap_sys_clk = sys_clk * OMAP3_PRM_CLKSEL_MULT;
    770 }
    771 #endif /* OMAP_3XXX || TI_DM37XX */
    772 
    773 #if defined(OMAP_4XXX) || defined(OMAP_5XXX)
    774 void
    775 omap4_cpu_clk(void)
    776 {
    777 	const vaddr_t prm_base = OMAP2_PRM_BASE + OMAP_L4_CORE_VOFFSET;
    778 	const vaddr_t cm_base = OMAP2_CM_BASE + OMAP_L4_CORE_VOFFSET;
    779 	static const uint32_t cm_clksel_freqs[] = OMAP4_CM_CLKSEL_FREQS;
    780 	const uint32_t prm_clksel = *(volatile uint32_t *)(prm_base + OMAP4_CM_SYS_CLKSEL);
    781 	const u_int clksel = __SHIFTOUT(prm_clksel, OMAP4_CM_SYS_CLKSEL_CLKIN);
    782 	const uint32_t sys_clk = cm_clksel_freqs[clksel];
    783 	const uint32_t dpll1 = *(volatile uint32_t *)(cm_base + OMAP4_CM_CLKSEL_DPLL_MPU);
    784 	const uint32_t dpll2 = *(volatile uint32_t *)(cm_base + OMAP4_CM_DIV_M2_DPLL_MPU);
    785 	const uint32_t m = __SHIFTOUT(dpll1, OMAP4_CM_CLKSEL_DPLL_MPU_DPLL_MULT);
    786 	const uint32_t n = __SHIFTOUT(dpll1, OMAP4_CM_CLKSEL_DPLL_MPU_DPLL_DIV);
    787 	const uint32_t m2 = __SHIFTOUT(dpll2, OMAP4_CM_DIV_M2_DPLL_MPU_DPLL_CLKOUT_DIV);
    788 
    789 	/*
    790 	 * MPU_CLK supplies ARM_FCLK which is twice the CPU frequency.
    791 	 */
    792 	curcpu()->ci_data.cpu_cc_freq = ((sys_clk * 2 * m) / ((n + 1) * m2)) * OMAP4_CM_CLKSEL_MULT / 2;
    793 	omap_sys_clk = sys_clk * OMAP4_CM_CLKSEL_MULT;
    794 	printf("%s: %"PRIu64": sys_clk=%u m=%u n=%u (%u) m2=%u mult=%u\n",
    795 	    __func__, curcpu()->ci_data.cpu_cc_freq,
    796 	    sys_clk, m, n, n+1, m2, OMAP4_CM_CLKSEL_MULT);
    797 
    798 #if defined(CPU_CORTEXA15)
    799 	if ((armreg_pfr1_read() & ARM_PFR1_GTIMER_MASK) != 0) {
    800 		beagle_putchar('0');
    801 		uint32_t voffset = OMAP_L4_PERIPHERAL_VBASE - OMAP_L4_PERIPHERAL_BASE;
    802 		uint32_t frac1_reg = OMAP5_PRM_FRAC_INCREMENTER_NUMERATOR;
    803 		uint32_t frac2_reg = OMAP5_PRM_FRAC_INCREMENTER_DENUMERATOR_RELOAD;
    804 		uint32_t frac1 = *(volatile uint32_t *)(frac1_reg + voffset);
    805 		beagle_putchar('1');
    806 		uint32_t frac2 = *(volatile uint32_t *)(frac2_reg + voffset);
    807 		beagle_putchar('2');
    808 		uint32_t numer = __SHIFTOUT(frac1, PRM_FRAC_INCR_NUM_SYS_MODE);
    809 		uint32_t denom = __SHIFTOUT(frac2, PRM_FRAC_INCR_DENUM_DENOMINATOR);
    810 		uint32_t freq = (uint64_t)omap_sys_clk * numer / denom;
    811 #if 1
    812 		if (freq != OMAP5_GTIMER_FREQ) {
    813 			static uint16_t numer_demon[8][2] = {
    814 			    {         0,          0 },	/* not used */
    815 			    {  26 *  64,  26 *  125 },	/* 12.0Mhz */
    816 			    {   2 * 768,   2 * 1625 },	/* 13.0Mhz */
    817 			    {         0,          0 },	/* 16.8Mhz (not used) */
    818 			    { 130 *   8, 130 *   25 },	/* 19.2Mhz */
    819 			    {   2 * 384,   2 * 1625 },	/* 26.0Mhz */
    820 			    {   3 * 256,   3 * 1125 },	/* 27.0Mhz */
    821 			    { 130 *   4, 130 *   25 },	/* 38.4Mhz */
    822 			};
    823 			if (numer_demon[clksel][0] != numer) {
    824 				frac1 &= ~PRM_FRAC_INCR_NUM_SYS_MODE;
    825 				frac1 |= numer_demon[clksel][0];
    826 			}
    827 			if (numer_demon[clksel][1] != denom) {
    828 				frac2 &= ~PRM_FRAC_INCR_DENUM_DENOMINATOR;
    829 				frac2 |= numer_demon[clksel][1];
    830 			}
    831 			*(volatile uint32_t *)(frac1_reg + voffset) = frac1;
    832 			*(volatile uint32_t *)(frac2_reg + voffset) = frac2
    833 			    | PRM_FRAC_INCR_DENUM_RELOAD;
    834 			freq = OMAP5_GTIMER_FREQ;
    835 		}
    836 #endif
    837 		beagle_putchar('3');
    838 #if 0
    839 		if (gtimer_freq != freq) {
    840 			armreg_cnt_frq_write(freq);	// secure only
    841 		}
    842 #endif
    843 		omap5_cnt_frq = freq;
    844 		beagle_putchar('4');
    845 	}
    846 #endif
    847 }
    848 #endif /* OMAP_4XXX || OMAP_5XXX */
    849 
    850 
    851 #if defined(OMAP_4XXX) || defined(OMAP_5XXX) || defined(TI_AM335X)
    852 static inline uint32_t
    853 emif_read_sdram_config(vaddr_t emif_base)
    854 {
    855 #ifdef CPU_CORTEXA15
    856 	return 0x61851b32; // XXX until i figure out why deref emif_base dies
    857 #else
    858 	emif_base += EMIF_SDRAM_CONFIG;
    859 	//printf("%s: sdram_config @ %#"PRIxVADDR" = ", __func__, emif_base);
    860 	uint32_t v = *(const volatile uint32_t *)(emif_base);
    861 	//printf("%#x\n", v);
    862 	return v;
    863 #endif
    864 }
    865 
    866 static psize_t
    867 emif_memprobe(void)
    868 {
    869 	uint32_t sdram_config = emif_read_sdram_config(OMAP_EMIF1_VBASE);
    870 	psize_t memsize = 1L;
    871 #if defined(TI_AM335X)
    872 	/*
    873 	 * The original bbone's u-boot misprograms the EMIF so correct it
    874 	 * if we detect if it has the wrong value.
    875 	 */
    876 	if (sdram_config == 0x41805332)
    877 		sdram_config -= __SHIFTIN(1, SDRAM_CONFIG_RSIZE);
    878 #endif
    879 #ifdef OMAP_EMIF2_VBASE
    880 	/*
    881 	 * OMAP4 and OMAP5 have two EMIFs so if the 2nd one is configured
    882 	 * like the first, we have twice the memory.
    883 	 */
    884 	const uint32_t sdram_config2 = emif_read_sdram_config(OMAP_EMIF2_VBASE);
    885 	if (sdram_config2 == sdram_config)
    886 		memsize <<= 1;
    887 #endif
    888 
    889 	const u_int ebank = __SHIFTOUT(sdram_config, SDRAM_CONFIG_EBANK);
    890 	const u_int ibank = __SHIFTOUT(sdram_config, SDRAM_CONFIG_IBANK);
    891 	const u_int rsize = 9 + __SHIFTOUT(sdram_config, SDRAM_CONFIG_RSIZE);
    892 	const u_int pagesize = 8 + __SHIFTOUT(sdram_config, SDRAM_CONFIG_PAGESIZE);
    893 	const u_int width = 2 - __SHIFTOUT(sdram_config, SDRAM_CONFIG_WIDTH);
    894 #ifdef TI_AM335X
    895 	KASSERT(ebank == 0);	// No chip selects on Sitara
    896 #endif
    897 	memsize <<= (ebank + ibank + rsize + pagesize + width);
    898 #ifdef VERBOSE_INIT_ARM
    899 	printf("sdram_config = %#x, memsize = %uMB\n", sdram_config,
    900 	    (u_int)(memsize >> 20));
    901 #endif
    902 	return memsize;
    903 }
    904 #endif
    905 
    906 #if defined(OMAP_3XXX)
    907 #define SDRC_MCFG(p)		(0x80 + (0x30 * (p)))
    908 #define SDRC_MCFG_MEMSIZE(m)	((((m) & __BITS(8,17)) >> 8) * 2)
    909 static psize_t
    910 omap3_memprobe(void)
    911 {
    912 	const vaddr_t gpmc_base = OMAP_SDRC_VBASE;
    913 	const uint32_t mcfg0 = *(volatile uint32_t *)(gpmc_base + SDRC_MCFG(0));
    914 	const uint32_t mcfg1 = *(volatile uint32_t *)(gpmc_base + SDRC_MCFG(1));
    915 
    916 	printf("mcfg0 = %#x, size %lld\n", mcfg0, SDRC_MCFG_MEMSIZE(mcfg0));
    917 	printf("mcfg1 = %#x, size %lld\n", mcfg1, SDRC_MCFG_MEMSIZE(mcfg1));
    918 
    919 	return (SDRC_MCFG_MEMSIZE(mcfg0) + SDRC_MCFG_MEMSIZE(mcfg1)) * 1024 * 1024;
    920 }
    921 #endif
    922 
    923 /*
    924  * EDID can be read from DVI-D (HDMI) port on BeagleBoard from
    925  * If EDID data is present, this function fills in the supplied edid_buf
    926  * and returns true. Otherwise, it returns false and the contents of the
    927  * buffer are undefined.
    928  */
    929 static bool
    930 beagle_read_edid(uint8_t *edid_buf, size_t edid_buflen)
    931 {
    932 #if defined(OMAP_3530)
    933 	i2c_tag_t ic = NULL;
    934 	uint8_t reg;
    935 	int error;
    936 
    937 	/* On Beagleboard, EDID is accessed using I2C2 ("omapiic2"). */
    938 	extern i2c_tag_t omap3_i2c_get_tag(device_t);
    939 	ic = omap3_i2c_get_tag(device_find_by_xname("omapiic2"));
    940 
    941 	if (ic == NULL)
    942 		return false;
    943 
    944 	iic_acquire_bus(ic, 0);
    945 	for (reg = DDC_EDID_START; reg < edid_buflen; reg++) {
    946 		error = iic_exec(ic, I2C_OP_READ_WITH_STOP, DDC_ADDR,
    947 		    &reg, sizeof(reg), &edid_buf[reg], 1, 0);
    948 		if (error)
    949 			break;
    950 	}
    951 	iic_release_bus(ic, 0);
    952 
    953 	return error == 0 ? true : false;
    954 #else
    955 	return false;
    956 #endif
    957 }
    958 
    959 void
    960 beagle_device_register(device_t self, void *aux)
    961 {
    962 	prop_dictionary_t dict = device_properties(self);
    963 
    964 	if (device_is_a(self, "armperiph")
    965 	    && device_is_a(device_parent(self), "mainbus")) {
    966 		/*
    967 		 * XXX KLUDGE ALERT XXX
    968 		 * The iot mainbus supplies is completely wrong since it scales
    969 		 * addresses by 2.  The simpliest remedy is to replace with our
    970 		 * bus space used for the armcore regisers (which armperiph uses).
    971 		 */
    972 		struct mainbus_attach_args * const mb = aux;
    973 		mb->mb_iot = &omap_bs_tag;
    974 		return;
    975 	}
    976 
    977 #ifdef CPU_CORTEXA9
    978 	/*
    979 	 * We need to tell the A9 Global/Watchdog Timer
    980 	 * what frequency it runs at.
    981 	 */
    982 	if (device_is_a(self, "a9tmr") || device_is_a(self, "a9wdt")) {
    983 		/*
    984 		 * This clock always runs at (arm_clk div 2) and only goes
    985 		 * to timers that are part of the A9 MP core subsystem.
    986 		 */
    987                 prop_dictionary_set_uint32(dict, "frequency",
    988 		    curcpu()->ci_data.cpu_cc_freq / 2);
    989 		return;
    990 	}
    991 #endif
    992 
    993 #ifdef CPU_CORTEXA15
    994 	if (device_is_a(self, "armgtmr")) {
    995 		/*
    996 		 * The frequency of the generic timer was figured out when
    997 		 * determined the cpu frequency.
    998 		 */
    999                 prop_dictionary_set_uint32(dict, "frequency", omap5_cnt_frq);
   1000 	}
   1001 #endif
   1002 
   1003 	if (device_is_a(self, "ehci")) {
   1004 #if defined(OMAP_3530)
   1005 		/* XXX Beagleboard specific port configuration */
   1006 		prop_dictionary_set_uint16(dict, "nports", 3);
   1007 		prop_dictionary_set_cstring(dict, "port0-mode", "none");
   1008 		prop_dictionary_set_cstring(dict, "port1-mode", "phy");
   1009 		prop_dictionary_set_cstring(dict, "port2-mode", "none");
   1010 		prop_dictionary_set_bool(dict, "phy-reset", true);
   1011 		prop_dictionary_set_int16(dict, "port0-gpio", -1);
   1012 		prop_dictionary_set_int16(dict, "port1-gpio", 147);
   1013 		prop_dictionary_set_bool(dict, "port1-gpioval", true);
   1014 		prop_dictionary_set_int16(dict, "port2-gpio", -1);
   1015 		prop_dictionary_set_uint16(dict, "dpll5-m", 443);
   1016 		prop_dictionary_set_uint16(dict, "dpll5-n", 11);
   1017 		prop_dictionary_set_uint16(dict, "dpll5-m2", 4);
   1018 #endif
   1019 #if defined(TI_DM37XX)
   1020 		/* XXX Beagleboard specific port configuration */
   1021 		prop_dictionary_set_uint16(dict, "nports", 3);
   1022 		prop_dictionary_set_cstring(dict, "port0-mode", "none");
   1023 		prop_dictionary_set_cstring(dict, "port1-mode", "phy");
   1024 		prop_dictionary_set_cstring(dict, "port2-mode", "none");
   1025 		prop_dictionary_set_bool(dict, "phy-reset", true);
   1026 		prop_dictionary_set_int16(dict, "port0-gpio", -1);
   1027 		prop_dictionary_set_int16(dict, "port1-gpio", 56);
   1028 		prop_dictionary_set_bool(dict, "port1-gpioval", true);
   1029 		prop_dictionary_set_int16(dict, "port2-gpio", -1);
   1030 #if 0
   1031 		prop_dictionary_set_uint16(dict, "dpll5-m", 443);
   1032 		prop_dictionary_set_uint16(dict, "dpll5-n", 11);
   1033 		prop_dictionary_set_uint16(dict, "dpll5-m2", 4);
   1034 #endif
   1035 #endif
   1036 #if defined(OMAP_4430)
   1037 		prop_dictionary_set_uint16(dict, "nports", 2);
   1038 		prop_dictionary_set_bool(dict, "phy-reset", false);
   1039 		prop_dictionary_set_cstring(dict, "port0-mode", "none");
   1040 		prop_dictionary_set_int16(dict, "port0-gpio", -1);
   1041 		prop_dictionary_set_cstring(dict, "port1-mode", "phy");
   1042 		prop_dictionary_set_int16(dict, "port1-gpio", 62);
   1043 		prop_dictionary_set_bool(dict, "port1-gpioval", true);
   1044 		omap2_gpio_ctl(1, GPIO_PIN_OUTPUT);
   1045 		omap2_gpio_write(1, 1);		// Power Hub
   1046 #endif
   1047 #if defined(OMAP_5430)
   1048 		prop_dictionary_set_uint16(dict, "nports", 3);
   1049 		prop_dictionary_set_cstring(dict, "port0-mode", "none");
   1050 		prop_dictionary_set_int16(dict, "port0-gpio", -1);
   1051 		prop_dictionary_set_cstring(dict, "port1-mode", "hsic");
   1052 		prop_dictionary_set_int16(dict, "port1-gpio", -1);
   1053 		prop_dictionary_set_cstring(dict, "port2-mode", "hsic");
   1054 		prop_dictionary_set_int16(dict, "port2-gpio", -1);
   1055 #endif
   1056 #if defined(OMAP_5430)
   1057 		bus_space_tag_t iot = &omap_bs_tag;
   1058 		bus_space_handle_t ioh;
   1059 		omap2_gpio_ctl(80, GPIO_PIN_OUTPUT);
   1060 		omap2_gpio_write(80, 0);
   1061 		prop_dictionary_set_uint16(dict, "nports", 1);
   1062 		prop_dictionary_set_cstring(dict, "port0-mode", "hsi");
   1063 #if 0
   1064 		prop_dictionary_set_bool(dict, "phy-reset", true);
   1065 		prop_dictionary_set_int16(dict, "port0-gpio", 80);
   1066 		prop_dictionary_set_bool(dict, "port0-gpioval", true);
   1067 #endif
   1068 		int rv = bus_space_map(iot, OMAP5_CM_CTL_WKUP_REF_CLK0_OUT_REF_CLK1_OUT, 4, 0, &ioh);
   1069 		KASSERT(rv == 0);
   1070 		uint32_t v = bus_space_read_4(iot, ioh, 0);
   1071 		v &= 0xffff;
   1072 		v |= __SHIFTIN(OMAP5_CM_CTL_WKUP_MUXMODE1_REF_CLK1_OUT,
   1073 		    OMAP5_CM_CTL_WKUP_MUXMODE1);
   1074 		bus_space_write_4(iot, ioh, 0, v);
   1075 		bus_space_unmap(iot, ioh, 4);
   1076 
   1077 		omap2_gpio_write(80, 1);
   1078 #endif
   1079 		return;
   1080 	}
   1081 
   1082 	if (device_is_a(self, "sdhc")) {
   1083 #if defined(OMAP_3430) || defined(OMAP_3530)
   1084 		prop_dictionary_set_uint32(dict, "clkmask", 0);
   1085 		prop_dictionary_set_bool(dict, "8bit", true);
   1086 #endif
   1087 #if defined(TI_AM335X) && 0	// doesn't work
   1088 		struct obio_attach_args * const obio = aux;
   1089 		if (obio->obio_addr == SDMMC2_BASE_TIAM335X)
   1090 			prop_dictionary_set_bool(dict, "8bit", true);
   1091 #endif
   1092 		return;
   1093 	}
   1094 
   1095 	if (device_is_a(self, "omapfb")) {
   1096 		if (beagle_read_edid(beagle_edid, sizeof(beagle_edid))) {
   1097 			prop_dictionary_set(dict, "EDID",
   1098 			    prop_data_create_data(beagle_edid,
   1099 						  sizeof(beagle_edid)));
   1100 		}
   1101 		if (use_fb_console)
   1102 			prop_dictionary_set_bool(dict, "is_console", true);
   1103 		return;
   1104 	}
   1105 	if (device_is_a(self, "tifb")) {
   1106 		if (use_fb_console)
   1107 			prop_dictionary_set_bool(dict, "is_console", true);
   1108 		return;
   1109 	}
   1110 	if (device_is_a(self, "com")) {
   1111 		if (use_fb_console)
   1112 			prop_dictionary_set_bool(dict, "is_console", false);
   1113 	}
   1114 #if defined(TI_AM335X)
   1115 	if (device_is_a(self, "tps65217pmic")) {
   1116 		pmic_dev = self;
   1117 	}
   1118 #endif
   1119 }
   1120 
   1121 #if defined(TI_AM335X)
   1122 int
   1123 set_mpu_volt(int mvolt)
   1124 {
   1125 	if (pmic_dev == NULL)
   1126 		return ENODEV;
   1127 
   1128 	/* MPU voltage is on vdcd2 */
   1129 	return tps65217pmic_set_volt(pmic_dev, "DCDC2", mvolt);
   1130 }
   1131 #endif
   1132