Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:45

0001 /*
0002  * This routine initializes the MC68360 Periodic Interval Timer
0003  *
0004  * The PIT has rather poor resolution, but it is easy to set up
0005  * and requires no housekeeping once it is going.
0006  */
0007 
0008 /*
0009  * Copyright (c) 1996 Eric Norum <eric@norum.ca>
0010  */
0011 
0012 #include <rtems.h>
0013 #include <bsp.h>
0014 #include <rtems/m68k/m68360.h>
0015 
0016 #define CLOCK_VECTOR     120
0017 #define CLOCK_IRQ_LEVEL    4
0018 
0019 char M360DefaultWatchdogFeeder = 1;
0020 
0021 /*
0022  * RTEMS and hardware have different notions of clock rate.
0023  */
0024 static unsigned long rtems_nsec_per_tick;
0025 static unsigned long pit_nsec_per_tick;
0026 static unsigned long nsec;
0027 
0028 /*
0029  * Periodic interval timer interrupt handler
0030  *    See if it's really time for a `tick'
0031  *    Perform a dummy read of DPRAM (work around bug in Rev. B of the 68360).
0032  *    Feed the watchdog
0033  *        Application code can override this by
0034  *        setting M360DefaultWatchdogFeeder to zero.
0035  */
0036 #define Clock_driver_support_at_tick(arg)  \
0037     do {                                   \
0038         nsec += pit_nsec_per_tick;         \
0039         if (nsec >= rtems_nsec_per_tick)   \
0040             return;                        \
0041         nsec -= rtems_nsec_per_tick;       \
0042         m360.dpram0[0];                    \
0043         if (M360DefaultWatchdogFeeder) {   \
0044             m360.swsr = 0x55;              \
0045             m360.swsr = 0xAA;              \
0046         }                                  \
0047     } while (0)                            \
0048 
0049 /*
0050  * Attach clock interrupt handler
0051  */
0052 #define Clock_driver_support_install_isr( _new ) \
0053     set_vector(_new, CLOCK_VECTOR, 1)
0054 
0055 /*
0056  * Set up the clock hardware
0057  *     The rate at which the periodic interval timer
0058  *     can generate interrupts is almost certainly not
0059  *     the same as desired by the BSP configuration.
0060  *     Handle the difference by choosing the largest PIT
0061  *     interval which is less than or equal to the RTEMS
0062  *     interval and skipping some hardware interrupts.
0063  *     To reduce the jitter in the calls to RTEMS the
0064  *     hardware interrupt interval is never greater than
0065  *     the maximum non-prescaled value from the PIT.
0066  *
0067  *     For a 25 MHz external clock the basic clock rate is
0068  *        40 nsec * 128 * 4 = 20.48 usec/tick
0069  */
0070 extern int m360_clock_rate;
0071 
0072 #define Clock_driver_support_initialize_hardware() \
0073     do {                                                                      \
0074         unsigned int divisor;                                                 \
0075         unsigned long nsec_per_chip_tick = 1000000000 / m360_clock_rate;      \
0076         unsigned long nsec_per_pit_tick = 512 * nsec_per_chip_tick;           \
0077         rtems_nsec_per_tick = rtems_configuration_get_microseconds_per_tick() * 1000; \
0078         divisor = rtems_nsec_per_tick / nsec_per_pit_tick;                    \
0079         if (divisor > 255)                                                    \
0080             divisor = 255;                                                    \
0081         else if (divisor == 0)                                                \
0082             divisor = 1;                                                      \
0083         pit_nsec_per_tick = nsec_per_pit_tick * divisor;                      \
0084         m360.pitr &= ~0x1FF;                                                  \
0085         m360.picr = (CLOCK_IRQ_LEVEL << 8) | CLOCK_VECTOR;                    \
0086         m360.pitr |= divisor;                                                 \
0087     } while (0)
0088 
0089 #define CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER
0090 
0091 #include "../../../shared/dev/clock/clockimpl.h"