source: rtems/c/src/lib/libbsp/powerpc/gen5200/clock/clock.c @ 1c79f01

4.104.115
Last change on this file since 1c79f01 was 1c79f01, checked in by Joel Sherrill <joel.sherrill@…>, on 09/16/08 at 19:05:48

2008-09-16 Joel Sherrill <joel.sherrill@…>

  • clock/clock.c, startup/bspstart.c: Remove unnecessary includes of rtems/libcsupport.h and rtems/libio.h.
  • Property mode set to 100644
File size: 12.9 KB
Line 
1/*===============================================================*\
2| Project: RTEMS generic MPC5200 BSP                              |
3+-----------------------------------------------------------------+
4| Partially based on the code references which are named below.   |
5| Adaptions, modifications, enhancements and any recent parts of  |
6| the code are:                                                   |
7|                    Copyright (c) 2005                           |
8|                    Embedded Brains GmbH                         |
9|                    Obere Lagerstr. 30                           |
10|                    D-82178 Puchheim                             |
11|                    Germany                                      |
12|                    rtems@embedded-brains.de                     |
13|                                                                 |
14| Reworked by Joel Sherrill to use clockdrv_shell.c               |
15+-----------------------------------------------------------------+
16| The license and distribution terms for this file may be         |
17| found in the file LICENSE in this distribution or at            |
18|                                                                 |
19| http://www.rtems.com/license/LICENSE.                           |
20|                                                                 |
21+-----------------------------------------------------------------+
22| this file contains the clock driver functions                   |
23\*===============================================================*/
24/***********************************************************************/
25/*                                                                     */
26/*   Module:       clock.c                                             */
27/*   Date:         07/17/2003                                          */
28/*   Purpose:      RTEMS MPC5x00 clock driver                          */
29/*                                                                     */
30/*---------------------------------------------------------------------*/
31/*                                                                     */
32/*   Description:  Use one of the GPTs for time base generation        */
33/*                 instead of the decrementer. The routine initializes */
34/*                 the General Purpose Timer GPT6 on the MPC5x00.      */
35/*                 The tick frequency is specified by the bsp.         */
36/*                                                                     */
37/*---------------------------------------------------------------------*/
38/*                                                                     */
39/*   Code                                                              */
40/*   References:   Clock driver for PPC403                             */
41/*   Module:       clock.c                                             */
42/*   Project:      RTEMS 4.6.0pre1 / PPC403 BSP                        */
43/*   Version       1.16                                                */
44/*   Date:         2002/11/01                                          */
45/*   Author(s) / Copyright(s):                                         */
46/*                                                                     */
47/*   Author: Jay Monkman (jmonkman@frasca.com)                         */
48/*   Copyright (C) 1998 by Frasca International, Inc.                  */
49/*                                                                     */
50/*   Derived from c/src/lib/libcpu/ppc/ppc403/clock/clock.c:           */
51/*                                                                     */
52/*   Author: Andrew Bray <andy@i-cubed.co.uk>                          */
53/*                                                                     */
54/*   COPYRIGHT (c) 1995 by i-cubed ltd.                                */
55/*                                                                     */
56/*   To anyone who acknowledges that this file is provided "AS IS"     */
57/*   without any express or implied warranty:                          */
58/*      permission to use, copy, modify, and distribute this file      */
59/*      for any purpose is hereby granted without fee, provided that   */
60/*      the above copyright notice and this notice appears in all      */
61/*      copies, and that the name of i-cubed limited not be used in    */
62/*      advertising or publicity pertaining to distribution of the     */
63/*      software without specific, written prior permission.           */
64/*      i-cubed limited makes no representations about the suitability */
65/*      of this software for any purpose.                              */
66/*                                                                     */
67/*   Derived from c/src/lib/libcpu/hppa1.1/clock/clock.c:              */
68/*                                                                     */
69/*   Modifications for deriving timer clock from cpu system clock by   */
70/*              Thomas Doerfler <td@imd.m.isar.de>                     */
71/*   for these modifications:                                          */
72/*   COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.                     */
73/*                                                                     */
74/*   COPYRIGHT (c) 1989-2007.                                          */
75/*   On-Line Applications Research Corporation (OAR).                  */
76/*                                                                     */
77/*   The license and distribution terms for this file may be           */
78/*   found in the file LICENSE in this distribution or at              */
79/*   http://www.rtems.com/license/LICENSE.                             */
80/*                                                                     */
81/*   Modifications for PPC405GP by Dennis Ehlin                        */
82/*---------------------------------------------------------------------*/
83/*                                                                     */
84/*   Partially based on the code references which are named above.     */
85/*   Adaptions, modifications, enhancements and any recent parts of    */
86/*   the code are under the right of                                   */
87/*                                                                     */
88/*         IPR Engineering, Dachauer Straße 38, D-80335 MÃŒnchen        */
89/*                        Copyright(C) 2003                            */
90/*                                                                     */
91/*---------------------------------------------------------------------*/
92/*                                                                     */
93/*   IPR Engineering makes no representation or warranties with        */
94/*   respect to the performance of this computer program, and          */
95/*   specifically disclaims any responsibility for any damages,        */
96/*   special or consequential, connected with the use of this program. */
97/*                                                                     */
98/*---------------------------------------------------------------------*/
99/*                                                                     */
100/*   Version history:  1.0                                             */
101/*                                                                     */
102/***********************************************************************/
103
104#include <bsp.h>
105#include <rtems/bspIo.h>
106#include <bsp/irq.h>
107
108#include <rtems.h>
109#include <rtems/clockdrv.h>
110
111#include <stdlib.h>                     /* for atexit() */
112#include "../include/mpc5200.h"
113
114#define GPT (BSP_PERIODIC_TIMER - BSP_SIU_IRQ_TMR0)
115
116extern uint32_t bsp_clicks_per_usec;
117
118/* this lets us do nanoseconds since last tick */
119uint64_t Clock_last_TBR;
120volatile uint32_t counter_value;
121volatile int ClockInitialized = 0;
122
123/*
124 *  ISR Handlers
125 */
126void mpc5200_gpt_clock_isr(rtems_vector_number vector, void *handle)
127{
128  uint32_t status;
129  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)handle;
130
131  status = gpt->status;
132
133  if (ClockInitialized  && (status & GPT_STATUS_TEXP)) {
134    gpt->status |= GPT_STATUS_RESET;
135    Clock_last_TBR = PPC_Get_timebase_register();
136
137    Clock_driver_ticks++;
138    rtems_clock_tick();
139  }
140}
141
142/*
143 *  Initialize MPC5x00 GPT
144 */
145void mpc5200_init_gpt(uint32_t gpt_no)
146{
147  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[gpt_no]);
148
149  gpt->status = GPT_STATUS_RESET;
150  gpt->emsel  = GPT_EMSEL_CE | GPT_EMSEL_ST_CONT | GPT_EMSEL_INTEN |
151                GPT_EMSEL_GPIO_OUT_HIGH | GPT_EMSEL_TIMER_MS_GPIO;
152
153}
154
155/*
156 *  Set MPC5x00 GPT counter
157 */
158void mpc5200_set_gpt_count(uint32_t counter_value, uint32_t gpt_no)
159{
160  uint32_t prescaler_value = 1;
161  uint32_t counter = counter_value;
162  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[gpt_no]);
163
164  /* Calculate counter/prescaler value, e.g.
165   *   IPB_Clock=33MHz -> Int. every 0,3 nsecs. - 130 secs
166   */
167  while ((counter >= (1 << 16)) && (prescaler_value < (1 << 16))) {
168    prescaler_value++;
169    counter = counter_value / prescaler_value;
170  }
171
172  counter = (uint16_t)counter;
173
174  gpt->count_in = (prescaler_value << 16) + counter;
175
176}
177
178uint32_t bsp_clock_nanoseconds_since_last_tick(void)
179{
180  uint64_t new_tbr;
181  uint64_t bus_cycles;
182  uint32_t nsecs;
183
184  new_tbr = PPC_Get_timebase_register();
185  bus_cycles = (new_tbr - Clock_last_TBR) * 4;
186  nsecs =  (uint32_t) (bus_cycles / (XLB_CLOCK / 1000000)) * 1000;
187
188  return nsecs;
189}
190
191/*
192 *  Enable MPC5x00 GPT interrupt
193 */
194void mpc5200_enable_gpt_int(uint32_t gpt_no)
195{
196  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[gpt_no]);
197
198  gpt->emsel |= GPT_EMSEL_CE | GPT_EMSEL_INTEN;
199  Clock_last_TBR = PPC_Get_timebase_register();
200}
201
202/*
203 *  Disable MPC5x00 GPT interrupt
204 */
205void mpc5200_disable_gpt_int(uint32_t gpt_no)
206{
207  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[gpt_no]);
208
209  gpt->emsel &= ~(GPT_EMSEL_CE | GPT_EMSEL_INTEN);
210}
211
212/*
213 *  Check MPC5x00 GPT status
214 */
215uint32_t mpc5200_check_gpt_status(uint32_t gpt_no)
216{
217  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[gpt_no]);
218
219  return ((gpt->emsel) & (GPT_EMSEL_CE | GPT_EMSEL_INTEN));
220}
221
222void clockOn()
223{
224  uint32_t gpt_no;
225
226  gpt_no = BSP_SIU_IRQ_TMR0 - BSP_PERIODIC_TIMER;
227
228  counter_value = rtems_configuration_get_microseconds_per_tick() *
229                      bsp_clicks_per_usec;
230
231  mpc5200_set_gpt_count(counter_value, gpt_no);
232  mpc5200_enable_gpt_int(gpt_no);
233
234  ClockInitialized = 1;
235}
236
237void clockOff()
238{
239  uint32_t gpt_no;
240
241  gpt_no = BSP_SIU_IRQ_TMR0 - BSP_PERIODIC_TIMER;
242
243  mpc5200_disable_gpt_int(gpt_no);
244
245  ClockInitialized = 0;
246}
247
248int BSP_get_clock_irq_level(void)
249{
250  /*
251   * Caution : if you change this, you must change the
252   * definition of BSP_PERIODIC_TIMER accordingly
253    */
254  return BSP_PERIODIC_TIMER;
255}
256
257int BSP_disconnect_clock_handler (unsigned gpt_no)
258{
259  rtems_status_code sc = RTEMS_SUCCESSFUL;
260
261  if ((gpt_no < GPT0) || (gpt_no > GPT7)) {
262    return 0;
263  }
264
265  clockOff( BSP_PERIODIC_TIMER);
266
267  sc = rtems_interrupt_handler_remove(
268    BSP_PERIODIC_TIMER,
269    mpc5200_gpt_clock_isr,
270    &mpc5200.gpt [gpt_no]
271  );
272  if (sc != RTEMS_SUCCESSFUL) {
273    return 0;
274  }
275
276  return 1;
277}
278
279int BSP_connect_clock_handler (unsigned gpt_no)
280{
281  rtems_status_code sc = RTEMS_SUCCESSFUL;
282
283  if ((gpt_no < GPT0) || (gpt_no > GPT7)) {
284    printk("Unable to set system clock handler\n");
285    rtems_fatal_error_occurred(1);
286  }
287
288  sc = rtems_interrupt_handler_install(
289    BSP_PERIODIC_TIMER,
290    "Clock",
291    RTEMS_INTERRUPT_UNIQUE,
292    mpc5200_gpt_clock_isr,
293    &mpc5200.gpt [gpt_no]
294  );
295  if (sc != RTEMS_SUCCESSFUL) {
296    return 0;
297  }
298
299  clockOn();
300
301  return 1;
302}
303
304#define CLOCK_VECTOR 0
305
306#define Clock_driver_support_at_tick()                                   \
307  do {                                                                   \
308    uint32_t status;                                                     \
309    struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[GPT]); \
310    \
311    status = gpt->status;                                                \
312    \
313    if (ClockInitialized  && (status & GPT_STATUS_TEXP)) {               \
314      gpt->status |= GPT_STATUS_RESET;                                   \
315      Clock_last_TBR = PPC_Get_timebase_register();                      \
316    }                                                                    \
317  } while(0)
318
319#define Clock_driver_support_install_isr( _new, _old ) \
320  do {                                                 \
321      (_old) = NULL; /* avoid warning */;              \
322      BSP_connect_clock_handler(GPT);                  \
323  } while(0)
324
325/* This driver does this in clockOn called at connection time */
326#define Clock_driver_support_initialize_hardware() \
327  do {        \
328    counter_value = rtems_configuration_get_microseconds_per_tick() * \
329                    bsp_clicks_per_usec; \
330    mpc5200_init_gpt(GPT); \
331    mpc5200_set_gpt_count(counter_value, GPT); \
332  } while (0)
333
334#define Clock_driver_nanoseconds_since_last_tick \
335    bsp_clock_nanoseconds_since_last_tick
336
337#define Clock_driver_support_shutdown_hardware() \
338  do { \
339    (void) BSP_disconnect_clock_handler (GPT); \
340  } while (0)
341
342#include "../../../shared/clockdrv_shell.c"
343
Note: See TracBrowser for help on using the repository browser.