[rtems commit] bsps: More accurate PowerPC clock driver

Sebastian Huber sebh at rtems.org
Mon Jul 9 08:39:08 UTC 2012


Module:    rtems
Branch:    master
Commit:    74af8c097004eb226a3fcb5a4b04f11f98bc90d6
Changeset: http://git.rtems.org/rtems/commit/?id=74af8c097004eb226a3fcb5a4b04f11f98bc90d6

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Apr  2 11:32:11 2012 +0200

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.

---

 .../lib/libbsp/powerpc/gen5200/startup/bspstart.c  |   10 ++++---
 .../lib/libbsp/powerpc/gen83xx/startup/bspstart.c  |    9 ++++--
 .../libbsp/powerpc/mpc8260ads/startup/bspstart.c   |    2 +
 .../lib/libbsp/powerpc/qemuppc/startup/bspstart.c  |   10 ++++---
 c/src/lib/libbsp/powerpc/qoriq/startup/bspstart.c  |    2 +-
 c/src/lib/libbsp/powerpc/shared/clock/clock.c      |   25 +++++++++++++++----
 c/src/lib/libbsp/powerpc/tqm8xx/startup/bspstart.c |    9 +++++-
 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 16d541a..ef948fc 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 3a9772d..3261617 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 17520a9..e6b0e60 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 10538e5..43dbef4 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 d47bf7b..0a7cd3a 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 27523c5..48abc27 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 cfd99e2..9eba188 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;
 




More information about the vc mailing list