Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * linux/include/linux/timecounter.h
0004  *
0005  * based on code that migrated away from
0006  * linux/include/linux/clocksource.h
0007  */
0008 #ifndef _LINUX_TIMECOUNTER_H
0009 #define _LINUX_TIMECOUNTER_H
0010 
0011 #include <linux/types.h>
0012 
0013 /* simplify initialization of mask field */
0014 #define CYCLECOUNTER_MASK(bits) (u64)((bits) < 64 ? ((1ULL<<(bits))-1) : -1)
0015 
0016 /**
0017  * struct cyclecounter - hardware abstraction for a free running counter
0018  *  Provides completely state-free accessors to the underlying hardware.
0019  *  Depending on which hardware it reads, the cycle counter may wrap
0020  *  around quickly. Locking rules (if necessary) have to be defined
0021  *  by the implementor and user of specific instances of this API.
0022  *
0023  * @read:       returns the current cycle value
0024  * @mask:       bitmask for two's complement
0025  *          subtraction of non 64 bit counters,
0026  *          see CYCLECOUNTER_MASK() helper macro
0027  * @mult:       cycle to nanosecond multiplier
0028  * @shift:      cycle to nanosecond divisor (power of two)
0029  */
0030 struct cyclecounter {
0031     u64 (*read)(const struct cyclecounter *cc);
0032     u64 mask;
0033     u32 mult;
0034     u32 shift;
0035 };
0036 
0037 /**
0038  * struct timecounter - layer above a %struct cyclecounter which counts nanoseconds
0039  *  Contains the state needed by timecounter_read() to detect
0040  *  cycle counter wrap around. Initialize with
0041  *  timecounter_init(). Also used to convert cycle counts into the
0042  *  corresponding nanosecond counts with timecounter_cyc2time(). Users
0043  *  of this code are responsible for initializing the underlying
0044  *  cycle counter hardware, locking issues and reading the time
0045  *  more often than the cycle counter wraps around. The nanosecond
0046  *  counter will only wrap around after ~585 years.
0047  *
0048  * @cc:         the cycle counter used by this instance
0049  * @cycle_last:     most recent cycle counter value seen by
0050  *          timecounter_read()
0051  * @nsec:       continuously increasing count
0052  * @mask:       bit mask for maintaining the 'frac' field
0053  * @frac:       accumulated fractional nanoseconds
0054  */
0055 struct timecounter {
0056     const struct cyclecounter *cc;
0057     u64 cycle_last;
0058     u64 nsec;
0059     u64 mask;
0060     u64 frac;
0061 };
0062 
0063 /**
0064  * cyclecounter_cyc2ns - converts cycle counter cycles to nanoseconds
0065  * @cc:     Pointer to cycle counter.
0066  * @cycles: Cycles
0067  * @mask:   bit mask for maintaining the 'frac' field
0068  * @frac:   pointer to storage for the fractional nanoseconds.
0069  */
0070 static inline u64 cyclecounter_cyc2ns(const struct cyclecounter *cc,
0071                       u64 cycles, u64 mask, u64 *frac)
0072 {
0073     u64 ns = (u64) cycles;
0074 
0075     ns = (ns * cc->mult) + *frac;
0076     *frac = ns & mask;
0077     return ns >> cc->shift;
0078 }
0079 
0080 /**
0081  * timecounter_adjtime - Shifts the time of the clock.
0082  * @delta:  Desired change in nanoseconds.
0083  */
0084 static inline void timecounter_adjtime(struct timecounter *tc, s64 delta)
0085 {
0086     tc->nsec += delta;
0087 }
0088 
0089 /**
0090  * timecounter_init - initialize a time counter
0091  * @tc:         Pointer to time counter which is to be initialized/reset
0092  * @cc:         A cycle counter, ready to be used.
0093  * @start_tstamp:   Arbitrary initial time stamp.
0094  *
0095  * After this call the current cycle register (roughly) corresponds to
0096  * the initial time stamp. Every call to timecounter_read() increments
0097  * the time stamp counter by the number of elapsed nanoseconds.
0098  */
0099 extern void timecounter_init(struct timecounter *tc,
0100                  const struct cyclecounter *cc,
0101                  u64 start_tstamp);
0102 
0103 /**
0104  * timecounter_read - return nanoseconds elapsed since timecounter_init()
0105  *                    plus the initial time stamp
0106  * @tc:          Pointer to time counter.
0107  *
0108  * In other words, keeps track of time since the same epoch as
0109  * the function which generated the initial time stamp.
0110  */
0111 extern u64 timecounter_read(struct timecounter *tc);
0112 
0113 /**
0114  * timecounter_cyc2time - convert a cycle counter to same
0115  *                        time base as values returned by
0116  *                        timecounter_read()
0117  * @tc:     Pointer to time counter.
0118  * @cycle_tstamp:   a value returned by tc->cc->read()
0119  *
0120  * Cycle counts that are converted correctly as long as they
0121  * fall into the interval [-1/2 max cycle count, +1/2 max cycle count],
0122  * with "max cycle count" == cs->mask+1.
0123  *
0124  * This allows conversion of cycle counter values which were generated
0125  * in the past.
0126  */
0127 extern u64 timecounter_cyc2time(const struct timecounter *tc,
0128                 u64 cycle_tstamp);
0129 
0130 #endif