diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-07-19 10:52:20 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2022-11-10 10:06:12 +0100 |
commit | 222bc4715d8102fb72291ee4f44284b59b10f274 (patch) | |
tree | 8950f1823383553342a7aa350975c6f2a3abb9ed | |
parent | 7b6d53974184b396486e199ca602c22c346f180f (diff) |
bsp/leon3: LEON3_PLB_FREQUENCY_DEFINED_BY_GPTIMER
-rw-r--r-- | bsps/sparc/leon3/clock/ckinit.c | 9 | ||||
-rw-r--r-- | bsps/sparc/leon3/include/bsp/leon3.h | 27 | ||||
-rw-r--r-- | bsps/sparc/leon3/start/cpucounter.c | 8 | ||||
-rw-r--r-- | spec/build/bsps/sparc/leon3/grp.yml | 2 | ||||
-rw-r--r-- | spec/build/bsps/sparc/leon3/optplbfreq.yml | 22 |
5 files changed, 62 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..ed1a9e4efe 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 1256d882b0..59727aa26d 100644 --- a/bsps/sparc/leon3/start/cpucounter.c +++ b/bsps/sparc/leon3/start/cpucounter.c @@ -47,7 +47,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; @@ -64,8 +68,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 79a480c5bf..681e111007 100644 --- a/spec/build/bsps/sparc/leon3/grp.yml +++ b/spec/build/bsps/sparc/leon3/grp.yml @@ -45,6 +45,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..d2632b989a --- /dev/null +++ b/spec/build/bsps/sparc/leon3/optplbfreq.yml @@ -0,0 +1,22 @@ +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-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 |