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/libbsp/powerpc | |
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/libbsp/powerpc')
-rw-r--r-- | c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c | 96 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c | 61 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/qoriq/configure.ac | 4 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/clock/clock.c | 56 |
4 files changed, 114 insertions, 103 deletions
diff --git a/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c b/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c index 5743dcff35..5724f9bf4b 100644 --- a/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c +++ b/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c @@ -26,14 +26,40 @@ #include <mpc55xx/regs.h> +#include <rtems/timecounter.h> + void Clock_isr(void *arg); -static uint64_t mpc55xx_clock_factor; +static rtems_timecounter_simple mpc55xx_tc; #if defined(MPC55XX_CLOCK_EMIOS_CHANNEL) #include <mpc55xx/emios.h> +static uint32_t mpc55xx_tc_get(rtems_timecounter_simple *tc) +{ + return EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CCNTR.R; +} + +static bool mpc55xx_tc_is_pending(rtems_timecounter_simple *tc) +{ + return EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CSR.B.FLAG != 0; +} + +static uint32_t mpc55xx_tc_get_timecount(struct timecounter *tc) +{ + return rtems_timecounter_simple_upcounter_get( + tc, + mpc55xx_tc_get, + mpc55xx_tc_is_pending + ); +} + +static void mpc55xx_tc_tick(void) +{ + rtems_timecounter_simple_upcounter_tick(&mpc55xx_tc, mpc55xx_tc_get); +} + static void mpc55xx_clock_at_tick(void) { union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS; @@ -60,6 +86,7 @@ static void mpc55xx_clock_handler_install(rtems_isr_entry isr) static void mpc55xx_clock_initialize(void) { + uint32_t mask; volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL]; union EMIOS_CCR_tag ccr = MPC55XX_ZERO_FLAGS; union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS; @@ -68,8 +95,6 @@ static void mpc55xx_clock_initialize(void) uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick(); uint64_t interval = (reference_clock * us_per_tick) / 1000000; - mpc55xx_clock_factor = (1000000000ULL << 32) / reference_clock; - /* Apply prescaler */ if (prescaler > 0) { interval /= (uint64_t) prescaler; @@ -110,6 +135,13 @@ static void mpc55xx_clock_initialize(void) ccr.B.FEN = 1; ccr.B.FREN = 1; regs->CCR.R = ccr.R; + + rtems_timecounter_simple_install( + &mpc55xx_tc, + reference_clock, + interval, + mpc55xx_tc_get_timecount + ); } static void mpc55xx_clock_cleanup(void) @@ -122,21 +154,31 @@ static void mpc55xx_clock_cleanup(void) regs->CCR.R = ccr.R; } -static uint32_t mpc55xx_clock_nanoseconds_since_last_tick(void) +#elif defined(MPC55XX_CLOCK_PIT_CHANNEL) + +static uint32_t mpc55xx_tc_get(rtems_timecounter_simple *tc) { - volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL]; - uint64_t c = regs->CCNTR.R; - union EMIOS_CSR_tag csr = { .R = regs->CSR.R }; - uint64_t k = mpc55xx_clock_factor; + return PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL].CVAL.R; +} - if (csr.B.FLAG != 0) { - c = regs->CCNTR.R + regs->CADR.R + 1; - } +static bool mpc55xx_tc_is_pending(rtems_timecounter_simple *tc) +{ + return PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL].TFLG.B.TIF != 0; +} - return (uint32_t) ((c * k) >> 32); +static uint32_t mpc55xx_tc_get_timecount(struct timecounter *tc) +{ + return rtems_timecounter_simple_downcounter_get( + tc, + mpc55xx_tc_get, + mpc55xx_tc_is_pending + ); } -#elif defined(MPC55XX_CLOCK_PIT_CHANNEL) +static void mpc55xx_tc_tick(void) +{ + rtems_timecounter_simple_downcounter_tick(&mpc55xx_tc, mpc55xx_tc_get); +} static void mpc55xx_clock_at_tick(void) { @@ -166,6 +208,7 @@ static void mpc55xx_clock_handler_install(rtems_isr_entry isr) static void mpc55xx_clock_initialize(void) { + uint32_t mask; volatile PIT_RTI_CHANNEL_tag *channel = &PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL]; uint64_t reference_clock = bsp_clock_speed; @@ -174,11 +217,16 @@ static void mpc55xx_clock_initialize(void) PIT_RTI_PITMCR_32B_tag pitmcr = { .B = { .FRZ = 1 } }; PIT_RTI_TCTRL_32B_tag tctrl = { .B = { .TIE = 1, .TEN = 1 } }; - mpc55xx_clock_factor = (1000000000ULL << 32) / reference_clock; - PIT_RTI.PITMCR.R = pitmcr.R; channel->LDVAL.R = interval; channel->TCTRL.R = tctrl.R; + + rtems_timecounter_simple_install( + &mpc55xx_tc, + reference_clock, + interval, + mpc55xx_tc_get_timecount + ); } static void mpc55xx_clock_cleanup(void) @@ -189,23 +237,9 @@ static void mpc55xx_clock_cleanup(void) channel->TCTRL.R = 0; } -static uint32_t mpc55xx_clock_nanoseconds_since_last_tick(void) -{ - volatile PIT_RTI_CHANNEL_tag *channel = - &PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL]; - uint32_t c = channel->CVAL.R; - uint32_t i = channel->LDVAL.R; - uint64_t k = mpc55xx_clock_factor; - - if (channel->TFLG.B.TIF != 0) { - c = channel->CVAL.R - i; - } - - return (uint32_t) (((i - c) * k) >> 32); -} - #endif +#define Clock_driver_timecounter_tick() mpc55xx_tc_tick() #define Clock_driver_support_at_tick() \ mpc55xx_clock_at_tick() #define Clock_driver_support_initialize_hardware() \ @@ -217,8 +251,6 @@ static uint32_t mpc55xx_clock_nanoseconds_since_last_tick(void) } while (0) #define Clock_driver_support_shutdown_hardware() \ mpc55xx_clock_cleanup() -#define Clock_driver_nanoseconds_since_last_tick \ - mpc55xx_clock_nanoseconds_since_last_tick /* Include shared source clock driver code */ #include "../../../../libbsp/shared/clockdrv_shell.h" diff --git a/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c b/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c index 039edde46e..c6300e254f 100644 --- a/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c +++ b/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c @@ -7,10 +7,10 @@ */ /* - * Copyright (c) 2011-2012 embedded brains GmbH. All rights reserved. + * Copyright (c) 2011-2015 embedded brains GmbH. All rights reserved. * * embedded brains GmbH - * Obere Lagerstr. 30 + * Dornierstr. 4 * 82178 Puchheim * Germany * <rtems@embedded-brains.de> @@ -20,6 +20,8 @@ * http://www.rtems.org/license/LICENSE. */ +#include <rtems/timecounter.h> + #include <libcpu/powerpc-utility.h> #include <bsp.h> @@ -29,10 +31,6 @@ /* This is defined in clockdrv_shell.h */ static rtems_isr Clock_isr(void *arg); -static uint32_t qoriq_clock_last_ccr; - -static uint32_t qoriq_clock_nanoseconds_per_timer_tick; - static volatile qoriq_pic_global_timer *const qoriq_clock = #if QORIQ_CLOCK_TIMER < 4 &qoriq.pic.gta [QORIQ_CLOCK_TIMER]; @@ -40,8 +38,17 @@ static volatile qoriq_pic_global_timer *const qoriq_clock = &qoriq.pic.gtb [QORIQ_CLOCK_TIMER - 4]; #endif +static volatile qoriq_pic_global_timer *const qoriq_timecounter = + #if QORIQ_CLOCK_TIMECOUNTER < 4 + &qoriq.pic.gta [QORIQ_CLOCK_TIMECOUNTER]; + #else + &qoriq.pic.gtb [QORIQ_CLOCK_TIMECOUNTER - 4]; + #endif + #define CLOCK_INTERRUPT (QORIQ_IRQ_GT_BASE + QORIQ_CLOCK_TIMER) +static struct timecounter qoriq_clock_tc; + static void qoriq_clock_handler_install(rtems_isr_entry *old_isr) { rtems_status_code sc = RTEMS_SUCCESSFUL; @@ -77,18 +84,28 @@ static void qoriq_clock_handler_install(rtems_isr_entry *old_isr) } } +static uint32_t qoriq_clock_get_timecount(struct timecounter *tc) +{ + uint32_t ccr = qoriq_timecounter->ccr; + + return GTCCR_COUNT_GET(-ccr); +} + static void qoriq_clock_initialize(void) { uint32_t timer_frequency = BSP_bus_frequency / 8; - uint32_t nanoseconds_per_second = 1000000000; uint32_t interval = (uint32_t) (((uint64_t) timer_frequency * (uint64_t) rtems_configuration_get_microseconds_per_tick()) / 1000000); - qoriq_clock_nanoseconds_per_timer_tick = - nanoseconds_per_second / timer_frequency; - qoriq_clock->bcr = GTBCR_COUNT(interval); - qoriq_clock_last_ccr = qoriq_clock->ccr; + + qoriq_timecounter->bcr = GTBCR_COUNT(0xffffffff); + + qoriq_clock_tc.tc_get_timecount = qoriq_clock_get_timecount; + qoriq_clock_tc.tc_counter_mask = GTCCR_COUNT_GET(0xffffffff); + qoriq_clock_tc.tc_frequency = timer_frequency; + qoriq_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; + rtems_timecounter_install(&qoriq_clock_tc); } static void qoriq_clock_cleanup(void) @@ -107,33 +124,13 @@ static void qoriq_clock_cleanup(void) } } -static void qoriq_clock_at_tick(void) -{ - qoriq_clock_last_ccr = qoriq_clock->ccr; -} - -static uint32_t qoriq_clock_nanoseconds_since_last_tick(void) -{ - uint32_t ccr = qoriq_clock->ccr; - uint32_t bcr = qoriq_clock->bcr; - - if ((ccr & GTCCR_TOG) != (qoriq_clock_last_ccr & GTCCR_TOG)) { - bcr += bcr; - } - - return (bcr - GTCCR_COUNT_GET(ccr)) * qoriq_clock_nanoseconds_per_timer_tick; -} - -#define Clock_driver_support_at_tick() \ - qoriq_clock_at_tick() +#define Clock_driver_support_at_tick() #define Clock_driver_support_initialize_hardware() \ qoriq_clock_initialize() #define Clock_driver_support_install_isr(clock_isr, old_isr) \ qoriq_clock_handler_install(&old_isr) #define Clock_driver_support_shutdown_hardware() \ qoriq_clock_cleanup() -#define Clock_driver_nanoseconds_since_last_tick \ - qoriq_clock_nanoseconds_since_last_tick /* Include shared source clock driver code */ #include "../../../shared/clockdrv_shell.h" diff --git a/c/src/lib/libbsp/powerpc/qoriq/configure.ac b/c/src/lib/libbsp/powerpc/qoriq/configure.ac index f1ff103d7c..409ac193c4 100644 --- a/c/src/lib/libbsp/powerpc/qoriq/configure.ac +++ b/c/src/lib/libbsp/powerpc/qoriq/configure.ac @@ -154,6 +154,10 @@ RTEMS_BSPOPTS_SET([QORIQ_CLOCK_TIMER],[qoriq_core_1],[4]) RTEMS_BSPOPTS_SET([QORIQ_CLOCK_TIMER],[*],[0]) RTEMS_BSPOPTS_HELP([QORIQ_CLOCK_TIMER],[global timer used for system clock, 0..3 maps to A0..A3, and 4..7 maps to B0..B3]) +RTEMS_BSPOPTS_SET([QORIQ_CLOCK_TIMECOUNTER],[qoriq_core_1],[5]) +RTEMS_BSPOPTS_SET([QORIQ_CLOCK_TIMECOUNTER],[*],[1]) +RTEMS_BSPOPTS_HELP([QORIQ_CLOCK_TIMECOUNTER],[global timer used for the timecounter, 0..3 maps to A0..A3, and 4..7 maps to B0..B3]) + RTEMS_BSPOPTS_SET([QORIQ_CHIP_VARIANT],[qoriq_t2080*],[QORIQ_CHIP_T2080]) RTEMS_BSPOPTS_SET([QORIQ_CHIP_VARIANT],[qoriq_t4240*],[QORIQ_CHIP_T4240]) RTEMS_BSPOPTS_SET([QORIQ_CHIP_VARIANT],[*],[QORIQ_CHIP_P1020]) diff --git a/c/src/lib/libbsp/powerpc/shared/clock/clock.c b/c/src/lib/libbsp/powerpc/shared/clock/clock.c index e9b1d4d24a..d2f2d0d1b0 100644 --- a/c/src/lib/libbsp/powerpc/shared/clock/clock.c +++ b/c/src/lib/libbsp/powerpc/shared/clock/clock.c @@ -7,7 +7,7 @@ */ /* - * Copyright (c) 2008-2013 embedded brains GmbH. All rights reserved. + * Copyright (c) 2008-2015 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Obere Lagerstr. 30 @@ -22,6 +22,7 @@ #include <rtems.h> #include <rtems/clockdrv.h> +#include <rtems/timecounter.h> #include <libcpu/powerpc-utility.h> #include <bsp/vectors.h> @@ -46,7 +47,12 @@ static uint32_t ppc_clock_decrementer_value = PPC_CLOCK_DECREMENTER_MAX; static uint32_t ppc_clock_next_time_base; -static uint64_t ppc_clock_factor; +static struct timecounter ppc_tc; + +static uint32_t ppc_get_timecount(struct timecounter *tc) +{ + return ppc_time_base(); +} static void ppc_clock_no_tick(void) { @@ -161,28 +167,6 @@ static int ppc_clock_exception_handler_ppc405(BSP_Exception_frame *frame, unsign return 0; } -static uint32_t ppc_clock_nanoseconds_since_last_tick(void) -{ - uint64_t k = ppc_clock_factor; - uint32_t c = ppc_decrementer_register(); - uint32_t i = ppc_clock_decrementer_value + 1; - - return (uint32_t) (((i - c) * k) >> 32); -} - -static uint32_t ppc_clock_nanoseconds_since_last_tick_ppc405(void) -{ - uint64_t k = ppc_clock_factor; - uint32_t i = ppc_clock_decrementer_value; - uint32_t c = i - PPC_SPECIAL_PURPOSE_REGISTER(PPC405_PIT); - - if ((PPC_SPECIAL_PURPOSE_REGISTER(PPC405_TSR) & BOOKE_TSR_DIS) != 0) { - c = i - PPC_SPECIAL_PURPOSE_REGISTER(PPC405_PIT) + i; - } - - return (uint32_t) ((c * k) >> 32); -} - void Clock_exit(void) { /* Set the decrementer to the maximum value */ @@ -201,18 +185,12 @@ rtems_device_driver Clock_initialize( uint64_t frequency = bsp_time_base_frequency; uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick(); uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000); + uint32_t mask; /* * Set default ticker. - * - * The function rtems_clock_tick() returns a status code. This value - * will be discarded since the RTEMS documentation claims that it is - * always successful. */ - ppc_clock_tick = (void (*)(void)) rtems_clock_tick; - - /* Factor for nano seconds extension */ - ppc_clock_factor = (1000000000ULL << 32) / frequency; + ppc_clock_tick = rtems_timecounter_tick; if (ppc_cpu_is_bookE() != PPC_BOOKE_405) { /* Decrementer value */ @@ -223,10 +201,6 @@ rtems_device_driver Clock_initialize( ppc_clock_decrementer_value = PPC_CLOCK_DECREMENTER_MAX; RTEMS_SYSLOG_ERROR( "decrementer value would be zero, will be set to maximum value instead\n"); } - - /* Set the nanoseconds since last tick handler */ - rtems_clock_set_nanoseconds_extension( ppc_clock_nanoseconds_since_last_tick); - if (ppc_cpu_is_bookE()) { /* Set decrementer auto-reload value */ PPC_SET_SPECIAL_PURPOSE_REGISTER( BOOKE_DECAR, ppc_clock_decrementer_value); @@ -253,9 +227,6 @@ rtems_device_driver Clock_initialize( /* PIT interval value */ ppc_clock_decrementer_value = interval; - /* Set the nanoseconds since last tick handler */ - rtems_clock_set_nanoseconds_extension(ppc_clock_nanoseconds_since_last_tick_ppc405); - /* Install exception handler */ ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, ppc_clock_exception_handler_ppc405); @@ -266,5 +237,12 @@ rtems_device_driver Clock_initialize( PPC_SET_SPECIAL_PURPOSE_REGISTER(PPC405_PIT, interval); } + /* Install timecounter */ + ppc_tc.tc_get_timecount = ppc_get_timecount; + ppc_tc.tc_counter_mask = 0xffffffff; + ppc_tc.tc_frequency = frequency; + ppc_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER; + rtems_timecounter_install(&ppc_tc); + return RTEMS_SUCCESSFUL; } |