1/* @title: Clocks */
2#pragma once
3#include <errno.h>
4#include <math/fixed.h>
5#include <stddef.h>
6#include <stdint.h>
7#include <structures/list.h>
8#include <time/time.h>
9
10struct clock_base {
11 size_t freq_khz;
12 fx32_32_t clock_mult;
13};
14
15enum clock_rating {
16 CLOCK_RATING_UNSUITABLE,
17 CLOCK_RATING_BASE,
18 CLOCK_RATING_GOOD,
19 CLOCK_RATING_BETTER,
20 CLOCK_RATING_BEST,
21 CLOCK_RATING_MAX,
22};
23
24enum clock_flags {
25 CLOCK_FLAG_NONE = 0,
26 CLOCK_FLAG_WATCHDOG = 1,
27 CLOCK_FLAG_HRES = 1 << 1,
28 CLOCK_FLAG_UNSTABLE = 1 << 2,
29 CLOCK_FLAG_TIMESTAMP_SOURCE = 1 << 3, /* This clock is where all of the
30 * timestamp_t's around the kernel
31 * are coming from */
32};
33
34enum clock_state {
35 CLOCK_STATE_OFF,
36 CLOCK_STATE_ON,
37};
38
39struct clock {
40 /* gives cycles */
41 uint64_t (*read)(struct clock *);
42 char *name;
43 fx32_32_t mult; /* cycle to ns */
44 fx32_32_t uncertainty_margin; /* ns per s */
45 size_t frequency_khz;
46 struct list_head list_internal;
47
48 enum clock_state state;
49 enum clock_flags flags;
50 enum clock_rating rating;
51 struct clock_base *base;
52
53 /* these expect state changes from OFF/ON */
54 enum errno (*enable)(struct clock *);
55 void (*disable)(struct clock *);
56 void (*suspend)(struct clock *);
57 void (*resume)(struct clock *);
58
59 void *private;
60};
61
62struct clock *clock_create(const char *fmt, ...);
63void clock_register(struct clock *c);
64
65static inline fx32_32_t clock_frequency_to_mult(struct clock *clock) {
66 return fx_div(a: fx_from_int(x: 1000000), b: fx_from_int(x: clock->frequency_khz));
67}
68
69static inline time_t clock_cycles_to_ns(struct clock *clock, uint64_t cycles) {
70 return fx_to_int(x: fx_mul(a: fx_from_int(x: cycles), b: clock->mult));
71}
72