Index: sys/arch/evbarm/conf/BEAGLEBONE =================================================================== RCS file: /cvsroot/src/sys/arch/evbarm/conf/BEAGLEBONE,v retrieving revision 1.3 diff -p -u -r1.3 BEAGLEBONE --- sys/arch/evbarm/conf/BEAGLEBONE 17 Oct 2012 14:48:11 -0000 1.3 +++ sys/arch/evbarm/conf/BEAGLEBONE 9 Dec 2012 08:52:19 -0000 @@ -132,7 +132,7 @@ options KTRACE # system call tracing, #options PERFCTRS # performance counters options DIAGNOSTIC # internally consistency checks -#options DEBUG +options DEBUG #options PMAP_DEBUG # Enable pmap_debug_level code #options IPKDB # remote kernel debugging #options VERBOSE_INIT_ARM # verbose bootstraping messages @@ -158,7 +158,7 @@ options UHUB_DEBUG # memorydisk= Set memorydisk size to KB # quiet Show aprint_naive output # verbose Show aprint_normal and aprint_verbose output -options BOOT_ARGS="\"\"" +options BOOT_ARGS="\"-d -v\"" config netbsd root on ? type ? @@ -175,31 +175,38 @@ options MEMSIZE=256 L3i0 at mainbus? # OBIO -obio0 at mainbus? base 0x48000000 size 0x1000000 # L4 CORE -obio1 at mainbus? base 0x48300000 size 0x0040000 # L4 WAKEUP -obio2 at mainbus? base 0x49000000 size 0x0100000 # L4 PERIPHERAL -#obio3 at mainbus? base 0x54000000 size 0x0800000 # L4 EMUL +obio0 at mainbus? base 0x44c00000 size 0x0400000 # L4_WKUP +obio1 at mainbus? base 0x48000000 size 0x1000000 # L4_PER +obio2 at mainbus? base 0x4a000000 size 0x1000000 # L4_FAST # General Purpose Memory Controller -gpmc0 at mainbus? base 0x6e000000 +gpmc0 at mainbus? base 0x50000000 + +# Interrupt Controller +omapicu0 at obio1 addr 0x48200000 size 0x1000 intrbase 0 + +# Power, Reset and Clock Management +prcm0 at obio0 addr 0x44e00000 size 0x2000 # PRM Module # SDHC controllers -sdhc0 at obio0 addr 0x4809C000 size 0x0400 intr 83 -#sdhc1 at obio0 addr 0x480B4000 size 0x0400 intr 86 -#sdhc2 at obio0 addr 0x480AD000 size 0x0400 intr 94 +# XXX Kludge -- the am335x's mmc registers start at an offset of #x100 +# from other omap3. (What about omap4?) Need to adapt the omap sdhc +# driver to handle this. +sdhc0 at obio1 addr 0x48060100 size 0x0f00 intr 64 +sdhc1 at obio1 addr 0x481d8100 size 0x0f00 intr 28 +#sdhc2 at obio1? L3i0? base 0x47811000 size 0x0ff00 intr 29 sdmmc* at sdhc? # SD/MMC bus ld* at sdmmc? -# Interrupt Controller -omapicu0 at obio0 addr 0x48200000 size 0x1000 intrbase 0 -omapgpio0 at obio1 addr 0x48310000 size 0x0400 intrbase 96 intr 29 -#omapgpio1 at obio2 addr 0x49050000 size 0x0400 intrbase 128 intr 30 -#omapgpio2 at obio2 addr 0x49052000 size 0x0400 intrbase 160 intr 31 -#omapgpio3 at obio2 addr 0x49054000 size 0x0400 intrbase 192 intr 32 -omapgpio4 at obio2 addr 0x49056000 size 0x0400 intrbase 224 intr 33 -#omapgpio5 at obio2 addr 0x49058000 size 0x0400 intrbase 256 intr 34 +# General-purpose I/O pins +#omapgpio0 at obio1 addr 0x44e07000 size 0x1000 intrbase 96 intr 29 +##omapgpio1 at obio2 addr 0x49050000 size 0x0400 intrbase 128 intr 30 +##omapgpio2 at obio2 addr 0x49052000 size 0x0400 intrbase 160 intr 31 +##omapgpio3 at obio2 addr 0x49054000 size 0x0400 intrbase 192 intr 32 +#omapgpio4 at obio2 addr 0x49056000 size 0x0400 intrbase 224 intr 33 +##omapgpio5 at obio2 addr 0x49058000 size 0x0400 intrbase 256 intr 34 -gpio* at omapgpio? +#gpio* at omapgpio? # # I2C Controller # omapi2c0 at tipb? addr 0xfffb3800 intr 36 mult 4 @@ -211,24 +218,36 @@ gpio* at omapgpio? # options I2C_HIGH_TIME_nSEC=1000 # On-board 16550 UARTs -com0 at obio2 addr 0x44e09000 intr 74 mult 4 # UART3 (console) +# XXX Currently broken for AM335X, because it gets attached before the +# interrupt controller (which is on obio1), but its attachment routine +# tries to establish an interrupt handler. The right way to handle +# this, I think, is just to kill the distinction between the obioN so +# that we can control the order in which all the obio devices attach, +# across power domains. +com0 at obio0 addr 0x44e09000 size 0x1000 intr 72 mult 4 # UART0 options CONSADDR=0x44e09000, CONSPEED=115200 -# Operating System Timer -omapmputmr0 at obio2 addr 0x49032000 intr 38 # GP Timer 2 -# Statistics Timer -omapmputmr1 at obio2 addr 0x49034000 intr 39 # GP Timer 3 -# Microtime Reference Timer -omapmputmr2 at obio2 addr 0x49036000 intr 40 # GP Timer 4 -options OMAP_MPU_TIMER_CLOCK_FREQ=12000000 +# XXX Clock assignment is kinda random. My DM timer 3 seems to be +# unhappy and I don't know why. DM timer 0 doesn't seem to deliver +# interrupts for the hard clock, although it seems to be the obvious +# choice. + +# Hardclock timer +omapdmtimer0 at obio1 addr 0x48040000 size 0x1000 intr 68 # DM Timer 2 + +# Time counter +omapdmtimer1 at obio0 addr 0x44e31000 size 0x1000 intr 67 # DM Timer 1ms + +# Statclock timer +omapdmtimer2 at obio1 addr 0x48044000 size 0x1000 intr 92 # DM Timer 4 + +options OMAP_SYSTEM_CLOCK_FREQ=24000000 # Watchdog timers -omapwdt32k* at obio2 addr 0x49030000 size 2048 # WDT3 -#omapwdt32k* at obio1 addr 0x4830c000 size 2048 # WDT1 -#omapwdt32k* at obio1 addr 0x48314000 size 2048 # WDT2 +#omapwdt32k* at obio0 addr 0x44e35000 size 0x1000 # WDT1 # onboard video -#omapfb* at obio0 addr 0x48050000 size 0x10000 +#omapfb* at obio1 addr 0x48050000 size 0x10000 # make sure the console display is always wsdisplay0 #wsdisplay0 at wsemuldisplaydev? console 1 @@ -250,12 +269,9 @@ omapwdt32k* at obio2 addr 0x49030000 siz pseudo-device wsmux # mouse & keyboard multiplexor pseudo-device wsfont -# Power, Reset and Clock Management -prcm* at obio1 addr 0x48306000 size 0x2000 # PRM Module - # On-board USB -#ehci* at obio0 addr 0x48064800 size 0x0400 intr 77 -#ohci* at obio0 addr 0x48064400 size 0x0400 intr 76 +#ehci* at obio1 addr 0x48064800 size 0x0400 intr 77 +#ohci* at obio1 addr 0x48064400 size 0x0400 intr 76 #usb* at ohci? #usb* at ehci? #uhub* at usb? @@ -279,7 +295,7 @@ options OMAP_CK_REF_SPEED=12000000 # Pseudo-Devices # disk/mass storage pseudo-devices -pseudo-device md # memory disk device (ramdisk) +#pseudo-device md # memory disk device (ramdisk) #pseudo-device vnd # disk-like interface to files #pseudo-device fss # file system snapshot device #pseudo-device putter # for puffs and pud Index: sys/arch/arm/omap/am335x_dmtimer.c =================================================================== RCS file: sys/arch/arm/omap/am335x_dmtimer.c diff -N sys/arch/arm/omap/am335x_dmtimer.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/omap/am335x_dmtimer.c 9 Dec 2012 08:52:20 -0000 @@ -0,0 +1,143 @@ +/* $NetBSD$ */ + +/* + * TI OMAP Dual-mode timer attachments for AM335x + */ + +/*- + * Copyright (c) 2012 Taylor R. Campbell + * 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. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 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 +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#ifndef STATHZ +# define STATHZ 97 +#endif + +struct am335x_dmtimer { + const char *ad_name; + unsigned int ad_version; + bus_addr_t ad_base_addr; + int ad_intr; + struct omap_module ad_module; +}; + +static const struct am335x_dmtimer am335x_dmtimers[] = { + { "DMTIMER0", 2, 0x44e05000, 66, { AM335X_PRCM_CM_WKUP, 0x10 } }, + { "DMTIMER1ms", 1, 0x44e31000, 67, { AM335X_PRCM_CM_WKUP, 0xc4 } }, + { "DMTIMER2", 2, 0x48040000, 68, { AM335X_PRCM_CM_PER, 0x80 } }, + { "DMTIMER3", 2, 0x48042000, 69, { AM335X_PRCM_CM_PER, 0x84 } }, + { "DMTIMER4", 2, 0x48044000, 92, { AM335X_PRCM_CM_PER, 0x88 } }, + { "DMTIMER5", 2, 0x48046000, 93, { AM335X_PRCM_CM_PER, 0xec } }, + { "DMTIMER6", 2, 0x48048000, 94, { AM335X_PRCM_CM_PER, 0xf0 } }, + { "DMTIMER7", 2, 0x4804a000, 95, { AM335X_PRCM_CM_PER, 0x7c } }, +}; + +static int am335x_dmtimer_match(device_t, cfdata_t, void *); +static void am335x_dmtimer_attach(device_t, device_t, void *); + +CFATTACH_DECL_NEW(omap_dmtimer_obio, sizeof(struct omap_dmtimer_softc), + am335x_dmtimer_match, am335x_dmtimer_attach, NULL, NULL); + +static int +am335x_dmtimer_match(device_t parent, cfdata_t match, void *aux) +{ + struct obio_attach_args *obio = aux; + size_t i; + + if (obio->obio_size != 0x1000) + return 0; + + for (i = 0; i < __arraycount(am335x_dmtimers); i++) + if ((obio->obio_addr == am335x_dmtimers[i].ad_base_addr) && + (obio->obio_intr == am335x_dmtimers[i].ad_intr)) + return 1; + + return 0; +} + +static void +am335x_dmtimer_attach(device_t parent, device_t self, void *aux) +{ + struct omap_dmtimer_softc *sc = device_private(self); + struct obio_attach_args *obio = aux; + const struct am335x_dmtimer *ad = NULL; + size_t i; + + for (i = 0; i < __arraycount(am335x_dmtimers); i++) + if ((obio->obio_addr == am335x_dmtimers[i].ad_base_addr) && + (obio->obio_intr == am335x_dmtimers[i].ad_intr)) { + ad = &am335x_dmtimers[i]; + break; + } + + KASSERT(ad != NULL); + aprint_normal(" %s", ad->ad_name); + + sc->sc_dev = self; + sc->sc_module = &ad->ad_module; + sc->sc_version = ad->ad_version; + sc->sc_intr = ad->ad_intr; + sc->sc_iot = obio->obio_iot; + + KASSERT(obio->obio_size == 0x1000); + if (bus_space_map(obio->obio_iot, obio->obio_addr, obio->obio_size, 0, + &sc->sc_ioh) != 0) + panic("%s: unable to map bus space", device_xname(self)); + + /* XXX Crock. */ + switch (device_unit(self)) { + case 0: + omap_dmtimer_attach_hardclock(sc); + break; + + case 1: + omap_dmtimer_attach_timecounter(sc); + break; + + case 2: + KASSERT(stathz == 0); + profhz = stathz = STATHZ; + omap_dmtimer_attach_statclock(sc); + break; + + default: + panic("%s: but what am I to do?", device_xname(self)); + } + + aprint_normal("\n"); +} Index: sys/arch/arm/omap/am335x_prcm.c =================================================================== RCS file: sys/arch/arm/omap/am335x_prcm.c diff -N sys/arch/arm/omap/am335x_prcm.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/omap/am335x_prcm.c 9 Dec 2012 08:52:20 -0000 @@ -0,0 +1,92 @@ +/* $NetBSD$ */ + +/* + * TI OMAP Power, Reset, and Clock Management on the AM335x + */ + +/*- + * Copyright (c) 2012 Taylor R. Campbell + * 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. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 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 +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include + +#include +#include + +#define AM335X_CLKCTRL_MODULEMODE_MASK __BITS(0, 1) +#define AM335X_CLKCTRL_MODULEMODE_DISABLED 0 +#define AM335X_CLKCTRL_MODULEMODE_ENABLE 2 + +static void +am335x_prcm_check_clkctrl(bus_size_t cm_module, + bus_size_t clkctrl_reg, uint32_t v) +{ +#ifdef DIAGNOSTIC + uint32_t u = prcm_read_4(cm_module, clkctrl_reg); + + if (__SHIFTOUT(u, AM335X_CLKCTRL_MODULEMODE_MASK) != + __SHIFTOUT(v, AM335X_CLKCTRL_MODULEMODE_MASK)) + aprint_error("clkctrl didn't take: %"PRIx32" -/-> %"PRIx32"\n", + u, v); +#else + (void)cm_module; + (void)clkctrl_reg; + (void)v; +#endif +} + +void +prcm_module_enable(const struct omap_module *om) +{ + bus_size_t cm_module = om->om_prcm_cm_module; + bus_size_t clkctrl_reg = om->om_prcm_cm_clkctrl_reg; + uint32_t clkctrl; + + clkctrl = prcm_read_4(cm_module, clkctrl_reg); + clkctrl &=~ AM335X_CLKCTRL_MODULEMODE_MASK; + clkctrl |= __SHIFTIN(AM335X_CLKCTRL_MODULEMODE_ENABLE, + AM335X_CLKCTRL_MODULEMODE_MASK); + prcm_write_4(cm_module, clkctrl_reg, clkctrl); + am335x_prcm_check_clkctrl(cm_module, clkctrl_reg, clkctrl); +} + +void +prcm_module_disable(const struct omap_module *om) +{ + bus_size_t cm_module = om->om_prcm_cm_module; + bus_size_t clkctrl_reg = om->om_prcm_cm_clkctrl_reg; + uint32_t clkctrl; + + clkctrl = prcm_read_4(cm_module, clkctrl_reg); + clkctrl &=~ AM335X_CLKCTRL_MODULEMODE_MASK; + clkctrl |= __SHIFTIN(AM335X_CLKCTRL_MODULEMODE_DISABLED, + AM335X_CLKCTRL_MODULEMODE_MASK); + prcm_write_4(cm_module, clkctrl_reg, clkctrl); + am335x_prcm_check_clkctrl(cm_module, clkctrl_reg, clkctrl); +} Index: sys/arch/arm/omap/am335x_prcm.h =================================================================== RCS file: sys/arch/arm/omap/am335x_prcm.h diff -N sys/arch/arm/omap/am335x_prcm.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/omap/am335x_prcm.h 9 Dec 2012 08:52:20 -0000 @@ -0,0 +1,61 @@ +/* $NetBSD$ */ + +/* + * TI OMAP Power, Reset, and Clock Management on the AM335x + */ + +/*- + * Copyright (c) 2012 Taylor R. Campbell + * 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. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 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. + */ + +#ifndef _ARM_OMAP_AM335X_PRCM_H_ +#define _ARM_OMAP_AM335X_PRCM_H_ + +#include + +struct omap_module { + bus_size_t om_prcm_cm_module; + bus_size_t om_prcm_cm_clkctrl_reg; +}; + +#define AM335X_PRCM_CM_PER 0x0000 +#define AM335X_PRCM_CM_WKUP 0x0400 +#define AM335X_PRCM_CM_DPLL 0x0500 +#define AM335X_PRCM_CM_MPU 0x0600 +#define AM335X_PRCM_CM_DEVICE 0x0700 +#define AM335X_PRCM_CM_RTC 0x0800 +#define AM335X_PRCM_CM_GFX 0x0900 +#define AM335X_PRCM_CM_CEFUSE 0x0a00 + +#define AM335X_PRCM_PRM_IRQ 0x0b00 +#define AM335X_PRCM_PRM_PER 0x0c00 +#define AM335X_PRCM_PRM_WKUP 0x0d00 +#define AM335X_PRCM_PRM_MPU 0x0e00 +#define AM335X_PRCM_PRM_DEVICE 0x0f00 +#define AM335X_PRCM_PRM_RTC 0x1000 +#define AM335X_PRCM_PRM_GFX 0x1100 +#define AM335X_PRCM_PRM_CEFUSE 0x1200 + +#endif /* _ARM_OMAP_AM335X_PRCM_H_ */ Index: sys/arch/arm/omap/files.omap2 =================================================================== RCS file: /cvsroot/src/sys/arch/arm/omap/files.omap2,v retrieving revision 1.15 diff -p -u -r1.15 files.omap2 --- sys/arch/arm/omap/files.omap2 5 Sep 2012 00:19:59 -0000 1.15 +++ sys/arch/arm/omap/files.omap2 9 Dec 2012 08:52:20 -0000 @@ -47,6 +47,14 @@ device omapgpio: gpiobus attach omapgpio at obio with omap2gpio file arch/arm/omap/omap2_gpio.c (omap2 | omap3) & omapgpio +# OMAP dual-mode timer +device omapdmtimer +file arch/arm/omap/omap_dmtimer.c omapdmtimer +defparam opt_omap.h OMAP_SYSTEM_CLOCK_FREQ + +attach omapdmtimer at obio with omap_dmtimer_obio +file arch/arm/omap/am335x_dmtimer.c ti_am335x & omapdmtimer + # OMAP 2430 General Purpose Timer device omapmputmr file arch/arm/omap/omap2_mputmr.c omapmputmr @@ -97,6 +105,7 @@ file arch/arm/omap/omap2_nand.c omapnan device prcm attach prcm at obio file arch/arm/omap/omap2_prcm.c prcm needs-flag +file arch/arm/omap/am335x_prcm.c ti_am335x # OHCI USB controller attach ohci at obio with obioohci Index: sys/arch/arm/omap/omap2_obio.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/omap/omap2_obio.c,v retrieving revision 1.14 diff -p -u -r1.14 omap2_obio.c --- sys/arch/arm/omap/omap2_obio.c 5 Sep 2012 00:19:59 -0000 1.14 +++ sys/arch/arm/omap/omap2_obio.c 9 Dec 2012 08:52:20 -0000 @@ -351,6 +351,10 @@ static const struct { #if 0 { .name = "dmac", .addr = DMAC_BASE, .required = true }, #endif +#if defined(TI_AM335X) + { .name = "omapicu", .addr = 0x48200000, .required = true }, + { .name = "prcm", .addr = 0x44e00000, .required = true }, +#endif }; static void Index: sys/arch/arm/omap/omap2_prcm.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/omap/omap2_prcm.c,v retrieving revision 1.3 diff -p -u -r1.3 omap2_prcm.c --- sys/arch/arm/omap/omap2_prcm.c 31 Jan 2012 04:31:37 -0000 1.3 +++ sys/arch/arm/omap/omap2_prcm.c 9 Dec 2012 08:52:20 -0000 @@ -77,6 +77,7 @@ prcm_attach(device_t parent, device_t se { struct obio_attach_args *obio = aux; + KASSERT(prcm_sc == NULL); prcm_sc = device_private(self); prcm_sc->sc_dev = self; @@ -84,7 +85,7 @@ prcm_attach(device_t parent, device_t se prcm_sc->sc_base = obio->obio_addr; prcm_sc->sc_size = OMAP2_PRM_SIZE; - + /* map i/o space for PRM */ if (bus_space_map(prcm_sc->sc_iot, prcm_sc->sc_base, prcm_sc->sc_size, 0, &prcm_sc->sc_ioh) != 0) { @@ -95,16 +96,20 @@ prcm_attach(device_t parent, device_t se aprint_normal(": Power, Reset and Clock Management\n"); } -static uint32_t -prcm_read(bus_addr_t module, bus_addr_t reg) -{ +uint32_t +prcm_read_4(bus_size_t module, bus_size_t reg) +{ + + KASSERT(prcm_sc != NULL); return bus_space_read_4(prcm_sc->sc_iot, prcm_sc->sc_ioh, module + reg); } -static void -prcm_write(bus_addr_t module, bus_addr_t reg, uint32_t data) -{ +void +prcm_write_4(bus_size_t module, bus_size_t reg, uint32_t data) +{ + + KASSERT(prcm_sc != NULL); bus_space_write_4(prcm_sc->sc_iot, prcm_sc->sc_ioh, module + reg, data); } @@ -113,10 +118,10 @@ void prcm_cold_reset(void) { uint32_t val; - - val = prcm_read(OMAP3430_GR_MOD, OMAP2_RM_RSTCTRL); + + val = prcm_read_4(OMAP3430_GR_MOD, OMAP2_RM_RSTCTRL); val |= OMAP_RST_DPLL3; - prcm_write(OMAP3430_GR_MOD, OMAP2_RM_RSTCTRL, val); + prcm_write_4(OMAP3430_GR_MOD, OMAP2_RM_RSTCTRL, val); } Index: sys/arch/arm/omap/omap2_prcm.h =================================================================== RCS file: /cvsroot/src/sys/arch/arm/omap/omap2_prcm.h,v retrieving revision 1.1 diff -p -u -r1.1 omap2_prcm.h --- sys/arch/arm/omap/omap2_prcm.h 28 Aug 2010 13:02:32 -0000 1.1 +++ sys/arch/arm/omap/omap2_prcm.h 9 Dec 2012 08:52:20 -0000 @@ -26,9 +26,16 @@ * SUCH DAMAGE. */ -#ifndef _OMAP2_PRCM_H_ -#define _OMAP2_PRCM_H_ +#ifndef _ARM_OMAP_OMAP2_PRCM_H_ +#define _ARM_OMAP_OMAP2_PRCM_H_ -void prcm_cold_reset(void); +struct omap_module; -#endif +uint32_t prcm_read_4(bus_size_t, bus_size_t); +void prcm_write_4(bus_size_t, bus_size_t, uint32_t); +void prcm_cold_reset(void); + +void prcm_module_enable(const struct omap_module *); +void prcm_module_disable(const struct omap_module *); + +#endif /* _ARM_OMAP_OMAP2_PRCM_H_ */ Index: sys/arch/arm/omap/omap3_sdhc.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/omap/omap3_sdhc.c,v retrieving revision 1.2 diff -p -u -r1.2 omap3_sdhc.c --- sys/arch/arm/omap/omap3_sdhc.c 29 Oct 2012 13:30:25 -0000 1.2 +++ sys/arch/arm/omap/omap3_sdhc.c 9 Dec 2012 08:52:20 -0000 @@ -45,6 +45,11 @@ __KERNEL_RCSID(0, "$NetBSD: omap3_sdhc.c #include #include +#ifdef TI_AM335X +# include +# include +#endif + #include #include @@ -72,6 +77,22 @@ struct obiosdhc_softc { void *sc_ih; /* interrupt vectoring */ }; +#ifdef TI_AM335X +struct am335x_sdhc { + const char *as_name; + bus_addr_t as_base_addr; + int as_intr; + struct omap_module as_module; +}; + +static const struct am335x_sdhc am335x_sdhc[] = { + /* XXX All offset by 0x100 because of the am335x's mmc registers. */ + { "MMCSH0", 0x48060100, 64, { AM335X_PRCM_CM_PER, 0x3c } }, + { "MMC1", 0x481d8100, 28, { AM335X_PRCM_CM_PER, 0xf4 } }, + { "MMCSH2", 0x47810100, 29, { AM335X_PRCM_CM_WKUP, 0xf8 } }, +}; +#endif + CFATTACH_DECL_NEW(obiosdhc, sizeof(struct obiosdhc_softc), obiosdhc_match, obiosdhc_attach, obiosdhc_detach, NULL); @@ -81,6 +102,10 @@ obiosdhc_match(device_t parent, cfdata_t #ifdef OMAP_3530 struct obio_attach_args * const oa = aux; #endif +#ifdef TI_AM335X + struct obio_attach_args * const oa = aux; + size_t i; +#endif #ifdef OMAP_3530 if (oa->obio_addr == SDMMC1_BASE_3530 @@ -89,6 +114,13 @@ obiosdhc_match(device_t parent, cfdata_t return 1; #endif +#ifdef TI_AM335X + for (i = 0; i < __arraycount(am335x_sdhc); i++) + if ((oa->obio_addr == am335x_sdhc[i].as_base_addr) && + (oa->obio_intr == am335x_sdhc[i].as_intr)) + return 1; +#endif + return 0; } @@ -99,6 +131,9 @@ obiosdhc_attach(device_t parent, device_ struct obio_attach_args * const oa = aux; uint32_t clkd, stat; int error, timo, clksft, n; +#ifdef TI_AM335X + size_t i; +#endif sc->sc.sc_dmat = oa->obio_dmat; sc->sc.sc_dev = self; @@ -131,6 +166,17 @@ obiosdhc_attach(device_t parent, device_ aprint_naive(": SDHC controller\n"); aprint_normal(": SDHC controller\n"); +#ifdef TI_AM335X + /* XXX Not really AM335X-specific. */ + for (i = 0; i < __arraycount(am335x_sdhc); i++) + if ((oa->obio_addr == am335x_sdhc[i].as_base_addr) && + (oa->obio_intr == am335x_sdhc[i].as_intr)) { + prcm_module_enable(&am335x_sdhc[i].as_module); + break; + } + KASSERT(i < __arraycount(am335x_sdhc)); +#endif + /* XXXXXX: Turn-on regurator via I2C. */ /* XXXXXX: And enable ICLOCK/FCLOCK. */ Index: sys/arch/arm/omap/omap_dmtimer.c =================================================================== RCS file: sys/arch/arm/omap/omap_dmtimer.c diff -N sys/arch/arm/omap/omap_dmtimer.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/omap/omap_dmtimer.c 9 Dec 2012 08:52:20 -0000 @@ -0,0 +1,402 @@ +/* $NetBSD$ */ + +/* + * TI OMAP Dual-mode timers + */ + +/*- + * Copyright (c) 2012 Taylor R. Campbell + * 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. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 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 +__KERNEL_RCSID(0, "$NetBSD$"); + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +typedef uint8_t dmt_reg_t; +typedef uint16_t dmt_timer_reg_t; + +static unsigned int + dmt_tc_get_timecount(struct timecounter *); +static int dmt_hardintr(void *); +static int dmt_statintr(void *); +static void dmt_start_periodic_intr(struct omap_dmtimer_softc *, int, + unsigned int, int (*)(void *)); +static void dmt_set_periodic_intr_frequency(struct omap_dmtimer_softc *, + unsigned int); +static void dmt_start_timecounter(struct omap_dmtimer_softc *); +static unsigned int + dmt_get_timecount(struct omap_dmtimer_softc *); +static void dmt_start(struct omap_dmtimer_softc *, unsigned int); +static void dmt_reset(struct omap_dmtimer_softc *); +static void dmt_enable(struct omap_dmtimer_softc *); +static void dmt_intr_enable(struct omap_dmtimer_softc *, uint32_t); +static void dmt_intr_ack(struct omap_dmtimer_softc *, uint32_t); +static uint32_t dmt_timer_read_4(struct omap_dmtimer_softc *, dmt_timer_reg_t); +static void dmt_timer_write_4(struct omap_dmtimer_softc *, dmt_timer_reg_t, + uint32_t); +static void dmt_timer_write_post_wait(struct omap_dmtimer_softc *, + dmt_timer_reg_t); +static uint32_t dmt_read_4(struct omap_dmtimer_softc *, dmt_reg_t); +static void dmt_write_4(struct omap_dmtimer_softc *, dmt_reg_t, uint32_t); + +static struct omap_dmtimer_softc *hardclock_sc; +static struct omap_dmtimer_softc *statclock_sc; +static struct timecounter dmt_timecounter; + +void +omap_dmtimer_attach_timecounter(struct omap_dmtimer_softc *sc) +{ + + if (dmt_timecounter.tc_priv != NULL) + panic("omap dmtimer timecounter already initialized"); + + dmt_timecounter.tc_priv = sc; +} + +static struct timecounter dmt_timecounter = { + .tc_get_timecount = dmt_tc_get_timecount, + .tc_counter_mask = 0xffffffff, /* XXXMAGIC Make sense? */ + .tc_frequency = OMAP_SYSTEM_CLOCK_FREQ, /* XXXPOWER */ + .tc_name = "dmtimer", /* XXX Which one? */ + .tc_quality = 100, /* XXXMAGIC? */ + .tc_priv = NULL, +}; + +static unsigned int +dmt_tc_get_timecount(struct timecounter *tc) +{ + struct omap_dmtimer_softc *sc = tc->tc_priv; + + if (sc == NULL) + panic("uninitialized omap dmtimer timecounter"); + + return dmt_get_timecount(sc); +} + +void +omap_dmtimer_attach_hardclock(struct omap_dmtimer_softc *sc) +{ + + if (hardclock_sc != NULL) + panic("%s: replacing hardclock %s", device_xname(sc->sc_dev), + device_xname(hardclock_sc->sc_dev)); + hardclock_sc = sc; +} + +void +omap_dmtimer_attach_statclock(struct omap_dmtimer_softc *sc) +{ + + KASSERT(stathz != 0); + if (statclock_sc != NULL) + panic("%s: replacing statclock %s", device_xname(sc->sc_dev), + device_xname(statclock_sc->sc_dev)); + statclock_sc = sc; +} + +void +cpu_initclocks(void) +{ + struct omap_dmtimer_softc *timecounter_sc = dmt_timecounter.tc_priv; + + if (hardclock_sc == NULL) + panic("omap dmtimer hardclock not initialized"); + dmt_enable(hardclock_sc); + dmt_start_periodic_intr(hardclock_sc, IPL_CLOCK, hz, &dmt_hardintr); + + if (timecounter_sc == NULL) + panic("omap dmtimer timecounter not initialized"); + dmt_enable(statclock_sc); + dmt_start_periodic_intr(statclock_sc, IPL_HIGH, stathz, &dmt_statintr); + + if (statclock_sc == NULL) + panic("omap dmtimer statclock not initialized"); + dmt_enable(timecounter_sc); + dmt_start_timecounter(timecounter_sc); + tc_init(&dmt_timecounter); +} + +void +setstatclockrate(int rate) +{ + struct omap_dmtimer_softc *sc = statclock_sc; + + if (rate < 0) + panic("I can't run the statistics clock backward!"); + + if (sc == NULL) + panic("There is no statclock timer!\n"); + + dmt_set_periodic_intr_frequency(sc, rate); +} + +static int +dmt_hardintr(void *frame) +{ + struct omap_dmtimer_softc *sc = hardclock_sc; + unsigned int counter; + + if (counter == 0) + aprint_error("omap dmtimer hardclock intr\n"); + counter = ((counter + 1) % 100); + KASSERT(sc != NULL); + dmt_intr_ack(sc, OMAP_DMTIMER_INTR_ALL); + hardclock(frame); + + return 1; +} + +static int +dmt_statintr(void *frame) +{ + struct omap_dmtimer_softc *sc = statclock_sc; + + KASSERT(sc != NULL); + dmt_intr_ack(sc, OMAP_DMTIMER_INTR_ALL); + statclock(frame); + + return 1; +} + +static void +dmt_start_periodic_intr(struct omap_dmtimer_softc *sc, int ipl, + unsigned int frequency, int (*func)(void *)) +{ + + dmt_reset(sc); + dmt_start(sc, frequency); + /* + * Null argument means func gets the interrupt frame. For + * whatever reason it's not an option to pass an argument (such + * as sc) and the interrupt frame both, which is why we have + * the global hardclock_sc and statclock_sc. + */ + intr_establish(sc->sc_intr, ipl, IST_LEVEL, func, 0); + dmt_intr_enable(sc, OMAP_DMTIMER_INTR_OVERFLOW); +} + +static void +dmt_set_periodic_intr_frequency(struct omap_dmtimer_softc *sc, + unsigned int frequency) +{ + + dmt_reset(sc); + dmt_start(sc, frequency); + dmt_intr_enable(sc, OMAP_DMTIMER_INTR_OVERFLOW); +} + +static void +dmt_start_timecounter(struct omap_dmtimer_softc *sc) +{ + + /* + * XXXPOWER On reset, the timer uses the system clock. For + * low-power operation, we can configure timers to use less + * frequent clocks, but there's currently no abstraction for + * doing this. + */ + dmt_reset(sc); + dmt_timer_write_4(sc, OMAP_DMTIMER_TIMER_LOAD, 0); + dmt_timer_write_4(sc, OMAP_DMTIMER_TIMER_COUNTER, 0); + dmt_timer_write_4(sc, OMAP_DMTIMER_TIMER_CTRL, + (OMAP_DMTIMER_TIMER_CTRL_START | + OMAP_DMTIMER_TIMER_CTRL_AUTORELOAD)); +} + +static unsigned int +dmt_get_timecount(struct omap_dmtimer_softc *sc) +{ + + return dmt_timer_read_4(sc, OMAP_DMTIMER_TIMER_COUNTER); +} + +static void +dmt_start(struct omap_dmtimer_softc *sc, unsigned int frequency) +{ + uint32_t value; + + /* + * XXXPOWER Should do something clever with prescaling and + * clock selection to save power. + */ + + value = (0xffffffff - ((OMAP_SYSTEM_CLOCK_FREQ / frequency) - 1)); + + dmt_timer_write_4(sc, OMAP_DMTIMER_TIMER_LOAD, value); + dmt_timer_write_4(sc, OMAP_DMTIMER_TIMER_COUNTER, value); + + dmt_timer_write_4(sc, OMAP_DMTIMER_TIMER_CTRL, + (OMAP_DMTIMER_TIMER_CTRL_START | + OMAP_DMTIMER_TIMER_CTRL_AUTORELOAD)); +} + +static void +dmt_reset(struct omap_dmtimer_softc *sc) +{ + uint32_t reset_mask; + unsigned int tries = 1000; /* XXXMAGIC */ + + if (sc->sc_version == 1) + reset_mask = OMAP_DMTIMER_V1_OCP_CFG_SOFTRESET_MASK; + else + reset_mask = OMAP_DMTIMER_V2_OCP_CFG_SOFTRESET_MASK; + + dmt_write_4(sc, OMAP_DMTIMER_OCP_CFG, reset_mask); + while (dmt_read_4(sc, OMAP_DMTIMER_OCP_CFG) & reset_mask) { + if (--tries == 0) + panic("unable to reset dmtimer %p", sc); + DELAY(10); /* XXXMAGIC */ + } + + /* + * Posted mode is enabled on reset on the OMAP35x but disabled + * on reset on the AM335x, so handle both cases. + * + * XXXPOWER Does enabling this reduce power consumption? + */ + sc->sc_posted = + (0 != (dmt_read_4(sc, OMAP_DMTIMER_TIMER_SYNC_INT_CTRL) + & OMAP_DMTIMER_TIMER_SYNC_INT_CTRL_POSTED)); +} + +static void +dmt_enable(struct omap_dmtimer_softc *sc) +{ + + if (!sc->sc_enabled) { + prcm_module_enable(sc->sc_module); + sc->sc_enabled = 1; + } +} + +static void +dmt_intr_enable(struct omap_dmtimer_softc *sc, uint32_t intr) +{ + + if (sc->sc_version == 1) { + dmt_write_4(sc, OMAP_DMTIMER_V1_INTR_ENABLE, intr); + } else { + dmt_write_4(sc, OMAP_DMTIMER_V2_INTR_ENABLE_CLEAR, + (OMAP_DMTIMER_INTR_ALL &~ intr)); + dmt_write_4(sc, OMAP_DMTIMER_V2_INTR_ENABLE_SET, intr); + } +} + +static void +dmt_intr_ack(struct omap_dmtimer_softc *sc, uint32_t intr) +{ + + if (sc->sc_version == 1) + dmt_write_4(sc, OMAP_DMTIMER_V1_INTR_STATUS, intr); + else + dmt_write_4(sc, OMAP_DMTIMER_V2_INTR_STATUS, intr); +} + +static uint32_t +dmt_timer_read_4(struct omap_dmtimer_softc *sc, dmt_timer_reg_t reg) +{ + dmt_reg_t timer_base; + + if (sc->sc_version == 1) + timer_base = OMAP_DMTIMER_V1_TIMER_REGS; + else + timer_base = OMAP_DMTIMER_V2_TIMER_REGS; + + dmt_timer_write_post_wait(sc, reg); + return dmt_read_4(sc, (timer_base + reg)); +} + +static void +dmt_timer_write_4(struct omap_dmtimer_softc *sc, dmt_timer_reg_t reg, + uint32_t value) +{ + dmt_reg_t timer_base; + + if (sc->sc_version == 1) + timer_base = OMAP_DMTIMER_V1_TIMER_REGS; + else + timer_base = OMAP_DMTIMER_V2_TIMER_REGS; + + dmt_timer_write_post_wait(sc, reg); + dmt_write_4(sc, (timer_base + reg), value); +} + +static void +dmt_timer_write_post_wait(struct omap_dmtimer_softc *sc, dmt_timer_reg_t reg) +{ + dmt_reg_t timer_base; + + if (sc->sc_version == 1) + timer_base = OMAP_DMTIMER_V1_TIMER_REGS; + else + timer_base = OMAP_DMTIMER_V2_TIMER_REGS; + + /* + * Make sure we can read the TWPS (OMAP_DMTIMER_TIMER_WRITE_POST) + * register with vanilla dmt_read_4. + */ + CTASSERT(OMAP_DMTIMER_TIMER_WRITE_POST == + OMAP_DMTIMER_REG_POSTED_INDEX(OMAP_DMTIMER_TIMER_WRITE_POST)); + + if (sc->sc_posted && OMAP_DMTIMER_REG_POSTED_P(reg)) { + unsigned int tries = 1000; /* XXXMAGIC */ + const dmt_reg_t write_post_reg = (timer_base + + OMAP_DMTIMER_TIMER_WRITE_POST); + + while (dmt_read_4(sc, write_post_reg) & + OMAP_DMTIMER_REG_POSTED_MASK(reg)) { + if (--tries == 0) + panic("dmtimer %p failed to complete write", + sc); + DELAY(10); /* XXXMAGIC */ + } + } +} + +static uint32_t +dmt_read_4(struct omap_dmtimer_softc *sc, dmt_reg_t reg) +{ + + return bus_space_read_4(sc->sc_iot, sc->sc_ioh, reg); +} + +static void +dmt_write_4(struct omap_dmtimer_softc *sc, dmt_reg_t reg, uint32_t value) +{ + + bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg, value); +} Index: sys/arch/arm/omap/omap_dmtimerreg.h =================================================================== RCS file: sys/arch/arm/omap/omap_dmtimerreg.h diff -N sys/arch/arm/omap/omap_dmtimerreg.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/omap/omap_dmtimerreg.h 9 Dec 2012 08:52:20 -0000 @@ -0,0 +1,164 @@ +/* $NetBSD$ */ + +/* + * TI OMAP Dual-mode timers: Registers + */ + +/*- + * Copyright (c) 2012 Taylor R. Campbell + * 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. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 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. + */ + +/* + * References: TI AM335x TRM, TI OMAP35x TRM. + */ + +#ifndef _ARM_OMAP_OMAP_DMTIMERREG_H_ +#define _ARM_OMAP_OMAP_DMTIMERREG_H_ + +#include + +#define OMAP_DMTIMER_ID 0x00 /* TIDR */ +#define OMAP_DMTIMER_OCP_CFG 0x10 /* TOCP_CFG */ + +#define OMAP_DMTIMER_OCP_CFG_IDLEMODE_FORCE_IDLE 0 +#define OMAP_DMTIMER_OCP_CFG_IDLEMODE_NO_IDLE 1 +#define OMAP_DMTIMER_OCP_CFG_IDLEMODE_SMART_IDLE 2 +#define OMAP_DMTIMER_OCP_CFG_IDLEMODE_RESERVED 3 + +/* + * DM timer version 1 + */ + +#define OMAP_DMTIMER_V1_ID_REVISION_MASK __BITS(0, 7) +#define OMAP_DMTIMER_V1_ID_RESERVED_MASK __BITS(8, 31) + +#define OMAP_DMTIMER_V1_OCP_CFG_AUTOIDLE_MASK __BITS(0, 0) +#define OMAP_DMTIMER_V1_OCP_CFG_SOFTRESET_MASK __BITS(1, 1) +#define OMAP_DMTIMER_V1_OCP_CFG_WAKEUP_MASK __BITS(2, 2) +#define OMAP_DMTIMER_V1_OCP_CFG_IDLEMODE_MASK __BITS(3, 4) +#define OMAP_DMTIMER_V1_OCP_CFG_EMUFREE_MASK __BITS(5, 5) +#define OMAP_DMTIMER_V1_OCP_CFG_RESERVED0_MASK __BITS(6, 8) +#define OMAP_DMTIMER_V1_OCP_CFG_CLOCKACT_MASK __BITS(9, 8) +#define OMAP_DMTIMER_V1_OCP_CFG_CLOCKACT_OFF 0 +#define OMAP_DMTIMER_V1_OCP_CFG_CLOCKACT_FUN 1 +#define OMAP_DMTIMER_V1_OCP_CFG_CLOCKACT_L4 2 +#define OMAP_DMTIMER_V1_OCP_CFG_CLOCKACT_L4_FUN 3 + +#define OMAP_DMTIMER_INTR_MATCH __BIT(0) +#define OMAP_DMTIMER_INTR_OVERFLOW __BIT(1) +#define OMAP_DMTIMER_INTR_CAPTURE __BIT(2) +#define OMAP_DMTIMER_INTR_ALL 0x7 + +#define OMAP_DMTIMER_V1_STATUS 0x14 /* TISTAT */ +#define OMAP_DMTIMER_V1_STATUS_RESETDONE __BIT(0) +#define OMAP_DMTIMER_V1_INTR_STATUS 0x18 /* TISR */ +#define OMAP_DMTIMER_V1_INTR_ENABLE 0x1c /* TIER */ +#define OMAP_DMTIMER_V1_TIMER_REGS 0x20 + +/* + * DM timer version 2 + */ + +#define OMAP_DMTIMER_V2_ID_Y_MINOR_MASK __BITS(0, 5) +#define OMAP_DMTIMER_V2_ID_CUSTOM_MASK __BITS(6, 7) +#define OMAP_DMTIMER_V2_ID_X_MAJOR_MASK __BITS(8, 10) +#define OMAP_DMTIMER_V2_ID_R_RTL_MASK __BITS(11, 15) +#define OMAP_DMTIMER_V2_ID_FUNC_MASK __BITS(16, 27) +#define OMAP_DMTIMER_V2_ID_RESERVED_MASK __BITS(28, 29) +#define OMAP_DMTIMER_V2_ID_SCHEME_MASK __BITS(30, 31) + +#define OMAP_DMTIMER_V2_OCP_CFG_SOFTRESET_MASK __BITS(0, 0) +#define OMAP_DMTIMER_V2_OCP_CFG_EMUFREE_MASK __BITS(1, 1) +#define OMAP_DMTIMER_V2_OCP_CFG_IDLEMODE_MASK __BITS(2, 3) + +#define OMAP_DMTIMER_V2_INTR_STATUS_RAW 0x24 +#define OMAP_DMTIMER_V2_INTR_STATUS 0x28 +#define OMAP_DMTIMER_V2_INTR_ENABLE_SET 0x2c +#define OMAP_DMTIMER_V2_INTR_ENABLE_CLEAR 0x30 +#define OMAP_DMTIMER_V2_TIMER_REGS 0x34 + +#define OMAP_DMTIMER_REG_INDEX_MASK 0x00ff +#define OMAP_DMTIMER_REG_POSTED_BIT_MASK 0x0f00 +#define OMAP_DMTIMER_REG_POSTED_INDEX(reg) \ + __SHIFTOUT((reg), OMAP_DMTIMER_REG_INDEX_MASK) +#define OMAP_DMTIMER_REG_POSTED_BIT(reg) \ + __SHIFTOUT((reg), OMAP_DMTIMER_REG_POSTED_BIT_MASK) +#define OMAP_DMTIMER_REG_POSTED_MASK(reg) \ + __BIT(OMAP_DMTIMER_REG_POSTED_BIT(reg)) +#define OMAP_DMTIMER_REG_POSTED_P(reg) \ + (((reg) & 0x1000) == 0x1000) + +#define OMAP_DMTIMER_TIMER_INTR_WAKEUP 0x0000 /* TWER */ +#define OMAP_DMTIMER_TIMER_CTRL 0x1004 /* TCLR */ +#define OMAP_DMTIMER_TIMER_CTRL_START __BIT(0) +#define OMAP_DMTIMER_TIMER_CTRL_AUTORELOAD __BIT(1) +#define OMAP_DMTIMER_TIMER_CTRL_PRESCALE_MASK __BITS(2, 4) +#define OMAP_DMTIMER_TIMER_CTRL_PRESCALE_ENABLE __BIT(5) +#define OMAP_DMTIMER_TIMER_CTRL_COMPARE_ENABLE __BIT(6) +#define OMAP_DMTIMER_TIMER_CTRL_PWM_SIGN __BIT(7) +#define OMAP_DMTIMER_TIMER_CTRL_TCM_MASK __BITS(8, 9) +#define OMAP_DMTIMER_TIMER_CTRL_TCM_NONE 0 +#define OMAP_DMTIMER_TIMER_CTRL_TCM_LOW_HIGH 1 +#define OMAP_DMTIMER_TIMER_CTRL_TCM_HIGH_LOW 2 +#define OMAP_DMTIMER_TIMER_CTRL_TCM_BOTH 3 +#define OMAP_DMTIMER_TIMER_CTRL_TRG_MASK __BITS(10, 11) +#define OMAP_DMTIMER_TIMER_CTRL_TRG_NONE 0 +#define OMAP_DMTIMER_TIMER_CTRL_TRG_OVERFLOW 1 +#define OMAP_DMTIMER_TIMER_CTRL_TRG_OVERFLOW_MATCH 2 +#define OMAP_DMTIMER_TIMER_CTRL_TRG_RESERVED 3 +#define OMAP_DMTIMER_TIMER_CTRL_PWM_PT __BIT(12) +#define OMAP_DMTIMER_TIMER_CTRL_PWM_PULSE 0 +#define OMAP_DMTIMER_TIMER_CTRL_PWM_TOGGLE 1 +#define OMAP_DMTIMER_TIMER_CTRL_CAPTURE_MODE __BIT(13) +#define OMAP_DMTIMER_TIMER_CTRL_CAPTURE_MODE_FIRST 0 +#define OMAP_DMTIMER_TIMER_CTRL_CAPTURE_MODE_SECOND 1 +#define OMAP_DMTIMER_TIMER_CTRL_GPO_CFG __BIT(14) +#define OMAP_DMTIMER_TIMER_COUNTER 0x1108 /* TCRR */ +#define OMAP_DMTIMER_TIMER_LOAD 0x120c /* TLDR */ +#define OMAP_DMTIMER_TIMER_TRIGGER 0x1310 /* TTGR */ +#define OMAP_DMTIMER_TIMER_WRITE_POST 0x0014 /* TWPS */ +#define OMAP_DMTIMER_TIMER_WRITE_POST_CTRL __BIT(0) +#define OMAP_DMTIMER_TIMER_WRITE_POST_COUNTER __BIT(1) +#define OMAP_DMTIMER_TIMER_WRITE_POST_LOAD __BIT(2) +#define OMAP_DMTIMER_TIMER_WRITE_POST_TRIGGER __BIT(3) +#define OMAP_DMTIMER_TIMER_WRITE_POST_MATCH __BIT(4) +#define OMAP_DMTIMER_TIMER_WRITE_POST_POS_INCR __BIT(5) +#define OMAP_DMTIMER_TIMER_WRITE_POST_NEG_INCR __BIT(6) +#define OMAP_DMTIMER_TIMER_WRITE_POST_COUNTER_VALUE __BIT(7) +#define OMAP_DMTIMER_TIMER_WRITE_POST_INTR_MASK_SET __BIT(8) +#define OMAP_DMTIMER_TIMER_WRITE_POST_INTR_MASK_COUNT __BIT(9) +#define OMAP_DMTIMER_TIMER_MATCH 0x1418 /* TMAR */ +#define OMAP_DMTIMER_TIMER_CAPTURE1 0x001c /* TCAR1 */ +#define OMAP_DMTIMER_TIMER_SYNC_INT_CTRL 0x0020 /* TSICR */ +#define OMAP_DMTIMER_TIMER_SYNC_INT_CTRL_SOFTRESET __BIT(1) +#define OMAP_DMTIMER_TIMER_SYNC_INT_CTRL_POSTED __BIT(2) +#define OMAP_DMTIMER_TIMER_CAPTURE2 0x0024 /* TCAR2 */ +#define OMAP_DMTIMER_TICK_POS_INCR 0x1528 /* TPIR */ +#define OMAP_DMTIMER_TICK_NEG_INCR 0x162c /* TNIR */ +#define OMAP_DMTIMER_TICK_COUNTER_VALUE 0x1730 /* TCVR */ +#define OMAP_DMTIMER_TICK_INTR_MASK_SET 0x1834 /* TOCR */ +#define OMAP_DMTIMER_TICK_INTR_MASK_COUNT 0x1938 /* TOWR */ + +#endif /* _ARM_OMAP_OMAP_DMTIMERREG_H_ */ Index: sys/arch/arm/omap/omap_dmtimervar.h =================================================================== RCS file: sys/arch/arm/omap/omap_dmtimervar.h diff -N sys/arch/arm/omap/omap_dmtimervar.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/arch/arm/omap/omap_dmtimervar.h 9 Dec 2012 08:52:20 -0000 @@ -0,0 +1,59 @@ +/* $NetBSD$ */ + +/* + * TI OMAP Dual-mode timers: Driver state + */ + +/*- + * Copyright (c) 2012 Taylor R. Campbell + * 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. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 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. + */ + +#ifndef _ARM_OMAP_OMAP_DMTIMERVAR_H_ +#define _ARM_OMAP_OMAP_DMTIMERVAR_H_ + +#include +#include +#include +#include + +struct omap_module; + +struct omap_dmtimer_softc { + device_t sc_dev; + const struct omap_module *sc_module; + unsigned int sc_version; + int sc_intr; + bus_space_tag_t sc_iot; + bus_space_handle_t sc_ioh; + + bool sc_posted; + bool sc_enabled; +}; + +void omap_dmtimer_attach_timecounter(struct omap_dmtimer_softc *); +void omap_dmtimer_attach_hardclock(struct omap_dmtimer_softc *); +void omap_dmtimer_attach_statclock(struct omap_dmtimer_softc *); + +#endif /* _ARM_OMAP_OMAP_DMTIMERVAR_H_ */