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

00001 /*
00002  * /include/asm/arch/mach-clps711x/timer.h
00003  *
00004  * Don't include directly - it's included through asm-arm/rtai.h
00005  *
00006  * Copyright (c) 2002 Thomas Gleixner, autronix automation <gleixner@autronix.de>
00007  * Copyright (c) 2002, Alex Züpke, SYSGO RTS GmbH (azu@sysgo.de)
00008  * 
00009 This program is free software; you can redistribute it and/or modify
00010 it under the terms of version 2 of the GNU General Public License as
00011 published by the Free Software Foundation.
00012 
00013 This program is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 GNU General Public License for more details.
00017 
00018 You should have received a copy of the GNU General Public License
00019 along with this program; if not, write to the Free Software
00020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  * This are the mach_clps711x (ARM7) timer inlines for 
00023  * RTAI Real Time Application Interface
00024  *
00025  * Thanks to Guennadi Liakhovetski, DSA GmbH (gl@dsa-ac.de) for review and 
00026  * a helping hand in unterstanding RTAI. 
00027  *
00028  * TODO's:      Beautify, test, test, test
00029  */
00030 /*
00031 --------------------------------------------------------------------------
00032 Acknowledgements
00033 - Paolo Mantegazza      (mantegazza@aero.polimi.it)
00034         creator of RTAI 
00035 */
00036 #ifndef _ASM_ARCH_RTAI_TIMER_H_
00037 #define _ASM_ARCH_RTAI_TIMER_H_
00038 
00039 #include <asm/proc/hard_system.h>
00040 #include <linux/sched.h>
00041 
00042 #define CPU_FREQ (tuned.cpu_freq)
00043 #define CHECK_TC2_BOUNDS
00044 #define DEBUG_INLINE 0
00045 #if DEBUG_INLINE > 0
00046 #define DI1(x) x
00047 #else
00048 #define DI1(x)
00049 #endif
00050 
00051 extern unsigned long rtai_lasttsc;
00052 extern unsigned long rtai_TC2latch;
00053 extern union rtai_tsc rtai_tsc;
00054 
00055 union rtai_tsc {
00056         unsigned long long tsc;
00057         unsigned long hltsc[2];
00058 };
00059 
00060 static inline int timer_irq_ack( void )
00061 {
00062         return 0;
00063 }
00064 
00065 /*
00066 *       rdtsc reads RTAI's timestampcounter. We use Timer/Counter TC1 on
00067 *       cpls711x (Cirrus Logic) ARM7 cpu's. This timer is not used by 
00068 *       Linux, but it maybe used by other drivers. Check this out first.
00069 *       The timer runs free counting down,with a wrap around every 128 ms
00070 *       If we don't get here within 64ms, we have killed our timebase.
00071 *       But if we miss this for 64ms our box is killed anyway -)
00072 *
00073 */
00074 static inline unsigned long long rdtsc(void)
00075 {
00076         unsigned long flags, ticks, act;
00077  
00078         // we read the 16 bit timer and calc ts on this value
00079         hard_save_flags_and_cli(flags);
00080         act = ( unsigned long) (clps_readl(TC1D) & 0xffff);
00081         /* take care of underflows */
00082         ticks = (rtai_lasttsc < act) ? (0x10000 - act + rtai_lasttsc) : (rtai_lasttsc - act);
00083         rtai_lasttsc = act;
00084         rtai_tsc.tsc += (unsigned long long) ticks;
00085         hard_restore_flags(flags);
00086         return rtai_tsc.tsc;
00087 }
00088 
00089 
00090 /*
00091 *       set the timer latch for timer/counter TC2 
00092 *       we check the bounds, as long as we are in testphase
00093 *       Switch this off by undef CHECK_TC2_BOUNDS
00094 */ 
00095 static inline void rt_set_timer_latch(unsigned long delay)
00096 {
00097         unsigned long flags;
00098         RTIME diff;
00099  
00100         // set 16 bit LATCH
00101         hard_save_flags_cli(flags);
00102 
00103         diff = rt_times.intr_time - rdtsc();
00104         /* we have missed the deadline already */
00105         if (diff < 0)   
00106                 diff = 1;           
00107 
00108         DI1( if (delay > LATCH) {
00109                 printk("rt_set_timer_latch delay > LATCH :%ld\n",delay);
00110                 delay = LATCH;
00111         });     
00112 
00113         rtai_TC2latch = (!delay ? ((unsigned long*)(&diff))[0] : delay);
00114 #ifdef CHECK_TC2_BOUNDS
00115         if (rtai_TC2latch > LATCH) {
00116                 DI1(printk("rt_set_timer_latch > LATCH :%ld\n",rtai_TC2latch));
00117                 rtai_TC2latch = LATCH;
00118         }       
00119 #endif
00120         /* This bound check is essential, remove it and you get in trouble */
00121         if (!rtai_TC2latch) {
00122                 DI1(printk("rt_set_timer_latch < 1 :%ld\n",rtai_TC2latch));
00123                 rtai_TC2latch = 1;
00124         }       
00125         clps_writel(0,TC2EOI);
00126         clps_writel(rtai_TC2latch, TC2D);
00127         clps_writel((clps_readl(INTMR1)|0x200), INTMR1);
00128         hard_restore_flags(flags);
00129 }   
00130 
00131 #define rt_set_timer_delay(x)  rt_set_timer_latch(x)
00132 
00133 #endif

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