diff options
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.c | 406 |
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 |