summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu
diff options
context:
space:
mode:
authorAlexander Krutwig <alexander.krutwig@embedded-brains.de>2015-04-01 15:33:25 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-05-20 08:40:34 +0200
commit75acd9e69f906cbd880a17ee4ca705ad7caa92c0 (patch)
tree71529028154cb323286b02392def2e5277eed312 /c/src/lib/libcpu
parenttimecounter: Use in RTEMS (diff)
downloadrtems-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.c23
-rw-r--r--c/src/lib/libcpu/arm/lpc22xx/clock/clockdrv.c53
-rw-r--r--c/src/lib/libcpu/arm/mc9328mxl/clock/clockdrv.c3
-rw-r--r--c/src/lib/libcpu/arm/pxa255/clock/clock.c2
-rw-r--r--c/src/lib/libcpu/arm/s3c24xx/clock/clockdrv.c14
-rw-r--r--c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c107
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;