summaryrefslogtreecommitdiffstats
path: root/bsps/sparc/leon3/clock/ckinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/sparc/leon3/clock/ckinit.c')
-rw-r--r--bsps/sparc/leon3/clock/ckinit.c126
1 files changed, 45 insertions, 81 deletions
diff --git a/bsps/sparc/leon3/clock/ckinit.c b/bsps/sparc/leon3/clock/ckinit.c
index 0cd78ea716..fecbf32c1b 100644
--- a/bsps/sparc/leon3/clock/ckinit.c
+++ b/bsps/sparc/leon3/clock/ckinit.c
@@ -27,6 +27,7 @@
#include <rtems/rtems/intr.h>
#include <ambapp.h>
#include <rtems/score/profiling.h>
+#include <rtems/score/sparcimpl.h>
#include <rtems/timecounter.h>
/* The LEON3 BSP Timer driver can rely on the Driver Manager if the
@@ -42,59 +43,7 @@ static int clkirq;
static void (*leon3_tc_tick)(void);
-static rtems_timecounter_simple leon3_tc;
-
-#ifndef RTEMS_SMP
-static uint32_t leon3_tc_get(rtems_timecounter_simple *tc)
-{
- return LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX].value;
-}
-
-static bool leon3_tc_is_pending(rtems_timecounter_simple *tc)
-{
- return LEON_Is_interrupt_pending(clkirq);
-}
-
-static void leon3_tc_at_tick( rtems_timecounter_simple *tc )
-{
- /* Nothing to do */
-}
-
-static uint32_t leon3_tc_get_timecount(struct timecounter *tc)
-{
- return rtems_timecounter_simple_downcounter_get(
- tc,
- leon3_tc_get,
- leon3_tc_is_pending
- );
-}
-
-static void leon3_tc_tick_simple(void)
-{
- rtems_timecounter_simple_downcounter_tick(
- &leon3_tc,
- leon3_tc_get,
- leon3_tc_at_tick
- );
-}
-#endif
-
-static uint32_t leon3_tc_get_timecount_up_counter(struct timecounter *tc)
-{
- return leon3_up_counter_low();
-}
-
-static uint32_t leon3_tc_get_timecount_irqmp(struct timecounter *tc)
-{
- return LEON3_IrqCtrl_Regs->timestamp[0].counter;
-}
-
-#ifdef RTEMS_SMP
-static uint32_t leon3_tc_get_timecount_second_timer(struct timecounter *tc)
-{
- return 0xffffffff - LEON3_Timer_Regs->timer[LEON3_CLOCK_INDEX + 1].value;
-}
-#endif
+static struct timecounter leon3_tc;
#ifdef RTEMS_PROFILING
#define IRQMP_TIMESTAMP_S1_S2 ((1U << 25) | (1U << 26))
@@ -146,12 +95,23 @@ static void leon3_tc_tick_irqmp_timestamp_init(void)
rtems_timecounter_tick();
}
-#ifdef RTEMS_SMP
-static void leon3_tc_tick_second_timer(void)
+static void leon3_tc_tick_default(void)
{
+#ifndef RTEMS_SMP
+ SPARC_Counter *counter;
+ rtems_interrupt_level level;
+
+ counter = &_SPARC_Counter_mutable;
+ rtems_interrupt_local_disable(level);
+
+ LEON3_IrqCtrl_Regs->iclear = counter->pending_mask;
+ counter->accumulated += counter->interval;
+
+ rtems_interrupt_local_enable(level);
+#endif
+
rtems_timecounter_tick();
}
-#endif
static void leon3_tc_do_tick(void)
{
@@ -196,9 +156,11 @@ static void leon3_clock_initialize(void)
{
volatile struct irqmp_timestamp_regs *irqmp_ts;
volatile struct gptimer_regs *gpt;
+ struct timecounter *tc;
irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0];
gpt = LEON3_Timer_Regs;
+ tc = &leon3_tc;
gpt->timer[LEON3_CLOCK_INDEX].reload =
rtems_configuration_get_microseconds_per_tick() - 1;
@@ -210,10 +172,8 @@ static void leon3_clock_initialize(void)
if (leon3_up_counter_is_available()) {
/* Use the LEON4 up-counter if available */
- leon3_tc.tc.tc_get_timecount = leon3_tc_get_timecount_up_counter;
- leon3_tc.tc.tc_counter_mask = 0xffffffff;
- leon3_tc.tc.tc_frequency = leon3_up_counter_frequency();
- leon3_tc.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ tc->tc_get_timecount = _SPARC_Get_timecount_asr23;
+ tc->tc_frequency = leon3_up_counter_frequency();
#ifdef RTEMS_PROFILING
if (!leon3_irqmp_has_timestamp(irqmp_ts)) {
@@ -222,13 +182,11 @@ static void leon3_clock_initialize(void)
#endif
leon3_tc_tick = leon3_tc_tick_irqmp_timestamp_init;
- rtems_timecounter_install(&leon3_tc.tc);
} else if (leon3_irqmp_has_timestamp(irqmp_ts)) {
/* Use the interrupt controller timestamp counter if available */
- leon3_tc.tc.tc_get_timecount = leon3_tc_get_timecount_irqmp;
- leon3_tc.tc.tc_counter_mask = 0xffffffff;
- leon3_tc.tc.tc_frequency = ambapp_freq_get(&ambapp_plb, LEON3_Timer_Adev);
- leon3_tc.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ tc->tc_get_timecount = _SPARC_Get_timecount_up;
+ tc->tc_frequency = ambapp_freq_get(&ambapp_plb, LEON3_Timer_Adev);
+
leon3_tc_tick = leon3_tc_tick_irqmp_timestamp_init;
/*
@@ -236,8 +194,6 @@ static void leon3_clock_initialize(void)
* counter. Use an arbitrary interrupt source.
*/
irqmp_ts->control = 0x1;
-
- rtems_timecounter_install(&leon3_tc.tc);
} else {
#ifdef RTEMS_SMP
/*
@@ -245,24 +201,32 @@ static void leon3_clock_initialize(void)
* controller. At least on SMP configurations we must use a second timer
* in free running mode for the timecounter.
*/
- gpt->timer[LEON3_CLOCK_INDEX + 1].ctrl =
+ gpt->timer[LEON3_COUNTER_GPTIMER_INDEX].ctrl =
GPTIMER_TIMER_CTRL_EN | GPTIMER_TIMER_CTRL_IE;
- leon3_tc.tc.tc_get_timecount = leon3_tc_get_timecount_second_timer;
- leon3_tc.tc.tc_counter_mask = 0xffffffff;
- leon3_tc.tc.tc_frequency = LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER;
- leon3_tc.tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
- leon3_tc_tick = leon3_tc_tick_second_timer;
- rtems_timecounter_install(&leon3_tc.tc);
+
+ tc->tc_get_timecount = _SPARC_Get_timecount_down;
#else
- leon3_tc_tick = leon3_tc_tick_simple;
- rtems_timecounter_simple_install(
- &leon3_tc,
- LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER,
- rtems_configuration_get_microseconds_per_tick(),
- leon3_tc_get_timecount
- );
+ SPARC_Counter *counter;
+
+ counter = &_SPARC_Counter_mutable;
+ counter->read_isr_disabled = _SPARC_Counter_read_clock_isr_disabled;
+ counter->read = _SPARC_Counter_read_clock;
+ counter->counter_register = &gpt->timer[LEON3_CLOCK_INDEX].value;
+ counter->pending_register = &LEON3_IrqCtrl_Regs->ipend;
+ counter->pending_mask = UINT32_C(1) << clkirq;
+ counter->accumulated = rtems_configuration_get_microseconds_per_tick();
+ counter->interval = rtems_configuration_get_microseconds_per_tick();
+
+ tc->tc_get_timecount = _SPARC_Get_timecount_clock;
#endif
+
+ tc->tc_frequency = LEON3_GPTIMER_0_FREQUENCY_SET_BY_BOOT_LOADER,
+ leon3_tc_tick = leon3_tc_tick_default;
}
+
+ tc->tc_counter_mask = 0xffffffff;
+ tc->tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ rtems_timecounter_install(tc);
}
#define Clock_driver_support_initialize_hardware() \