Date: Thu, 16 Feb 2012 14:42:35 +0000 (UTC) From: Damjan Marion <dmarion@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r231822 - in projects/armv6/sys: arm/ti arm/ti/am335x arm/ti/omap4 boot/fdt/dts conf Message-ID: <201202161442.q1GEgZ7s020985@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dmarion Date: Thu Feb 16 14:42:35 2012 New Revision: 231822 URL: http://svn.freebsd.org/changeset/base/231822 Log: Initial codedrop for TI AM335x / BeagleBone Includes: - AINTC Interrupt controller code - minimal PRCM code to enable Timers and select clock source - DMTimer code - CPU ID code - Console UART (FDT) Approved by: cognet (mentor) Added: projects/armv6/sys/arm/ti/aintc.c projects/armv6/sys/arm/ti/am335x/ projects/armv6/sys/arm/ti/am335x/am335x_dmtimer.c projects/armv6/sys/arm/ti/am335x/am335x_prcm.c projects/armv6/sys/arm/ti/am335x/am335x_reg.h projects/armv6/sys/arm/ti/am335x/files.am335x projects/armv6/sys/arm/ti/am335x/std.am335x projects/armv6/sys/arm/ti/am335x/std.beaglebone projects/armv6/sys/arm/ti/std.ti projects/armv6/sys/boot/fdt/dts/beaglebone.dts Deleted: projects/armv6/sys/arm/ti/std.omap Modified: projects/armv6/sys/arm/ti/omap4/std.omap4 projects/armv6/sys/arm/ti/ti_cpuid.c projects/armv6/sys/conf/options.arm Added: projects/armv6/sys/arm/ti/aintc.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/armv6/sys/arm/ti/aintc.c Thu Feb 16 14:42:35 2012 (r231822) @@ -0,0 +1,191 @@ +/*- + * Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org> + * All rights reserved. + * + * Based on OMAP3 INTC code by Ben Gray + * + * 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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/ktr.h> +#include <sys/module.h> +#include <sys/rman.h> +#include <machine/bus.h> +#include <machine/intr.h> + +#include <dev/fdt/fdt_common.h> +#include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> + +#define INTC_REVISION 0x00 +#define INTC_SYSCONFIG 0x10 +#define INTC_SYSSTATUS 0x14 +#define INTC_SIR_IRQ 0x40 +#define INTC_CONTROL 0x48 +#define INTC_THRESHOLD 0x68 +#define INTC_MIR_CLEAR(x) (0x88 + ((x) * 0x20)) +#define INTC_MIR_SET(x) (0x8C + ((x) * 0x20)) +#define INTC_ISR_SET(x) (0x90 + ((x) * 0x20)) +#define INTC_ISR_CLEAR(x) (0x94 + ((x) * 0x20)) + +struct ti_aintc_softc { + device_t sc_dev; + struct resource * aintc_res[3]; + bus_space_tag_t aintc_bst; + bus_space_handle_t aintc_bsh; + uint8_t ver; +}; + +static struct resource_spec ti_aintc_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { -1, 0 } +}; + + +static struct ti_aintc_softc *ti_aintc_sc = NULL; + +#define aintc_read_4(reg) \ + bus_space_read_4(ti_aintc_sc->aintc_bst, ti_aintc_sc->aintc_bsh, reg) +#define aintc_write_4(reg, val) \ + bus_space_write_4(ti_aintc_sc->aintc_bst, ti_aintc_sc->aintc_bsh, reg, val) + + +static int +ti_aintc_probe(device_t dev) +{ + if (!ofw_bus_is_compatible(dev, "ti,aintc")) + return (ENXIO); + device_set_desc(dev, "TI AINTC Interrupt Controller"); + return (BUS_PROBE_DEFAULT); +} + +static int +ti_aintc_attach(device_t dev) +{ + struct ti_aintc_softc *sc = device_get_softc(dev); + uint32_t x; + + sc->sc_dev = dev; + + if (ti_aintc_sc) + return (ENXIO); + + if (bus_alloc_resources(dev, ti_aintc_spec, sc->aintc_res)) { + device_printf(dev, "could not allocate resources\n"); + return (ENXIO); + } + + sc->aintc_bst = rman_get_bustag(sc->aintc_res[0]); + sc->aintc_bsh = rman_get_bushandle(sc->aintc_res[0]); + + ti_aintc_sc = sc; + + x = aintc_read_4(INTC_REVISION); + device_printf(dev, "Revision %u.%u\n",(x >> 4) & 0xF, x & 0xF); + return (0); +} + +static device_method_t ti_aintc_methods[] = { + DEVMETHOD(device_probe, ti_aintc_probe), + DEVMETHOD(device_attach, ti_aintc_attach), + { 0, 0 } +}; + +static driver_t ti_aintc_driver = { + "aintc", + ti_aintc_methods, + sizeof(struct ti_aintc_softc), +}; + +static devclass_t ti_aintc_devclass; + +DRIVER_MODULE(aintc, simplebus, ti_aintc_driver, ti_aintc_devclass, 0, 0); + +int +arm_get_next_irq(int last_irq) +{ + uint32_t active_irq; + + if (last_irq != -1) { + aintc_write_4(INTC_ISR_CLEAR(last_irq >> 5), + 1UL << (last_irq & 0x1F)); + aintc_write_4(INTC_CONTROL,1); + } + + /* Get the next active interrupt */ + active_irq = aintc_read_4(INTC_SIR_IRQ); + + /* Check for spurious interrupt */ + if ((active_irq & 0xffffff80)) { + device_printf(ti_aintc_sc->sc_dev, + "Spurious interrupt detected (0x%08x)\n", active_irq); + return -1; + } + + if (active_irq != last_irq) + return active_irq; + else + return -1; +} + +void +arm_mask_irq(uintptr_t nb) +{ + aintc_write_4(INTC_MIR_SET(nb >> 5), (1UL << (nb & 0x1F))); +} + +void +arm_unmask_irq(uintptr_t nb) +{ + aintc_write_4(INTC_MIR_CLEAR(nb >> 5), (1UL << (nb & 0x1F))); +} + +static int +fdt_ti_aintc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, + int *pol) +{ + + if (!fdt_is_compatible(node, "ti,aintc")) + return (ENXIO); + + *interrupt = fdt32_to_cpu(intr[0]); + *trig = INTR_TRIGGER_CONFORM; + *pol = INTR_POLARITY_CONFORM; + + return (0); +} + +fdt_pic_decode_t fdt_pic_table[] = { + &fdt_ti_aintc_decode_ic, + NULL +}; + + Added: projects/armv6/sys/arm/ti/am335x/am335x_dmtimer.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/armv6/sys/arm/ti/am335x/am335x_dmtimer.c Thu Feb 16 14:42:35 2012 (r231822) @@ -0,0 +1,373 @@ +/*- + * Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org> + * 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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/malloc.h> +#include <sys/rman.h> +#include <sys/timeet.h> +#include <sys/timetc.h> +#include <sys/watchdog.h> +#include <machine/bus.h> +#include <machine/cpu.h> +#include <machine/frame.h> +#include <machine/intr.h> + +#include <dev/fdt/fdt_common.h> +#include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> + +#include <machine/bus.h> +#include <machine/fdt.h> + +#define AM335X_NUM_TIMERS 8 + +#define DMTIMER_TIDR 0x00 /* Identification Register */ +#define DMTIMER_TIOCP_CFG 0x10 /* Timer OCP Configuration Reg */ +#define DMTIMER_IQR_EOI 0x20 /* Timer IRQ End-Of-Interrupt Reg */ +#define DMTIMER_IRQSTATUS_RAW 0x24 /* Timer IRQSTATUS Raw Reg */ +#define DMTIMER_IRQSTATUS 0x28 /* Timer IRQSTATUS Reg */ +#define DMTIMER_IRQENABLE_SET 0x2c /* Timer IRQSTATUS Set Reg */ +#define DMTIMER_IRQENABLE_CLR 0x30 /* Timer IRQSTATUS Clear Reg */ +#define DMTIMER_IRQWAKEEN 0x34 /* Timer IRQ Wakeup Enable Reg */ +#define DMTIMER_TCLR 0x38 /* Timer Control Register */ +#define DMTIMER_TCRR 0x3C /* Timer Counter Register */ +#define DMTIMER_TLDR 0x40 /* Timer Load Reg */ +#define DMTIMER_TTGR 0x44 /* Timer Trigger Reg */ +#define DMTIMER_TWPS 0x48 /* Timer Write Posted Status Reg */ +#define DMTIMER_TMAR 0x4C /* Timer Match Reg */ +#define DMTIMER_TCAR1 0x50 /* Timer Capture Reg */ +#define DMTIMER_TSICR 0x54 /* Timer Synchr. Interface Control Reg */ +#define DMTIMER_TCAR2 0x48 /* Timer Capture Reg */ + + +struct am335x_dmtimer_softc { + struct resource * tmr_mem_res[AM335X_NUM_TIMERS]; + struct resource * tmr_irq_res[AM335X_NUM_TIMERS]; + uint32_t clkfreq; + struct am335x_dmtimer { + bus_space_tag_t bst; + bus_space_handle_t bsh; + struct eventtimer et; + } t[AM335X_NUM_TIMERS]; +}; + +static struct resource_spec am335x_dmtimer_mem_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { SYS_RES_MEMORY, 1, RF_ACTIVE }, + { SYS_RES_MEMORY, 2, RF_ACTIVE }, + { SYS_RES_MEMORY, 3, RF_ACTIVE }, + { SYS_RES_MEMORY, 4, RF_ACTIVE }, + { SYS_RES_MEMORY, 5, RF_ACTIVE }, + { SYS_RES_MEMORY, 6, RF_ACTIVE }, + { SYS_RES_MEMORY, 7, RF_ACTIVE }, + { -1, 0, 0 } +}; +static struct resource_spec am335x_dmtimer_irq_spec[] = { + { SYS_RES_IRQ, 0, RF_ACTIVE }, + { SYS_RES_IRQ, 1, RF_ACTIVE }, + { SYS_RES_IRQ, 2, RF_ACTIVE }, + { SYS_RES_IRQ, 3, RF_ACTIVE }, + { SYS_RES_IRQ, 4, RF_ACTIVE }, + { SYS_RES_IRQ, 5, RF_ACTIVE }, + { SYS_RES_IRQ, 6, RF_ACTIVE }, + { SYS_RES_IRQ, 7, RF_ACTIVE }, + { -1, 0, 0 } +}; + +static struct am335x_dmtimer *am335x_dmtimer_tc_tmr = NULL; + +/* Read/Write macros for Timer used as timecounter */ +#define am335x_dmtimer_tc_read_4(reg) \ + bus_space_read_4(am335x_dmtimer_tc_tmr->bst, \ + am335x_dmtimer_tc_tmr->bsh, reg) + +#define am335x_dmtimer_tc_write_4(reg, val) \ + bus_space_write_4(am335x_dmtimer_tc_tmr->bst, \ + am335x_dmtimer_tc_tmr->bsh, reg, val) + +/* Read/Write macros for Timer used as eventtimer */ +#define am335x_dmtimer_et_read_4(reg) \ + bus_space_read_4(tmr->bst, tmr->bsh, reg) + +#define am335x_dmtimer_et_write_4(reg, val) \ + bus_space_write_4(tmr->bst, tmr->bsh, reg, val) + +static unsigned am335x_dmtimer_tc_get_timecount(struct timecounter *); + +static struct timecounter am335x_dmtimer_tc = { + .tc_name = "AM335x Timecouter", + .tc_get_timecount = am335x_dmtimer_tc_get_timecount, + .tc_poll_pps = NULL, + .tc_counter_mask = ~0u, + .tc_frequency = 0, + .tc_quality = 1000, +}; + +static unsigned +am335x_dmtimer_tc_get_timecount(struct timecounter *tc) +{ + return am335x_dmtimer_tc_read_4(DMTIMER_TCRR); +} + +static int +am335x_dmtimer_start(struct eventtimer *et, struct bintime *first, + struct bintime *period) +{ + struct am335x_dmtimer *tmr = (struct am335x_dmtimer *)et->et_priv; + uint32_t load, count; + uint32_t tclr = 0; + + if (period != NULL) { + load = (et->et_frequency * (period->frac >> 32)) >> 32; + if (period->sec > 0) + load += et->et_frequency * period->sec; + tclr |= 2; /* autoreload bit */ + panic("periodic timer not implemented\n"); + } else { + load = 0; + } + + if (first != NULL) { + count = (tmr->et.et_frequency * (first->frac >> 32)) >> 32; + if (first->sec != 0) + count += tmr->et.et_frequency * first->sec; + } else { + count = load; + } + + /* Reset Timer */ + am335x_dmtimer_et_write_4(DMTIMER_TSICR, 2); + + /* Wait for reset to complete */ + while (am335x_dmtimer_et_read_4(DMTIMER_TIOCP_CFG) & 1); + + /* set load value */ + am335x_dmtimer_et_write_4(DMTIMER_TLDR, 0xFFFFFFFE - load); + + /* set counter value */ + am335x_dmtimer_et_write_4(DMTIMER_TCRR, 0xFFFFFFFE - count); + + /* enable overflow interrupt */ + am335x_dmtimer_et_write_4(DMTIMER_IRQENABLE_SET, 2); + + /* start timer(ST) */ + tclr |= 1; + am335x_dmtimer_et_write_4(DMTIMER_TCLR, tclr); + + return (0); +} + +static int +am335x_dmtimer_stop(struct eventtimer *et) +{ + struct am335x_dmtimer *tmr = (struct am335x_dmtimer *)et->et_priv; + + /* Disable all interrupts */ + am335x_dmtimer_et_write_4(DMTIMER_IRQENABLE_CLR, 7); + + /* Stop Timer */ + am335x_dmtimer_et_write_4(DMTIMER_TCLR, 0); + + return (0); +} + +static int +am335x_dmtimer_intr(void *arg) +{ + struct am335x_dmtimer *tmr = (struct am335x_dmtimer *)arg; + + /* Ack interrupt */ + am335x_dmtimer_et_write_4(DMTIMER_IRQSTATUS, 7); + if (tmr->et.et_active) + tmr->et.et_event_cb(&tmr->et, tmr->et.et_arg); + + return (FILTER_HANDLED); +} + +static int +am335x_dmtimer_probe(device_t dev) +{ + struct am335x_dmtimer_softc *sc; + sc = (struct am335x_dmtimer_softc *)device_get_softc(dev); + + if (ofw_bus_is_compatible(dev, "ti,am335x-dmtimer")) { + device_set_desc(dev, "AM335x DMTimer"); + return(BUS_PROBE_DEFAULT); + } + + return (ENXIO); +} + +static int +am335x_dmtimer_attach(device_t dev) +{ + struct am335x_dmtimer_softc *sc = device_get_softc(dev); + phandle_t node; + pcell_t clock; + void *ihl; + int err; + int i; + + if (am335x_dmtimer_tc_tmr != NULL) + return (EINVAL); + + /* Get the base clock frequency */ + node = ofw_bus_get_node(dev); + if ((OF_getprop(node, "clock-frequency", &clock, sizeof(clock))) <= 0) { + device_printf(dev, "missing clock-frequency attribute in FDT\n"); + return (ENXIO); + } + sc->clkfreq = fdt32_to_cpu(clock); + + /* Request the memory resources */ + err = bus_alloc_resources(dev, am335x_dmtimer_mem_spec, + sc->tmr_mem_res); + if (err) { + device_printf(dev, "Error: could not allocate mem resources\n"); + return (ENXIO); + } + + /* Request the IRQ resources */ + err = bus_alloc_resources(dev, am335x_dmtimer_irq_spec, + sc->tmr_irq_res); + if (err) { + device_printf(dev, "Error: could not allocate irq resources\n"); + return (ENXIO); + } + + for(i=0;i<AM335X_NUM_TIMERS;i++) { + sc->t[i].bst = rman_get_bustag(sc->tmr_mem_res[i]); + sc->t[i].bsh = rman_get_bushandle(sc->tmr_mem_res[i]); + } + + /* Take DMTimer2 for TC */ + am335x_dmtimer_tc_tmr = &sc->t[2]; + + /* Reset Timer */ + am335x_dmtimer_tc_write_4(DMTIMER_TSICR, 2); + + /* Wait for reset to complete */ + while (am335x_dmtimer_tc_read_4(DMTIMER_TIOCP_CFG) & 1); + + /* set load value */ + am335x_dmtimer_tc_write_4(DMTIMER_TLDR, 0); + + /* set counter value */ + am335x_dmtimer_tc_write_4(DMTIMER_TCRR, 0); + + /* Set Timer autoreload(AR) and start timer(ST) */ + am335x_dmtimer_tc_write_4(DMTIMER_TCLR, 3); + + am335x_dmtimer_tc.tc_frequency = sc->clkfreq; + tc_init(&am335x_dmtimer_tc); + + /* Setup and enable the timer */ + if (bus_setup_intr(dev, sc->tmr_irq_res[3], INTR_TYPE_CLK, + am335x_dmtimer_intr, NULL, &sc->t[3], &ihl) != 0) { + bus_release_resources(dev, am335x_dmtimer_irq_spec, + sc->tmr_irq_res); + device_printf(dev, "Unable to setup the clock irq handler.\n"); + return (ENXIO); + } + + sc->t[3].et.et_name = "AM335x Eventtimer0"; + sc->t[3].et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT; + sc->t[3].et.et_quality = 1000; + sc->t[3].et.et_frequency = sc->clkfreq; + sc->t[3].et.et_min_period.sec = 0; + sc->t[3].et.et_min_period.frac = + ((0x00000002LLU << 32) / sc->t[3].et.et_frequency) << 32; + sc->t[3].et.et_max_period.sec = 0xfffffff0U / sc->t[3].et.et_frequency; + sc->t[3].et.et_max_period.frac = + ((0xfffffffeLLU << 32) / sc->t[3].et.et_frequency) << 32; + sc->t[3].et.et_start = am335x_dmtimer_start; + sc->t[3].et.et_stop = am335x_dmtimer_stop; + sc->t[3].et.et_priv = &sc->t[3]; + et_register(&sc->t[3].et); + + return (0); +} + +static device_method_t am335x_dmtimer_methods[] = { + DEVMETHOD(device_probe, am335x_dmtimer_probe), + DEVMETHOD(device_attach, am335x_dmtimer_attach), + { 0, 0 } +}; + +static driver_t am335x_dmtimer_driver = { + "am335x-dmtimer", + am335x_dmtimer_methods, + sizeof(struct am335x_dmtimer_softc), +}; + +static devclass_t am335x_dmtimer_devclass; + +DRIVER_MODULE(am335x_dmtimer, simplebus, am335x_dmtimer_driver, am335x_dmtimer_devclass, 0, 0); + +void +cpu_initclocks(void) +{ + cpu_initclocks_bsp(); +} + +void +DELAY(int usec) +{ + int32_t counts; + uint32_t first, last; + + if (am335x_dmtimer_tc_tmr == NULL) { + for (; usec > 0; usec--) + for (counts = 200; counts > 0; counts--) + /* Prevent gcc from optimizing out the loop */ + cpufunc_nullop(); + return; + } + + /* Get the number of times to count */ + counts = usec * ((am335x_dmtimer_tc.tc_frequency / 1000000) + 1);; + + first = am335x_dmtimer_tc_read_4(DMTIMER_TCRR); + + while (counts > 0) { + last = am335x_dmtimer_tc_read_4(DMTIMER_TCRR); + if (last>first) { + counts -= (int32_t)(last - first); + } else { + counts -= (int32_t)((0xFFFFFFFF - first) + last); + } + first = last; + } +} + Added: projects/armv6/sys/arm/ti/am335x/am335x_prcm.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/armv6/sys/arm/ti/am335x/am335x_prcm.c Thu Feb 16 14:42:35 2012 (r231822) @@ -0,0 +1,156 @@ +/*- + * Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org> + * 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 <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/malloc.h> +#include <sys/rman.h> +#include <sys/timeet.h> +#include <sys/timetc.h> +#include <sys/watchdog.h> +#include <machine/bus.h> +#include <machine/cpu.h> +#include <machine/frame.h> +#include <machine/intr.h> + +#include <dev/fdt/fdt_common.h> +#include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> + +#include <machine/bus.h> +#include <machine/fdt.h> + +#define CM_PER 0 +#define CM_PER_L4LS_CLKSTCTRL (CM_PER + 0x00) +#define CM_PER_TIMER7_CLKCTRL (CM_PER + 0x7C) +#define CM_PER_TIMER2_CLKCTRL (CM_PER + 0x80) +#define CM_PER_TIMER3_CLKCTRL (CM_PER + 0x84) +#define CM_PER_TIMER4_CLKCTRL (CM_PER + 0x88) +#define CM_PER_TIMER5_CLKCTRL (CM_PER + 0xEC) +#define CM_PER_TIMER6_CLKCTRL (CM_PER + 0xF0) + +#define CM_DPLL 0x500 +#define CLKSEL_TIMER7_CLK (CM_DPLL + 0x04) +#define CLKSEL_TIMER2_CLK (CM_DPLL + 0x08) +#define CLKSEL_TIMER3_CLK (CM_DPLL + 0x0C) +#define CLKSEL_TIMER4_CLK (CM_DPLL + 0x10) +#define CLKSEL_TIMER5_CLK (CM_DPLL + 0x18) +#define CLKSEL_TIMER6_CLK (CM_DPLL + 0x1C) + +struct am335x_prcm_softc { + struct resource * res[2]; + bus_space_tag_t bst; + bus_space_handle_t bsh; +}; + +static struct resource_spec am335x_prcm_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { -1, 0 } +}; + +static struct am335x_prcm_softc *am335x_prcm_sc = NULL; + +/* Read/Write macros */ +#define prcm_read_4(reg) \ + bus_space_read_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg) +#define prcm_write_4(reg, val) \ + bus_space_write_4(am335x_prcm_sc->bst, am335x_prcm_sc->bsh, reg, val) + +static int +am335x_prcm_probe(device_t dev) +{ + struct am335x_prcm_softc *sc; + sc = (struct am335x_prcm_softc *)device_get_softc(dev); + + if (ofw_bus_is_compatible(dev, "am335x,prcm")) { + device_set_desc(dev, "AM335x PRCM"); + return(BUS_PROBE_DEFAULT); + } + + return (ENXIO); +} + +static int +am335x_prcm_attach(device_t dev) +{ + struct am335x_prcm_softc *sc = device_get_softc(dev); + + if (am335x_prcm_sc) + return (ENXIO); + + if (bus_alloc_resources(dev, am335x_prcm_spec, sc->res)) { + device_printf(dev, "could not allocate resources\n"); + return (ENXIO); + } + + sc->bst = rman_get_bustag(sc->res[0]); + sc->bsh = rman_get_bushandle(sc->res[0]); + + am335x_prcm_sc = sc; + + /* Select CLK_M_OSC clock for Timer 2 */ + prcm_write_4(CLKSEL_TIMER2_CLK,1); + while ((prcm_read_4(CLKSEL_TIMER2_CLK) & 0x1) != 1); + + /* Enable Timer 2 Module */ + prcm_write_4(CM_PER_TIMER2_CLKCTRL, 2); + while ((prcm_read_4(CM_PER_TIMER2_CLKCTRL) & 0x3) != 2); + + /* Select CLK_M_OSC clock for Timer 3 */ + prcm_write_4(CLKSEL_TIMER3_CLK,1); + while ((prcm_read_4(CLKSEL_TIMER3_CLK) & 0x1) != 1); + + /* Enable Timer 3 Module */ + prcm_write_4(CM_PER_TIMER3_CLKCTRL, 2); + while ((prcm_read_4(CM_PER_TIMER3_CLKCTRL) & 0x3) != 2); + + return (0); +} + +static device_method_t am335x_prcm_methods[] = { + DEVMETHOD(device_probe, am335x_prcm_probe), + DEVMETHOD(device_attach, am335x_prcm_attach), + { 0, 0 } +}; + +static driver_t am335x_prcm_driver = { + "am335x-prcm", + am335x_prcm_methods, + sizeof(struct am335x_prcm_softc), +}; + +static devclass_t am335x_prcm_devclass; + +DRIVER_MODULE(am335x_prcm, simplebus, am335x_prcm_driver, + am335x_prcm_devclass, 0, 0); + Added: projects/armv6/sys/arm/ti/am335x/am335x_reg.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/armv6/sys/arm/ti/am335x/am335x_reg.h Thu Feb 16 14:42:35 2012 (r231822) @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org> + * 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 _AM335X_REG_H_ +#define _AM335X_REG_H_ + +#define AM335X_L4_WKUP_BASE 0x44C00000 +#define AM335X_L4_WKUP_SIZE 0x400000 + +#define AM335X_CONTROL_BASE AM335X_L4_WKUP_BASE + 0x210000 +#define AM335X_CONTROL_SIZE 0x2000 +#define AM335X_CONTROL_DEVICE_ID 0x0600 +#define AM335X_CONTROL_DEV_FEATURE 0x0604 + +#endif + Added: projects/armv6/sys/arm/ti/am335x/files.am335x ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/armv6/sys/arm/ti/am335x/files.am335x Thu Feb 16 14:42:35 2012 (r231822) @@ -0,0 +1,20 @@ +#$FreeBSD$ + +kern/kern_clocksource.c standard + +arm/arm/bus_space_generic.c standard +arm/arm/bus_space_asm_generic.S standard +arm/arm/cpufunc_asm_armv5.S standard +arm/arm/cpufunc_asm_arm10.S standard +arm/arm/cpufunc_asm_arm11.S standard +arm/arm/cpufunc_asm_armv7.S standard +arm/arm/irq_dispatch.S standard + +arm/ti/ti_machdep.c standard +arm/ti/aintc.c standard + +arm/ti/am335x/am335x_prcm.c standard +arm/ti/am335x/am335x_dmtimer.c standard +arm/ti/am335x/if_cpsw.c standard + +dev/uart/uart_dev_ns8250.c optional uart Added: projects/armv6/sys/arm/ti/am335x/std.am335x ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/armv6/sys/arm/ti/am335x/std.am335x Thu Feb 16 14:42:35 2012 (r231822) @@ -0,0 +1,21 @@ +# AM335x generic configuration +#$FreeBSD$ +files "../ti/am335x/files.am335x" +include "../ti/std.ti" +makeoption ARM_LITTLE_ENDIAN + +# Physical memory starts at 0x80000000. We assume images are loaded at +# 0x80200000, e.g. from u-boot with 'fatload mmc 0 0x80200000 kernel.bin' +# +# +options PHYSADDR=0x80000000 +options KERNPHYSADDR=0x80200000 +makeoptions KERNPHYSADDR=0x80200000 +options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm +makeoptions KERNVIRTADDR=0xc0200000 + +options STARTUP_PAGETABLE_ADDR=0x80000000 + +options SOC_TI_AM335X + +options ARM_L2_PIPT Added: projects/armv6/sys/arm/ti/am335x/std.beaglebone ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/armv6/sys/arm/ti/am335x/std.beaglebone Thu Feb 16 14:42:35 2012 (r231822) @@ -0,0 +1,3 @@ +# $FreeBSD$ + +include "../ti/am335x/std.am335x" Modified: projects/armv6/sys/arm/ti/omap4/std.omap4 ============================================================================== --- projects/armv6/sys/arm/ti/omap4/std.omap4 Thu Feb 16 14:08:14 2012 (r231821) +++ projects/armv6/sys/arm/ti/omap4/std.omap4 Thu Feb 16 14:42:35 2012 (r231822) @@ -1,7 +1,7 @@ # Omap4430 generic configuration #$FreeBSD$ files "../ti/omap4/files.omap4" -include "../ti/std.omap" +include "../ti/std.ti" makeoption ARM_LITTLE_ENDIAN # Physical memory starts at 0x80000000. We assume images are loaded at Added: projects/armv6/sys/arm/ti/std.ti ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/armv6/sys/arm/ti/std.ti Thu Feb 16 14:42:35 2012 (r231822) @@ -0,0 +1,6 @@ +# $FreeBSD$ + +# This should be armv7-a but current gcc doesn't support it +# makeoptions CONF_CFLAGS=-march=armv6 + +cpu CPU_CORTEXA Modified: projects/armv6/sys/arm/ti/ti_cpuid.c ============================================================================== --- projects/armv6/sys/arm/ti/ti_cpuid.c Thu Feb 16 14:08:14 2012 (r231821) +++ projects/armv6/sys/arm/ti/ti_cpuid.c Thu Feb 16 14:42:35 2012 (r231822) @@ -51,9 +51,7 @@ __FBSDID("$FreeBSD$"); #include <arm/ti/omap4/omap4_reg.h> #include <arm/ti/omap3/omap3_reg.h> -#ifdef notyet #include <arm/ti/am335x/am335x_reg.h> -#endif #define OMAP4_STD_FUSE_DIE_ID_0 0x2200 #define OMAP4_ID_CODE 0x2204 @@ -216,7 +214,6 @@ omap3_get_revision(void) OMAP_REV_MINOR(chip_revision)); } -#ifdef notyet static void am335x_get_revision(void) { @@ -255,7 +252,6 @@ am335x_get_revision(void) printf("Texas Instruments AM335%c Processor, Revision ES1.%u\n", cpu_last_char, AM335X_DEVREV(chip_revision)); } -#endif /** * ti_cpu_ident - attempts to identify the chip we are running on @@ -278,11 +274,9 @@ ti_cpu_ident(void *dummy) case CHIP_OMAP_4: omap4_get_revision(); break; -#ifdef notyet case CHIP_AM335X: am335x_get_revision(); break; -#endif default: panic("Unknown chip type, fixme!\n"); } Added: projects/armv6/sys/boot/fdt/dts/beaglebone.dts ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ projects/armv6/sys/boot/fdt/dts/beaglebone.dts Thu Feb 16 14:42:35 2012 (r231822) @@ -0,0 +1,118 @@ +/*- + * Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org> + * 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. + */ + +/dts-v1/; + +/ { + model = "beaglebone"; + compatible = "beaglebone", "ti,am335x"; + #address-cells = <1>; + #size-cells = <1>; + + interrupt-parent = <&AINTC>; + + aliases { + soc = &SOC; + uart0 = &uart0; + }; + + memory { + device_type = "memory"; + reg = < 0x80000000 0x10000000 >; /* 256MB RAM */ + }; + + SOC: am335x { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + ranges; + bus-frequency = <0>; + + AINTC: interrupt-controller@48200000 { + compatible = "ti,aintc"; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + reg = < 0x48200000 0x1000 >; + }; + + prcm@44E00000 { + compatible = "am335x,prcm"; + #address-cells = <1>; + #size-cells = <1>; + reg = < 0x44E00000 0x1300 >; + }; + + dmtimers@44E05000 { + compatible = "ti,am335x-dmtimer"; + #address-cells = <1>; + #size-cells = <1>; + reg = < 0x44E05000 0x1000 + 0x44E31000 0x1000 + 0x48040000 0x1000 + 0x48042000 0x1000 + 0x48044000 0x1000 + 0x48046000 0x1000 + 0x48048000 0x1000 + 0x4804A000 0x1000 >; + interrupts = < 66 67 68 69 92 93 94 95 >; + interrupt-parent = <&AINTC>; + clock-frequency = < 24000000 >; + }; + + uart0: serial@44E09000 { + compatible = "ns16550"; + reg = <0x44E09000 0x1000>; + reg-shift = <2>; + interrupts = < 72 >; + interrupt-parent = <&AINTC>; + clock-frequency = < 48000000 >; /* FIXME */ + }; + + enet0: ethernet@4A100000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "ti,cpsw"; + reg = <0x4A100000 0x2000>; + interrupts = <40 41 42 43>; + interrupt-parent = <&AINTC>; + phy-handle = <&phy0>; + mdio@0 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "ti,cpsw-mdio"; + phy0: ethernet-phy@0 { + reg = <0x0>; + }; + }; + }; + }; + *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202161442.q1GEgZ7s020985>