Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 May 2015 03:16:19 +0000 (UTC)
From:      Oleksandr Tymoshenko <gonzo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r283276 - in head: . sys/arm/conf sys/arm/ti sys/arm/ti/am335x sys/arm/ti/cpsw sys/arm/ti/omap4 sys/arm/ti/usb sys/boot/fdt/dts/arm sys/dev/uart
Message-ID:  <201505220316.t4M3GJT9021693@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gonzo
Date: Fri May 22 03:16:18 2015
New Revision: 283276
URL: https://svnweb.freebsd.org/changeset/base/283276

Log:
  Switch TI platform support code from using FreeBSD's custom-baked DTS
  files to vendor-provided ones. It should make easier to adopt platform
  code to new revisions of hardware and to use DTS overlays for various
  Beaglebone extensions (shields/capes).
  
  Original dts filenames were not changed, they're now wrappers over dts
  files provided by TI. So make sure you update .dtb files on your
  devices as part of kernel update
  
  GPIO addressing was changed: instead of one global /dev/gpioc0 there
  are per-bank instances of /dev/gpiocX. Each bank has 32 pins so for
  instance pin 121 on /dev/gpioc0 in old addressing scheme is now pin 25
  on /dev/gpioc3
  
  On Pandaboard serial console devices was changed from /dev/ttyu0 to
  /dev/ttyu2 so you'll have to update /etc/ttys to get login prompt
  on serial port in multiuser mode. Single user mode serial console
  should work as-is
  
  Differential Revision:	https://reviews.freebsd.org/D2146
  Reviewed by:	rpaulo, ian, Michal Meloun, Svatopluk Kraus

Added:
  head/sys/arm/ti/am335x/am335x_ecap.c   (contents, props changed)
  head/sys/arm/ti/am335x/am335x_ehrpwm.c   (contents, props changed)
  head/sys/arm/ti/am335x/am335x_musb.c   (contents, props changed)
  head/sys/arm/ti/am335x/am335x_pwmss.c   (contents, props changed)
  head/sys/arm/ti/ti_hwmods.c   (contents, props changed)
  head/sys/arm/ti/ti_hwmods.h   (contents, props changed)
  head/sys/arm/ti/ti_pinmux.c   (contents, props changed)
  head/sys/arm/ti/ti_pinmux.h   (contents, props changed)
  head/sys/arm/ti/usb/omap_host.c   (contents, props changed)
  head/sys/arm/ti/usb/omap_tll.c   (contents, props changed)
  head/sys/boot/fdt/dts/arm/beaglebone-common.dtsi   (contents, props changed)
  head/sys/boot/fdt/dts/arm/pandaboard-common.dtsi   (contents, props changed)
  head/sys/boot/fdt/dts/arm/pandaboard-es.dts   (contents, props changed)
Deleted:
  head/sys/arm/ti/am335x/am335x_pwm.c
  head/sys/boot/fdt/dts/arm/am335x.dtsi
Modified:
  head/UPDATING
  head/sys/arm/conf/BEAGLEBONE
  head/sys/arm/conf/PANDABOARD
  head/sys/arm/ti/aintc.c
  head/sys/arm/ti/am335x/am335x_dmtimer.c
  head/sys/arm/ti/am335x/am335x_gpio.c
  head/sys/arm/ti/am335x/am335x_lcd.c
  head/sys/arm/ti/am335x/am335x_lcd.h
  head/sys/arm/ti/am335x/am335x_pmic.c
  head/sys/arm/ti/am335x/am335x_prcm.c
  head/sys/arm/ti/am335x/am335x_pwm.h
  head/sys/arm/ti/am335x/am335x_scm_padconf.c
  head/sys/arm/ti/am335x/am335x_usbss.c
  head/sys/arm/ti/am335x/files.am335x
  head/sys/arm/ti/cpsw/if_cpsw.c
  head/sys/arm/ti/cpsw/if_cpswreg.h
  head/sys/arm/ti/cpsw/if_cpswvar.h
  head/sys/arm/ti/files.ti
  head/sys/arm/ti/omap4/files.omap4
  head/sys/arm/ti/omap4/omap4_gpio.c
  head/sys/arm/ti/omap4/omap4_prcm_clks.c
  head/sys/arm/ti/omap4/omap4_scm_padconf.c
  head/sys/arm/ti/ti_adc.c
  head/sys/arm/ti/ti_common.c
  head/sys/arm/ti/ti_edma3.c
  head/sys/arm/ti/ti_gpio.c
  head/sys/arm/ti/ti_gpio.h
  head/sys/arm/ti/ti_i2c.c
  head/sys/arm/ti/ti_mbox.c
  head/sys/arm/ti/ti_prcm.h
  head/sys/arm/ti/ti_scm.c
  head/sys/arm/ti/ti_scm.h
  head/sys/arm/ti/ti_sdhci.c
  head/sys/arm/ti/ti_sdma.c
  head/sys/arm/ti/usb/omap_ehci.c
  head/sys/arm/ti/usb/omap_usb.h
  head/sys/boot/fdt/dts/arm/am335x-evm.dts
  head/sys/boot/fdt/dts/arm/beaglebone-black.dts
  head/sys/boot/fdt/dts/arm/beaglebone.dts
  head/sys/boot/fdt/dts/arm/pandaboard.dts
  head/sys/dev/uart/uart_dev_ti8250.c

Modified: head/UPDATING
==============================================================================
--- head/UPDATING	Fri May 22 02:00:44 2015	(r283275)
+++ head/UPDATING	Fri May 22 03:16:18 2015	(r283276)
@@ -31,6 +31,19 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11
 	disable the most expensive debugging functionality run
 	"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
 
+20150521:
+	TI platform code switched to using vendor DTS files and this update
+	may break existing systems running on Beaglebone, Beaglebone Black,
+	and Pandaboard:
+
+	- dtb files should be regenerated/reinstalled. Filenames are the
+	  same but content is different now
+	- GPIO addressing was changed, now each GPIO bank (32 pins per bank)
+	  has its own /dev/gpiocX device, e.g. pin 121 on /dev/gpioc0 in old
+	  addressing scheme is now pin 25 on /dev/gpioc3.
+	- Pandaboard: /etc/ttys should be updated, serial console device is
+	  now /dev/ttyu2, not /dev/ttyu0
+
 20150501:
 	soelim(1) from gnu/usr.bin/groff has been replaced by usr.bin/soelim.
 	If you need the GNU extension from groff soelim(1), install groff

Modified: head/sys/arm/conf/BEAGLEBONE
==============================================================================
--- head/sys/arm/conf/BEAGLEBONE	Fri May 22 02:00:44 2015	(r283275)
+++ head/sys/arm/conf/BEAGLEBONE	Fri May 22 03:16:18 2015	(r283276)
@@ -133,5 +133,8 @@ device		axe			# ASIX Electronics USB Eth
 device		usb_template    	# Control of the gadget
 device		usfs
 
+# Pinmux
+device		fdt_pinctrl
+
 # Flattened Device Tree
 options 	FDT			# Configure using FDT/DTB data

Modified: head/sys/arm/conf/PANDABOARD
==============================================================================
--- head/sys/arm/conf/PANDABOARD	Fri May 22 02:00:44 2015	(r283275)
+++ head/sys/arm/conf/PANDABOARD	Fri May 22 03:16:18 2015	(r283276)
@@ -57,6 +57,7 @@ options 	DDB			# Enable the kernel debug
 #options 	BOOTP_NFSV3
 #options 	BOOTP_WIRED_TO=ue0
 
+device		fdt_pinctrl
 # Interrupt controller
 device		gic
 
@@ -81,6 +82,7 @@ device		pl310			# PL310 L2 cache control
 
 # GPIO
 device		gpio
+device		gpioled
 
 # The following enables MFS as root, this seems similar to an initramfs or initrd
 # as used in Linux.

Modified: head/sys/arm/ti/aintc.c
==============================================================================
--- head/sys/arm/ti/aintc.c	Fri May 22 02:00:44 2015	(r283275)
+++ head/sys/arm/ti/aintc.c	Fri May 22 03:16:18 2015	(r283276)
@@ -69,7 +69,6 @@ static struct resource_spec ti_aintc_spe
 	{ -1, 0 }
 };
 
-
 static struct ti_aintc_softc *ti_aintc_sc = NULL;
 
 #define	aintc_read_4(_sc, reg)		\
@@ -77,6 +76,12 @@ static struct ti_aintc_softc *ti_aintc_s
 #define	aintc_write_4(_sc, reg, val)		\
     bus_space_write_4((_sc)->aintc_bst, (_sc)->aintc_bsh, (reg), (val))
 
+/* List of compatible strings for FDT tree */
+static struct ofw_compat_data compat_data[] = {
+	{"ti,am33xx-intc",	1},
+	{"ti,omap2-intc",	1},
+	{NULL,		 	0},
+};
 
 static void
 aintc_post_filter(void *arg)
@@ -92,9 +97,9 @@ ti_aintc_probe(device_t dev)
 	if (!ofw_bus_status_okay(dev))
 		return (ENXIO);
 
-
-	if (!ofw_bus_is_compatible(dev, "ti,aintc"))
+	if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
 		return (ENXIO);
+
 	device_set_desc(dev, "TI AINTC Interrupt Controller");
 	return (BUS_PROBE_DEFAULT);
 }

Modified: head/sys/arm/ti/am335x/am335x_dmtimer.c
==============================================================================
--- head/sys/arm/ti/am335x/am335x_dmtimer.c	Fri May 22 02:00:44 2015	(r283275)
+++ head/sys/arm/ti/am335x/am335x_dmtimer.c	Fri May 22 03:16:18 2015	(r283276)
@@ -54,7 +54,8 @@ __FBSDID("$FreeBSD$");
 #include <machine/bus.h>
 
 #include <arm/ti/ti_prcm.h>
-#include <arm/ti/ti_scm.h>
+#include <arm/ti/ti_hwmods.h>
+#include <arm/ti/ti_pinmux.h>
 
 #define	AM335X_NUM_TIMERS	8
 
@@ -109,78 +110,38 @@ __FBSDID("$FreeBSD$");
 #define	DEFAULT_ET_TIMER	2
 #define	DEFAULT_TC_TIMER	3
 
+#define	DMTIMER_READ4(sc, reg)	(bus_read_4((sc)->tmr_mem_res, (reg)))
+#define	DMTIMER_WRITE4(sc, reg, val)	(bus_write_4((sc)->tmr_mem_res, (reg), (val)))
+
 struct am335x_dmtimer_softc {
-	struct resource *	tmr_mem_res[AM335X_NUM_TIMERS];
-	struct resource *	tmr_irq_res[AM335X_NUM_TIMERS];
+	device_t		dev;
+	int			tmr_mem_rid;
+	struct resource *	tmr_mem_res;
+	int			tmr_irq_rid;
+	struct resource *	tmr_irq_res;
+	void			*tmr_irq_handler;
 	uint32_t		sysclk_freq;
-	uint32_t		tc_num;		/* Which timer number is tc. */
-	uint32_t		tc_tclr;	/* Cached tc TCLR register. */
-	struct resource *	tc_memres;	/* Resources for tc timer. */
-	uint32_t		et_num;		/* Which timer number is et. */
-	uint32_t		et_tclr;	/* Cached et TCLR register. */
-	struct resource *	et_memres;	/* Resources for et timer. */
+	uint32_t		tclr;		/* Cached TCLR register. */
 	int			pps_curmode;	/* Edge mode now set in hw. */
 	struct task 		pps_task;	/* For pps_event handling. */
 	struct cdev *		pps_cdev;
 	struct pps_state 	pps;
-	struct timecounter	tc;
-	struct eventtimer	et;
-};
 
-static struct am335x_dmtimer_softc *am335x_dmtimer_sc;
-
-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 }
+	union {
+		struct timecounter tc;
+		struct eventtimer et;
+	} func;
 };
 
-static inline uint32_t
-am335x_dmtimer_tc_read_4(struct am335x_dmtimer_softc *sc, uint32_t reg)
-{
-
-	return (bus_read_4(sc->tc_memres, reg));
-}
-
-static inline void
-am335x_dmtimer_tc_write_4(struct am335x_dmtimer_softc *sc, uint32_t reg,
-    uint32_t val)
-{
-
-	bus_write_4(sc->tc_memres, reg, val);
-}
-
-static inline uint32_t
-am335x_dmtimer_et_read_4(struct am335x_dmtimer_softc *sc, uint32_t reg)
-{
-
-	return (bus_read_4(sc->et_memres, reg));
-}
+static struct am335x_dmtimer_softc *am335x_dmtimer_et_sc = NULL;
+static struct am335x_dmtimer_softc *am335x_dmtimer_tc_sc = NULL;
 
-static inline void
-am335x_dmtimer_et_write_4(struct am335x_dmtimer_softc *sc, uint32_t reg,
-    uint32_t val)
-{
 
-	bus_write_4(sc->et_memres, reg, val);
-}
+#ifdef PPS_SYNC
+/* -1 - not detected, 0 - not found, > 0 - timerX module */
+static int am335x_dmtimer_pps_module = -1;
+static const char *am335x_dmtimer_pps_hwmod = NULL;
+#endif
 
 /*
  * PPS driver routines, included when the kernel is built with option PPS_SYNC.
@@ -215,19 +176,19 @@ am335x_dmtimer_set_capture_mode(struct a
 		return;
 
 	sc->pps_curmode = newmode;
-	sc->tc_tclr &= ~DMT_TCLR_CAPTRAN_MASK;
+	sc->tclr &= ~DMT_TCLR_CAPTRAN_MASK;
 	switch (newmode) {
 	case PPS_CAPTUREASSERT:
-		sc->tc_tclr |= DMT_TCLR_CAPTRAN_LOHI;
+		sc->tclr |= DMT_TCLR_CAPTRAN_LOHI;
 		break;
 	case PPS_CAPTURECLEAR:
-		sc->tc_tclr |= DMT_TCLR_CAPTRAN_HILO;
+		sc->tclr |= DMT_TCLR_CAPTRAN_HILO;
 		break;
 	default:
 		/* It can't be BOTH, so it's disabled. */
 		break;
 	}
-	am335x_dmtimer_tc_write_4(sc, DMT_TCLR, sc->tc_tclr);
+	DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
 }
 
 static void
@@ -244,10 +205,10 @@ am335x_dmtimer_tc_poll_pps(struct timeco
 	 * TCAR status to re-arm the capture for the next second, we have to
 	 * write to the IRQ status register, not the RAW register.  Quirky.
 	 */
-	if (am335x_dmtimer_tc_read_4(sc, DMT_IRQSTATUS_RAW) & DMT_IRQ_TCAR) {
+	if (DMTIMER_READ4(sc, DMT_IRQSTATUS_RAW) & DMT_IRQ_TCAR) {
 		pps_capture(&sc->pps);
-		sc->pps.capcount = am335x_dmtimer_tc_read_4(sc, DMT_TCAR1);
-		am335x_dmtimer_tc_write_4(sc, DMT_IRQSTATUS, DMT_IRQ_TCAR);
+		sc->pps.capcount = DMTIMER_READ4(sc, DMT_TCAR1);
+		DMTIMER_WRITE4(sc, DMT_IRQSTATUS, DMT_IRQ_TCAR);
 		taskqueue_enqueue_fast(taskqueue_fast, &sc->pps_task);
 	}
 }
@@ -339,21 +300,15 @@ static struct cdevsw am335x_dmtimer_pps_
 	.d_name =       PPS_CDEV_NAME,
 };
 
-/*
- * Set up the PPS cdev and the the kernel timepps stuff.
- *
- * Note that this routine cannot touch the hardware, because bus space resources
- * are not fully set up yet when this is called.
- */
-static int
-am335x_dmtimer_pps_init(device_t dev, struct am335x_dmtimer_softc *sc)
+static void
+am335x_dmtimer_pps_find()
 {
-	int i, timer_num, unit;
+	int i;
 	unsigned int padstate;
 	const char * padmux;
 	struct padinfo {
 		char * ballname;
-		char * muxname;
+		const char * muxname;
 		int    timer_num;
 	} padinfo[] = {
 		{"GPMC_ADVn_ALE", "timer4", 4}, 
@@ -370,21 +325,47 @@ am335x_dmtimer_pps_init(device_t dev, st
 	 * is configured for input.  The right symbolic values aren't exported
 	 * yet from ti_scm.h.
 	 */
-	timer_num = 0;
-	for (i = 0; i < nitems(padinfo) && timer_num == 0; ++i) {
-		if (ti_scm_padconf_get(padinfo[i].ballname, &padmux, 
+	am335x_dmtimer_pps_module = 0;
+	for (i = 0; i < nitems(padinfo) && am335x_dmtimer_pps_module == 0; ++i) {
+		if (ti_pinmux_padconf_get(padinfo[i].ballname, &padmux, 
 		    &padstate) == 0) {
 			if (strcasecmp(padinfo[i].muxname, padmux) == 0 &&
-			    (padstate & (0x01 << 5)))
-				timer_num = padinfo[i].timer_num;
+			    (padstate & (0x01 << 5))) {
+				am335x_dmtimer_pps_module = padinfo[i].timer_num;
+				am335x_dmtimer_pps_hwmod = padinfo[i].muxname;
+			}
 		}
 	}
 
-	if (timer_num == 0) {
-		device_printf(dev, "No DMTimer found with capture pin "
+
+	if (am335x_dmtimer_pps_module == 0) {
+		printf("am335x_dmtimer: No DMTimer found with capture pin "
 		    "configured as input; PPS driver disabled.\n");
-		return (DEFAULT_TC_TIMER);
 	}
+}
+
+/*
+ * Set up the PPS cdev and the the kernel timepps stuff.
+ *
+ * Note that this routine cannot touch the hardware, because bus space resources
+ * are not fully set up yet when this is called.
+ */
+static void
+am335x_dmtimer_pps_init(device_t dev, struct am335x_dmtimer_softc *sc)
+{
+	int unit;
+
+	if (am335x_dmtimer_pps_module == -1)
+		am335x_dmtimer_pps_find();
+
+	/* No PPS input */
+	if (am335x_dmtimer_pps_module == 0)
+		return;
+
+	/* Not PPS-enabled input */
+	if ((am335x_dmtimer_pps_module > 0) &&
+	    (!ti_hwmods_contains(dev, am335x_dmtimer_pps_hwmod)))
+	 	return;
 
 	/*
 	 * Indicate our capabilities (pretty much just capture of either edge).
@@ -398,35 +379,21 @@ am335x_dmtimer_pps_init(device_t dev, st
 	 * Set up to capture the PPS via timecounter polling, and init the task
 	 * that does deferred pps_event() processing after capture.
 	 */
-	sc->tc.tc_poll_pps = am335x_dmtimer_tc_poll_pps;
+	sc->func.tc.tc_poll_pps = am335x_dmtimer_tc_poll_pps;
 	TASK_INIT(&sc->pps_task, 0, am335x_dmtimer_process_pps_event, sc);
 
 	/* Create the PPS cdev.  */
-	unit = device_get_unit(dev);
 	sc->pps_cdev = make_dev(&am335x_dmtimer_pps_cdevsw, unit, 
-	    UID_ROOT, GID_WHEEL, 0600, PPS_CDEV_NAME "%d", unit);
+	    UID_ROOT, GID_WHEEL, 0600, PPS_CDEV_NAME);
 	sc->pps_cdev->si_drv1 = sc;
+	unit = device_get_unit(sc->pps_cdev);
 
 	device_printf(dev, "Using DMTimer%d for PPS device /dev/%s%d\n", 
-	    timer_num, PPS_CDEV_NAME, unit);
-
-	return (timer_num);
+	    am335x_dmtimer_pps_module, PPS_CDEV_NAME, unit);
 }
 
-#else /* PPS_SYNC */
-
-static int
-am335x_dmtimer_pps_init(device_t dev, struct am335x_dmtimer_softc *sc)
-{
-
-	/*
-	 * When PPS support is not compiled in, there's no need to use a timer
-	 * that has an associated capture-input pin, so use the default.
-	 */
-	return (DEFAULT_TC_TIMER);
-}
+#endif
 
-#endif /* PPS_SYNC */
 /*
  * End of PPS driver code.
  */
@@ -438,7 +405,7 @@ am335x_dmtimer_tc_get_timecount(struct t
 
 	sc = tc->tc_priv;
 
-	return (am335x_dmtimer_tc_read_4(sc, DMT_TCRR));
+	return (DMTIMER_READ4(sc, DMT_TCRR));
 }
 
 static int
@@ -462,13 +429,13 @@ am335x_dmtimer_start(struct eventtimer *
 	 * from the et_event_cb() routine dispatched from our own handler, but
 	 * it's not clear to me that that's the only case possible.
 	 */
-	sc->et_tclr &= ~(DMT_TCLR_START | DMT_TCLR_AUTOLOAD);
-	am335x_dmtimer_et_write_4(sc, DMT_TCLR, sc->et_tclr);
-	am335x_dmtimer_et_write_4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
+	sc->tclr &= ~(DMT_TCLR_START | DMT_TCLR_AUTOLOAD);
+	DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
+	DMTIMER_WRITE4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
 
 	if (period != 0) {
 		reload_count = ((uint32_t)et->et_frequency * period) >> 32;
-		sc->et_tclr |= DMT_TCLR_AUTOLOAD;
+		sc->tclr |= DMT_TCLR_AUTOLOAD;
 	} else {
 		reload_count = 0;
 	}
@@ -482,13 +449,13 @@ am335x_dmtimer_start(struct eventtimer *
 	 * Set auto-reload and current-count values.  This timer hardware counts
 	 * up from the initial/reload value and interrupts on the zero rollover.
 	 */
-	am335x_dmtimer_et_write_4(sc, DMT_TLDR, 0xFFFFFFFF - reload_count);
-	am335x_dmtimer_et_write_4(sc, DMT_TCRR, 0xFFFFFFFF - initial_count);
+	DMTIMER_WRITE4(sc, DMT_TLDR, 0xFFFFFFFF - reload_count);
+	DMTIMER_WRITE4(sc, DMT_TCRR, 0xFFFFFFFF - initial_count);
 
 	/* Enable overflow interrupt, and start the timer. */
-	am335x_dmtimer_et_write_4(sc, DMT_IRQENABLE_SET, DMT_IRQ_OVF);
-	sc->et_tclr |= DMT_TCLR_START;
-	am335x_dmtimer_et_write_4(sc, DMT_TCLR, sc->et_tclr);
+	DMTIMER_WRITE4(sc, DMT_IRQENABLE_SET, DMT_IRQ_OVF);
+	sc->tclr |= DMT_TCLR_START;
+	DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
 
 	return (0);
 }
@@ -501,10 +468,10 @@ am335x_dmtimer_stop(struct eventtimer *e
 	sc = et->et_priv;
 
 	/* Stop timer, disable and clear interrupt. */
-	sc->et_tclr &= ~(DMT_TCLR_START | DMT_TCLR_AUTOLOAD);
-	am335x_dmtimer_et_write_4(sc, DMT_TCLR, sc->et_tclr);
-	am335x_dmtimer_et_write_4(sc, DMT_IRQENABLE_CLR, DMT_IRQ_OVF);
-	am335x_dmtimer_et_write_4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
+	sc->tclr &= ~(DMT_TCLR_START | DMT_TCLR_AUTOLOAD);
+	DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
+	DMTIMER_WRITE4(sc, DMT_IRQENABLE_CLR, DMT_IRQ_OVF);
+	DMTIMER_WRITE4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
 	return (0);
 }
 
@@ -516,13 +483,96 @@ am335x_dmtimer_intr(void *arg)
 	sc = arg;
 
 	/* Ack the interrupt, and invoke the callback if it's still enabled. */
-	am335x_dmtimer_et_write_4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
-	if (sc->et.et_active)
-		sc->et.et_event_cb(&sc->et, sc->et.et_arg);
+	DMTIMER_WRITE4(sc, DMT_IRQSTATUS, DMT_IRQ_OVF);
+	if (sc->func.et.et_active)
+		sc->func.et.et_event_cb(&sc->func.et, sc->func.et.et_arg);
 
 	return (FILTER_HANDLED);
 }
 
+/*
+ * Checks if timer is suitable to be system timer
+ */
+static int
+am335x_dmtimer_system_compatible(device_t dev)
+{
+	phandle_t node;
+
+	node = ofw_bus_get_node(dev);
+	if (OF_hasprop(node, "ti,timer-alwon"))
+		return (0);
+
+	return (1);
+}
+
+static int
+am335x_dmtimer_init_et(struct am335x_dmtimer_softc *sc)
+{
+	if (am335x_dmtimer_et_sc != NULL)
+		return (EEXIST);
+
+#ifdef PPS_SYNC
+	if ((am335x_dmtimer_pps_module > 0) &&
+	    (!ti_hwmods_contains(sc->dev, am335x_dmtimer_pps_hwmod))) {
+	    	device_printf(sc->dev, "not PPS enabled\n");
+	 	return (ENXIO);
+	}
+#endif
+
+	/* Setup eventtimer interrupt handler. */
+	if (bus_setup_intr(sc->dev, sc->tmr_irq_res, INTR_TYPE_CLK,
+			am335x_dmtimer_intr, NULL, sc, &sc->tmr_irq_handler) != 0) {
+		device_printf(sc->dev, "Unable to setup the clock irq handler.\n");
+		return (ENXIO);
+	}
+
+	sc->func.et.et_name = "AM335x Eventtimer";
+	sc->func.et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
+	sc->func.et.et_quality = 1000;
+	sc->func.et.et_frequency = sc->sysclk_freq;
+	sc->func.et.et_min_period =
+	    ((0x00000005LLU << 32) / sc->func.et.et_frequency);
+	sc->func.et.et_max_period =
+	    (0xfffffffeLLU << 32) / sc->func.et.et_frequency;
+	sc->func.et.et_start = am335x_dmtimer_start;
+	sc->func.et.et_stop = am335x_dmtimer_stop;
+	sc->func.et.et_priv = sc;
+	et_register(&sc->func.et);
+
+	am335x_dmtimer_et_sc = sc;
+
+	return (0);
+}
+
+static int
+am335x_dmtimer_init_tc(struct am335x_dmtimer_softc *sc)
+{
+	if (am335x_dmtimer_tc_sc != NULL)
+		return (EEXIST);
+
+	/* Set up timecounter, start it, register it. */
+	DMTIMER_WRITE4(sc, DMT_TSICR, DMT_TSICR_RESET);
+	while (DMTIMER_READ4(sc, DMT_TIOCP_CFG) & DMT_TIOCP_RESET)
+		continue;
+
+	sc->tclr |= DMT_TCLR_START | DMT_TCLR_AUTOLOAD;
+	DMTIMER_WRITE4(sc, DMT_TLDR, 0);
+	DMTIMER_WRITE4(sc, DMT_TCRR, 0);
+	DMTIMER_WRITE4(sc, DMT_TCLR, sc->tclr);
+
+	sc->func.tc.tc_name           = "AM335x Timecounter";
+	sc->func.tc.tc_get_timecount  = am335x_dmtimer_tc_get_timecount;
+	sc->func.tc.tc_counter_mask   = ~0u;
+	sc->func.tc.tc_frequency      = sc->sysclk_freq;
+	sc->func.tc.tc_quality        = 1000;
+	sc->func.tc.tc_priv           = sc;
+	tc_init(&sc->func.tc);
+
+	am335x_dmtimer_tc_sc = sc;
+
+	return (0);
+}
+
 static int
 am335x_dmtimer_probe(device_t dev)
 {
@@ -530,7 +580,8 @@ am335x_dmtimer_probe(device_t dev)
 	if (!ofw_bus_status_okay(dev))
 		return (ENXIO);
 
-	if (ofw_bus_is_compatible(dev, "ti,am335x-dmtimer")) {
+	if (ofw_bus_is_compatible(dev, "ti,am335x-timer-1ms") ||
+	    ofw_bus_is_compatible(dev, "ti,am335x-timer")) {
 		device_set_desc(dev, "AM335x DMTimer");
 		return(BUS_PROBE_DEFAULT);
 	}
@@ -542,8 +593,9 @@ static int
 am335x_dmtimer_attach(device_t dev)
 {
 	struct am335x_dmtimer_softc *sc;
-	void *ihl;
 	int err;
+	clk_ident_t timer_id;
+	int enable;
 
 	/*
 	 * Note that if this routine returns an error status rather than running
@@ -552,9 +604,7 @@ am335x_dmtimer_attach(device_t dev)
 	 */
 
 	sc = device_get_softc(dev);
-
-	if (am335x_dmtimer_sc != NULL)
-		return (EINVAL);
+	sc->dev = dev;
 
 	/* Get the base clock frequency. */
 	err = ti_prcm_clk_get_source_freq(SYS_CLK, &sc->sysclk_freq);
@@ -564,82 +614,61 @@ am335x_dmtimer_attach(device_t dev)
 	}
 
 	/* Request the memory resources. */
-	err = bus_alloc_resources(dev, am335x_dmtimer_mem_spec,
-		sc->tmr_mem_res);
-	if (err) {
+	sc->tmr_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+	    &sc->tmr_mem_rid, RF_ACTIVE);
+	if (sc->tmr_mem_res == NULL) {
 		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);
+	sc->tmr_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+	    &sc->tmr_irq_rid, RF_ACTIVE);
 	if (err) {
+		bus_release_resource(dev, SYS_RES_MEMORY, sc->tmr_mem_rid,
+		    sc->tmr_mem_res);
 		device_printf(dev, "Error: could not allocate irq resources\n");
 		return (ENXIO);
 	}
 
-	/*
-	 * Use the default eventtimer.  Let the PPS init routine decide which
-	 * timer to use for the timecounter.
-	 */
-	sc->et_num = DEFAULT_ET_TIMER;
-	sc->tc_num = am335x_dmtimer_pps_init(dev, sc);
+#ifdef PPS_SYNC
+	am335x_dmtimer_pps_init(dev, sc);
+#endif
 
-	sc->et_memres = sc->tmr_mem_res[sc->et_num];
-	sc->tc_memres = sc->tmr_mem_res[sc->tc_num];
+	enable = 0;
+	/* Try to use as a timecounter or event timer */
+	if (am335x_dmtimer_system_compatible(dev)) {
+		if (am335x_dmtimer_init_tc(sc) == 0)
+			enable = 1;
+		else if (am335x_dmtimer_init_et(sc) == 0)
+			enable = 1;
+	}
+
+	if (enable) {
+		/* Enable clocks and power on the chosen devices. */
+		timer_id = ti_hwmods_get_clock(dev);
+		if (timer_id == INVALID_CLK_IDENT) {
+			bus_release_resource(dev, SYS_RES_MEMORY, sc->tmr_mem_rid,
+			    sc->tmr_mem_res);
+			bus_release_resource(dev, SYS_RES_IRQ, sc->tmr_irq_rid,
+			    sc->tmr_irq_res);
+			device_printf(dev, "failed to get device id using ti,hwmods\n");
+			return (ENXIO);
+		}
 
-	/* Enable clocks and power on the chosen devices. */
-	err  = ti_prcm_clk_set_source(DMTIMER0_CLK + sc->et_num, SYSCLK_CLK);
-	err |= ti_prcm_clk_enable(DMTIMER0_CLK + sc->et_num);
-	err |= ti_prcm_clk_set_source(DMTIMER0_CLK + sc->tc_num, SYSCLK_CLK);
-	err |= ti_prcm_clk_enable(DMTIMER0_CLK + sc->tc_num);
-	if (err) {
-		device_printf(dev, "Error: could not enable timer clock\n");
-		return (ENXIO);
-	}
+		err  = ti_prcm_clk_set_source(timer_id, SYSCLK_CLK);
+		err |= ti_prcm_clk_enable(timer_id);
 
-	/* Setup eventtimer interrupt handler. */
-	if (bus_setup_intr(dev, sc->tmr_irq_res[sc->et_num], INTR_TYPE_CLK,
-			am335x_dmtimer_intr, NULL, sc, &ihl) != 0) {
-		device_printf(dev, "Unable to setup the clock irq handler.\n");
-		return (ENXIO);
+		if (err) {
+			bus_release_resource(dev, SYS_RES_MEMORY, sc->tmr_mem_rid,
+			    sc->tmr_mem_res);
+			bus_release_resource(dev, SYS_RES_IRQ, sc->tmr_irq_rid,
+			    sc->tmr_irq_res);
+			device_printf(dev, "Error: could not enable timer clock\n");
+			return (ENXIO);
+		}
 	}
 
-	/* Set up timecounter, start it, register it. */
-	am335x_dmtimer_tc_write_4(sc, DMT_TSICR, DMT_TSICR_RESET);
-	while (am335x_dmtimer_tc_read_4(sc, DMT_TIOCP_CFG) & DMT_TIOCP_RESET)
-		continue;
-
-	sc->tc_tclr |= DMT_TCLR_START | DMT_TCLR_AUTOLOAD;
-	am335x_dmtimer_tc_write_4(sc, DMT_TLDR, 0);
-	am335x_dmtimer_tc_write_4(sc, DMT_TCRR, 0);
-	am335x_dmtimer_tc_write_4(sc, DMT_TCLR, sc->tc_tclr);
-
-	sc->tc.tc_name           = "AM335x Timecounter";
-	sc->tc.tc_get_timecount  = am335x_dmtimer_tc_get_timecount;
-	sc->tc.tc_counter_mask   = ~0u;
-	sc->tc.tc_frequency      = sc->sysclk_freq;
-	sc->tc.tc_quality        = 1000;
-	sc->tc.tc_priv           = sc;
-	tc_init(&sc->tc);
-
-	sc->et.et_name = "AM335x Eventtimer";
-	sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
-	sc->et.et_quality = 1000;
-	sc->et.et_frequency = sc->sysclk_freq;
-	sc->et.et_min_period =
-	    ((0x00000005LLU << 32) / sc->et.et_frequency);
-	sc->et.et_max_period =
-	    (0xfffffffeLLU << 32) / sc->et.et_frequency;
-	sc->et.et_start = am335x_dmtimer_start;
-	sc->et.et_stop = am335x_dmtimer_stop;
-	sc->et.et_priv = sc;
-	et_register(&sc->et);
-
-	/* Store a pointer to the softc for use in DELAY(). */
-	am335x_dmtimer_sc = sc;
-
 	return (0);
 }
 
@@ -667,7 +696,7 @@ DELAY(int usec)
 	int32_t counts;
 	uint32_t first, last;
 
-	sc = am335x_dmtimer_sc;
+	sc = am335x_dmtimer_tc_sc;
 
 	if (sc == NULL) {
 		for (; usec > 0; usec--)
@@ -680,10 +709,10 @@ DELAY(int usec)
 	/* Get the number of times to count */
 	counts = (usec + 1) * (sc->sysclk_freq / 1000000);
 
-	first = am335x_dmtimer_tc_read_4(sc, DMT_TCRR);
+	first = DMTIMER_READ4(sc, DMT_TCRR);
 
 	while (counts > 0) {
-		last = am335x_dmtimer_tc_read_4(sc, DMT_TCRR);
+		last = DMTIMER_READ4(sc, DMT_TCRR);
 		if (last > first) {
 			counts -= (int32_t)(last - first);
 		} else {

Added: head/sys/arm/ti/am335x/am335x_ecap.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/arm/ti/am335x/am335x_ecap.c	Fri May 22 03:16:18 2015	(r283276)
@@ -0,0 +1,201 @@
+/*-
+ * Copyright (c) 2013 Oleksandr Tymoshenko <gonzo@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/limits.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.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 "am335x_pwm.h"
+
+#define	ECAP_TSCTR		0x00
+#define	ECAP_CAP1		0x08
+#define	ECAP_CAP2		0x0C
+#define	ECAP_CAP3		0x10
+#define	ECAP_CAP4		0x14
+#define	ECAP_ECCTL2		0x2A
+#define		ECCTL2_MODE_APWM		(1 << 9)
+#define		ECCTL2_SYNCO_SEL		(3 << 6)
+#define		ECCTL2_TSCTRSTOP_FREERUN	(1 << 4)
+
+#define	ECAP_READ2(_sc, reg)	bus_read_2((_sc)->sc_mem_res, reg);
+#define	ECAP_WRITE2(_sc, reg, value)	\
+    bus_write_2((_sc)->sc_mem_res, reg, value);
+#define	ECAP_READ4(_sc, reg)	bus_read_4((_sc)->sc_mem_res, reg);
+#define	ECAP_WRITE4(_sc, reg, value)	\
+    bus_write_4((_sc)->sc_mem_res, reg, value);
+
+#define	PWM_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	PWM_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#define	PWM_LOCK_INIT(_sc)	mtx_init(&(_sc)->sc_mtx, \
+    device_get_nameunit(_sc->sc_dev), "am335x_ecap softc", MTX_DEF)
+#define	PWM_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->sc_mtx)
+
+static device_probe_t am335x_ecap_probe;
+static device_attach_t am335x_ecap_attach;
+static device_detach_t am335x_ecap_detach;
+
+struct am335x_ecap_softc {
+	device_t		sc_dev;
+	struct mtx		sc_mtx;
+	struct resource		*sc_mem_res;
+	int			sc_mem_rid;
+};
+
+static device_method_t am335x_ecap_methods[] = {
+	DEVMETHOD(device_probe,		am335x_ecap_probe),
+	DEVMETHOD(device_attach,	am335x_ecap_attach),
+	DEVMETHOD(device_detach,	am335x_ecap_detach),
+
+	DEVMETHOD_END
+};
+
+static driver_t am335x_ecap_driver = {
+	"am335x_ecap",
+	am335x_ecap_methods,
+	sizeof(struct am335x_ecap_softc),
+};
+
+static devclass_t am335x_ecap_devclass;
+
+/*
+ * API function to set period/duty cycles for ECAPx
+ */
+int
+am335x_pwm_config_ecap(int unit, int period, int duty)
+{
+	device_t dev;
+	struct am335x_ecap_softc *sc;
+	uint16_t reg;
+
+	dev = devclass_get_device(am335x_ecap_devclass, unit);
+	if (dev == NULL)
+		return (ENXIO);
+
+	if (duty > period)
+		return (EINVAL);
+
+	if (period == 0)
+		return (EINVAL);
+
+	sc = device_get_softc(dev);
+	PWM_LOCK(sc);
+
+	reg = ECAP_READ2(sc, ECAP_ECCTL2);
+	reg |= ECCTL2_MODE_APWM | ECCTL2_TSCTRSTOP_FREERUN | ECCTL2_SYNCO_SEL;
+	ECAP_WRITE2(sc, ECAP_ECCTL2, reg);
+
+	/* CAP3 in APWM mode is APRD shadow register */
+	ECAP_WRITE4(sc, ECAP_CAP3, period - 1);
+
+	/* CAP4 in APWM mode is ACMP shadow register */
+	ECAP_WRITE4(sc, ECAP_CAP4, duty);
+	/* Restart counter */
+	ECAP_WRITE4(sc, ECAP_TSCTR, 0);
+
+	PWM_UNLOCK(sc);
+
+	return (0);
+}
+
+static int
+am335x_ecap_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (!ofw_bus_is_compatible(dev, "ti,am33xx-ecap"))
+		return (ENXIO);
+
+	device_set_desc(dev, "AM335x eCAP");
+
+	return (BUS_PROBE_DEFAULT);
+}
+
+static int
+am335x_ecap_attach(device_t dev)
+{
+	struct am335x_ecap_softc *sc;
+
+	sc = device_get_softc(dev);
+	sc->sc_dev = dev;
+
+	PWM_LOCK_INIT(sc);
+
+	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
+	    &sc->sc_mem_rid, RF_ACTIVE);
+	if (sc->sc_mem_res == NULL) {
+		device_printf(dev, "cannot allocate memory resources\n");
+		goto fail;
+	}
+
+	return (0);
+
+fail:
+	PWM_LOCK_DESTROY(sc);
+	return (ENXIO);
+}
+
+static int
+am335x_ecap_detach(device_t dev)
+{
+	struct am335x_ecap_softc *sc;
+
+	sc = device_get_softc(dev);
+
+	PWM_LOCK(sc);
+	if (sc->sc_mem_res)
+		bus_release_resource(dev, SYS_RES_MEMORY,
+		    sc->sc_mem_rid, sc->sc_mem_res);
+	PWM_UNLOCK(sc);
+
+	PWM_LOCK_DESTROY(sc);
+
+
+	return (0);
+}
+
+DRIVER_MODULE(am335x_ecap, am335x_pwmss, am335x_ecap_driver, am335x_ecap_devclass, 0, 0);
+MODULE_VERSION(am335x_ecap, 1);
+MODULE_DEPEND(am335x_ecap, am335x_pwmss, 1, 1, 1);

Added: head/sys/arm/ti/am335x/am335x_ehrpwm.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/arm/ti/am335x/am335x_ehrpwm.c	Fri May 22 03:16:18 2015	(r283276)
@@ -0,0 +1,448 @@
+/*-
+ * Copyright (c) 2013 Oleksandr Tymoshenko <gonzo@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/limits.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/resource.h>
+#include <sys/rman.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.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 "am335x_pwm.h"
+
+/* In ticks */
+#define	DEFAULT_PWM_PERIOD	1000
+#define	PWM_CLOCK		100000000UL
+
+#define	PWM_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
+#define	PWM_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
+#define	PWM_LOCK_INIT(_sc)	mtx_init(&(_sc)->sc_mtx, \
+    device_get_nameunit(_sc->sc_dev), "am335x_ehrpwm softc", MTX_DEF)
+#define	PWM_LOCK_DESTROY(_sc)	mtx_destroy(&(_sc)->sc_mtx)
+
+#define	EPWM_READ2(_sc, reg)	bus_read_2((_sc)->sc_mem_res, reg);
+#define	EPWM_WRITE2(_sc, reg, value)	\
+    bus_write_2((_sc)->sc_mem_res, reg, value);
+
+#define	EPWM_TBCTL		0x00
+#define		TBCTL_FREERUN		(2 << 14)
+#define		TBCTL_PHDIR_UP		(1 << 13)
+#define		TBCTL_PHDIR_DOWN	(0 << 13)
+#define		TBCTL_CLKDIV(x)		((x) << 10)
+#define		TBCTL_CLKDIV_MASK	(3 << 10)
+#define		TBCTL_HSPCLKDIV(x)	((x) << 7)
+#define		TBCTL_HSPCLKDIV_MASK	(3 << 7)
+#define		TBCTL_SYNCOSEL_DISABLED	(3 << 4)
+#define		TBCTL_PRDLD_SHADOW	(0 << 3)
+#define		TBCTL_PRDLD_IMMEDIATE	(0 << 3)
+#define		TBCTL_PHSEN_ENABLED	(1 << 2)
+#define		TBCTL_PHSEN_DISABLED	(0 << 2)
+#define		TBCTL_CTRMODE_MASK	(3)
+#define		TBCTL_CTRMODE_UP	(0 << 0)
+#define		TBCTL_CTRMODE_DOWN	(1 << 0)
+#define		TBCTL_CTRMODE_UPDOWN	(2 << 0)
+#define		TBCTL_CTRMODE_FREEZE	(3 << 0)
+
+#define	EPWM_TBSTS		0x02
+#define	EPWM_TBPHSHR		0x04
+#define	EPWM_TBPHS		0x06
+#define	EPWM_TBCNT		0x08
+#define	EPWM_TBPRD		0x0a
+/* Counter-compare */
+#define	EPWM_CMPCTL		0x0e
+#define		CMPCTL_SHDWBMODE_SHADOW		(1 << 6)
+#define		CMPCTL_SHDWBMODE_IMMEDIATE	(0 << 6)
+#define		CMPCTL_SHDWAMODE_SHADOW		(1 << 4)
+#define		CMPCTL_SHDWAMODE_IMMEDIATE	(0 << 4)
+#define		CMPCTL_LOADBMODE_ZERO		(0 << 2)
+#define		CMPCTL_LOADBMODE_PRD		(1 << 2)

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505220316.t4M3GJT9021693>