source: rtems/bsps/powerpc/mpc55xxevb/clock/clock-config.c @ e560ee85

Last change on this file since e560ee85 was e560ee85, checked in by Joel Sherrill <joel@…>, on 03/01/22 at 21:38:55

bsps/powerpc/: Scripted embedded brains header file clean up

Updates #4625.

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSBSPsPowerPCMPC55XX
5 *
6 * @brief Clock driver configuration.
7 */
8
9/*
10 * Copyright (c) 2009-2013 embedded brains GmbH.  All rights reserved.
11 *
12 * The license and distribution terms for this file may be
13 * found in the file LICENSE in this distribution or at
14 * http://www.rtems.org/license/LICENSE.
15 */
16
17#include <bsp.h>
18#include <bsp/fatal.h>
19#include <bsp/irq.h>
20
21#include <mpc55xx/regs.h>
22
23#include <rtems/timecounter.h>
24
25void Clock_isr(void *arg);
26
27static rtems_timecounter_simple mpc55xx_tc;
28
29#if defined(MPC55XX_CLOCK_EMIOS_CHANNEL)
30
31#include <mpc55xx/emios.h>
32
33static uint32_t mpc55xx_tc_get(rtems_timecounter_simple *tc)
34{
35  return EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CCNTR.R;
36}
37
38static bool mpc55xx_tc_is_pending(rtems_timecounter_simple *tc)
39{
40  return EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CSR.B.FLAG != 0;
41}
42
43static uint32_t mpc55xx_tc_get_timecount(struct timecounter *tc)
44{
45  return rtems_timecounter_simple_upcounter_get(
46    tc,
47    mpc55xx_tc_get,
48    mpc55xx_tc_is_pending
49  );
50}
51
52static void mpc55xx_tc_at_tick(rtems_timecounter_simple *tc)
53{
54  union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS;
55  csr.B.FLAG = 1;
56  EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CSR.R = csr.R;
57}
58
59static void mpc55xx_tc_tick(void)
60{
61  rtems_timecounter_simple_upcounter_tick(
62    &mpc55xx_tc,
63    mpc55xx_tc_get,
64    mpc55xx_tc_at_tick
65  );
66}
67
68static void mpc55xx_clock_handler_install(rtems_isr_entry isr)
69{
70  rtems_status_code sc = RTEMS_SUCCESSFUL;
71
72  sc = mpc55xx_interrupt_handler_install(
73    MPC55XX_IRQ_EMIOS(MPC55XX_CLOCK_EMIOS_CHANNEL),
74    "clock",
75    RTEMS_INTERRUPT_UNIQUE,
76    MPC55XX_INTC_MIN_PRIORITY,
77    (rtems_interrupt_handler) isr,
78    NULL
79  );
80  if (sc != RTEMS_SUCCESSFUL) {
81    bsp_fatal(MPC55XX_FATAL_CLOCK_EMIOS_IRQ_INSTALL);
82  }
83}
84
85static void mpc55xx_clock_initialize(void)
86{
87  volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL];
88  union EMIOS_CCR_tag ccr = MPC55XX_ZERO_FLAGS;
89  union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS;
90  unsigned prescaler = mpc55xx_emios_global_prescaler();
91  uint64_t reference_clock = bsp_clock_speed;
92  uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
93  uint64_t interval = (reference_clock * us_per_tick) / 1000000;
94
95  /* Apply prescaler */
96  if (prescaler > 0) {
97    interval /= (uint64_t) prescaler;
98  } else {
99    bsp_fatal(MPC55XX_FATAL_CLOCK_EMIOS_PRESCALER);
100  }
101
102  /* Check interval */
103  if (interval == 0 || interval > MPC55XX_EMIOS_VALUE_MAX) {
104    bsp_fatal(MPC55XX_FATAL_CLOCK_EMIOS_INTERVAL);
105  }
106
107  /* Configure eMIOS channel */
108
109  /* Set channel in GPIO mode */
110  ccr.B.MODE = MPC55XX_EMIOS_MODE_GPIO_INPUT;
111  regs->CCR.R = ccr.R;
112
113  /* Clear status flags */
114  csr.B.OVR = 1;
115  csr.B.OVFL = 1;
116  csr.B.FLAG = 1;
117  regs->CSR.R = csr.R;
118
119  /* Set internal counter start value */
120  regs->CCNTR.R = 1;
121
122  /* Set timer period */
123  regs->CADR.R = (uint32_t) interval - 1;
124
125  /* Set control register */
126  #if MPC55XX_CHIP_FAMILY == 551
127    ccr.B.MODE = MPC55XX_EMIOS_MODE_MCB_UP_INT_CLK;
128  #else
129    ccr.B.MODE = MPC55XX_EMIOS_MODE_MC_UP_INT_CLK;
130  #endif
131  ccr.B.UCPREN = 1;
132  ccr.B.FEN = 1;
133  ccr.B.FREN = 1;
134  regs->CCR.R = ccr.R;
135
136  rtems_timecounter_simple_install(
137    &mpc55xx_tc,
138    reference_clock,
139    interval,
140    mpc55xx_tc_get_timecount
141  );
142}
143
144#elif defined(MPC55XX_CLOCK_PIT_CHANNEL)
145
146static uint32_t mpc55xx_tc_get(rtems_timecounter_simple *tc)
147{
148  return PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL].CVAL.R;
149}
150
151static bool mpc55xx_tc_is_pending(rtems_timecounter_simple *tc)
152{
153  return PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL].TFLG.B.TIF != 0;
154}
155
156static uint32_t mpc55xx_tc_get_timecount(struct timecounter *tc)
157{
158  return rtems_timecounter_simple_downcounter_get(
159    tc,
160    mpc55xx_tc_get,
161    mpc55xx_tc_is_pending
162  );
163}
164
165static void mpc55xx_tc_at_tick(rtems_timecounter_simple *tc)
166{
167  volatile PIT_RTI_CHANNEL_tag *channel =
168    &PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL];
169  PIT_RTI_TFLG_32B_tag tflg = { .B = { .TIF = 1 } };
170
171  channel->TFLG.R = tflg.R;
172}
173
174static void mpc55xx_tc_tick(void)
175{
176  rtems_timecounter_simple_downcounter_tick(
177    &mpc55xx_tc,
178    mpc55xx_tc_get,
179    mpc55xx_tc_at_tick
180  );
181}
182
183static void mpc55xx_clock_handler_install(rtems_isr_entry isr)
184{
185  rtems_status_code sc = RTEMS_SUCCESSFUL;
186
187  sc = mpc55xx_interrupt_handler_install(
188    MPC55XX_IRQ_PIT_CHANNEL(MPC55XX_CLOCK_PIT_CHANNEL),
189    "clock",
190    RTEMS_INTERRUPT_UNIQUE,
191    MPC55XX_INTC_MIN_PRIORITY,
192    (rtems_interrupt_handler) isr,
193    NULL
194  );
195  if (sc != RTEMS_SUCCESSFUL) {
196    bsp_fatal(MPC55XX_FATAL_CLOCK_PIT_IRQ_INSTALL);
197  }
198}
199
200static void mpc55xx_clock_initialize(void)
201{
202  volatile PIT_RTI_CHANNEL_tag *channel =
203    &PIT_RTI.CHANNEL [MPC55XX_CLOCK_PIT_CHANNEL];
204  uint64_t reference_clock = bsp_clock_speed;
205  uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
206  uint64_t interval = (reference_clock * us_per_tick) / 1000000;
207  PIT_RTI_PITMCR_32B_tag pitmcr = { .B = { .FRZ = 1 } };
208  PIT_RTI_TCTRL_32B_tag tctrl = { .B = { .TIE = 1, .TEN = 1 } };
209
210  PIT_RTI.PITMCR.R = pitmcr.R;
211  channel->LDVAL.R = interval;
212  channel->TCTRL.R = tctrl.R;
213
214  rtems_timecounter_simple_install(
215    &mpc55xx_tc,
216    reference_clock,
217    interval,
218    mpc55xx_tc_get_timecount
219  );
220}
221
222#endif
223
224#define Clock_driver_timecounter_tick() mpc55xx_tc_tick()
225#define Clock_driver_support_initialize_hardware() \
226  mpc55xx_clock_initialize()
227#define Clock_driver_support_install_isr(isr) \
228  mpc55xx_clock_handler_install(isr)
229
230/* Include shared source clock driver code */
231#include "../../../shared/dev/clock/clockimpl.h"
Note: See TracBrowser for help on using the repository browser.