svn commit: r231822 - in projects/armv6/sys: arm/ti arm/ti/am335x arm/ti/omap4 boot/fdt/dts conf

Damjan Marion dmarion at FreeBSD.org
Thu Feb 16 14:42:35 UTC 2012


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 at 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 at 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 at 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 at 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 at 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 at 48200000 {
+			compatible = "ti,aintc";
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <1>;
+			reg =	< 0x48200000 0x1000 >;
+		};
+
+		prcm at 44E00000 {
+			compatible = "am335x,prcm";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = < 0x44E00000 0x1300 >;
+		};
+
+		dmtimers at 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 at 44E09000 {
+			compatible = "ns16550";
+			reg = <0x44E09000 0x1000>;
+			reg-shift = <2>;
+			interrupts = < 72 >;
+			interrupt-parent = <&AINTC>;
+			clock-frequency = < 48000000 >; /* FIXME */
+		};
+
+		enet0: ethernet at 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 at 0 {
+				#address-cells = <1>;
+				#size-cells = <0>;
+				compatible = "ti,cpsw-mdio";
+				phy0: ethernet-phy at 0 {
+					reg = <0x0>;
+				};
+			};
+		};
+	};
+

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-projects mailing list