Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | /* * BK Id: SCCS/s.time.h 1.13 06/27/01 14:49:58 trini */ /* * Common time prototypes and such for all ppc machines. * * Written by Cort Dougan (cort@fsmlabs.com) to merge * Paul Mackerras' version and mine for PReP and Pmac. */ #ifdef __KERNEL__ #include <linux/config.h> #include <linux/mc146818rtc.h> #include <linux/threads.h> #include <asm/processor.h> /* time.c */ extern unsigned tb_ticks_per_jiffy; extern unsigned tb_to_us; extern unsigned tb_last_stamp; extern unsigned long disarm_decr[NR_CPUS]; extern void to_tm(int tim, struct rtc_time * tm); extern time_t last_rtc_update; extern void set_dec_cpu6(unsigned int val); int via_calibrate_decr(void); /* Accessor functions for the decrementer register. * The 4xx doesn't even have a decrementer. I tried to use the * generic timer interrupt code, which seems OK, with the 4xx PIT * in auto-reload mode. The problem is PIT stops counting when it * hits zero. If it would wrap, we could use it just like a decrementer. */ static __inline__ unsigned int get_dec(void) { #if defined(CONFIG_4xx) return (mfspr(SPRN_PIT)); #else return (mfspr(SPRN_DEC)); #endif } static __inline__ void set_dec(unsigned int val) { #if defined(CONFIG_4xx) return; /* Have to let it auto-reload */ #elif defined(CONFIG_8xx_CPU6) set_dec_cpu6(val); #else mtspr(SPRN_DEC, val); #endif } /* Accessor functions for the timebase (RTC on 601) registers. */ /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */ #ifdef CONFIG_6xx extern __inline__ int const __USE_RTC(void) { return (mfspr(SPRN_PVR)>>16) == 1; } #else #define __USE_RTC() 0 #endif extern __inline__ unsigned long get_tbl(void) { unsigned long tbl; asm volatile("mftb %0" : "=r" (tbl)); return tbl; } extern __inline__ unsigned long get_tbu(void) { unsigned long tbl; asm volatile("mftbu %0" : "=r" (tbl)); return tbl; } extern __inline__ unsigned long get_rtcl(void) { unsigned long rtcl; asm volatile("mfrtcl %0" : "=r" (rtcl)); return rtcl; } extern __inline__ unsigned get_native_tbl(void) { if (__USE_RTC()) return get_rtcl(); else return get_tbl(); } /* On machines with RTC, this function can only be used safely * after the timestamp and for 1 second. It is only used by gettimeofday * however so it should not matter. */ extern __inline__ unsigned tb_ticks_since(unsigned tstamp) { if (__USE_RTC()) { int delta = get_rtcl() - tstamp; return delta<0 ? delta + 1000000000 : delta; } else { return get_tbl() - tstamp; } } #if 0 extern __inline__ unsigned long get_bin_rtcl(void) { unsigned long rtcl, rtcu1, rtcu2; asm volatile("\ 1: mfrtcu %0\n\ mfrtcl %1\n\ mfrtcu %2\n\ cmpw %0,%2\n\ bne- 1b\n" : "=r" (rtcu1), "=r" (rtcl), "=r" (rtcu2) : : "cr0"); return rtcu2*1000000000+rtcl; } extern __inline__ unsigned binary_tbl(void) { if (__USE_RTC()) return get_bin_rtcl(); else return get_tbl(); } #endif /* Use mulhwu to scale processor timebase to timeval */ #define mulhwu(x,y) \ ({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;}) unsigned mulhwu_scale_factor(unsigned, unsigned); #endif /* __KERNEL__ */ |