diff options
author | Alexander Krutwig <alexander.krutwig@embedded-brains.de> | 2015-04-01 15:33:25 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-05-20 08:40:34 +0200 |
commit | 75acd9e69f906cbd880a17ee4ca705ad7caa92c0 (patch) | |
tree | 71529028154cb323286b02392def2e5277eed312 /c/src/lib/libcpu | |
parent | timecounter: Use in RTEMS (diff) | |
download | rtems-75acd9e69f906cbd880a17ee4ca705ad7caa92c0.tar.bz2 |
bsps: Convert clock drivers to use a timecounter
Update #2271.
Diffstat (limited to 'c/src/lib/libcpu')
-rw-r--r-- | c/src/lib/libcpu/arm/at91rm9200/clock/clock.c | 23 | ||||
-rw-r--r-- | c/src/lib/libcpu/arm/lpc22xx/clock/clockdrv.c | 53 | ||||
-rw-r--r-- | c/src/lib/libcpu/arm/mc9328mxl/clock/clockdrv.c | 3 | ||||
-rw-r--r-- | c/src/lib/libcpu/arm/pxa255/clock/clock.c | 2 | ||||
-rw-r--r-- | c/src/lib/libcpu/arm/s3c24xx/clock/clockdrv.c | 14 | ||||
-rw-r--r-- | c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c | 107 |
6 files changed, 80 insertions, 122 deletions
diff --git a/c/src/lib/libcpu/arm/at91rm9200/clock/clock.c b/c/src/lib/libcpu/arm/at91rm9200/clock/clock.c index 16cf145b37..42b85f3f98 100644 --- a/c/src/lib/libcpu/arm/at91rm9200/clock/clock.c +++ b/c/src/lib/libcpu/arm/at91rm9200/clock/clock.c @@ -22,8 +22,6 @@ #include <at91rm9200.h> #include <at91rm9200_pmc.h> -static unsigned long st_pimr_reload; - /** * Enables clock interrupt. * @@ -77,17 +75,16 @@ rtems_irq_connect_data clock_isr_data = { BSP_install_rtems_irq_handler(&clock_isr_data); \ } while(0) -uint16_t st_pimr_value; static void Clock_driver_support_initialize_hardware(void) { uint32_t st_str; int slck; + unsigned long value; /* the system timer is driven from SLCK */ slck = at91rm9200_get_slck(); - st_pimr_value = (((rtems_configuration_get_microseconds_per_tick() * slck) + + value = (((rtems_configuration_get_microseconds_per_tick() * slck) + (1000000/2))/ 1000000); - st_pimr_reload = st_pimr_value; /* read the status to clear the int */ st_str = ST_REG(ST_SR); @@ -97,21 +94,9 @@ static void Clock_driver_support_initialize_hardware(void) AIC_SMR_REG(AIC_SMR_SYSIRQ) = AIC_SMR_PRIOR(0x7); /* set the timer value */ - ST_REG(ST_PIMR) = st_pimr_reload; + ST_REG(ST_PIMR) = value; } -static uint32_t bsp_clock_nanoseconds_since_last_tick(void) -{ - uint16_t slck_counts; - - slck_counts = st_pimr_value - st_pimr_reload; - return (rtems_configuration_get_microseconds_per_tick() * slck_counts * 1000) - / st_pimr_value; -} - -#define Clock_driver_nanoseconds_since_last_tick \ - bsp_clock_nanoseconds_since_last_tick - #define Clock_driver_support_at_tick() \ do { \ uint32_t st_str; \ @@ -126,4 +111,6 @@ static void Clock_driver_support_shutdown_hardware( void ) BSP_remove_rtems_irq_handler(&clock_isr_data); } +#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER + #include "../../../../libbsp/shared/clockdrv_shell.h" diff --git a/c/src/lib/libcpu/arm/lpc22xx/clock/clockdrv.c b/c/src/lib/libcpu/arm/lpc22xx/clock/clockdrv.c index 02f5b8c5ea..e75fed8a9e 100644 --- a/c/src/lib/libcpu/arm/lpc22xx/clock/clockdrv.c +++ b/c/src/lib/libcpu/arm/lpc22xx/clock/clockdrv.c @@ -17,12 +17,39 @@ #include <bsp/irq.h> #include <lpc22xx.h> #include <rtems/bspIo.h> /* for printk */ +#include <rtems/timecounter.h> void Clock_isr(rtems_irq_hdl_param arg); static void clock_isr_on(const rtems_irq_connect_data *unused); static void clock_isr_off(const rtems_irq_connect_data *unused); static int clock_isr_is_on(const rtems_irq_connect_data *irq); +static rtems_timecounter_simple lpc22xx_tc; + +static uint32_t lpc22xx_tc_get(rtems_timecounter_simple *tc) +{ + return T0TC; +} + +static bool lpc22xx_tc_is_pending(rtems_timecounter_simple *tc) +{ + return (T0IR & 0x1) != 0; +} + +static uint32_t lpc22xx_tc_get_timecount(struct timecounter *tc) +{ + return rtems_timecounter_simple_upcounter_get( + tc, + lpc22xx_tc_get, + lpc22xx_tc_is_pending + ); +} + +static void lpc22xx_tc_tick(void) +{ + rtems_timecounter_simple_upcounter_tick(&lpc22xx_tc, lpc22xx_tc_get); +} + /* Replace the first value with the clock's interrupt name. */ rtems_irq_connect_data clock_isr_data = { .name = LPC22xx_INTERRUPT_TIMER0, @@ -74,9 +101,10 @@ rtems_irq_connect_data clock_isr_data = { */ #define Clock_driver_support_initialize_hardware() \ do { \ + uint32_t mask; \ /* disable and clear timer 0, set to */ \ T0TCR &= 0; \ - /* TC is incrementet on every pclk.*/ \ + /* TC is incremented on every pclk.*/ \ T0PC = 0; \ /* initialize the timer period and prescaler */ \ T0MR0 = ((LPC22xx_Fpclk/1000 * \ @@ -89,6 +117,13 @@ rtems_irq_connect_data clock_isr_data = { T0TCR = 1; \ /* enable interrupt, skyeye will check this*/ \ T0IR |= 0x01; \ + /* install timecounter */ \ + rtems_timecounter_simple_install( \ + &lpc22xx_tc, \ + LPC22xx_Fpclk, \ + T0MR0, \ + lpc22xx_tc_get_timecount \ + ); \ } while (0) /** @@ -104,20 +139,6 @@ rtems_irq_connect_data clock_isr_data = { BSP_remove_rtems_irq_handler(&clock_isr_data); \ } while (0) -static uint32_t bsp_clock_nanoseconds_since_last_tick(void) -{ - uint32_t clicks; - uint32_t microseconds; - - clicks = T0TC; /* T0TC is the 32bit time counter 0 */ - - microseconds = (rtems_configuration_get_microseconds_per_tick() - clicks); - return microseconds * 1000; -} - -#define Clock_driver_nanoseconds_since_last_tick \ - bsp_clock_nanoseconds_since_last_tick - /** * Enables clock interrupt. * @@ -149,6 +170,8 @@ static int clock_isr_is_on(const rtems_irq_connect_data *irq) return T0IR & 0x01; /* MR0 mask */ } +#define Clock_driver_timecounter_tick() lpc22xx_tc_tick() + /* Make sure to include this, and only at the end of the file */ #include "../../../../libbsp/shared/clockdrv_shell.h" diff --git a/c/src/lib/libcpu/arm/mc9328mxl/clock/clockdrv.c b/c/src/lib/libcpu/arm/mc9328mxl/clock/clockdrv.c index 0c3ab5dd93..d5dc69c9a0 100644 --- a/c/src/lib/libcpu/arm/mc9328mxl/clock/clockdrv.c +++ b/c/src/lib/libcpu/arm/mc9328mxl/clock/clockdrv.c @@ -130,5 +130,8 @@ static int clock_isr_is_on(const rtems_irq_connect_data *irq) return MC9328MXL_TMR1_TCTL & MC9328MXL_TMR_TCTL_IRQEN; } +#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER + /* Make sure to include this, and only at the end of the file */ + #include "../../../../libbsp/shared/clockdrv_shell.h" diff --git a/c/src/lib/libcpu/arm/pxa255/clock/clock.c b/c/src/lib/libcpu/arm/pxa255/clock/clock.c index 92d9b21d2b..69b684926c 100644 --- a/c/src/lib/libcpu/arm/pxa255/clock/clock.c +++ b/c/src/lib/libcpu/arm/pxa255/clock/clock.c @@ -116,4 +116,6 @@ static void Clock_driver_support_shutdown_hardware( void ) BSP_remove_rtems_irq_handler(&clock_isr_data); } +#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER + #include "../../../../libbsp/shared/clockdrv_shell.h" diff --git a/c/src/lib/libcpu/arm/s3c24xx/clock/clockdrv.c b/c/src/lib/libcpu/arm/s3c24xx/clock/clockdrv.c index 519d3f850d..a92dc607a3 100644 --- a/c/src/lib/libcpu/arm/s3c24xx/clock/clockdrv.c +++ b/c/src/lib/libcpu/arm/s3c24xx/clock/clockdrv.c @@ -28,17 +28,6 @@ rtems_irq_connect_data clock_isr_data = { }; /** - * Return the nanoseconds since last tick - */ -static uint32_t clock_driver_get_nanoseconds_since_last_tick(void) -{ - return 0; -} - -#define Clock_driver_nanoseconds_since_last_tick \ - clock_driver_get_nanoseconds_since_last_tick - -/** * When we get the clock interrupt * - clear the interrupt bit? * - restart the timer? @@ -74,6 +63,7 @@ static uint32_t clock_driver_get_nanoseconds_since_last_tick(void) do { \ uint32_t cr; \ uint32_t freq; \ + uint32_t mask; \ /* set MUX for Timer4 to 1/16 */ \ cr=rTCFG1 & 0xFFF0FFFF; \ rTCFG1=(cr | (3<<16)); \ @@ -131,5 +121,7 @@ static int clock_isr_is_on(const rtems_irq_connect_data *irq) return 1; } +#define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER + /* Make sure to include this, and only at the end of the file */ #include "../../../../libbsp/shared/clockdrv_shell.h" diff --git a/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c b/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c index 218828cf4a..41b10cb30d 100644 --- a/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c +++ b/c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c @@ -29,6 +29,7 @@ #include <libcpu/spr.h> #include <rtems/bspIo.h> /* for printk() */ #include <libcpu/powerpc-utility.h> +#include <rtems/timecounter.h> #include <bspopts.h> /* for CLOCK_DRIVER_USE_FAST_IDLE */ @@ -48,11 +49,12 @@ volatile uint32_t Clock_driver_ticks; */ static uint32_t Clock_Decrementer_value; -/* - * This is the value by which elapsed count down timer ticks are multiplied to - * give an elapsed duration in nanoseconds, left-shifted by 32 bits - */ -static uint64_t Clock_Decrementer_reference; +static struct timecounter Clock_TC; + +static uint32_t Clock_Get_timecount(struct timecounter *tc) +{ + return ppc_time_base(); +} void clockOff(void* unused) { @@ -94,16 +96,27 @@ void clockOn(void* unused) static void clockHandler(void) { #if (CLOCK_DRIVER_USE_FAST_IDLE == 1) - do { - rtems_clock_tick(); - } while ( + rtems_interrupt_level level; + uint32_t tb; + + rtems_interrupt_disable(level); + + tb = ppc_time_base(); + rtems_timecounter_tick(); + + while ( _Thread_Heir == _Thread_Executing && _Thread_Executing->Start.entry_point == (Thread_Entry) rtems_configuration_get_idle_task() - ); + ) { + tb += Clock_Decrementer_value; + ppc_set_time_base( tb ); + rtems_timecounter_tick(); + } + rtems_interrupt_enable(level); #else - rtems_clock_tick(); + rtems_timecounter_tick(); #endif } @@ -141,7 +154,6 @@ void clockIsr(void *unused) rtems_interrupt_enable(flags); Clock_driver_ticks += 1; - /* * Real Time Clock counter/timer is set to automatically reload. */ @@ -187,7 +199,6 @@ int clockIsOn(void* unused) return 0; } - /* * Clock_exit * @@ -199,53 +210,6 @@ void Clock_exit( void ) (void) BSP_disconnect_clock_handler (); } -static uint32_t Clock_driver_nanoseconds_since_last_tick(void) -{ - uint32_t clicks, tmp; - - PPC_Get_decrementer( clicks ); - - /* - * Multiply by 1000 here separately from below so we do not overflow - * and get a negative value. - */ - tmp = (Clock_Decrementer_value - clicks) * 1000; - tmp /= (BSP_bus_frequency/BSP_time_base_divisor); - - return tmp * 1000; -} - -static uint32_t Clock_driver_nanoseconds_since_last_tick_bookE(void) -{ - uint32_t clicks; - uint64_t c; - - PPC_Get_decrementer( clicks ); - c = Clock_Decrementer_value - clicks; - - /* - * Check whether a clock tick interrupt is pending and hence that the - * decrementer's wrapped. If it has, we'll compensate by returning a time one - * tick period longer. - * - * We have to check interrupt status after reading the decrementer. If we - * don't, we may miss an interrupt and read a wrapped decrementer value - * without compensating for it - */ - if ( _read_BOOKE_TSR() & BOOKE_TSR_DIS ) - { - /* - * Re-read the decrementer: The tick interrupt may have been - * generated and the decrementer wrapped during the time since we - * last read it and the time we checked the interrupt status - */ - PPC_Get_decrementer( clicks ); - c = (Clock_Decrementer_value - clicks) + Clock_Decrementer_value; - } - - return (uint32_t)((c * Clock_Decrementer_reference) >> 32); -} - /* * Clock_initialize * @@ -262,9 +226,6 @@ rtems_device_driver Clock_initialize( Clock_Decrementer_value = (BSP_bus_frequency/BSP_time_base_divisor)* rtems_configuration_get_milliseconds_per_tick(); - Clock_Decrementer_reference = ((uint64_t)1000000U<<32)/ - (BSP_bus_frequency/BSP_time_base_divisor); - /* set the decrementer now, prior to installing the handler * so no interrupts will happen in a while. */ @@ -283,24 +244,14 @@ rtems_device_driver Clock_initialize( _write_BOOKE_TCR(tcr); rtems_interrupt_enable(l); - - /* - * Set the nanoseconds since last tick handler - */ - rtems_clock_set_nanoseconds_extension( - Clock_driver_nanoseconds_since_last_tick_bookE - ); - } - else - { - /* - * Set the nanoseconds since last tick handler - */ - rtems_clock_set_nanoseconds_extension( - Clock_driver_nanoseconds_since_last_tick - ); } + Clock_TC.tc_get_timecount = Clock_Get_timecount; + Clock_TC.tc_counter_mask = 0xffffffff; + Clock_TC.tc_frequency = (1000 * BSP_bus_frequency) / BSP_time_base_divisor; + Clock_TC.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; + rtems_timecounter_install(&Clock_TC); + /* * If a decrementer exception was pending, it is cleared by * executing the default (nop) handler at this point; |