source: rtems/bsps/m68k/uC5282/clock/clock.c @ 753873e5

Last change on this file since 753873e5 was 753873e5, checked in by Joel Sherrill <joel@…>, on 03/22/22 at 20:03:30

Update Eric Norum contact info and start to normalize file headers

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