summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-07-19 10:52:20 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-07-23 16:31:12 +0200
commit4e141b8b3b3248a33f4d53d5ae3dc7beb1403df4 (patch)
treec4ea32e0c7b7c9a11a249e109980c7f3e8475a1d
parent51edd5ce46aa9028d680a3718ebf6f45ef8a3cbb (diff)
bsp/leon3: LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER
-rw-r--r--bsps/sparc/leon3/clock/ckinit.c9
-rw-r--r--bsps/sparc/leon3/include/bsp/leon3.h27
-rw-r--r--bsps/sparc/leon3/start/cpucounter.c8
-rw-r--r--spec/build/bsps/sparc/leon3/grp.yml2
-rw-r--r--spec/build/bsps/sparc/leon3/optplbfreq.yml23
5 files changed, 63 insertions, 6 deletions
diff --git a/bsps/sparc/leon3/clock/ckinit.c b/bsps/sparc/leon3/clock/ckinit.c
index f1f63e5920..f654bc7ae2 100644
--- a/bsps/sparc/leon3/clock/ckinit.c
+++ b/bsps/sparc/leon3/clock/ckinit.c
@@ -25,12 +25,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.
@@ -195,7 +198,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 f3a9def60b..6fd354c4b3 100644
--- a/bsps/sparc/leon3/include/bsp/leon3.h
+++ b/bsps/sparc/leon3/include/bsp/leon3.h
@@ -43,7 +43,9 @@
#include <grlib/irqamp-regs.h>
#include <grlib/io.h>
+#if !defined(LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER)
#include <grlib/ambapp.h>
+#endif
struct ambapp_dev;
@@ -285,6 +287,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.
*
* @return Returns the register value.
@@ -347,11 +368,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 8c431d6c9d..d8eac5b894 100644
--- a/bsps/sparc/leon3/start/cpucounter.c
+++ b/bsps/sparc/leon3/start/cpucounter.c
@@ -53,7 +53,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;
@@ -70,8 +74,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_processor_local_bus_frequency();
+#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 fe8b5f5744..3367393cb9 100644
--- a/spec/build/bsps/sparc/leon3/grp.yml
+++ b/spec/build/bsps/sparc/leon3/grp.yml
@@ -42,6 +42,8 @@ links:
- role: build-dependency
uid: optleon3smp
- role: build-dependency
+ uid: optplbfreq
+- role: build-dependency
uid: optpwrdwnhlt
- role: build-dependency
uid: ../start
diff --git a/spec/build/bsps/sparc/leon3/optplbfreq.yml b/spec/build/bsps/sparc/leon3/optplbfreq.yml
new file mode 100644
index 0000000000..9cf60ab90a
--- /dev/null
+++ b/spec/build/bsps/sparc/leon3/optplbfreq.yml
@@ -0,0 +1,23 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+actions:
+- get-boolean: null
+- define-condition: null
+build-type: option
+default: false
+default-by-family: []
+default-by-variant:
+- value: true
+ variants:
+ - sparc/gr712rc
+ - sparc/gr740
+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