Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  3)  * Based on clocksource code. See commit 74d23cc704d1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  4)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  5) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  6) #include <linux/timecounter.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  8) void timecounter_init(struct timecounter *tc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  9) 		      const struct cyclecounter *cc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) 		      u64 start_tstamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) 	tc->cc = cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) 	tc->cycle_last = cc->read(cc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) 	tc->nsec = start_tstamp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) 	tc->mask = (1ULL << cc->shift) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) 	tc->frac = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) EXPORT_SYMBOL_GPL(timecounter_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)  * timecounter_read_delta - get nanoseconds since last call of this function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)  * @tc:         Pointer to time counter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)  * When the underlying cycle counter runs over, this will be handled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)  * correctly as long as it does not run over more than once between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)  * calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)  * The first call to this function for a new time counter initializes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)  * the time tracking and returns an undefined result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static u64 timecounter_read_delta(struct timecounter *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 	u64 cycle_now, cycle_delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 	u64 ns_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) 	/* read cycle counter: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) 	cycle_now = tc->cc->read(tc->cc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 	/* calculate the delta since the last timecounter_read_delta(): */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) 	cycle_delta = (cycle_now - tc->cycle_last) & tc->cc->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) 	/* convert to nanoseconds: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) 	ns_offset = cyclecounter_cyc2ns(tc->cc, cycle_delta,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) 					tc->mask, &tc->frac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) 	/* update time stamp of timecounter_read_delta() call: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) 	tc->cycle_last = cycle_now;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) 	return ns_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) u64 timecounter_read(struct timecounter *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) 	u64 nsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 	/* increment time by nanoseconds since last call */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) 	nsec = timecounter_read_delta(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) 	nsec += tc->nsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) 	tc->nsec = nsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) 	return nsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) EXPORT_SYMBOL_GPL(timecounter_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)  * This is like cyclecounter_cyc2ns(), but it is used for computing a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)  * time previous to the time stored in the cycle counter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static u64 cc_cyc2ns_backwards(const struct cyclecounter *cc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) 			       u64 cycles, u64 mask, u64 frac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) 	u64 ns = (u64) cycles;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) 	ns = ((ns * cc->mult) - frac) >> cc->shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) 	return ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) u64 timecounter_cyc2time(struct timecounter *tc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) 			 u64 cycle_tstamp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) 	u64 delta = (cycle_tstamp - tc->cycle_last) & tc->cc->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) 	u64 nsec = tc->nsec, frac = tc->frac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) 	 * Instead of always treating cycle_tstamp as more recent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) 	 * than tc->cycle_last, detect when it is too far in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) 	 * future and treat it as old time stamp instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) 	if (delta > tc->cc->mask / 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) 		delta = (tc->cycle_last - cycle_tstamp) & tc->cc->mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) 		nsec -= cc_cyc2ns_backwards(tc->cc, delta, tc->mask, frac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) 		nsec += cyclecounter_cyc2ns(tc->cc, delta, tc->mask, &frac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) 	return nsec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) EXPORT_SYMBOL_GPL(timecounter_cyc2time);