rtai-core/include/asm-arm/arch-pxa/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/timer.h>
00034 #include <asm/mach/irq.h>
00035 #include <linux/timex.h>
00036 
00037 #define CPU_FREQ (tuned.cpu_freq)
00038 
00039 static inline int timer_irq_ack( void )
00040 {
00041         OSSR = OSSR_M0;
00042         rt_unmask_irq(TIMER_8254_IRQ);
00043         if ( (int)(OSCR - OSMR0) < 0 )
00044                 /* This is what just happened: we were setting a next timer interrupt
00045                    in the scheduler, while a previously configured timer-interrupt
00046                    happened, so, just restore the correct value of the match register and
00047                    proceed as usual. Yes, we will have to re-calculate the next interrupt. */
00048                 OSMR0 = OSCR - 1;
00049         return 0;
00050 }
00051 
00052 union rtai_tsc {
00053         unsigned long long tsc;
00054         unsigned long hltsc[2];
00055 };
00056 extern volatile union rtai_tsc rtai_tsc;
00057 
00058 static inline RTIME rdtsc(void)
00059 {
00060         RTIME ts;
00061         unsigned long flags, count;
00062 
00063         hard_save_flags_and_cli(flags);
00064 
00065         if ( ( count = OSCR ) < rtai_tsc.hltsc[0] )
00066                 rtai_tsc.hltsc[1]++;
00067         rtai_tsc.hltsc[0] = count;
00068         ts = rtai_tsc.tsc;
00069         hard_restore_flags(flags);
00070 
00071         return ts;
00072 }
00073 
00074 #define PROTECT_TIMER
00075 
00076 #if 0
00077 #define REG_BASE  0xf8000000
00078 #define REG_OSMR0 0x00000000
00079 #define REG_OSCR  0x00000010
00080 #define REG_OSSR  0x00000014
00081 #define REG_ICMR  0x00050004
00082 static inline void rt_set_timer_match_reg(int delay)
00083 {
00084         unsigned long flags;
00085 
00086         hard_save_flags_cli( flags );
00087 
00088         __asm__ __volatile__ (
00089         "mov    r2, #0xfa000000         @ REG_BASE\n"
00090 #ifdef PROTECT_TIMER
00091 "       cmp     %0, %2                  @ if ( delay > LATCH || delay < 0 )\n"
00092 "       movhi   %0, %2                  @       delay = LATCH;\n"
00093 #endif
00094 "       teq     %0, #0                  @ if ( delay == 0 ) {\n"
00095 "       ldreq   r1, [r2, #0]            @       r1 = OSMR0;\n"
00096 "       addeq   r0, r1, %1              @       r0 = r1 + rt_times.periodic_tick;\n"
00097 "       ldrne   r0, [r2, #0x10]         @ } else { r0 = OSCR;\n"
00098 "       addne   r0, r0, %0              @       r0 = r0 + delay; }\n"
00099 "       str     r0, [r2, #0]            @ OSMR0 = r0;\n"
00100                 :
00101                 : "r" (delay), "r" (rt_times.periodic_tick), "r" (LATCH)
00102                 : "r0", "r1", "r2", "memory", "cc" );
00103 
00104         hard_restore_flags( flags );
00105 }
00106 
00107 #else
00108 /* Current version */
00109 static inline void rt_set_timer_match_reg(int delay)
00110 {
00111         unsigned long flags;
00112         unsigned long next_match;
00113 
00114 #ifdef PROTECT_TIMER
00115         if ( delay > LATCH )
00116                 delay = LATCH;
00117 #endif
00118 
00119         hard_save_flags_cli(flags);
00120 
00121         if ( delay )
00122                 next_match = OSMR0 = delay + OSCR;
00123 //              next_match = OSMR0 = delay + rtai_tsc.hltsc[0];
00124         else
00125                 next_match = ( OSMR0 += rt_times.periodic_tick );
00126 //              next_match = OSMR0 = ((unsigned long *)&rt_times.intr_time)[0];
00127 
00128 #ifdef PROTECT_TIMER
00129         while ((int)(next_match - OSCR) < 2 * SETUP_TIME_TICKS ) {
00130                 OSSR = OSSR_M0;  /* Clear match on timer 0 */
00131                 next_match = OSMR0 = OSCR + 4 * SETUP_TIME_TICKS;
00132         }
00133 #endif
00134 
00135         hard_restore_flags(flags);
00136 }
00137 #endif
00138 
00139 #define rt_set_timer_delay(x)  rt_set_timer_match_reg(x)
00140 
00141 #endif

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