RTEMS
cpucounter.c
1 /*
2  * Copyright (c) 2014, 2018 embedded brains GmbH. All rights reserved.
3  *
4  * embedded brains GmbH
5  * Dornierstr. 4
6  * 82178 Puchheim
7  * Germany
8  * <rtems@embedded-brains.de>
9  *
10  * The license and distribution terms for this file may be
11  * found in the file LICENSE in this distribution or at
12  * http://www.rtems.org/license/LICENSE.
13  */
14 
15 #include <leon.h>
16 
17 #include <rtems/counter.h>
18 #include <rtems/sysinit.h>
19 #include <rtems/score/sparcimpl.h>
20 
21 static uint32_t leon3_counter_frequency = 1000000000;
22 
23 uint32_t _CPU_Counter_frequency(void)
24 {
25  return leon3_counter_frequency;
26 }
27 
28 static void leon3_counter_initialize(void)
29 {
30  volatile struct irqmp_timestamp_regs *irqmp_ts;
31  volatile struct gptimer_regs *gpt;
32  SPARC_Counter *counter;
33 
34  irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0];
35  gpt = LEON3_Timer_Regs;
36  counter = &_SPARC_Counter_mutable;
37 
38  leon3_up_counter_enable();
39 
40  if (leon3_up_counter_is_available()) {
41  /* Use the LEON4 up-counter if available */
42  counter->read_isr_disabled = _SPARC_Counter_read_asr23;
43  counter->read = _SPARC_Counter_read_asr23;
44 
45  leon3_counter_frequency = leon3_up_counter_frequency();
46  } else if (leon3_irqmp_has_timestamp(irqmp_ts)) {
47  /* Use the interrupt controller timestamp counter if available */
48  counter->read_isr_disabled = _SPARC_Counter_read_up;
49  counter->read = _SPARC_Counter_read_up;
50  counter->counter_register = &LEON3_IrqCtrl_Regs->timestamp[0].counter;
51 
52  /* Enable interrupt timestamping for an arbitrary interrupt line */
53  irqmp_ts->control = 0x1;
54 
55  leon3_counter_frequency = ambapp_freq_get(&ambapp_plb, LEON3_IrqCtrl_Adev);
56  } else if (gpt != NULL) {
57  /* Fall back to the first GPTIMER if available */
58  counter->read_isr_disabled = _SPARC_Counter_read_down;
59  counter->read = _SPARC_Counter_read_down;
60  counter->counter_register = &gpt->timer[LEON3_COUNTER_GPTIMER_INDEX].value;
61 
62  /* Enable timer just in case no clock driver is configured */
63  gpt->timer[LEON3_COUNTER_GPTIMER_INDEX].ctrl |= GPTIMER_TIMER_CTRL_EN;
64 
65  leon3_counter_frequency = ambapp_freq_get(&ambapp_plb, LEON3_Timer_Adev) /
66  (gpt->scaler_reload + 1);
67  }
68 }
69 
70 RTEMS_SYSINIT_ITEM(
71  leon3_counter_initialize,
72  RTEMS_SYSINIT_CPU_COUNTER,
73  RTEMS_SYSINIT_ORDER_FIRST
74 );
75 
76 SPARC_COUNTER_DEFINITION;
LEON3 BSP data types and macros.
Free-Running Counter and Busy Wait Delay API.