source: rtems/c/src/lib/libcpu/powerpc/mpc8xx/clock/clock.c @ e1df032

4.104.114.95
Last change on this file since e1df032 was e1df032, checked in by Till Straumann <strauman@…>, on 07/10/08 at 21:51:55

2008-07-10 Till Straumann <strauman@…>

  • ChangeLog?, mpc8xx/clock/clock.c, ppc403/clock/clock.c, ppc403/irq/ictrl.h, rtems/powerpc/powerpc.h: Removed all macro definitions which depended on the compiler defining a PPC CPU-model dependent symbol from files in cpukit. Macros which were not used by cpukit have been moved to libcpu/powerpc/rtems/powerpc/powerpc.h.
  • Property mode set to 100644
File size: 4.9 KB
RevLine 
[8ef3818]1/*  clock.c
2 *
3 *  This routine initializes the PIT on the MPC8xx.
4 *  The tick frequency is specified by the bsp.
5 *
6 *  Author: Jay Monkman (jmonkman@frasca.com)
7 *  Copyright (C) 1998 by Frasca International, Inc.
8 *
9 *  Derived from c/src/lib/libcpu/ppc/ppc403/clock/clock.c:
10 *
11 *  Author: Andrew Bray <andy@i-cubed.co.uk>
12 *
13 *  COPYRIGHT (c) 1995 by i-cubed ltd.
14 *
15 *  To anyone who acknowledges that this file is provided "AS IS"
16 *  without any express or implied warranty:
17 *      permission to use, copy, modify, and distribute this file
18 *      for any purpose is hereby granted without fee, provided that
19 *      the above copyright notice and this notice appears in all
20 *      copies, and that the name of i-cubed limited not be used in
21 *      advertising or publicity pertaining to distribution of the
22 *      software without specific, written prior permission.
23 *      i-cubed limited makes no representations about the suitability
24 *      of this software for any purpose.
25 *
26 *  Derived from c/src/lib/libcpu/hppa1_1/clock/clock.c:
27 *
[c4cc8199]28 *  COPYRIGHT (c) 1989-2007.
[8ef3818]29 *  On-Line Applications Research Corporation (OAR).
30 *
31 *  The license and distribution terms for this file may be
32 *  found in the file LICENSE in this distribution or at
[21e1c44]33 *  http://www.rtems.com/license/LICENSE.
[8ef3818]34 *
35 *  $Id$
36 */
37
[61bd0301]38#include <rtems.h>
[11c2382]39#include <rtems/clockdrv.h>
[8ef3818]40#include <rtems/libio.h>
[e1df032]41#include <rtems/powerpc/powerpc.h>
[8ef3818]42
43#include <stdlib.h>                     /* for atexit() */
44#include <mpc8xx.h>
45
[66c373bf]46volatile uint32_t   Clock_driver_ticks;
[8ef3818]47extern volatile m8xx_t m8xx;
[37731c2b]48extern int BSP_get_clock_irq_level();
49extern int BSP_connect_clock_handler(rtems_isr_entry);
50extern int BSP_disconnect_clock_handler();
[8ef3818]51
52void Clock_exit( void );
[37731c2b]53
[8ef3818]54/*
55 * These are set by clock driver during its init
56 */
57 
58rtems_device_major_number rtems_clock_major = ~0;
59rtems_device_minor_number rtems_clock_minor;
60 
61/*
62 *  ISR Handler
63 */
64rtems_isr Clock_isr(rtems_vector_number vector)
65{
66  m8xx.piscr |= M8xx_PISCR_PS;
67  Clock_driver_ticks++;
68  rtems_clock_tick();
69}
70
[37731c2b]71void clockOn(void* unused)
[8ef3818]72{
[37731c2b]73  unsigned desiredLevel;
[66c373bf]74  uint32_t   pit_value;
[fb6bc245]75  uint32_t mf_value;
[0130f653]76  rtems_boolean force_prescaler = FALSE;
[c4cc8199]77  extern uint32_t bsp_clicks_per_usec;
78  extern uint32_t bsp_clock_speed;
79
80  if (bsp_clicks_per_usec == 0) {
[0130f653]81    /*
82     * oscclk is too low for PIT, compute extclk and derive PIT from there
83     */
84    mf_value  = m8xx.plprcr >> 20;   
[c4cc8199]85    pit_value = (bsp_clock_speed
[0130f653]86                 / (mf_value+1)
87                 / 1000
88                 / 4
89                 * rtems_configuration_get_microseconds_per_tick()
90                 / 1000);
91    m8xx.sccr |=  (1<<23);
92    force_prescaler = TRUE;
93  }
94  else {
95    pit_value = (rtems_configuration_get_microseconds_per_tick() *
[c4cc8199]96                 bsp_clicks_per_usec);
[8ef3818]97 
[0130f653]98    m8xx.sccr &= ~(1<<23);
99  }
100if ((pit_value > 0xffff) || force_prescaler){
101    /*
102     * try to activate prescaler
103     * NOTE: divider generates odd values now...
104     */
105    pit_value = pit_value / 128;
106    m8xx.sccr |= (1<<24);
107  }
108  else {
109    m8xx.sccr &= ~(1<<24);
110  }
111
[8ef3818]112  if (pit_value > 0xffff) {           /* pit is only 16 bits long */
113    rtems_fatal_error_occurred(-1);
[37731c2b]114  }
[0130f653]115  m8xx.pitc = pit_value - 1;
[37731c2b]116
117  desiredLevel = BSP_get_clock_irq_level();
[61bd0301]118  /* set PIT irq level, enable PIT, PIT interrupts */
119  /*  and clear int. status */
[37731c2b]120  m8xx.piscr = M8xx_PISCR_PIRQ(desiredLevel) |
121    M8xx_PISCR_PTE | M8xx_PISCR_PS | M8xx_PISCR_PIE;
[8ef3818]122}
[37731c2b]123/*
124 * Called via atexit()
125 * Remove the clock interrupt handler by setting handler to NULL
126 */
[8ef3818]127void
[37731c2b]128clockOff(void* unused)
[8ef3818]129{
[37731c2b]130  /* disable PIT and PIT interrupts */
131  m8xx.piscr &= ~(M8xx_PISCR_PTE | M8xx_PISCR_PIE);
[8ef3818]132}
133
[37731c2b]134int clockIsOn(void* unused)
135{
136  if (m8xx.piscr & M8xx_PISCR_PIE) return 1;
137  return 0;
138}
[8ef3818]139
140/*
141 * Called via atexit()
142 * Remove the clock interrupt handler by setting handler to NULL
143 */
144void
145Clock_exit(void)
146{
[37731c2b]147  (void) BSP_disconnect_clock_handler ();
[8ef3818]148}
149
[37731c2b]150void Install_clock(rtems_isr_entry clock_isr)
151{
152  Clock_driver_ticks = 0;
153
154  BSP_connect_clock_handler (clock_isr);
155  atexit(Clock_exit);
156}
157
158void
159ReInstall_clock(rtems_isr_entry new_clock_isr)
160{
161  BSP_connect_clock_handler (new_clock_isr);
162}
163
164
[8ef3818]165rtems_device_driver Clock_initialize(
166  rtems_device_major_number major,
167  rtems_device_minor_number minor,
168  void *pargp
169)
170{
171  Install_clock( Clock_isr );
[37731c2b]172 
[8ef3818]173  /*
174   * make major/minor avail to others such as shared memory driver
175   */
176 
177  rtems_clock_major = major;
178  rtems_clock_minor = minor;
179 
180  return RTEMS_SUCCESSFUL;
181}
182 
183rtems_device_driver Clock_control(
184  rtems_device_major_number major,
185  rtems_device_minor_number minor,
186  void *pargp
187)
188{
189  rtems_libio_ioctl_args_t *args = pargp;
190 
191  if (args == 0)
192    goto done;
193 
194  /*
195   * This is hokey, but until we get a defined interface
196   * to do this, it will just be this simple...
197   */
198 
199  if (args->command == rtems_build_name('I', 'S', 'R', ' ')) {
200    Clock_isr(PPC_IRQ_LVL0);
201  }
202  else if (args->command == rtems_build_name('N', 'E', 'W', ' ')) {
203    ReInstall_clock(args->buffer);
204  }
205 
206 done:
207  return RTEMS_SUCCESSFUL;
208}
Note: See TracBrowser for help on using the repository browser.