diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-04-02 11:32:11 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-04-02 13:40:15 +0200 |
commit | 8bb00ace5090804804f6011a02e097176fa63bb8 (patch) | |
tree | 53efdb2189daab1802eb62a11f879ce787ddf03c | |
parent | bsp/gen83xx: Support cache BSP options (diff) | |
download | rtems-8bb00ace5090804804f6011a02e097176fa63bb8.tar.bz2 |
bsps: More accurate PowerPC clock driver
The clock driver used previously the bsp_clicks_per_usec value. For a
33333333Hz time base frequency this leads to a relative error of one per
cent for example due to integer truncation.
7 files changed, 47 insertions, 20 deletions
diff --git a/c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c b/c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c index 16d541a6de..ef948fcd89 100644 --- a/c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c +++ b/c/src/lib/libbsp/powerpc/gen5200/startup/bspstart.c @@ -105,10 +105,11 @@ #include <bsp/irq-generic.h> #include <bsp/mpc5200.h> -/* - * Driver configuration parameters - */ -uint32_t bsp_clicks_per_usec; +/* Configuration parameter for clock driver */ +uint32_t bsp_time_base_frequency; + +/* Legacy */ +uint32_t bsp_clicks_per_usec; void BSP_panic(char *s) { @@ -157,6 +158,7 @@ void bsp_start(void) mpc5200.config = xlb_cfg; } + bsp_time_base_frequency = XLB_CLOCK / 4; bsp_clicks_per_usec = (XLB_CLOCK/4000000); /* diff --git a/c/src/lib/libbsp/powerpc/gen83xx/startup/bspstart.c b/c/src/lib/libbsp/powerpc/gen83xx/startup/bspstart.c index 3a9772d165..3261617e39 100644 --- a/c/src/lib/libbsp/powerpc/gen83xx/startup/bspstart.c +++ b/c/src/lib/libbsp/powerpc/gen83xx/startup/bspstart.c @@ -34,7 +34,10 @@ /* Configuration parameters for console driver, ... */ unsigned int BSP_bus_frequency; -/* Configuration parameters for clock driver, ... */ +/* Configuration parameter for clock driver */ +uint32_t bsp_time_base_frequency; + +/* Legacy */ uint32_t bsp_clicks_per_usec; /* Default decrementer exception handler */ @@ -113,11 +116,11 @@ void bsp_start( void) #ifdef HAS_UBOOT BSP_bus_frequency = bsp_uboot_board_info.bi_busfreq; - bsp_clicks_per_usec = bsp_uboot_board_info.bi_busfreq / 4000000; #else /* HAS_UBOOT */ BSP_bus_frequency = BSP_CLKIN_FRQ * BSP_SYSPLL_MF / BSP_SYSPLL_CKID; - bsp_clicks_per_usec = BSP_bus_frequency / 4000000; #endif /* HAS_UBOOT */ + bsp_time_base_frequency = BSP_bus_frequency / 4; + bsp_clicks_per_usec = bsp_time_base_frequency / 1000000; /* Initialize some console parameters */ for (i = 0; i < Console_Port_Count; ++i) { diff --git a/c/src/lib/libbsp/powerpc/mpc8260ads/startup/bspstart.c b/c/src/lib/libbsp/powerpc/mpc8260ads/startup/bspstart.c index 17520a9a4c..e6b0e60f6b 100644 --- a/c/src/lib/libbsp/powerpc/mpc8260ads/startup/bspstart.c +++ b/c/src/lib/libbsp/powerpc/mpc8260ads/startup/bspstart.c @@ -58,6 +58,7 @@ SPR_RW(SPRG1) * Driver configuration parameters */ uint32_t bsp_clock_speed; +uint32_t bsp_time_base_frequency; uint32_t bsp_clicks_per_usec; uint32_t bsp_serial_per_sec; /* Serial clocks per second */ bool bsp_serial_external_clock; @@ -207,6 +208,7 @@ void bsp_start(void) /* * initialize the device driver parameters */ + bsp_time_base_frequency = 10000000; bsp_clicks_per_usec = 10; /* for 40MHz extclk */ bsp_serial_per_sec = 40000000; bsp_serial_external_clock = 0; diff --git a/c/src/lib/libbsp/powerpc/qemuppc/startup/bspstart.c b/c/src/lib/libbsp/powerpc/qemuppc/startup/bspstart.c index 10538e5be4..43dbef49b9 100644 --- a/c/src/lib/libbsp/powerpc/qemuppc/startup/bspstart.c +++ b/c/src/lib/libbsp/powerpc/qemuppc/startup/bspstart.c @@ -32,10 +32,11 @@ */ unsigned int BSP_bus_frequency; -/* - * Driver configuration parameters - */ -uint32_t bsp_clicks_per_usec; +/* Configuration parameter for clock driver */ +uint32_t bsp_time_base_frequency; + +/* Legacy */ +uint32_t bsp_clicks_per_usec; /* * Memory on this board. @@ -78,6 +79,7 @@ void bsp_start( void ) * this should speed up some tests :-) */ BSP_bus_frequency = 20; + bsp_time_base_frequency = 20000000; bsp_clicks_per_usec = BSP_bus_frequency; /* diff --git a/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c b/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c index d47bf7bc0a..0a7cd3a5dc 100644 --- a/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c +++ b/c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c @@ -43,7 +43,7 @@ LINKER_SYMBOL(bsp_exc_vector_base); /* Configuration parameters for console driver, ... */ unsigned int BSP_bus_frequency; -/* Configuration parameters for clock driver, ... */ +/* Configuration parameter for clock driver, ... */ uint32_t bsp_clicks_per_usec; void BSP_panic(char *s) diff --git a/c/src/lib/libbsp/powerpc/shared/clock/clock.c b/c/src/lib/libbsp/powerpc/shared/clock/clock.c index 27523c592c..48abc274ca 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-2011 embedded brains GmbH. All rights reserved. + * Copyright (c) 2008-2012 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Obere Lagerstr. 30 @@ -32,9 +32,9 @@ /* * This variable must be defined in the BSP and valid before clock driver - * initialization. The clicks refer to the decrementer and time base. + * initialization. */ -extern uint32_t bsp_clicks_per_usec; +extern uint32_t bsp_time_base_frequency; #define PPC_CLOCK_DECREMENTER_MAX UINT32_MAX @@ -46,7 +46,9 @@ rtems_device_minor_number rtems_clock_minor = UINT32_MAX; static uint32_t ppc_clock_decrementer_value = PPC_CLOCK_DECREMENTER_MAX; -static uint32_t ppc_clock_next_time_base = 0; +static uint32_t ppc_clock_next_time_base; + +static uint64_t ppc_clock_factor; static void ppc_clock_no_tick(void) { @@ -151,7 +153,11 @@ static int ppc_clock_exception_handler_e300( BSP_Exception_frame *frame, unsigne static uint32_t ppc_clock_nanoseconds_since_last_tick(void) { - return ((ppc_clock_decrementer_value - ppc_decrementer_register()) * 1000) / bsp_clicks_per_usec; + 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); } void Clock_exit(void) @@ -165,6 +171,10 @@ void Clock_exit(void) rtems_device_driver Clock_initialize( rtems_device_major_number major, rtems_device_minor_number minor, void *arg) { + 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); + /* Current CPU type */ ppc_cpu_id_t cpu_type = get_ppc_cpu_type(); @@ -184,8 +194,11 @@ rtems_device_driver Clock_initialize( rtems_device_major_number major, rtems_dev /* Set the decrementer to the maximum value */ ppc_set_decrementer_register( PPC_CLOCK_DECREMENTER_MAX); + /* Factor for nano seconds extension */ + ppc_clock_factor = (1000000000ULL << 32) / frequency; + /* Decrementer value */ - ppc_clock_decrementer_value = bsp_clicks_per_usec * rtems_configuration_get_microseconds_per_tick() - 1; + ppc_clock_decrementer_value = interval - 1; /* Check decrementer value */ if (ppc_clock_decrementer_value == 0) { diff --git a/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c b/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c index cfd99e2fa2..9eba18839e 100644 --- a/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c +++ b/c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c @@ -40,8 +40,12 @@ /* Configuration parameters for console driver, ... */ uint32_t BSP_bus_frequency; -/* Configuration parameters for clock driver, ... */ +/* Configuration parameter for clock driver */ +uint32_t bsp_time_base_frequency; + +/* Legacy */ uint32_t bsp_clicks_per_usec; /* for PIT driver: OSCCLK */ + /* for timer: */ uint32_t bsp_timer_average_overhead; /* Average overhead of timer in ticks */ uint32_t bsp_timer_least_valid; /* Least valid number from timer */ @@ -173,7 +177,8 @@ void bsp_start( void) BSP_panic("Cannot determine BUS frequency\n"); } - bsp_clicks_per_usec = BSP_bus_frequency/1000000/16; + bsp_time_base_frequency = BSP_bus_frequency / 16; + bsp_clicks_per_usec = bsp_time_base_frequency / 1000000; bsp_timer_least_valid = 3; bsp_timer_average_overhead = 3; |