0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/clocksource.h>
0011 #include <linux/delay.h>
0012 #include <linux/init.h>
0013 #include <linux/kernel.h>
0014 #include <linux/module.h>
0015 #include <linux/timex.h>
0016
0017
0018
0019
0020 struct arm_delay_ops arm_delay_ops __ro_after_init = {
0021 .delay = __loop_delay,
0022 .const_udelay = __loop_const_udelay,
0023 .udelay = __loop_udelay,
0024 };
0025
0026 static const struct delay_timer *delay_timer;
0027 static bool delay_calibrated;
0028 static u64 delay_res;
0029
0030 int read_current_timer(unsigned long *timer_val)
0031 {
0032 if (!delay_timer)
0033 return -ENXIO;
0034
0035 *timer_val = delay_timer->read_current_timer();
0036 return 0;
0037 }
0038 EXPORT_SYMBOL_GPL(read_current_timer);
0039
0040 static inline u64 cyc_to_ns(u64 cyc, u32 mult, u32 shift)
0041 {
0042 return (cyc * mult) >> shift;
0043 }
0044
0045 static void __timer_delay(unsigned long cycles)
0046 {
0047 cycles_t start = get_cycles();
0048
0049 while ((get_cycles() - start) < cycles)
0050 cpu_relax();
0051 }
0052
0053 static void __timer_const_udelay(unsigned long xloops)
0054 {
0055 unsigned long long loops = xloops;
0056 loops *= arm_delay_ops.ticks_per_jiffy;
0057 __timer_delay(loops >> UDELAY_SHIFT);
0058 }
0059
0060 static void __timer_udelay(unsigned long usecs)
0061 {
0062 __timer_const_udelay(usecs * UDELAY_MULT);
0063 }
0064
0065 void __init register_current_timer_delay(const struct delay_timer *timer)
0066 {
0067 u32 new_mult, new_shift;
0068 u64 res;
0069
0070 clocks_calc_mult_shift(&new_mult, &new_shift, timer->freq,
0071 NSEC_PER_SEC, 3600);
0072 res = cyc_to_ns(1ULL, new_mult, new_shift);
0073
0074 if (res > 1000) {
0075 pr_err("Ignoring delay timer %ps, which has insufficient resolution of %lluns\n",
0076 timer, res);
0077 return;
0078 }
0079
0080 if (!delay_calibrated && (!delay_res || (res < delay_res))) {
0081 pr_info("Switching to timer-based delay loop, resolution %lluns\n", res);
0082 delay_timer = timer;
0083 lpj_fine = timer->freq / HZ;
0084 delay_res = res;
0085
0086
0087 arm_delay_ops.ticks_per_jiffy = lpj_fine;
0088 arm_delay_ops.delay = __timer_delay;
0089 arm_delay_ops.const_udelay = __timer_const_udelay;
0090 arm_delay_ops.udelay = __timer_udelay;
0091 } else {
0092 pr_info("Ignoring duplicate/late registration of read_current_timer delay\n");
0093 }
0094 }
0095
0096 unsigned long calibrate_delay_is_known(void)
0097 {
0098 delay_calibrated = true;
0099 return lpj_fine;
0100 }
0101
0102 void calibration_delay_done(void)
0103 {
0104 delay_calibrated = true;
0105 }