socsvn commit: r237610 - in soc2012/aleek/beaglexm-armv6/sys: arm/ti/am37x boot/fdt/dts

aleek at FreeBSD.org aleek at FreeBSD.org
Wed Jun 13 14:38:57 UTC 2012


Author: aleek
Date: Wed Jun 13 14:38:54 2012
New Revision: 237610
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=237610

Log:
  Almost all OMAP3 GPTIMER support is written

Modified:
  soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_gptimer.c
  soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_gptimer.h
  soc2012/aleek/beaglexm-armv6/sys/boot/fdt/dts/beagleboardxm.dts

Modified: soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_gptimer.c
==============================================================================
--- soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_gptimer.c	Wed Jun 13 14:20:15 2012	(r237609)
+++ soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_gptimer.c	Wed Jun 13 14:38:54 2012	(r237610)
@@ -42,6 +42,7 @@
 #include <sys/rman.h>
 #include <sys/timetc.h>
 #include <sys/lock.h>
+#include "sys/gpio.h""
 #include <sys/mutex.h>
 
 #include <machine/bus.h>
@@ -56,8 +57,11 @@
 #include <arm/ti/am37x/am37x_gptimer.h>
 
 
+
 static struct omap3_gptimer_softc *g_omap3_gptimer_sc = NULL;
 
+static unsigned int delay_loops_per_us = 100;
+
 
 /**
  * Timer for tick counting. This is used to measure time by CPU
@@ -89,6 +93,48 @@
 	.tc_quality        = 1000,
 };
 
+#define __omap3_delay(i)                                     \
+	do {                                                     \
+		unsigned int cnt = (i);                              \
+		__asm __volatile("1:  subs   %0, %0, 1\n"            \
+		                 "    bne    1b\n"                   \
+		                 : "+r" (cnt) : : "cc");             \
+	} while(0)
+
+/**
+ *	omap3_calibrate_delay_loop - uses the setup timecounter to configure delay
+ *
+ *	This is not very scientfic, basically just use the timecount to measure the
+ *	time to do 1000 delay loops (for loop with 1024 loops).
+ *
+ *
+ */
+static int
+omap3_calibrate_delay_loop(struct timecounter *tc)
+{
+	u_int oldirqstate;
+	unsigned int start, end;
+	uint64_t nanosecs;
+	
+	/* Disable interrupts to ensure they don't mess up the calculation */
+	oldirqstate = disable_interrupts(I32_bit);
+
+	start = omap3_gptimer_tc_get_timecount(tc);
+	__omap3_delay(10240);
+	end = omap3_gptimer_tc_get_timecount(tc);
+
+	restore_interrupts(oldirqstate);
+
+	/* Calculate the number of loops in 1us */
+	nanosecs = ((uint64_t)(end - start) * 1000000000ULL) / tc->tc_frequency;
+	delay_loops_per_us = (unsigned int)((uint64_t)(10240 * 1000) / nanosecs);
+
+	printf("OMAP3: delay loop calibrated to %u cycles\n", delay_loops_per_us);
+	
+	return (0);
+}
+
+
 static unsigned
 omap3_gptimer_tc_get_timecount(struct timecounter *tc)
 {
@@ -99,7 +145,7 @@
 }
 
 /**
- *	omap_gptimer_read_count - reads the current timer value
+ *	omap3_gptimer_read_count - reads the current timer value
  *	@n: the number of the timer (first timer is number 1)
  *	@cnt:
  *	
@@ -110,8 +156,8 @@
 int
 omap3_gptimer_read_count(unsigned int n, uint32_t *cnt)
 {
-	struct omap_gptimer_softc *sc = g_omap_gptimer_sc;
-	struct omap_gptimer *timer;
+	struct omap3_gptimer_softc *sc = g_omap3_gptimer_sc;
+	struct omap3_gptimer *timer;
 	int ret;
 
 	/* Sanity checks */
@@ -125,10 +171,10 @@
 	
 	OMAP3_GPTIMER_LOCK(timer);
 	
-	if (!(timer->flags & OMAP_GPTIMER_ACTIVATED_FLAG)) {
+	if (!(timer->flags & OMAP3_GPTIMER_ACTIVATED_FLAG)) {
 		ret = EINVAL;
 	} else {
-		*cnt = omap_gptimer_readl(timer, timer->tcrr);
+		*cnt = omap3_gptimer_readl(timer, OMAP3_GPT_TCRR);
 		ret = 0;
 	}
 
@@ -139,7 +185,7 @@
 
 
 /**
- *	omap_gptimer_write_count - writes a value into the current count
+ *	omap3_gptimer_write_count - writes a value into the current count
  *	@n: the number of the timer (first timer is number 1)
  *	@cnt: the value to put in the count register
  *
@@ -151,23 +197,23 @@
 int
 omap3_gptimer_write_count(unsigned int n, uint32_t cnt)
 {
-	struct omap_gptimer_softc *sc = g_omap_gptimer_sc;
-	struct omap_gptimer *timer;
+	struct omap3_gptimer_softc *sc = g_omap3_gptimer_sc;
+	struct omap3_gptimer *timer;
 
 	/* Sanity checks */
 	if (sc == NULL)
 		return (ENOMEM);
-	if ((n == 0) || (n > MAX_NUM_TIMERS))
+	if ((n == 0) || (n > OMAP3_NUM_TIMERS))
 		return (EINVAL);
 
 	/* Get a pointer to the individual timer struct */
 	timer = &sc->sc_timers[n-1];
-	if (!(timer->flags & OMAP_GPTIMER_ACTIVATED_FLAG))
+	if (!(timer->flags & OMAP3_GPTIMER_ACTIVATED_FLAG))
 		return (EINVAL);
 
 	OMAP3_GPTIMER_LOCK(timer);
 	
-	omap_gptimer_writel(timer, timer->tcrr, cnt);
+	omap3_gptimer_writel(timer, OMAP3_GPT_TCRR, cnt);
 
 	OMAP3_GPTIMER_UNLOCK(timer);
 	
@@ -176,7 +222,7 @@
 
 
 /**
- *	omap_gptimer_readl - reads a 32-bit value from one of the timer registers
+ *	omap3_gptimer_readl - reads a 32-bit value from one of the timer registers
  *	@timer: Timer device context
  *	@off: The offset of a register from the timer register address range
  *
@@ -191,7 +237,7 @@
 }
 
 /**
- *	omap_gptimer_writel - writes a 32-bit value to one of the timer registers
+ *	omap3_gptimer_writel - writes a 32-bit value to one of the timer registers
  *	@timer: Timer device context
  *	@off: The offset of a register from the timer register address range
  *	@val: The value to write into the register
@@ -206,9 +252,81 @@
 	bus_write_4(timer->mem_res, off, val);
 }
 
+/**
+ *	omap_gptimer_get_freq - gets the frequency of an activated timer
+ *	@n: the number of the timer (first timer is number 1)
+ *	@freq: unpon return will contain the current freq
+ *
+ *	The timer must be activated, if not this function will return EINVAL.
+ *
+ *	RETURNS:
+ *	Returns 0 on success, otherwise an error code
+ */
+int
+omap3_gptimer_get_freq(unsigned int n, uint32_t *freq)
+{
+	struct omap3_gptimer_softc *sc = g_omap3_gptimer_sc;
+	struct omap3_gptimer *timer;
+	unsigned int src_freq;
+	unsigned int tmr_freq;
+	unsigned int prescaler;
+	uint32_t tclr, tldr;
+	int rc;
+
+	/* Sanity checks */
+	if (sc == NULL)
+		return (ENOMEM);
+	if ((n == 0) || (n > OMAP3_NUM_TIMERS))
+		return (EINVAL);
+	if (freq == NULL)
+		return (EINVAL);
+
+	/* Get a pointer to the individual timer struct */
+	timer = &sc->sc_timers[n-1];
+	if (!(timer->flags & OMAP3_GPTIMER_ACTIVATED_FLAG))
+		return (EINVAL);
+
+	/* We get the frequency by first reading the source frequency */
+	if ((rc = ti_prcm_clk_get_source_freq(timer->source, &src_freq)) != 0)
+		return (rc);
+
+
+	OMAP3_GPTIMER_LOCK(timer);
+	
+	/* Determine if the pre-scalar is enabled and if so the prescaler value */
+	tclr = omap3_gptimer_readl(timer, OMAP3_GPT_TCLR);
+	if (tclr & TCLR_PRE)
+		prescaler = 1UL << (((tclr & TCLR_PTV_MASK) >> 2) + 1);
+	else
+		prescaler = 1;
+
+	/* Get the reload count */
+	tldr = omap3_gptimer_readl(timer, OMAP3_GPT_TLDR);
+	
+	OMAP3_GPTIMER_UNLOCK(timer);
+	
+	
+	/* Calculate the tick freq */
+	tmr_freq = (src_freq / prescaler);
+
+	/* If auto-reload mode is set and the reload count is not zero then the
+	 * frequency is the period between overflows.
+	 */
+	if ((tclr & TCLR_AR) && (tldr != 0x00000000)) {
+		tmr_freq /= ((0xffffffff - tldr) + 1);
+	}
+	
+	
+	if (freq != NULL)
+		*freq = tmr_freq;
+	
+	return (0);
+}
+
+
 
 /**
- *	omap_gptimer_activate - configures the timer
+ *	omap3_gptimer_activate - configures the timer
  *	@n: the number of the timer (first timer is number 1)
  *	@flags: defines the type of timer to turn on
  *	@time_ns: the period of the timer in nanoseconds
@@ -220,11 +338,11 @@
  *	Returns 0 on success, otherwise an error code
  */
 int
-omap_gptimer_activate(unsigned int n, unsigned int flags, unsigned int time_us,
+omap3_gptimer_activate(unsigned int n, unsigned int flags, unsigned int time_us,
                     void (*callback)(void *data), void *data)
 {
-	struct omap_gptimer_softc *sc = g_omap3_gptimer_sc;
-	struct omap_gptimer *timer;
+	struct omap3_gptimer_softc *sc = g_omap3_gptimer_sc;
+	struct omap3_gptimer *timer;
 	uint32_t val;
 	uint64_t tickcount;
 	unsigned int freq;
@@ -243,11 +361,11 @@
 	timer = &sc->sc_timers[n-1];
 	
 	/* Sanity check the timer is availabe and not activated */
-	if (!(timer->flags & OMAP_GPTIMER_AVAILABLE_FLAG)) {
+	if (!(timer->flags & OMAP3_GPTIMER_AVAILABLE_FLAG)) {
 		device_printf(sc->sc_dev, "Error: timer %d not available\n", n);
 		return (EINVAL);
 	}
-	if (timer->flags & OMAP_GPTIMER_ACTIVATED_FLAG) {
+	if (timer->flags & OMAP3_GPTIMER_ACTIVATED_FLAG) {
 		device_printf(sc->sc_dev, "Error: timer %d already activated\n", n);
 		return (EINVAL);
 	}
@@ -277,13 +395,13 @@
 
 	/* Reset the timer and poll on the reset complete flag */
 	if (timer->profile == OMAP_GPTIMER_PROFILE_OMAP3) {
-		omap_gptimer_writel(timer, OMAP3_GPT_TIOCP_CFG, 0x2);
+		omap3_gptimer_writel(timer, OMAP3_GPT_TIOCP_CFG, 0x2);
 		/* TODO: add a timeout */
-		while ((omap_gptimer_readl(timer, OMAP3_GPT_TISTAT) & 0x01) == 0x00)
+		while ((omap3_gptimer_readl(timer, OMAP3_GPT_TISTAT) & 0x01) == 0x00)
 			continue;
 
 		/* Clear the interrupt status */
-		omap_gptimer_writel(timer, OMAP3_GPT_TISR, TCAR | OVF | MAT);
+		omap3_gptimer_writel(timer, OMAP3_GPT_TISR, TCAR | OVF | MAT);
 	}
 
 	/* If the user supplied a zero value we set a free running timer */
@@ -321,10 +439,10 @@
 			/* Adjust the count and apply the prescaler */
 			tickcount >>= (prescaler + 1);
 
-			val = omap3_gptimer_readl(timer, timer->tclr);
+			val = omap3_gptimer_readl(timer, OMAP3_GPT_TCLR);
 			val &= ~TCLR_PTV_MASK;
 			val |= TCLR_PRE | (prescaler << 2);
-			omap3_gptimer_writel(timer, timer->tclr, val);
+			omap3_gptimer_writel(timer, OMAP3_GPT_TCLR, val);
 		}
 	
 		/* Calculate the start value */
@@ -335,7 +453,7 @@
 	}
 	
 	/* Load the start value into the count register */
-	omap3_gptimer_writel(timer, timer->tcrr, startcount);
+	omap3_gptimer_writel(timer, OMAP3_GPT_TCRR, startcount);
 	
 	
 	
@@ -344,12 +462,12 @@
 	 */
 	if (flags & OMAP3_GPTIMER_PERIODIC_FLAG) {
 		/* Enable auto reload */
-		val = omap3_gptimer_readl(timer, timer->tclr);
+		val = omap3_gptimer_readl(timer, OMAP3_GPT_TCLR);
 		val |= TCLR_AR;
-		omap3_gptimer_writel(timer, timer->tclr, val);
+		omap3_gptimer_writel(timer, OMAP3_GPT_TCLR, val);
 		
 		/* Set the reload value */
-		omap3_gptimer_writel(timer, timer->tldr, startcount);
+		omap3_gptimer_writel(timer, OMAP3_GPT_TLDR, startcount);
 	}
 
 
@@ -377,7 +495,7 @@
 
 
 	/* Finally set the activated flag */
-	timer->flags |= OMAP_GPTIMER_ACTIVATED_FLAG;
+	timer->flags |= OMAP3_GPTIMER_ACTIVATED_FLAG;
 
 	OMAP3_GPTIMER_UNLOCK(timer);
 	
@@ -386,6 +504,127 @@
 	return (0);
 }
 
+/**
+ *	omap3_gptimer_start - starts a one-shot or periodic timer
+ *	@n: the number of the timer (first timer is number 1)
+ *	
+ *
+ *	RETURNS:
+ *	Returns 0 on success, otherwise an error code
+ */
+int
+omap3_gptimer_start(unsigned int n)
+{
+	return 0;
+}
+
+/**
+ *	omap3_gptimer_stop - stops a one-shot or periodic timer
+ *	@n: the number of the timer (first timer is number 1)
+ *	
+ *
+ *	RETURNS:
+ *	Returns 0 on success, otherwise an error code
+ */
+int
+omap3_gptimer_stop(unsigned int n)
+{
+	return 0;
+}
+
+/**
+ *	omap3_gptimer_set_intr_filter - sets a filter 
+ *	@n: the number of the timer (first timer is number 1)
+ *	
+ *
+ *	RETURNS:
+ *	Returns 0 on success, otherwise an error code
+ */
+int
+omap3_gptimer_set_intr_filter(unsigned int n, driver_filter_t filter)
+{
+	struct omap3_gptimer_softc *sc = g_omap3_gptimer_sc;
+	struct omap3_gptimer *timer;
+	uint32_t val;
+
+	/* Sanity checks */
+	if (sc == NULL)
+		return (ENOMEM);
+	if ((n == 0) || (n > sc->sc_num_timers))
+		return (EINVAL);
+
+	/* Get a pointer to the individual timer struct */
+	timer = &sc->sc_timers[n-1];
+
+	OMAP3_GPTIMER_LOCK(timer);
+
+	/* If a callback is already installed this won't work */
+	if (timer->callback != NULL) {
+		OMAP3_GPTIMER_UNLOCK(timer);
+		return(EINVAL);
+	}
+	
+	/* Sanity check the timer is already activated and periodic type */
+	if ((timer->flags & (OMAP3_GPTIMER_ACTIVATED_FLAG | OMAP3_GPTIMER_PERIODIC_FLAG))
+	    != (OMAP3_GPTIMER_ACTIVATED_FLAG | OMAP3_GPTIMER_PERIODIC_FLAG)) {
+		OMAP3_GPTIMER_UNLOCK(timer);
+		return(EINVAL);
+	}
+	
+	
+	/* Attempt to activate the interrupt for the tick */
+	if (bus_setup_intr(sc->sc_dev, timer->irq_res, INTR_TYPE_CLK,
+	                   filter, NULL, NULL, &timer->irq_h)) {
+		device_printf(sc->sc_dev, "Error: failed to activate interrupt\n");
+		OMAP3_GPTIMER_UNLOCK(timer);
+		return(EINVAL);
+	}
+	
+	
+	/* Enable the overflow interrupts */
+	if (timer->profile == OMAP_GPTIMER_PROFILE_OMAP3) {
+		val = omap3_gptimer_readl(timer, OMAP3_GPT_TIER);
+		val |= OVF;
+		omap3_gptimer_writel(timer, OMAP3_GPT_TIER, val);
+	}
+	
+	OMAP3_GPTIMER_UNLOCK(timer);
+	
+	return(0);
+}
+
+/**
+ *	omap3_gptimer_intr_filter_ack - acknowledges a timer interrupt
+ *	@n: the number of the timer (first timer is number 1)
+ *
+ *	This function should only be called from filter interrupt handler installed
+ *	by calling the omap_gptimer_set_intr_filter() function.
+ *
+ *	RETURNS:
+ *	Nothing
+ */
+void
+omap3_gptimer_intr_filter_ack(unsigned int n)
+{
+	struct omap3_gptimer_softc *sc = g_omap3_gptimer_sc;
+	struct omap3_gptimer *timer;
+	uint32_t stat;
+
+	/* Get a pointer to the individual timer struct */
+	timer = &sc->sc_timers[n-1];
+
+	OMAP3_GPTIMER_LOCK(timer);
+	
+	/* Read the interrupt status flag and clear it */
+	/* Read the status and it with the enable flag */
+	stat =  omap3_gptimer_readl(timer, OMAP3_GPT_TISR);
+	stat &= omap3_gptimer_readl(timer, OMAP3_GPT_TIER);
+		
+	/* Clear the status flag */
+	omap3_gptimer_writel(timer, OMAP3_GPT_TISR, stat);
+	OMAP3_GPTIMER_UNLOCK(timer);
+}
+
 
 
 /**
@@ -416,7 +655,7 @@
 DELAY(int usec)
 {
 	int32_t counts;
-	uint32_t first, last;
+	//uint32_t first, last;
 
 	if (omap3_gptimer_tc_tmr == NULL) {
 		for (; usec > 0; usec--)
@@ -430,9 +669,75 @@
 static void
 omap3_gptimer_intr(void *arg)
 {
+	struct omap3_gptimer *timer = (struct omap3_gptimer *) arg;
+	void (*callback)(void *data);
+	void*    callback_data;
+	uint32_t stat = 0x0000;
+
+	OMAP3_GPTIMER_LOCK(timer);
+
+	/* Read the interrupt status flag and clear it */
+	if (timer->profile == OMAP_GPTIMER_PROFILE_OMAP3) {
+		
+		/* Read the status and it with the enable flag */
+		stat =  omap3_gptimer_readl(timer, OMAP3_GPT_TISR);
+		stat &= omap3_gptimer_readl(timer, OMAP3_GPT_TIER);
+		
+		/* Clear the status flag */
+		omap3_gptimer_writel(timer, OMAP3_GPT_TISR, stat);
+	}
+	
+	/* Store the callback details before releasing the lock */
+	callback = timer->callback;
+	callback_data = timer->callback_data;
+	
+	OMAP3_GPTIMER_UNLOCK(timer);
+
+	/* Check if an actual overflow interrupt */
+	if ((stat & OVF) && (callback != NULL))
+		callback(timer->callback_data);
+}
+
+/**
+ *	omap3_clk_intr - interrupt handler for the tick timer (GPTIMER10)
+ *	@arg: the trapframe, needed for the hardclock system function.
+ *
+ *	This interrupt is triggered every hz times a second.  It's role is basically
+ *	to just clear the interrupt status and set it up for triggering again, plus
+ *	tell the system a tick timer has gone off by calling the hardclock()
+ *	function from the kernel API.
+ *
+ *	RETURNS:
+ *	Always returns FILTER_HANDLED. 
+ */
+static int
+omap3_timer_tick_intr(void *arg)
+{
+	struct trapframe *frame = arg;
+#if defined(OMAP3_HEARTBEAT_GPIO)
+	static int heartbeat_cnt = 0;
+#endif
+
+	/* Acknowledge the interrupt */
+	omap3_gptimer_intr_filter_ack(TICKTIMER_GPTIMER);
+
+	/* Heartbeat */
+#if defined(OMAP3_HEARTBEAT_GPIO)
+	if (heartbeat_cnt++ >= (hz/2)) {
+		//printf("[BRG] ** tick **\n");
+		gpio_pin_toggle(OMAP3_HEARTBEAT_GPIO);
+		heartbeat_cnt = 0;
+	}
+#endif
 
+	/* Do what we came here for */
+	hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
+	
+	/* Indicate we've handed the interrupt */
+	return (FILTER_HANDLED);
 }
 
+
 static int
 omap3_gptimer_probe(device_t dev)
 {
@@ -477,7 +782,7 @@
 		                                        RF_ACTIVE | RF_SHAREABLE);
 
 		// I decided to delete support for OMAP4 timers from the original code - aleek
-		rev = omap_gptimer_readl(timer, OMAP_GPT_TIDR);
+		rev = omap3_gptimer_readl(timer, OMAP3_GPT_TIDR);
 		switch (rev) {
 			case 0x00000013:  /* OMAP3 without 1ms generation */
 			case 0x00000015:
@@ -502,14 +807,14 @@
 		timer->source = (GPTIMER1_CLK + n);
 
 		/* Finally mark the timer as available */
-		timer->flags = OMAP_GPTIMER_AVAILABLE_FLAG;
+		timer->flags = OMAP3_GPTIMER_AVAILABLE_FLAG;
 	}
 
 	/* Store the number of timers installed */
 	sc->sc_num_timers = n;
 	
 	/* Store the timer structure globally - this driver should never be unloaded */
-	g_omap_gptimer_sc = sc;
+	g_omap3_gptimer_sc = sc;
 
 	/* setup GPTIMER10 for system ticks, and GPTIMER11 for general purpose counter */
 
@@ -519,17 +824,17 @@
 	tick = 1000000 / hz;
 
 	/* Next setup one of the timers to be the system tick timer */
-	if (omap3_gptimer_activate(TICKTIMER_GPTIMER, OMAP_GPTIMER_PERIODIC_FLAG,
+	if (omap3_gptimer_activate(TICKTIMER_GPTIMER, OMAP3_GPTIMER_PERIODIC_FLAG,
 	                          tick, NULL, NULL)) {
 		panic("Error: failed to activate system tick timer\n");
 	}
 	
 	/* Setup an interrupt filter for the timer */
-	if (omap_gptimer_set_intr_filter(TICKTIMER_GPTIMER, omap3_timer_tick_intr))
+	if (omap3_gptimer_set_intr_filter(TICKTIMER_GPTIMER, omap3_timer_tick_intr))
 		panic("Error: failed to start system tick timer\n");
 	
 	/* Lastly start the tick timer */
-	if (omap_gptimer_start(TICKTIMER_GPTIMER))
+	if (omap3_gptimer_start(TICKTIMER_GPTIMER))
 		panic("Error: failed to start system tick timer\n");
 
 	omap3_gptimer_get_freq(TICKTIMER_GPTIMER, &timer_freq);
@@ -538,42 +843,41 @@
 
 
 	/* Setup another timer to be the timecounter */
-	if (omap3_gptimer_activate(TIMECOUNT_GPTIMER, OMAP_GPTIMER_PERIODIC_FLAG, 0,
+	if (omap3_gptimer_activate(TIMECOUNT_GPTIMER, OMAP3_GPTIMER_PERIODIC_FLAG, 0,
 	                        NULL, NULL)) {
 		printf("Error: failed to activate system tick timer\n");
-	} else if (omap_gptimer_start(TIMECOUNT_GPTIMER)) {
+	} else if (omap3_gptimer_start(TIMECOUNT_GPTIMER)) {
 		printf("Error: failed to start system tick timer\n");
 	}
 
 	/* Save the system clock speed */
 	omap3_gptimer_get_freq(TIMECOUNT_GPTIMER, &timer_freq);
-	g_omap3_timecounter.tc_frequency = timer_freq;
+	omap3_gptimer_tc.tc_frequency = timer_freq;
 	
 	/* Setup the time counter */
-	tc_init(&g_omap3_timecounter);
+	tc_init(&omap3_gptimer_tc);
 
 	/* Calibrate the delay loop */
-	omap3_calibrate_delay_loop(&g_omap3_timecounter);
+	omap3_calibrate_delay_loop(&omap3_gptimer_tc);
 
 	/* Restore interrupt state */
 	restore_interrupts(oldirqstate);
 
 }
 
-static device_method_t g_omap_gptimer_methods[] = {
-	DEVMETHOD(device_probe, omap_gptimer_probe),
-	DEVMETHOD(device_attach, omap_gptimer_attach),
+static device_method_t g_omap3_gptimer_methods[] = {
+	DEVMETHOD(device_probe, omap3_gptimer_probe),
+	DEVMETHOD(device_attach, omap3_gptimer_attach),
 	{0, 0},
 };
 
-static driver_t g_omap_gptimer_driver = {
-	"omap_gptimer",
-	g_omap_gptimer_methods,
-	sizeof(struct omap_gptimer_softc),
+static driver_t g_omap3_gptimer_driver = {
+	"omap3_gptimer",
+	g_omap3_gptimer_methods,
+	sizeof(struct omap3_gptimer_softc),
 };
-static devclass_t g_omap_gptimer_devclass;
+static devclass_t g_omap3_gptimer_devclass;
 
-DRIVER_MODULE(omap_gptimer, omap, g_omap_gptimer_driver, g_omap_gptimer_devclass, 0, 0);
-MODULE_DEPEND(omap_gptimer, ti_prcm, 1, 1, 1);
+DRIVER_MODULE(omap3_gptimer, omap, g_omap3_gptimer_driver, g_omap3_gptimer_devclass, 0, 0);
+MODULE_DEPEND(omap3_gptimer, ti_prcm, 1, 1, 1);
 
-}

Modified: soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_gptimer.h
==============================================================================
--- soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_gptimer.h	Wed Jun 13 14:20:15 2012	(r237609)
+++ soc2012/aleek/beaglexm-armv6/sys/arm/ti/am37x/am37x_gptimer.h	Wed Jun 13 14:38:54 2012	(r237610)
@@ -12,23 +12,23 @@
 #define OMAP3_GPT_TIDR			0x0000
 #define OMAP3_GPT_TIOCP_CFG		0x0010
 #define OMAP3_GPT_TISTAT		0x0014
-#define OMAP3_GPT_TISR           0x0018
-#define OMAP3_GPT_TIER           0x001C
-#define OMAP3_GPT_TWER           0x0020
-#define OMAP3_GPT_TCLR           0x0024
-#define OMAP3_GPT_TCRR           0x0028
-#define OMAP3_GPT_TLDR           0x002C
-#define OMAP3_GPT_TTGR           0x0030
-#define OMAP3_GPT_TWPS           0x0034
-#define OMAP3_GPT_TMAR           0x0038
-#define OMAP3_GPT_TCAR1          0x003C
-#define OMAP3_GPT_TSICR          0x0040
-#define OMAP3_GPT_TCAR2          0x0044
-#define OMAP3_GPT_TPIR           0x0048
-#define OMAP3_GPT_TNIR           0x004C
-#define OMAP3_GPT_TCVR           0x0050
-#define OMAP3_GPT_TOCR           0x0054
-#define OMAP3_GPT_TOWR           0x0058
+#define OMAP3_GPT_TISR			0x0018
+#define OMAP3_GPT_TIER			0x001C
+#define OMAP3_GPT_TWER			0x0020
+#define OMAP3_GPT_TCLR			0x0024
+#define OMAP3_GPT_TCRR			0x0028
+#define OMAP3_GPT_TLDR			0x002C
+#define OMAP3_GPT_TTGR			0x0030
+#define OMAP3_GPT_TWPS			0x0034
+#define OMAP3_GPT_TMAR			0x0038
+#define OMAP3_GPT_TCAR1			0x003C
+#define OMAP3_GPT_TSICR			0x0040
+#define OMAP3_GPT_TCAR2			0x0044
+#define OMAP3_GPT_TPIR			0x0048
+#define OMAP3_GPT_TNIR			0x004C
+#define OMAP3_GPT_TCVR			0x0050
+#define OMAP3_GPT_TOCR			0x0054
+#define OMAP3_GPT_TOWR			0x0058
 
 /* GPT_TCLR Register bit fields */
 #define TCLR_GPO_CFG            (0x1 << 14)
@@ -43,14 +43,30 @@
 #define TCLR_AR                 (0x1 << 1)
 #define TCLR_ST                 (0x1 << 0)
 
+/* The interrupt/status bits used in the timer registers. */
+#define TCAR                    (0x1 << 2)
+#define OVF                     (0x1 << 1)
+#define MAT                     (0x1 << 0)
+
 /*
  * The following flags define the clocking source, if specified the timer will
  * be clocked from the 32Khz source, otherwise it clocked from the sysclk.
  */
-#define OMAP_GPTIMER_32KCLK_FLAG      0x00000100
+#define OMAP3_GPTIMER_32KCLK_FLAG		0x00000100
 
+/* Indicates if the timer should be periodic, if not specified the timer is
+ * one-shot and you have to call omap_timer_start() to restart the timer.
+ */
+#define OMAP3_GPTIMER_PERIODIC_FLAG		0x00000001
 
-/**
+#define OMAP_GPTIMER_PROFILE_UNKNOWN	-1
+#define OMAP_GPTIMER_PROFILE_OMAP3		3
+
+// XXX @todo fix it, move somewhere
+#define OMAP3_HEARTBEAT_GPIO	150
+
+
+/*
  *	Macros for driver mutex locking
  */
 #define OMAP3_GPTIMER_LOCK(_tmr)            mtx_lock(&(_tmr)->mtx)
@@ -58,7 +74,7 @@
 #define OMAP3_GPTIMER_ASSERT_LOCKED(_tmr)   mtx_assert(&(_tmr)->mtx, MA_OWNED);
 #define OMAP3_GPTIMER_ASSERT_UNLOCKED(_tmr) mtx_assert(&(_tmr)->mtx, MA_NOTOWNED);
 
-/**
+/*
  *	Data structure per Timer. 
  */
 struct omap3_gptimer {
@@ -66,8 +82,8 @@
 	/* Flags indicating current and configured status */
 	unsigned int        flags;
 
-#define OMAP_GPTIMER_AVAILABLE_FLAG      0x01000000
-#define OMAP_GPTIMER_ACTIVATED_FLAG      0x02000000
+#define OMAP3_GPTIMER_AVAILABLE_FLAG      0x01000000
+#define OMAP3_GPTIMER_ACTIVATED_FLAG      0x02000000
 	
     /* Lock taken when configuring the registers */
 	struct mtx          mtx;
@@ -95,7 +111,7 @@
 
 /**
  *	Timer driver context, allocated and stored globally, this driver is not
- *	intended to ever be unloaded (see g_omap_gptimer_sc).
+ *	intended to ever be unloaded (see g_omap3_gptimer_sc).
  *
  */
 struct omap3_gptimer_softc {
@@ -106,6 +122,8 @@
 	
 };
 
+void
+omap3_gptimer_intr_filter_ack(unsigned int n);
 
 static unsigned
 omap3_gptimer_tc_get_timecount(struct timecounter *tc);
@@ -118,17 +136,33 @@
 omap3_gptimer_writel(struct omap3_gptimer *timer, bus_size_t off, uint32_t val);
 
 int
-omap_gptimer_activate(unsigned int n, unsigned int flags, unsigned int time_us,
+omap3_gptimer_activate(unsigned int n, unsigned int flags, unsigned int time_us,
                     void (*callback)(void *data), void *data);
 
+int
+omap3_gptimer_start(unsigned int n);
+
+int
+omap3_gptimer_stop(unsigned int n);
+
+int
+omap3_gptimer_get_freq(unsigned int n, uint32_t *freq);
+
+static int
+omap3_calibrate_delay_loop(struct timecounter *tc);
+
+int
+omap3_gptimer_set_intr_filter(unsigned int n, driver_filter_t filter);
+
 static void
 omap3_gptimer_intr(void *arg);
 
+static int
+omap3_timer_tick_intr(void *arg);
 
 static int
 omap3_gptimer_probe(device_t dev);
 
-
 static int
 omap3_gptimer_attach(device_t dev);
 

Modified: soc2012/aleek/beaglexm-armv6/sys/boot/fdt/dts/beagleboardxm.dts
==============================================================================
--- soc2012/aleek/beaglexm-armv6/sys/boot/fdt/dts/beagleboardxm.dts	Wed Jun 13 14:20:15 2012	(r237609)
+++ soc2012/aleek/beaglexm-armv6/sys/boot/fdt/dts/beagleboardxm.dts	Wed Jun 13 14:38:54 2012	(r237610)
@@ -59,6 +59,20 @@
 			reg =	< 0x48200000 0x1000 >;
 		};
 
+		GPIO: gpio {
+			#gpio-cells = <3>;
+			compatible = "ti,gpio";
+			gpio-controller;
+			reg =<	0x48310000 0x1000
+				0x49050000 0x1000
+				0x49052000 0x1000
+				0x49054000 0x1000
+				0x49056000 0x1000
+				0x49058000 0x1000  >;
+			interrupts = < 29 30 31 32 33 34 >;
+			interrupt-parent = <&AINTC>;
+		};
+
 		dmtimers at 44E05000 {
 			compatible = "ti,am37x-dmtimer";
 			#address-cells = <1>;


More information about the svn-soc-all mailing list