rtai-core/include/asm-arm/arch-sa1100/rtai_timer.h

00001 /* 020222 asm-arm/arch-sa1100/timer.h - ARM/SA1100 specific timer
00002 Don't include directly - it's included through asm-arm/rtai.h
00003 
00004 COPYRIGHT (C) 2002 Guennadi Liakhovetski, DSA GmbH (gl@dsa-ac.de)
00005 COPYRIGHT (C) 2002 Wolfgang Müller (wolfgang.mueller@dsa-ac.de)
00006 Copyright (c) 2001 Alex Züpke, SYSGO RTS GmbH (azu@sysgo.de)
00007 
00008 This program is free software; you can redistribute it and/or modify
00009 it under the terms of version 2 of the GNU General Public License as
00010 published by the Free Software Foundation.
00011 
00012 This program is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with this program; if not, write to the Free Software
00019 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 */
00021 /*
00022 --------------------------------------------------------------------------
00023 Acknowledgements
00024 - Paolo Mantegazza      (mantegazza@aero.polimi.it)
00025         creator of RTAI 
00026 */
00027 
00028 #ifndef _ASM_ARCH_RTAI_TIMER_H_
00029 #define _ASM_ARCH_RTAI_TIMER_H_
00030 
00031 #include <asm/proc/hard_system.h>
00032 #include <linux/time.h>
00033 #include <linux/timex.h>
00034 
00035 #define CPU_FREQ (tuned.cpu_freq)
00036 
00037 static inline int timer_irq_ack( void )
00038 {
00039         OSSR = OSSR_M0;
00040         rt_unmask_irq(TIMER_8254_IRQ);
00041         if ( (int)(OSCR - OSMR0) < 0 )
00042                 /* This is what just happened: we were setting a next timer interrupt
00043                    in the scheduler, while a previously configured timer-interrupt
00044                    happened, so, just restore the correct value of the match register and
00045                    proceed as usual. Yes, we will have to re-calculate the next interrupt. */
00046                 OSMR0 = OSCR - 1;
00047         return 0;
00048 }
00049 
00050 union rtai_tsc {
00051         unsigned long long tsc;
00052         unsigned long hltsc[2];
00053 };
00054 extern volatile union rtai_tsc rtai_tsc;
00055 
00056 static inline RTIME rdtsc(void)
00057 {
00058         RTIME ts;
00059         unsigned long flags, count;
00060 
00061         hard_save_flags_and_cli(flags);
00062 
00063         if ( ( count = OSCR ) < rtai_tsc.hltsc[0] )
00064                 rtai_tsc.hltsc[1]++;
00065         rtai_tsc.hltsc[0] = count;
00066         ts = rtai_tsc.tsc;
00067         hard_restore_flags(flags);
00068 
00069         return ts;
00070 }
00071 
00072 #define PROTECT_TIMER
00073 
00074 #if 0
00075 #define REG_BASE  0xfa000000
00076 #define REG_OSMR0 0x00000000
00077 #define REG_OSCR  0x00000010
00078 #define REG_OSSR  0x00000014
00079 #define REG_ICMR  0x00050004
00080 static inline void rt_set_timer_match_reg(int delay)
00081 {
00082         unsigned long flags;
00083 
00084         hard_save_flags_cli( flags );
00085 
00086         __asm__ __volatile__ (
00087         "mov    r2, #0xfa000000         @ REG_BASE\n"
00088 #ifdef PROTECT_TIMER
00089 "       cmp     %0, %2                  @ if ( delay > LATCH || delay < 0 )"
00090 "       movhi   %0, %2                  @       delay = LATCH;\n"
00091 #endif
00092 "       teq     %0, #0                  @ if ( delay == 0 ) {"
00093 "       ldreq   r1, [r2, #0]            @       r1 = OSMR0;"
00094 "       addeq   r0, r1, %1              @       r0 = r1 + rt_times.periodic_tick;"
00095 "       ldrne   r0, [r2, #0x10]         @ } else { r0 = OSCR;"
00096 "       addne   r0, r0, %0              @       r0 = r0 + delay; }"
00097 "       str     r0, [r2, #0]            @ OSMR0 = r0;\n"
00098                 :
00099                 : "r" (delay), "r" (rt_times.periodic_tick), "r" (LATCH)
00100                 : "r0", "r1", "r2", "memory", "cc" );
00101 
00102         hard_restore_flags( flags );
00103 }
00104 
00105 #else
00106 /* Current version */
00107 static inline void rt_set_timer_match_reg(int delay)
00108 {
00109         unsigned long flags;
00110         unsigned long next_match;
00111 
00112 #ifdef PROTECT_TIMER
00113         if ( delay > LATCH )
00114                 delay = LATCH;
00115 #endif
00116 
00117         hard_save_flags_cli(flags);
00118 
00119         if ( delay )
00120                 next_match = OSMR0 = delay + OSCR;
00121 //              next_match = OSMR0 = delay + rtai_tsc.hltsc[0];
00122         else
00123                 next_match = ( OSMR0 += rt_times.periodic_tick );
00124 //              next_match = OSMR0 = ((unsigned long *)&rt_times.intr_time)[0];
00125 
00126 #ifdef PROTECT_TIMER
00127         while ((int)(next_match - OSCR) < SETUP_TIME_TICKS ) {
00128                 OSSR = OSSR_M0;  /* Clear match on timer 0 */
00129                 next_match = OSMR0 = OSCR + 2 * SETUP_TIME_TICKS;
00130         }
00131 #endif
00132 
00133         hard_restore_flags(flags);
00134 }
00135 #endif
00136 
00137 #define rt_set_timer_delay(x)  rt_set_timer_match_reg(x)
00138 
00139 #endif

Generated on Sat Jul 24 19:36:02 2004 for RTAI API by doxygen 1.3.4