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

4.104.114.84.95
Last change on this file since d3b05790 was 7da3405, checked in by Joel Sherrill <joel.sherrill@…>, on 06/20/07 at 21:42:00

2007-06-20 Joel Sherrill <joel.sherrill@…>

Add Embedded Planets EP5200 which is the same as the Freescale
5200Lite (a.k.a. IceCube?) evaluation board.

  • Makefile.am: Add linkcmds.ep5200. Add -DMPC5200_BAPI_LIBC_HEADERS to remove some warnings in bestcomm.
  • preinstall.am: Add linkcmds.ep5200.
  • clock/clock.c: Correct math for prescaler/counter when bus speed is high enough to require multiple passes of loop.
  • console/console.c: Use same math for initial baud rate as when it is changed via ioctl. When HAS_UBOOT is defined, initialize console to the same baud as it was with U-Boot.
  • include/bsp.h: Add EP5200 and console boot baud support.
  • include/mpc5200.h: Spacing.
  • startup/bspstart.c: If HAS_UBOOT and SHOW_MORE_INIT_SETTINGS are both defined, dump the U-Boot BD info structure.
  • vectors/vectors.S: ep5200 cannot use vectors segment. When loading it, U-Boot freezes. Besides, U-Boot can automatically start the BSP so we do not have to run from board reset.
  • startup/linkcmds.ep5200: New file.
  • Property mode set to 100644
File size: 13.7 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| The license and distribution terms for this file may be         |
15| found in the file LICENSE in this distribution or at            |
16|                                                                 |
17| http://www.rtems.com/license/LICENSE.                           |
18|                                                                 |
19+-----------------------------------------------------------------+
20| this file contains the clock driver functions                   |
21\*===============================================================*/
22/***********************************************************************/
23/*                                                                     */
24/*   Module:       clock.c                                             */
25/*   Date:         07/17/2003                                          */
26/*   Purpose:      RTEMS MPC5x00 clock driver                          */
27/*                                                                     */
28/*---------------------------------------------------------------------*/
29/*                                                                     */
30/*   Description:  Use one of the GPTs for time base generation        */
31/*                 instead of the decrementer. The routine initializes */
32/*                 the General Purpose Timer GPT6 on the MPC5x00.      */
33/*                 The tick frequency is specified by the bsp.         */
34/*                                                                     */
35/*---------------------------------------------------------------------*/
36/*                                                                     */
37/*   Code                                                              */
38/*   References:   Clock driver for PPC403                             */
39/*   Module:       clock.c                                             */
40/*   Project:      RTEMS 4.6.0pre1 / PPC403 BSP                        */
41/*   Version       1.16                                                */
42/*   Date:         2002/11/01                                          */
43/*   Author(s) / Copyright(s):                                         */
44/*                                                                     */
45/*   Author: Jay Monkman (jmonkman@frasca.com)                         */
46/*   Copyright (C) 1998 by Frasca International, Inc.                  */
47/*                                                                     */
48/*   Derived from c/src/lib/libcpu/ppc/ppc403/clock/clock.c:           */
49/*                                                                     */
50/*   Author: Andrew Bray <andy@i-cubed.co.uk>                          */
51/*                                                                     */
52/*   COPYRIGHT (c) 1995 by i-cubed ltd.                                */
53/*                                                                     */
54/*   To anyone who acknowledges that this file is provided "AS IS"     */
55/*   without any express or implied warranty:                          */
56/*      permission to use, copy, modify, and distribute this file      */
57/*      for any purpose is hereby granted without fee, provided that   */
58/*      the above copyright notice and this notice appears in all      */
59/*      copies, and that the name of i-cubed limited not be used in    */
60/*      advertising or publicity pertaining to distribution of the     */
61/*      software without specific, written prior permission.           */
62/*      i-cubed limited makes no representations about the suitability */
63/*      of this software for any purpose.                              */
64/*                                                                     */
65/*   Derived from c/src/lib/libcpu/hppa1.1/clock/clock.c:              */
66/*                                                                     */
67/*   Modifications for deriving timer clock from cpu system clock by   */
68/*              Thomas Doerfler <td@imd.m.isar.de>                     */
69/*   for these modifications:                                          */
70/*   COPYRIGHT (c) 1997 by IMD, Puchheim, Germany.                     */
71/*                                                                     */
72/*   COPYRIGHT (c) 1989-1999.                                          */
73/*   On-Line Applications Research Corporation (OAR).                  */
74/*                                                                     */
75/*   The license and distribution terms for this file may be           */
76/*   found in the file LICENSE in this distribution or at              */
77/*   http://www.rtems.com/license/LICENSE.                        */
78/*                                                                     */
79/*   Modifications for PPC405GP by Dennis Ehlin                        */
80/*---------------------------------------------------------------------*/
81/*                                                                     */
82/*   Partially based on the code references which are named above.     */
83/*   Adaptions, modifications, enhancements and any recent parts of    */
84/*   the code are under the right of                                   */
85/*                                                                     */
86/*         IPR Engineering, Dachauer Straße 38, D-80335 MÃŒnchen        */
87/*                        Copyright(C) 2003                            */
88/*                                                                     */
89/*---------------------------------------------------------------------*/
90/*                                                                     */
91/*   IPR Engineering makes no representation or warranties with        */
92/*   respect to the performance of this computer program, and          */
93/*   specifically disclaims any responsibility for any damages,        */
94/*   special or consequential, connected with the use of this program. */
95/*                                                                     */
96/*---------------------------------------------------------------------*/
97/*                                                                     */
98/*   Version history:  1.0                                             */
99/*                                                                     */
100/***********************************************************************/
101
102#include <bsp.h>
103#include <rtems/bspIo.h>
104#include "../irq/irq.h"
105
106#include <rtems.h>
107#include <rtems/clockdrv.h>
108#include <rtems/libio.h>
109
110#include <stdlib.h>                     /* for atexit() */
111#include "../include/mpc5200.h"
112
113volatile uint32_t Clock_driver_ticks;
114
115void Clock_exit(void);
116
117uint32_t counter_value;
118
119volatile int ClockInitialized = 0;
120
121
122/*
123 * These are set by clock driver during its init
124 */
125rtems_device_major_number rtems_clock_major = ~0;
126rtems_device_minor_number rtems_clock_minor;
127
128
129/*
130 *  ISR Handlers
131 */
132void mpc5200_gpt_clock_isr(rtems_irq_hdl_param handle)
133  {
134  uint32_t status;
135  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)handle;
136
137  status = gpt->status;
138
139
140  if(ClockInitialized  && (status & GPT_STATUS_TEXP))
141    {
142
143    gpt->status |= GPT_STATUS_TEXP;
144
145
146    Clock_driver_ticks++;
147    rtems_clock_tick();
148
149    }
150
151  }
152
153
154/*
155 *  Initialize MPC5x00 GPT
156 */
157void mpc5200_init_gpt(uint32_t gpt_no)
158  {
159  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[gpt_no]);
160
161  gpt->status = GPT_STATUS_RESET;
162  gpt->emsel  = GPT_EMSEL_CE | GPT_EMSEL_ST_CONT | GPT_EMSEL_INTEN | GPT_EMSEL_GPIO_OUT_HIGH | GPT_EMSEL_TIMER_MS_GPIO;
163
164  }
165
166
167/*
168 *  Set MPC5x00 GPT counter
169 */
170void mpc5200_set_gpt_count(uint32_t counter_value, uint32_t gpt_no)
171  {
172  uint32_t prescaler_value = 1;
173  uint32_t counter = counter_value;
174  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[gpt_no]);
175
176  /* Calculate counter/prescaler value, e.g. IPB_Clock=33MHz -> Int. every 0,3 nsecs. - 130 secs.*/
177  while((counter >= (1 << 16)) && (prescaler_value < (1 << 16)))
178    {
179      prescaler_value++;
180      counter = counter_value / prescaler_value;
181    }
182
183  counter = (uint16_t)counter;
184
185  gpt->count_in = (prescaler_value << 16) + counter;
186
187  }
188
189
190/*
191 *  Enable MPC5x00 GPT interrupt
192 */
193void mpc5200_enable_gpt_int(uint32_t gpt_no)
194  {
195  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[gpt_no]);
196
197  gpt->emsel |= GPT_EMSEL_CE | GPT_EMSEL_INTEN;
198
199  }
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
214/*
215 *  Check MPC5x00 GPT status
216 */
217uint32_t mpc5200_check_gpt_status(uint32_t gpt_no)
218  {
219  struct mpc5200_gpt *gpt = (struct mpc5200_gpt *)(&mpc5200.gpt[gpt_no]);
220
221  return ((gpt->emsel) & (GPT_EMSEL_CE | GPT_EMSEL_INTEN));
222
223  }
224
225
226void clockOn(const rtems_irq_connect_data* irq)
227  {
228  uint32_t gpt_no;
229
230
231  gpt_no = BSP_SIU_IRQ_TMR0 - (irq->name);
232
233  counter_value = rtems_configuration_get_microseconds_per_tick() *
234                      rtems_cpu_configuration_get_clicks_per_usec();
235
236  mpc5200_set_gpt_count(counter_value, (uint32_t)gpt_no);
237  mpc5200_enable_gpt_int((uint32_t)gpt_no);
238
239  Clock_driver_ticks = 0;
240  ClockInitialized = 1;
241
242  }
243
244
245void clockOff(const rtems_irq_connect_data* irq)
246  {
247  uint32_t gpt_no;
248
249  gpt_no = BSP_SIU_IRQ_TMR0 - (irq->name);
250
251  mpc5200_disable_gpt_int((uint32_t)gpt_no);
252
253  ClockInitialized = 0;
254
255  }
256
257
258int clockIsOn(const rtems_irq_connect_data* irq)
259  {
260  uint32_t gpt_no;
261
262  gpt_no = BSP_SIU_IRQ_TMR0 - (irq->name);
263
264  if(mpc5200_check_gpt_status(gpt_no) && ClockInitialized)
265    return ClockInitialized;
266  else
267    return 0;
268  }
269
270
271int BSP_get_clock_irq_level()
272  {
273
274  /*
275   * Caution : if you change this, you must change the
276   * definition of BSP_PERIODIC_TIMER accordingly
277    */
278  return BSP_PERIODIC_TIMER;
279  }
280
281
282int BSP_disconnect_clock_handler (void)
283  {
284  rtems_irq_connect_data clockIrqData;
285  clockIrqData.name   = BSP_PERIODIC_TIMER;
286
287
288  if (!BSP_get_current_rtems_irq_handler(&clockIrqData))
289    {
290
291    printk("Unable to stop system clock\n");
292    rtems_fatal_error_occurred(1);
293
294    }
295
296  return BSP_remove_rtems_irq_handler (&clockIrqData);
297
298  }
299
300
301int BSP_connect_clock_handler (uint32_t gpt_no)
302  {
303
304  rtems_irq_hdl hdl = 0;
305  rtems_irq_connect_data clockIrqData;
306
307
308  /*
309   * Reinit structure
310   */
311
312  clockIrqData.name   = BSP_PERIODIC_TIMER;
313
314  if(!BSP_get_current_rtems_irq_handler(&clockIrqData))
315    {
316
317    printk("Unable to get system clock handler\n");
318    rtems_fatal_error_occurred(1);
319
320    }
321
322  if(!BSP_remove_rtems_irq_handler (&clockIrqData))
323    {
324
325    printk("Unable to remove current system clock handler\n");
326    rtems_fatal_error_occurred(1);
327
328    }
329
330  if ((gpt_no >= GPT0) ||
331      (gpt_no <= GPT7)) {
332    hdl = (rtems_irq_hdl_param )&mpc5200.gpt[gpt_no];
333  }
334  else {
335    printk("Unable to set system clock handler\n");
336    rtems_fatal_error_occurred(1);
337  }
338
339  clockIrqData.hdl    = mpc5200_gpt_clock_isr;
340  clockIrqData.handle = (rtems_irq_hdl_param) hdl;
341  clockIrqData.on     = clockOn;
342  clockIrqData.off    = clockOff;
343  clockIrqData.isOn   = clockIsOn;
344
345  return BSP_install_rtems_irq_handler (&clockIrqData);
346
347  }
348
349
350/*
351 * Called via atexit()
352 * Remove the clock interrupt handler by setting handler to NULL
353 */
354void Clock_exit(void)
355  {
356
357  (void) BSP_disconnect_clock_handler ();
358
359  }
360
361
362void Install_clock(rtems_device_minor_number gpt_no)
363  {
364
365  Clock_driver_ticks = 0;
366
367  counter_value = rtems_configuration_get_microseconds_per_tick() *
368                      rtems_cpu_configuration_get_clicks_per_usec();
369
370  mpc5200_init_gpt((uint32_t)gpt_no);
371  mpc5200_set_gpt_count(counter_value, (uint32_t)gpt_no);
372
373
374  BSP_connect_clock_handler(gpt_no);
375
376  ClockInitialized = 1;
377
378  atexit(Clock_exit);
379
380  }
381
382void ReInstall_clock(uint32_t gpt_no)
383  {
384
385  BSP_connect_clock_handler(gpt_no);
386
387  }
388
389
390rtems_device_driver Clock_initialize
391  (
392  rtems_device_major_number major,
393  rtems_device_minor_number minor,
394  void *pargp
395  )
396  {
397  /* force minor according to definitions in irq.h */
398  minor = BSP_PERIODIC_TIMER - BSP_SIU_IRQ_TMR0;
399
400  Install_clock((uint32_t)minor);
401
402  /*
403   * make major/minor avail to others such as shared memory driver
404   */
405  rtems_clock_major = major;
406  rtems_clock_minor = minor;
407
408  return RTEMS_SUCCESSFUL;
409
410  }
411
412rtems_device_driver Clock_control
413  (
414  rtems_device_major_number major,
415  rtems_device_minor_number minor,
416  void *pargp
417  )  {
418
419  rtems_libio_ioctl_args_t *args = pargp;
420
421  /* forec minor according to definitions in irq.h */
422  minor = BSP_PERIODIC_TIMER - BSP_SIU_IRQ_TMR0;
423
424  if(args != 0) {
425    /*
426     * This is hokey, but until we get a defined interface
427     * to do this, it will just be this simple...
428     */
429    if(args->command == rtems_build_name('I', 'S', 'R', ' ')) {
430      if ((minor >= GPT0) ||
431          (minor <= GPT7)) {
432        mpc5200_gpt_clock_isr((rtems_irq_hdl_param )&mpc5200.gpt[minor]);
433      }
434      else {
435        printk("Unable to call system clock handler\n");
436        rtems_fatal_error_occurred(1);
437      }
438    }
439    else if(args->command == rtems_build_name('N', 'E', 'W', ' ')) {
440      ReInstall_clock((uint32_t)minor);
441    }
442  }
443  return RTEMS_SUCCESSFUL;
444
445}
Note: See TracBrowser for help on using the repository browser.