source: rtems/bsps/sparc/leon3/start/cpucounter.c @ 65f868c

5
Last change on this file since 65f868c was 65f868c, checked in by Sebastian Huber <sebastian.huber@…>, on 05/23/18 at 12:17:25

Add _CPU_Counter_frequency()

Add rtems_counter_frequency() API function. Use it to initialize the
counter value converter via the new system initialization step
(RTEMS_SYSINIT_CPU_COUNTER). This decouples the counter implementation
and the counter converter. It avoids an unnecessary pull in of the
64-bit integer division from libgcc.

Update #3456.

  • Property mode set to 100644
File size: 2.2 KB
Line 
1/*
2 * Copyright (c) 2014, 2016 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
21static uint32_t leon3_counter_frequency = 1000000000;
22
23uint32_t _CPU_Counter_frequency(void)
24{
25  return leon3_up_counter_frequency;
26}
27
28static void leon3_counter_initialize(void)
29{
30  volatile struct irqmp_timestamp_regs *irqmp_ts;
31  volatile struct gptimer_regs *gpt;
32
33  irqmp_ts = &LEON3_IrqCtrl_Regs->timestamp[0];
34  gpt = LEON3_Timer_Regs;
35
36  leon3_up_counter_enable();
37
38  if (leon3_up_counter_is_available()) {
39    /* Use the LEON4 up-counter if available */
40
41    _SPARC_Counter_initialize(
42      _SPARC_Counter_read_asr23,
43      _SPARC_Counter_difference_normal,
44      NULL
45    );
46
47    leon3_counter_frequency = leon3_up_counter_frequency();
48  } else if (leon3_irqmp_has_timestamp(irqmp_ts)) {
49    /* Use the interrupt controller timestamp counter if available */
50
51    /* Enable interrupt timestamping for an arbitrary interrupt line */
52    irqmp_ts->control = 0x1;
53
54    _SPARC_Counter_initialize(
55      _SPARC_Counter_read_address,
56      _SPARC_Counter_difference_normal,
57      (volatile const uint32_t *) &irqmp_ts->counter
58    );
59
60    leon3_counter_frequency = ambapp_freq_get(&ambapp_plb, LEON3_IrqCtrl_Adev);
61  } else if (gpt != NULL) {
62    /* Fall back to the first GPTIMER if available */
63
64    /* Enable timer just in case no clock driver is configured */
65    gpt->timer[LEON3_CLOCK_INDEX].ctrl |= GPTIMER_TIMER_CTRL_EN;
66
67    _SPARC_Counter_initialize(
68      _SPARC_Counter_read_address,
69      _SPARC_Counter_difference_clock_period,
70      (volatile const uint32_t *) &gpt->timer[LEON3_CLOCK_INDEX].value
71    );
72
73    leon3_counter_frequency = ambapp_freq_get(&ambapp_plb, LEON3_Timer_Adev) /
74      (gpt->scaler_reload - 1);
75  }
76}
77
78RTEMS_SYSINIT_ITEM(
79  leon3_counter_initialize,
80  RTEMS_SYSINIT_CPU_COUNTER,
81  RTEMS_SYSINIT_ORDER_FIRST
82);
83
84SPARC_COUNTER_DEFINITION;
Note: See TracBrowser for help on using the repository browser.