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

4.115
Last change on this file since 3cd3a260 was 3cd3a260, checked in by Sebastian Huber <sebastian.huber@…>, on 12/12/14 at 15:32:58

bsp/mpc8xx: Fix warnings

close #2211

  • Property mode set to 100644
File size: 5.2 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.
[780eab4]5 */
6
7/*
[8ef3818]8 *  Author: Jay Monkman (jmonkman@frasca.com)
9 *  Copyright (C) 1998 by Frasca International, Inc.
10 *
11 *  Derived from c/src/lib/libcpu/ppc/ppc403/clock/clock.c:
12 *
13 *  Author: Andrew Bray <andy@i-cubed.co.uk>
14 *
15 *  COPYRIGHT (c) 1995 by i-cubed ltd.
16 *
17 *  To anyone who acknowledges that this file is provided "AS IS"
18 *  without any express or implied warranty:
19 *      permission to use, copy, modify, and distribute this file
20 *      for any purpose is hereby granted without fee, provided that
21 *      the above copyright notice and this notice appears in all
22 *      copies, and that the name of i-cubed limited not be used in
23 *      advertising or publicity pertaining to distribution of the
24 *      software without specific, written prior permission.
25 *      i-cubed limited makes no representations about the suitability
26 *      of this software for any purpose.
27 *
28 *  Derived from c/src/lib/libcpu/hppa1_1/clock/clock.c:
29 *
[c4cc8199]30 *  COPYRIGHT (c) 1989-2007.
[8ef3818]31 *  On-Line Applications Research Corporation (OAR).
32 *
33 *  The license and distribution terms for this file may be
34 *  found in the file LICENSE in this distribution or at
[c499856]35 *  http://www.rtems.org/license/LICENSE.
[8ef3818]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>
[3507f3f9]45#include <bsp.h>
[8ef3818]46
[66c373bf]47volatile uint32_t   Clock_driver_ticks;
[8ef3818]48extern volatile m8xx_t m8xx;
[c8bcff57]49extern int BSP_get_clock_irq_level(void);
[d1dde59]50extern uint32_t bsp_clicks_per_usec;
[8ef3818]51
52/*
[780eab4]53 *  Prototypes
[8ef3818]54 */
[780eab4]55rtems_isr Clock_isr(rtems_vector_number vector);
56void Clock_exit( void );
57void clockOn(void* unused);
58void clockOff(void* unused);
59int clockIsOn(void* unused);
60void Install_clock(rtems_isr_entry clock_isr);
61void ReInstall_clock(rtems_isr_entry new_clock_isr);
[359e537]62
[8ef3818]63/*
64 *  ISR Handler
65 */
66rtems_isr Clock_isr(rtems_vector_number vector)
67{
68  m8xx.piscr |= M8xx_PISCR_PS;
69  Clock_driver_ticks++;
70  rtems_clock_tick();
71}
72
[37731c2b]73void clockOn(void* unused)
[8ef3818]74{
[37731c2b]75  unsigned desiredLevel;
[66c373bf]76  uint32_t   pit_value;
[663e5293]77  uint32_t   extclk;
[9a73f421]78  bool force_prescaler = false;
[663e5293]79  uint32_t immr_val;
[c4cc8199]80
81  if (bsp_clicks_per_usec == 0) {
[0130f653]82    /*
83     * oscclk is too low for PIT, compute extclk and derive PIT from there
84     */
[663e5293]85    /*
86     * determine external input clock by examining the PLL settings
87     * this must be done differently depending on type of PLL
88     */
89    _mfspr(immr_val,M8xx_IMMR);
90    if (8 == ((immr_val & 0x0000FF00) >> 8)) {
91      /*
92       * for MPC866: complex PLL
93       */
94      uint32_t plprcr_val;
95      uint32_t mfn_value;
96      uint32_t mfd_value;
97      uint32_t mfi_value;
98      uint32_t pdf_value;
99      uint32_t s_value;
100
101      plprcr_val = m8xx.plprcr;
102      mfn_value  = (plprcr_val & (0xf8000000)) >> (31- 4);
103      mfd_value  = (plprcr_val & (0x07c00000)) >> (31- 9);
104      s_value    = (plprcr_val & (0x00300000)) >> (31-11);
105      mfi_value  = (plprcr_val & (0x000f0000)) >> (31-15);
106      pdf_value  = (plprcr_val & (0x00000006)) >> (31-30);
[359e537]107      extclk = (((uint64_t)bsp_clock_speed)
[780eab4]108          * ((pdf_value + 1) * (mfd_value + 1))
109          / (mfi_value * (mfd_value + 1) + mfn_value)
110          * (1 << s_value));
[663e5293]111    }
112    else {
113      /*
114       * for MPC860/850 etc: simple PLL
115       */
116      uint32_t mf_value;
117      mf_value  = m8xx.plprcr >> 20;
118      extclk    = bsp_clock_speed / (mf_value+1);
119    }
120    pit_value = (extclk
[780eab4]121       / 1000
122       / 4
123       * rtems_configuration_get_microseconds_per_tick()
124       / 1000);
[0130f653]125    m8xx.sccr |=  (1<<23);
[9a73f421]126    force_prescaler = true;
[0130f653]127  }
128  else {
129    pit_value = (rtems_configuration_get_microseconds_per_tick() *
[780eab4]130                    bsp_clicks_per_usec);
[359e537]131
[0130f653]132    m8xx.sccr &= ~(1<<23);
133  }
[780eab4]134
135  if ((pit_value > 0xffff) || force_prescaler) {
[0130f653]136    /*
137     * try to activate prescaler
138     * NOTE: divider generates odd values now...
139     */
140    pit_value = pit_value / 128;
141    m8xx.sccr |= (1<<24);
142  }
143  else {
144    m8xx.sccr &= ~(1<<24);
145  }
146
[8ef3818]147  if (pit_value > 0xffff) {           /* pit is only 16 bits long */
148    rtems_fatal_error_occurred(-1);
[37731c2b]149  }
[0130f653]150  m8xx.pitc = pit_value - 1;
[37731c2b]151
152  desiredLevel = BSP_get_clock_irq_level();
[61bd0301]153  /* set PIT irq level, enable PIT, PIT interrupts */
154  /*  and clear int. status */
[37731c2b]155  m8xx.piscr = M8xx_PISCR_PIRQ(desiredLevel) |
156    M8xx_PISCR_PTE | M8xx_PISCR_PS | M8xx_PISCR_PIE;
[8ef3818]157}
[780eab4]158
[37731c2b]159/*
160 * Called via atexit()
161 * Remove the clock interrupt handler by setting handler to NULL
162 */
[780eab4]163void clockOff(void* unused)
[8ef3818]164{
[37731c2b]165  /* disable PIT and PIT interrupts */
[359e537]166  m8xx.piscr &= ~(M8xx_PISCR_PTE | M8xx_PISCR_PIE);
[8ef3818]167}
168
[37731c2b]169int clockIsOn(void* unused)
170{
[780eab4]171  if (m8xx.piscr & M8xx_PISCR_PIE)
172    return 1;
[37731c2b]173  return 0;
174}
[8ef3818]175
176/*
177 * Called via atexit()
178 * Remove the clock interrupt handler by setting handler to NULL
179 */
[780eab4]180void Clock_exit(void)
[8ef3818]181{
[37731c2b]182  (void) BSP_disconnect_clock_handler ();
[8ef3818]183}
184
[37731c2b]185void Install_clock(rtems_isr_entry clock_isr)
186{
187  Clock_driver_ticks = 0;
188
189  BSP_connect_clock_handler (clock_isr);
190  atexit(Clock_exit);
191}
192
[780eab4]193void ReInstall_clock(rtems_isr_entry new_clock_isr)
[37731c2b]194{
195  BSP_connect_clock_handler (new_clock_isr);
196}
197
[8ef3818]198rtems_device_driver Clock_initialize(
199  rtems_device_major_number major,
200  rtems_device_minor_number minor,
201  void *pargp
202)
203{
204  Install_clock( Clock_isr );
[359e537]205
[8ef3818]206  return RTEMS_SUCCESSFUL;
207}
Note: See TracBrowser for help on using the repository browser.