[PATCH v3 21/38] bsp/leon3: LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER

Sebastian Huber sebastian.huber at embedded-brains.de
Wed Jul 12 13:50:00 UTC 2023


---
 bsps/sparc/leon3/clock/ckinit.c            |  9 +++++++-
 bsps/sparc/leon3/include/bsp/leon3.h       | 27 ++++++++++++++++++----
 bsps/sparc/leon3/start/cpucounter.c        |  8 +++++++
 spec/build/bsps/sparc/leon3/grp.yml        |  2 ++
 spec/build/bsps/sparc/leon3/optplbfreq.yml | 21 +++++++++++++++++
 5 files changed, 61 insertions(+), 6 deletions(-)
 create mode 100644 spec/build/bsps/sparc/leon3/optplbfreq.yml

diff --git a/bsps/sparc/leon3/clock/ckinit.c b/bsps/sparc/leon3/clock/ckinit.c
index eea598dd48..fc20577634 100644
--- a/bsps/sparc/leon3/clock/ckinit.c
+++ b/bsps/sparc/leon3/clock/ckinit.c
@@ -44,12 +44,15 @@
 #include <bsp/irq.h>
 #include <bsp/leon3.h>
 #include <rtems/rtems/intr.h>
-#include <grlib/ambapp.h>
 #include <grlib/irqamp.h>
 #include <rtems/score/profiling.h>
 #include <rtems/score/sparcimpl.h>
 #include <rtems/timecounter.h>
 
+#if !defined(LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER)
+#include <grlib/ambapp.h>
+#endif
+
 /* The LEON3 BSP Timer driver can rely on the Driver Manager if the
  * DrvMgr is initialized during startup. Otherwise the classic driver
  * must be used.
@@ -214,7 +217,11 @@ static void leon3_clock_initialize(void)
   } else if (irqmp_ts != NULL) {
     /* Use the interrupt controller timestamp counter if available */
     tc->tc_get_timecount = _SPARC_Get_timecount_up;
+#if defined(LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER)
+    tc->tc_frequency = leon3_processor_local_bus_frequency();
+#else
     tc->tc_frequency = ambapp_freq_get(ambapp_plb(), LEON3_Timer_Adev);
+#endif
 
     leon3_tc_tick = leon3_tc_tick_irqmp_timestamp_init;
 
diff --git a/bsps/sparc/leon3/include/bsp/leon3.h b/bsps/sparc/leon3/include/bsp/leon3.h
index 1402dfca1b..599d616aaf 100644
--- a/bsps/sparc/leon3/include/bsp/leon3.h
+++ b/bsps/sparc/leon3/include/bsp/leon3.h
@@ -42,7 +42,9 @@
 #include <bspopts.h>
 #include <bsp/irqimpl.h>
 
+#if !defined(LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER)
 #include <grlib/ambapp.h>
+#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -194,6 +196,25 @@ extern gptimer *LEON3_Timer_Regs;
  */
 extern struct ambapp_dev *LEON3_Timer_Adev;
 
+/**
+ * @brief Gets the processor local bus frequency in Hz.
+ *
+ * @return Returns the frequency.
+ */
+static inline uint32_t leon3_processor_local_bus_frequency( void )
+{
+#if defined(LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER)
+  return ( grlib_load_32( &LEON3_Timer_Regs->sreload ) + 1 ) *
+    LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER;
+#else
+  /*
+   * For simplicity, assume that the interrupt controller uses the processor
+   * clock.  This is at least true on the GR740.
+   */
+  return ambapp_freq_get( ambapp_plb(), LEON3_IrqCtrl_Adev );
+#endif
+}
+
 /**
  * @brief Gets the LEON up-counter low register (%ASR23) value.
  *
@@ -257,11 +278,7 @@ static inline bool leon3_up_counter_is_available( void )
  */
 static inline uint32_t leon3_up_counter_frequency( void )
 {
-  /*
-   * For simplicity, assume that the interrupt controller uses the processor
-   * clock.  This is at least true on the GR740.
-   */
-  return ambapp_freq_get( ambapp_plb(), LEON3_IrqCtrl_Adev );
+  return leon3_processor_local_bus_frequency();
 }
 
 /**
diff --git a/bsps/sparc/leon3/start/cpucounter.c b/bsps/sparc/leon3/start/cpucounter.c
index 5672cbbd45..57fd487009 100644
--- a/bsps/sparc/leon3/start/cpucounter.c
+++ b/bsps/sparc/leon3/start/cpucounter.c
@@ -66,7 +66,11 @@ static void leon3_counter_initialize(void)
     /* Enable interrupt timestamping for an arbitrary interrupt line */
     grlib_store_32(&irqmp_ts->itstmpc, IRQAMP_ITSTMPC_TSISEL(1));
 
+#if defined(LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER)
+    leon3_counter_frequency = leon3_processor_local_bus_frequency();
+#else
     leon3_counter_frequency = ambapp_freq_get(ambapp_plb(), LEON3_IrqCtrl_Adev);
+#endif
   } else if (gpt != NULL) {
     gptimer_timer *timer;
     uint32_t       tctrl;
@@ -83,8 +87,12 @@ static void leon3_counter_initialize(void)
     tctrl |= GPTIMER_TCTRL_EN | GPTIMER_TCTRL_RS | GPTIMER_TCTRL_LD;
     grlib_store_32(&timer->tctrl, tctrl);
 
+#if defined(LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER)
+    leon3_counter_frequency = LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER;
+#else
     leon3_counter_frequency = ambapp_freq_get(ambapp_plb(), LEON3_Timer_Adev) /
       (grlib_load_32(&gpt->sreload) + 1);
+#endif
   }
 }
 
diff --git a/spec/build/bsps/sparc/leon3/grp.yml b/spec/build/bsps/sparc/leon3/grp.yml
index 48da9acba8..964682d0fe 100644
--- a/spec/build/bsps/sparc/leon3/grp.yml
+++ b/spec/build/bsps/sparc/leon3/grp.yml
@@ -38,6 +38,8 @@ links:
   uid: optconirq
 - role: build-dependency
   uid: optleon3smp
+- role: build-dependency
+  uid: optplbfreq
 - role: build-dependency
   uid: optpwrdwnhlt
 - role: build-dependency
diff --git a/spec/build/bsps/sparc/leon3/optplbfreq.yml b/spec/build/bsps/sparc/leon3/optplbfreq.yml
new file mode 100644
index 0000000000..f542e322ac
--- /dev/null
+++ b/spec/build/bsps/sparc/leon3/optplbfreq.yml
@@ -0,0 +1,21 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH & Co. KG
+actions:
+- get-boolean: null
+- define-condition: null
+build-type: option
+default:
+- enabled-by:
+  - sparc/gr712rc
+  - sparc/gr740
+  value: true
+enabled-by: true
+links: []
+name: LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER
+description: |
+  If this option is set to true, then the processor local bus (PLB) frequency
+  is directly defined by the first GPTIMER frequency neglecting the actual bus
+  topology.  It is assumed that the boot loader configured the first GPTIMER to
+  have a frequency of LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER.
+type: build
-- 
2.35.3



More information about the devel mailing list