summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/beatnik/marvell/gt_timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/powerpc/beatnik/marvell/gt_timer.c')
-rw-r--r--c/src/lib/libbsp/powerpc/beatnik/marvell/gt_timer.c406
1 files changed, 203 insertions, 203 deletions
diff --git a/c/src/lib/libbsp/powerpc/beatnik/marvell/gt_timer.c b/c/src/lib/libbsp/powerpc/beatnik/marvell/gt_timer.c
index d70c6a9653..e53e8e10a1 100644
--- a/c/src/lib/libbsp/powerpc/beatnik/marvell/gt_timer.c
+++ b/c/src/lib/libbsp/powerpc/beatnik/marvell/gt_timer.c
@@ -14,13 +14,13 @@
* ----------
* This software ('beatnik' RTEMS BSP for MVME6100 and MVME5500) was
* created by Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
- * Stanford Linear Accelerator Center, Stanford University.
+ * Stanford Linear Accelerator Center, Stanford University.
*
* Acknowledgement of sponsorship
* ------------------------------
* The 'beatnik' BSP was produced by
* the Stanford Linear Accelerator Center, Stanford University,
- * under Contract DE-AC03-76SFO0515 with the Department of Energy.
+ * under Contract DE-AC03-76SFO0515 with the Department of Energy.
*
* Government disclaimer of liability
* ----------------------------------
@@ -53,6 +53,7 @@
*
* ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
*/
+
#include <rtems.h>
#include <bsp/gtreg.h>
#include <libcpu/io.h>
@@ -68,199 +69,196 @@
static inline uint32_t gt_rd(uint32_t off)
{
- return in_le32( (volatile unsigned *)(BSP_MV64x60_BASE+off) );
+ return in_le32( (volatile unsigned *)(BSP_MV64x60_BASE+off) );
}
static inline void gt_wr(uint32_t off, uint32_t val)
{
- out_le32( (volatile unsigned *)(BSP_MV64x60_BASE+off), val);
+ out_le32( (volatile unsigned *)(BSP_MV64x60_BASE+off), val);
}
static inline uint32_t gt_timer_bitmod(uint32_t off, uint32_t clr, uint32_t set)
{
- unsigned flags;
- uint32_t rval;
- rtems_interrupt_disable(flags);
- rval = gt_rd( off );
- gt_wr( off, (rval & ~clr) | set );
- rtems_interrupt_enable(flags);
- return rval;
+ unsigned flags;
+ uint32_t rval;
+
+ rtems_interrupt_disable(flags);
+ rval = gt_rd( off );
+ gt_wr( off, (rval & ~clr) | set );
+ rtems_interrupt_enable(flags);
+ return rval;
}
-#define GT_TIMER_MAX 3
-#define TIMER_ARGCHECK(t) do { if ((t)<0 || (t)>GT_TIMER_MAX) return -1; } while (0)
+#define GT_TIMER_MAX 3
+#define TIMER_ARGCHECK(t) do { if ((t)<0 || (t)>GT_TIMER_MAX) return -1; } while (0)
static struct {
- void (*isr)(void *);
- void *arg;
+ void (*isr)(void *);
+ void *arg;
} gt_timer_isrs[GT_TIMER_MAX+1] = {{0},};
uint32_t BSP_timer_read(uint32_t timer)
{
- TIMER_ARGCHECK(timer);
- return gt_rd(GT_TIMER_0 + (timer<<2));
+ TIMER_ARGCHECK(timer);
+ return gt_rd(GT_TIMER_0 + (timer<<2));
}
int
BSP_timer_start(uint32_t timer, uint32_t period)
{
- TIMER_ARGCHECK(timer);
- gt_wr(GT_TIMER_0 + (timer<<2), period);
- return 0;
+ TIMER_ARGCHECK(timer);
+ gt_wr(GT_TIMER_0 + (timer<<2), period);
+ return 0;
}
int
BSP_timer_stop(uint32_t timer)
{
- TIMER_ARGCHECK(timer);
- /* disable, clear period, re-enable */
- gt_timer_bitmod(GT_TIMER_0_3_Ctl, GT_TIMER_0_Ctl_Enb << (timer<<3), 0);
- gt_wr(GT_TIMER_0 + (timer<<2), 0);
- gt_timer_bitmod(GT_TIMER_0_3_Ctl, 0, GT_TIMER_0_Ctl_Enb << (timer<<3));
- return 0;
+ TIMER_ARGCHECK(timer);
+ /* disable, clear period, re-enable */
+ gt_timer_bitmod(GT_TIMER_0_3_Ctl, GT_TIMER_0_Ctl_Enb << (timer<<3), 0);
+ gt_wr(GT_TIMER_0 + (timer<<2), 0);
+ gt_timer_bitmod(GT_TIMER_0_3_Ctl, 0, GT_TIMER_0_Ctl_Enb << (timer<<3));
+ return 0;
}
int
BSP_timer_setup(uint32_t timer, void (*isr)(void *arg), void *arg, int reload)
{
- TIMER_ARGCHECK(timer);
- if ( isr && gt_timer_isrs[timer].isr )
- return -1;
- BSP_timer_stop(timer);
- /* mask and clear */
- gt_timer_bitmod(GT_TIMER_0_3_Intr_Msk, GT_TIMER_0_Intr<<timer, 0);
- gt_timer_bitmod(GT_TIMER_0_3_Intr_Cse, GT_TIMER_0_Intr<<timer, 0);
-
- /* set reload bit */
- if ( reload )
- gt_timer_bitmod(GT_TIMER_0_3_Ctl, 0, GT_TIMER_0_Ctl_Rld << (timer<<3));
- else
- gt_timer_bitmod(GT_TIMER_0_3_Ctl, GT_TIMER_0_Ctl_Rld << (timer<<3), 0);
-
- asm volatile("":::"memory");
-
- if ( isr ) {
- gt_timer_isrs[timer].isr = isr;
- gt_timer_isrs[timer].arg = arg;
- asm volatile("":::"memory");
- gt_timer_bitmod(GT_TIMER_0_3_Intr_Msk, 0, GT_TIMER_0_Intr<<timer);
- } else {
- gt_timer_isrs[timer].isr = 0;
- gt_timer_isrs[timer].arg = 0;
- }
- return 0;
+ TIMER_ARGCHECK(timer);
+ if ( isr && gt_timer_isrs[timer].isr )
+ return -1;
+
+ BSP_timer_stop(timer);
+ /* mask and clear */
+ gt_timer_bitmod(GT_TIMER_0_3_Intr_Msk, GT_TIMER_0_Intr<<timer, 0);
+ gt_timer_bitmod(GT_TIMER_0_3_Intr_Cse, GT_TIMER_0_Intr<<timer, 0);
+
+ /* set reload bit */
+ if ( reload )
+ gt_timer_bitmod(GT_TIMER_0_3_Ctl, 0, GT_TIMER_0_Ctl_Rld << (timer<<3));
+ else
+ gt_timer_bitmod(GT_TIMER_0_3_Ctl, GT_TIMER_0_Ctl_Rld << (timer<<3), 0);
+
+ asm volatile("":::"memory");
+
+ if ( isr ) {
+ gt_timer_isrs[timer].isr = isr;
+ gt_timer_isrs[timer].arg = arg;
+ asm volatile("":::"memory");
+ gt_timer_bitmod(GT_TIMER_0_3_Intr_Msk, 0, GT_TIMER_0_Intr<<timer);
+ } else {
+ gt_timer_isrs[timer].isr = 0;
+ gt_timer_isrs[timer].arg = 0;
+ }
+ return 0;
}
static void
gt_timer_hdl(rtems_irq_hdl_param arg)
{
-int iarg = (int)arg;
-int timer;
-uint32_t bit;
-
- for ( ; iarg; iarg >>= 4 ) {
- timer = (iarg & 0xf)-1;
- bit = GT_TIMER_0_Intr<<timer;
- if ( gt_timer_bitmod(GT_TIMER_0_3_Intr_Cse, bit, 0) & bit ) {
- /* cause was set */
- if ( ! gt_timer_isrs[timer].isr ) {
- printk("gt_timer: warning; no ISR connected but and IRQ happened (timer # %i)\n", timer);
- /* mask */
- gt_timer_bitmod(GT_TIMER_0_3_Intr_Msk, bit, 0);
- } else {
- gt_timer_isrs[timer].isr(gt_timer_isrs[timer].arg);
- }
- }
- }
+ int iarg = (int)arg;
+ int timer;
+ uint32_t bit;
+
+ for ( ; iarg; iarg >>= 4 ) {
+ timer = (iarg & 0xf)-1;
+ bit = GT_TIMER_0_Intr<<timer;
+ if ( gt_timer_bitmod(GT_TIMER_0_3_Intr_Cse, bit, 0) & bit ) {
+ /* cause was set */
+ if ( ! gt_timer_isrs[timer].isr ) {
+ printk("gt_timer: warning; no ISR connected but and IRQ happened (timer # %i)\n", timer);
+ /* mask */
+ gt_timer_bitmod(GT_TIMER_0_3_Intr_Msk, bit, 0);
+ } else {
+ gt_timer_isrs[timer].isr(gt_timer_isrs[timer].arg);
+ }
+ }
+ }
}
int
BSP_timers_initialize(void)
{
-rtems_irq_connect_data xx = {0};
-int i, ainc, arg;
-
- xx.hdl = gt_timer_hdl;
- xx.on = 0;
- xx.off = 0;
- xx.isOn = 0;
-
- switch (BSP_getDiscoveryVersion(0)) {
- case MV_64360:
- i = 3;
- ainc = 1;
- arg = 4;
- break;
- default:
- i = 1;
- ainc = 0x0202;
- arg = 0x0403;
- break;
- }
-
- for ( ; i>=0; i--, arg-=ainc ) {
- xx.name = BSP_IRQ_TIME0_1 + i;
- xx.handle = (rtems_irq_hdl_param)arg;
- if ( !BSP_install_rtems_irq_handler(&xx) )
- return -1;
- }
-
- return 0;
+ rtems_irq_connect_data xx = {0};
+ int i, ainc, arg;
+
+ xx.hdl = gt_timer_hdl;
+ xx.on = 0;
+ xx.off = 0;
+ xx.isOn = 0;
+
+ switch (BSP_getDiscoveryVersion(0)) {
+ case MV_64360:
+ i = 3;
+ ainc = 1;
+ arg = 4;
+ break;
+ default:
+ i = 1;
+ ainc = 0x0202;
+ arg = 0x0403;
+ break;
+ }
+
+ for ( ; i>=0; i--, arg-=ainc ) {
+ xx.name = BSP_IRQ_TIME0_1 + i;
+ xx.handle = (rtems_irq_hdl_param)arg;
+ if ( !BSP_install_rtems_irq_handler(&xx) )
+ return -1;
+ }
+
+ return 0;
}
-int
+#ifdef DEBUG_MODULAR
+static int
BSP_timers_uninstall(void)
{
-rtems_irq_connect_data xx = {0};
-int i;
-
- xx.hdl = gt_timer_hdl;
- xx.on = 0;
- xx.off = 0;
- xx.isOn = 0;
-
- for ( i=0; i<= GT_TIMER_MAX; i++ ) {
- if ( BSP_timer_setup(i, 0, 0, 0) )
- return -1;
- }
-
- switch (BSP_getDiscoveryVersion(0)) {
- case MV_64360:
- i = 3;
- break;
- default:
- i = 1;
- break;
- }
-
- for ( ; i >= 0; i-- ) {
- xx.name = BSP_IRQ_TIME0_1 + i;
- BSP_get_current_rtems_irq_handler(&xx);
- if ( !BSP_remove_rtems_irq_handler(&xx) )
- return -1;
- }
-
- return 0;
+ rtems_irq_connect_data xx = {0};
+ int i;
+
+ xx.hdl = gt_timer_hdl;
+ xx.on = 0;
+ xx.off = 0;
+ xx.isOn = 0;
+
+ for ( i=0; i<= GT_TIMER_MAX; i++ ) {
+ if ( BSP_timer_setup(i, 0, 0, 0) )
+ return -1;
+ }
+
+ switch (BSP_getDiscoveryVersion(0)) {
+ case MV_64360:
+ i = 3;
+ break;
+ default:
+ i = 1;
+ break;
+ }
+
+ for ( ; i >= 0; i-- ) {
+ xx.name = BSP_IRQ_TIME0_1 + i;
+ BSP_get_current_rtems_irq_handler(&xx);
+ if ( !BSP_remove_rtems_irq_handler(&xx) )
+ return -1;
+ }
+
+ return 0;
}
+#endif
uint32_t
BSP_timer_clock_get(uint32_t timer)
{
- return BSP_bus_frequency;
+ return BSP_bus_frequency;
}
int BSP_timer_instances(void)
{
- return GT_TIMER_MAX + 1;
+ return GT_TIMER_MAX + 1;
}
-#ifdef DEBUG
-void BSP_timer_test_isr(void *arg)
-{
- printk("TIMER IRQ (user arg 0x%x)\n",arg);
-}
-#endif
-
/* On a 64260A we can't read the status (on/off), apparently
* so we maintain it locally and assume the firmware has
* not enabled the dog initially...
@@ -269,32 +267,33 @@ static uint32_t wdog_on = 0x00ffffff;
static uint32_t rd_wdcnf(void)
{
- uint32_t cnf = gt_rd(GT_WDOG_Config);
- /* BSD driver says that on the 64260A we always
- * read 0xffffffff so we have to maintain the
- * status locally (and hope we get the initial
- * value right).
- */
- if ( ~0 == cnf )
- cnf = wdog_on;
- return cnf;
+ uint32_t cnf = gt_rd(GT_WDOG_Config);
+
+ /* BSD driver says that on the 64260A we always
+ * read 0xffffffff so we have to maintain the
+ * status locally (and hope we get the initial
+ * value right).
+ */
+ if ( ~0 == cnf )
+ cnf = wdog_on;
+ return cnf;
}
/* change on/off state assume caller has IRQs disabled */
static void dog_toggle(uint32_t ctl)
{
- ctl &= ~( GT_WDOG_Config_Ctl1a | GT_WDOG_Config_Ctl1b \
- | GT_WDOG_Config_Ctl2a | GT_WDOG_Config_Ctl2b);
- gt_wr(GT_WDOG_Config, ctl | GT_WDOG_Config_Ctl1a);
- gt_wr(GT_WDOG_Config, ctl | GT_WDOG_Config_Ctl1b);
+ ctl &= ~( GT_WDOG_Config_Ctl1a | GT_WDOG_Config_Ctl1b \
+ | GT_WDOG_Config_Ctl2a | GT_WDOG_Config_Ctl2b);
+ gt_wr(GT_WDOG_Config, ctl | GT_WDOG_Config_Ctl1a);
+ gt_wr(GT_WDOG_Config, ctl | GT_WDOG_Config_Ctl1b);
}
static void dog_pet(uint32_t ctl)
{
- ctl &= ~( GT_WDOG_Config_Ctl1a | GT_WDOG_Config_Ctl1b \
- | GT_WDOG_Config_Ctl2a | GT_WDOG_Config_Ctl2b);
- gt_wr(GT_WDOG_Config, ctl | GT_WDOG_Config_Ctl2a);
- gt_wr(GT_WDOG_Config, ctl | GT_WDOG_Config_Ctl2b);
+ ctl &= ~( GT_WDOG_Config_Ctl1a | GT_WDOG_Config_Ctl1b \
+ | GT_WDOG_Config_Ctl2a | GT_WDOG_Config_Ctl2b);
+ gt_wr(GT_WDOG_Config, ctl | GT_WDOG_Config_Ctl2a);
+ gt_wr(GT_WDOG_Config, ctl | GT_WDOG_Config_Ctl2b);
}
@@ -307,41 +306,41 @@ static void dog_pet(uint32_t ctl)
int
BSP_watchdog_enable(uint32_t timeout_us)
{
-unsigned long long x = timeout_us;
-unsigned flags;
-uint32_t ctl;
+ unsigned long long x = timeout_us;
+ unsigned flags;
+ uint32_t ctl;
- x *= BSP_bus_frequency;
- x /= 256; /* there seems to be a prescaler */
+ x *= BSP_bus_frequency;
+ x /= 256; /* there seems to be a prescaler */
x /= 1000000; /* us/s */
- if ( x > (1<<24)-1 )
- x = (1<<24)-1;
+ if ( x > (1<<24)-1 )
+ x = (1<<24)-1;
- if ( 0xffffffff != timeout_us )
- timeout_us = x;
+ if ( 0xffffffff != timeout_us )
+ timeout_us = x;
- rtems_interrupt_disable(flags);
+ rtems_interrupt_disable(flags);
- ctl = rd_wdcnf();
+ ctl = rd_wdcnf();
- /* if enabled, disable first */
- if ( GT_WDOG_Config_Enb & ctl ) {
- dog_toggle(ctl);
- }
- if ( 0xffffffff == timeout_us ) {
- timeout_us = ctl & ((1<<24)-1);
- dog_toggle(ctl);
- dog_pet(ctl);
- } else {
- gt_wr(GT_WDOG_Config, timeout_us | GT_WDOG_Config_Ctl1a);
- gt_wr(GT_WDOG_Config, timeout_us | GT_WDOG_Config_Ctl1b);
- }
+ /* if enabled, disable first */
+ if ( GT_WDOG_Config_Enb & ctl ) {
+ dog_toggle(ctl);
+ }
+ if ( 0xffffffff == timeout_us ) {
+ timeout_us = ctl & ((1<<24)-1);
+ dog_toggle(ctl);
+ dog_pet(ctl);
+ } else {
+ gt_wr(GT_WDOG_Config, timeout_us | GT_WDOG_Config_Ctl1a);
+ gt_wr(GT_WDOG_Config, timeout_us | GT_WDOG_Config_Ctl1b);
+ }
- wdog_on = GT_WDOG_Config_Enb | timeout_us;
+ wdog_on = GT_WDOG_Config_Enb | timeout_us;
- rtems_interrupt_enable(flags);
- return 0;
+ rtems_interrupt_enable(flags);
+ return 0;
}
/* Disable watchdog
@@ -352,17 +351,17 @@ int BSP_watchdog_disable(void)
unsigned long flags;
uint32_t ctl;
- rtems_interrupt_disable(flags);
+ rtems_interrupt_disable(flags);
- ctl = rd_wdcnf();
+ ctl = rd_wdcnf();
- if ( (GT_WDOG_Config_Enb & ctl) ) {
- dog_toggle(ctl);
- wdog_on = ctl & ~(GT_WDOG_Config_Enb);
- }
+ if ( (GT_WDOG_Config_Enb & ctl) ) {
+ dog_toggle(ctl);
+ wdog_on = ctl & ~(GT_WDOG_Config_Enb);
+ }
- rtems_interrupt_enable(flags);
- return 0;
+ rtems_interrupt_enable(flags);
+ return 0;
}
/* Check status -- unfortunately there seems to be no way
@@ -372,10 +371,10 @@ uint32_t ctl;
*/
int BSP_watchdog_status(void)
{
-uint32_t ctl = rd_wdcnf();
+ uint32_t ctl = rd_wdcnf();
- /* report also the current period */
- return GT_WDOG_Config_Enb & ctl ? ctl : 0;
+ /* report also the current period */
+ return GT_WDOG_Config_Enb & ctl ? ctl : 0;
}
/* Pet the watchdog (rearm to configured timeout)
@@ -384,13 +383,14 @@ uint32_t ctl = rd_wdcnf();
*/
int BSP_watchdog_pet(void)
{
-unsigned long flags;
- if ( !wdog_on )
- return -1;
- rtems_interrupt_disable(flags);
- dog_pet(rd_wdcnf());
- rtems_interrupt_enable(flags);
- return 0;
+ unsigned long flags;
+
+ if ( !wdog_on )
+ return -1;
+ rtems_interrupt_disable(flags);
+ dog_pet(rd_wdcnf());
+ rtems_interrupt_enable(flags);
+ return 0;
}
@@ -398,13 +398,13 @@ unsigned long flags;
int
_cexpModuleFinalize(void *unused)
{
- BSP_watchdog_disable();
- return BSP_timers_uninstall();
+ BSP_watchdog_disable();
+ return BSP_timers_uninstall();
}
void
_cexpModuleInitialize(void *unused)
{
- BSP_timers_initialize();
+ BSP_timers_initialize();
}
#endif