summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/powerpc
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/powerpc
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/powerpc')
-rw-r--r--c/src/lib/libcpu/powerpc/mpc6xx/clock/c_clock.c107
1 files changed, 29 insertions, 78 deletions
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;