1 /* Copyright 2018 SiFive, Inc */
2 /* SPDX-License-Identifier: Apache-2.0 */
9 * @brief API for manipulating clock sources
11 * The clock interface allows for controlling the rate of various clocks in the system.
18 /* The generic interface to all clocks. */
19 struct __metal_clock_vtable {
20 long (*get_rate_hz)(const struct metal_clock *clk);
21 long (*set_rate_hz)(struct metal_clock *clk, long hz);
25 * @brief Function signature of clock pre-rate change callbacks
27 typedef void (*metal_clock_pre_rate_change_callback)(void *priv);
30 * @brief Function signature of clock post-rate change callbacks
32 typedef void (*metal_clock_post_rate_change_callback)(void *priv);
36 * @brief The handle for a clock
38 * Clocks are defined as a pointer to a `struct metal_clock`, the contents of which
39 * are implementation defined. Users of the clock interface must call functions
40 * which accept a `struct metal_clock *` as an argument to interract with the clock.
42 * Note that no mechanism for obtaining a pointer to a `struct metal_clock` has been
43 * defined, making it impossible to call any of these functions without invoking
44 * implementation-defined behavior.
47 const struct __metal_clock_vtable *vtable;
49 /* Pre-rate change callback */
50 metal_clock_pre_rate_change_callback _pre_rate_change_callback;
51 void *_pre_rate_change_callback_priv;
53 /* Post-rate change callback */
54 metal_clock_post_rate_change_callback _post_rate_change_callback;
55 void *_post_rate_change_callback_priv;
59 * @brief Returns the current rate of the given clock
61 * @param clk The handle for the clock
62 * @return The current rate of the clock in Hz
64 inline long metal_clock_get_rate_hz(const struct metal_clock *clk) { return clk->vtable->get_rate_hz(clk); }
67 * @brief Set the current rate of a clock
69 * @param clk The handle for the clock
70 * @param hz The desired rate in Hz
71 * @return The new rate of the clock in Hz.
73 * Attempts to set the current rate of the given clock to as close as possible
74 * to the given rate in Hz. Returns the actual value that's been selected, which
77 * Prior to and after the rate change of the clock, this will call the registered
78 * pre- and post-rate change callbacks.
80 inline long metal_clock_set_rate_hz(struct metal_clock *clk, long hz)
82 if(clk->_pre_rate_change_callback != NULL)
83 clk->_pre_rate_change_callback(clk->_pre_rate_change_callback_priv);
85 long out = clk->vtable->set_rate_hz(clk, hz);
87 if (clk->_post_rate_change_callback != NULL)
88 clk->_post_rate_change_callback(clk->_post_rate_change_callback_priv);
94 * @brief Register a callback that must be called before a rate change
96 * @param clk The handle for the clock
97 * @param cb The callback to be registered
98 * @param priv Private data for the callback handler
100 inline void metal_clock_register_pre_rate_change_callback(struct metal_clock *clk, metal_clock_pre_rate_change_callback cb, void *priv)
102 clk->_pre_rate_change_callback = cb;
103 clk->_pre_rate_change_callback_priv = priv;
107 * @brief Registers a callback that must be called after a rate change
109 * @param clk The handle for the clock
110 * @param cb The callback to be registered
111 * @param priv Private data for the callback handler
113 inline void metal_clock_register_post_rate_change_callback(struct metal_clock *clk, metal_clock_post_rate_change_callback cb, void *priv)
115 clk->_post_rate_change_callback = cb;
116 clk->_post_rate_change_callback_priv = priv;