linux/include/linux/timecounter.h
<<
>>
Prefs
   1/*
   2 * linux/include/linux/timecounter.h
   3 *
   4 * based on code that migrated away from
   5 * linux/include/linux/clocksource.h
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 */
  17#ifndef _LINUX_TIMECOUNTER_H
  18#define _LINUX_TIMECOUNTER_H
  19
  20#include <linux/types.h>
  21
  22/* simplify initialization of mask field */
  23#define CYCLECOUNTER_MASK(bits) (cycle_t)((bits) < 64 ? ((1ULL<<(bits))-1) : -1)
  24
  25/**
  26 * struct cyclecounter - hardware abstraction for a free running counter
  27 *      Provides completely state-free accessors to the underlying hardware.
  28 *      Depending on which hardware it reads, the cycle counter may wrap
  29 *      around quickly. Locking rules (if necessary) have to be defined
  30 *      by the implementor and user of specific instances of this API.
  31 *
  32 * @read:               returns the current cycle value
  33 * @mask:               bitmask for two's complement
  34 *                      subtraction of non 64 bit counters,
  35 *                      see CYCLECOUNTER_MASK() helper macro
  36 * @mult:               cycle to nanosecond multiplier
  37 * @shift:              cycle to nanosecond divisor (power of two)
  38 */
  39struct cyclecounter {
  40        cycle_t (*read)(const struct cyclecounter *cc);
  41        cycle_t mask;
  42        u32 mult;
  43        u32 shift;
  44};
  45
  46/**
  47 * struct timecounter - layer above a %struct cyclecounter which counts nanoseconds
  48 *      Contains the state needed by timecounter_read() to detect
  49 *      cycle counter wrap around. Initialize with
  50 *      timecounter_init(). Also used to convert cycle counts into the
  51 *      corresponding nanosecond counts with timecounter_cyc2time(). Users
  52 *      of this code are responsible for initializing the underlying
  53 *      cycle counter hardware, locking issues and reading the time
  54 *      more often than the cycle counter wraps around. The nanosecond
  55 *      counter will only wrap around after ~585 years.
  56 *
  57 * @cc:                 the cycle counter used by this instance
  58 * @cycle_last:         most recent cycle counter value seen by
  59 *                      timecounter_read()
  60 * @nsec:               continuously increasing count
  61 * @mask:               bit mask for maintaining the 'frac' field
  62 * @frac:               accumulated fractional nanoseconds
  63 */
  64struct timecounter {
  65        const struct cyclecounter *cc;
  66        cycle_t cycle_last;
  67        u64 nsec;
  68        u64 mask;
  69        u64 frac;
  70};
  71
  72/**
  73 * cyclecounter_cyc2ns - converts cycle counter cycles to nanoseconds
  74 * @cc:         Pointer to cycle counter.
  75 * @cycles:     Cycles
  76 * @mask:       bit mask for maintaining the 'frac' field
  77 * @frac:       pointer to storage for the fractional nanoseconds.
  78 */
  79static inline u64 cyclecounter_cyc2ns(const struct cyclecounter *cc,
  80                                      cycle_t cycles, u64 mask, u64 *frac)
  81{
  82        u64 ns = (u64) cycles;
  83
  84        ns = (ns * cc->mult) + *frac;
  85        *frac = ns & mask;
  86        return ns >> cc->shift;
  87}
  88
  89/**
  90 * timecounter_adjtime - Shifts the time of the clock.
  91 * @delta:      Desired change in nanoseconds.
  92 */
  93static inline void timecounter_adjtime(struct timecounter *tc, s64 delta)
  94{
  95        tc->nsec += delta;
  96}
  97
  98/**
  99 * timecounter_init - initialize a time counter
 100 * @tc:                 Pointer to time counter which is to be initialized/reset
 101 * @cc:                 A cycle counter, ready to be used.
 102 * @start_tstamp:       Arbitrary initial time stamp.
 103 *
 104 * After this call the current cycle register (roughly) corresponds to
 105 * the initial time stamp. Every call to timecounter_read() increments
 106 * the time stamp counter by the number of elapsed nanoseconds.
 107 */
 108extern void timecounter_init(struct timecounter *tc,
 109                             const struct cyclecounter *cc,
 110                             u64 start_tstamp);
 111
 112/**
 113 * timecounter_read - return nanoseconds elapsed since timecounter_init()
 114 *                    plus the initial time stamp
 115 * @tc:          Pointer to time counter.
 116 *
 117 * In other words, keeps track of time since the same epoch as
 118 * the function which generated the initial time stamp.
 119 */
 120extern u64 timecounter_read(struct timecounter *tc);
 121
 122/**
 123 * timecounter_cyc2time - convert a cycle counter to same
 124 *                        time base as values returned by
 125 *                        timecounter_read()
 126 * @tc:         Pointer to time counter.
 127 * @cycle_tstamp:       a value returned by tc->cc->read()
 128 *
 129 * Cycle counts that are converted correctly as long as they
 130 * fall into the interval [-1/2 max cycle count, +1/2 max cycle count],
 131 * with "max cycle count" == cs->mask+1.
 132 *
 133 * This allows conversion of cycle counter values which were generated
 134 * in the past.
 135 */
 136extern u64 timecounter_cyc2time(struct timecounter *tc,
 137                                cycle_t cycle_tstamp);
 138
 139#endif
 140