source: rtems/bsps/powerpc/qoriq/clock/clock-config.c @ 8f8ccee

5
Last change on this file since 8f8ccee was 7632906, checked in by Sebastian Huber <sebastian.huber@…>, on 04/19/18 at 04:35:52

bsps: Move clock drivers to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 4.4 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup QorIQ
5 *
6 * @brief QorIQ clock configuration.
7 */
8
9/*
10 * Copyright (c) 2011, 2017 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#include <rtems/timecounter.h>
24
25#include <libcpu/powerpc-utility.h>
26
27#include <bsp.h>
28#include <bsp/qoriq.h>
29#include <bsp/irq.h>
30
31/* This is defined in dev/clock/clockimpl.h */
32static rtems_isr Clock_isr(void *arg);
33
34static struct timecounter qoriq_clock_tc;
35
36#ifdef QORIQ_IS_HYPERVISOR_GUEST
37
38#define CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR
39
40void qoriq_decrementer_dispatch(void)
41{
42  PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_TSR, BOOKE_TSR_DIS);
43  Clock_isr(NULL);
44}
45
46static uint32_t qoriq_clock_get_timecount(struct timecounter *tc)
47{
48  return ppc_alternate_time_base();
49}
50
51static void qoriq_clock_initialize(void)
52{
53  uint64_t frequency = bsp_time_base_frequency;
54  uint32_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
55  uint32_t interval = (uint32_t) ((frequency * us_per_tick) / 1000000);
56
57  PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_DECAR, interval - 1);
58  PPC_SET_SPECIAL_PURPOSE_REGISTER_BITS(
59    BOOKE_TCR,
60    BOOKE_TCR_DIE | BOOKE_TCR_ARE
61  );
62  ppc_set_decrementer_register(interval - 1);
63
64  qoriq_clock_tc.tc_get_timecount = qoriq_clock_get_timecount;
65  qoriq_clock_tc.tc_counter_mask = 0xffffffff;
66  qoriq_clock_tc.tc_frequency = qoriq_clock_frequency;
67  qoriq_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
68  rtems_timecounter_install(&qoriq_clock_tc);
69}
70
71#else /* !QORIQ_IS_HYPERVISOR_GUEST */
72
73static volatile qoriq_pic_global_timer *const qoriq_clock =
74  #if QORIQ_CLOCK_TIMER < 4
75    &qoriq.pic.gta [QORIQ_CLOCK_TIMER];
76  #else
77    &qoriq.pic.gtb [QORIQ_CLOCK_TIMER - 4];
78  #endif
79
80static volatile qoriq_pic_global_timer *const qoriq_timecounter =
81  #if QORIQ_CLOCK_TIMECOUNTER < 4
82    &qoriq.pic.gta [QORIQ_CLOCK_TIMECOUNTER];
83  #else
84    &qoriq.pic.gtb [QORIQ_CLOCK_TIMECOUNTER - 4];
85  #endif
86
87#define CLOCK_INTERRUPT (QORIQ_IRQ_GT_BASE + QORIQ_CLOCK_TIMER)
88
89static void qoriq_clock_handler_install(void)
90{
91  rtems_status_code sc = RTEMS_SUCCESSFUL;
92
93#if defined(RTEMS_MULTIPROCESSING) && !defined(RTEMS_SMP)
94  {
95    Processor_mask affinity;
96
97    _Processor_mask_From_index(&affinity, ppc_processor_id());
98    bsp_interrupt_set_affinity(CLOCK_INTERRUPT, &affinity);
99  }
100#endif
101
102  sc = qoriq_pic_set_priority(
103    CLOCK_INTERRUPT,
104    QORIQ_PIC_PRIORITY_LOWEST,
105    NULL
106  );
107  if (sc != RTEMS_SUCCESSFUL) {
108    rtems_fatal_error_occurred(0xdeadbeef);
109  }
110
111  sc = rtems_interrupt_handler_install(
112    CLOCK_INTERRUPT,
113    "Clock",
114    RTEMS_INTERRUPT_UNIQUE,
115    Clock_isr,
116    NULL
117  );
118  if (sc != RTEMS_SUCCESSFUL) {
119    rtems_fatal_error_occurred(0xdeadbeef);
120  }
121}
122
123static uint32_t qoriq_clock_get_timecount(struct timecounter *tc)
124{
125  uint32_t ccr = qoriq_timecounter->ccr;
126
127  return GTCCR_COUNT_GET(-ccr);
128}
129
130static void qoriq_clock_initialize(void)
131{
132  uint32_t timer_frequency = BSP_bus_frequency / 8;
133  uint32_t interval = (uint32_t) (((uint64_t) timer_frequency
134    * (uint64_t) rtems_configuration_get_microseconds_per_tick()) / 1000000);
135
136  qoriq_clock->bcr = GTBCR_COUNT(interval);
137
138  qoriq_timecounter->bcr = GTBCR_COUNT(0xffffffff);
139
140  qoriq_clock_tc.tc_get_timecount = qoriq_clock_get_timecount;
141  qoriq_clock_tc.tc_counter_mask = GTCCR_COUNT_GET(0xffffffff);
142  qoriq_clock_tc.tc_frequency = timer_frequency;
143  qoriq_clock_tc.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
144  rtems_timecounter_install(&qoriq_clock_tc);
145}
146
147static void qoriq_clock_cleanup(void)
148{
149  rtems_status_code sc = RTEMS_SUCCESSFUL;
150
151  qoriq_clock->bcr = GTBCR_CI;
152
153  sc = rtems_interrupt_handler_remove(
154    CLOCK_INTERRUPT,
155    Clock_isr,
156    NULL
157  );
158  if (sc != RTEMS_SUCCESSFUL) {
159    rtems_fatal_error_occurred(0xdeadbeef);
160  }
161}
162
163#define Clock_driver_support_install_isr(clock_isr) \
164  qoriq_clock_handler_install()
165
166#define Clock_driver_support_set_interrupt_affinity(online_processors) \
167  bsp_interrupt_set_affinity(CLOCK_INTERRUPT, online_processors)
168
169#define Clock_driver_support_shutdown_hardware() \
170  qoriq_clock_cleanup()
171
172#endif /* QORIQ_IS_HYPERVISOR_GUEST */
173
174#define Clock_driver_support_initialize_hardware() \
175  qoriq_clock_initialize()
176
177/* Include shared source clock driver code */
178#include "../../../shared/dev/clock/clockimpl.h"
Note: See TracBrowser for help on using the repository browser.