Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Common time prototypes and such for all ppc machines.
0004  *
0005  * Written by Cort Dougan (cort@cs.nmt.edu) to merge
0006  * Paul Mackerras' version and mine for PReP and Pmac.
0007  */
0008 
0009 #ifndef __POWERPC_TIME_H
0010 #define __POWERPC_TIME_H
0011 
0012 #ifdef __KERNEL__
0013 #include <linux/types.h>
0014 #include <linux/percpu.h>
0015 
0016 #include <asm/processor.h>
0017 #include <asm/cpu_has_feature.h>
0018 #include <asm/vdso/timebase.h>
0019 
0020 /* time.c */
0021 extern u64 decrementer_max;
0022 
0023 extern unsigned long tb_ticks_per_jiffy;
0024 extern unsigned long tb_ticks_per_usec;
0025 extern unsigned long tb_ticks_per_sec;
0026 extern struct clock_event_device decrementer_clockevent;
0027 extern u64 decrementer_max;
0028 
0029 
0030 extern void generic_calibrate_decr(void);
0031 
0032 /* Some sane defaults: 125 MHz timebase, 1GHz processor */
0033 extern unsigned long ppc_proc_freq;
0034 #define DEFAULT_PROC_FREQ   (DEFAULT_TB_FREQ * 8)
0035 extern unsigned long ppc_tb_freq;
0036 #define DEFAULT_TB_FREQ     125000000UL
0037 
0038 extern bool tb_invalid;
0039 
0040 struct div_result {
0041     u64 result_high;
0042     u64 result_low;
0043 };
0044 
0045 static inline u64 get_vtb(void)
0046 {
0047     if (cpu_has_feature(CPU_FTR_ARCH_207S))
0048         return mfspr(SPRN_VTB);
0049 
0050     return 0;
0051 }
0052 
0053 /* Accessor functions for the decrementer register.
0054  * The 4xx doesn't even have a decrementer.  I tried to use the
0055  * generic timer interrupt code, which seems OK, with the 4xx PIT
0056  * in auto-reload mode.  The problem is PIT stops counting when it
0057  * hits zero.  If it would wrap, we could use it just like a decrementer.
0058  */
0059 static inline u64 get_dec(void)
0060 {
0061     if (IS_ENABLED(CONFIG_40x))
0062         return mfspr(SPRN_PIT);
0063 
0064     return mfspr(SPRN_DEC);
0065 }
0066 
0067 /*
0068  * Note: Book E and 4xx processors differ from other PowerPC processors
0069  * in when the decrementer generates its interrupt: on the 1 to 0
0070  * transition for Book E/4xx, but on the 0 to -1 transition for others.
0071  */
0072 static inline void set_dec(u64 val)
0073 {
0074     if (IS_ENABLED(CONFIG_40x))
0075         mtspr(SPRN_PIT, (u32)val);
0076     else if (IS_ENABLED(CONFIG_BOOKE))
0077         mtspr(SPRN_DEC, val);
0078     else
0079         mtspr(SPRN_DEC, val - 1);
0080 }
0081 
0082 static inline unsigned long tb_ticks_since(unsigned long tstamp)
0083 {
0084     return mftb() - tstamp;
0085 }
0086 
0087 #define mulhwu(x,y) \
0088 ({unsigned z; asm ("mulhwu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
0089 
0090 #ifdef CONFIG_PPC64
0091 #define mulhdu(x,y) \
0092 ({unsigned long z; asm ("mulhdu %0,%1,%2" : "=r" (z) : "r" (x), "r" (y)); z;})
0093 #else
0094 extern u64 mulhdu(u64, u64);
0095 #endif
0096 
0097 extern void div128_by_32(u64 dividend_high, u64 dividend_low,
0098              unsigned divisor, struct div_result *dr);
0099 
0100 extern void secondary_cpu_time_init(void);
0101 extern void __init time_init(void);
0102 
0103 DECLARE_PER_CPU(u64, decrementers_next_tb);
0104 
0105 static inline u64 timer_get_next_tb(void)
0106 {
0107     return __this_cpu_read(decrementers_next_tb);
0108 }
0109 
0110 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
0111 void timer_rearm_host_dec(u64 now);
0112 #endif
0113 
0114 /* Convert timebase ticks to nanoseconds */
0115 unsigned long long tb_to_ns(unsigned long long tb_ticks);
0116 
0117 void timer_broadcast_interrupt(void);
0118 
0119 /* SPLPAR */
0120 void accumulate_stolen_time(void);
0121 
0122 #endif /* __KERNEL__ */
0123 #endif /* __POWERPC_TIME_H */