source: rtems/bsps/m68k/uC5282/clock/clock.c @ c9625a21

Last change on this file since c9625a21 was a5c3bfb, checked in by Joel Sherrill <joel@…>, on 08/29/18 at 17:37:29

uC5282/clock/clock.c: Correct bsp_idle_thread() prototype

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 * Use the last periodic interval timer (PIT3) as the system clock.
3 *
4 *  Author: W. Eric Norum <norume@aps.anl.gov>
5 *
6 *  COPYRIGHT (c) 2005.
7 *  On-Line Applications Research Corporation (OAR).
8 *
9 *  The license and distribution terms for this file may be
10 *  found in the file LICENSE in this distribution or at
11 *  http://www.rtems.org/license/LICENSE.
12 */
13
14#include <rtems.h>
15#include <rtems/timecounter.h>
16#include <bsp.h>
17#include <mcf5282/mcf5282.h>
18
19/*
20 * CPU load counters
21 * Place in static RAM so updates don't hit the SDRAM
22 */
23#define IDLE_COUNTER    __SRAMBASE.idle_counter
24#define FILTERED_IDLE   __SRAMBASE.filtered_idle
25#define MAX_IDLE_COUNT  __SRAMBASE.max_idle_count
26#define PITC_PER_TICK   __SRAMBASE.pitc_per_tick
27#define NSEC_PER_PITC   __SRAMBASE.nsec_per_pitc
28#define FILTER_SHIFT    6
29
30/*
31 * Use INTC0 base
32 */
33#define CLOCK_VECTOR (64+58)
34
35static rtems_timecounter_simple uC5282_tc;
36
37static uint32_t uC5282_tc_get(rtems_timecounter_simple *tc)
38{
39  return MCF5282_PIT3_PCNTR;
40}
41
42static bool uC5282_tc_is_pending(rtems_timecounter_simple *tc)
43{
44  return (MCF5282_PIT3_PCSR & MCF5282_PIT_PCSR_PIF) != 0;
45}
46
47static uint32_t uC5282_tc_get_timecount(struct timecounter *tc)
48{
49  return rtems_timecounter_simple_downcounter_get(
50    tc,
51    uC5282_tc_get,
52    uC5282_tc_is_pending
53  );
54}
55
56static void uC5282_tc_at_tick(rtems_timecounter_simple *tc)
57{
58  unsigned idle = IDLE_COUNTER;
59  IDLE_COUNTER = 0;
60  if (idle > MAX_IDLE_COUNT)
61    MAX_IDLE_COUNT = idle;
62  FILTERED_IDLE = idle + FILTERED_IDLE - (FILTERED_IDLE>>FILTER_SHIFT);
63  MCF5282_PIT3_PCSR |= MCF5282_PIT_PCSR_PIF;
64}
65
66static void uC5282_tc_tick(void)
67{
68  rtems_timecounter_simple_downcounter_tick(
69    &uC5282_tc,
70    uC5282_tc_get,
71    uC5282_tc_at_tick
72  );
73}
74
75/*
76 * Attach clock interrupt handler
77 */
78#define Clock_driver_support_install_isr( _new ) \
79    set_vector(_new, CLOCK_VECTOR, 1)
80
81/*
82 * Set up the clock hardware
83 *
84 * f_pit = f_clk / 2^(preScaleCode+1) / N  = 1/(us_per_tick/us_per_s)
85 *
86 * N = f_clk / 2^(preScaleCode+1) * us_per_tick / us_per_s
87 *
88 * ns_per_pit_clk = ns_per_s / (f_clk / 2^(preScaleCode+1))
89 *                = ns_per_s * 2^(preScaleCode+1) / f_clk;
90 */
91#define Clock_driver_support_initialize_hardware()                       \
92    do {                                                                 \
93        unsigned long long N;                                            \
94        int level;                                                       \
95        int preScaleCode = 0;                                            \
96                N  = bsp_get_CPU_clock_speed();                                  \
97                N *= rtems_configuration_get_microseconds_per_tick();            \
98                N /= 2*1000000; /* min_prescale * us_per_s */                    \
99                while ( N > 0x10000 ) {                                          \
100                        preScaleCode++;                                              \
101                        N >>= 1;                                                     \
102                }                                                                \
103                PITC_PER_TICK  = N;                                              \
104                N  = 2000000000ULL << preScaleCode;                              \
105                N /= bsp_get_CPU_clock_speed();                                  \
106                NSEC_PER_PITC  = N;                                              \
107        IDLE_COUNTER   = 0;                                              \
108        FILTERED_IDLE  = 0;                                              \
109        MAX_IDLE_COUNT = 0;                                              \
110        bsp_allocate_interrupt(PIT3_IRQ_LEVEL, PIT3_IRQ_PRIORITY);       \
111        MCF5282_INTC0_ICR58 = MCF5282_INTC_ICR_IL(PIT3_IRQ_LEVEL) |      \
112                              MCF5282_INTC_ICR_IP(PIT3_IRQ_PRIORITY);    \
113        rtems_interrupt_disable( level );                                \
114        MCF5282_INTC0_IMRH &= ~MCF5282_INTC_IMRH_INT58;                  \
115        MCF5282_PIT3_PCSR &= ~MCF5282_PIT_PCSR_EN;                       \
116        rtems_interrupt_enable( level );                                 \
117        MCF5282_PIT3_PCSR = MCF5282_PIT_PCSR_PRE(preScaleCode) |         \
118                            MCF5282_PIT_PCSR_OVW |                       \
119                            MCF5282_PIT_PCSR_PIE |                       \
120                            MCF5282_PIT_PCSR_RLD;                        \
121        MCF5282_PIT3_PMR = PITC_PER_TICK - 1;                            \
122        MCF5282_PIT3_PCSR = MCF5282_PIT_PCSR_PRE(preScaleCode) |         \
123                            MCF5282_PIT_PCSR_PIE |                       \
124                            MCF5282_PIT_PCSR_RLD |                       \
125                            MCF5282_PIT_PCSR_EN;                         \
126         rtems_timecounter_simple_install( \
127           &uC5282_tc, \
128           bsp_get_CPU_clock_speed() >> (preScaleCode + 1), \
129           PITC_PER_TICK, \
130           uC5282_tc_get_timecount \
131         ); \
132    } while (0)
133
134/*
135 * Provide our own version of the idle task
136 */
137void * bsp_idle_thread(uintptr_t ignored)
138{
139  /* Atomic increment */
140  for(;;)
141    __asm__ volatile ("addq.l #1,%0"::"m"(IDLE_COUNTER));
142}
143
144int bsp_cpu_load_percentage(void)
145{
146    return MAX_IDLE_COUNT ?
147           (100 - ((100 * (FILTERED_IDLE >> FILTER_SHIFT)) / MAX_IDLE_COUNT)) :
148           0;
149}
150
151#define Clock_driver_timecounter_tick() uC5282_tc_tick()
152
153#include "../../../shared/dev/clock/clockimpl.h"
Note: See TracBrowser for help on using the repository browser.