source: rtems/c/src/lib/libbsp/powerpc/mpc55xxevb/clock/clock-config.c @ a4475277

4.115
Last change on this file since a4475277 was a4475277, checked in by Sebastian Huber <sebastian.huber@…>, on 06/07/11 at 09:14:06

2011-06-07 Sebastian Huber <sebastian.huber@…>

  • clock/clock-config.c: Fixes to pass psnsext01.
  • startup/bspstart.c: Workaround for GCC 4.6 bug.
  • include/smsc9218i.h, network/smsc9218i.c, Makefile.am: Changes throughout.
  • Property mode set to 100644
File size: 4.1 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup mpc55xx
5 *
6 * @brief Clock driver configuration.
7 */
8
9/*
10 * Copyright (c) 2009
11 * embedded brains GmbH
12 * Obere Lagerstr. 30
13 * D-82178 Puchheim
14 * Germany
15 * <rtems@embedded-brains.de>
16 *
17 * The license and distribution terms for this file may be
18 * found in the file LICENSE in this distribution or at
19 * http://www.rtems.com/license/LICENSE.
20 */
21
22#include <mpc55xx/regs.h>
23#include <mpc55xx/emios.h>
24
25#include <rtems.h>
26
27#include <bsp.h>
28#include <bsp/irq.h>
29
30#define RTEMS_STATUS_CHECKS_USE_PRINTK
31
32#include <rtems/status-checks.h>
33
34#define MPC55XX_CLOCK_EMIOS_CHANNEL (MPC55XX_EMIOS_CHANNEL_NUMBER - 1)
35
36/* This is defined in clockdrv_shell.h */
37rtems_isr Clock_isr( rtems_vector_number vector);
38
39#define Clock_driver_support_at_tick() \
40 do { \
41    union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS; \
42    csr.B.FLAG = 1; \
43    EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL].CSR.R = csr.R; \
44 } while (0)
45
46static uint64_t mpc55xx_clock_factor;
47
48static void mpc55xx_clock_handler_install( rtems_isr_entry isr,
49                                           rtems_isr_entry *old_isr)
50{
51  rtems_status_code sc = RTEMS_SUCCESSFUL;
52
53  sc = mpc55xx_interrupt_handler_install(
54    MPC55XX_IRQ_EMIOS_GET_REQUEST( MPC55XX_CLOCK_EMIOS_CHANNEL),
55    "clock",
56    RTEMS_INTERRUPT_UNIQUE,
57    MPC55XX_INTC_MIN_PRIORITY,
58    (rtems_interrupt_handler) isr,
59    NULL
60  );
61 *old_isr = NULL;
62  RTEMS_CHECK_SC_VOID( sc, "install clock interrupt handler");
63}
64
65static void mpc55xx_clock_initialize( void)
66{
67  volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL];
68  union EMIOS_CCR_tag ccr = MPC55XX_ZERO_FLAGS;
69  union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS;
70  unsigned prescaler = mpc55xx_emios_global_prescaler();
71  uint64_t interval = ((uint64_t) bsp_clock_speed
72    * (uint64_t) rtems_configuration_get_microseconds_per_tick()) / 1000000;
73
74  mpc55xx_clock_factor = (1000000000ULL << 32) / bsp_clock_speed;
75
76  /* Apply prescaler */
77  if (prescaler > 0) {
78    interval /= (uint64_t) prescaler;
79  } else {
80    RTEMS_SYSLOG_ERROR( "unexpected global eMIOS prescaler\n");
81  }
82
83  /* Check interval */
84  if (interval == 0 || interval > MPC55XX_EMIOS_VALUE_MAX) {
85    interval = MPC55XX_EMIOS_VALUE_MAX;
86    RTEMS_SYSLOG_ERROR( "clock timer interval out of range\n");
87  }
88
89  /* Configure eMIOS channel */
90
91  /* Set channel in GPIO mode */
92  ccr.B.MODE = MPC55XX_EMIOS_MODE_GPIO_INPUT;
93  regs->CCR.R = ccr.R;
94
95  /* Clear status flags */
96  csr.B.OVR = 1;
97  csr.B.OVFL = 1;
98  csr.B.FLAG = 1;
99  regs->CSR.R = csr.R;
100
101  /* Set timer period */
102  regs->CADR.R = (uint32_t) interval - 1;
103
104  /* Set unused registers */
105  regs->CBDR.R = 0;
106  regs->CCNTR.R = 0;
107  regs->ALTCADR.R = 0;
108
109  /* Set control register */
110  ccr.B.MODE = MPC55XX_EMIOS_MODE_MCB_UP_INT_CLK;
111  ccr.B.UCPREN = 1;
112  ccr.B.FEN = 1;
113  ccr.B.FREN = 1;
114  regs->CCR.R = ccr.R;
115}
116
117static void mpc55xx_clock_cleanup( void)
118{
119  rtems_status_code sc = RTEMS_SUCCESSFUL;
120  volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL];
121  union EMIOS_CCR_tag ccr = MPC55XX_ZERO_FLAGS;
122
123  /* Set channel in GPIO mode */
124  ccr.B.MODE = MPC55XX_EMIOS_MODE_GPIO_INPUT;
125  regs->CCR.R = ccr.R;
126
127  /* Remove interrupt handler */
128  sc = rtems_interrupt_handler_remove(
129    MPC55XX_IRQ_EMIOS_GET_REQUEST( MPC55XX_CLOCK_EMIOS_CHANNEL),
130    (rtems_interrupt_handler) Clock_isr,
131    NULL
132  );
133  RTEMS_CHECK_SC_VOID( sc, "remove clock interrupt handler");
134}
135
136static uint32_t mpc55xx_clock_nanoseconds_since_last_tick( void)
137{
138  volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL];
139  uint64_t c = regs->CCNTR.R;
140  union EMIOS_CSR_tag csr = { .R = regs->CSR.R };
141  uint64_t k = mpc55xx_clock_factor;
142
143  if (csr.B.FLAG != 0) {
144    c = regs->CCNTR.R + regs->CADR.R + 1;
145  }
146
147  return (uint32_t) ((c * k) >> 32);
148}
149
150#define Clock_driver_support_initialize_hardware() mpc55xx_clock_initialize()
151
152#define Clock_driver_support_install_isr( isr, old_isr) \
153  mpc55xx_clock_handler_install(isr,&old_isr)
154
155#define Clock_driver_support_shutdown_hardware() mpc55xx_clock_cleanup()
156
157#define Clock_driver_nanoseconds_since_last_tick \
158  mpc55xx_clock_nanoseconds_since_last_tick
159
160/* Include shared source clock driver code */
161#include "../../../../libbsp/shared/clockdrv_shell.h"
Note: See TracBrowser for help on using the repository browser.