00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00045
00046
00047
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
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
00124 else
00125 next_match = ( OSMR0 += rt_times.periodic_tick );
00126
00127
00128 #ifdef PROTECT_TIMER
00129 while ((int)(next_match - OSCR) < 2 * SETUP_TIME_TICKS ) {
00130 OSSR = OSSR_M0;
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